fix: Windkarte verbirgt Labels ausgeblendeter Status

Per-Status LayerGroups statt einer globalen labelLayer. syncLabels
respektiert hiddenStatuses und entfernt Labels für versteckte
Status-Kategorien beim Zoomen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-06-06 09:22:00 +02:00
parent 894263e5c4
commit 415e772e57
+32 -16
View File
@@ -33,6 +33,7 @@
let _hidden: string[] = []; let _hidden: string[] = [];
$effect(() => { $effect(() => {
_hidden = hiddenStatuses; _hidden = hiddenStatuses;
syncLabelsFn?.();
if (!geojsonLayer) return; if (!geojsonLayer) return;
restyleAll(selectedSlug); restyleAll(selectedSlug);
// Deselect if selected area's status was just hidden. // Deselect if selected area's status was just hidden.
@@ -58,7 +59,8 @@
let bufferLayer: import("leaflet").LayerGroup | null = null; let bufferLayer: import("leaflet").LayerGroup | null = null;
let ring2kmLayer: import("leaflet").LayerGroup | null = null; let ring2kmLayer: import("leaflet").LayerGroup | null = null;
let ring5kmLayer: import("leaflet").LayerGroup | null = null; let ring5kmLayer: import("leaflet").LayerGroup | null = null;
let labelLayer: import("leaflet").LayerGroup | null = null; let labelLayers: Record<string, import("leaflet").LayerGroup> = {};
let syncLabelsFn: (() => void) | null = null;
let selectedSlug = $state<string | null>(null); let selectedSlug = $state<string | null>(null);
let geojsonLayer: import("leaflet").GeoJSON | null = null; let geojsonLayer: import("leaflet").GeoJSON | null = null;
let buffering = $state(false); let buffering = $state(false);
@@ -198,7 +200,13 @@
map = L.map(mapEl, { zoomControl: true, attributionControl: false }).setView([50.62, 10.42], 10); map = L.map(mapEl, { zoomControl: true, attributionControl: false }).setView([50.62, 10.42], 10);
L.control.attribution({ position: "bottomleft" }).addTo(map); L.control.attribution({ position: "bottomleft" }).addTo(map);
labelLayer = L.layerGroup(); // not added to map yet — shown only at zoom >= 13 // One label LayerGroup per status — lets syncLabels respect hiddenStatuses
labelLayers = {
rechtskraeftig: L.layerGroup(),
entwurf_2: L.layerGroup(),
entwurf_2_voraussichtlich: L.layerGroup(),
entwurf_3: L.layerGroup(),
};
onready?.({ reset: () => map!.setView([50.62, 10.42], 10) }); onready?.({ reset: () => map!.setView([50.62, 10.42], 10) });
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
@@ -295,7 +303,9 @@
// Permanent label via divIcon marker at polygon center // Permanent label via divIcon marker at polygon center
const nr = area.gebiets_nr ?? p.name; const nr = area.gebiets_nr ?? p.name;
if (nr && labelLayer) { const featStatus = (feature?.properties?.status ?? "rechtskraeftig") as string;
const targetGroup = labelLayers[featStatus] ?? labelLayers.rechtskraeftig;
if (nr && targetGroup) {
const center = (layer as import("leaflet").Polygon).getBounds().getCenter(); const center = (layer as import("leaflet").Polygon).getBounds().getCenter();
L.marker(center, { L.marker(center, {
icon: L.divIcon({ icon: L.divIcon({
@@ -306,29 +316,35 @@
}), }),
interactive: false, interactive: false,
keyboard: false, keyboard: false,
}).addTo(labelLayer); }).addTo(targetGroup);
} }
}, },
}).addTo(map); }).addTo(map);
restyleAll(selectedSlug); restyleAll(selectedSlug);
// Labels: show from zoom 13, scale font proportionally with zoom // Labels: show from zoom 13, scale font proportionally with zoom.
// Per-status LayerGroup so hidden statuses also hide their labels.
const syncLabels = () => { const syncLabels = () => {
if (!labelLayer || !map) return; if (!map) return;
const z = map.getZoom(); const z = map.getZoom();
if (z >= 13) { const show = z >= 13;
if (!map.hasLayer(labelLayer)) map.addLayer(labelLayer); const fontSize = Math.max(8, Math.min(26, Math.round(9 * Math.pow(2, z - 13))));
const fontSize = Math.max(8, Math.min(26, Math.round(9 * Math.pow(2, z - 13)))); for (const [status, layer] of Object.entries(labelLayers)) {
labelLayer.eachLayer((l) => { const visible = show && !_hidden.includes(status);
const el = (l as import("leaflet").Marker).getElement(); if (visible) {
const span = el?.querySelector<HTMLElement>(".windkarte-label"); if (!map.hasLayer(layer)) map.addLayer(layer);
if (span) span.style.fontSize = fontSize + "px"; layer.eachLayer((l) => {
}); const el = (l as import("leaflet").Marker).getElement();
} else { const span = el?.querySelector<HTMLElement>(".windkarte-label");
if (map.hasLayer(labelLayer)) map.removeLayer(labelLayer); if (span) span.style.fontSize = fontSize + "px";
});
} else {
if (map.hasLayer(layer)) map.removeLayer(layer);
}
} }
}; };
syncLabelsFn = syncLabels;
map.on("zoomend", syncLabels); map.on("zoomend", syncLabels);
syncLabels(); syncLabels();