// components/uiWidgets/baseMapPanel/BaseMapPanel.js , aus rechliche Grunde nur OSM, dieses Feature ist optional, aktuell nicht genutzt import React, { useEffect, useMemo, useRef, useState } from "react"; import L from "leaflet"; import { Icon } from "@iconify/react"; // Minimal, safe defaults (no API key required). You can extend via config later. const DEFAULT_BASE_LAYERS = [ { id: "osm-standard", name: "Standard", url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", attribution: "© OpenStreetMap contributors", minZoom: 0, maxZoom: 19, }, { id: "osm-humanitarian", name: "Humanitarian", url: "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", attribution: "© OpenStreetMap contributors, Humanitarian OpenStreetMap Team", minZoom: 0, maxZoom: 19, }, { id: "cyclosm", name: "CyclOSM", url: "https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", attribution: "© OpenStreetMap contributors, CyclOSM", minZoom: 0, maxZoom: 20, }, { id: "carto-light", name: "Carto Light", url: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png", attribution: "© OpenStreetMap contributors, © CARTO", subdomains: "abcd", minZoom: 0, maxZoom: 20, }, ]; function getCurrentTileLayer(map) { let found = null; if (!map) return null; map.eachLayer(layer => { if (!found && layer instanceof L.TileLayer) { found = layer; } }); return found; } export default function BaseMapPanel({ map, onSelect, onClose, initialId }) { const [activeId, setActiveId] = useState(initialId || null); const layerCacheRef = useRef({}); const bases = useMemo(() => { try { if (typeof window !== "undefined") { const cfg = window.__leafletConfig; if (cfg && cfg.tileSources) { return Object.entries(cfg.tileSources).map(([key, ts]) => ({ id: key, name: ts.name || key, url: ts.url, attribution: ts.attribution || "© OpenStreetMap contributors", minZoom: ts.minZoom ?? cfg.minZoom ?? 0, maxZoom: ts.maxZoom ?? cfg.maxZoom ?? 19, subdomains: ts.subdomains, })); } } } catch (_) {} return DEFAULT_BASE_LAYERS; }, []); const applyBase = id => { if (!map) return; const base = bases.find(b => b.id === id) || bases[0]; if (!base) return; // Remove current tile layer const current = getCurrentTileLayer(map); if (current) { try { map.removeLayer(current); } catch (_) {} } // Get or create the new layer let nextLayer = layerCacheRef.current[id]; if (!nextLayer) { nextLayer = L.tileLayer(base.url, { attribution: base.attribution, subdomains: base.subdomains || "abc", tileSize: 256, minZoom: base.minZoom ?? 0, maxZoom: base.maxZoom ?? 19, noWrap: true, // Ensure base tiles stay behind overlays zIndex: 1, }); layerCacheRef.current[id] = nextLayer; } nextLayer.addTo(map); try { if (typeof map.setMinZoom === "function") map.setMinZoom(base.minZoom ?? 0); if (typeof map.setMaxZoom === "function") map.setMaxZoom(base.maxZoom ?? 19); if (typeof window !== "undefined") { window.__tileSourceMinZoom = base.minZoom ?? 0; window.__tileSourceMaxZoom = base.maxZoom ?? 19; } } catch (_) {} setActiveId(id); try { localStorage.setItem("baseMapId", id); } catch (_) {} onSelect && onSelect(id); }; useEffect(() => { const saved = (() => { try { return localStorage.getItem("baseMapId"); } catch (_) { return null; } })(); const targetId = initialId || saved || bases[0]?.id; if (targetId) { applyBase(targetId); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [map]); return (

Map Layers

{bases.map(b => ( ))}
); }