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
+8 -6
View File
@@ -25,8 +25,8 @@ const delayColor = ["case",
const map = new maplibregl.Map({
container: "map",
center: [8.23, 46.82],
zoom: 7.4,
center: [9.6, 49.2], // Deutschland + Schweiz
zoom: 5.6,
hash: true,
style: {
version: 8,
@@ -50,7 +50,8 @@ const map = new maplibregl.Map({
route: { type: "geojson", data: EMPTY },
trains: {
type: "geojson", data: EMPTY,
attribution: 'Fahrplan &amp; Echtzeit: <a href="https://opentransportdata.swiss">opentransportdata.swiss</a>',
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)',
},
},
layers: [
@@ -234,7 +235,7 @@ async function refreshStatus() {
try {
const s = await (await fetch("api/status")).json();
if (!s.ready) {
loading.textContent = s.feed_version ? "Züge werden geladen …"
loading.textContent = s.loaded ? "Züge werden geladen …"
: "Fahrplan wird vorbereitet … beim ersten Start dauert das 15–20 Minuten.";
loading.hidden = false;
return;
@@ -244,8 +245,9 @@ async function refreshStatus() {
await refreshTrains();
loading.hidden = true;
}
const rtOk = s.realtime && !s.rt_error && s.rt_age !== null && s.rt_age < 180;
el.textContent = `${s.vehicles} Züge unterwegs` + (rtOk ? "" : " · Verspätungen zurzeit nicht verfügbar");
const rtOk = s.rt_ok;
el.textContent = `${s.vehicles} Züge unterwegs` + (rtOk ? "" : s.rt_some
? " · Verspätungen teilweise nicht verfügbar" : " · Verspätungen zurzeit nicht verfügbar");
el.className = rtOk ? "" : "warn";
} catch (e) {
loading.textContent = "Keine Verbindung zum Server …";