bluegreencity-ki

Salt Exposure Criterion

Status: Implemented ✅
Module: bluegreencity_ki/criteria/salt.py
Related Criterion: street_type
Data Sources:

Overview

The salt criterion evaluates salt exposure risk for urban trees based on official winter road service (Winterdienst) priority data. The City of Hannover (via aha) maintains a tiered priority system for winter road maintenance (gritting, salting), which directly correlates with salt exposure for roadside trees.

This criterion complements the existing street_type criterion by providing more precise, locally validated data about actual winter maintenance activities rather than relying solely on OSM highway classifications.

Implementation

Location

How It Works

The criterion uses a multi-stage fallback chain:

  1. Strategy 1 – PostGIS table: Loads pre-imported salt routes from PostGIS (if configured)
  2. Strategy 2 – Local file: Loads salt routes from a GeoPackage/Shapefile (if configured)
  3. Strategy 3 – ALKIS roads + Winterdienst CSV (primary approach):
    • Loads ALKIS road polygons (Verkehrsflächen) with enriched street names via load_alkis_roads()
    • Loads the aha Winterdienst CSV (parsed from the official PDF)
    • Builds a lookup dict: street name → WD class (W0/W1/W2)
    • Duplicate resolution: keeps highest WD class per street (W1 > W2 > W0)
    • Joins WD class onto ALKIS road polygons; unmatched roads default to W0
    • Performs sjoin_nearest between trees and ALKIS road polygons (max_distance: 50m)
  4. Class Mapping: Maps winter service classes (W0, W1, W2) to risk scores
  5. Fallback: Trees without nearby routes or missing data receive score 0.0 (no salt risk)

Rationale

Connection to Salt Exposure

Winter road maintenance directly impacts tree health through:

Trees along priority winter service routes receive more frequent and intensive salting, leading to higher cumulative salt exposure throughout the winter season.

Advantages Over OSM Highway Classification

Factor street_type (OSM) salt (aha/ALKIS)
Data Source Crowdsourced, global Official, local authority
Update Frequency Variable Annually maintained
Salt Correlation Indirect (traffic volume) Direct (maintenance priority)
Local Accuracy Variable High (Hannover-specific)
Bus Routes Not included Included in priorities
Cycle Paths Partially Explicitly prioritized

Data Sources

1. aha Winterdienst Priority System

The aha Region Hannover provides a publicly accessible list of winter service priorities:

URL: https://www.aha-region.de/stadtreinigung/winterdienst

The system uses three priority classes (Winterdienstklassen) for winter road maintenance:

Class German Name Description Salt Intensity Risk Score
W1 Höchste Priorität Main arterial roads, bus routes Very High 1.0
W2 Nachrangige Priorität Connector roads, secondary streets Medium 0.5
W0 Kein Winterdienst No winter service None 0.0

2. ALKIS Street Names (More Precise Alternative to OSM)

For more precise street name matching, ALKIS (Amtliches Liegenschaftskatasterinformationssystem) data from LGLN can be used:

Data Sources:

Tables Used:

Connection Logic:

  1. First Connection (Parcel → Location):
    • AX_Flurstueck.zeigtAuf → AX_LagebezeichnungohneHausnummer
    • AX_Flurstueck.weistAuf → AX_LagebezeichnungmitHausnummer
  2. Second Connection (Location → Street Name):
    • Join via lagebez_schl key composed of:
      • land (2 digits) + regierungsbezirk (1 digit) + kreis (2 digits) + gemeinde (3 digits) + lage (5 digits)

Note: For traffic areas (Verkehrsflächen), mainly AX_LagebezeichnungohneHausnummer is used. Individual parcels can have multiple location references.

Import Script: scripts/import_alkis_streets.py

Data Format (aha PDF)

Example from aha PDF table:

Str.-Nr. | Straßenname        | Zusatz                              | RKL | WD
---------|--------------------|------------------------------------|-----|----
03340    | Windausstraße      | von Großer Kolonnenweg bis ...     | R5  | W2
03057    | Windmühlenstraße   | von Zufahrt Parkgarage bis Georg.. | R1  | W1
03750    | Windröschenweg     | von Höltjebaumstraße bis Wendep... | R6  | W0

Note: The Reinigungsklasse (RKL) column should be ignored - only the WD (Winterdienst) column is relevant.

Scoring Logic

W1 (Höchste Priorität)      → Risk Score = 1.00 (highest salt exposure)
W2 (Nachrangige Priorität)  → Risk Score = 0.50 (moderate salt exposure)
W0 (Kein Winterdienst)      → Risk Score = 0.00 (no salt exposure)
Missing data                 → Risk Score = 0.00 (no salt risk)

Output Fields:

Legacy join helper columns such as winterdienst, winterdienst_left, and winterdienst_right are treated as internal source fields and are not written into the final pipeline output.

Configuration

Basic Configuration

criteria:
  - name: "salt"
    weight: 0.5  # example; current calibrated weight in config/config.yaml
    params:
      mapping:
        "W1": 1.0   # Höchste Priorität
        "W2": 0.5   # Nachrangige Priorität
        "W0": 0.0   # Kein Winterdienst

inputs:
  salt:
    winterdienst_csv: "./data/derived/salt/winterdienst_strassenverzeichnis_2026.csv"
    winterdienst_name_field: "strassenname"
    winterdienst_class_field: "winterdienst"
    priority_field: "winterdienst"
  
  salt_join:
    max_distance: 50.0            # Max distance to match street (meters)

With PostGIS Table

inputs:
  salt:
    type: "postgis"
    schema: "bgcki"
    table: "context_salt_routes"
    postgis_table: "context_salt_routes"
    postgis_schema: "bgcki"
    priority_field: "winterdienst"
  
  salt_join:
    max_distance: 50.0

Data Requirements

Data Preparation Steps

The primary approach uses ALKIS road polygons + aha Winterdienst CSV:

Step 1: Parse aha PDF to CSV

python scripts/parse_winterdienst_pdf.py

This creates data/derived/salt/winterdienst_strassenverzeichnis_2026.csv with 3,187 street entries (semicolon-delimited, UTF-8).

Step 2: ALKIS Road Data

ALKIS road polygons are loaded automatically by the pipeline via load_alkis_roads(), which:

  1. Fetches AX_Flurstueck cadastral parcels (Verkehrsflächen, funktion 5110/5112) from WFS
  2. Clips to ALKIS Landnutzung extent
  3. Enriches with street names via zeigtAuf → AX_LagebezeichnungOhneHausnummer → lagebez_schl → CSV
  4. Reuses the centrally resolved OSM roads cache when highway hierarchy is needed elsewhere in the pipeline
  5. Caches the ALKIS result as GeoPackage

See: ALKIS Integration Guide

Alternative: Pre-imported PostGIS Routes

For pre-geocoded salt routes:

  1. Import to PostGIS as bgcki.context_salt_routes

Street Name Sources

OSM Highway Name Attributes

The OSM highways table (bgcki.context_osm_highways) includes:

Column Description Example
name Street name “Windmühlenstraße”
ref Route reference “A2”, “B3”
official_name Official name (if different) -
alt_name Alternative name -
old_name Historical name -

See: https://wiki.openstreetmap.org/wiki/Key:name

ALKIS Street Name Attributes

The ALKIS street names table (bgcki.context_alkis_street_names) includes:

Column Description
lagebez_schl Location key (13 digits)
strasse Official street name
gemeinde Municipality code

Required Table Schema

CREATE TABLE bgcki.context_salt_routes (
    id SERIAL PRIMARY KEY,
    strasse VARCHAR(255),           -- Street name
    winterdienst VARCHAR(2),        -- Winter service class: W0, W1, W2
    str_nr VARCHAR(10),             -- Street number from aha data
    zusatz TEXT,                    -- Additional location info
    geom GEOMETRY(LineString, 25832) -- Street geometry
);

CREATE INDEX ON bgcki.context_salt_routes USING GIST (geom);

Integration with Other Criteria

The salt criterion integrates with:

Validation Strategy

Cross-Validation with street_type

Compare salt classes with OSM highway classifications:

# Expected correlations (approximate)
W1 ↔ motorway, trunk, primary (major roads)
W2 ↔ secondary, tertiary (connector roads)
W0 ↔ residential, service (local roads)

Discrepancies may indicate:

Field Validation

For selected sample locations:

  1. Check physical presence of salt damage indicators
  2. Compare observed vs. predicted risk scores
  3. Seasonal validation (end of winter assessment)

Known Limitations

  1. Data availability: Requires obtaining official data from aha
  2. Temporal changes: Priority routes may change annually
  3. Microclimate effects: Salt drift depends on wind, drainage
  4. Salt type variations: Different salts (NaCl, CaCl2) have different impacts
  5. Hannover-specific: Not transferable to other cities without adaptation
  6. Landesstraßen-Lücke (issue #256): The aha list covers municipal roads only. Highways, expressways and state roads (Südschnellweg, Messeschnellweg, A2, A7, A37, B6, B65 — ~1.465 km in the ALKIS cache) never match the street names in the winterdienst list and silently fall back to W0 (“no salt exposure”), although they are salted at state level with high priority. Affected: ~1,735 trees (1.9 % of the operative population, verified 2026-10-06). The salt_value for these trees is therefore a lower bound. Planned fix: dedicated class for ALKIS highway in (motorway, trunk, primary) plus a salt_source provenance flag.

References

Changelog


Created: 2026-02-03
Last Updated: 2026-10-06 Status: Implemented ✅