This page was generated from nhd_navigation.ipynb. Interactive online version:

# NHD Navigation#

```
[1]:
```

```
import folium
import networkx as nx
import pynhd
from pynhd import GeoConnex, WaterData
```

In this example, we explore navigating the National Hydrography Dataset (NHD) using the `networkx`

package. First, we use `pynhd.enhd_flowlines_nx`

to obtain the CONUS drainage network based on the ENHD. This function returns a `networkx.DiGraph`

object, a mapping from the node IDs of the generated network to ComIDs of ENHD, and a list of topologically sorted ComIDs. Note that for performance reasons, the node IDs of
the generated network are different than the ComIDs of ENHD.

```
[2]:
```

```
graph, node2comid, _ = pynhd.enhd_flowlines_nx()
comid2node = {v: k for k, v in node2comid.items()}
```

We validate our navigation approach with the Mainstemsâ€™ dataset that we can retrieve from the GeoConnex web service. Moreover, for visualization purposes, we obtain the flowline geometries from the WaterData web service.

```
[3]:
```

```
gcx = GeoConnex("mainstems")
nhd_flw = WaterData("nhdflowline_network")
```

We pick Wisconsin River for this tutorial. Letâ€™s start by getting the mainstem of Wisconsin River from GeoConnex.

```
[4]:
```

```
ms = gcx.byid("id", "323742")
ms.explore()
```

```
[4]:
```

GeoConnex returns a GeoDataFrame containing the requested mainstem(s) and their headwater and outlet NHDPlus v2 ComIDs. We use these two ComIDs to the navigate Wisconsin River in the ENHD network.

```
[5]:
```

```
outlet_comid = int(ms["outlet_nhdpv2_comid"].str.rsplit("/", n=1).iloc[0][-1])
head_comid = int(ms["head_nhdpv2_comid"].str.rsplit("/", n=1).iloc[0][-1])
```

Navigating from a headwater to an outlet is straightforward. We use `networkx.shortest_path`

that returns a list of nodes that we can use to get the ComIDs of the flowlines. Finding the shortest path between two nodes in a network is a well-known problem in graph theory. For a weighted graph with positive weight values, the Dijkstraâ€™s algorithm is the most efficient approach. Note that in graph theory, the shortest path is a path that
has the minimum sum of its edge weights, i.e., the path with the least resistance (minimum navigation cost).

So, for navigating a NHDPlus from upstream to downstream, we need to consider using an attribute as edge weights that favors the flowlines without divergence. Thus, using the `divergence`

attribute is recommended for cases that divergence is a concern. However, ENHD provides a dendritic drainage network for CONUS, i.e., no divergence. So, we can simply navigate between two nodes in the ENHD network without using any weights.

```
[6]:
```

```
main_comids = [
node2comid[n] for n in nx.shortest_path(graph, comid2node[head_comid], comid2node[outlet_comid])
]
flw_main = nhd_flw.byid("comid", main_comids)
```

For visualization purposes and validating our approach, we overlay the flowlines that we obtained through navigation, on the mainstem of the Wisconsin River.

```
[7]:
```

```
m = ms.explore(style_kwds={"color": "blue", "weight": 4})
folium.GeoJson(flw_main, style_function=lambda f: {"color": "red", "weight": 1}).add_to(m)
m
```

```
[7]:
```