terrain-hydrology — Claude Code skill: what it does, how to install
Configures elevation surface analysis, viewsheds, and hydrologic modeling from DTMs and DSMs.
npx skills add muend/geoai-skills --skill terrain-hydrology -a claude-codeWhat 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-code2Manually: put the files in place
~/.claude/skills/terrain-hydrology/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/terrain-hydrology/
1Skills CLI (Vercel)
npx skills add muend/geoai-skills --skill terrain-hydrology -a codex2Manually: put the files in place
.agents/skills/terrain-hydrology/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add muend/geoai-skills --skill terrain-hydrology -a cursor2Manually: put the files in place
.cursor/skills/terrain-hydrology/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install muend/geoai-skills terrain-hydrology2Manually: put the files in place
.github/skills/terrain-hydrology/SKILL.md1Skills CLI (Vercel)
npx skills add muend/geoai-skills --skill terrain-hydrology -a gemini-cli2Platform CLI
gemini skills install https://github.com/muend/geoai-skills --path skills/terrain-hydrologyManually: put the files in place
.devin/skills/terrain-hydrology/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add muend/geoai-skills --skill terrain-hydrology -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
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