feat(windkarte): geometry eingebettet in wind_area CMS-Einträge
GeoJSON-Geometrie direkt in CMS-Einträgen gespeichert — kein separates GeoJSON-File mehr. WindkarteMap baut FeatureCollection aus areas[].geometry. WindArea-Typ bekommt geometry-Feld. geojsonUrl-Prop entfernt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,13 +5,11 @@
|
||||
|
||||
let {
|
||||
areas,
|
||||
geojsonUrl,
|
||||
onselect,
|
||||
onready = null,
|
||||
initialGebietsNr = null,
|
||||
}: {
|
||||
areas: WindArea[];
|
||||
geojsonUrl: string;
|
||||
onselect: (area: WindArea | null, center: [number, number] | null) => void;
|
||||
onready?: ((ctrl: { reset: () => void }) => void) | null;
|
||||
initialGebietsNr?: string | null;
|
||||
@@ -136,8 +134,21 @@
|
||||
});
|
||||
|
||||
try {
|
||||
const geoRes = await fetch(geojsonUrl);
|
||||
const geo: GeoJSON.FeatureCollection = await geoRes.json();
|
||||
// Build FeatureCollection directly from CMS areas (geometry embedded)
|
||||
const geo: GeoJSON.FeatureCollection = {
|
||||
type: "FeatureCollection",
|
||||
features: areas
|
||||
.filter((a) => a.geometry)
|
||||
.map((a) => ({
|
||||
type: "Feature" as const,
|
||||
properties: {
|
||||
name: a.gebiets_nr,
|
||||
bezeichnung: a.bezeichnung,
|
||||
status: a.status ?? "rechtskraeftig",
|
||||
},
|
||||
geometry: a.geometry!,
|
||||
})),
|
||||
};
|
||||
|
||||
const layerMap = new Map<string, { feature: GeoJSON.Feature; layer: import("leaflet").Layer }>();
|
||||
|
||||
@@ -147,8 +158,9 @@
|
||||
return style(s, false);
|
||||
},
|
||||
onEachFeature: (feature, layer) => {
|
||||
const cmsArea = byNr[feature.properties?.name] ?? null;
|
||||
if (cmsArea) feature.properties.cms = cmsArea;
|
||||
const p = feature.properties ?? {};
|
||||
const area = byNr[p.name] ?? { _slug: "", gebiets_nr: p.name ?? "", status: p.status, bezeichnung: p.bezeichnung };
|
||||
feature.properties.cms = area;
|
||||
|
||||
const name = feature.properties?.name ?? "";
|
||||
layerMap.set(name, { feature, layer });
|
||||
@@ -169,15 +181,15 @@
|
||||
|
||||
layer.on("click", async (e) => {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
await selectFeature(L, feature, layer, cmsArea);
|
||||
await selectFeature(L, feature, layer, area);
|
||||
});
|
||||
|
||||
// Hover tooltip
|
||||
const hoverLabel = feature.properties?.bezeichnung ?? name;
|
||||
const hoverLabel = area.bezeichnung ?? p.name ?? "";
|
||||
layer.bindTooltip(hoverLabel, { sticky: true, className: "windkarte-tooltip" });
|
||||
|
||||
// Permanent label via divIcon marker at polygon center
|
||||
const nr = cmsArea?.gebiets_nr ?? name;
|
||||
const nr = area.gebiets_nr ?? p.name;
|
||||
if (nr && labelLayer) {
|
||||
const center = (layer as import("leaflet").Polygon).getBounds().getCenter();
|
||||
L.marker(center, {
|
||||
@@ -217,11 +229,11 @@
|
||||
if (initialGebietsNr) {
|
||||
const entry = layerMap.get(initialGebietsNr);
|
||||
if (entry) {
|
||||
await selectFeature(L, entry.feature, entry.layer, byNr[initialGebietsNr] ?? null, true);
|
||||
await selectFeature(L, entry.feature, entry.layer, byNr[initialGebietsNr] ?? null);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("GeoJSON laden fehlgeschlagen:", e);
|
||||
console.error("Karte laden fehlgeschlagen:", e);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
env.PUBLIC_CMS_URL || "http://localhost:3000"
|
||||
).replace(/\/$/, "");
|
||||
|
||||
const GEOJSON_URL = `${CMS_BASE}/api/assets/geodaten/windvorranggebiete_swt_2012.geojson`;
|
||||
|
||||
let areas = $state<WindArea[]>([]);
|
||||
let areas = $state<WindArea[]>([]);
|
||||
let selectedArea = $state<WindArea | null>(null);
|
||||
let selectedCenter = $state<[number, number] | null>(null);
|
||||
let mapReady = $state(false);
|
||||
@@ -106,7 +104,6 @@
|
||||
{#await MapComponent then Map}
|
||||
<Map
|
||||
{areas}
|
||||
geojsonUrl={GEOJSON_URL}
|
||||
{initialGebietsNr}
|
||||
onselect={handleSelect}
|
||||
onready={(ctrl) => { resetMap = ctrl.reset; }}
|
||||
|
||||
@@ -10,4 +10,5 @@ export type WindArea = {
|
||||
gemeinden?: string[];
|
||||
stellungnahme?: { _slug: string; slug?: string } | string | null;
|
||||
notizen?: string;
|
||||
geometry?: GeoJSON.Geometry;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user