diff --git a/app.js b/app.js index df0b62a..398ae4a 100644 --- a/app.js +++ b/app.js @@ -11,7 +11,8 @@ document.addEventListener('DOMContentLoaded', async () => { bakedData: {}, // Cache for standalone persistence ownerMapping: { firstName: 'vorname', lastName: 'nachname' }, // Default for ALKIS and modern Shapefiles ownerStatuses: {}, // { "name vorname": { status: "...", notiz: "..." } } - showAuxiliary: true + showAuxiliary: true, + isEditMode: false }; const STATUS_MAP = { @@ -383,7 +384,7 @@ document.addEventListener('DOMContentLoaded', async () => { ksfAngle, ksfMirrored, totalHeight: geoms.totalHeight, layers: { - marker: L.marker(latlng, { draggable: true, icon: turbineIcon }), + marker: L.marker(latlng, { draggable: state.isEditMode, icon: turbineIcon }), sweptArea: L.geoJSON(geoms.sweptArea, { style: { color: '#00c8ff', weight: 1, dashArray: '4, 4', fillOpacity: 0.1 } }), techDist: L.geoJSON(geoms.techDist, { style: { color: '#ffcc00', weight: 2, dashArray: '5, 5', fillOpacity: 0 } }), techDistSmall: L.geoJSON(geoms.techDistSmall, { style: { color: '#ffcc00', weight: 1.5, dashArray: '2, 4', fillOpacity: 0 } }), @@ -393,7 +394,7 @@ document.addEventListener('DOMContentLoaded', async () => { blf: L.geoJSON(geoms.blf, { style: { color: '#9b59b6', weight: 1, dashArray: '3, 3', fillOpacity: 0.2 } }), mf: L.geoJSON(geoms.mf, { style: { color: '#95a5a6', weight: 1, dashArray: '2, 2', fillOpacity: 0.15 } }), rotationHandle: L.marker(latlng, { - draggable: true, + draggable: state.isEditMode, icon: L.divIcon({ className: 'rotation-handle', html: ` @@ -437,7 +438,9 @@ document.addEventListener('DOMContentLoaded', async () => { updateLabel(turbine, geoms); // Click to Edit - turbine.layers.marker.on('click', () => openEditPanel(turbine)); + turbine.layers.marker.on('click', () => { + if (state.isEditMode) openEditPanel(turbine); + }); // Drag Update turbine.layers.marker.on('drag', (e) => { @@ -633,6 +636,20 @@ document.addEventListener('DOMContentLoaded', async () => { }; } + const checkShowOwnersOutline = document.getElementById('checkShowOwnersOutline'); + if (checkShowOwnersOutline) { + checkShowOwnersOutline.onchange = () => { + const outlineLayer = overlays["Flurstücke & Eigentümer (Umriss)"]; + if (outlineLayer) { + if (checkShowOwnersOutline.checked) { + state.map.addLayer(outlineLayer); + } else { + state.map.removeLayer(outlineLayer); + } + } + }; + } + // UTM Creation Logic const btnCreateAtUTM = document.getElementById('btnCreateAtUTM'); const inputUtmE = document.getElementById('utm-e'); @@ -1207,6 +1224,59 @@ document.addEventListener('DOMContentLoaded', async () => { layerControl.addOverlay(layer, layerName); layer.bringToFront(); // Ensure it's on top of local shapefiles + + // ---- Erzeuge zusätzlich den Umriss-Layer ---- + const outlineLayerName = "Flurstücke & Eigentümer (Umriss)"; + const outlineLayer = L.geoJSON(geojson, { + style: () => ({ color: '#000', weight: 1.5, fillOpacity: 0, fillColor: 'transparent' }), + onEachFeature: (feature, outLayer) => { + if (feature.properties) { + const props = feature.properties; + const firstName = (props.vorname || props.VNA || '').trim(); + const lastName = (props.nachname || props.GNA || '').trim(); + + let rawStatus = props.status || 'Kein Status'; + let notiz = props.notiz || ''; + + const matched = getAlkisOwnerStatus(firstName, lastName, state); + if (matched) { + rawStatus = matched.status; + notiz = matched.notiz; + } + + const status = (rawStatus && LEGACY_STATUS_MAP[rawStatus.toLowerCase()]) ? LEGACY_STATUS_MAP[rawStatus.toLowerCase()] : (rawStatus || 'Kein Status'); + + const popup = generateAlkisPopup(props, firstName, lastName, status, notiz, outlineLayerName); + outLayer.bindPopup(popup); + + const flur = props.FLN || '-'; + let fst = '-'; + if (props.ZAE) { + fst = props.NEN ? `${props.ZAE}/${props.NEN}` : props.ZAE; + } + const labelContent = ` +
+ ${lastName}, ${firstName}
+ Flur ${flur}, Flst. ${fst} +
+ `; + outLayer.bindTooltip(labelContent, { + permanent: true, + direction: 'center', + className: 'alkis-label', + offset: [0, 0] + }); + } + } + }); + + overlays[outlineLayerName] = outlineLayer; + const checkShowOwnersOutline = document.getElementById('checkShowOwnersOutline'); + if (checkShowOwnersOutline && checkShowOwnersOutline.checked) { + state.map.addLayer(outlineLayer); + } + layerControl.addOverlay(outlineLayer, outlineLayerName); + outlineLayer.bringToFront(); } // Manual Import & Bundling @@ -1912,6 +1982,67 @@ document.addEventListener('DOMContentLoaded', async () => { }; } + // Initialize Edit Mode Toggle + const btnToggleEditMode = document.getElementById('btnToggleEditMode'); + const editModeIcon = document.getElementById('editModeIcon'); + const editModeText = document.getElementById('editModeText'); + + function updateEditModeUI() { + if (state.isEditMode) { + editModeIcon.innerText = '🔓'; + editModeText.innerText = 'Bearbeitung aktiv'; + btnToggleEditMode.classList.replace('btn-secondary', 'btn-primary'); + btnPlaceTurbine.disabled = false; + btnPlaceTurbine.style.opacity = '1'; + btnCreateAtUTM.disabled = false; + btnCreateAtUTM.style.opacity = '1'; + if (btnManageOwners) { + btnManageOwners.disabled = false; + btnManageOwners.style.opacity = '1'; + } + } else { + editModeIcon.innerText = '🔒'; + editModeText.innerText = 'Bearbeitung gesperrt'; + btnToggleEditMode.classList.replace('btn-primary', 'btn-secondary'); + btnPlaceTurbine.disabled = true; + btnPlaceTurbine.style.opacity = '0.5'; + btnCreateAtUTM.disabled = true; + btnCreateAtUTM.style.opacity = '0.5'; + if (btnManageOwners) { + btnManageOwners.disabled = true; + btnManageOwners.style.opacity = '0.5'; + } + + closeEditPanel(); + if (ownerModal) ownerModal.style.display = 'none'; + if (placementMode) { + placementMode = false; + btnPlaceTurbine.classList.remove('active'); + state.map.getContainer().style.cursor = ''; + state.map.getContainer().classList.remove('placement-active'); + } + } + + state.turbines.forEach(t => { + if (state.isEditMode) { + t.layers.marker.dragging.enable(); + t.layers.rotationHandle.dragging.enable(); + } else { + t.layers.marker.dragging.disable(); + t.layers.rotationHandle.dragging.disable(); + } + }); + } + + if (btnToggleEditMode) { + btnToggleEditMode.addEventListener('click', () => { + state.isEditMode = !state.isEditMode; + updateEditModeUI(); + }); + // Set initial state (locked) + updateEditModeUI(); + } + updateLegend(); console.log("WindPlaner initialisiert."); document.getElementById('statusInfo').innerText = "System bereit. Karte geladen."; diff --git a/index.html b/index.html index 6b95b9a..1c4716e 100644 --- a/index.html +++ b/index.html @@ -42,6 +42,12 @@ + + @@ -98,11 +104,11 @@

UTM-Position

- +
- +
@@ -145,11 +151,11 @@
- +
- +
- +
- +
- +
- +
- +
@@ -215,11 +221,11 @@

Bitte ordnen Sie die Spalten für Namen aus dem Layer "Eigentümer" zu:

- +
- +