diff --git a/README.md b/README.md index ed4f915..ceec1db 100644 --- a/README.md +++ b/README.md @@ -85,158 +85,3 @@ CSS Custom Properties und `dvh`-Einheiten (mit `vh`-Fallback). Kein IE11-Support ins Englische findet nicht statt (nur die App-Oberfläche selbst ist zweisprachig). - Fahrtalarm-Ton und Vollbild-Overlay funktionieren nur bei offenem Tab; bei geschlossenem Browser zeigt ein Push nur die Systembenachrichtigung. - - - -# ÖPNV Navi – Backend - -Node.js/Express-Backend für die ÖPNV-Navi-App: bündelt VBB-HAFAS, -DB-IRIS (echte Bahnhöfe), eine selbst gehostete OTP2-Instanz für die -Routenplanung sowie Web-Push-Benachrichtigungen hinter einer gemeinsamen API. - -## Tech-Stack - -- Node.js, Express -- [hafas-client](https://github.com/public-transport/hafas-client) (VBB-Profil) -- DB-IRIS (XML, via `fast-xml-parser`) für echte DB-Bahnhöfe -- OTP2 (GraphQL GTFS API) für die Routenplanung – **eigene, extern laufende - OTP2-Instanz vorausgesetzt**, wird hier nicht mitgeliefert -- `better-sqlite3` für Favoriten, Verspätungsstatistik und Web-Push-Subscriptions -- `web-push` für Browser-Push-Benachrichtigungen -- `helmet`, `cors`, `express-rate-limit`, `morgan` - -## Einrichtung - -```bash -npm install -``` - -### Umgebungsvariablen (`.env`) - -| Variable | Pflicht | Beschreibung | -|---|---|---| -| `PORT` | nein | Port, auf dem der Server lauscht (Standard siehe `server.js`) | -| `HAFAS_USER_AGENT` | nein | User-Agent für HAFAS-Anfragen | -| `DB_PATH` | nein | Pfad zur SQLite-Datenbankdatei (Standard: `./data/oepnv-navi.sqlite`) | -| `VAPID_PUBLIC_KEY` | für Web-Push | Öffentlicher VAPID-Schlüssel | -| `VAPID_PRIVATE_KEY` | für Web-Push | **Geheim!** Privater VAPID-Schlüssel | -| `VAPID_SUBJECT` | für Web-Push | `mailto:deine@email.de` | - -VAPID-Keys einmalig erzeugen: - -```bash -npx web-push generate-vapid-keys -``` - -Ohne `VAPID_PUBLIC_KEY`/`VAPID_PRIVATE_KEY` bleibt Web-Push deaktiviert -(Warnung im Log beim Start), der Rest der App läuft normal weiter. - -**Wichtig:** `VAPID_PRIVATE_KEY` ist ein echtes Geheimnis – nicht ins -Git-Repo committen, `.env` gehört in die `.gitignore`. - -### Start - -```bash -npm start # node src/server.js -npm run dev # mit --watch (Node 18+) -``` - -## Ordnerstruktur - -``` -backend/ -├── package.json -└── src/ - ├── server.js Express-App, Middleware, Routen-Mounting, Hintergrund-Jobs - ├── db/ - │ └── database.js SQLite-Setup + Schema (Favoriten, Verspätungen, Push) - ├── middleware/ - │ └── apiKey.js X-API-Key-Schutz (nur für /push/register, APNs) - ├── routes/ - │ ├── locations.js / stations Haltestellen-/Adress-/POI-Suche - │ ├── departures.js VBB-Abfahrten (+ Störungen) - │ ├── dbTimetables.js DB-IRIS-Abfahrten für echte Bahnhöfe (+ Störungen) - │ ├── summary.js Sammel-Endpunkt für mehrere Haltestellen (Favoriten) - │ ├── trip.js Fahrt-Details (Zwischenhalte, Live-Position) - │ ├── otpJourneys.js Routenplanung über die eigene OTP2-Instanz - │ ├── journeys.js Ältere HAFAS-basierte Routenplanung (Legacy) - │ ├── radar.js Fahrzeugpositionen im Kartenausschnitt - │ ├── disruptions.js Ortsbezogene Störungen - │ ├── remarks.js Netzweite Störungsmeldungen - │ ├── fares.js VBB-Tarifzonen + BVG-Preise - │ ├── favorites.js Server-seitige Favoriten (Legacy/optional) - │ ├── delayStats.js Verspätungsstatistik pro Linie - │ ├── webPush.js Web-Push: Subscribe/Unsubscribe/Fahrtalarm - │ ├── push.js APNs-Registrierung für die separate iOS-App - │ └── health.js Health-Dashboard (/health/full, /health/dashboard) - └── utils/ - ├── hafas.js Zentraler HAFAS-Client - ├── vbbDepartures.js VBB-Abfahrten-Kernlogik + Verspätungs-Aufzeichnung - ├── dbIris.js / dbDepartureMerge.js / dbDeparturesService.js - │ DB-IRIS-Kernlogik (Planwerte + Echtzeit-Änderungen mergen) - ├── dbStations.js ~5.400 echte DB-Bahnhöfe (dynamischer Import, ESM) - ├── otpClient.js OTP2-GraphQL-Client (Routenplanung, Umstiegszeit, Rollstuhl) - ├── disruptionFilter.js "Echte Störung" vs. Rauschen, Gleisänderungs-Anreicherung - ├── delayStats.js Aggregation der Verspätungsstatistik - ├── tripInfo.js Gemeinsame Fahrt-Detail-Logik (Route + Push-Job) - ├── webPush.js web-push-Wrapper (VAPID, Versand, Fehlerbehandlung) - ├── pushStore.js DB-Zugriff für Push-Subscriptions/Favoriten/Fahrtalarme - ├── pushJobs.js Hintergrund-Jobs: Störungs-Check (60s) & Fahrtalarm-Check (20s) - ├── lineColors.js Linienfarben (vbb-line-colors + Fallback-Heuristik) - ├── products.js Verkehrsmittel-Filter-Mapping - ├── vbbFareZones.js / bvgPriceScraper.js - │ Tarifzonen + Preise, täglich automatisch aktualisiert - ├── cache.js Einfacher In-Memory-TTL-Cache - └── hafasErrors.js Nutzerfreundliche Fehlermeldungen für HAFAS-Fehler -``` - -## API-Endpunkte (Übersicht) - -Alle Pfade relativ zum konfigurierten Basis-Pfad (z. B. `/live_navi`). - -| Bereich | Endpunkte | -|---|---| -| Suche | `GET /locations`, `GET /stations` (Alias) | -| Abfahrten | `GET /departures/:stationId`, `GET /db/departures/:evaNo` | -| Sammel-Abfahrten | `POST /summary/departures` | -| Fahrt-Details | `GET /trip/:id` | -| Routenplanung | `GET /otp/journeys` (OTP2), `GET /journeys` (Legacy/HAFAS) | -| Live-Karte | `GET /radar` | -| Störungen | `GET /disruptions/nearby`, `GET /remarks` | -| Tarife | `GET /fares` | -| Favoriten | `GET/POST/DELETE /favorites` | -| Verspätungsstatistik | `GET /stats/delays/:line` | -| Web-Push | `GET /webpush/public-key`, `POST /webpush/subscribe`, `POST /webpush/unsubscribe`, `POST/DELETE /webpush/trip-alarm` | -| APNs (iOS-App) | `POST /push/register` | -| Health | `GET /health/full`, `GET /health/dashboard` | - -## Datenbank (SQLite) - -Automatisch angelegt beim ersten Start (`db/database.js`): - -- `favorites` – server-seitige Favoriten (optional, Client nutzt primär `localStorage`) -- `push_tokens` – APNs-Geräte-Tokens (iOS-App) -- `delay_samples` – Verspätungs-Rohdaten pro Fahrt, passiv befüllt bei jeder - normalen Abfahrten-Abfrage; alte Einträge (>90 Tage) werden täglich automatisch gelöscht -- `push_subscriptions` – Web-Push-Abos (ein Datensatz pro Browser/Gerät) -- `push_favorite_stations` – Kopie der Favoriten-Haltestellen je Abo (für den Störungs-Job) -- `push_trip_alarms` – höchstens ein aktiver Fahrtalarm je Abo - -## Hintergrund-Jobs - -Beim Start (`server.js`) registriert: - -- Vorwärmen des DB-Bahnhofs-Caches -- Tägliches Neuladen der VBB-Tarifzonen und BVG-Preise -- Tägliches Aufräumen alter Verspätungs-Samples -- **Störungs-Check** (alle 60s): prüft für jede Web-Push-Subscription die - verknüpften Favoriten-Haltestellen auf neue Störungen, verschickt bei Bedarf Push -- **Fahrtalarm-Check** (alle 20s): prüft aktive, per Push gespiegelte Fahrtalarme - und löst bei Erreichen der Zielhaltestelle aus - -## Abhängigkeiten außerhalb dieses Repos - -- Eine laufende **OTP2-Instanz** (VBB-GTFS + Berlin/Brandenburg-OSM) für die - Routenplanung – Adresse in `utils/otpClient.js` konfigurieren -- Ein Reverse Proxy (z. B. NPM/nginx), der den gewünschten Pfad (z. B. - `/live_navi`) auf diesen Node-Prozess weiterleitet diff --git a/index.html b/index.html index 711f23a..d84451c 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + ÖPNV Navi – Live-Abfahrten für Berlin & Brandenburg diff --git a/styles.css b/styles.css index ad07b2a..4012a5e 100644 --- a/styles.css +++ b/styles.css @@ -50,6 +50,20 @@ html, body { Live-Karte (100vw kann inkl. Scrollbar-Breite minimal über die tatsächliche Fensterbreite hinausschießen). */ overflow-x: hidden; + /* Unterdrückt Doppel-Tipp-Zoom auf Mobilgeräten, den manche Browser auch + bei user-scalable=no im Viewport-Meta-Tag noch zulassen - normales + vertikales Scrollen/Wischen bleibt davon unberührt. Die Live-Karte ist + unten explizit ausgenommen, damit Leaflets eigene Pinch-Geste zum + Zoomen der Karte selbst weiterhin funktioniert. */ + touch-action: manipulation; +} + +/* Ausnahme für die Live-Karte: Leaflet steuert das Zoomen/Verschieben der + Kartenansicht komplett selbst über eigene Touch-Gesten (unabhängig vom + deaktivierten Seiten-Zoom oben) - braucht dafür die volle Touch-Kontrolle. */ +#live-map, +#live-map * { + touch-action: none; } button {