Files
mesh-configs/skills/devops/web-hosting-deployment/references/gtfs-routing-lessons.md
T

66 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GTFS-Verbindungssuche: RAPTOR real erprobt (2026-08-19)
Kontext: Webseite urlaub.perfekt-ohne-en.de (Zugsuche, nur Nahverkehr/kein ICE).
Nutzer stellte echte GTFS-Datei bereit (Regional/S-Bahn) — Verarbeitung brachte
mehrere harte Lektionen.
## Lektion 1: RAPTOR verbessert, aber ist KEINE fertige Lösung
Einfacher **Dijkstra** auf GTFS ist instabil bei grossen Knoten: benachbarte Ziele
ergaben absurde Differenzen (Mainz→Berlin 11h vs. Nachbar Wiesbaden 3h — unmoeglich).
**RAPTOR** (Round-Based) ist der richtige Algorithmus und verbessert die Konsistenz
(Mainz & Wiesbaden → Berlin wurden konsistent ~8h22).
**ABER:** RAPTOR erzeugt weiterhin einzelne absurde Fernwerte (z.B. Mainz→Berlin
~22h, real Regional ~7-9h; Trefferquote ~66-95%). Ein Algorithmus mit solcher
Einzelfehlerquote darf NICHT als finale Fahrzeit-Quelle ausgegeben werden.
**Praxisfix (Nutzer-Entscheidung „3 dann 1"):**
- **Option 3 (sofort):** nur *team-verifizierte* Kernzeiten konkret anzeigen
(Plausibilitaets-Anker: Trier→Saarbruecken ~1h, Koeln→Aachen ~50min, vom Team
bestaetigt). Alle anderen Verbindungen → `fahrzeit_h='pruefen'` in SQLite; Template
rendert stattdessen orangen Hinweis „vor Fahrt prüfen". NIE absurde/inkonsistente
Zahl als real stehen lassen.
- **Option 1 (danach):** robuste Suche erst auf die Seite schreiben, wenn JEDER Wert
separat gegen einen Plausibilitaets-Anker verifiziert ist.
## Lektion 2: Konsistenz-Check = Nachbar-Ziele gegeneinander pruefen
Der schnellste Fehlerdetektor: benachbarte Ziele vergleichen. Mainz→Berlin darf
nicht dramatisch von Wiesbaden→Berlin abweichen (gleiche geographische Lage).
Erst wenn das Cluster konsistent ist, Werte freigeben.
## Lektion 3: PDF-Haltestellenliste via VORAB-PFAD-CACHE
Nutzerwunsch: PDF soll die komplette Verbindung (`von → zwischenhalte → nach`) zeigen,
nicht nur Start/Ziel. On-the-fly-Routing bei jedem PDF-Aufruf ist zu langsam
(RAPTOR ~40-200s → nginx **504 Gateway Timeout**).
**Lösung:** Vorab einmalig Pfad-Cache bauen (`pfade_cache.json`), NUR die Kern-Ebenen
1+2 (~1.900 eindeutige `von|nach`-Paare; Ebene 3 = Kleinstaedte braucht keine eigenen
PDFs). PDF-Route liest `json.load(cache)[f"{start}|{ziel}"]["seg"]` → Ladezeit von
504 auf **~0,4s**. Wiederverwendbares Muster: Wenn On-the-fly-Berechnung zu langsam
ist, vorab einen Cache bauen und die Route daraus lesen.
- Template ergaenzt Start-Stadt als ersten + Ziel-Stadt als letzten Eintrag, damit
die Liste immer den Rahmen `von → ... → nach` bildet.
## Lektion 4: GTFS-Datenmodell-Fallen
- `stops.txt` Spaltenreihenfolge ist NICHT `stop_id,stop_name,...` — sie ist
`stop_name,parent_station,stop_id,stop_lat,stop_lon,...`. Beim Import die echte
stop_id aus den richtigen Spalten ziehen (parent_station ist oft die nutzbare ID).
- Ein Bahnhof hat **mehrere stop_ids** (Saarbruecken Hbf hat 6, nur je 1 aktiv in `st`;
Koeln Hbf hat 2). Geo-Merging (<350m) gruppiert sie; sonst matcht die Suche auf
eine tote ID und liefert „keine Verbindung".
- Zeit-Spalten: `HH:MM` ODER `HH:MM:SS` — to_sec() muss beides handhaben.
- COROS/Efa-Text-APIs liefern oft `\\n` als literalen Backslash-n statt echten
Zeilenumbruchen → vor dem Parsen `text.replace('\\n','\n')`.
## Performance-Falle bei Gesamt-Neuberechnung
Pro-Profile-Query (33 Abfahrtszeiten) × pro Verbindung ist zu teuer fuer ~12.000
Verbindungen (huubai 18h). Effizienter: **EIN Dijkstra/RAPTOR je eindeutiger
Start-Bahnhof (Ausbreitung zu allen Zielen in einem Lauf)** → ~250 Starts statt
12.000 × viele → von Stunden auf ~10min. Cache die Ausbreitung je Start und lese
die Ziel-Ankunft daraus ab.