Offline-Karten: Kern implementiert (Region-Download → IndexedDB → Offline-Render)

map-offline.js (window.MapOffline): lädt Vektorkacheln eines Bereichs via pmtiles.getZxy
in IndexedDB + cacht die Glyphs mit (KRITISCH: ohne Glyphs lässt MapLibre offline die
ganze Kachel fallen). byt://-Protokoll bedient MapLibre IndexedDB-first, remote-Fallback.
- map-gl-style.js: build({offline}) nutzt byt-Source statt pmtiles:// (Flag by_offline_tiles,
  Default AUS bis gerätegetestet); glyphs bleiben /fonts (SW-gecacht)
- ui.js + map.js: map-offline.js mitladen + byt-Protokoll registrieren
- getZxy liefert bereits dekomprimierte MVT (kein gunzip) → ~15 MB/5km in IndexedDB

Headless bewiesen: Download 97 Tiles (5km München) → Netz AUS → 1903 Features gerendert,
nicht geladene Gegend (Paris) korrekt leer. Offen: Download-Button/FAB-Segment-5-Verdrahtung,
adaptives Lernen, Bereichsauswahl/Routen-Korridor (siehe docs/OFFLINE_MAPS_PLAN.md).
This commit is contained in:
rene 2026-06-05 19:46:18 +02:00
parent 2a809a9a0b
commit 8f13f4d38d
9 changed files with 177 additions and 20 deletions

View file

@ -12,6 +12,12 @@
var TILES_VER = '20260605';
function tilesUrl() { return window.location.origin + '/tiles/' + TILES_FILE + '?v=' + TILES_VER; }
// Offline-Tiles-Modus (byt://-Quelle). Opt-in via localStorage by_offline_tiles='1' bzw. ?tilesoffline=1.
// Default AUS, bis auf Gerät verifiziert — dann hier auf Staging-Default umstellen (analog by_map_gl).
function _offlineEnabled() {
try { return localStorage.getItem('by_offline_tiles') === '1'; } catch (e) { return false; }
}
var THEMES = {
light: {
bg: '#f2efe8', land: '#cbe3a8', park: '#aedd88', water: '#7fbbe8',
@ -38,11 +44,17 @@
function build(opts) {
opts = opts || {};
var t = THEMES[opts.dark ? 'dark' : 'light'];
// offline → Tiles übers byt://-Protokoll (IndexedDB-first, remote-Fallback) statt direkt aus der
// Remote-PMTiles. Nötig für Offline-Betrieb. Default aus Flag (by_offline_tiles), explizit übersteuerbar.
var useOffline = opts.offline != null ? opts.offline : _offlineEnabled();
var src = useOffline
? { type: 'vector', tiles: ['byt://t/{z}/{x}/{y}'], minzoom: 0, maxzoom: 14 }
: { type: 'vector', url: 'pmtiles://' + tilesUrl() };
return {
version: 8,
glyphs: window.location.origin + '/fonts/{fontstack}/{range}.pbf',
sources: {
by: { type: 'vector', url: 'pmtiles://' + tilesUrl() },
by: src,
},
layers: [
{ id: 'bg', type: 'background', paint: { 'background-color': t.bg } },
@ -160,5 +172,5 @@
setTimeout(fn, 60);
}
window.MapGLStyle = { build: build, tilesUrl: tilesUrl, tilesFile: TILES_FILE, collapseAttribution: collapseAttribution };
window.MapGLStyle = { build: build, tilesUrl: tilesUrl, tilesFile: TILES_FILE, collapseAttribution: collapseAttribution, offlineEnabled: _offlineEnabled };
})();