Belgien: offizielle NMBS/SNCB-Feeds mit Echtzeit; Gleis-IDs (8863008_10) auf Bahnhof abgleichen

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-22 08:17:58 +02:00
parent ae50ac39ac
commit 53b7c24a81
5 changed files with 13 additions and 11 deletions
+5 -6
View File
@@ -9,7 +9,7 @@ dunkler Karte (OpenStreetMap) und Satellit (swisstopo SWISSIMAGE, ausserhalb der
```
Fahrpläne (GTFS) ─────────────────────────┐
CH opentransportdata.swiss, DE gtfs.de, ├▶ updater-Container (stündlich)
FR SNCF, NL OVapi, BE GTFS.be │ ├─ Filter: nur Bahn (route_type 2, 100–199)
FR SNCF, NL OVapi, BE NMBS/SNCB │ ├─ Filter: nur Bahn (route_type 2, 100–199)
OpenStreetMap (Geofabrik, 5 Länder) ──────┘ ├─ osmium: nur Schienennetz, je Land zugeschnitten
├─ pfaedle: Streckenverläufe
└─▶ data/feeds/<ch|de|fr|nl|be>/<version>/
@@ -80,7 +80,7 @@ Die Hinweise erscheinen unten rechts auf der Karte.
- Echtzeit Deutschland: [gtfs.de](https://gtfs.de/de/realtime/) (CC BY-SA 4.0, Beta, Abdeckung je nach Region)
- Frankreich: SNCF über [transport.data.gouv.fr](https://transport.data.gouv.fr/datasets/horaires-sncf) (ODbL), Fahrplan und Echtzeit
- Niederlande: [OVapi / Stichting OpenGeo](https://gtfs.ovapi.nl), Fahrplan und Echtzeit
- Belgien: [GTFS.be](https://gtfs.be) (Community-Feed aus NMBS/SNCB-Daten), nur Fahrplan
- Belgien: NMBS/SNCB [Open Data](https://www.belgiantrain.be/en/3rd-party-services/mobility-service-providers/public-data) (HAFAS-Feeds), Fahrplan und Echtzeit
- Landesgrenzen: [Natural Earth](https://www.naturalearthdata.com) (gemeinfrei) und OpenStreetMap
- 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)
@@ -96,11 +96,10 @@ Die Hinweise erscheinen unten rechts auf der Karte.
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; die anderen Länder zusammen ~4 GB.
- Belgien hat keine offene Echtzeit (nur nach Registrierung bei data.belgianmobility.io). Wer einen
GTFS-RT-Zugang hat, trägt URL und Key als `TRAINPULSE_BE_RT_URL` / `TRAINPULSE_BE_RT_KEY` in `.env` ein.
- Belgien: die Feed-Adressen unter sncb-opendata.hafas.de sind nicht offiziell dokumentiert und
laufen evtl. aus (die NMBS stellt auf data.belgianmobility.io um). Dann neue Adresse als
`TRAINPULSE_BE_RT_URL` (und ggf. `TRAINPULSE_BE_RT_KEY`) in `.env` eintragen.
- Paris (RER/Transilien) ist nicht enthalten – das ist ein eigener Datensatz.
- 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.
- In der Nacht des Fahrplanwechsels (2. Sonntag im Dezember) fehlen bis zum nächsten
stündlichen Lauf die Züge.
+1 -1
View File
@@ -149,7 +149,7 @@ def test_all():
fm.header.gtfs_realtime_version = "2.0"
e = fm.entity.add(id="1")
e.trip_update.trip.trip_id, e.trip_update.trip.start_date = "T1", "20261021"
st = e.trip_update.stop_time_update.add(stop_id="B")
st = e.trip_update.stop_time_update.add(stop_id="B_7") # Belgien: Gleis als Suffix
st.arrival.delay = st.departure.delay = 300
_, rt = realtime.parse(fm.SerializeToString(), f.trip_index)
assert rt[("T1", "20261021")][1][0][0] is None
+4 -3
View File
@@ -35,9 +35,10 @@ SOURCES = {
"needs_key": False,
"rt_interval": 60, # OVapi: nicht öfter als 1x pro Minute
},
"be": { # SNCB/NMBS über GTFS.be (Community-Feed); Echtzeit nur mit Registrierung -> vorerst ohne
"gtfs_url": "https://data.gtfs.be/sncb/gtfs/be-sncb-gtfs.zip",
"rt_url": os.environ.get("TRAINPULSE_BE_RT_URL", ""),
"be": { # SNCB/NMBS offizielle Open-Data-Feeds (HAFAS); Fahrplan täglich, Echtzeit passt zu dessen trip_ids
"gtfs_url": "https://sncb-opendata.hafas.de/gtfs/static/c21ac6758dd25af84cca5b707f3cb3de",
"rt_url": os.environ.get("TRAINPULSE_BE_RT_URL",
"https://sncb-opendata.hafas.de/gtfs/realtime/d22ad6759ee25bg84ddb6c818g4dc4de_TC"),
"rt_key": os.environ.get("TRAINPULSE_BE_RT_KEY", ""),
"needs_key": False,
"rt_interval": 60,
+2
View File
@@ -315,6 +315,8 @@ class Feed:
# Frankreich, Niederlande: nur Haltestellen-ID; über den Bahnhof abgleichen, damit es
# auch bei Gleiswechsel passt, und der Reihe nach (eine Fahrt kann einen Bahnhof zweimal haben)
k = self.stop_index.get(u[1])
if k is None: # Belgien meldet das Gleis ("8863008_10"), der Fahrplan nur den Bahnhof ("8863008")
k = self.stop_index.get(u[1].rsplit("_", 1)[0])
if k is None:
continue
for i in range(j, len(stops)):
+1 -1
View File
@@ -60,7 +60,7 @@ const map = new maplibregl.Map({
attribution: 'Fahrplan &amp; Echtzeit: <a href="https://opentransportdata.swiss">opentransportdata.swiss</a>, '
+ '<a href="https://gtfs.de">gtfs.de</a> (<a href="https://www.delfi.de">DELFI e.V.</a>, CC BY-SA 4.0), '
+ '<a href="https://transport.data.gouv.fr/datasets/horaires-sncf">SNCF</a> (ODbL), '
+ '<a href="https://gtfs.ovapi.nl">OVapi</a>, <a href="https://gtfs.be">GTFS.be</a> (NMBS/SNCB)',
+ '<a href="https://gtfs.ovapi.nl">OVapi</a>, <a href="https://www.belgiantrain.be/en/3rd-party-services/mobility-service-providers/public-data">NMBS/SNCB</a>',
},
},
layers: [