Hydrology & watersheds
Where water goes on a DEM: conditioning, flow direction and accumulation, watersheds, stream networks and HAND.
Everything here starts from one assumption: water flows downhill, and every cell in the DEM has somewhere to send it. Real elevation data does not satisfy that. Sinks, flat areas and one-cell pits — most of them artefacts of the interpolation that built the DEM rather than features of the landscape — leave cells with no downhill neighbour, and a flow path that reaches one simply stops.
So conditioning comes first and is not optional: fill or breach the depressions, resolve the flats, then compute flow direction and accumulation. From there, watersheds, stream networks, stream order and HAND all fall out of the same two rasters. The threshold you pick for "this is a stream" decides the entire network, including its Strahler order.
The concepts explain what each raster means and where its assumptions bite; the how-to guides run the sequence; and the fixes cover the catchments and networks that come out wrong.
🧭 Start with the concepts
The ideas the how-to guides below assume you already have.
- DEM Hydrology Explained: From Elevation to Where Water Goes
- Flow Direction Explained: D8, D-Infinity and MFD Compared
- Pour Points Explained: Why Watershed Delineation Needs a Snapped Outlet
- Stream Order Explained: Strahler, Shreve and What They Measure
- How DEM Resolution and Source Change a Drainage Network
- Height Above Nearest Drainage Explained: A Quick Flood Proxy
Show every concept in this topic
⚙️ Then do the task
Step-by-step walkthroughs with code you can copy and adapt.
- How to Condition a DEM for Hydrology: Breaching or Filling
- How to Calculate Flow Accumulation from a DEM in Python
- How to Delineate a Watershed from a Pour Point in Python
- How to Extract a Stream Network from a DEM
- How to Calculate Strahler Stream Order in Python
- How to Split a Catchment into Sub-basins at Many Outlets
Show every how-to guide in this topic
- How to Summarise Catchment Attributes: Area, Slope and Land Cover
- How to Calculate Height Above Nearest Drainage (HAND) in Python
- How to Burn a Known River Network into a DEM
- How to map floods from Sentinel-1 in Python
- How to fit return periods to annual maxima in Python
- How to Find Snowmelt Timing from Stations and Satellites in Python
- How to Measure Impervious Surface by Watershed in Python
- How to Measure Land Cover Along Streams in Python
- How to Get Rivers and Water Bodies From OpenStreetMap in Python
🔧 When it breaks
The errors this topic produces, with the cause explained rather than just the command.
- Fixing a Watershed That Comes Out as a Few Pixels
- Fixing Streams That Run in Straight Parallel Lines Across Flat Ground
- Fixing Flow Accumulation That Is All Zeros, NoData or Stops at the Edge
- Fixing Streams That Stop at Roads, Bridges and Embankments
- Fixing Catchment Areas That Are Wrong on a Latitude–Longitude DEM
- A SAR flood map shows water where there is none
Learning paths through this topic
A curated route rather than a list — the guides in the order that builds on itself.
Related topics
Subjects that keep coming up alongside this one, most overlap first.