Auftrag
Das Amt für Umweltschutz und Katastrophenvorsorge der Stadt Stuttgart braucht eine integrierte Multi-Hazard- und Klimarisiko- Bewertung für das Stadtgebiet. Stuttgarts Kessellage, das Neckartal, die Hanglagen am Rand und der städtische Wärmeinsel-Effekt machen den Standort besonders aussagekräftig — sechs Naturgefahren wirken hier räumlich sehr unterschiedlich, und der Klimawandel verändert das Bild bis 2050 zusätzlich.
Du sollst diese Analyse end-to-end durchführen — von der Daten- beschaffung über die Berechnung der Gefahren-Indizes bis zu einer publikationsreifen Karten-Komposition und einem schriftlichen Bericht. Die Bewertung soll vier Kernfragen beantworten:
- Topografie & Gefahren: Welche räumlichen Muster zeigen die sechs Naturgefahren über das Stadtgebiet?
- Multi-Geometrie-Exposition: Welche Restaurants (Punkte), Gebäude (Polygone) und Straßenabschnitte (Linien) sind dem Hochwasser-Risiko am stärksten ausgesetzt?
- Statistik & Komposit-Bewertung: Wie korrelieren die Gefahren untereinander, wie verteilen sich die Werte, und wie sieht ein gewichteter Komposit-Score aus?
- Klima-Projektion: Wie verschiebt sich das Risikobild unter RCP 4.5 und RCP 8.5 bis 2050?
Bibliotheks-Empfehlung und Skill-Konsultation
Für die geodatenbasierten Berechnungen sollst du primär die
geo-api-Bibliothek nutzen — sie bündelt unter GeospatialRaster
und GeospatialVector genau die Datenquellen (OSM, Microsoft
Planetary Computer, DWD/CORDEX, Open-Meteo) und Algorithmen (Terrain-
Derivate, Spectral Indices, Zonal Statistics, Routing), die du hier
brauchst. Lies dazu vor der ersten Code-Aktion den Skill
geo-api. Wo geo-api keinen direkten Algorithmus hat (z.B.
spezielle Vektor-Operationen, statistische Aggregationen), entscheide
selbst über Fallback-Pakete — die Skills geopandas-shapely,
xarray-rioxarray, rasterio, grass-gis, gdal-binaries,
pyproj und qgis-styles sind verfügbar und sollen ergänzend
konsultiert werden wenn die Aufgabe es erfordert.
Für QGIS-Visualisierung (Layer-Tree, Styling, Screenshots, Bookmarks,
Layout) nutze die QGIS-MCP-Bridge über den Skill
spatial-agent-bridge. Den Workflow-Skill bench (Coverage-Tasks-
Sektion) musst du auch konsultieren — er beschreibt das
RESULT.json-Schema und den Self-Review-Loop für Screenshots.
Tool-Wahl ist explizit deine Entscheidung — der Prompt schreibt keine konkreten Funktions- oder Modul-Namen vor. Begründe in deinem initialen Plan kurz, welchen Pfad du gehst und warum.
Vorgehen
Beginne mit einem schriftlichen Plan (3–8 Sätze) in der
RESULT.json unter summary.plan — welche Phasen du in welcher
Reihenfolge angehst, welche Skills du gelesen hast, welche
Datenquellen du benutzt. Erst dann mit der Implementierung beginnen.
Erstelle früh die Verzeichnisstruktur:
artifacts/
├── data/
│ ├── basemaps/
│ ├── osm/ (Restaurants, Gebäude, Straßen, Bezirke)
│ ├── terrain/ (DEM + Derivate)
│ ├── hazards/ (6 Gefahren-Indizes + Komposit + Inundationszonen)
│ ├── analysis/ (Sampling-Resultate, Aggregationen)
│ └── climate/ (RCP-skalierte Resultate)
├── charts/ (matplotlib-PNGs)
└── screenshots/ (QGIS-Screenshots)
Speichere das QGIS-Projekt unter artifacts/stuttgart_hazards.qgz.
Setze das Projekt-CRS bewusst (EPSG:25832 ist eine naheliegende Wahl
für Süddeutschland).
Phase 1 — Studiengebiet definieren und Basisdaten beschaffen
Bestimme das Studiengebiet: das Stadtgebiet Stuttgart mit den umgebenden Höhenrücken (Bopser, Killesberg, Frauenkopf), insgesamt eine BBox von ca. 10 × 10 km. Hole für dieses Gebiet:
- ein digitales Höhenmodell mit ca. 30 m Auflösung (Copernicus GLO-30 via Microsoft Planetary Computer ist Standard);
- einen OSM-Basemap-Layer;
- die OSM-Vektordaten: alle Restaurants (POI), alle Gebäude- Polygone, das fahrbare Straßennetz, die Stadtbezirks-Grenzen.
Hinweis zur DEM-Beschaffung: lade nur den AOI-Ausschnitt herunter, nicht ganze Kachel-Stapel.
Organisiere die geladenen Layer in QGIS in einem sinnvollen Layer-
Baum (Gruppen wie "Terrain/Rohdaten", "Urban/Gebäude", "POI",
"Verwaltung/Bezirke", "Basemaps"). Style-Beispiele aus dem Skill
qgis-styles sind willkommen.
Mache am Ende der Phase einen Übersichts-Screenshot.
Phase 2 — Terrain-Derivate
Aus dem DEM müssen die wichtigsten Geländeableitungen entstehen. Mindestens nötig sind:
- Hangneigung (Slope, in Grad)
- Exposition (Aspect, 0-360°)
- topographische Position (z.B. TPI auf ~330 m Fensterradius)
- topographic wetness index (z.B. TWI)
- Ruggedness (z.B. TRI)
- Profil-Krümmung
- Höhe über nächstem Vorfluter (HAND)
- Flow Accumulation
- Hillshade (für Visualisierung)
Welche Library/welches Tool du verwendest, ist offen — geo-api hat
für viele davon einen terrain-Accessor, GRASS GIS bietet
spezialisierte Module (siehe Skill grass-gis), GDAL-CLI hat ein
paar Basics (siehe Skill gdal-binaries). HAND ist meist der
aufwändigste Schritt (Flow-Accumulation → Stream-Extraktion →
vertikale Distanz).
Performance-Hinweis: Watershed-Algorithmen (besonders HAND und
Flow-Accumulation) können bei naiver Python-Implementierung auf
einem 10×10 km / 30-m-DEM mehrere zehn GB RAM verbrauchen. Wenn
du merkst dass dein Prozess >20 GB RSS belegt, brich ab und wechsle
den Pfad — GRASS GIS' r.watershed ist auf großen DEMs deutlich
RAM-effizienter als Python-Pendants (zeit-tested C-Code).
Alternativ kannst du den DEM vor der HAND-Berechnung downsamplen
(~60 m statt 30 m halbiert die Pixel-Zahl und ein Viertel den RAM-
Bedarf). Dokumentiere die Wahl unter summary.hazard_formulas.
Style die Derivate so dass die Information klar wird: Hillshade als Graustufen-Hintergrund; Slope warm; TPI divergierend (Täler/Rücken); TWI sequenziell (trocken→nass); HAND sequenziell (nahe Vorfluter→ hoch darüber).
Screenshot der Derivate-Übersicht (Hillshade + halbtransparenter Slope ist ein guter Default).
Phase 3 — Sechs Gefahren-Indizes und ein Komposit
Berechne aus den Terrain-Derivaten sechs normalisierte Gefahren- Indizes (jeweils auf [0,1] skaliert, 1 = höchste Gefahr) sowie einen gewichteten Komposit. Folgende Indizes mit folgenden physikalischen Begründungen sind erwartet:
| Index | Was es modelliert | Empfohlene Komponenten |
|---|---|---|
| Wind-Exposition | Rücken und Westhänge sind Wind-exponiert | TPI, Westhang-Maß, relative Höhenposition, Slope |
| Frost-Risiko | Kaltluft sammelt sich in Tälern und feuchten Senken | Talposition (Inverse von TPI), TWI, niedrige Höhenposition |
| Hochwasser-Risiko | Tiefliegend nahe Vorflutern mit großem Einzugsgebiet | Inverse HAND, TWI, Flow-Accumulation |
| Hitzestress | Niedrige Höhe + Südhang + Stadtfaktor | Höheninverse, Südhang-Maß, urbaner Faktor (Konstante) |
| Hangrutsch | Steil + nass + konkav | Slope, TWI, Konkavität |
| Erosion (LS-Faktor) | RUSLE-LS-Faktor aus Flow × Slope | Flow-Accumulation, Slope-Funktion |
Die genauen Formeln und Gewichte sind dein Ermessen — orientiere dich
an Standard-Literatur (RUSLE für Erosion, TPI für Wind, HAND für
Flood). Dokumentiere die gewählten Formeln in der RESULT.json
unter summary.hazard_formulas.
Komposit: gewichtete Summe der sechs Indizes (deine Gewichts-Wahl, begründet — typischerweise Flood + Heat höher in einer städtischen Hitze-/Hochwasser-Domäne).
Screenshots: pro „signature"-Gefahr (Wind, Flood, Heat, Hangrutsch) eine eigene Karte über Hillshade, plus eine Komposit-Übersichts- Karte.
Zusätzlich: HAND-basierte Inundations-Zonen für drei Szenarien (1 m / 2 m / 5 m Wasserspiegel über nächstem Vorfluter). Die Zonen als Polygone exportieren (z.B. nach GPKG). Berechne und melde pro Szenario: geflutete Fläche (km²), Anzahl betroffener Gebäude, Gesamtlänge betroffener Straßen (km).
Phase 4 — Multi-Geometrie-Exposition
Drei verschiedene Geometrie-Typen sollen mit Hazard-Werten beprobt werden. Das ist bewusst so gewählt — sie verlangen unterschiedliche Raster-zu-Vektor-Extraktionsmethoden:
- Restaurants (Punkte): für jeden Punkt die Werte aller 6 Gefahren
- Höhe + Slope ziehen. Daraus Komposit-Score pro Restaurant berechnen (Gewichte sind deine Wahl, dokumentieren). Vier Risikoklassen (Niedrig / Mittel / Hoch / Sehr Hoch).
- Gebäude (Polygone): pro Polygon den Hochwasser-Index aggregieren (Zonal-Statistics oder Centroid-Sampling — wähle was sinnvoll ist). Vier Risikoklassen.
- Straßen (Linien): pro Segment ebenfalls den Hochwasser-Index aggregieren. Vier Risikoklassen, plus Linienbreite proportional zum Score in der Visualisierung.
Export aller drei Resultate jeweils als GPKG unter
artifacts/data/analysis/. Die Restaurant-Resultate zusätzlich als
GeoJSON und CSV.
Bezirks-Level-Aggregation: die Restaurants per Spatial-Join den Stadtbezirken zuweisen, pro Bezirk Mittelwert/Anzahl/% Hochrisiko berechnen, als Choropleth-Polygone in QGIS visualisieren.
Screenshots: pro Geometrie-Typ ein dedizierter Screenshot (Restaurants/Gebäude/Straßen jeweils nach Risikoklasse), plus Bezirks-Choropleth, plus die drei Inundationszonen.
Phase 5 — Statistik und Charts
Generiere mindestens sieben Charts als PNG unter artifacts/charts/
(matplotlib ist der naheliegende Default). Mindest-Inventar:
- Korrelations-Heatmap der 6 Gefahren über alle Restaurants (6×6, Pearson, divergierende Farbskala mit annotierten Werten);
- Histogramm-Panel der 6 Gefahren (Verteilungs-Form je Hazard);
- Radar-Charts der Top-5 risikoreichsten Restaurants;
- Balkendiagramm Restaurant-Anzahl pro Risikoklasse;
- Scatter Höhe × Hochwasser-Score (mit Trendlinie);
- Boxplots pro Risikoklasse über alle 6 Gefahren;
- Klima-Vergleichs-Balkendiagramm (Baseline vs RCP 4.5 vs RCP 8.5).
Chart 7 wird in Phase 7 berechnet, kann aber als Skelett schon hier vorbereitet sein.
Phase 6 — Hochrisiko-Inspektion und Evakuierungs-Routing
Selektiere die Restaurants mit Komposit-Score > 0.50. Zoome auf das räumliche Cluster der höchsten Konzentration und das einzelne Restaurant mit dem höchsten Score (eigene Screenshots).
Wähle die drei Restaurants mit dem höchsten Komposit-Score und
berechne für jedes eine Fußgänger-Route zu einem sicheren Punkt
(z.B. ein Punkt mit HAND > 10 m auf einem Höhenrücken). Die
Routen-Berechnung kann über OSM-Routing erfolgen (geo-api hat
dafür eine Routing-Komponente; alternativ OSMnx für Graph-basiertes
Routing, siehe entsprechende Skills).
Identifiziere Routensegmente die durch Flood-prone-Bereiche (Hochwasser-Index > 0.5) laufen — das sind „vulnerable" Segmente. Report: Routen-Länge, geschätzte Gehzeit, vulnerable Anteil.
Screenshot der drei Routen mit Hervorhebung der vulnerable Segmente.
Phase 7 — Klimaprojektion (RCP 4.5 und RCP 8.5, Horizont 2050)
Wende für jeden Restaurant-Punkt Klima-Skalierungsfaktoren auf die baseline-Gefahren-Werte an. Orientierungswerte für das CORDEX- Ensemble bis 2050 (Region Süddeutschland):
| Gefahr | RCP 4.5 Faktor | RCP 8.5 Faktor | Richtung |
|---|---|---|---|
| Wind | ~1.00 | ~1.00 | statisch |
| Frost | ~0.77 | ~0.55 | abnehmend |
| Hochwasser | ~1.03 | ~1.07 | leicht steigend |
| Hitze | ~1.80 | ~2.59 | stark steigend |
| Hangrutsch | ~1.00 | ~1.00 | statisch |
| Erosion | ~1.03 | ~1.07 | leicht steigend |
Du kannst diese Faktoren direkt nutzen (Quelle: EURO-CORDEX
EUR-11, MPI-M-MPI-ESM-LR, 2050) oder per geo_api.ClimateDataApi
feinere Werte holen wenn das mit deinem Workflow passt. Dokumentiere
in RESULT.json welche Faktoren du benutzt hast.
Pro Restaurant: skaliere jede Gefahr (gedeckelt auf 1.0), berechne
den Komposit neu, ordne neue Risikoklasse zu. Speichere die Resultate
als CSV unter artifacts/data/climate/. Berichte die Klassen-
Verschiebung (% in jeder Klasse pro Szenario).
Generiere Chart 7 mit den realen Daten. Screenshot: side-by-side Restaurants Baseline vs RCP 8.5 in QGIS.
Phase 8 — Finalisierung
Layer-Baum für die Publikation aufräumen — eine saubere Hierarchie mit Analyse-Ergebnissen oben, Gefahren in der Mitte, Rohdaten/ Basemap unten.
Finaler Komposit-Screenshot: Hillshade + 2-m-Inundationszone semitransparent + Gebäude nach Hochwasser-Risiko + Restaurants nach Komposit-Risikoklasse + Evakuierungs-Routen sichtbar.
Schreibe einen Bericht unter artifacts/RESULTS.md (deutsch oder
englisch, deine Wahl) mit den üblichen Sektionen: Executive
Summary, Studiengebiet, Methodik, Ergebnisse pro Phase, Klima-
Projektionen, Empfehlungen. Charts via Markdown einbetten.
Self-Review-Loop für jeden Screenshot
Aus Skill bench PROTOCOL §10 (Coverage-Tasks): nach jedem
Screenshot prüfe das Bild bevor du weiter gehst. Wenn du Claude Code
bist, öffne das PNG mit deinem Read-Tool und prüfe visuell.
Wenn du Codex bist, nutze Bash + Python/PIL um die Pixel-Verteilung
zu checken (ein std < 5 deutet auf ein leeres/uniformes Bild hin).
Wenn der Screenshot die Erwartung nicht erfüllt (leer, falsch
zentriert, falsche Layer sichtbar, identisch zur vorigen Phase),
korrigiere und schieße neu. Maximal zwei Retries pro Phase.
Dokumentiere Retries in RESULT.json unter summary.review_notes[].
Screenshot-Regeln (verbindlich)
- Führe nach jedem load_project zuerst eine map_navigation aus (z. B. zoom_to_layer oder set_extent), bevor du den ersten Screenshot machst — der Canvas-Extent ist nach dem Projektladen in dieser Umgebung undefiniert und ergäbe ein leeres Bild.
- Rufe get_map_screenshot IMMER mit expliziten Maßen auf:
width=1600, height=1000(dpi Default 96). Die Fenstergeometrie ist in dieser Umgebung nicht verlässlich — verlasse dich nie auf die Canvas-Größe. - Nutze NIEMALS
include_overlays=true— der Widget-Grab-Pfad liefert in dieser Umgebung leere Bilder. Map-Tips sind für diese Aufgabe nicht erforderlich. - Prüfe nach jedem Screenshot den
content_hashder Antwort: ist er identisch zum vorherigen Screenshot, hat sich die Karte nicht geändert — dann stimmt etwas mit Sichtbarkeit/Extent nicht (Self-Review-Loop!).
RESULT.json — was rein muss
Die RESULT.json muss dem Schema aus dem bench-Skill (PROTOCOL.md)
genügen — das verlangt auf oberster Ebene zwingend task_id,
run_index, mode, summary, hard_checks und anti_checks.
Für jede anti.never:-Regel dieser Task muss ein
anti_checks[]-Eintrag mit id, violation und evidence
existieren — ein fehlender Eintrag wird als Verstoß gewertet.
Unter summary:
plan: dein initialer Plan-String (siehe oben);phases_completed: Array["1", "2", ..., "8"];data_sources_used: Liste der Datenquellen-Endpunkte mit Versionen (z.B.{"copernicus_glo30": "dem 1.0", "osm_overpass": "<date>"});hazard_formulas: Dict mit den von dir gewählten Formeln und Gewichten pro Gefahr;climate_factors_used: Dict mit den Skalierungsfaktoren je Hazard für RCP 4.5 und RCP 8.5;composite_weights: Dict mit deinen Gewichten für den Komposit- Score pro Geometrie-Typ;screenshots_written: Liste der relativen Pfade;charts_written: Liste der relativen Pfade;inundation_stats: Dict pro Szenario{"1m": {"area_km2": ..., "buildings_affected": ..., "streets_km_affected": ...}, "2m": {...}, "5m": {...}};risk_class_distribution: Dict{"baseline": {"Niedrig": <pct>, "Mittel": <pct>, "Hoch": <pct>, "Sehr Hoch": <pct>}, "rcp45": {...}, "rcp85": {...}};top_10_risk_restaurants: Liste mit Name (oder ID), Bezirk, Komposit-Score, dominanter Gefahr;evacuation_routes: Liste mit Start-Restaurant, Ziel-Koordinate, Routen-Länge_m, Gehzeit_min, vulnerable_km;failures: Array{phase, action, error}für jeden Schritt der nicht durchging;review_notes: Self-Review-Loop-Dokumentation;abort_reason: String oder null.
Aufräumen am Schluss
Alle temporären QGIS-Layer, Gruppen, Bookmarks, Layouts gehören in
einen Tree-Knoten Benchmark/B08_stuttgart_hazard_climate_risks/run_<N>,
damit der nächste Run aus einem sauberen Zustand starten kann.
Datei-Outputs in artifacts/ bleiben erhalten — die sind das
Resultat der Aufgabe.
























