import os from pathlib import Path DATA_DIR = Path(os.environ.get("TRAINPULSE_DATA", "/var/lib/trainpulse")) FEEDS_DIR = DATA_DIR / "feeds" # fertig aufbereitete Fahrpläne: feeds/// TZ = "Europe/Zurich" # Datenquellen. Jede hat einen GTFS-Fahrplan und einen passenden GTFS-RT-Feed (Trip Updates). SOURCES = { "ch": { # opentransportdata.swiss; GTFS-URL leer = automatisch das aktuelle Fahrplanjahr "gtfs_url": os.environ.get("TRAINPULSE_GTFS_URL", ""), "rt_url": os.environ.get("TRAINPULSE_RT_URL", "https://api.opentransportdata.swiss/la/gtfs-rt"), "rt_key": os.environ.get("TRAINPULSE_RT_KEY", ""), "needs_key": True, "rt_interval": 35, # Limit sind 2 Abfragen/Minute (Sliding Window) }, "de": { # gtfs.de (Daten von DELFI e.V.), Fahrplan CC BY 4.0, Echtzeit CC BY-SA 4.0 "gtfs_url": os.environ.get("TRAINPULSE_DE_GTFS_URL", "https://download.gtfs.de/germany/free/latest.zip"), "rt_url": os.environ.get("TRAINPULSE_DE_RT_URL", "https://realtime.gtfs.de/realtime-free.pb"), "rt_key": "", "needs_key": False, "rt_interval": 60, # ~6 MB pro Abruf, öfter lohnt sich nicht }, "fr": { # SNCF (TGV, Intercités, TER) über transport.data.gouv.fr, ODbL "gtfs_url": "https://eu.ftp.opendatasoft.com/sncf/plandata/Export_OpenData_SNCF_GTFS_NewTripId.zip", "rt_url": "https://proxy.transport.data.gouv.fr/resource/sncf-gtfs-rt-trip-updates", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "nl": { # OVapi / Stichting OpenGeo; Züge und Trams/Metro stehen in zwei getrennten Feeds "gtfs_url": "https://gtfs.ovapi.nl/nl/gtfs-nl.zip", # mehrere Echtzeit-Adressen durch Leerzeichen getrennt "rt_url": "https://gtfs.ovapi.nl/nl/trainUpdates.pb https://gtfs.ovapi.nl/nl/tripUpdates.pb", "rt_key": "", "needs_key": False, "rt_interval": 60, # OVapi: nicht öfter als 1x pro Minute }, "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, }, # Spanien: Renfe hat Fern-/Regionalverkehr und Cercanías (S-Bahn) als getrennte Fahrpläne "es": { # Renfe AVE, Alvia, Media Distancia …; Echtzeit ohne Datum, Trip-IDs enthalten den Tag "gtfs_url": "https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_transit.zip", "rt_url": "https://gtfsrt.renfe.com/trip_updates_LD.pb", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "es_cer": { # Renfe Cercanías/Rodalies (alles S-Bahn) "country": "es", "all_sbahn": True, "gtfs_url": "https://ssl.renfe.com/ftransit/Fichero_CER_FOMENTO/fomento_transit.zip", "rt_url": "https://gtfsrt.renfe.com/trip_updates.pb", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "pl": { # alle Bahnbetreiber, aufbereitet von Mikołaj Kuranowski (mkuran.pl); Echtzeit CC BY 4.0 "gtfs_url": "https://mkuran.pl/gtfs/polish_trains.zip", "rt_url": "https://mkuran.pl/gtfs/polish_trains/updates.pb", "rt_key": "", "needs_key": False, "rt_interval": 120, # ~5 MB pro Abruf }, "no": { # Entur (NLOD); Gesamt-Echtzeit wäre 15 MB, darum nur die Betreiber von Bahn, Tram, T-bane "gtfs_url": "https://storage.googleapis.com/marduk-production/outbound/gtfs/rb_norway-aggregated-gtfs.zip", "rt_url": " ".join(f"https://api.entur.io/realtime/v1/gtfs-rt/trip-updates?datasource={ds}" for ds in ("VYG", "FLT", "GOA", "RUT", "ATB", "SKY")), "rt_key": "", "needs_key": False, "rt_interval": 60, }, "dk": { # Rejseplanen (alle Verkehrsmittel); keine offene Echtzeit "gtfs_url": "https://www.rejseplanen.info/labs/GTFS.zip", "rt_url": "", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "at": { # ÖBB (CC BY 4.0), einmal pro Fahrplanjahr ({year}); keine offene Echtzeit "gtfs_url": "https://static.web.oebb.at/open-data/soll-fahrplan-gtfs/GTFS_Fahrplan_{year}.zip", "rt_url": "", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "at_wl": { # Wiener Linien (Tram, U-Bahn, Badner Bahn), CC BY 4.0 "country": "at", "check_hours": 24, # Server nennt kein Datum: 1x täglich laden (~100 MB) und Inhalt vergleichen "gtfs_url": "http://www.wienerlinien.at/ogd_realtime/doku/ogd/gtfs/gtfs.zip", "rt_url": "", "rt_key": "", "needs_key": False, "rt_interval": 60, }, "se": { # Trafiklab GTFS Sweden 3 (alle Züge); kostenloser Key nötig, auch für den Fahrplan "gtfs_url": "https://opendata.samtrafiken.se/gtfs-sweden/sweden.zip?key={key}", # Echtzeit nur für einige Regionen (Stockholm, Skåne); Züge landesweit noch nicht "rt_url": " ".join("https://opendata.samtrafiken.se/gtfs-rt-sweden/{op}/TripUpdatesSweden.pb?key={key}".replace("{op}", op) for op in ("sl", "skane")), "rt_key": os.environ.get("TRAINPULSE_SE_KEY", ""), "needs_key": True, "static_needs_key": True, # Bronze-Key: 30 000 Echtzeit- und 50 Fahrplan-Abrufe im Monat "rt_interval": int(os.environ.get("TRAINPULSE_SE_RT_INTERVAL") or 300), "check_hours": 48, }, } ENABLED = [s for s in (os.environ.get("TRAINPULSE_SOURCES") or ",".join(SOURCES)).split(",") if s in SOURCES] def country(source: str) -> str: """Land einer Quelle (Spanien und Österreich haben je zwei).""" return SOURCES[source].get("country", source) # OpenStreetMap: daraus werden das Schienennetz (für pfaedle) gefiltert OSM_URLS = os.environ.get("TRAINPULSE_OSM_URLS", " ".join([ "https://download.geofabrik.de/europe/switzerland-latest.osm.pbf", "https://download.geofabrik.de/europe/germany-latest.osm.pbf", "https://download.geofabrik.de/europe/france-latest.osm.pbf", "https://download.geofabrik.de/europe/netherlands-latest.osm.pbf", "https://download.geofabrik.de/europe/belgium-latest.osm.pbf", "https://download.geofabrik.de/europe/austria-latest.osm.pbf", "https://download.geofabrik.de/europe/denmark-latest.osm.pbf", "https://download.geofabrik.de/europe/spain-latest.osm.pbf", "https://download.geofabrik.de/europe/norway-latest.osm.pbf", "https://download.geofabrik.de/europe/poland-latest.osm.pbf", "https://download.geofabrik.de/europe/sweden-latest.osm.pbf", ])).split() PFAEDLE = os.environ.get("TRAINPULSE_PFAEDLE", "pfaedle") OSMIUM = os.environ.get("TRAINPULSE_OSMIUM", "osmium") PMTILES = os.environ.get("TRAINPULSE_PMTILES", "pmtiles") TILES_BBOX = "-9.6,35.8,31.3,71.3" # von Galicien bis Nordkap, Andalusien bis Finnmark TILES_MAXZOOM = 14 # die Karte vergrössert Vektorkacheln darüber hinaus selbst; spart viel Platz USER_AGENT = "trainpulse/0.1 (+https://scarriffle.com)"