Commit graph

1045 commits

Author SHA1 Message Date
827ea95191 Tiles-Progress: Stufe 4 zeigt echte planetiler-Phase statt Müll-ETA 2026-06-05 17:21:08 +02:00
43b1e8026f Docs: Offline-Karten-Plan (GL/Vektor) — budget-getrieben + adaptives Funkloch-Lernen
Festgehalten als Feature-Plan: Region-Extract per pmtiles (budget-getrieben statt
Radius, ~16 MB Default, gemessen 15 MB für 10km München / ~18-22km Land), Client
IndexedDB-Blob + MapLibre lokal/remote, adaptives Lernen (rollendes Vorausladen
beim Aufzeichnen + Funkloch-Gedächtnis aus echten Fetch-Fehlern, alles lokal),
manuelles Vorab-Laden, Budget+LRU. Umsetzung nach Produktions-Rollout.
2026-06-05 17:16:16 +02:00
29076bcdff Tiles: Fortschritts-Snapshot-Skript (Stufe/Balken/ETA) für Build-Monitoring + .gitignore 2026-06-05 16:50:52 +02:00
d11794355c Tiles: DACH + alle Anrainer (15 Länder) + Einzel-PBFs nach Merge freigeben
TILES_REGIONS auf germany/austria/switzerland + france/italy/czech-republic/
poland/slovakia/hungary/slovenia/netherlands/belgium/luxembourg/denmark/
liechtenstein erweitert. Output bleibt dach.pmtiles (Frontend-Name stabil).
Nach time-filter werden History + Einzel-PBFs gelöscht → ~27 GB weniger
Spitzen-Plattenplatz vor planetiler.
2026-06-05 16:15:20 +02:00
c7201aa07b Karten-Attribution: standardmäßig eingeklappt (nur ⓘ) + doppelten Hinweis entfernt
Punkt 6: MapLibre rendert die Compact-Attribution offen (maplibregl-compact-show
+ open) → voller Text '© OpenStreetMap contributors' immer sichtbar. Neuer Helper
MapGLStyle.collapseAttribution() entfernt die Klasse/open nach dem Hinzufügen →
nur noch das ⓘ, der Text erscheint erst auf Klick (rechtlich nach ODbL ausreichend).
In map-gl-mini.js (Seitenkarten) + map.js (zentrale Karte) verdrahtet.

Punkt 7: poison.js + lost.js hatten UNTER der Karte zusätzlich ein hartkodiertes
'© OpenStreetMap-Mitwirkende' — doppelt zum Karten-ⓘ. Entfernt (+ ungenutzte
.lost-map-attribution CSS-Klasse). Verifiziert: osmTextLeafCount 2-3 → 1, compactShown true → false.
2026-06-05 15:48:11 +02:00
da6451a1c7 Karten: Mitglieder-Karte (Forum) auf GL + verwaiste Orte-Seite gelöscht
Mitglieder-Karte (forum.js): L.map/L.tileLayer(OSM) → UI.map.create, Cluster
+ Marker über die Facade (UI.map.clusterGroup/svgMarker), eigenes Leaflet-/
MarkerCluster-Nachladen raus. destroy() gibt Karte+Gruppe beim Verlassen frei.
Headless verifiziert: GL-Canvas, 2 Mitglieder-Marker, keine Fehler.

places.js (separate 'Hundefreundliche Orte'-Seite) war verwaist — in keiner
Navigation/keinem pages-Registry, nicht erreichbar. Die hundefreundlichen Orte
laufen längst als POI-Marker auf der zentralen GL-Karte (map.js). Auf Renés
Entscheidung gelöscht (JS + CSS-Block in components.css).

Damit laufen ALLE erreichbaren Karten der App auf MapLibre GL.
2026-06-05 15:28:51 +02:00
720971d252 Routen-Detailkarte: WebGL-Kontext-Leak gefixt → bleibt GL + zoomt auf Route
Eigentliche Ursache von 'Detailkarte zoomt nicht auf die Route': die Karte war
auf dem Gerät gar keine GL-Karte mehr, sondern der Leaflet+OSM-RASTER-Fallback.
Grund: _detailMap (GL-Kontext) wurde beim Schließen des Modals NIE freigegeben —
jede geöffnete Route leakte einen WebGL-Kontext. Nach ~8 wirft MapLibre, und
UI.map.create fällt auf Leaflet+OSM zurück. Genau die Mapnik-Kacheln aus Renés
Screenshots (und die OSM-Attribution, die wir doch loswerden wollten).

Fixes:
- _detailMap modulweit + im onClose des Detail-Modals freigeben.
- routes.js destroy(): _detailMap/_suggestMap/_searchMap + Mini-Maps beim
  Verlassen der Seite freigeben.
- ui.js: Offscreen-Snapshot-Kontext nach 15s Leerlauf freigeben (hielt dauerhaft
  einen Kontext; Cache bleibt → kein Neu-Rendern).
- _fitRouteMap fittet jetzt aufs 'load'/'idle'-Event der Karte (iOS verwirft ein
  fitBounds VOR dem ersten Render) statt nur auf feste Timeouts.

Verifiziert (headless): 12 Detail-Öffnungen in Folge bleiben ALLE GL
(Leaflet:false), GL-Canvas-Zahl bleibt bei 1–2 statt zu wachsen. Vorher leakte
jede Öffnung einen Kontext.
2026-06-05 15:10:12 +02:00
d203ab17a8 Routen: Detail/Vorschlag-Zoom robust (ResizeObserver) + Navi-Sperrbildschirm nur per Fingerabdruck
Punkt 3 (Zoom auf die Route): feste Timeouts (0/200/500ms) griffen auf iOS oft
zu früh — der Modal-Container war noch nicht final vermessen, die Karte blieb
beim Start-Zoom (zoom 14, center=Start) hängen statt auf die ganze Route zu
zoomen. Jetzt _fitRouteMap mit ResizeObserver: fittet erneut, SOBALD der
Container seine endgültige Größe hat (Detail + Vorschläge). Facade-fitBounds
prüft jetzt auch clientHeight>0 (0-Höhe ergab schlechten Fit).

Punkt 5 (Navigations-Sperrbildschirm): der 2-Sek-Halten-Handler hing am ganzen
Dim-Overlay → Halten IRGENDWO entsperrte. Jetzt ein eigener Fingerabdruck-Knopf
(rk-nav-unlock-btn) wie beim Aufzeichnen-Dim; nur dort entsperrt es, mit
setPointerCapture. Tippen daneben tut bewusst nichts.

Verifiziert (headless): Detail fittet die ganze Route (v1204, 0 Fehler);
Dim-Hintergrund 2,2s halten → bleibt gesperrt, Knopf 2,2s halten → entsperrt.
2026-06-05 14:47:15 +02:00
285928f6f7 Karten: Routen-Übersichtskarte klickbar + Tagebuch-Karten auf GL
Punkt 2 (Routen-Übersicht 'Karte'): _renderRoutesOnMap crashte, weil die
Polyline-Facade kein bindTooltip/on/setStyle/getLatLngs kannte. In
map-gl-mini.js ergänzt — inkl. breiter, fast unsichtbarer Hit-Linie, damit
Routen auf dem Handy gut antippbar sind (Klick → Detail). Hover-Tooltip
(Name+km) + Hover-Highlight.

Punkt 4 (Tagebuch): beide Leaflet/OSM-Karten (Standort-Übersicht +
Einzeleintrag) auf UI.map.create + Facade-Marker migriert. popupopen-Wiring
(kennt die GL-Facade nicht) → Klick-Delegation auf dem Karten-Container.
Karten-Instanzen werden beim View-Wechsel/Verlassen freigegeben (destroy +
_clearDiaryMaps) gegen WebGL-Kontext-Leak. Detail/Übersicht fitten mehrfach
(Container-Timing).

Nebenbei: _loadPraise warf NotFoundError (insertBefore) — #diary-list liegt
in #diary-view-content, nicht direkt in _container. Jetzt vor der Liste in
deren echtem Elternknoten einfügen.

Verifiziert (headless, eingeloggt, echte Daten): Routenkarte 8 Marker klickbar
→ Detail; Detail+Vorschläge zoomen auf die Route; Tagebuch-Karte GL mit 108
Markern, Popup-Klick → Eintrag, keine Fehler.
2026-06-05 14:23:22 +02:00
1defeec537 Routen-Vorschau: echtes Karten-PNG (Basemap+Route) statt nackter SVG-Form
In der Routenliste fehlte der geografische Kontext — man sah nur die Routen-
form auf grünem Grund, nicht WO sie liegt oder wo sie entlangführt.

Lösung: UI.map.snapshot() rendert pro Track ein PNG aus EINEM geteilten
Offscreen-GL-Kontext (gleicher Style wie die echte Karte: Straßen, Orte,
Wald, Gewässer), zeichnet Route + Start/Ziel-Marker ein und cached das
Ergebnis. So bekommt jede Karte ihren Kontext, ohne bei vielen Listen-
einträgen das WebGL-Kontextlimit (iOS ~8) zu sprengen.

- ui.js: Offscreen-Singleton + serielle Render-Queue + Cache (_glSnapshot)
- routes.js: _buildMiniMap zeigt sofort SVG, upgradet dann aufs PNG
- GL aus → null → SVG-Platzhalter bleibt (Produktion/Flag aus unverändert)
2026-06-05 13:57:47 +02:00
a0d16ba800 Fix: Seiten-Crash bleibt nicht mehr für die ganze Session hängen
Ein transienter Init-Fehler (Netz-Blip, SW-Update mitten in der Navigation,
Race) setzte page.module={} — der Guard 'if (page.module)' lud die Seite
danach nie mehr nach. Auf einer iOS-PWA, die nie ganz neu lädt, blieb 'Die
Seite funktioniert nicht mehr' damit tagelang hängen, obwohl der eigentliche
Bug (Routen-GL) längst gefixt war.

- echten Fehler nicht mehr verschlucken (console.error)
- page.module bei Exception NICHT mehr tot stellen → nächster Aufruf versucht neu
- 'Erneut versuchen'-Button im Fehler-State
- Routen v1199 in Chromium+WebKit headless verifiziert (Liste/Entdecken/Detail ok)
2026-06-05 13:48:58 +02:00
d96fa9e24e Seitenkarten destroy(): GL-Karte beim Seitenwechsel freigeben (WebGL-Kontext-Leak)
poison/lost/walks/events: destroy() ruft _map.remove() → app.js gibt den WebGL-Kontext beim
Navigieren frei. Sonst akkumulieren Kontexte → iOS-Limit (~8) → neue GL-Karten (z.B. Routen-Detail)
scheitern → Leaflet-Raster-Fallback.
2026-06-05 13:16:38 +02:00
27a3f954a4 Routen-Fixes: Richtungspfeile (SVG-interne Rotation) + Filter standardmäßig zu
- Pfeile: rotate als SVG-Pfad-Attribut statt CSS-transform am Element (maplibregl.Marker
  überschrieb das transform → Pfeile zeigten alle nach Norden)
- Filter-Panel + Badge: doppeltes class-Attribut (class=X class=hidden) → Browser ignorierte
  'hidden' → Filter immer offen + roter Badge immer an. Zu 'X hidden' gemergt.
2026-06-05 13:13:14 +02:00
fbaf7c5409 Routen-GL-Fix: Detail/Suggest-Karte fittet Route korrekt (Modal-0×0-Timing)
- Facade fitBounds: try/catch + skip wenn Container 0×0 (sonst NaN-LngLat im Modal)
- createMap: mehrfaches resize() nach Erstellung (Modal-Animation)
- _buildDetailMap/_suggestMap: Re-Fit nach 200/500ms (Route ganz sichtbar, Pfeile)
- Facade: scrollWheelZoom-Stub (map.scrollZoom)
2026-06-05 13:01:19 +02:00
96119e02ef Seitenkarten GL Runde 2: Events, Gassi, Routen + Facade-Erweiterung
- Facade: Polyline (geojson line-source, addTo/setLatLngs/getBounds/remove), clusterGroup,
  marker.getLatLng, map.distance(Haversine), on('click') normalisiert e.latlng aus e.lngLat, _ll objekttauglich
- events: L.markerClusterGroup→UI.map.clusterGroup
- walks: window.L-Guard, L.featureGroup→UI.map.featureGroup, fitBounds ohne .pad
- routes: L.polyline/L.circleMarker→UI.map.*, navMap/Pfeil-Marker→svgMarker, latLngBounds→coords,
  trimMap distance/click, Mini-Vorschauen auf SVG (kein WebGL-Limit, kein OSM-Raster)
2026-06-05 12:48:09 +02:00
5844f1ef51 Seitenkarten auf MapLibre GL (Facade) — Runde 1: Giftköder + Verlorene
- map-gl-mini.js: Leaflet-kompatible MapLibre-Facade (createMap/svgMarker/circleMarker/
  featureGroup-Wrapper mit setView/fitBounds/invalidateSize/addTo/bindPopup/openPopup/on/remove)
- ui.js: UI.map.create/svgMarker/leafletMarker branchen auf GL (by_map_gl, Staging-Default),
  + UI.map.circleMarker/featureGroup, loadMapLibreUI
- poison.js/lost.js: window.L-Guards entfernt, L.circleMarker→UI.map.circleMarker
2026-06-05 12:33:01 +02:00
9c4b999331 GL-Style: Straßennummern (A9/B304/ST2078) + Straßenarten farblich
- road-refs-Layer: ref aus transportation_name entlang Autobahn/Bundes-/Landstraße (aufrecht)
- roads-Farbe per match(class): Autobahn rötlich, Trunk orange, primary gelb-orange, secondary blassgelb, Rest weiß
2026-06-05 12:05:01 +02:00
eaf7801e6b GL-Style: Schutzgebiete (park) als Umrandung statt Füllung + Wald dunkler
René: Ebersberger Forst in GL heller statt dunkler. Ursache: park-Layer (Naturpark/Schutzgebiet)
lag als flache hellgrüne Füllung ÜBER dem Wald → aufhellend. Jetzt dezente Füllung (0.18) +
grüne gestrichelte Umrandung (wie OSM), Wald-Farbe (landcover wood, dunkler #74b356) bleibt sichtbar.
2026-06-05 11:59:02 +02:00
04b2d8aeb8 GL-Style: Landbedeckung nach Klasse (Wald/Wiese/Moor unterscheidbar)
landcover-Fill per match(class): Wald (wood) dunkler Grün, Wiese (grass) heller,
Moor/Feuchtgebiet (wetland) eigene teal-grüne Farbe (Ufer-/Moorzonen), Farmland/Sand abgesetzt.
Vorher flach einfarbig → Wald nicht von Wiese unterscheidbar.
2026-06-05 11:53:14 +02:00
cc1fdb00b1 GL-Style: kräftigere Schrift (Open Sans Semibold, self-hosted), sattere Farben, Bahntrassen
- Labels + Cluster-Zahlen auf Open Sans Semibold (Glyphs gehostet) — Schrift war zu dünn
- Farben gesättigt: Grün/Park/Wasser kräftiger, Füll-Deckkraft 0.55→0.8 (wirkten blass)
- Bahn-Layer (class rail/transit): Basis-Linie + Schwellen-Effekt (fehlten ganz)
2026-06-05 11:47:52 +02:00
fc9cac410c GL-Style: Pfade von Straßen trennen + Infodichte (Hausnummern, POI-Namen)
- transportation nach class: Pfade/Tracks dünn+gestrichelt; Straßen weiß, Breite nach Klasse
  (motorway/trunk breit … minor schmal) — Pfade sehen nicht mehr wie Straßen aus
- neue Label-Layer: poi (Kinderspielplatz/Schule… ab Z15) + housenumber (ab Z17), name:de
- Label-Reihenfolge = Kollisions-Priorität (Orte zuerst)
2026-06-05 11:35:24 +02:00
3523a44a0b MapLibre: GL als Staging-Default + Feinschliff (Cluster-Zahlen, Theme-Robustheit)
- _useGL: Staging default-AN (Prod aus, ?mapgl=0 überschreibt) → Breitentest
- Cluster zeigen ZAHL (point_count) statt Icon (Glyphs vorhanden)
- Theme-Wechsel: Wetter-Raster + Rec-Track nach setStyle neu anlegen; Click-Handler nur einmal binden (keine doppelten Popups)
2026-06-05 11:26:55 +02:00
425f99effb MapLibre-Port 3b+3c: Wetter + GPS-Aufzeichnung für GL entgaten
3b Wetter: engine-neutrale Helfer (_wxAddRaster→raster-source unter den Markern, _mapOnMove,
   _wxAddTempMarker→maplibregl.Marker). _toggleRadar/_loadRadar/_toggleTemp/_loadTempLabels gebrancht.
3c GPS: _recTrackGL (geojson line-source), _updateRecMarker (maplibregl.Marker), _recCleanupMap.
   _updateRecMap/_startRecording-Resume/Cleanup gebrancht, Gates entfernt. panTo [lng,lat] für GL.
2026-06-05 11:19:40 +02:00
9c959dd632 GL-Karte: Ortsnamen-Labels (Glyphs self-hosted) + ScaleControl raus (lag unter der Status-Pill)
- main.py: /fonts-Mount (Glyph-PBFs aus data/tiles/fonts), Open Sans Regular self-hosted
- map-gl-style.js: glyphs-URL + Label-Layer (Ortsnamen/Straßen/Gewässer, name:de)
- map.js _initMapGL: ScaleControl entfernt (überdeckte die Zoom/Wetter/Zecken-Pill)
Ortsnamen für Orientierung (René), auch bei kleinem Zoom.
2026-06-05 11:09:08 +02:00
4d0cd0f460 Karten-Fix: fraktionalen MapLibre-Zoom für Scan-Schwelle runden
MapLibre-Zoom ist kontinuierlich (13.7); Statusleiste rundet (zeigt Z14), Scan verglich roh
→ bei angezeigtem Z14 (echt 13.x) galt zoom<14 → Marker gecleart, erst ab Z15 sichtbar.
Jetzt Math.round(getZoom()) für die 10/14-Schwellen (wie die Anzeige). Leaflet unverändert (ganzzahlig).
2026-06-05 11:01:09 +02:00
980338d7f1 Karten-Fix: Scan-Race bei schnellen Zoom-Folgen (Z16→Z13→Z14 → keine Marker)
_loadOsmLayers verwarf Scan-Anfragen, die während eines laufenden Scans kamen (return).
Bei langsamem Overpass (Handy) ging so der finale Z14-Scan verloren → Marker leer.
Jetzt: _scanQueued merkt die Anfrage vor, finally holt sie nach → letzte Ansicht wird garantiert gescannt.
2026-06-05 10:56:08 +02:00
d447de2b8d GL-Cluster: weißes Kategorie-Icon mittig auf Cluster-Kreis (clsym-Layer + cli-Icon-Variante)
René: 'geclusterte Marker haben kein Symbol'. Jeder Cluster ist genau eine Kategorie →
weißes Phosphor-Icon in der Cluster-Mitte (icon-size skaliert mit point_count). Keine Glyphs nötig.
2026-06-05 10:47:36 +02:00
2ccf75e076 Karten-Fix: Overlay-Button-Zonen click-through (blockierten Karten-Pannen)
René: 'wo die Karten-Buttons auftauchen ist eine Zone die Kartenbedienung verhindert'.
.map-statusbar/.map-speed-dial/.map-crosshair/.map-search-wrap(inactive)/.map-rec-panel(inactive)
fingen Touch in ihrer Bounding-Box → tote Zonen. Jetzt pointer-events:none, nur Buttons auto.
Erklärt die 'reagiert nach kurzer Zeit'-Verzögerung (Drag startet tot, greift erst im Karten-Bereich).
Gilt für beide Engines (verbessert auch Leaflet).
2026-06-05 10:43:17 +02:00
2d7eca16a7 MapLibre-Port 3a-Fix: Scanner-Endlosschleife (resize im Scan) + Pinch-Page-Zoom + Rotation
- _loadOsmLayers: kein _map.resize() für GL (löste move→moveend→scan-Loop aus, 'pausenlos')
- _initMapGL: touchZoomRotate.disableRotation() + touchPitch.disable() + container touch-action:none
  → Pinch=reines Zoom, bleibt in der Karte (kein iOS-Page-Zoom), keine ungewollte Drehung
2026-06-05 10:26:35 +02:00
ef16ec92ba MapLibre-Port 3a: ?mapgl=1/0 früh in boot.js erfassen + GL-App-Pfad headless end-to-end verifiziert (2936 reale Marker, Popup, null Fehler) 2026-06-05 10:16:15 +02:00
542106e77b MapLibre-Port Runde 3a: MapGLMarkers in map.js verdrahtet (flag-gated)
- _loadOsmLayers/_loadAll/_addPlaces/_addPoison/_addBreeders/_applyVisibility/_deleteUserPoi
  engine-neutral (GL: POI-DATEN statt Marker, MapGLMarkers.setLayer/setVisible)
- Standort-Dot, Place-Picker-Temp-Marker, Such-Marker als maplibregl.Marker
- engine-spez. Aufrufe über Facade (_mapFlyTo/_mapSetView/_mapResize)
- Wetter + GPS-Recording für GL vorerst gegated (Port in 3b/3c)
- Flag 'by_map_gl'/?mapgl=1, default AUS
2026-06-05 10:06:54 +02:00
11922c1d22 MapLibre-Port Runde 2: GL-Marker-Subsystem (map-gl-markers.js) + headless Test-Harness
Eigenständiges Modul: per-Kategorie GeoJSON-Cluster, rasterisierte Phosphor-Icons,
Danger-Polygone, Sichtbarkeit, Click→Popup. /maplibre-markers-test zum headless-Verifizieren
VOR dem Einbau in map.js (auth-gated).
2026-06-05 09:52:45 +02:00
63c9be68c6 MapLibre-Port Runde 1: Engine-Fundament (flag-gated, Default Leaflet)
map.js: _useGL()/loadMapLibre()/_initMapGL() + engine-neutrale Facade
(_mapFlyTo/_mapSetView/_mapGetZoom/_mapResize/_mapGetCenter/_mapPaddedBounds, kapselt
[lat,lon]↔[lng,lat]). init() verzweigt auf GL bei Flag 'by_map_gl'/?mapgl=1. Basemap+
Controls+Dark(setStyle)+Scan-Wiring+Crosshair. POI-Layer/Marker = Runde 2. Flag default AUS.
2026-06-05 09:37:59 +02:00
a27695d9c6 MapLibre-Perf-Test: /maplibre-perf-test (Basemap + 600 Cluster-Marker, GPU) — Handy-Proof vor dem Umbau 2026-06-05 09:24:13 +02:00
5e354f7e8e MapLibre-Migration M1: Geometrie-Style-Modul (MapGLStyle, Light+Dark, kein Glyph) für zentrale Karte 2026-06-05 09:20:41 +02:00
7d761bb342 NOTAUS: Vektor-Basemap hart deaktiviert — protomaps-leaflet hängt App auf dem Handy auf
Main-Thread-Rendering von protomaps-leaflet + App-Map-Logik blockiert UI-Thread.
Greift auch bei localStorage-Flag=1. Performance erst lösen, dann reaktivieren.
2026-06-05 09:12:01 +02:00
1d64dc5d70 Fix: zentrale Karte nutzte window.UI (undefined) statt bare UI → immer Raster-Branch
ui.js exponiert 'const UI' = globales lexikalisches Binding (bare UI), NICHT window.UI.
map.js _addBasemap prüfte window.UI → immer falsy → Vektor-Pfad nie genommen.
Jetzt: typeof UI-Check. (window.UI?.toast in boot/api/app sind separat tote No-Ops.)
2026-06-05 09:06:09 +02:00
5cb7c3091d Diagnose: /ui-vector-test — testet echten ui.js-Vektor-Pfad (UI.map.create) ohne Auth 2026-06-05 09:01:58 +02:00
b0fece16c8 Fix: CSP worker-src 'self' blob: (SW-Registrierung war durch blob:-only blockiert) + Vektor-Basemap auf Staging default-an
- worker-src blob: hatte sw.js (same-origin) blockiert → SW-Registrierung schlug app-weit fehl
  → alter SW servierte stale ui.js → UI.map.vectorLayer undefined → stiller Raster-Fallback
- _vectorMapEnabled: Staging default AN (Reifephase), Prod AUS bis Freigabe, Flag überschreibt
2026-06-05 08:52:36 +02:00
736c326635 Tile-Server: Isolations-Testseite /leaflet-vector-test (protomaps-leaflet + DACH, ohne App-Shell) 2026-06-05 08:39:43 +02:00
647aa684db Vektor-Basemap: zentrale Karte (pages/map.js) integrieren — sie umging UI.map.create
- map.js _addBasemap: Vektor-Layer (Flag) mit Raster-Fallback, eigener Basemap-Code
- Theme-Wechsel baut Vektor-Layer mit passendem Flavor neu (kein CSS-Filter bei Vektor)
- ui.js: UI.map.vectorEnabled()/vectorLayer() exponiert für Karten mit eigenem Layer-Mgmt
- APP_VER bump
2026-06-05 08:28:11 +02:00
b2262a8e86 Vektor-Basemap: ?vectormap=1/0 früh in boot.js erfassen (überlebt Query-Stripping beim Boot) + APP_VER bump 2026-06-05 07:57:21 +02:00
9006c85434 Bump APP_VER 1173→1174 (Vektor-Basemap-Integration) 2026-06-04 22:26:42 +02:00
2b5afcf0ae Tile-Server: Vektor-Basemap in PWA integrieren (protomaps-leaflet, Feature-Flag)
- ui.js Map.create: Basemap-Swap OSM-Raster→PMTiles-Vektorlayer hinter Flag
  'by_vector_map' (?vectormap=1/0). Leaflet+markercluster+Marker unverändert,
  sauberer Raster-Fallback bei Fehler. Attribution Pflicht eingeblendet.
- map-vector.js: protomaps-leaflet paintRules/labelRules für OpenMapTiles-Schema
  (Light+Dark), Labels per Canvas-Text → keine Glyphs nötig. Quelle /tiles/dach.pmtiles.
- protomaps-leaflet 4.0.1 vendored.
- Makefile: 'make tiles' (download→merge -H+time-filter dedup→planetiler) + 'make tiles-deploy'
  (atomarer Swap, ENV=prod für Produktion).
2026-06-04 21:53:07 +02:00
a561759034 Tile-Server-Spike: MapLibre-Testseite /maplibre-test (vendored maplibre-gl+pmtiles)
- /maplibre-test rendert bayern.pmtiles per pmtiles-Protokoll, minimaler
  Geometrie-Style (OpenMapTiles-Layer, keine Glyphs), Touren-Demo als GeoJSON-Line
- maplibre-gl 4.7.1 + pmtiles 3.2.1 lokal vendored (CSP script-src 'self')
- CSP: worker-src blob: (MapLibre-Worker)
2026-06-04 20:42:35 +02:00
e5a2953a80 Tile-Server: HEAD-Support für /tiles (Dateigröße-Probe ohne 405) 2026-06-04 20:35:06 +02:00
bdadde8b98 Tile-Server: eigene Range-fähige /tiles-Route (StaticFiles liefert hinter BaseHTTPMiddleware kein 206)
Spike-Befund: app-weit kommen nur 200 ohne Accept-Ranges zurück, FileResponse-Range
wird von der BaseHTTPMiddleware gebrochen. MapLibre/pmtiles braucht aber Byte-Ranges.
Route gibt 206 als normales Response (Byte-Slice) zurück. Produktion: nginx/NPM direkt.
2026-06-04 20:31:57 +02:00
d9ecdb15fb Tile-Server-Spike: /tiles StaticFiles-Mount + tiles/ vom Tar/Git ausschließen
- main.py: geschützter /tiles-Mount (TILES_DIR, No-Op ohne Verzeichnis), Range-Requests via Starlette FileResponse
- Makefile: tiles/ aus TAR_EXCLUDE (546MB pmtiles nicht ins Staging-Tar)
- .gitignore: *.pmtiles/*.osm.pbf/tiles-build ausschließen
2026-06-04 20:27:33 +02:00
cde019cacf Docs: Übergabe Tile-Server (planetiler→PMTiles→MapLibre, Staging-Spike-Plan) 2026-06-04 19:57:59 +02:00
545b57c723 Fix: Account-Löschung FK-sicher über alle Tabellen (defer_foreign_keys + Introspektion)
Der alte delete_account löschte nur ~6 Tabellen und scheiterte am finalen
DELETE FROM users, sobald der User Zeilen in Non-Cascade-Tabellen hatte
(routes, places, walks, events, forum_threads, invoices …). Jetzt:
PRAGMA defer_foreign_keys + foreign_key_list-Introspektion (CASCADE automatisch,
NO-ACTION-Eigentum löschen, Actor/SET-NULL-Spalten nullen) plus user_id/owner_id-
Scan für Tabellen ohne formale FK. Regressionstest test_account_deletion.py.

Relevant für App-Store-Gl. 4 (In-App-Konto-Löschung muss zuverlässig funktionieren).
2026-06-04 19:21:18 +02:00