-
Notifications
You must be signed in to change notification settings - Fork 33
[5pt] Incorporate roads into FIM #1543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AliForghani-NOAA
wants to merge
29
commits into
dev
Choose a base branch
from
dev-roads-fimpact
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
19 tasks
ZahraGhahremani
previously approved these changes
Jul 9, 2025
RobHanna-NOAA
previously approved these changes
Jul 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only tested the pull_osm_roads early on. Sounds like we are all good on all fronts.
9ab6e7d
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR addresses the issue #1385 and includes the following enhancements:
Ingests OSM roads as a new input data for FIM.
Derives the threshold discharge required for a road inundation. To achieve higher spatial resolution, each road segment is further split at HydroID boundaries, and the minimum non-zero HAND value within each segment is extracted as the inundation threshold stage. The corresponding threshold discharge values are then interpolated from the HydroTables using these threshold stages.
Develops a new tool to identify inundated roads for a given flood event and report the maximum flood depth for each road segment.
Note that pulling OSM data requires a new Python package called
overpy
. The updated pre-clipped dataset with new osm roads data has been prepared here:inputs/pre_clip_huc8/20250606/
.In-Depth Workflow Explanation
The workflow required developing three new scripts and a major update to
src/aggregate_by_huc.py
.data/roads/pull_osm_roads.py
(new script)This script downloads OSM road data. OSM data is structured using key-value pairs; for roads, the key we use is
highway
. In this script, we focus on five major road types (i.e., osm values):motorway
,trunk
,primary
,secondary
, andtertiary
. For more details, see the OSM road tag documentation.Because OSM roads can be very long (e.g., >10 km), the script splits them using NWM catchment boundaries (found in
data/inputs/pre_clip_huc8
) to generate more localized and accurate FIMpact results. Each resulting road segment is assigned a new ID in the formatosmid_catchmentid
and is used as the input road dataset for the FIM pipeline. The updated pre-clipped dataset with new osm roads data has been prepared here:inputs/pre_clip_huc8/20250606/
src/process_roads_fimpact.py
(new script)This script is run for each branch of an HUC using three inputs:
HAND-generated HydroIDs offer additional spatial resolution, as a single road segment may intersect multiple HydroIDs (each identified by a unique
feature_id
). To account for this, the script splits road segments at HydroID boundaries and calculates the minimum HAND value (excluding zeros) within each segment to serve as the inundation threshold.We use
rasterstats.zonal_stats()
to extract HAND values; however, this function can return incorrect results when the input lines are jagged—often caused by overlaying roads with catchment polygons. To mitigate this, we first explode all multi-part geometries to ensure each segment is a singleLineString
. After running the zonal statistics, we group byosmid_catchid
andHydroID
, retaining only the segment with the minimum threshold HAND value within each HydroID to eliminate redundant exploded segments.Three new columns are added to the road dataset:
threshold_hand
,HydroID
, andfeature_id
. The results are saved asosm_roads_fimpact_***.csv
for each branch, where***
represents the branch number. Each CSV file contains one record perosmid_catchid
within eachHydroID
, providing the minimum HAND value for that combination.src/aggregate_by_huc.py
(updated script)For each branch, the script retrieves the discharge value corresponding to each
threshold_hand
from the branch’s HydroTable (per HydroID) and assigns it asthreshold_discharge
. Any record with athreshold_hand
value greater than 25m (the maximum stage listed in the HydroTables) is removed entirely. The outputs from all branches are combined into a single file:osm_roads_fimpact.csv
.tools/road_inundation.py
(new script)This tool takes two inputs:
osm_roads_fimpact.csv
file), andThe script identifies road segments where the given flow (referred to as
evaluated_discharge
) exceeds thethreshold discharge
and flags them as inundated. It also looks up the stage corresponding to theevaluated_discharge
(and call itevaluated_stage
) and subtracts theevaluated_stage
from thethreshold_hand
value to calculate theflood_depth
.Records with negative flood depth are currently removed, as these may result from non-monotonic synthetic rating curves—most commonly observed in branch zero.
Note that a single road segment may have multiple inundation records, originating from different branches or intersecting multiple HydroIDs. The code retains only the record with the maximum flood depth for each road segment.
The figure below displays the output of the new tool, with inundated roads (with their flood depth) and non-inundated roads (black) overlaid on a FIM raster. Both results were generated from a common 50-year recurrence interval flow file for HUC 11070103.
Additions
Changes
src/process_roads_fimpact.py
scriptTesting
The new Docker image with the new
overpy
Python package was tested successfully ondata/roads/pull_osm_roads.py
to retrieve OSM road data for both CONUS and Alaska.The road FIMpact functionality has been successfully tested on three HUCs ( 05030104, 11070103, and 12030203).
Deployment Plan (For developer use)
How does the changes affect the product?
Issuer Checklist (For developer use)
You may update this checklist before and/or after creating the PR. If you're unsure about any of them, please ask, we're here to help! These items are what we are going to look for before merging your code.
[_pt] PR: <description>
dev
branch (the default branch), you have a descriptive Feature Branch name using the format:dev-<description-of-change>
(e.g.dev-revise-levee-masking
)dev
branchpre-commit
hooks were run locally4.x.x.x
Merge Checklist (For Technical Lead use only)