A watershed (catchment basin or drainage divide) is an area of land where all precipitation drains downhill into a common stream, river, lake, or oceanic outlet. Automated watershed delineation from Digital Elevation Models is a foundational workflow in civil hydrology, flood hazard assessment, dam construction, and water resources management. Hydrological modeling relies on the physical law of gravity: water flows along the steepest downward gradient. In this comprehensive masterclass, we execute the full D8 hydrological modeling sequence in QGIS using SAGA and GRASS processing tools.
š Prerequisites
- QGIS 3.34+ with SAGA and GRASS GIS toolboxes enabled.
- Hydrologically sound high-resolution DEM (30m SRTM or 12.5m ALOS) in a metric UTM projection.
- Defined pour point coordinates (stream gauge or proposed dam location).
š ļø Technical Environment
Required Software: QGIS / SAGA GIS / GRASS GIS (Recommended: QGIS 3.34 LTR)
Practice Dataset: Hydrologically Conditioned SRTM 30m DEM Tile
Source Portal: HydroSHEDS / USGS
CRS / Format: Projected UTM CRS (GeoTIFF)
š Conceptual Technical Diagram: D8 Hydrological Flow Direction Routing Matrix
The deterministic 8-direction (D8) algorithm directing runoff from the center cell to the steepest descent neighbor.
Step-by-Step Workflow & Methodological Execution
Module 1: Hydrological Pre-Processing & Sink Filling
Raw digital elevation models inevitably contain artificial depressions, pits, and sinks caused by satellite radar speckle, interpolation artifacts, or sensor errors. If left uncorrected, virtual water will flow into these pits and stop, breaking the downstream flow network: 1. Open Processing Toolbox -> SAGA -> Terrain Analysis - Hydrology -> Fill Sinks (Wang & Liu). 2. Set Input: Select your metric DEM. 3. Minimum Slope: Keep default (0.01 degrees) to maintain a subtle gradient across flat lakebeds. 4. Output: Generates a 'Filled DEM' where every internal depression is filled up to its spill rim, guaranteeing continuous downhill hydrological routing to the map boundaries.
Module 2: Flow Direction (D8) and Flow Accumulation
1. Flow Direction (SAGA -> Flow Accumulation (Top-Down) or GRASS `r.watershed`): ⢠Analyzes each cell and its 8 immediate neighbors. Water is assumed to flow in the direction of the steepest downward slope. ⢠The D8 model assigns an integer code (1, 2, 4, 8, 16, 32, 64, 128) representing the 8 compass cardinal and intercardinal directions. 2. Flow Accumulation: ⢠Calculates the total number of upstream cells that drain into each individual focal cell. ⢠Cells with a flow accumulation of 0 represent mountain ridge lines and drainage divides. Cells with very high values (e.g., > 10,000 cells) represent permanent rivers and primary drainage channels.
Module 3: Channel Extraction, Pour Point Snapping & Basin Delineation
1. Extract Stream Network: Use the Raster Calculator to threshold flow accumulation: `"flow_acc" > 1000`. This isolates all drainage channels draining at least 1,000 upstream pixels. 2. Snap Pour Points: Create a point vector representing your study outlet (e.g., water quality station). Use GRASS `r.water.outlet` or SAGA 'Upslope Area'. Crucial step: Snap your point exactly onto the high-accumulation stream line; placing it just one pixel off on a dry slope delineates a tiny micro-basin! 3. Delineate Basin: Execute the Upslope Area tool. The algorithm traces upstream flow paths from your pour point until it encounters the regional drainage divide, outputting the exact polygon boundary of the contributing watershed.
ā ļø Common Errors & Troubleshooting
ā Flow accumulation grid shows discontinuous streams with abrupt ends
š” Resolution: You skipped the 'Fill Sinks' step! Spurious digital pits trap simulated water; always run Wang & Liu sink filling first.
ā Delineated watershed covers only 1 or 2 pixels
š” Resolution: Your pour point (outlet coordinates) is not positioned directly on the high-accumulation stream line; snap pour point to stream raster!
š” Expert Tips & Best Practices
- Choose flow accumulation threshold carefully: a lower threshold (e.g. 500 cells) extracts dense headwater streams, while a higher threshold (e.g. 5000 cells) extracts major rivers only.
- Convert stream raster to vector using 'r.to.vect' in GRASS for network routing calculations.
š Python PySheds Automated Watershed Delineation
from pysheds.grid import Grid
import numpy as np
# Initialize PySheds spatial grid from DEM
grid = Grid.from_raster("elevation_filled.tif")
dem = grid.read_raster("elevation_filled.tif")
# 1. Resolve Flow Direction using D8 algorithm
fdir = grid.flowdir(dem)
# 2. Compute Flow Accumulation (Upstream Contributing Area)
acc = grid.accumulation(fdir)
# 3. Define catchment pour point coordinates (X, Y in UTM)
x_pour, y_pour = 772450.0, 3167820.0
# Snap pour point to highest accumulation cell within 5-pixel window
x_snap, y_snap = grid.snap_to_mask(acc > 1000, (x_pour, y_pour))
# 4. Delineate upstream catchment basin
catchment = grid.catchment(x=x_snap, y=y_snap, fdir=fdir, xytype='coordinate')
# Clip and polygonize catchment boundary
grid.clip_to(catchment)
shapes = grid.polygonize()
# Export catchment boundary as GeoJSON
import geopandas as gpd
basin_gdf = gpd.GeoDataFrame.from_features(shapes, crs="EPSG:32643")
basin_gdf.to_file("delineated_watershed.geojson", driver="GeoJSON")
print(f"Watershed Area: {basin_gdf.geometry.area.sum() / 1e6:.2f} sq km")