From 4c68c7c40c7f124fa34ba8b050d72818552f6d18 Mon Sep 17 00:00:00 2001 From: Bock <abock@usgs.gov> Date: Thu, 18 May 2023 08:04:04 -0600 Subject: [PATCH] moved some code around --- workspace/02_NHD_navigate_Sp.Rmd | 823 ++++++++++++++++++++++++++++++ workspace/06-2_aggregate_cats.Rmd | 19 +- 2 files changed, 836 insertions(+), 6 deletions(-) create mode 100644 workspace/02_NHD_navigate_Sp.Rmd diff --git a/workspace/02_NHD_navigate_Sp.Rmd b/workspace/02_NHD_navigate_Sp.Rmd new file mode 100644 index 0000000..daebbea --- /dev/null +++ b/workspace/02_NHD_navigate_Sp.Rmd @@ -0,0 +1,823 @@ +--- +title: "NHD Navigate" +output: html_document +editor_options: + chunk_output_type: console +--- +This notebook Generate Segments and POIS from POI data sources and builds +a minimally-sufficient stream network connecting all POis, as well as generating first-cut of +national segment network. + +```{r setup_rmd, echo=FALSE, cache=FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.width=6, + fig.height=4, + cache=FALSE) +``` + +```{r setup} +# Load custom functions +source("R/utils.R") +source("R/NHD_navigate.R") +source("R/hyrefactor_funs.R") + +# increase timeout for data downloads +options(timeout=600) + +# Load Configuration of environment +source("R/config.R") + +# Gages output from Gage_selection +gages <- read_sf(gage_info_gpkg, "Gages") +# need some extra attributes for a few POI analyses +atts <- readRDS(file.path(data_paths$nhdplus_dir, "nhdplus_flowline_attributes.rds")) + +sparrow_dir <- "data/sparrow" + +collapse <- TRUE +``` + +```{r huc12 POIs} +# Derive or load HUC12 POIs +if(needs_layer(temp_gpkg, nav_poi_layer)) { + + nhd <- read_sf(nav_gpkg, nhd_flowline) + try(nhd <- select(nhd, -c(minNet, WB, struct_POI, struct_Net, POI_ID, dend, poi)), silent = TRUE) + + # Some NHDPlus VPUs include HUCs from other VPUs + if(vpu == "02"){ + grep_exp <-"^02|^04" + } else if (vpu == "08") { + grep_exp <- "^03|^08" + } else { + grep_exp <- paste0("^", substr(vpu, start = 1, stop = 2)) + } + + # Join HUC12 outlets with NHD + HUC12_COMIDs <- read_sf(data_paths$hu12_points_path, "hu_points") %>% + filter(grepl(grep_exp, .data$HUC12)) %>% + select(COMID, HUC12) %>% + # Remove this when HUC12 outlets finished + group_by(COMID) %>% + filter(row_number() == 1) %>% + ungroup() + + # Create POIs - some r05 HUC12 POIs not in R05 NHD + huc12_POIs <- POI_creation(st_drop_geometry(HUC12_COMIDs), nhd, "HUC12") + tmp_POIs <- huc12_POIs + + # Write out geopackage layer representing POIs for given theme + write_sf(huc12_POIs, temp_gpkg, nav_poi_layer) + tmp_POIs <- huc12_POIs +} else { + # Load HUC12 POIs as the tmpPOIs if they already exist + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) + nhd <- read_sf(nav_gpkg, nhd_flowline) +} + +mapview(filter(tmp_POIs, Type_HUC12 != ""), layer.name = "HUC12 POIs", col.regions = "red") +``` + +```{r streamgage POIs} +if(!"Type_Gages" %in% names(tmp_POIs)) { + + ref_gages <- read_sf("data/ref_gages.gpkg") + + # Previously identified streamgages within Gage_Selection.Rmd + streamgages_VPU <- gages %>% + rename(COMID = comid) %>% + filter(COMID %in% nhd$COMID) %>% + #st_drop_geometry() %>% + switchDiv(., nhd) + + streamgages <- streamgages_VPU %>% + group_by(COMID) %>% + # If multiple gages per COMID, pick one with highest rank as rep POI_ID + filter(gage_score == max(gage_score), !is.na(drain_area)) %>% + ungroup() %>% + select(COMID, site_no) + + # Derive TE POIs + tmp_POIs <- POI_creation(st_drop_geometry(streamgages), nhd, "Gages") %>% + addType(., tmp_POIs, "Gages", nexus = FALSE) + + # Write out geopackage layer representing POIs for given theme + write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +} else { + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +} + +mapview(filter(tmp_POIs, !is.na(Type_Gages)), layer.name = "Streamgage POIs", col.regions = "blue") +``` + +# R01 - missing one +```{r Sparrow Cal POIs} +if(!"Type_Sparrow" %in% names(tmp_POIs)) { + + # Load Sparrow calibration POIs + sparrow_cal_pois <- read_sf("data/sparrow/sparrow_source.gpkg", "calibration_poi") %>% + mutate(COMID = as.integer(COMID)) %>% + filter(COMID %in% nhd$COMID) %>% + select(COMID, MonitoringLocationIdentifier, site_no, station_nm, + usgs_hy_id, distance_m, longitude, latitude, nat_id) %>% + st_as_sf(coords = c("longitude", "latitude"), crs = 4326) %>% + select(COMID, nat_id) + + # Derive TE POIs + tmp_POIs <- POI_creation(st_drop_geometry(sparrow_cal_pois), nhd, "Sparrow") %>% + addType(., tmp_POIs, "Sparrow", nexus = FALSE) + + missing_sparrow <- filter(sparrow_cal_pois, !nat_id %in% tmp_POIs$Type_Sparrow) + if(nrow(missing_sparrow) > 0){write_sf(missing_sparrow, temp_gpkg, "missing_sparrow")} + write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +} else { + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +} + +mapview(filter(tmp_POIs, !is.na(Type_Gages)), layer.name = "Streamgage POIs", col.regions = "blue") +``` + +```{r TE POIs} +if(!"Type_TE" %in% names(tmp_POIs)) { + + if(vpu == "08"){ + nhd$VPUID <- "08" + } else { + nhd$VPUID <- substr(nhd$RPUID, 1, 2) + } + + # Read in Thermoelectric shapefile + TE_COMIDs <- read_sf(data_paths$TE_points_path, "2015_TE_Model_Estimates_lat.long_COMIDs") %>% + mutate(COMID = as.integer(COMID)) %>% + inner_join(., select(st_drop_geometry(nhd), COMID, VPUID), by = "COMID") %>% + filter(grepl(paste0("^", substr(vpu, 1, 2), ".*"), .data$VPUID), COMID > 0) %>% + switchDiv(., nhd) %>% + group_by(COMID) %>% + summarize(EIA_PLANT = paste0(unique(EIA_PLANT_), collapse = " "), count = n()) %>% + ungroup() %>% + select(COMID, EIA_PLANT) + + # Derive TE POIs + tmp_POIs <- POI_creation(st_drop_geometry(TE_COMIDs), nhd, "TE") %>% + addType(., tmp_POIs, "TE", nexus = FALSE, bind = TRUE) + + # As a fail-safe, write out list of TE plants not assigned a POI + if(nrow(filter(TE_COMIDs, !COMID %in% tmp_POIs$COMID)) > 0) { + write_sf(filter(TE_COMIDs, !COMID %in% tmp_POIs$COMID), + temp_gpkg, "unassigned_TE") + } + + # Write out geopackage layer representing POIs for given theme + write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +} else { + # Load TE POIs if they already exist + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +} + +mapview(filter(tmp_POIs, Type_TE != ""), layer.name = "TE Plant POIs", col.regions = "blue") +``` + +```{r waterbody outlet POIs} +# Derive or load Waterbody POIs ---------------------- +if(!"Type_WBOut" %in% names(tmp_POIs)) { + + sparrow_wb_outlet <- read_sf("data/sparrow/sparrow_source.gpkg", "wb_outlets") %>% + filter(COMID %in% nhd$COMID) + + sparrow_wb <- read_sf("data/sparrow/sparrow_source.gpkg", "waterbodies") %>% + filter(COMID %in% nhd$WBAREACOMI) + + # Waterbodies sourced from NHD waterbody layer for entire VPU + WBs_VPU_all <- filter(readRDS("data/NHDPlusNationalData/nhdplus_waterbodies.rds"), + COMID %in% nhd$WBAREACOMI) %>% + mutate(FTYPE = as.character(FTYPE)) %>% + mutate(source = "NHDv2WB") %>% + st_transform(crs) + + # Waterbody list that strictly meet the size criteria + wb_lst <- st_drop_geometry(WBs_VPU_all) %>% + dplyr::filter(FTYPE %in% c("LakePond", "Reservoir") & AREASQKM >= (min_da_km/2)) %>% + dplyr::select(COMID) %>% + filter(!COMID == 166410600) %>% + rbind(dplyr::select(st_drop_geometry(sparrow_wb), COMID)) + + if (file.exists(data_paths$resops_NID_CW)){ + # ResOpsUS locations in the VPU waterbody set + resops_wb_df <- read.csv(data_paths$resops_NID_CW) %>% + dplyr::filter(WBAREACOMI %in% WBs_VPU_all$COMID) %>% + dplyr::select(DAM_ID, DAM_NAME, COMID = WBAREACOMI, FlowLcomid) %>% + distinct() + + # Add ResOPsUS locations to waterbody list + if(nrow(resops_wb_df) > 0){ + wb_lst <- rbind(wb_lst, select(resops_wb_df, COMID)) %>% + distinct() + } + } + + # Waterbodies that meet the size criteria and/or are in ResOpsUS datasets + WBs_VPU <- WBs_VPU_all %>% + dplyr::filter(COMID %in% wb_lst$COMID) + + WBs_VPU <- filter(WBs_VPU, COMID != 666170) #1R16 + + # Attribute flowlines that are in waterbodies + nhd <- mutate(nhd, WB = ifelse(WBAREACOMI > 0 & WBAREACOMI %in% WBs_VPU$COMID, 1, 0)) + + wbout_COMIDs <- nhd %>% #filter(nhd, dend == 1 & WB == 1) + filter(WBAREACOMI %in% WBs_VPU$COMID) %>% + filter(!WBAREACOMI %in% sparrow_wb_outlet$WB_COMID) %>% + group_by(WBAREACOMI) %>% + slice(which.min(Hydroseq)) %>% + switchDiv(., nhd) %>% + select(COMID, WBAREACOMI, LevelPathI) %>% + st_drop_geometry() %>% + rbind(select(st_drop_geometry(sparrow_wb_outlet), COMID, WBAREACOMI = WB_COMID)) + + tmp_POIs <- POI_creation(wbout_COMIDs, nhd, "WBOut") %>% + addType(., tmp_POIs, "WBOut", nexus = FALSE, bind = TRUE) + + # Write out waterbodies + write_sf(WBs_VPU, nav_gpkg, WBs_layer) + + # Write specific ResOpsUS data to a separate sheet + if(nrow(wb_lst) > 0){ + resops_POIs_df <- st_drop_geometry(tmp_POIs) %>% + dplyr::select(COMID, Type_WBOut) %>% + dplyr::filter(!is.na(Type_WBOut)) %>% + dplyr::inner_join(select(resops_wb_df, -FlowLcomid), by = c("Type_WBOut" = "COMID")) + + write.csv(resops_POIs_df, file.path("data/reservoir_Data", paste0("resops_POIs_",vpu,".csv"))) + } + + + wb_out <- filter(tmp_POIs, !is.na(Type_WBOut)) + missing_wb_out <- filter(sparrow_wb_outlet, !WB_COMID %in% wb_out$Type_WBOut) + missing_wb_out_com <- filter(sparrow_wb_outlet, + !COMID %in% wb_out$COMID) + if(nrow(missing_wb_out) > 0){write_sf(missing_wb_out, temp_gpkg, "missing_sparrow_WB")} + if(nrow(missing_wb_out_com) > 0){write_sf(missing_wb_out_com, temp_gpkg, "missing_sparrow_WBout")} + + sparrow_wb_ids <- select(sparrow_wb_outlet, COMID, WB_COMID, nat_id) + + tmp_POIs <- tmp_POIs %>% + left_join(select(st_drop_geometry(sparrow_wb_ids), -COMID), by = c("Type_WBOut" = "WB_COMID")) %>% + mutate(Type_Sparrow = ifelse(is.na(Type_Sparrow), nat_id, Type_Sparrow)) %>% + select(-nat_id) + + write_sf(nhd, nav_gpkg, nhd_flowline) + write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +} else { + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) + nhd <- read_sf(nav_gpkg, nhd_flowline) + WBs_VPU <- read_sf(nav_gpkg, WBs_layer) + resops_POIs_df <- read.csv(file.path("data/reservoir_Data", paste0("resops_POIs_",vpu,".csv"))) +} + +mapview(filter(tmp_POIs, !is.na(Type_WBOut)), layer.name = "Waterbody outlet POIs", col.regions = "red") +``` + +```{r NID POIs} +# Derive or load NID POIs ---------------------- +if(all(is.na(tmp_POIs$Type_NID))) { + + sparrow_nid <- read_sf("data/sparrow/sparrow_source.gpkg", "nid_pois") + + sparrow_wb_nid <- sparrow_nid %>% + #rename(COMID = ComID) %>% + filter(COMID %in% nhd$COMID) %>% + select(COMID, NIDID, nat_id) + + if(nrow(sparrow_wb_nid) > 0){ + # Determine which NID facilitites have been co-located with ResOps + res_ops_table <- read.csv(data_paths$resops_NID_CW) %>% + mutate(new_WBARECOMI = ifelse(is.na(WBAREACOMI) & is.na(NHDAREA), HR_NHDPLUSID, WBAREACOMI)) %>% + mutate(new_WBARECOMI = ifelse(is.na(new_WBARECOMI) & is.na(HR_NHDPLUSID), NHDAREA, new_WBARECOMI)) %>% + filter(new_WBARECOMI %in% tmp_POIs$Type_WBOut, !is.na(new_WBARECOMI)) %>% + select(NID_ID = NID_Source_FeatureID, Type_WBOut = new_WBARECOMI) %>% + filter() + + # Attribute those NID facilities precisely at the outlet + if(nrow(res_ops_table) > 0){ + tmp_POIs <- tmp_POIs %>% + left_join(res_ops_table, by = "Type_WBOut") %>% + mutate(Type_NID = ifelse(!is.na(NID_ID), NID_ID, NA)) %>% + select(-NID_ID) + + sparrow_wb_nid <- filter(sparrow_wb_nid, !NIDID %in% tmp_POIs$Type_NID) + } + + # Derive other NID POIs + tmp_POIs <- POI_creation(st_drop_geometry(sparrow_wb_nid), nhd, "NID") %>% + addType(., tmp_POIs, "NID", nexus = FALSE, bind = TRUE) %>% + left_join(select(st_drop_geometry(sparrow_wb_nid), NIDID, nat_id), by = c("Type_NID" = "NIDID")) %>% + mutate(Type_Sparrow = ifelse(is.na(Type_Sparrow), nat_id, Type_Sparrow)) %>% + select(-nat_id) + + sparrow_wb_nid_missing <- filter(sparrow_wb_nid, !nat_id %in% tmp_POIs$Type_Sparrow) %>% + mutate(WB_Comid = paste("Sparrow_nid_", row_number())) + + if(nrow(sparrow_wb_nid_missing) > 0){write_sf(sparrow_wb_nid_missing, temp_gpkg, "missing_wb_nid")} + # Write out geopackage layer representing POIs for given theme + write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) + mapview(filter(tmp_POIs, Type_NID != ""), layer.name = "NID POIs", col.regions = "blue") + } + +} else { + # Load NID POIs if they already exist + tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +} +``` + + +```{r Diversion POIs} +# # Derive POIs at confluences where they are absent ---------------------- +# if(needs_layer(temp_gpkg, "diversions")) { +# +# div_pois_source <- read_sf("data/sparrow/sparrow_source.gpkg", "div_poi") %>% +# filter(COMID %in% nhd$COMID) %>% +# select(COMID, nat_id) +# +# div_POIs <- POI_creation(st_drop_geometry(div_pois_source), nhd, "Div") %>% +# mutate(Type_Sparrow = NA, nexus = NA) %>% +# st_compatibalize(., tmp_POIs) +# +# tmp_POIs <- data.table::rbindlist(list(tmp_POIs, +# select(div_POIs, -c(Type_Div))), fill = TRUE) %>% +# st_as_sf() %>% +# left_join(select(st_drop_geometry(div_pois_source), COMID, nat_id), by = "COMID") %>% +# mutate(Type_Sparrow = ifelse(is.na(Type_Sparrow), nat_id, Type_Sparrow)) %>% +# select(-nat_id) +# +# missing_div <- filter(div_pois_source, !nat_id %in% tmp_POIs$Type_Sparrow) +# if(nrow(missing_div) > 0){write_sf(missing_div, temp_gpkg, "missing_div")} +# +# write_sf(div_pois_source, temp_gpkg, "diversions") +# # Write out geopackage layer representing POIs for given theme +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# } else { +# # Load NID POIs if they already exist +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# } +``` + +```{r Confluence POIs} +# # Derive POIs at confluences where they are absent ---------------------- +# if(all(is.na(tmp_POIs$Type_Conf)) | !"Type_Conf" %in% colnames(tmp_POIs)) { +# +# # Navigate upstream from each POI and determine minimally-sufficient network between current POI sets +# up_net <- unique(unlist(lapply(unique(tmp_POIs$COMID), NetworkNav, nhd))) +# finalNet <- unique(NetworkConnection(up_net, st_drop_geometry(nhd))) +# +# # Subset NHDPlusV2 flowlines to navigation results and write to shapefile +# nhd <- mutate(nhd, minNet = ifelse(COMID %in% finalNet, 1, 0)) +# +# # Create new confluence POIs +# conf_COMIDs <- st_drop_geometry(filter(nhd, minNet == 1)) %>% +# # Downstream hydrosequence of 0 indicates +# # the flowline is terminating or +# # leaving the domain, so they +# # are excluded from this process +# filter(DnHydroseq > 0) %>% +# group_by(DnHydroseq) %>% +# filter(n()> 1) %>% +# mutate(Type_Conf = LevelPathI) %>% +# ungroup() %>% +# select(COMID, Type_Conf) +# +# tmp_POIs <- POI_creation2(conf_COMIDs, filter(nhd, minNet == 1), "Conf") %>% +# addType2(., tmp_POIs, "Conf", nexus = FALSE, bind = TRUE) +# +# write_sf(nhd, nav_gpkg, nhd_flowline) +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# } else { +# nhd <- read_sf(nav_gpkg, nhd_flowline) +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# } +# +# mapview(filter(tmp_POIs, !is.na(Type_Conf)), layer.nameble = "Confluence POIs", col.regions = "blue") +``` + +```{r Terminal POIs} +# # Derive or load Terminal POIs ---------------------- +# if(all(is.na(tmp_POIs$Type_Term))) { +# +# # Terminal POIs on levelpaths with upstream POIs +# term_paths <- filter(st_drop_geometry(nhd), Hydroseq %in% filter(nhd, COMID %in% tmp_POIs$COMID)$TerminalPa) +# +# # Non-POI levelpath terminal pois, but meet size criteria +# terminal_POIs <- st_drop_geometry(nhd) %>% +# filter(Hydroseq == TerminalPa | (toCOMID == 0 | is.na(toCOMID) | !toCOMID %in% COMID)) %>% +# filter(!COMID %in% term_paths$COMID, TotDASqKM >= min_da_km) %>% +# bind_rows(term_paths) %>% +# # Use level path identifier as Type ID +# select(COMID, LevelPathI) +# +# tmp_POIs <- POI_creation2(terminal_POIs, nhd, "Term") %>% +# addType2(., tmp_POIs, "Term", nexus = FALSE, bind = TRUE) +# +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# } else { +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# nhd <- read_sf(nav_gpkg, nhd_flowline) +# } +# +# mapview(filter(tmp_POIs, !is.na(Type_Term)), layer.name = "Terminal POIs", col.regions = "blue") +``` + +```{r waterbody inlet POIs} +# # Derive or load Waterbody POIs ---------------------- +# if(all(is.na(tmp_POIs$Type_WBIn))) { +# +# sparrow_inlets <- read_sf("data/sparrow/sparrow_source.gpkg", "wb_inlets") %>% +# filter(COMID %in% nhd$COMID) +# +# WBs_VPU <- filter(WBs_VPU, COMID != 666170) #1R16 +# +# wbout_COMIDs <- filter(tmp_POIs, !is.na(Type_WBOut)) +# nhd_out <- filter(nhd, COMID %in% wbout_COMIDs$COMID) +# +# # Create waterbody inlet POIs +# wbin_COMIDs <- filter(nhd, WB == 0, +# DnHydroseq %in% filter(nhd, WB == 1)$Hydroseq) %>% +# select(-WBAREACOMI) %>% +# switchDiv(., nhd) %>% +# inner_join(st_drop_geometry(filter(nhd, minNet == 1)) %>% +# select(Hydroseq, WBAREACOMI), by = c("DnHydroseq" = "Hydroseq")) %>% +# select(COMID, WBAREACOMI, minNet) %>% +# group_by(COMID) %>% +# # Ensure the inlets are on the network defined by confluence POIs +# filter(minNet == 1) %>% +# select(COMID, WBAREACOMI) +# +# # Headwater Waterbodies that may need the network extended through the inlet +# need_wbin <- st_drop_geometry(filter(WBs_VPU, source == "NHDv2WB")) %>% +# dplyr::select(COMID)%>% +# dplyr::filter(!COMID %in% wbin_COMIDs$WBAREACOMI) +# +# up_lp <- filter(nhd, LevelPathI %in% nhd_out$LevelPathI, +# WBAREACOMI %in% need_wbin$COMID) %>% +# group_by(WBAREACOMI) %>% +# filter(n() > 1, StartFlag != 1) %>% +# slice(which.min(Hydroseq)) +# +# wbin_pois <- select(nhd, COMID, DnHydroseq, LevelPathI) %>% +# inner_join(select(st_drop_geometry(up_lp), Hydroseq, WBAREACOMI, LevelPathI), +# by = c("DnHydroseq" = "Hydroseq", "LevelPathI" = "LevelPathI")) %>% +# select(COMID, WBAREACOMI) %>% +# rbind(wbin_COMIDs) +# +# tmp_POIs <- POI_creation2(st_drop_geometry(wbin_pois), nhd, "WBIn") %>% +# addType2(., tmp_POIs, "WBIn", nexus = FALSE, bind = TRUE) +# +# tmp_POIs <- tmp_POIs %>% +# left_join(select(st_drop_geometry(sparrow_inlets), WB_COMID, nat_id), +# by = c("Type_WBIn" = "WB_COMID"), multiple = "all") %>% +# mutate(Type_Sparrow = ifelse(is.na(Type_Sparrow), nat_id, Type_Sparrow)) %>% +# select(-nat_id) +# +# missing_wb_in <- filter(sparrow_inlets, !nat_id %in% tmp_POIs$Type_Sparrow | +# !WB_COMID %in% tmp_POIs$Type_WBIn) +# +# if(nrow(missing_wb_in) > 0){write_sf(missing_wb_in, temp_gpkg, "missing_wbin")} +# #tmp_POIs$nexus <- ifelse(is.na(tmp_POIs$nexus), FALSE, tmp_POIs$nexus) +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# } else { +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# nhd <- read_sf(nav_gpkg, nhd_flowline) +# } +# +# mapview(filter(tmp_POIs, !is.na(Type_WBIn)), layer.name = "Waterbody inlet POIs", col.regions = "blue") + +# mapview(filter(tmp_POIs, !is.na(Type_WBOut)), layer.name = "Waterbody outlet POIs", col.regions = "red") +``` + + +This chunk breaks up potential aggregated segments where the elevation range of the are contributing to the segment exceeds 500-m +```{r Elevation Break POIs} +# # derive incremental segments from POIs +# inc_segs <- segment_increment(filter(nhd, minNet == 1), +# filter(st_drop_geometry(nhd), +# COMID %in% tmp_POIs$COMID, COMID %in% filter(nhd, minNet == 1)$COMID)) %>% +# # bring over VAA data +# inner_join(select(atts, COMID, DnHydroseq, VA_MA, TOTMA, LENGTHKM, MAXELEVSMO, +# MINELEVSMO, WBAREACOMI, WBAreaType, FTYPE, +# AreaSqKM, TotDASqKM), by = "COMID") +# +# # Build dataframe for creation of points based on breaks +# elev_pois_split <- inc_segs %>% +# group_by(POI_ID) %>% +# # Get elevation info +# mutate(MAXELEVSMO = na_if(MAXELEVSMO, -9998), MINELEVSMO = na_if(MINELEVSMO, -9998), +# elev_diff_seg = max(MINELEVSMO) - min(MINELEVSMO)) %>% +# # Filter out to those incremental segments that need splitting above the defined elevation threshold +# filter((max(MINELEVSMO) - min(MINELEVSMO)) > (elev_diff * 100)) %>% +# # Do not aggregate on fake lfowlines +# filter(AreaSqKM > 0, TotDASqKM > max_elev_TT_DA) %>% +# # Order from upstream to downstream +# arrange(desc(Hydroseq)) %>% +# # Get attributes used for splitting +# # csum_length = cumulative length US to DS along segment, cumsum_elev = cumulative US to DS elev diff along segment +# # inc_elev = elevation range of each segment +# # iter = estimated number of times we'd need to split existing agg flowlines, or number of rows in set +# mutate(csum_length = cumsum(LENGTHKM), +# inc_elev = cumsum(MINELEVSMO - MINELEVSMO), +# #nc_elev_diff = c(inc_elev[1], (inc_elev - lag(inc_elev))[-1]), +# iter = min(round(max(inc_elev) / (elev_diff * 100)), n()), +# elev_POI_ID = NA) %>% +# # Remove segments we can't break +# filter(iter > 0, n() > 1) %>% +# # Track original iteration number +# mutate(orig_iter = iter) %>% +# ungroup() +# +# if(nrow(elev_pois_split) > 0) { +# +# # For reach iteration +# elev_POIs <- do.call("rbind", lapply(unique(elev_pois_split$POI_ID), split_elev, +# elev_pois_split, elev_diff*100, max_elev_TT_DA)) %>% +# filter(!elev_POI_ID %in% tmp_POIs$COMID, COMID == elev_POI_ID) %>% +# mutate(Type_Elev = 1) %>% +# select(COMID, Type_Elev) %>% +# unique() +# +# if(nrow(elev_POIs) > 0){ +# tmp_POIs <- POI_creation(select(elev_POIs, COMID, Type_Elev), nhd, "Elev") %>% +# addType(., tmp_POIs, "Elev") +# } +# +# +# } else { +# +# tmp_POIs$Type_Elev <- rep(NA, nrow(tmp_POIs)) +# +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# nhd <- read_sf(nav_gpkg, nhd_flowline) +# } +# +# if(!all(is.na(tmp_POIs$Type_Elev))) +# mapview(filter(tmp_POIs, Type_Elev == 1), layer.name = "Elevation break POIs", col.regions = "blue") +``` + +```{r Time of travel POIs} +# if(all(is.na(tmp_POIs$Type_Travel))) { +# +# # derive incremental segments from POIs +# inc_segs <- segment_increment(filter(nhd, minNet == 1), +# filter(st_drop_geometry(nhd), +# COMID %in% tmp_POIs$COMID, COMID %in% filter(nhd, minNet == 1)$COMID)) %>% +# # bring over VAA data +# inner_join(select(atts, COMID, DnHydroseq, VA_MA, TOTMA, LENGTHKM, MAXELEVSMO, MINELEVSMO, +# WBAREACOMI, WBAreaType, FTYPE, +# AreaSqKM, TotDASqKM), by = "COMID") +# +# # TT POIs +# tt_pois_split <- inc_segs %>% +# # Should we substitute with a very small value +# mutate(VA_MA = ifelse(VA_MA < 0, NA, VA_MA)) %>% +# mutate(FL_tt_hrs = (LENGTHKM * ft_per_km)/ VA_MA / s_per_hr ) %>% +# group_by(POI_ID) %>% +# filter(sum(FL_tt_hrs) > travt_diff, TotDASqKM > max_elev_TT_DA) %>% +# # Sort upstream to downsream +# arrange(desc(Hydroseq)) %>% +# # Get cumulative sums of median elevation +# mutate(csum_length = cumsum(LENGTHKM), +# cumsum_tt = cumsum(FL_tt_hrs), +# iter = min(round(sum(FL_tt_hrs) / travt_diff), n()), +# tt_POI_ID = NA) %>% +# # Only look to split segments based on travel time longer than 10 km +# #filter(sum(LENGTHKM) > (split_meters/1000)) %>% +# filter(iter > 0, n() > 1) %>% +# # Track original iteration number +# mutate(orig_iter = iter) %>% +# ungroup() +# +# # For reach iteration +# tt_POIs <- do.call("rbind", lapply(unique(tt_pois_split$POI_ID), split_tt, +# tt_pois_split, travt_diff, max_elev_TT_DA)) %>% +# filter(!tt_POI_ID %in% tmp_POIs$COMID, COMID == tt_POI_ID) %>% +# mutate(Type_Travel = 1) %>% +# select(COMID, Type_Travel) %>% +# unique() +# +# tmp_POIs <- POI_creation2(select(tt_POIs, COMID, Type_Travel), nhd, "Travel") %>% +# addType2(., tmp_POIs, "Travel", nexus = FALSE, bind = TRUE) +# +# write_sf(tmp_POIs, temp_gpkg, nav_poi_layer) +# }else{ +# tmp_POIs <- read_sf(temp_gpkg, nav_poi_layer) +# nhd <- read_sf(nav_gpkg, nhd_flowline) +# } +# +# mapview(filter(tmp_POIs, Type_Travel == 1), layer.name = "Travel time break POIs", col.regions = "blue") +``` + +```{r Final POIs} +# # Derive final POI set ---------------------- +# if(needs_layer(nav_gpkg, pois_all_layer)) { +# +# unCon_POIs <- filter(nhd, COMID %in% tmp_POIs$COMID, AreaSqKM == 0) %>% +# distinct() +# +# # If any POIs happened to fall on flowlines w/o catchment +# if (nrow(unCon_POIs) >0){ +# # For confluence POIs falling on Flowlines w/o catchments, derive upstream valid flowline, +# poi_fix <- DS_poiFix2(tmp_POIs, nhd %>% distinct()) +# new_POIs <- st_compatibalize(poi_fix$new_POIs, tmp_POIs) +# xWalk <- distinct(poi_fix$xWalk) +# not_matched <- distinct(poi_fix$unmatched) +# +# # POIs that didn't need to be moved +# tmp_POIs_fixed <- filter(tmp_POIs, nexus == TRUE | +# !COMID %in% c(poi_fix$xWalk$oldPOI, poi_fix$xWalk$COMID)) +# # bind together +# final_POIs <- bind_rows(tmp_POIs_fixed, select(poi_fix$new_POIs, -c(oldPOI, to_com))) +# +# # if a POI will be a nexus, it can not be terminal. +# final_POIs <- mutate(final_POIs, Type_Term = ifelse(nexus == 1, NA, Type_Term)) +# +# # Write out fixes +# write_sf(new_POIs, temp_gpkg, poi_moved_layer) +# write_sf(xWalk, temp_gpkg, poi_xwalk_layer) +# # write out final POIs +# write_sf(final_POIs, nav_gpkg, pois_all_layer) +# write_sf(not_matched, temp_gpkg, "on_zeroDA") +# } else { +# # If no fixes designate as NA +# xWalk <- NA +# +# tmp_POIs$nexus <- as.integer(tmp_POIs$nexus) +# +# # if a POI will be a nexus, it can not be terminal. +# tmp_POIs <- mutate(tmp_POIs, Type_Term = ifelse(nexus == 1, NA, Type_Term)) +# +# # write out final POIs +# write_sf(tmp_POIs, temp_gpkg, pois_all_layer) +# final_POIs <- tmp_POIs +# } +# +# } else { +# # Need all three sets for attribution below +# final_POIs <- read_sf(nav_gpkg, pois_all_layer) +# new_POIs <- if(!needs_layer(temp_gpkg, poi_moved_layer)) read_sf(temp_gpkg, poi_moved_layer) else (NA) +# xWalk <- if(!needs_layer(temp_gpkg, poi_xwalk_layer)) read_sf(temp_gpkg, poi_xwalk_layer) else (NA) +# unCon_POIs <- filter(st_drop_geometry(filter(nhd, minNet == 1)), +# COMID %in% tmp_POIs$COMID, AreaSqKM == 0) +# } +``` + +```{r Draft nsegment generation} +# if(needs_layer(temp_gpkg, nsegments_layer)) { +# +# # Sort POIs by Levelpath and Hydrosequence in upstream to downstream order +# seg_POIs <- filter(st_drop_geometry(nhd), +# COMID %in% tmp_POIs$COMID, COMID %in% filter(nhd, minNet == 1)$COMID) +# # derive incremental segments from POIs +# inc_segs <- segment_increment(filter(nhd, minNet == 1), seg_POIs) +# +# nhd_Final <- nhd %>% +# left_join(select(inc_segs, COMID, POI_ID), by = "COMID") +# +# # create and write out final dissolved segments +# nsegments_fin <- segment_creation(nhd_Final, xWalk) +# +# nhd_Final <- select(nhd_Final, -POI_ID) %>% +# left_join(select(st_drop_geometry(nsegments_fin$raw_segs), COMID, POI_ID), by = "COMID") +# nsegments <- nsegments_fin$diss_segs +# +# # Produce the minimal POIs needed to derive the network based on LP and terminal outlets +# strucFeat <- structPOIsNet(nhd_Final, final_POIs) +# nhd_Final <- nhd_Final %>% +# mutate(struct_POI = ifelse(COMID %in% strucFeat$struc_POIs$COMID, 1, 0), +# struct_Net = ifelse(COMID %in% strucFeat$structnet$COMID, 1, 0)) +# +# write_sf(nhd_Final, nav_gpkg, nhd_flowline) +# write_sf(nsegments, temp_gpkg, nsegments_layer) +# } else { +# # Read in NHDPlusV2 flowline simple features and filter by vector processing unit (VPU) +# final_POIs <- read_sf(nav_gpkg, pois_all_layer) +# nhd_Final <- read_sf(nav_gpkg, nhd_flowline) +# nsegments <- read_sf(temp_gpkg, nsegments_layer) +# } +# +# # Ensure that all the problem POIs have been taken care of +# sub <- nhd_Final %>% filter(COMID %in% final_POIs$COMID) +# print (paste0(nrow(sub[sub$AreaSqKM == 0,]), " POIs on flowlines with no local drainage contributions")) +# noDA_pois <- filter(final_POIs, COMID %in% filter(sub, AreaSqKM == 0)$COMID) +# write_sf(noDA_pois, temp_gpkg, "noDA_pois") +``` + +# Start from here next time +```{r POI Collapse} +# # number POIs +# final_POIs <- mutate(final_POIs, id = row_number(), moved = NA) +# write_sf(final_POIs, nav_gpkg, pois_all_layer) +# +# # Load data +# if(collapse){ +# +# # Move HUC12 to other POIs +# huc_to_poi <- poi_move(final_POIs, "Type_HUC12", .10, 2.5) +# move_table <- huc_to_poi$moved_points %>% +# mutate(move_cat = "HUC12 to other") +# +# # Gages to confluences +# gage_to_conf <- poi_move(huc_to_poi$final_pois, "Type_Gages", .05, 2.5, "Type_Conf") # 47 +# move_table <- gage_to_conf$moved_points %>% +# mutate(move_cat = "Gage to conf") %>% +# rbind(move_table) +# +# # Gages to waterbody inlets +# gage_to_wbin <- poi_move(gage_to_conf$final_pois, "Type_Gages", .05, 2.5, "Type_WBIn") # 2 +# move_table <- gage_to_wbin$moved_points %>% +# mutate(move_cat = "Gage to WBin") %>% +# rbind(move_table) +# +# # Gages to waterbody outlets +# gage_to_wbout <- poi_move(gage_to_wbin$final_pois, "Type_Gages", .05, 2.5, "Type_WBOut") # 6 +# move_table <- gage_to_wbout$moved_points %>% +# mutate(move_cat = "Gage to WBout") %>% +# rbind(move_table) +# +# # Streamgage to term outlet +# gage_to_term <- poi_move(gage_to_wbout$final_pois, "Type_Gages", .05, 2.5, "Type_Term") +# # NID to waterbody outlet +# nid_to_wbout <- poi_move(gage_to_wbout$final_pois, "Type_NID", .025, 1, "Type_WBOut") +# +# # Sparrow to confluence +# sparrow_to_conf <- poi_move(gage_to_wbout$final_pois, "Type_Sparrow", .05, 2.5, "Type_Conf") +# move_table <- sparrow_to_conf$moved_points %>% +# mutate(move_cat = "Sparrow to Conf") %>% +# rbind(move_table) +# +# # Sparrow to WBoutlet +# sparrow_to_wbout <- poi_move(sparrow_to_conf$final_pois, "Type_Sparrow", .05, 2.5, "Type_WBOut") +# # Sparrow to WBInlet +# sparrow_to_wbin <- poi_move(gage_to_wbout$final_pois, "Type_Sparrow", .05, 2.5, "Type_WBIn") +# +# POIs <- sparrow_to_conf$final_pois +# write_sf(POIs, nav_gpkg, final_poi_layer) +# write_sf(move_table, temp_gpkg, "pois_collapsed") +# } else { +# write_sf(final_POIs, nav_gpkg, final_poi_layer) +# POIs <- final_POIs +# } +``` + +# ```{r lookup} +# # Final POI layer +# POIs <- POIs %>% +# arrange(COMID) %>% +# mutate(identifier = row_number()) +# +# # Unique POI geometry +# final_POI_geom <- POIs %>% +# select(identifier) %>% +# cbind(st_coordinates(.)) %>% +# group_by(X, Y) %>% +# mutate(geom_id = cur_group_id()) %>% +# ungroup() +# +# final_POIs_table <- POIs %>% +# inner_join(select(st_drop_geometry(final_POI_geom), -X, -Y), by = "identifier") %>% +# select(-identifier) +# +# # POI data theme table +# pois_data_table <- reshape2::melt(st_drop_geometry(select(final_POIs_table, +# -nexus)), +# id.vars = c("COMID", "geom_id")) %>% +# filter(!is.na(value)) %>% +# group_by(COMID, geom_id) %>% +# mutate(identifier = cur_group_id()) %>% +# rename(hy_id = COMID, poi_id = identifier, hl_reference = variable, hl_link = value) %>% +# distinct() +# +# # POI Geometry table +# poi_geometry_table <- select(final_POIs_table, hy_id = COMID, geom_id) %>% +# inner_join(distinct(pois_data_table, hy_id, geom_id, poi_id), +# by = c("hy_id" = "hy_id", "geom_id" = "geom_id")) %>% +# distinct() +# +# write_sf(pois_data_table, nav_gpkg, "poi_data") +# write_sf(poi_geometry_table, nav_gpkg, "poi_geometry") +# +# # Create xwalk table +# if(needs_layer(nav_gpkg, lookup_table_refactor)) { +# full_cats <- readRDS(data_paths$fullcats_table) +# +# lookup <- dplyr::select(sf::st_drop_geometry(nhd_Final), +# NHDPlusV2_COMID = COMID, +# realized_catchmentID = COMID, +# mainstem = LevelPathI) %>% +# dplyr::mutate(realized_catchmentID = ifelse(realized_catchmentID %in% full_cats$FEATUREID, +# realized_catchmentID, NA)) %>% +# left_join(select(st_drop_geometry(poi_geometry_table), hy_id, poi_geom_id = geom_id), +# by = c("NHDPlusV2_COMID" = "hy_id")) +# +# sf::write_sf(lookup, nav_gpkg, lookup_table_refactor) +# } +# +# ``` diff --git a/workspace/06-2_aggregate_cats.Rmd b/workspace/06-2_aggregate_cats.Rmd index ba68264..1b1584c 100644 --- a/workspace/06-2_aggregate_cats.Rmd +++ b/workspace/06-2_aggregate_cats.Rmd @@ -44,15 +44,20 @@ outlets_POI <- read_sf(out_refac_gpkg, outlets_layer) %>% POIs_data <- read_sf(nav_gpkg, poi_data_table) # reconciled have no ID applied in refactoring flowlines -reconciled <- st_transform(read_sf(out_refac_gpkg, reconciled_layer), crs) +reconciled <- st_transform(read_sf(out_refac_gpkg, reconciled_layer), crs) +refactored <- st_drop_geometry(read_sf(out_refac_gpkg, refactored_layer)) %>% + select(COMID, Hydroseq) %>% + mutate(COMID = as.integer(COMID)) + divides <- st_transform(read_sf(out_refac_gpkg, divide_layer), crs) lookup <- read_sf(out_refac_gpkg, lookup_table_refactor) %>% inner_join(select(st_drop_geometry(nhd), COMID, TotDASqKM), by = c("NHDPlusV2_COMID" = "COMID")) highest_DA <- lookup %>% + inner_join(refactored, by = c("NHDPlusV2_COMID" = "COMID")) %>% group_by(reconciled_ID) %>% - filter(TotDASqKM == max(TotDASqKM)) + filter(Hydroseq == min(Hydroseq)) ``` ```{r agg_catchments I} @@ -79,12 +84,14 @@ if(needs_layer(out_agg_gpkg, agg_cats_layer)){ type = rep("terminal", length(missing_outlets)))) write_sf(filter(reconciled, ID %in% missing_outlets), out_agg_gpkg, "missing_outlets") - outlets <- outlets %>% - left_join(select(st_drop_geometry(reconciled), ID, toID), by = "ID") %>% - mutate(type = ifelse(type == "terminal" & !is.na(toID), "outlet", type)) %>% - select(-toID) } + outlets <- outlets %>% + left_join(select(st_drop_geometry(reconciled), ID, toID), by = "ID") %>% + mutate(type = ifelse(is.na(toID), "terminal", "outlet")) %>% + mutate(type = ifelse(type == "terminal" & !is.na(toID), "outlet", type)) %>% + select(-toID) + outlets <- unique(outlets) agg_cats <- aggregate_catchments(flowpath = reconciled, divide = divides, -- GitLab