### Get Hydro Location Example Source: https://doi-usgs.github.io/hydroloom/reference/get_hydro_location.html Demonstrates how to use get_hydro_location with sample data. Requires the nhdplusTools package and sample flowlines. ```R if (require(nhdplusTools)) { source(system.file("extdata", "sample_flines.R", package = "nhdplusTools")) indexes <- index_points_to_lines(sample_flines, sf::st_sfc(sf::st_sfc(list(sf::st_point(c(-76.86934, 39.49328)), sf::st_point(c(-76.91711, 39.40884)), sf::st_point(c(-76.88081, 39.36354))), crs = 4326))) get_hydro_location(indexes, sample_flines) } ``` -------------------------------- ### Load and Inspect Sample Data with Hydroloom Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html Loads the `new_hope` dataset and inspects its structure and column names. This is a prerequisite for network navigation examples. ```R library(hydroloom) library(sf) hy_net <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) nrow(hy_net) #> [1] 746 class(hy_net) #> [1] "sf" "tbl_df" "tbl" "data.frame" names(hy_net) #> [1] "COMID" "GNIS_ID" "GNIS_NAME" "LENGTHKM" "REACHCODE" #> [6] "WBAREACOMI" "FTYPE" "FCODE" "StreamLeve" "StreamOrde" #> [11] "StreamCalc" "FromNode" "ToNode" "Hydroseq" "LevelPathI" #> [16] "Pathlength" "TerminalPa" "ArbolateSu" "Divergence" "StartFlag" #> [21] "TerminalFl" "DnLevel" "UpLevelPat" "UpHydroseq" "DnLevelPat" #> [26] "DnMinorHyd" "DnDrainCou" "DnHydroseq" "FromMeas" "ToMeas" #> [31] "RtnDiv" "VPUIn" "VPUOut" "AreaSqKM" "TotDASqKM" #> [36] "geom" class(hy(hy_net, clean = TRUE)) #> [1] "hy" "tbl_df" "tbl" "data.frame" names(hy(hy_net, clean = TRUE)) #> [1] "id" "length_km" #> [3] "aggregate_id" "wbid" #> [5] "feature_type" "feature_type_code" #> [7] "stream_level" "stream_order" #> [9] "stream_calculator" "fromnode" #> [11] "tonode" "topo_sort" #> [13] "levelpath" "pathlength_km" #> [15] "terminal_topo_sort" "arbolate_sum" #> [17] "divergence" "start_flag" #> [19] "terminal_flag" "dn_stream_level" #> [21] "up_levelpath" "up_topo_sort" #> [23] "dn_levelpath" "dn_minor_topo_sort" #> [25] "dn_topo_sort" "aggregate_id_from_measure" #> [27] "aggregate_id_to_measure" "da_sqkm" #> [29] "total_da_sqkm" ``` -------------------------------- ### Subset Network Example Source: https://doi-usgs.github.io/hydroloom/reference/subset_network.html Demonstrates how to subset a network upstream of a given outlet using the subset_network function. This example reads a network from a GeoPackage and then calculates the number of features in the subset. ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) sub <- subset_network(x, 8893420) nrow(sub) #> [1] 24 ``` -------------------------------- ### Install hydroloom Package Source: https://doi-usgs.github.io/hydroloom/index.html Install the hydroloom package from CRAN or the latest development version from GitHub. ```R install.packages("hydroloom") ``` ```R remotes::install_github("doi-usgs/hydroloom") ``` -------------------------------- ### Example: Indexing Points to Waterbodies with Hydroloom Source: https://doi-usgs.github.io/hydroloom/reference/index_points_to_waterbodies.html Demonstrates how to use `index_points_to_waterbodies` with sample data. Requires the `nhdplusTools` package and sample data. Ensure units are set for the search radius. ```R if (require(nhdplusTools)) { source(system.file("extdata/sample_data.R", package = "nhdplusTools")) waterbodies <- sf::st_transform( sf::read_sf(sample_data, "NHDWaterbody"), 5070) points <- sf::st_transform( sf::st_sfc(sf::st_point(c(-89.356086, 43.079943)), crs = 4326), 5070) index_points_to_waterbodies(waterbodies, points, search_radius = units::set_units(500, "m")) } #> near_wb_COMID near_wb_dist in_wb_COMID #> 1 167120949 272.8278 167120949 ``` -------------------------------- ### Make Attribute Topology Example Source: https://doi-usgs.github.io/hydroloom/reference/make_attribute_topology.html Demonstrates how to use `make_attribute_topology` to create an attribute topology from a spatial data frame. It also shows how to use `add_toids` and compares results. ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) y <- dplyr::select(x, COMID) y <- sf::st_transform(y, 5070) z <- make_attribute_topology(y, 10) x <- add_toids(hy(x), return_dendritic = FALSE) x[x$id == x$id[1], ]$toid #> [1] 8894334 z[z$COMID == x$id[1], ]$toid #> [1] 8894334 ``` -------------------------------- ### Fix Flow Direction Example Source: https://doi-usgs.github.io/hydroloom/reference/fix_flowdir.html This example demonstrates how to use fix_flowdir to correct a flowline's geometry. It involves reading a network, identifying a flowline, reversing its geometry, and then applying fix_flowdir to restore the correct direction. The example also visualizes the original and corrected flowline endpoints. ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) # We add a tocomid with prepare_nhdplus x <- add_toids(hy(x)) # Look at the end node of the 10th line. (n1 <- get_node(x[10, ], position = "end")) #> Simple feature collection with 1 feature and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 1520118 ymin: 1560497 xmax: 1520118 ymax: 1560497 #> Projected CRS: +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs #> geometry #> 1 POINT (1520118 1560497) # Break the geometry by reversing it. sf::st_geometry(x)[10] <- sf::st_reverse(sf::st_geometry(x)[10]) # Note that the end node is different now. (n2 <- get_node(x[10, ], position = "end")) #> Simple feature collection with 1 feature and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 1520229 ymin: 1560983 xmax: 1520229 ymax: 1560983 #> Projected CRS: +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs #> geometry #> 1 POINT (1520229 1560983) # Pass the broken geometry to fix_flowdir with the network for toCOMID sf::st_geometry(x)[10] <- fix_flowdir(x$id[10], x) # Note that the geometry is now in the right order. (n3 <- get_node(x[10, ], position = "end")) #> Simple feature collection with 1 feature and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 1520118 ymin: 1560497 xmax: 1520118 ymax: 1560497 #> Projected CRS: +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs #> geometry #> 1 POINT (1520118 1560497) plot(sf::st_geometry(x)[10]) plot(n1, add = TRUE) plot(n2, add = TRUE, col = "blue") plot(n3, add = TRUE, cex = 2, col = "red") ``` -------------------------------- ### Get Start and End Nodes of Lines Source: https://doi-usgs.github.io/hydroloom/reference/get_node.html Demonstrates how to use the get_node function to extract the start and end nodes from LINESTRING features. The resulting nodes can then be plotted. ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) start <- get_node(x, "start") end <- get_node(x, "end") plot(sf::st_zm(sf::st_geometry(x)), lwd = x$StreamOrde, col = "blue") plot(sf::st_geometry(start), add = TRUE) plot(sf::st_zm(sf::st_geometry(x)), lwd = x$StreamOrde, col = "blue") plot(sf::st_geometry(end), add = TRUE) ``` -------------------------------- ### Edge-to-edge network topology example Source: https://doi-usgs.github.io/hydroloom/articles/hydroloom.html This example illustrates an edge-to-edge topology representation for a network, where connectivity is defined by 'id' and 'toid' attributes. Terminal flowlines can have 'NA', 0, or an empty string for 'toid'. ```R #> id toid fromnode tonode #> 1 3 N1 N3 #> 2 3 N2 N3 #> 3 NA N3 N4 ``` -------------------------------- ### Example: Navigating Paths Between Network Outlets Source: https://doi-usgs.github.io/hydroloom/reference/navigate_connected_paths.html Demonstrates how to use `navigate_connected_paths` after reading a network from a GeoPackage, adding TOIDs, and specifying outlet IDs. The output includes network distances and the sequence of flowpath identifiers along each path. ```R x <- sf::read_sf(system.file("extdata", "walker.gpkg", package = "hydroloom")) outlets <- c(5329303, 5329357, 5329317, 5329365, 5329435, 5329817) x <- add_toids(hy(x)) navigate_connected_paths(x, outlets) ``` -------------------------------- ### Navigate Upstream Mainstem Source: https://doi-usgs.github.io/hydroloom/reference/navigate_hydro_network.html Navigates the network upstream along the mainstem. Requires the 'UM' mode. The starting catchment is included. ```R start <- 8894356 um <- navigate_hydro_network(x, start, "UM") plot_fun(x, start, um) ``` -------------------------------- ### Calculate Stream Order and Plot Source: https://doi-usgs.github.io/hydroloom/reference/add_streamorder.html This example demonstrates how to read a network dataset, select relevant columns, calculate stream order using `add_streamorder`, and then visualize the results by plotting the geometry with line widths corresponding to the calculated stream order and stream calculator values. ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) x <- dplyr::select(x, COMID, FromNode, ToNode, Divergence) x <- add_streamorder(x) plot(sf::st_geometry(x), lwd = x$stream_order, col = "blue") plot(sf::st_geometry(x), lwd = x$stream_calculator, col = "blue") ``` -------------------------------- ### Prepare and Navigate Flow Table Source: https://doi-usgs.github.io/hydroloom/articles/flow-table.html Prepares the flow table by filtering relevant flowlines and cleaning 'to_permanent_identifier'. It then uses `navigate_network_dfs` to find upstream and downstream flowlines relative to a starting point. ```R # remove coastal and make terminals go to an empty id. flow_table <- sf::read_sf(fs, "NHDFlow") |> filter(from_permanent_identifier %in% fl$permanent_identifier) |> mutate(to_permanent_identifier = ifelse(!to_permanent_identifier %in% from_permanent_identifier, "", to_permanent_identifier)) # Remove loops found in navigate network dfs remove <- hydroloom::check_hy_graph(flow_table) # this is naive and these removals would normally be reviewed. flow_table <- flow_table |> mutate(row = seq_len(n())) |> filter(!row %in% remove$row) down <- navigate_network_dfs(flow_table, sub$permanent_identifier, direction = "down") up <- navigate_network_dfs(flow_table, sub$permanent_identifier, direction = "up") subdown <- fl[fl$permanent_identifier %in% unique(unlist(down)), ] subup <- fl[fl$permanent_identifier %in% unique(unlist(up)), ] map_image <- "flow-table-fig.jpeg" map <- mapview::mapview(list(subup, subdown, point)) mapview::mapviewOptions(fgb = FALSE) mapview::mapshot(map, file = map_image) knitr::include_graphics(map_image) ``` -------------------------------- ### Fractional Accumulation Mode Setup Source: https://doi-usgs.github.io/hydroloom/articles/accumulate_downstream.html Prepares data for fractional accumulation by calculating an equal divergence fraction for each downstream path. This mode apportions upstream values across diversions. ```R y <- x |> group_by(FromNode) | # split evenly among downstream flowlines mutate(divergence_fraction = 1 / max(n())) | ungroup() y$frac_totdasqkm <- accumulate_downstream(y, "AreaSqKM") # diversions now carry a fraction of upstream area plot(y["frac_totdasqkm"], lwd = y$frac_totdasqkm / 20, main = "Fractional accumulation") ``` -------------------------------- ### Navigate Downstream Mainstem Source: https://doi-usgs.github.io/hydroloom/reference/navigate_hydro_network.html Navigates the network downstream along the mainstem. Requires the 'DM' mode. The starting catchment is included. ```R plot_fun <- function(x, s, n) { plot(sf::st_geometry(x), col = "grey") plot(sf::st_geometry(x[x$id %in% n, ]), add = TRUE) plot(sf::st_geometry(x[x$id %in% s, ]), col = "red", lwd = 3, add = TRUE) } x <- hy(sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom"))) start <- 8891126 dm <- navigate_hydro_network(x, start, "DM") plot_fun(x, start, dm) ``` -------------------------------- ### Example of Identifying Bridge Flowlines Source: https://doi-usgs.github.io/hydroloom/reference/get_bridge_flowlines.html Demonstrates how to use `get_bridge_flowlines` on a sample data frame representing a network. In this dendritic tree structure, all flowlines are identified as bridges. ```R x <- data.frame( id = c(1, 2, 3, 4, 5, 6, 7, 8, 9), toid = c(2, 3, 4, 5, 0, 7, 8, 9, 4) ) # 1 -> 2 -> 3 -> 4 -> 5 # ^ # | # 6 -> 7 -> 8 -> 9 # # Dendritic tree: all flowlines are bridges get_bridge_flowlines(x) #> [1] 1 2 3 4 5 6 7 8 9 ``` -------------------------------- ### Example: Rescale Measure Upstream Source: https://doi-usgs.github.io/hydroloom/reference/rescale_measures.html Demonstrates rescaling a measure of 60 from an aggregate where the flowline's range is 50 to 100. The result is 20, indicating 20% of the way up the flowline. ```R rescale_measures(60, 50, 100) #> [1] 20 ``` -------------------------------- ### Add Pfafstetter Codes with NHDPlusTools Data Source: https://doi-usgs.github.io/hydroloom/reference/add_pfafstetter.html An example demonstrating the use of add_pfafstetter with data from the nhdplusTools package. This involves preparing the network data, calculating downstream accumulation, levelpaths, and then Pfafstetter codes. ```R # uses tempdir for example work_dir <- nhdplusTools::nhdplusTools_data_dir(tempdir()) try( source(system.file("extdata/nhdplushr_data.R", package = "nhdplusTools")) ) if (exists("hr_data")) { x <- hy(hr_data$NHDFlowline) x <- add_toids(x) x <- dplyr::select(x, id, toid, da_sqkm) #' add terminal_id -- add in function? x <- sort_network(x, split = TRUE) x$total_da_sqkm <- accumulate_downstream(x, "da_sqkm") x$name <- "" x <- add_levelpaths(x, name_attribute = "name", weight_attribute = "total_da_sqkm") x <- add_pfafstetter(x, max_level = 3) plot(x["pf_level_3"], lwd = 2) pfaf <- add_pfafstetter(x, max_level = 4) hr_catchment <- dplyr::left_join(hr_data$NHDPlusCatchment, sf::st_drop_geometry(pfaf), by = c("FEATUREID" = "id")) colors <- data.frame(pf_level_4 = unique(hr_catchment$pf_level_4), color = sample(terrain.colors(length(unique(hr_catchment$pf_level_4))))) hr_catchment <- dplyr::left_join(hr_catchment, colors, by = "pf_level_4") plot(hr_catchment["color"], border = NA, reset = FALSE) plot(sf::st_geometry(x), col = "blue", add = TRUE) } else { message("nhdplusTools > 1.0 required for this example") } ``` -------------------------------- ### navigate_network_dfs Source: https://doi-usgs.github.io/hydroloom/reference/navigate_network_dfs.html Performs a depth-first search starting from specified nodes to find all reachable paths in a network. Nodes are marked as visited to avoid cycles and redundant paths. ```APIDOC ## navigate_network_dfs ### Description Given a starting node, return all reachable paths. Once visited, a node is marked as visited and will not take part in a future path. ### Usage ``` navigate_network_dfs(x, starts, direction = "down", reset = FALSE) ``` ### Arguments * **x** (data.frame or list) - Contains hydroloom compatible network or list as returned by `make_index_ids` ("to" mode for downstream or "from" mode for upstream). The index list format avoids recreating the index ids for every call to `navigate_network_dfs` in the case that it needs to be called many times. * **starts** (vector) - Vector with ids from `x` to start at. * **direction** (character) - "up", "upmain", "down", or "downmain". If "upmain" or "downmain", `x` must contain sufficient information to construct an upmain and downmain network (see details). * **reset** (logical) - If TRUE, reset graph for each start such that later paths will have overlapping results. ### Value List containing dfs result for each start. ### Details `navigate_network_dfs` offers two usage patterns. In the simple case, you can provide an `hy` in which case preprocessing is performed automatically, or you can do the preprocessing ahead of time and provide index ids. The latter is more complicated but can be much faster in certain circumstances. `hy` object: If the function will only be called one or a few times, it can be called with `x` containing (at a minimum) `id` and `toid`. For "upmain" and "downmain" support, `x` also requires attributes for determination of the primary upstream and downstream connection across every junction. In this pattern, the `hy` object will be passed to `make_index_ids` called for every call to `navigate_network_dfs` and the resulting index ids will be used for network navigation. Index ids: If the function will be called repeatedly or index_ids are available for other reasons, the index_id list as created by `make_index_ids` ("to" mode for downstream or "from" mode for upstream). For "upmain" and "downmain" support, the `main` element must be included. ``` -------------------------------- ### Example: Rescale Measure Downstream Source: https://doi-usgs.github.io/hydroloom/reference/rescale_measures.html Demonstrates rescaling a measure of 40 from an aggregate where the flowline's range is 0 to 50. The result is 80, indicating 80% of the way up the flowline. ```R rescale_measures(40, 0, 50) #> [1] 80 ``` -------------------------------- ### Create Node Topology with Divergence Data Source: https://doi-usgs.github.io/hydroloom/reference/make_node_topology.html This example shows how to create node topology while incorporating divergence information. The `add_div` argument accepts a data frame with 'id' and 'toid' for diverted paths. Diverted paths are marked with value 2, main paths from divergences with 1, and others with 0. ```R # just the divergences which have unique fromids in x but don't in new hope. div <- add_toids(dplyr::select(x, COMID, FromNode, ToNode), return_dendritic = FALSE) div <- div[div$toid %in% x$COMID[x$Divergence == 2], ] y <- dplyr::select(add_toids(x), -ToNode, -FromNode) y <- make_node_topology(y, add_div = div) #> Warning: nhdplusTools make_node_topology is deprecated. Use hydroloom version. ``` -------------------------------- ### Navigate Upstream with Tributaries Source: https://doi-usgs.github.io/hydroloom/reference/navigate_hydro_network.html Navigates the network upstream, including tributaries. Requires the 'UT' mode. The starting catchment is included. Be aware that tributaries emanating from diversions can significantly impact results. ```R ut <- navigate_hydro_network(x, start, "UT") plot_fun(x, start, ut) ``` -------------------------------- ### Navigate Network DFS Downstream Source: https://doi-usgs.github.io/hydroloom/reference/navigate_network_dfs.html Initiates a DFS from a given node to find all connected nodes downstream. Requires a hydro network object and a starting node ID. ```r x <- hy(sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom"))) x <- add_toids(x, return_dendritic = FALSE) navigate_network_dfs(x, 8893402) ``` -------------------------------- ### Sort Network with Diversions Source: https://doi-usgs.github.io/hydroloom/reference/sort_network.html Sorts a network that may contain diversions, ensuring correct topological ordering. This example demonstrates sorting after adding TOIDs without enforcing dendritic structure. ```R g <- add_toids(x, return_dendritic = FALSE) g <- sort_network(g) g$topo_sort <- nrow(g):1 plot(g['topo_sort']) ``` -------------------------------- ### Get Line Node Source: https://doi-usgs.github.io/hydroloom/reference/get_node.html Extracts the start or end node from LINESTRING features. ```APIDOC ## get_node ### Description Given one or more lines, returns a particular node from the line. ### Usage ```R get_node(x, position = "end") ``` ### Arguments * **x** (sf) - sf data.frame with one or more LINESTRING features * **position** (character) - either "start" or "end" ### Value sf data.frame containing requested nodes ### Examples ```R x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) start <- get_node(x, "start") end <- get_node(x, "end") plot(sf::st_zm(sf::st_geometry(x)), lwd = x$StreamOrde, col = "blue") plot(sf::st_geometry(start), add = TRUE) plot(sf::st_zm(sf::st_geometry(x)), lwd = x$StreamOrde, col = "blue") plot(sf::st_geometry(end), add = TRUE) ``` ``` -------------------------------- ### Navigate Network with Hydroloom Source: https://doi-usgs.github.io/hydroloom/articles/hydroloom.html Demonstrates using navigate_network_dfs with both internally generated graphs and pre-built index_ids. Use 'to' for downstream navigation and 'from' for upstream. ```r navigate_network_dfs(y, starts = y$id[1], direction = "down") ``` ```r to_index <- make_index_ids(y, mode = "to") navigate_network_dfs(to_index, starts = y$id[1], direction = "down") ``` ```r from_index <- make_index_ids(y, mode = "from") avigate_network_dfs(from_index, starts = y$id[1], direction = "up") ``` -------------------------------- ### Navigate Downstream with Diversions Source: https://doi-usgs.github.io/hydroloom/reference/navigate_hydro_network.html Navigates the network downstream, including diversions. Requires the 'DD' mode. The starting catchment is included. ```R dd <- navigate_hydro_network(x, start, "DD") plot_fun(x, start, dd) ``` -------------------------------- ### Load and Prepare Sample Network Data Source: https://doi-usgs.github.io/hydroloom/articles/accumulate_downstream.html Loads the New Hope sample watershed and subsets it to a connected upstream basin for analysis. Requires the sf package. ```R net <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) # subset to a connected upstream basin x <- subset_network(net, 8893236) plot(sf::st_geometry(net)) plot(sf::st_geometry(x), col = "red", add = TRUE) ``` -------------------------------- ### Prepare and Visualize Network Features Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html Prepares and visualizes key network features like the outlet, main path, and headwater using NHDPlus data. Requires the hydroloom package and plotting configuration. ```R # work in hydroloom attribute names for demo sake hy_net <- hy(hy_net) # the smallest topo_sort is the most downstream outlet <- hy_net[hy_net$topo_sort == min(hy_net$topo_sort), ] # features with the levelpath of the outlet are the mainpath, # or mainstem of the network main_path <- hy_net[hy_net$levelpath == outlet$levelpath, ] # the largest topo sort along the main path is its headwater flowline headwater <- main_path[main_path$topo_sort == max(main_path$topo_sort), ] # basemap par(mar = c(0, 0, 0, 0)) nhdplusTools::plot_nhdplus(bbox = sf::st_bbox(hy_net), plot_config = pc) # plot the elements prepped above plot(map_prep(hy_net), col = "dodgerblue2", add = TRUE, lwd = 0.5) plot(map_prep(outlet), col = "magenta", add = TRUE, lwd = 4) plot(map_prep(headwater), col = "magenta", add = TRUE, lwd = 4) plot(map_prep(main_path), col = "darkblue", add = TRUE, lwd = 1.5) ``` -------------------------------- ### Constructing a lightweight flownetwork topology Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html This R code demonstrates how to construct a lightweight flownetwork topology from a geometric network using Hydroloom utilities. It involves selecting base network attributes, creating a geometric network with divergence, and then converting it to a node topology. ```R # select only id, name, feature_type. # Note that the geometry is "sticky" and is included in base_net base_net <- dplyr::select(hy_net, id, GNIS_NAME, feature_type) # create a geometric network -- this includes divergences base_net <- dplyr::left_join(make_attribute_topology(base_net, min_distance = 10), base_net, by = "id") |> sf::st_sf() names(base_net) #> [1] "id" "toid" "GNIS_NAME" "feature_type" "geom" nrow(base_net) #> [1] 832 ``` ```R # now switch from a flownetwork topology to a node topology. base_net <- hydroloom::make_node_topology(base_net, add_div = TRUE, add = TRUE) names(base_net) #> [1] "id" "fromnode" "tonode" "GNIS_NAME" "feature_type" #> [6] "geom" nrow(base_net) #> [1] 746 ``` ```R # divergence determination needs a dominant feature type input unique(base_net$feature_type) #> [1] "StreamRiver" "Connector" "ArtificialPath" ``` ```R base_net <- add_divergence(base_net, coastal_outlet_ids = outlet$id, inland_outlet_ids = c(), name_attr = "GNIS_NAME", type_attr = "feature_type", major_types = "StreamRiver") names(base_net) #> [1] "id" "fromnode" "tonode" "GNIS_NAME" "feature_type" #> [6] "geom" "divergence" nrow(base_net) #> [1] 746 ``` ```R # now we can add a dendritic toid attribute because we have "divergence" base_net <- add_toids(base_net, return_dendritic = TRUE) # note that no rows were added -- these are only downmain! nrow(base_net) #> [1] 746 ``` ```R # now add a length attribute as the accumulated flowline length. base_net$length_km <- as.numeric(st_length(base_net) / 1000) base_net$weight <- accumulate_downstream(base_net, "length_km") #> Dendritic routing will be applied. Diversions are assumed to have 0 flow fraction. ``` ```R base_net <- add_levelpaths(base_net, name_attribute = "GNIS_NAME", weight_attribute = "weight") names(base_net) #> [1] "id" "toid" "levelpath_outlet_id" #> [4] "topo_sort" "levelpath" "geom" #> [7] "tonode" "GNIS_NAME" "feature_type" #> [10] "divergence" "fromnode" "length_km" #> [13] "weight" ``` -------------------------------- ### Get Hydro Location Function Source: https://doi-usgs.github.io/hydroloom/reference/get_hydro_location.html This R function, `get_hydro_location`, is used to find the exact point geometry on a flowline based on provided indexes and flowpath data. ```APIDOC ## get_hydro_location ### Description Given a flowline index, returns the hydrologic location (point) along the specific linear element referenced by the index. ### Usage ```R get_hydro_location(indexes, flowpath) ``` ### Arguments * **indexes**: data.frame as output from `index_points_to_lines`. * **flowpath**: data.frame with three columns: `id`, `frommeas`, and `tomeas` as well as geometry. ### Value sfc_POINT simple feature geometry list of length `nrow(indexes)` ### Examples ```R if (require(nhdplusTools)) { source(system.file("extdata", "sample_flines.R", package = "nhdplusTools")) indexes <- index_points_to_lines(sample_flines, sf::st_sfc(sf::st_sfc(list(sf::st_point(c(-76.86934, 39.49328)), sf::st_point(c(-76.91711, 39.40884)), sf::st_point(c(-76.88081, 39.36354))), crs = 4326))) get_hydro_location(indexes, sample_flines) } ``` ``` -------------------------------- ### Navigate Network DFS Upstream Source: https://doi-usgs.github.io/hydroloom/reference/navigate_network_dfs.html Performs a DFS starting from a given node to find all connected nodes upstream. This is useful for tracing flow paths against the primary direction. ```r navigate_network_dfs(x, 8897784, direction = "up") ``` -------------------------------- ### Compare Flow Network Construction Methods Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html Compares flow networks constructed using hydroloom and NHDPlus to identify differences in 'upmain' and 'downmain' attributes. This helps in understanding discrepancies arising from different accumulation methods. ```r flow_net_nhdplus <- to_flownetwork(hy_net) | dplyr::arrange(id, toid) flow_net_hydroloom <- to_flownetwork(base_net) | dplyr::arrange(id, toid) different_downmain <- flow_net_nhdplus[flow_net_nhdplus$downmain != flow_net_hydroloom$downmain, ] different_downmain #> # A tibble: 0 × 4 #> # ℹ 4 variables: id , toid , upmain , downmain different_upmain <- flow_net_nhdplus[flow_net_nhdplus$upmain != flow_net_hydroloom$upmain, ] different_upmain #> # A tibble: 2 × 4 #> id toid upmain downmain #> #> 1 8893470 8893552 TRUE TRUE #> 2 8893472 8893552 FALSE TRUE different_upmain <- hy_net[hy_net$id %in% c(different_upmain$id, different_upmain$toid), ] par(mar = c(0, 0, 0, 0)) nhdplusTools::plot_nhdplus(bbox = sf::st_bbox(different_upmain), plot_config = pc) plot(map_prep(hy_net), col = "dodgerblue2", add = TRUE, lwd = 0.5) plot(map_prep(different_upmain), col = "blue", add = TRUE, lwd = 2) ``` -------------------------------- ### Get Bridge Flowlines Function Signature Source: https://doi-usgs.github.io/hydroloom/reference/get_bridge_flowlines.html Shows the usage and S3 methods for the `get_bridge_flowlines` function. It accepts a data frame or 'hy' object and an optional quiet argument. ```R get_bridge_flowlines(x, quiet = FALSE) # S3 method for class 'data.frame' get_bridge_flowlines(x, quiet = FALSE) # S3 method for class 'hy' get_bridge_flowlines(x, quiet = FALSE) ``` -------------------------------- ### List Geodatabase Files Source: https://doi-usgs.github.io/hydroloom/articles/flow-table.html Lists all files in a directory matching a specific geodatabase pattern. Ensure the directory variable 'dir' is defined before use. ```r fs <- list.files(dir, pattern = ".*1908.*.gdb", full.names = TRUE) ``` -------------------------------- ### Upstream and Downstream Network Navigation Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html Performs both upstream ('up') and downstream ('down') navigation from a starting flowline in a hydrological network. This is useful for understanding network connectivity from a specific point. ```R start <- half_path[half_path$topo_sort == max(half_path$topo_sort), ] up <- navigate_hydro_network(hy_net, start = start$id, mode = "up") up <- hy_net[hy_net$id %in% up, ] down <- navigate_hydro_network(hy_net, start = start$id, mode = "down") down <- hy_net[hy_net$id %in% down, ] par(mar = c(0, 0, 0, 0)) nhdplusTools::plot_nhdplus(bbox = sf::st_bbox(hy_net), plot_config = pc) plot(map_prep(hy_net), col = "dodgerblue2", add = TRUE, lwd = 0.5) plot(map_prep(start), col = "magenta", add = TRUE, lwd = 4) plot(map_prep(up), col = "darkblue", add = TRUE, lwd = 2) plot(map_prep(down), col = "blue", add = TRUE, lwd = 2) ``` -------------------------------- ### Animate Level Path Visualization Source: https://doi-usgs.github.io/hydroloom/articles/advanced_network.html Creates an animated GIF showing level paths filling in from outlet to headwaters. This requires inverting the plotting order and filtering for level paths with more than two flowlines. The animation highlights the outlet flowline in red and newly added level paths in blue. ```R # Invert plotting order fpath <- dplyr::arrange(fpath, topo_sort) # Level Paths with more then 2 flowlines lp <- dplyr::group_by(fpath, levelpath) |> dplyr::filter(n() > 2) # Unique Level Path ID lp <- unique(lp$levelpath) # Terminal flowline terminal_fpath <- dplyr::filter(fpath, id %in% terminal_id) gif_file <- "levelpath.gif" try({ gifski::save_gif({ for (i in seq_along(lp)) { lp_plot <- dplyr::filter(fpath, levelpath == lp[i]) outlet_plot <- dplyr::filter(lp_plot, id %in% terminal_id) plot(sf::st_geometry(fpath), lwd = 0.5, col = "grey") plot(sf::st_geometry(terminal_fpath), lwd = 3, col = "red", add = TRUE) plot(sf::st_geometry(dplyr::filter(fpath, levelpath %in% lp[1:i])), add = TRUE) plot(sf::st_geometry(lp_plot), col = "blue", add = TRUE) plot(sf::st_geometry(outlet_plot), col = "red", lwd = 1.5, add = TRUE) } }, gif_file, delay = 0.5) knitr::include_graphics(gif_file) }) ``` -------------------------------- ### Read and Process Hydrological Data with hy() Source: https://doi-usgs.github.io/hydroloom/reference/hy.html Demonstrates reading a spatial data file and applying the primary hy() function for initial processing. Shows the default output structure. ```r x <- sf::read_sf(system.file("extdata/new_hope.gpkg", package = "hydroloom")) hy(x) ``` -------------------------------- ### Navigate Network Upstream with Distance Limit Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html Navigates upstream from a specified start point within a hydrological network, limiting the navigation by a given distance. The pathlength_km attribute is used to calculate the distance. ```R # this is just the ids path <- navigate_hydro_network(hy_net, start = outlet$id, mode = "UM") # filter the source data to get the id's representation path <- hy_net[hy_net$id %in% path, ] # pathlength_km is the distance from the furthest downstream network outlet # it is used within navigate_hydro_network to filter to a given distance. pathlength <- max(path$pathlength_km) - min(path$pathlength_km) half_path <- navigate_hydro_network(hy_net, start = outlet$id, mode = "UM", distance = pathlength / 2) half_path <- hy_net[hy_net$id %in% half_path, ] par(mar = c(0, 0, 0, 0)) nhdplusTools::plot_nhdplus(bbox = sf::st_bbox(hy_net), plot_config = pc) plot(map_prep(hy_net), col = "dodgerblue2", add = TRUE, lwd = 0.5) plot(map_prep(half_path), col = "magenta", add = TRUE, lwd = 3) plot(map_prep(path), col = "darkblue", add = TRUE, lwd = 2) ``` -------------------------------- ### Navigate Network Depth First Function Signature Source: https://doi-usgs.github.io/hydroloom/reference/navigate_network_dfs.html This is the function signature for navigate_network_dfs. It outlines the parameters and their types. ```R navigate_network_dfs(x, starts, direction = "down", reset = FALSE) ``` -------------------------------- ### Prepare Geometry for Plotting Source: https://doi-usgs.github.io/hydroloom/articles/network_navigation.html A helper function to prepare spatial data for plotting by transforming to a web mercator projection and simplifying geometry. ```R map_prep <- \(x, tol = 100) { sf::st_geometry(x) |> # no attributes sf::st_transform(3857) |> # basemap projection sf::st_simplify(dTolerance = tol) # sleaner rendering } pc <- list(flowline = list(col = NA)) # to hide flowlines in basemap oldpar <- par(mar = c(0, 0, 0, 0)) # par is reset in cleanup nhdplusTools::plot_nhdplus(bbox = sf::st_bbox(hy_net), plot_config = pc) plot(map_prep(hy_net), col = "blue", add = TRUE) ``` -------------------------------- ### Get Hydroloom Names Source: https://doi-usgs.github.io/hydroloom/reference/hydroloom_names.html Call `hydroloom_names()` without arguments to retrieve the current mapping of hydroloom attribute names to data source names. These mappings are stored in the hydroloom environment and will reset when R is restarted. ```r hydroloom_names() ``` -------------------------------- ### Fractional Accumulation Visualization Source: https://doi-usgs.github.io/hydroloom/articles/accumulate_downstream.html Zooms in on diversions to visualize the fractional accumulation of upstream area, showing how values are distributed across diverging flowlines. ```R # zoom in to see what's going on at diversions plot(sf::st_geometry(y[y$COMID %in% c("8893210", "8893222"), ]), col = NA) plot(y["frac_totdasqkm"], lwd = y$frac_totdasqkm / 20, main = "Fractional accumulation", add = TRUE) ``` -------------------------------- ### Get or Set Hydroloom Names Source: https://doi-usgs.github.io/hydroloom/reference/hydroloom_names.html Retrieves the current Hydroloom name mappings or sets additional mappings. Note that these settings are temporary and will reset upon R session restart. For persistent changes, add them to your project or user .Rprofile. ```APIDOC ## hydroloom_names ### Description Retrieve hydroloom name mapping from hydroloom environment. Hydroloom uses a specific set of attribute names within the package and includes mappings from names used in some data sources. This function will return those names and can be used to set additional name mappings. ### Usage ```R hydroloom_names(x = NULL, clear = FALSE) ``` ### Arguments * `x` (named character vector, optional): Additional names to add to the hydroloom environment. If not specified, no names will be added and the current value stored in the hydroloom environment will be returned. * `clear` (logical, optional): If TRUE, all names will be removed and replaced with `x`. ### Value Named character vector containing hydroloom names with registered attribute name mappings in `names`. ### Examples ```R # Get current hydroloom names hydroloom_names() # Example output: # id3dhp comid # "id" "id" # nhdplusid featureid # "id" "id" # permanent_identifier from_permanent_identifier # "id" "id" # reconciled_id aggregated_id # "id" "id" # toid tocomid # "toid" "toid" # to_permanent_identifier reconciled_toid # "toid" "toid" # aggregated_toid tonode # "toid" "tonode" # fromnode divergence # "fromnode" "divergence" # divergence_fraction wbareacomi # "divergence_fraction" "wbid" # totdasqkm totda # "total_da_sqkm" "total_da_sqkm" # areasqkm lengthkm # "da_sqkm" "length_km" # pathlength arbolatesu # "pathlength_km" "arbolate_sum" # hydroseq uphydroseq # "topo_sort" "up_topo_sort" # dnhydroseq dnminorhyd # "dn_topo_sort" "dn_minor_topo_sort" # terminalpa terminalfl # "terminal_topo_sort" "terminal_flag" # startflag levelpathi # "start_flag" "levelpath" # levelpathid outletID # "levelpath" "levelpath_outlet_id" # uplevelpat dnlevelpat # "up_levelpath" "dn_levelpath" # streamleve dnlevel # "stream_level" "dn_stream_level" # streamorde streamcalc # "stream_order" "stream_calculator" # ftype fcode # "feature_type" "feature_type_code" # vpuid rpuid # "vector_proc_unit" "raster_proc_unit" # reachcode mainstemid # "aggregate_id" "aggregate_id" # reach_meas reachcode_measure # "aggregate_id_measure" "aggregate_id_measure" # frommeas tomeas # "aggregate_id_from_measure" "aggregate_id_to_measure" # mainstemid_from_measure mainstemid_to_measure # "aggregate_id_from_measure" "aggregate_id_to_measure" ``` ```R # Set additional names (temporary) hydroloom_names(x = c(my_id = "id", my_name = "name")) # Clear all names and set new ones (temporary) hydroloom_names(x = c(new_id = "id"), clear = TRUE) ``` ```