{"id":16798,"plugin_id":"plugins_6a68c8b958b88191b2bfeae31847c8da","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:13:47.241Z","digest":"be06b30e474eda06723127e1cb9c46b66fd52e67e1e2544deeaac54601d8699d","against":null,"payload":{"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.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":213},{"relative_path":"references/authoritative-sources.md","size_in_bytes":784}],"skill_md_contents":"---\nname: terrain-hydrology\ndescription: >-\n  Always invoke for terrain, drainage, viewshed, or visibility analysis from\n  elevation, even before the DEM or correct surface is chosen. Covers\n  DTM-versus-DSM selection, slope, aspect, curvature, hillshade, conditioning,\n  flow direction/accumulation, streams, watersheds, and catchments. Use\n  point-cloud-lidar first only when an elevation surface must be created from\n  LiDAR or photogrammetric points.\nlicense: MIT\nmetadata:\n  author: Muhammed Enes Duran\n---\n\n# Terrain & Hydrology\n\nPurpose: terrain products whose numbers are physically meaningful. The two\nrecurring failure modes: **unit mismatch** (degree coordinates with meter\nelevations silently corrupts every derivative) and **unconditioned DEMs**\n(flow routed into spurious pits produces fragmented, fictional streams).\n\n## DEM hygiene first\n\n| Check | Rule |\n|---|---|\n| Surface type | **DTM** (bare earth) for hydrology/slope; **DSM** (with canopy/buildings) for viewshed/solar. Using a DSM for watersheds routes rivers over treetops. |\n| 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. |\n| Nodata | Identify the nodata value (-9999, -32768, 3.4e38) and mask it — never let it enter statistics or fill algorithms as \"very deep hole\". |\n| Voids | Fill data voids (interpolation from edges) BEFORE hydrological conditioning; document filled areas. |\n| **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. |\n\n## Derivatives\n\n```python\nimport whitebox\nwbt = whitebox.WhiteboxTools()\nwbt.slope(\"dem.tif\", \"slope_deg.tif\", units=\"degrees\")\nwbt.aspect(\"dem.tif\", \"aspect_deg.tif\")\nwbt.plan_curvature(\"dem.tif\", \"plan_curv.tif\")\n```\n\n- Slope: state units (degrees vs percent — 45° = 100%); Horn's method\n  (3×3) is the standard; steeper terrain → consider resolution effects\n  (slope flattens as cell size grows — report cell size with every slope\n  statistic).\n- Aspect: circular variable — never average it arithmetically; use vector\n  (sin/cos) averaging; flat cells have undefined aspect (mask, don't zero).\n- Curvature: plan (flow convergence) vs profile (flow acceleration) —\n  pick per question.\n- Hillshade is for cartography (see `cartography-geoviz`), never analysis\n  input.\n- Ruggedness/position: TRI, TPI (radius-dependent — report the radius),\n  geomorphons for landform classification.\n\n## Hydrological conditioning — order matters\n\n```\nvoids filled → breach depressions (preferred) → fill remaining pits\n→ flow direction → flow accumulation → streams → watersheds\n```\n\n- **Breaching before filling** (WhiteboxTools\n  `BreachDepressionsLeastCost`): carves through barriers (road embankments\n  over culverts) instead of flooding upstream areas flat. Pure fill on\n  flat/embanked terrain creates large artificial lakes with arbitrary flow\n  paths.\n- Real depressions exist (karst, prairie potholes, reservoirs). If the\n  landscape genuinely holds water, don't condition it away — model with\n  explicit sink handling and say so.\n- Flow direction: **D8** for stream networks/watersheds (discrete,\n  standard); **D-infinity/MFD** for dispersal quantities (wetness index,\n  erosion) on hillslopes.\n\n## Streams and watersheds\n\n- Stream extraction threshold (min. accumulation) is a MODELING choice:\n  derive from a mapped reference network (match total stream length) or\n  report the threshold and show two alternatives — never present one\n  threshold's network as \"the\" rivers.\n- **Pour point snapping**: outlet coordinates rarely fall on the modeled\n  stream cell. Snap to the highest-accumulation cell within a search\n  radius (`wbt.jenson_snap_pour_points`) — an unsnapped pour point yields\n  a tiny, wrong watershed silently.\n- Verify delineation: watershed area vs authoritative basin data (±5-10%),\n  and the modeled network overlaid on imagery/topo maps at 3 locations.\n- Wetness index (TWI), stream power (SPA): compute from conditioned DEM +\n  MFD accumulation; they are relative indices — don't read absolute\n  thresholds across regions.\n\n## Viewshed\n\n- Use a **DSM** (or DTM + feature heights) — bare-earth viewsheds\n  overstate visibility wherever trees/buildings exist; state which surface\n  was used.\n- Set observer height (~1.7 m person, tower height for infrastructure) and\n  target height explicitly; defaults differ across tools.\n- Account for earth curvature + refraction beyond ~5 km\n  (`wbt.viewshed` handles it; verify the flag).\n- Deliver binary visible/not plus the observer point(s) and parameters in\n  the metadata; for siting problems, cumulative viewsheds from candidate\n  sets feed `mcda-suitability-analysis`.\n\n## Tooling\n\nWhiteboxTools (conditioning, full hydrology suite, fast) · `pysheds`\n(lightweight Python watersheds) · `richdem` (derivatives) · GDAL\n(`gdaldem`) for quick slope/hillshade · GRASS (`r.watershed`) for very\nlarge DEMs (no explicit fill needed — least-cost routing).\n\n## Verification protocol\n\n1. Derivative histograms: slope > 60° over large areas or negative\n   accumulation = unit/nodata bug.\n2. Stream network overlay on imagery at 3 locations, including one flat\n   area (where artifacts concentrate).\n3. Watershed area cross-check vs authoritative basin polygons.\n4. Report: DEM source/date/resolution, conditioning method, flow\n   algorithm, stream threshold, all in the deliverable.\n\n## Pitfalls checklist\n\n- Slope from a geographic-CRS DEM without z-factor (values ~100× off).\n- DSM used for watershed delineation (rivers over treetops).\n- Fill-only conditioning across road embankments → phantom lakes.\n- Unsnapped pour point → 3-cell \"watershed\".\n- Arithmetic mean of aspect (350° and 10° average to south, not north).\n- Nodata treated as elevation in fill/statistics.\n- One arbitrary stream threshold presented as the drainage network.\n\n## Execution contract\n\n- **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.\n- **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.\n- **Verification protocol:** inspect derivative distributions, hillshade artifacts, stream overlays, watershed area, pour-point snapping, threshold sensitivity, and elevation-control residuals.\n- **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.\n- **Deliverables:** conditioned DEM, derivatives and hydrologic products, parameter and threshold record, CRS and vertical datum, QA maps, validation metrics, and limitations.\n- **Source freshness:** consult [the authoritative source registry](references/authoritative-sources.md) before applying tool algorithms or product rules and record the checked date.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}