Initial: Mesh-Skills, Configs, Scripts
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# GTFS-RAPTOR-Verbindungssuche: Praxis & Pitfalls (2026-08-19, urlaub.perfekt-ohne-en.de)
|
||||
|
||||
Echte Nahverkehrs-Verbindungs-Suche (RE/RB/S-Bahn, kein ICE) aus einer GTFS-Datei
|
||||
(Nutzer lieferte `r.und.s.bahnen.zip`). Löst die Aufgabe "komplette Haltestellenliste
|
||||
in einer PDF + konsistente Fahrzeiten für viele Zielverbindungen".
|
||||
|
||||
## Warum RAPTOR statt Dijkstra
|
||||
|
||||
Einfacher Dijkstra auf einem statischen Graphen ist bei großen Knoten **instabil**:
|
||||
benachbarte Ziele ergaben absurde Differenzen (Mainz→Berlin 11h vs. Nachbar Wiesbaden
|
||||
3h). **RAPTOR** (Round-Based Public Transit Optimized Route) erweitert die Reichweite
|
||||
Runde um Runde über echte Trips und behandelt "Zug nehmen → aussteigen → umsteigen"
|
||||
natürlich. Für Zeit-abhängiges Transit-Routing ist RAPTOR der Standard.
|
||||
|
||||
## GTFS-Import — Spaltenreihenfolge ist NICHT selbsterklärend!
|
||||
|
||||
Vor dem Import IMMER `head -1 <datei>.txt` lesen, nie annehmen:
|
||||
|
||||
- `stops.txt`: `stop_name, parent_station, stop_id, stop_lat, stop_lon, …`
|
||||
**stop_id ist Spalte 3**, parent_station Spalte 2. Ein Bahnhof hat oft ZWEI Zeilen
|
||||
(parent-'Hbf' + stop_id-Knoten); die `stop_id` ist fürs Joinen zu `stop_times` gedacht.
|
||||
- `stop_times.txt`: `trip_id, arrival_time, departure_time, stop_id, stop_sequence, …`
|
||||
**stop_id Spalte 4**.
|
||||
- `trips.txt`: `route_id, service_id, trip_id` — **trip_id Spalte 3**, nicht 0.
|
||||
Import-Bug hier: Spalte 0 (route_id) genommen → nur 964 statt 110.087 Trips.
|
||||
- `stop_times.txt` ist riesig (82MB); als SQLite laden mit Index auf `(trip_id, seq)`.
|
||||
|
||||
## Bahnhof = mehrere stop_ids, nur 1 aktiv in `st`
|
||||
|
||||
Große Knoten haben MEHRERE stop_ids (Saarbrücken Hbf = 6, Köln Hbf = 2), aber nur
|
||||
einige kommen in `stop_times` vor. `SELECT stop_id WHERE stop_name='Köln Hbf'` kann eine
|
||||
"tote" ID mit 0 Trips liefern. **Lösung: Geo-Merge** — Stops <350m Abstand (Haversine)
|
||||
in eine Gruppe fassen; Routing löst Start/Ziel über die GANZE Gruppe auf und nimmt MIN
|
||||
über alle Ziel-IDs. Sonst schlägt die Verbindung fehl oder wird absurd.
|
||||
|
||||
## `resolve("Berlin")`-Substring-Falle
|
||||
|
||||
`name.lower() in stop_name.lower()` matcht ALLE Stops mit "berlin" im Namen — auch
|
||||
kleine Orte (z.B. ein Ort "Berlin" unweit Trier → unter 5h statt quer durchs Land!).
|
||||
Für mehrdeutige Städte IMMER eindeutigen Bahnhof angeben (`"Berlin Hbf"`) und die
|
||||
Site-DB-`nach`-Werte darauf normieren. Umlaute: Name-basiertes Matching braucht
|
||||
Umlaut-Rücktranskription (ue/oe/ae/ss ↔ ü/ö/ä/ß).
|
||||
|
||||
## RAPTOR: Dauer UND Pfad (für PDF-Haltestellenliste)
|
||||
|
||||
Nur Dauer reicht nicht — die PDF soll die komplette Haltestellenliste zeigen. RAPTOR
|
||||
muss pro Stop den **parent** speichern (mit welchem trip + Einstieg-Stop erreicht) und
|
||||
nach Ziel-Erreichen den Pfad rückwärts rekonstruieren: je Segment alle Stops von
|
||||
Einstieg bis Ausstieg → echte GTFS-Haltefolge (Trier→Konz→Saarburg→…→Saarbrücken).
|
||||
Für Lesbarkeit `[von] + halteliste + [nach]` als Rahmen.
|
||||
|
||||
## PDF-Route: Pfad-Cache statt Live-RAPTOR (sonst 504)
|
||||
|
||||
Live-RAPTOR bei jedem PDF-Aufruf ist zu langsam (bis 200s → nginx 504 Gateway Timeout).
|
||||
Lösung: **Pfad-Cache vorab bauen** (`pfade_cache.json`: key `von|nach` → seg + dauer_h)
|
||||
und die PDF-Route liest nur JSON → PDF <1s.
|
||||
⚠️ Cache auf die Kern-Ebenen (1+2) begrenzen: alle Paare wären ~7h Bauzeit, die
|
||||
Kernmenge ~35min.
|
||||
|
||||
## Start ohne Bahnhof (Radevormwald) → Remap + Bus-Vorsatz
|
||||
|
||||
Ein Startort ohne Schienenanschluss hat KEINEN Stop im Feed → Routing fehlt für die
|
||||
wichtigste Ebene 1. Lösung: auf nächstgelegenen Bahnhof remappen (Radevormwald →
|
||||
Remscheid-Lennep Bf) und einen Bus-Vorsatz (~20min) als erstes "Segment" + zur Dauer
|
||||
addieren. Solche Fälle explizit als `START_REMAP = {ort: (bahnhof, bus_min)}` führen,
|
||||
sonst fehlt die Ebene-1-PDF komplett.
|
||||
|
||||
## Unsichere/absurde Fernzeiten → "prüfen", nie falsch anzeigen
|
||||
|
||||
Auch RAPTOR liefert auf manchen komplexen Fernstrecken falsche Werte (z.B. >10h, wenn
|
||||
Routing fehlschlug; real Regional 6–9h). Ehrlich handeln: plausible Werte behalten,
|
||||
unsichere (>10h / 0.0h / leer) als **`'prüfen'` mit Kategorie `unsicher (vor Fahrt
|
||||
prüfen)`** markieren, und das Template zeigt „vor Fahrt prüfen" statt einer Zahl. Das
|
||||
Template muss jede unsichere Kategorie in seiner Gruppen-Map führen, sonst
|
||||
verschwinden die Zeilen still.
|
||||
|
||||
## Empirische Referenz-Anker (Plausibilitäts-Check, Regional only)
|
||||
|
||||
- Trier→Saarbrücken ~55–60min (RE 1 direkt)
|
||||
- Köln→Aachen ~35–50min (RE 1/RE 9)
|
||||
- Köln→Frankfurt regional ~2,5–3h MIT Umstiegen (~1,5h wäre nur ICE = NICHT korrekt)
|
||||
- Radevormwald→Frankfurt ~5,5h (Bus + Remscheid-Lennep + Regional)
|
||||
- Verifizieren mit diesen Ankern, NIE dem Algorithmus blind vertrauen.
|
||||
Reference in New Issue
Block a user