2026-06-12 09:29:50 +00:00
|
|
|
|
# Maintainer-Handbuch – rd13_tile_server
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
|
|
|
|
|
> Zielgruppe: **Entwickler & Maintainer** – Menschen, die den Code verstehen, erweitern oder reviewen.
|
2026-06-12 09:29:50 +00:00
|
|
|
|
> Voraussetzung: Entwicklungserfahrung mit Docker, MapLibre GL Styles, OSM-Daten.
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-06-12 09:29:50 +00:00
|
|
|
|
## Architektur – Martin + tileserver-gl Stack
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
|
|
|
|
|
```
|
2026-06-12 09:29:50 +00:00
|
|
|
|
Internet (HTTPS)
|
|
|
|
|
|
↓
|
|
|
|
|
|
NPM Reverse Proxy (tiles.rd13server.de, Rate Limiting)
|
|
|
|
|
|
├─ /osm/{z}/{x}/{y}.pbf → Martin (Vektor-Tiles)
|
|
|
|
|
|
└─ /osm-intl/{z}/{x}/{y}.png → tileserver-gl (Raster-PNG)
|
|
|
|
|
|
↓
|
|
|
|
|
|
tileserver-gl renders Martin Vektor → PNG
|
|
|
|
|
|
↓
|
|
|
|
|
|
Martin reads osm.mbtiles (Vector Tiles)
|
|
|
|
|
|
↓
|
|
|
|
|
|
/data/osm.mbtiles (OpenFreeMap snapshot)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-06-12 09:29:50 +00:00
|
|
|
|
**Stack-Komponenten:**
|
|
|
|
|
|
|
|
|
|
|
|
| Komponente | Input | Output | Verantwortung |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| **Martin** | `osm.mbtiles` | `/{layer}/{z}/{x}/{y}.pbf` | Vektor-API, Tile-Distribution |
|
|
|
|
|
|
| **tileserver-gl** | Martin PBF + `osm-intl.json` | `/{style}/{z}/{x}/{y}.png` | Rendering, PNG-Tile-Cache |
|
|
|
|
|
|
| **NPM** | HTTP Client Requests | HTTPS Responses | Proxy, SSL, Rate-Limit |
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
2026-06-12 09:29:50 +00:00
|
|
|
|
**Verwandte ADRs:**
|
|
|
|
|
|
- [ADR-001: Tile Rendering Stack – Martin + tileserver-gl](docs/adr/001-martin-tileserver-gl-stack.md)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Projektstruktur
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2026-06-12 09:29:50 +00:00
|
|
|
|
rd13_tile_server/
|
|
|
|
|
|
├── config/
|
|
|
|
|
|
│ └── martin.yaml ← Martin Server-Konfiguration
|
|
|
|
|
|
├── data/
|
|
|
|
|
|
│ ├── osm.mbtiles ← OpenFreeMap Vector-Snapshot (~94 GB)
|
|
|
|
|
|
│ ├── styles/
|
|
|
|
|
|
│ │ └── osm-intl.json ← MapLibre GL Style für Raster-Rendering
|
|
|
|
|
|
│ ├── fonts/
|
|
|
|
|
|
│ │ ├── Metropolis Black/
|
|
|
|
|
|
│ │ ├── Open Sans Regular/
|
|
|
|
|
|
│ │ └── … (47 weitere Font-Varianten)
|
|
|
|
|
|
│ └── sprites/ ← Marker/Icons (derzeit leer)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
├── docs/
|
2026-06-12 09:29:50 +00:00
|
|
|
|
│ ├── adr/
|
|
|
|
|
|
│ │ ├── 000-template.md
|
|
|
|
|
|
│ │ └── 001-martin-tileserver-gl-stack.md
|
|
|
|
|
|
│ ├── history/
|
|
|
|
|
|
│ ├── requirements/
|
|
|
|
|
|
│ │ └── REQUIREMENTS.md
|
|
|
|
|
|
│ ├── USER.md, ADMIN.md, MAINTAINER.md
|
|
|
|
|
|
│ └── … (API-Endpoints, Integration-Guides)
|
|
|
|
|
|
├── docker-compose.yml ← Martin + tileserver-gl
|
|
|
|
|
|
└── scripts/
|
|
|
|
|
|
├── download-data.sh ← OSM-MBTiles fetcher
|
|
|
|
|
|
└── download-satellite.py ← Satellit-MBTiles fetcher (optional)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-06-12 09:29:50 +00:00
|
|
|
|
## Style-Customization (osm-intl.json)
|
|
|
|
|
|
|
|
|
|
|
|
Die Kartographer-Karten werden von `data/styles/osm-intl.json` definiert. Das ist eine Standard **MapLibre GL Style** (v8-kompatibel).
|
|
|
|
|
|
|
|
|
|
|
|
### Tipps zum Ändern
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
2026-06-12 09:29:50 +00:00
|
|
|
|
**1. Farben anpassen** (einfach)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"layers": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "water-area",
|
|
|
|
|
|
"paint": {
|
|
|
|
|
|
"fill-color": "#b0d4fc" ← Ändere zu z.B. "#0066cc"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**2. Layer-Sichtbarkeit nach Zoom-Level** (mittelschwer)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "poi-icon",
|
|
|
|
|
|
"minzoom": 14, ← POI-Icons nur ab Zoom 14 sichtbar
|
|
|
|
|
|
"maxzoom": 20 ← Max Zoom-Level
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**3. Label-Schriftart** (mittelschwer)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"text-font": ["Open Sans Bold"] ← Verfügbare Fonts in data/fonts/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Verfügbare Fonts** (aus `/data/fonts/`):
|
|
|
|
|
|
- Metropolis (Black, Bold, Light, Regular, Thin + Italic-Varianten)
|
|
|
|
|
|
- Open Sans (Bold, Regular, Semibold + Italic-Varianten)
|
|
|
|
|
|
- PT Sans (Bold, Caption, Regular, Narrow + Varianten)
|
|
|
|
|
|
- Roboto (Black, Bold, Light, Medium, Regular, Thin + Italic-Varianten)
|
|
|
|
|
|
- Noto Sans (Bold, Italic, Regular)
|
|
|
|
|
|
|
|
|
|
|
|
**4. Linien-Dicke nach Zoom-Level** (fortgeschritten)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"line-width": [
|
|
|
|
|
|
"interpolate", ← Interpolations-Funktion
|
|
|
|
|
|
["linear"], ← Linear interpolieren
|
|
|
|
|
|
["zoom"], ← Input: aktueller Zoom-Level
|
|
|
|
|
|
6, 0.5, ← Bei Zoom 6: 0.5px
|
|
|
|
|
|
20, 6 ← Bei Zoom 20: 6px
|
|
|
|
|
|
]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Style testen (lokal)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-06-12 09:29:50 +00:00
|
|
|
|
# Nach Änderungen an osm-intl.json:
|
|
|
|
|
|
docker compose restart tileserver
|
|
|
|
|
|
|
|
|
|
|
|
# PNG-Tile abrufen
|
|
|
|
|
|
curl -s "http://localhost:9983/osm-intl/10/544/335.png" -o /tmp/test.png
|
|
|
|
|
|
file /tmp/test.png
|
|
|
|
|
|
|
|
|
|
|
|
# In MediaWiki-Kartographer URL testen:
|
|
|
|
|
|
# https://tiles.rd13server.de/osm-intl/{z}/{x}/{y}.png
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Martin Vector-Source verstehen
|
|
|
|
|
|
|
|
|
|
|
|
Martin liest Vektor-Daten aus `osm.mbtiles` und serviert sie als PBF (Protocol Buffers).
|
|
|
|
|
|
|
|
|
|
|
|
**Available Layers in osm.mbtiles** (abhängig von OpenFreeMap-Schema):
|
|
|
|
|
|
|
|
|
|
|
|
Beispiel: `http://localhost:9982/catalog` zeigt alle Source-Layer.
|
|
|
|
|
|
|
|
|
|
|
|
Typisch enthalten:
|
|
|
|
|
|
- `water` – Seen, Flüsse
|
|
|
|
|
|
- `landuse` – Wald, Park, Gras, Acker
|
|
|
|
|
|
- `building` – Gebäude-Polygone
|
|
|
|
|
|
- `road` – Straßen (Motorway, Trunk, Primary, Secondary, etc.)
|
|
|
|
|
|
- `railway` – Eisenbahn-Linien
|
|
|
|
|
|
- `place` – Orte (City, Town, Village)
|
|
|
|
|
|
- `poi` – Points of Interest
|
|
|
|
|
|
|
|
|
|
|
|
**Layer in osm-intl.json updaten:**
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"source": "osm", ← Vector-Tile-Source (Martin)
|
|
|
|
|
|
"source-layer": "water", ← Welcher OSM-Layer? (prüfe /catalog)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Falls Layer fehlt → `http://localhost:9982/catalog` prüfen, oder mit `layer` in osm-intl.json experimential einen neuen hinzufügen.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Rendering-Performance tunen
|
|
|
|
|
|
|
|
|
|
|
|
**tileserver-gl Cache:**
|
|
|
|
|
|
|
|
|
|
|
|
- **Disk-Cache:** `/tmp/pmtiles-cache` (wächst mit Nutzung; max ~50 GB bei voller Coverage)
|
|
|
|
|
|
- **Memory:** ~500 MB standard, skaliert mit Anfrage-Load
|
|
|
|
|
|
- **Warm-up:** Erste Anfrage zu neuem Tile-Bereich ist langsam (~100–200ms), danach <20ms
|
|
|
|
|
|
|
|
|
|
|
|
**Bottleneck identifizieren:**
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Logs verfolgen (live)
|
|
|
|
|
|
docker compose logs -f tileserver | grep "render"
|
|
|
|
|
|
|
|
|
|
|
|
# Performance der Martin-API
|
|
|
|
|
|
curl -w "Time: %{time_total}s\n" -s http://localhost:9982/osm/0/0/0 | head
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Falls zu langsam:**
|
|
|
|
|
|
1. Martin-Worker-Prozesse erhöhen: `config/martin.yaml` → `worker_processes`
|
|
|
|
|
|
2. tileserver-gl Memory erhöhen: docker-compose.yml → `deploy.resources.limits.memory`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Tests & Validierung
|
|
|
|
|
|
|
|
|
|
|
|
### Tile-Integrität checken
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Vektor-Tile (PBF) abrufen und inspizieren
|
|
|
|
|
|
curl -s "http://localhost:9982/osm/0/0/0.pbf" | file -
|
|
|
|
|
|
# Should: PBF (Tile protocol buffer)
|
|
|
|
|
|
|
|
|
|
|
|
# Raster-Tile (PNG) abrufen und prüfen
|
|
|
|
|
|
curl -s "http://localhost:8080/osm-intl/0/0/0.png" -o /tmp/t.png
|
|
|
|
|
|
file /tmp/t.png
|
|
|
|
|
|
# Should: image/png
|
|
|
|
|
|
|
|
|
|
|
|
# MediaWiki-Test URL
|
|
|
|
|
|
# https://tiles.rd13server.de/osm-intl/0/0/0.png
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Smoke-Test nach Update
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Nach Tile-Daten-Update (osm.mbtiles):
|
|
|
|
|
|
for zoom in 0 5 10 14; do
|
|
|
|
|
|
curl -s "http://localhost:9983/osm-intl/$zoom/0/0.png" \
|
|
|
|
|
|
-o /tmp/test_z$zoom.png && echo "✓ Zoom $zoom" || echo "✗ Zoom $zoom"
|
|
|
|
|
|
done
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Deployment & Release
|
|
|
|
|
|
|
|
|
|
|
|
### Checklist vor Push
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] `docker compose logs` prüfen – keine Errors
|
|
|
|
|
|
- [ ] Test-Tiles (Zoom 0, 5, 10, 14) erfolgreich
|
|
|
|
|
|
- [ ] REQUIREMENTS.md aktualisiert (falls Anforderung geändert)
|
|
|
|
|
|
- [ ] ADR erstellt (falls architektur-relevant)
|
|
|
|
|
|
- [ ] ADMIN.md / MAINTAINER.md aktualisiert
|
|
|
|
|
|
- [ ] CHANGELOG.md aktualisiert (falls vorhanden)
|
|
|
|
|
|
- [ ] Git commit + push
|
|
|
|
|
|
|
|
|
|
|
|
### Version & Releases
|
|
|
|
|
|
|
|
|
|
|
|
Derzeit: `rolling release` (jeder Commit ist live).
|
|
|
|
|
|
|
|
|
|
|
|
Falls später strikte Versionierung nötig:
|
|
|
|
|
|
- Versioning: Semantic Versioning (MAJOR.MINOR.PATCH)
|
|
|
|
|
|
- Releases: Tag in Git + Changelog
|
|
|
|
|
|
- Example: `v1.0.0` (Martin 0.9.0 + tileserver-gl 4.7.0)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Bekannte Limitations & Future TODOs
|
|
|
|
|
|
|
|
|
|
|
|
**Jetzt (ADR-001):**
|
|
|
|
|
|
- ✅ Martin + tileserver-gl für statische 2–4×/Year Updates
|
|
|
|
|
|
- ✅ Styles anpassbar (osm-intl.json)
|
|
|
|
|
|
- ✅ Fonts + Sprites nutzbar
|
|
|
|
|
|
|
|
|
|
|
|
**Zukünftig (Falls nötig):**
|
|
|
|
|
|
- [ ] **ADR-002:** Live OSM-Update-Pipeline (OpenMapTiles Server)
|
|
|
|
|
|
- [ ] Sprites/Icons erweitern (derzeit leer)
|
|
|
|
|
|
- [ ] Mehrere Styles pro Kartographie-Kontext (dark mode, print-optimized)
|
|
|
|
|
|
- [ ] Horizontal scaling (Kubernetes / Load Balancer)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Ressourcen
|
|
|
|
|
|
|
|
|
|
|
|
- [Martin Tile Server Documentation](https://maplibre.org/martin/)
|
|
|
|
|
|
- [tileserver-gl Documentation](https://tileserver.readthedocs.io/)
|
|
|
|
|
|
- [MapLibre GL Style Specification v8](https://maplibre.org/maplibre-gl-js-docs/style-spec/)
|
|
|
|
|
|
- [OpenMapTiles Schema](https://openmaptiles.org/schema/)
|
|
|
|
|
|
- [OSM Wiki: Map Tiles](https://wiki.openstreetmap.org/wiki/Tiles)
|
2026-06-03 11:17:15 +00:00
|
|
|
|
cd <repo>
|
|
|
|
|
|
# Dependencies installieren
|
|
|
|
|
|
# Dev-Server starten
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Architekturentscheidungen (ADRs)
|
|
|
|
|
|
|
|
|
|
|
|
ADR-Dateien liegen unter `docs/adr/`. Format: `NNN-titel.md`.
|
|
|
|
|
|
|
|
|
|
|
|
| Nr. | Titel | Status | Datum |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| 000 | Template | accepted | … |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Coding-Konventionen
|
|
|
|
|
|
|
|
|
|
|
|
<!-- TODO: Projektspezifische Konventionen -->
|
|
|
|
|
|
|
|
|
|
|
|
- **Branches:** `feat/<ticket>-beschreibung`, `fix/<ticket>-beschreibung`
|
|
|
|
|
|
- **Commits:** Conventional Commits (`feat|fix|chore|docs|refactor|test|ci`)
|
|
|
|
|
|
- **Tests:** `tests/` spiegelt Source-Struktur, ≥ 80% Coverage
|
|
|
|
|
|
- **Linting:** …
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Agent-Kontext & History
|
|
|
|
|
|
|
|
|
|
|
|
Der Agent liest beim Start immer `history/summary/PROJECT_CONTEXT.md`.
|
|
|
|
|
|
Nach Abschluss einer Aufgabe wird dort der Projektzustand aktualisiert.
|
|
|
|
|
|
|
|
|
|
|
|
- Vollständige Konversationen: `history/prompts/` (committed – History bleibt vollständig erhalten)
|
|
|
|
|
|
- Komprimierter Kontext: `history/summary/PROJECT_CONTEXT.md` (committed)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Neues Feature hinzufügen
|
|
|
|
|
|
|
|
|
|
|
|
1. `history/summary/PROJECT_CONTEXT.md` lesen – aktuellen Stand verstehen
|
|
|
|
|
|
2. Issue / Ticket anlegen
|
|
|
|
|
|
3. Branch: `git checkout -b feat/<ticket>-beschreibung`
|
|
|
|
|
|
4. Implementieren + Tests schreiben
|
|
|
|
|
|
5. Dokumentation in `docs/USER.md` oder `docs/ADMIN.md` aktualisieren
|
|
|
|
|
|
6. `git commit` – Quality Gate läuft automatisch (pre-commit hook)
|
|
|
|
|
|
7. PR erstellen + Review
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Designentscheidungen
|
|
|
|
|
|
|
|
|
|
|
|
| Entscheidung | Begründung |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| … | … |
|