diff --git a/docs/ADMIN.md b/docs/ADMIN.md index b7cb804..72ad46a 100644 --- a/docs/ADMIN.md +++ b/docs/ADMIN.md @@ -237,7 +237,7 @@ docker compose logs -f tileserver # Raster-Rendering - Image: `192.168.178.6:8083/cschulz/rd13_tile_server-marker-api:latest` (Forgejo Registry) - API Root: `http://localhost:9984` - Endpunkt: `/styles/v4/marker/{type}+{hexcolor}(@{scale}x).png` -- Typen: `pin-s` (20×30px), `pin-m` (27×41px, Maptiler-Standard), `pin-l` (34×52px); 85% opak, weißer Rand + Innenpunkt +- Typen: `pin-s` (20×50px), `pin-m` (30×70px), `pin-l` (35×90px) @1x – exakte Kartographer-Maße (mapbox-lib.js `sizes`); weißer Rand + Innenpunkt, 85% opak - Image neu bauen: `docker compose build marker-api && docker compose up -d marker-api` - CI: Forgejo baut + pusht automatisch bei Änderungen in `services/marker-api/` diff --git a/docs/history/prompts/2026-07-01_marker-api_session.md b/docs/history/prompts/2026-07-01_marker-api_session.md index aedd467..729c621 100644 --- a/docs/history/prompts/2026-07-01_marker-api_session.md +++ b/docs/history/prompts/2026-07-01_marker-api_session.md @@ -113,6 +113,28 @@ Geometry-Fix: r=35.5% der Breite, tipY=97.5%, Spitze passt jetzt sauber in die C ### Prompt 13 «Das sieht aber immer noch komisch aus...» +### Prompt 15 +«Ich habe immer zwischen den tests den gesamten browser cache geleert das kann es nicht sein!» + +### Antwort 15 +Analyse der Kartographer-Quelldatei `/wikidata/extensions/Kartographer/lib/external/mapbox/mapbox-lib.js` (Zeilen 14773–14789): + +```js +var sizes = { small: [20,50], medium: [30,70], large: [35,90] }; +iconSize: sizes[size], // CSS-Zielgröße +iconAnchor: [sizes[size][0]/2, sizes[size][1]/2] // Anker = MITTE +``` + +Zwei Ursachen: +1. Größen-Mismatch: Kartographer erwartet pin-m = 30×70px. Wir lieferten 27×41px. CSS-Stretch: +11% horizontal / +71% vertikal → schlanke Spitze wird zu dickem Oval. +2. iconAnchor an der Mitte [15,35]: Funktioniert nur wenn Canvas wirklich 70px hoch ist. + +Fix: baseSizes auf exakte Kartographer-Maße gesetzt: +- pin-s: 20×50, pin-m: 30×70, pin-l: 35×90 +- Geometrie angepasst: r = w*0.47 (Kreis füllt Breite), cy=r+1, tipY=h-1 + +Verifiziert: pin-m@1x=30×70px, pin-m@2x=60×140px. Pin mit langer Spitze korrekt. + ### Prompt 14 «besser aber immer noch nicht perfekt ich will es perfekt!! und ich will einen weißen rand und weißen punkt in der mitte wenn es geht» diff --git a/docs/history/summary/PROJECT_CONTEXT.md b/docs/history/summary/PROJECT_CONTEXT.md index 93dff72..009c666 100644 --- a/docs/history/summary/PROJECT_CONTEXT.md +++ b/docs/history/summary/PROJECT_CONTEXT.md @@ -1,6 +1,6 @@ # PROJECT_CONTEXT – rd13_tile_server -**Letzte Aktualisierung:** 2026-07-01 – ✅ **Marker-API**: Go-Service für Maptiler-kompatible Marker-Endpunkte (`/styles/v4/marker/*`). Korrekte 27×41px Proportionen (Maptiler-Standard), weißer Rand (A=255), weißer Innenpunkt (A=255), 85% opaker Fill. Forgejo CI baut + pusht Image. +**Letzte Aktualisierung:** 2026-07-01 – ✅ **Marker-API**: Go-Service für Maptiler-kompatible Marker-Endpunkte (`/styles/v4/marker/*`). Maße exakt nach Kartographer mapbox-lib.js: pin-m=30×70px (@1x)/60×140px (@2x). Weißer Rand + Innenpunkt (A=255). Ursache der Verzerrung: Größen-Mismatch (27×41→30×70 CSS-Stretch). Forgejo CI baut + pusht Image. --- diff --git a/services/marker-api/main.go b/services/marker-api/main.go index e227f6c..8aaab64 100644 --- a/services/marker-api/main.go +++ b/services/marker-api/main.go @@ -25,10 +25,14 @@ var markerPattern = regexp.MustCompile( // Der Pin ankert an der Spitze (bottom-center), nicht am Bildmittelpunkt. type pinDims struct{ w, h float64 } +// Maße MÜSSEN exakt den Werten in Kartographer's mapbox-lib.js entsprechen: +// sizes = { small: [20,50], medium: [30,70], large: [35,90] } +// Leaflet rendert das Bild per CSS auf genau diese Pixelgröße. +// Abweichungen → verzerrte Form (27×41 → 30×70 streckt Spitze um 71% vertikal). var baseSizes = map[string]pinDims{ - "pin-s": {20, 30}, - "pin-m": {27, 41}, // Maptiler-Standard - "pin-l": {34, 52}, + "pin-s": {20, 50}, + "pin-m": {30, 70}, // mapbox-lib.js: sizes.medium = [30, 70] + "pin-l": {35, 90}, } // Marker-Cache (max 500 Einträge, reicht für alle Farb/Typ/Scale-Kombinationen) @@ -163,15 +167,17 @@ func generateMarker(pinType, hexColor string, scale float64) ([]byte, error) { h = 15 } - // Geometrie: Kreis füllt ~74% der Breite, r/d ≈ 0.37 → Öffnungswinkel 22° - // Entspricht exakt Maptiler pin-m Proportionen (27×41px @1x) + // Geometrie für 30×70 (@1x) / 60×140 (@2x): + // - Kreis füllt fast die ganze Breite (r≈47% width) + // - iconAnchor=[w/2, h/2] in mapbox-lib.js → Anker liegt bei y=35 im Tail + // - Spitze bei y≈h-1: 34px unterhalb des Ankers (deutlich sichtbar) cx := w / 2 - r := w * 0.37 // Kreisradius: Kreis fast so breit wie Canvas - cy := r + h*0.04 // Kreismittelpunkt Y: kleiner oberer Rand - tipY := h - h*0.03 // Spitze Y: 3% Abstand vom unteren Rand + r := w * 0.47 // r≈14px (@1x): Kreis fast so breit wie Canvas + cy := r + 1.0 // cy≈15: Kreis berührt fast den oberen Rand + tipY := h - 1.0 // Spitze 1px vom unteren Rand - borderW := math.Max(2.0, w*0.08) // weißer Rand: gut sichtbar - innerR := r * 0.38 // weißer Innenpunkt: 38% des Kreisradius + borderW := math.Max(1.5, w*0.06) // weißer Rand + innerR := r * 0.36 // weißer Innenpunkt // Füllfarbe: 85% opak; Rand und Punkt: vollständig weiß fillBase := hexToColor(hexColor) @@ -234,7 +240,7 @@ func handleMarker(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "image/png") - w.Header().Set("Cache-Control", "public, max-age=2592000, immutable") + w.Header().Set("Cache-Control", "public, max-age=86400") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Length", strconv.Itoa(len(data))) w.WriteHeader(http.StatusOK)