WIP: Deutschland als zweite Datenquelle (gtfs.de)

- mehrere Quellen (ch, de) mit je eigenem Fahrplan und Echtzeit-Feed
- OSM CH+DE, mit osmium auf Schienennetz gefiltert, für pfaedle
- Landesgrenze CH gegen doppelte grenzüberschreitende Züge
- Import robust gegen andere Spaltenreihenfolge (gtfs.de)
- Kacheln für CH+DE (Zoom 14)

Noch nicht vollständig getestet (pfaedle auf Deutschland läuft).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X48pE4bzjHej8w9HyZXCjb
This commit is contained in:
Claude
2026-10-21 21:27:54 +02:00
parent 2e3c10a6c4
commit 2a4962c379
11 changed files with 370 additions and 168 deletions
+30 -18
View File
@@ -1,23 +1,29 @@
# TrainPulse – Schweiz
# TrainPulse
Live-Karte aller Züge in der Schweiz: Position entlang der echten Strecke, Linie, Zugnummer,
Ziel, Verspätung und Fahrtverlauf mit Gleis. Hintergrund umschaltbar zwischen Karte
(OpenStreetMap) und Satellit (swisstopo SWISSIMAGE, ausserhalb der Schweiz Sentinel-2).
Live-Karte aller Züge in der Schweiz und in Deutschland: Position entlang der echten Strecke,
Linie, Ziel, Verspätung und Fahrtverlauf mit Gleis. Hintergrund umschaltbar zwischen Karte,
dunkler Karte (OpenStreetMap) und Satellit (swisstopo SWISSIMAGE, ausserhalb der Schweiz Sentinel-2).
## Wie es funktioniert
```
opentransportdata.swiss ──GTFS (Mo+Do)──▶ updater-Container (stündlich)
├─ Filter: nur Bahn (route_type 100–199)
OpenStreetMap (Geofabrik) ─────────────────▶├─ pfaedle: echte Streckenverläufe
└─▶ data/feeds/<version>/
opentransportdata.swiss ──GTFS-RT (35 s)──▶ web-Container (Port 8080)
├─ Position = Fahrplan + Verspätung, entlang Strecke
└─ /api/vehicles, /api/trip/…, /api/status, Weboberfläche
opentransportdata.swiss ──GTFS (Mo+Do)──┐
gtfs.de (DELFI) ─────────GTFS (täglich)──┼▶ updater-Container (stündlich)
│ ├─ Filter: nur Bahn (route_type 2, 100–199)
OpenStreetMap CH + DE (Geofabrik) ───────┴▶ ├─ osmium: nur Schienennetz, pfaedle: Streckenverläufe
└─▶ data/feeds/<ch|de>/<version>/
opentransportdata.swiss ──GTFS-RT (35 s)──┐
gtfs.de ─────────────────GTFS-RT (60 s)───┴▶ web-Container (Port 8080)
├─ Position = Fahrplan + Verspätung, entlang Strecke
└─ /api/vehicles, /api/trip/…, /api/status, Weboberfläche
```
Es gibt in der Schweiz **keine offenen GPS-Positionen** der Züge. Die Position wird aus Fahrplan
und gemeldeter Verspätung berechnet und auf den Streckenverlauf gelegt.
Es gibt **keine offenen GPS-Positionen** der Züge. Die Position wird aus Fahrplan und gemeldeter
Verspätung berechnet und auf den Streckenverlauf gelegt.
Beide Fahrpläne enthalten grenzüberschreitende Züge. Damit sie nicht doppelt erscheinen, zeigt der
Schweizer Fahrplan nur Züge innerhalb der Schweiz und der deutsche nur Züge ausserhalb
(Landesgrenze aus OpenStreetMap, `trainpulse/ch_border.json`).
Wechsel des Fahrplans: Neue Fahrpläne erscheinen Montag und Donnerstag zwischen 9 und 10 Uhr,
die Echtzeitdaten stellen erst um 15 Uhr um. Der Server lädt deshalb immer den Fahrplan, auf den
@@ -57,7 +63,7 @@ hinter deinen bestehenden Reverse Proxy hängen.
| Status | `curl localhost:8080/api/status` |
| Logs Webserver | `docker compose logs -f web` |
| Logs Fahrplan-Update | `docker compose logs -f updater` |
| Fahrplan sofort neu aufbereiten | `docker compose exec updater python -m trainpulse.prepare --force` |
| Fahrplan sofort neu aufbereiten | `docker compose exec updater python -m trainpulse.prepare --source de --force` (oder `ch`) |
| Selbsttest | `docker compose exec web python tests/test_core.py` |
| Stoppen / Starten | `docker compose down` / `docker compose up -d` |
@@ -65,7 +71,9 @@ hinter deinen bestehenden Reverse Proxy hängen.
Die Hinweise erscheinen unten rechts auf der Karte.
- Fahrplan & Echtzeit: [opentransportdata.swiss](https://opentransportdata.swiss) (Quellenangabe Pflicht)
- Fahrplan & Echtzeit Schweiz: [opentransportdata.swiss](https://opentransportdata.swiss) (Quellenangabe Pflicht)
- Fahrplan Deutschland: [gtfs.de](https://gtfs.de), Daten von DELFI e.V. (CC BY 4.0)
- Echtzeit Deutschland: [gtfs.de](https://gtfs.de/de/realtime/) (CC BY-SA 4.0, Beta, Abdeckung je nach Region)
- Karte: © OpenStreetMap-Mitwirkende (ODbL), Kacheln von [Protomaps](https://protomaps.com)
- Streckenverläufe: berechnet mit [pfaedle](https://github.com/ad-freiburg/pfaedle) aus OpenStreetMap-Daten (ODbL)
- Satellit Schweiz: © swisstopo (frei, Quellenangabe)
@@ -73,9 +81,13 @@ Die Hinweise erscheinen unten rechts auf der Karte.
## Bekannte Grenzen
- Nur Bahn. Busse, Trams und Schiffe sind im Fahrplan, werden aber noch herausgefiltert.
- Der Schweizer Fahrplan enthält auch einige ausländische Züge (z. B. TGV, TER); deren Strecke
ausserhalb der Schweiz ist nur Luftlinie, weil der OSM-Ausschnitt nur die Schweiz abdeckt.
- Nur Bahn. Busse, Trams und U-Bahnen sind im Fahrplan, werden aber noch herausgefiltert.
- Züge des Schweizer Fahrplans im übrigen Ausland (z. B. Tirano, Domodossola, Frankreich)
werden nicht angezeigt, sobald sie die Schweiz verlassen.
- Der kostenlose deutsche Fahrplan enthält keine Zugnummern und kein Fahrtziel; angezeigt
wird als Ziel der letzte Halt.
- Der deutsche Echtzeit-Feed ist ~6 MB gross (komprimiert). Bei einem Abruf pro Minute sind das
rund 9 GB Datenverkehr pro Tag.
- Zwischen zwei Abfragen fahren die Züge auf gerader Linie; in engen Kurven schneiden sie
für ein paar Sekunden minimal ab.
- Zusätzliche Fahrten, die nur in den Echtzeitdaten vorkommen (Extrazüge), fehlen.