Skip to main content
skill CX Codex

terrain-hydrology — Claude Code skill: what it does, how to install

Configures elevation surface analysis, viewsheds, and hydrologic modeling from DTMs and DSMs.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add muend/geoai-skills --skill terrain-hydrology -a claude-code
Open on GitHub

What terrain-hydrology does

The skill enforces a strict verification workflow for elevation rasters before running flow or visibility models. It insists on checking coordinate systems: running slope calculations on an unprojected EPSG:4326 DEM without z-factor corrections corrupts derivative values roughly a hundredfold.

Under the hood, it guides hydrological conditioning using tools such as WhiteboxTools, pysheds, richdem, GDAL, and GRASS. The workflow prioritizes least-cost depression breaching before filling pits, applies D8 or MFD flow routing, and snaps pour points to high-accumulation cells to prevent tiny broken watersheds.

For viewshed studies, the skill dictates using a surface model with obstacles (DSM) rather than bare earth, while factoring in target heights and earth curvature. Omitting depression breaching over road culverts leads directly to artificial flat lakes and bogus river channels.

What it helps with

  • verify DEM projection and vertical units before analysis
  • condition terrain rasters using depression breaching and filling
  • delineate stream networks and watersheds with pour-point snapping
  • calculate slope, aspect, curvature, and topographic indices
  • generate viewsheds accounting for observer heights and refraction

Example prompts for the agent

  • Inspect dem.tif, reproject to a local projected CRS, and compute slope in degrees
  • Condition this elevation raster using WhiteboxTools and delineate the catchment
  • Calculate a viewshed from a 30m tower point taking earth curvature into account

How to install terrain-hydrology

1Skills CLI (Vercel)

npx skills add muend/geoai-skills --skill terrain-hydrology -a claude-code

2Manually: put the files in place

~/.claude/skills/terrain-hydrology/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/terrain-hydrology/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about terrain-hydrology

How to install terrain-hydrology in Claude Code?

Run npx skills add muend/geoai-skills --skill terrain-hydrology -a claude-code in your terminal.

What does terrain-hydrology do?

It guides the agent through terrain derivatives, viewshed modeling, and hydrologic conditioning, guarding against unprojected coordinate mismatches and broken stream delineations.

Why should depressions be breached before filling?

Standard pit filling dams water behind road embankments, creating massive artificial sinks. Breaching cuts through culverts and keeps natural drainage pathways intact.

Source text

SKILL.md · MIT
---
name: terrain-hydrology
description: >-
  Always invoke for terrain, drainage, viewshed, or visibility analysis from
  elevation, even before the DEM or correct surface is chosen. Covers
  DTM-versus-DSM selection, slope, aspect, curvature, hillshade, conditioning,
  flow direction/accumulation, streams, watersheds, and catchments. Use
  point-cloud-lidar first only when an elevation surface must be created from
  LiDAR or photogrammetric points.
license: MIT
metadata:
  author: Muhammed Enes Duran
---

# Terrain & Hydrology

Purpose: terrain products whose numbers are physically meaningful. The two
recurring failure modes: **unit mismatch** (degree coordinates with meter
elevations silently corrupts every derivative) and **unconditioned DEMs**
(flow routed into spurious pits produces fragmented, fictional streams).

## DEM hygiene first

| Check | Rule |
|---|---|
| Surface type | **DTM** (bare earth) for hydrology/slope; **DSM** (with canopy/buildings) for viewshed/solar. Using a DSM for watersheds routes rivers over treetops. |
| Source | Copernicus GLO-30 > SRTM for most global work; national LiDAR DTMs when available (see `point-cloud-lidar` to make your own). Record source + acquisition date. |
| Nodata | Identify the nodata value (-9999, -32768, 3.4e38) and mask it — never let it enter statistics or fill algorithms as "very deep hole". |
| Voids | Fill data voids (interpolation from edges) BEFORE hydrological conditioning; document filled areas. |
| **CRS + units** | Reproject to a projected CRS so horizontal units = vertical units (meters). Slope from a 4326 DEM without z-factor correction is the classic silent error. If staying geographic, apply a latitude-dependent z-factor — better: don't. |

## Derivatives

```python
import whitebox
wbt = whitebox.WhiteboxTools()
wbt.slope("dem.tif", "slope_deg.tif", units="degrees")
wbt.aspect("dem.tif", "aspect_deg.tif")
wbt.plan_curvature("dem.tif", "plan_curv.tif")
```

- Slope: state units (degrees vs percent — 45° = 100%); Horn's method
  (3×3) is the standard; steeper terrain → consider resolution effects
  (slope flattens as cell size grows — report cell size with every slope
  statistic).
- Aspect: circular variable — never average it arithmetically; use vector
  (sin/cos) averaging; flat cells have undefined aspect (mask, don't zero).
- Curvature: plan (flow convergence) vs profile (flow acceleration) —
  pick per question.
- Hillshade is for cartography (see `cartography-geoviz`), never analysis
  input.
- Ruggedness/position: TRI, TPI (radius-dependent — report the radius),
  geomorphons for landform classification.

## Hydrological conditioning — order matters

```
voids filled → breach depressions (preferred) → fill remaining pits
→ flow direction → flow accumulation → streams → watersheds
```

- **Breaching before filling** (WhiteboxTools
  `BreachDepressionsLeastCost`): carves through barriers (road embankments
  over culverts) instead of flooding upstream areas flat. Pure fill on
  flat/embanked terrain creates large artificial lakes with arbitrary flow
  paths.
- Real depressions exist (karst, prairie potholes, reservoirs). If the
  landscape genuinely holds water, don't condition it away — model with
  explicit sink handling and say so.
- Flow direction: **D8** for stream networks/watersheds (discrete,
  standard); **D-infinity/MFD** for dispersal quantities (wetness index,
  erosion) on hillslopes.

## Streams and watersheds

- Stream extraction threshold (min. accumulation) is a MODELING choice:
  derive from a mapped reference network (match total stream length) or
  report the threshold and show two alternatives — never present one
  threshold's network as "the" rivers.
- **Pour point snapping**: outlet coordinates rarely fall on the modeled
  stream cell. Snap to the highest-accumulation cell within a search
  radius (`wbt.jenson_snap_pour_points`) — an unsnapped pour point yields
  a tiny, wrong watershed silently.
- Verify delineation: watershed area vs authoritative basin data (±5-10%),
  and the modeled network overlaid on imagery/topo maps at 3 locations.
- Wetness index (TWI), stream power (SPA): compute from conditioned DEM +
  MFD accumulation; they are relative indices — don't read absolute
  thresholds across regions.

## Viewshed

- Use a **DSM** (or DTM + feature heights) — bare-earth viewsheds
  overstate visibility wherever trees/buildings exist; state which surface
  was used.
- Set observer height (~1.7 m person, tower height for infrastructure) and
  target height explicitly; defaults differ across tools.
- Account for earth curvature + refraction beyond ~5 km
  (`wbt.viewshed` handles it; verify the flag).
- Deliver binary visible/not plus the observer point(s) and parameters in
  the metadata; for siting problems, cumulative viewsheds from candidate
  sets feed `mcda-suitability-analysis`.

## Tooling

WhiteboxTools (conditioning, full hydrology suite, fast) · `pysheds`
(lightweight Python watersheds) · `richdem` (derivatives) · GDAL
(`gdaldem`) for quick slope/hillshade · GRASS (`r.watershed`) for very
large DEMs (no explicit fill needed — least-cost routing).

## Verification protocol

1. Derivative histograms: slope > 60° over large areas or negative
   accumulation = unit/nodata bug.
2. Stream network overlay on imagery at 3 locations, including one flat
   area (where artifacts concentrate).
3. Watershed area cross-check vs authoritative basin polygons.
4. Report: DEM source/date/resolution, conditioning method, flow
   algorithm, stream threshold, all in the deliverable.

## Pitfalls checklist

- Slope from a geographic-CRS DEM without z-factor (values ~100× off).
- DSM used for watershed delineation (rivers over treetops).
- Fill-only conditioning across road embankments → phantom lakes.
- Unsnapped pour point → 3-cell "watershed".
- Arithmetic mean of aspect (350° and 10° average to south, not north).
- Nodata treated as elevation in fill/statistics.
- One arbitrary stream threshold presented as the drainage network.

## Execution contract

- **Workflow:** inspect DEM source, CRS, vertical units, datum, resolution, and nodata; condition terrain; derive gradients and flow; delineate products; test thresholds; validate against imagery and controls.
- **Decision rules:** use terrain workflows on raster elevation products, point-cloud workflows before DEM generation, and choose conditioning and flow algorithms from landscape and scale.
- **Verification protocol:** inspect derivative distributions, hillshade artifacts, stream overlays, watershed area, pour-point snapping, threshold sensitivity, and elevation-control residuals.
- **Failure modes:** reject products from DSM misuse, geographic-unit slope, vertical datum mismatch, unconditioned barriers, nodata contamination, unsnapped outlets, or resolution unsupported by source data.
- **Deliverables:** conditioned DEM, derivatives and hydrologic products, parameter and threshold record, CRS and vertical datum, QA maps, validation metrics, and limitations.
- **Source freshness:** consult [the authoritative source registry](references/authoritative-sources.md) before applying tool algorithms or product rules and record the checked date.

© Muhammed Enes Duran · MIT · muend/geoai-skills

Similar skills

All skills for Data and databases →

From the same set18

swe-devops-standards This skill guides agents through geospatial and GeoAI code reviews, testing, dependency management, and delivery. Use it when code or repository changes are in scope. CX Codex +1 ★ 35repo stars spatial-statistics A skill that pushes your agent through spatial statistics: clustering, hot spots, dependence, and the diagnostics a regression needs afterwards. CX Codex +1 ★ 35repo stars remote-sensing-analysis Harmonizes satellite and aerial imagery across processing levels, builds STAC pipelines, and handles cloud masking or spectral indices before running analysis. CX Codex +1 ★ 35repo stars postgis-spatial-sql This skill guides spatial SQL backend choices and query design across PostGIS and DuckDB Spatial. Use it to inspect SRIDs, spatial indexes, joins, and query plans. CX Codex +1 ★ 35repo stars point-cloud-lidar A skill for LAS, LAZ and COPC data: ground classification, DTM/DSM/CHM surfaces, canopy and building metrics, vertical datums. Useful when the input is a raw cloud. CX Codex +1 ★ 35repo stars network-accessibility-analysis Replaces straight-line buffers with true network travel costs across walking, transit, and driving modes. Builds isochrones and origin-destination matrices. CX Codex +1 ★ 35repo stars movement-trajectory This skill guides GPS/GNSS track cleaning, stop and trip detection, road matching, and flow aggregation. Use it when you need to turn timestamped locations into movement analysis. CX Codex +1 ★ 35repo stars ml-experiment-standards Makes the agent audit leakage, pick splits and justify metrics before a model gets trained. Useful when a result has to replicate, not just look good. CX Codex +1 ★ 35repo stars

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor