// Vektor-Basemap für Leaflet via protomaps-leaflet, gerendert aus unseren eigenen // PMTiles (OpenMapTiles-Schema von planetiler, ausgeliefert unter /tiles/). // Ersetzt den OSM-Raster-Layer — Leaflet + markercluster + alle Marker bleiben unberührt. // Labels werden von protomaps-leaflet per Canvas-Text gezeichnet → KEINE Glyphs nötig. (function () { 'use strict'; // Single-File-Tile-Archiv (DACH). Liegt im data-Volume, per Range ausgeliefert. var TILES_FILE = 'dach.pmtiles'; function tilesUrl() { return window.location.origin + '/tiles/' + TILES_FILE; } // Straßenbreite zoomabhängig (dünn weit draußen, breit im Detail). function roadWidth(z) { if (z >= 16) return 4; if (z >= 14) return 2.5; if (z >= 12) return 1.5; if (z >= 9) return 0.8; return 0.4; } // Farbpaletten Light/Dark. var THEMES = { light: { bg: '#f4f1ec', water: '#a0c8f0', land: '#dce8c8', park: '#c8e6b0', road: '#ffffff', roadCasing: '#d9cfc2', building: '#e6ddcf', buildingLine: '#d4cabb', boundary: '#b08ac0', label: '#33312e', labelHalo: 'rgba(255,255,255,.85)', }, dark: { bg: '#1a1d21', water: '#16242e', land: '#222820', park: '#27331f', road: '#3a4046', roadCasing: '#23282d', building: '#262b30', buildingLine: '#31373d', boundary: '#7d5a8c', label: '#cfd2d6', labelHalo: 'rgba(0,0,0,.8)', }, }; function buildRules(t) { var P = protomapsL; var paint = [ { dataLayer: 'landcover', symbolizer: new P.PolygonSymbolizer({ fill: t.land, opacity: 0.55 }) }, { dataLayer: 'park', symbolizer: new P.PolygonSymbolizer({ fill: t.park, opacity: 0.5 }) }, { dataLayer: 'water', symbolizer: new P.PolygonSymbolizer({ fill: t.water }) }, { dataLayer: 'waterway', symbolizer: new P.LineSymbolizer({ color: t.water, width: 0.8 }) }, // Straßen-Casing zuerst (liegt unter der Füllung), dann die Straße. { dataLayer: 'transportation', minzoom: 11, symbolizer: new P.LineSymbolizer({ color: t.roadCasing, width: function (z) { return roadWidth(z) + 1.5; } }) }, { dataLayer: 'transportation', symbolizer: new P.LineSymbolizer({ color: t.road, width: roadWidth }) }, { dataLayer: 'building', minzoom: 13, symbolizer: new P.PolygonSymbolizer({ fill: t.building, stroke: t.buildingLine, width: 0.5 }) }, { dataLayer: 'boundary', symbolizer: new P.LineSymbolizer({ color: t.boundary, width: 1, dash: [2, 2] }) }, ]; var label = [ { dataLayer: 'place', minzoom: 4, symbolizer: new P.CenteredTextSymbolizer({ labelProps: ['name:de', 'name'], fill: t.label, stroke: t.labelHalo, width: 2.5, font: function (z) { return (z >= 10 ? '600 13px' : '600 11px') + ' system-ui, sans-serif'; }, }) }, ]; return { paint: paint, label: label }; } // Erzeugt den Leaflet-Layer. dark=true → dunkles Theme. function basemapLayer(opts) { opts = opts || {}; var t = THEMES[opts.dark ? 'dark' : 'light']; var rules = buildRules(t); return protomapsL.leafletLayer({ url: tilesUrl(), paintRules: rules.paint, labelRules: rules.label, backgroundColor: t.bg, attribution: '© OpenStreetMap contributors', }); } window.MapVector = { basemapLayer: basemapLayer, tilesUrl: tilesUrl, tilesFile: TILES_FILE, }; })();