/* ==========================================================================
Kirschner Gebäudeservice — Karte
MapLibre GL (lokal) mit Kacheln von OpenFreeMap. Lädt erst, wenn die Karte
in die Nähe des sichtbaren Bereichs scrollt; bis dahin (und falls WebGL
fehlt) bleibt die schematische Vorschau stehen.
========================================================================== */
const STYLE = 'https://tiles.openfreemap.org/styles/dark';
/* Dunkler Stil, auf die Nachtblau-Palette der Seite umgefärbt */
const TINT = [
['background', 'background-color', '#0A1424'],
['water', 'fill-color', '#16263F'],
['waterway', 'line-color', '#16263F'],
['landuse_residential', 'fill-color', '#0F1D33'],
['landcover_wood', 'fill-color', '#0E1B2F'],
['landuse_park', 'fill-color', '#0E1B2F'],
['building', 'fill-color', '#13233B'],
['building', 'fill-outline-color', '#1F3354'],
['highway_path', 'line-color', '#1F3354'],
['highway_minor', 'line-color', '#1B2D4A'],
['highway_major_casing', 'line-color', 'rgba(91,138,214,.28)'],
['highway_major_inner', 'line-color', '#1F3354'],
['highway_major_subtle', 'line-color', '#1F3354'],
['highway_motorway_casing', 'line-color', 'rgba(91,138,214,.4)'],
['highway_motorway_subtle', 'line-color', '#1F3354'],
['railway', 'line-color', '#1F3354'],
['highway_name_other', 'text-color', '#8C9BB3'],
['highway_name_other', 'text-halo-color', '#0A1424'],
];
const LOCALE = {
'CooperativeGesturesHandler.WindowsHelpText': 'Strg + Scrollen zum Zoomen',
'CooperativeGesturesHandler.MacHelpText': '⌘ + Scrollen zum Zoomen',
'CooperativeGesturesHandler.MobileHelpText': 'Mit zwei Fingern verschieben',
'NavigationControl.ZoomIn': 'Vergrößern',
'NavigationControl.ZoomOut': 'Verkleinern',
'AttributionControl.ToggleAttribution': 'Quellenangaben',
};
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
function loadCss(href) {
if (document.querySelector(`link[href="${href}"]`)) return;
const l = document.createElement('link');
l.rel = 'stylesheet';
l.href = href;
document.head.appendChild(l);
}
function hasWebGL() {
try {
const c = document.createElement('canvas');
return !!(c.getContext('webgl2') || c.getContext('webgl'));
} catch (e) {
return false;
}
}
async function mount(el) {
const lng = Number(el.dataset.lng);
const lat = Number(el.dataset.lat);
loadCss(new URL('vendor/maplibre/maplibre-gl.css', import.meta.url).href);
const maplibregl = await import('./vendor/maplibre/maplibre-gl.mjs');
const canvas = document.createElement('div');
canvas.className = 'map__canvas';
el.appendChild(canvas);
const map = new maplibregl.Map({
container: canvas,
style: STYLE,
center: [lng, lat],
zoom: reduce ? 15 : 12.6,
attributionControl: { compact: true },
cooperativeGestures: true,
dragRotate: false,
pitchWithRotate: false,
locale: LOCALE,
});
map.addControl(new maplibregl.NavigationControl({ showCompass: false }), 'bottom-right');
const marker = document.createElement('div');
marker.className = 'map-marker';
marker.innerHTML = `${el.dataset.label}`;
new maplibregl.Marker({ element: marker, anchor: 'bottom' }).setLngLat([lng, lat]).addTo(map);
map.on('style.load', () => {
for (const [layer, prop, value] of TINT) {
if (map.getLayer(layer)) map.setPaintProperty(layer, prop, value);
}
});
map.once('load', () => {
el.classList.add('is-live');
if (!reduce) map.flyTo({ center: [lng, lat], zoom: 15, duration: 2600, essential: false });
});
}
const maps = [...document.querySelectorAll('[data-map]')];
if (maps.length && hasWebGL()) {
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (!e.isIntersecting) return;
io.unobserve(e.target);
mount(e.target).catch((err) => console.warn('Karte nicht geladen, Vorschau bleibt:', err));
});
}, { rootMargin: '400px 0px' });
maps.forEach((m) => io.observe(m));
}