bluegreencity-ki

GK25 Criterion — Shallow-Subsurface Geology

Overview

The gk25 criterion evaluates drought risk from the geology of the shallow subsurface (down to 2 m below surface) using the Geologische Karte von Niedersachsen 1:25.000 (GK25, Detailkartierung) from the LBEG (Landesamt für Bergbau, Energie und Geologie). The uppermost geological layer determines the water storage and drainage behaviour of the root zone: fast-draining sands and gravels increase drought stress, while silts, loams and loess store plant-available water.

The criterion is currently configured with weight 0.0: it contributes extras and the ML feature gk25_material_class to the AutoGluon training dataset, but not to the weighted total score (pending weight recalibration).

Implementation

Location

Data Source

Important: The GK25 exists as two separate services. NodeId=201 is the Detailkartierung (detailed mapping) which covers Hannover. NodeId=202 is the Übersichtskartierung (overview mapping) which only covers northern Lower Saxony and has no data for Hannover.

WFS Server Quirks (verified 2026-07)

The LBEG cardomap WFS silently ignores all server-side filters:

The only working strategy is a full download of the layer (~620 MB GML, ~140,000 polygons Niedersachsen-wide, ~25 s) followed by a client-side clip to the configured bbox_wgs84. The clipped result (~1,780 polygons for Hannover) is cached as GPKG under data/derived/geology/gk25_hannover.gpkg with refresh_days: 365.

How It Works

  1. Load polygons: load_gk25_polygons() reads the GPKG cache, or performs a full WFS download + clip when the cache is missing or stale (with stale-cache fallback on network failure).
  2. Spatial join: Trees are joined onto GK25 polygons (intersects, boundary duplicates deduplicated).
  3. Parse SCHICHTEN: The SCHICHTEN symbol string (Symbolschlüssel Geologie, PREUSS et al. 1991) encodes one or more layers separated by über (“over”), each as Stratigraphie/Petrographie/Genese — e.g. qD/U/Lg über krlo/^t/ = Drenthe till silt over Alb claystone.
  4. Classify uppermost layer: The uppermost layer is classified into a material class. Thin covers with an empty petrography field (Steinsohle xp, Raseneisenstein Ra) fall back to the next deeper layer.
  5. Score lookup: Material class → risk score via the configurable material_scores mapping. Trees without coverage or with unclassifiable strings receive the neutral score.

Classification Rules (in priority order)

Priority Rule Material class Default score
1 (y) in stratigraphy or genesis token y/yy/ym anthropogenic (artificial fill) 0.8
2 Petrography W water 0.1
3 Petrography contains ^ (solid rock) rock 0.6
4 Petrography token H* (peat) or genesis Hn/Hm peat 0.2
5 Genesis token L* (Lg, Lf, Lo, Lol, Lou, Lhf) or Mg silt_loam 0.3
6 Petrography token T clay 0.4
7 Petrography has U and sand fraction mixed_silt_sand 0.5
8 Petrography token U silt_loam 0.3
9 Petrography token G gravel 0.8
10 Petrography token S/fS/mS/gS sand 0.7
— No rule matches on any layer unknown neutral

Distribution for Hannover (polygons): silt_loam 586, sand 529, rock 210, peat 162, water 115, anthropogenic 81, gravel 40, clay 33, mixed_silt_sand 23 — 0 unknown.

Configuration

inputs:
  gk25_wfs:
    url: "https://nibis.lbeg.de/cardomap3/public/ogc.ashx?NodeId=201&Service=WFS"
    typename: "cls:L160"
    version: "2.0.0"
    srs_name: "EPSG:25832"
    schichten_field: "SCHICHTEN"
    klartext_field: "KLARTEXT"
    bbox_wgs84: [9.60, 52.30, 9.92, 52.46]
    cache_path: "./data/derived/geology/gk25_hannover.gpkg"
    refresh_days: 365

criteria:
  - name: "gk25"
    weight: 0.0
    params:
      material_scores:
        anthropogenic: 0.8
        water: 0.1
        rock: 0.6
        peat: 0.2
        clay: 0.4
        silt_loam: 0.3
        mixed_silt_sand: 0.5
        gravel: 0.8
        sand: 0.7

Parameters

Parameter Type Default Description
material_scores dict see above Material class → risk score; merged over built-in defaults

Output Fields

  1. gk25_risk — risk score (0–1); neutral for trees without coverage
  2. gk25_material_class — material class of the uppermost classifiable layer (ML feature; no_data outside coverage, unknown if unclassifiable)
  3. gk25_schichten — raw SCHICHTEN symbol string
  4. gk25_klartext — human-readable layer description

Metadata

{
    "n_trees": 465000,
    "n_scored": 460000,
    "n_unknown": 0,
    "n_missing": 5000,
    "material_class_distribution": {"silt_loam": ..., "sand": ..., ...},
}

Known Limitations

  1. Weight 0.0: No contribution to the weighted total score until weights are recalibrated.
  2. Natural geology only: In built-up areas the GK25 shows the original (pre-development) geology; actual urban soils may be heavily modified. The anthropogenic class only covers mapped artificial fills.
  3. Uppermost layer only: Deeper layers (relevant for deep-rooting species) are not evaluated, except as fallback for thin covers.
  4. Full-download dependency: A change in the LBEG server behaviour (e.g. working BBOX filters) would allow a much lighter fetch; the loader notes this.

References

Changelog

2026-07-22: Initial Implementation (#166)


Author: BlueGreenCity-KI Team Last Updated: 2026-07-22