Phase 6: Kartenmodule #7

Merged
florian.wilde merged 2 commits from feat/phase-6-karten into main 2026-09-04 04:32:48 +00:00
Owner

Alles, was einen Ort hat: Löschwasser, Objekte mit Feuerwehrplan, die Lagekarte
eines Einsatzes und die geplante Förderstrecke.

Version 0.7.0.

Keine Kacheln aus dem Netz

Wo eine Wehr ausrückt, wo ihre Hydranten liegen und welche Objekte sie im Blick
hat, ist niemandes Geschäft. Es gibt deshalb keinen Rückfall auf einen
öffentlichen Kartendienst — auch nicht „nur zum Ausprobieren". Der Kartenserver
läuft selbst:

docker compose --profile karte up -d

Ohne ihn läuft trotzdem alles außer den Straßen: Punkte liegen richtig,
Entfernungen stimmen, die Umkreissuche rechnet. Die Karte sagt oben, dass der
Hintergrund fehlt — sie tut nicht so, als wäre nichts. Dasselbe gilt für einen
eingetragenen, aber nicht erreichbaren Server; das war der erste Fehler, den
ich beim Durchsehen im Browser gefunden habe.

Was drin ist

Umkreissuche über PostGIS — ST_DWithin auf der Geografie mit GiST-Index:
in die Karte tippen, und rechts steht, was in 500 Metern erreichbar ist, nach
Entfernung sortiert, mit Nennweite und Durchfluss. Findet sich nichts, steht
auch das da.

Import aus GeoJSON und Stadtwerke-CSV — erkennt DN 100, 48,5031,
24.05.2026 und vertauschte Achsen. Zwei Schritte wie beim Geräteimport: erst
zeigen, was herauskäme, dann übernehmen. Ein zweiter Import aktualisiert statt
zu verdoppeln. Geraten wird nichts: fehlt die Position, wird die Zeile mit
Zeilennummer und Grund übersprungen; ohne Statusangabe steht „ungeprüft", nicht
„einsatzbereit".

Objekte und Feuerwehrpläne — Zufahrt, Gefahren und Schlüsseldepot sind
eigene Felder und stehen oben, weil sie in dieser Reihenfolge auf der Anfahrt
gelesen werden. Dazu Ansprechpartner mit der Angabe, wer nachts ans Telefon
geht, und Planblätter nach DIN 14095 mit ihrem Stand. Gesucht wird über alles —
„Photovoltaik" findet die Schule.

Lagekarte — 22 taktische Zeichen nach FwDV 102, selbst gezeichnet als SVG.
Ein Werkzeug, ein Klick. Der Abgleich läuft über denselben Ereignisstrom wie
die Atemschutzüberwachung aus Phase 5, mit demselben Hook. Zurücknehmen statt
löschen: was um 14:12 eingezeichnet wurde, gehört zur Mitschrift.

Wasserförderung — Strecke in die Karte tippen, Durchmesser und Fördermenge
einstellen; Pumpenzahl, Schlauchlängen, Restdruck rechnen mit. Geht ein
Abschnitt selbst mit voller Pumpe nicht auf, sagt die Ausgabe das. Unter jeder
Rechnung steht, was sie ist: eine Planungshilfe.

Dateiabruf — /api/dateien/[id], mandantengebunden und protokolliert. Bis
hierher gab es nur den Upload; mit den Feuerwehrplänen gibt es zum ersten Mal
Dateien, die jemand hochlädt und später wieder ansehen will.

Der Fehler, den die Tests gefunden haben

Die Reibungsbeiwerte lagen um den Faktor zehn daneben — aus der Formel
verlust = beiwert × (menge/100)² folgt 0,0234 für den B-Schlauch, nicht 0,23.
Aufgefallen ist das nur, weil die Tests gegen die Tabellenwerte der
Ausbildung
prüfen (1,5 bar je 100 m bei 800 l/min) und nicht gegen das, was
die Funktion gerade ausrechnet. Ein Test, der die eigene Implementierung
bestätigt, hätte hier fröhlich grün gemeldet.

Zwei bewusste Abweichungen von Phase-6.md

Keine Cluster-Darstellung. Bei einigen hundert Löschwasserstellen sind
Cluster eine Lösung für ein Problem, das erst bei Zehntausenden entsteht — und
sie verstecken genau das, was man sehen will: die Lücke im Netz.

Kein Höhenprofil aus einem Geländemodell. Die Höhe wird je Punkt von Hand
eingetragen; ein DGM wäre ein weiterer Datensatz von hunderten Megabyte. Ohne
Höhe rechnet FLORIAN mit ebenem Gelände, und das steht an der Eingabe.

Zum Testen

git checkout feat/phase-6-karten
docker compose up -d && npm install
npm run db:migrate && npm run db:seed && npm run dev
  • /karte — 24 Löschwasserstellen aus dem Seed, davon zwei defekt und zwei
    ungeprüft, dazu Weiher, Zisterne und Saugstelle im Außenbereich. In die
    Karte tippen
    → Umkreissuche rechts.
  • /karte/objekte — Schule, Pflegeheim, Aussiedlerhof. Suche nach
    „Photovoltaik" oder „Silo" probieren.
  • /karte/wasserfoerderung — zwei Punkte tippen, dann den Durchmesser von
    B auf C stellen: die Pumpenzahl springt.
  • Ein Einsatz öffnen → ganz unten die Lagekarte. Zeichen wählen, in die
    Karte tippen; auf einem zweiten Fenster erscheint es innerhalb von zwei
    Sekunden.

Nachweise

  • npx tsc --noEmit ohne Ausgabe
  • npm run test — 354 Tests grün
  • npx playwright test — 153 Tests grün, kein Fehlschlag
  • npm run build — 44 Routen

Zum Dashboard

Die E2E-Suite schreibt weiter in die Demowehr — beim vierten Phasenabschluss
in Folge. Diesmal hatte die Geräteliste 101 statt 49 Geräte, wodurch INV-0001
nicht mehr auf Seite 1 stand und fünf Tests aus Phase 1 rot wurden. 54
Testgeräte abgeräumt; die Ursache bleibt. Das kostet inzwischen in jeder
Phase Zeit
— ein eigener Testmandant wäre die Lösung.

Neu dazu: auf der Einsatzseite aus Phase 3 gibt React im Entwicklungsmodus
eine DOM-Warnung aus (<p> enthält ein <div>). Die neuen Kartenseiten sind
sauber; die Stelle sitzt in Phase-3-Code und ich habe sie nicht eingekreist.

Weiterhin offen: npm run lint läuft nicht (keine ESLint-Konfiguration).

🤖 Generated with Claude Code

Alles, was einen Ort hat: Löschwasser, Objekte mit Feuerwehrplan, die Lagekarte eines Einsatzes und die geplante Förderstrecke. Version 0.7.0. ## Keine Kacheln aus dem Netz Wo eine Wehr ausrückt, wo ihre Hydranten liegen und welche Objekte sie im Blick hat, ist niemandes Geschäft. Es gibt deshalb **keinen** Rückfall auf einen öffentlichen Kartendienst — auch nicht „nur zum Ausprobieren". Der Kartenserver läuft selbst: ```bash docker compose --profile karte up -d ``` **Ohne ihn läuft trotzdem alles außer den Straßen**: Punkte liegen richtig, Entfernungen stimmen, die Umkreissuche rechnet. Die Karte sagt oben, dass der Hintergrund fehlt — sie tut nicht so, als wäre nichts. Dasselbe gilt für einen eingetragenen, aber nicht erreichbaren Server; das war der erste Fehler, den ich beim Durchsehen im Browser gefunden habe. ## Was drin ist **Umkreissuche über PostGIS** — `ST_DWithin` auf der Geografie mit GiST-Index: in die Karte tippen, und rechts steht, was in 500 Metern erreichbar ist, nach Entfernung sortiert, mit Nennweite und Durchfluss. Findet sich nichts, steht auch das da. **Import aus GeoJSON und Stadtwerke-CSV** — erkennt `DN 100`, `48,5031`, `24.05.2026` und vertauschte Achsen. Zwei Schritte wie beim Geräteimport: erst zeigen, was herauskäme, dann übernehmen. Ein zweiter Import aktualisiert statt zu verdoppeln. **Geraten wird nichts:** fehlt die Position, wird die Zeile mit Zeilennummer und Grund übersprungen; ohne Statusangabe steht „ungeprüft", nicht „einsatzbereit". **Objekte und Feuerwehrpläne** — Zufahrt, Gefahren und Schlüsseldepot sind eigene Felder und stehen oben, weil sie in dieser Reihenfolge auf der Anfahrt gelesen werden. Dazu Ansprechpartner mit der Angabe, wer nachts ans Telefon geht, und Planblätter nach DIN 14095 mit ihrem Stand. Gesucht wird über alles — „Photovoltaik" findet die Schule. **Lagekarte** — 22 taktische Zeichen nach FwDV 102, selbst gezeichnet als SVG. Ein Werkzeug, ein Klick. Der Abgleich läuft über denselben Ereignisstrom wie die Atemschutzüberwachung aus Phase 5, mit demselben Hook. Zurücknehmen statt löschen: was um 14:12 eingezeichnet wurde, gehört zur Mitschrift. **Wasserförderung** — Strecke in die Karte tippen, Durchmesser und Fördermenge einstellen; Pumpenzahl, Schlauchlängen, Restdruck rechnen mit. Geht ein Abschnitt selbst mit voller Pumpe nicht auf, sagt die Ausgabe das. Unter jeder Rechnung steht, was sie ist: eine Planungshilfe. **Dateiabruf** — `/api/dateien/[id]`, mandantengebunden und protokolliert. Bis hierher gab es nur den Upload; mit den Feuerwehrplänen gibt es zum ersten Mal Dateien, die jemand hochlädt und später wieder ansehen will. ## Der Fehler, den die Tests gefunden haben Die **Reibungsbeiwerte lagen um den Faktor zehn daneben** — aus der Formel `verlust = beiwert × (menge/100)²` folgt 0,0234 für den B-Schlauch, nicht 0,23. Aufgefallen ist das nur, weil die Tests gegen die **Tabellenwerte der Ausbildung** prüfen (1,5 bar je 100 m bei 800 l/min) und nicht gegen das, was die Funktion gerade ausrechnet. Ein Test, der die eigene Implementierung bestätigt, hätte hier fröhlich grün gemeldet. ## Zwei bewusste Abweichungen von Phase-6.md **Keine Cluster-Darstellung.** Bei einigen hundert Löschwasserstellen sind Cluster eine Lösung für ein Problem, das erst bei Zehntausenden entsteht — und sie verstecken genau das, was man sehen will: die Lücke im Netz. **Kein Höhenprofil aus einem Geländemodell.** Die Höhe wird je Punkt von Hand eingetragen; ein DGM wäre ein weiterer Datensatz von hunderten Megabyte. Ohne Höhe rechnet FLORIAN mit ebenem Gelände, und das steht an der Eingabe. ## Zum Testen ```bash git checkout feat/phase-6-karten docker compose up -d && npm install npm run db:migrate && npm run db:seed && npm run dev ``` - **`/karte`** — 24 Löschwasserstellen aus dem Seed, davon zwei defekt und zwei ungeprüft, dazu Weiher, Zisterne und Saugstelle im Außenbereich. **In die Karte tippen** → Umkreissuche rechts. - **`/karte/objekte`** — Schule, Pflegeheim, Aussiedlerhof. Suche nach „Photovoltaik" oder „Silo" probieren. - **`/karte/wasserfoerderung`** — zwei Punkte tippen, dann den Durchmesser von B auf C stellen: die Pumpenzahl springt. - **Ein Einsatz öffnen** → ganz unten die Lagekarte. Zeichen wählen, in die Karte tippen; auf einem zweiten Fenster erscheint es innerhalb von zwei Sekunden. ## Nachweise - `npx tsc --noEmit` ohne Ausgabe - `npm run test` — 354 Tests grün - `npx playwright test` — **153 Tests grün**, kein Fehlschlag - `npm run build` — 44 Routen ## Zum Dashboard **Die E2E-Suite schreibt weiter in die Demowehr** — beim vierten Phasenabschluss in Folge. Diesmal hatte die Geräteliste 101 statt 49 Geräte, wodurch `INV-0001` nicht mehr auf Seite 1 stand und fünf Tests aus Phase 1 rot wurden. 54 Testgeräte abgeräumt; die Ursache bleibt. **Das kostet inzwischen in jeder Phase Zeit** — ein eigener Testmandant wäre die Lösung. Neu dazu: auf der **Einsatzseite aus Phase 3** gibt React im Entwicklungsmodus eine DOM-Warnung aus (`<p>` enthält ein `<div>`). Die neuen Kartenseiten sind sauber; die Stelle sitzt in Phase-3-Code und ich habe sie nicht eingekreist. Weiterhin offen: **`npm run lint` läuft nicht** (keine ESLint-Konfiguration). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
florian.wilde added 1 commit 2026-09-04 00:52:56 +00:00
Phase 6: alles, was einen Ort hat — Loeschwasser, Objekte mit Feuerwehrplan,
die Lagekarte eines Einsatzes und die geplante Foerderstrecke.

Keine Kacheln aus dem Netz. Wo eine Wehr ausrueckt und wo ihre Hydranten
liegen, ist niemandes Geschaeft; der Kartenserver laeuft selbst
(tileserver-gl im Compose-Profil "karte"). Ohne ihn zeigt die Karte einen
leeren Grund und sagt das auch — Punkte, Entfernungen und Umkreissuche
funktionieren trotzdem. Dasselbe gilt fuer einen eingetragenen, aber nicht
erreichbaren Server.

Die Umkreissuche laeuft ueber PostGIS: ST_DWithin auf der Geografie mit
GiST-Index rechnet in Metern und nutzt den Index. Gefragt wird waehrend der
Fahrt, und bei tausend Hydranten waere alles andere ein vollstaendiger
Tabellendurchlauf.

Der Import aus GeoJSON und Stadtwerke-CSV ist nachsichtig, aber ehrlich: er
erkennt "DN 100", deutsche Kommazahlen, Datumsangaben und vertauschte Achsen
— raet aber nichts. Fehlt die Position, wird die Zeile uebersprungen; ohne
Statusangabe steht "ungeprueft", nicht "einsatzbereit".

22 taktische Zeichen nach FwDV 102 selbst gezeichnet, die Lagekarte gleicht
ueber denselben Ereignisstrom ab wie die Atemschutzueberwachung.

Die Wasserfoerderung rechnet Reibung, Hoehe und Pumpenzahl; das Ergebnis wird
nie gespeichert, sondern bei jeder Anzeige neu gerechnet. Geht eine Strecke
nicht auf, sagt die Ausgabe das.

Behoben: die Reibungsbeiwerte lagen im ersten Wurf um den Faktor zehn daneben.
Aufgefallen ist es nur, weil die Tests gegen die Tabellenwerte der Ausbildung
pruefen und nicht gegen die eigene Implementierung.

Dazu ein Abruf fuer abgelegte Dateien (/api/dateien/[id]) — bis hierher gab es
nur den Upload.

59 neue Tests (48 Unit, 11 E2E je Browser).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
florian.wilde added 1 commit 2026-09-04 01:11:33 +00:00
Karte, Objekte und Wasserfoerderung dazu; die uebrigen Bilder auf den
aktuellen Stand gebracht (die Seitenleiste zeigt jetzt die Karte).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
florian.wilde merged commit c779266450 into main 2026-09-04 04:32:48 +00:00
florian.wilde deleted branch feat/phase-6-karten 2026-09-04 04:32:48 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: florian.wilde/FireAdministration#7