Water Module

Water body detection from elevation data using slope analysis.

This module identifies water bodies by detecting flat surfaces (low slope) in DEM data. Water is characterized by near-zero slope, while terrain typically has higher slopes.

Water Detection

src.terrain.water.identify_water_by_slope(dem_data, slope_threshold=0.1, fill_holes=True)[source]

Identify water bodies by detecting flat areas (low slope).

Water bodies typically have very flat surfaces with near-zero slope. This function calculates local slope using Horn’s method and identifies pixels below the threshold as potential water. Optionally applies morphological operations to fill small gaps and smooth the water mask.

Parameters:
  • dem_data (np.ndarray) – Digital elevation model as 2D array (height values)

  • slope_threshold (float) – Maximum slope magnitude to classify as water. Default: 0.1 (very flat surfaces) Typical range: 0.05 to 0.5 depending on DEM resolution Values are gradient magnitude from Horn’s method

  • fill_holes (bool) – Apply morphological operations to fill small gaps in water mask and smooth boundaries. Default: True

Returns:

Boolean mask (dtype=bool) where True = water, False = land.

Same shape as dem_data.

Return type:

np.ndarray

Raises:

ValueError – If dem_data is not 2D or slope_threshold is negative

Examples

>>> dem = np.array([[100, 100, 110], [100, 100, 110], [110, 110, 120]])
>>> water_mask = identify_water_by_slope(dem, slope_threshold=0.1)
>>> water_mask.dtype
dtype('bool')
>>> water_mask.shape
(3, 3)

Identify water bodies by detecting flat areas in DEM. Used in Combined Render: Full-Featured Example for lake/river detection.

Example:

from src.terrain.water import identify_water_by_slope

# Detect water in DEM
water_mask = identify_water_by_slope(
    dem_data,
    slope_threshold=0.1,  # Flatter than 0.1 = water
    fill_holes=True       # Smooth boundaries
)

# Use mask to color water blue
colors[water_mask] = [0.02, 0.13, 0.25]  # Michigan blue

How it works:

  1. Calculate slope magnitude using Horn’s method (Sobel operators)

  2. Classify pixels below threshold as water

  3. Apply morphological operations to fill gaps and smooth boundaries

Typical slope thresholds:

  • 0.05: Very strict, only extremely flat surfaces

  • 0.1: Default, good for most DEMs

  • 0.2-0.5: More permissive, captures wetlands and floodplains

Slope threshold depends on DEM resolution:

  • High-res DEM (1-10m): Use lower threshold (0.05-0.1)

  • Low-res DEM (30m+): Use higher threshold (0.1-0.3)

Internal Functions

src.terrain.water._calculate_slope(dem_data)[source]

Calculate slope magnitude using Horn’s method (GPU-accelerated).

Uses Horn’s method with proper convolution kernels for more accurate slope computation on downsampled DEM data. This is more robust than Sobel for terrain slope analysis.

Uses PyTorch GPU acceleration when available (7x speedup on CUDA).

Parameters:

dem_data (np.ndarray) – 2D elevation data

Returns:

Slope magnitude (gradient magnitude), same shape as input

Return type:

np.ndarray

Calculate slope magnitude using Sobel operators (Horn’s method).

src.terrain.water._smooth_water_mask(water_mask, structure_size=3)[source]

Smooth water mask using morphological operations.

Applies closing (dilation then erosion) to fill small holes within water bodies and smooth boundaries. Preserves water regions while removing noise.

Parameters:
  • water_mask (np.ndarray) – Boolean water mask

  • structure_size (int) – Size of morphological structuring element

Returns:

Smoothed boolean water mask

Return type:

np.ndarray

Apply morphological operations to smooth water mask.