# Geo-Dienste: OSRM (Routing) + Nominatim (Geocoding)

Selbstgehostete Geo-Dienste auf einem **Österreich-OSM-Extrakt** (Geofabrik).
Sie liefern die Eintreffzeit-Sortierung (`orderByEintreffzeit`) und die
Adress-Geokodierung (`geocodeAddress`). Beide Dienste laufen in einem
**internen** Compose-Netz und sind nur für den App-Container erreichbar.

## Komponenten

- **OSRM** (`ghcr.io/project-osrm/osrm-backend`, `--algorithm mld`) — `/table`
  liefert die Fahrzeit-Matrix von EINER Quelle (`sources=0`) zu N Zielen.
  Koordinaten in OSRM-Reihenfolge `lng,lat`.
- **Nominatim** (`mediagis/nominatim`) — `/search?countrycodes=at` geokodiert
  österreichische Adressen.

## Erstinbetriebnahme

> Achtung: Import/Preprocessing brauchen Netzzugriff (Geofabrik, ~700 MB–1 GB),
> mehrere GB RAM/Disk und Zeit (Minuten bis Stunden). Nicht in CI/Sandbox.

1. **OSRM-Daten vorbereiten** (extract → partition → customize):

   ```bash
   make -C infra/geo data      # oder: scripts/prepare-osm-data.sh
   ```

   Erzeugt das `.osrm`-Set in `infra/geo/data` und füllt das OSRM-Volume.

2. **Dienste starten**:

   ```bash
   make -C infra/geo up
   # entspricht:
   # docker compose -f docker-compose.yml -f docker-compose.geo.yml up -d osrm nominatim
   ```

   Nominatim importiert beim ersten Start den PBF-Extrakt automatisch.

3. **Health prüfen** (intern, über die App):

   ```bash
   make -C infra/geo health     # ruft GET /api/geo/health (auth-gated)
   ```

## Konfiguration (kanonisch in `src/lib/env.ts`)

| Variable             | Default                  | Zweck                                  |
| -------------------- | ------------------------ | -------------------------------------- |
| `OSRM_URL`           | `http://osrm:5000`       | Basis-URL des OSRM-Dienstes            |
| `NOMINATIM_URL`      | `http://nominatim:8080`  | Basis-URL des Nominatim-Dienstes       |
| `GEO_HTTP_TIMEOUT_MS`| `4000`                   | Timeout/Abort für Geo-HTTP-Aufrufe     |
| `HAVERSINE_KMH`      | `50`                     | Durchschnittstempo der Luftlinie-Fallback-Schätzung |

## Fallback-Verhalten

Fällt OSRM aus, schaltet `orderByEintreffzeit` **vollständig** auf die
Haversine-Luftlinie um (`mode: "haversine"`, `isFallback: true`). Die UI
kennzeichnet diese Werte als „Luftlinie (geschätzt)" (`EtaBadge`). Wehren ohne
Koordinaten landen stets am Ende der Liste.

## Daten-Updates

Der Geofabrik-Extrakt veraltet. Aktualisierung ist ein manueller Lauf:

```bash
make -C infra/geo data && make -C infra/geo up
```
