diff --git a/src/lib/components/WindkarteMap.svelte b/src/lib/components/WindkarteMap.svelte index 27beebc..c4f9a25 100644 --- a/src/lib/components/WindkarteMap.svelte +++ b/src/lib/components/WindkarteMap.svelte @@ -9,12 +9,14 @@ onready = null, initialGebietsNr = null, hiddenStatuses = [], + hiddenRings = ["2km", "5km"], }: { areas: WindArea[]; onselect: (area: WindArea | null, center: [number, number] | null) => void; onready?: ((ctrl: { reset: () => void }) => void) | null; initialGebietsNr?: string | null; hiddenStatuses?: string[]; + hiddenRings?: string[]; } = $props(); // Mirror prop into plain variable so Leaflet event handlers read current value. @@ -46,6 +48,20 @@ let selectedSlug = $state(null); let geojsonLayer: import("leaflet").GeoJSON | null = null; let buffering = $state(false); + let permanentRing2km = $state(null); + let permanentRing5km = $state(null); + + $effect(() => { + const hidden = hiddenRings; + for (const [key, layer] of [["2km", permanentRing2km], ["5km", permanentRing5km]] as [string, import("leaflet").LayerGroup | null][]) { + if (!layer || !map) continue; + if (hidden.includes(key)) { + if (map.hasLayer(layer)) map.removeLayer(layer); + } else { + if (!map.hasLayer(layer)) map.addLayer(layer); + } + } + }); const COLORS: Record = { rechtskraeftig: { fill: "#2d7a45", stroke: "#1a4d28" }, @@ -258,6 +274,19 @@ map.on("zoomend", syncLabels); syncLabels(); + // Permanent 2km / 5km rings for all areas (built async, shown/hidden via hiddenRings prop) + const { buffer: turfBuffer } = await import("@turf/buffer"); + const r2 = L.layerGroup(); + const r5 = L.layerGroup(); + for (const feature of geo.features) { + const b2 = turfBuffer(feature, 2, { units: "kilometers" }); + if (b2) L.geoJSON(b2, { style: { color: "#5e6fa3", fillColor: "#5e6fa3", fillOpacity: 0.04, weight: 1.5, dashArray: "10 5" }, interactive: false }).addTo(r2); + const b5 = turfBuffer(feature, 5, { units: "kilometers" }); + if (b5) L.geoJSON(b5, { style: { color: "#8a567a", fillColor: "#8a567a", fillOpacity: 0.03, weight: 1.5, dashArray: "14 6" }, interactive: false }).addTo(r5); + } + permanentRing2km = r2; + permanentRing5km = r5; + // Auto-select from hash if (initialGebietsNr) { const entry = layerMap.get(initialGebietsNr); diff --git a/src/lib/components/blocks/WindkarteBlock.svelte b/src/lib/components/blocks/WindkarteBlock.svelte index 0988380..39c113e 100644 --- a/src/lib/components/blocks/WindkarteBlock.svelte +++ b/src/lib/components/blocks/WindkarteBlock.svelte @@ -22,6 +22,7 @@ let areas = $state([]); let initialGebietsNr = $state(null); let resetMap: (() => void) | null = null; let hiddenStatuses = $state([]); + let hiddenRings = $state(["2km", "5km"]); function toggleStatus(status: string) { hiddenStatuses = hiddenStatuses.includes(status) @@ -29,6 +30,12 @@ let areas = $state([]); : [...hiddenStatuses, status]; } + function toggleRing(ring: string) { + hiddenRings = hiddenRings.includes(ring) + ? hiddenRings.filter((r) => r !== ring) + : [...hiddenRings, ring]; + } + const MapComponent = browser ? import("$lib/components/WindkarteMap.svelte").then((m) => m.default) : null; @@ -113,6 +120,7 @@ let areas = $state([]); {areas} {initialGebietsNr} {hiddenStatuses} + {hiddenRings} onselect={handleSelect} onready={(ctrl) => { resetMap = ctrl.reset; }} /> @@ -159,6 +167,18 @@ let areas = $state([]); {ring.label} {/each} + {#each [{ key: "2km", color: "#5e6fa3", label: "2 km" }, { key: "5km", color: "#8a567a", label: "5 km" }] as ring} + + {/each}