UI: Add Edit Mode Toggle and Outline Layer
Deploy Bürgerwind / deploy (push) Successful in 17s
Details
Deploy Bürgerwind / deploy (push) Successful in 17s
Details
This commit is contained in:
parent
be2831fcbd
commit
89dfcdff25
139
app.js
139
app.js
|
|
@ -11,7 +11,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
bakedData: {}, // Cache for standalone persistence
|
bakedData: {}, // Cache for standalone persistence
|
||||||
ownerMapping: { firstName: 'vorname', lastName: 'nachname' }, // Default for ALKIS and modern Shapefiles
|
ownerMapping: { firstName: 'vorname', lastName: 'nachname' }, // Default for ALKIS and modern Shapefiles
|
||||||
ownerStatuses: {}, // { "name vorname": { status: "...", notiz: "..." } }
|
ownerStatuses: {}, // { "name vorname": { status: "...", notiz: "..." } }
|
||||||
showAuxiliary: true
|
showAuxiliary: true,
|
||||||
|
isEditMode: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const STATUS_MAP = {
|
const STATUS_MAP = {
|
||||||
|
|
@ -383,7 +384,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
ksfAngle, ksfMirrored,
|
ksfAngle, ksfMirrored,
|
||||||
totalHeight: geoms.totalHeight,
|
totalHeight: geoms.totalHeight,
|
||||||
layers: {
|
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 } }),
|
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 } }),
|
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 } }),
|
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 } }),
|
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 } }),
|
mf: L.geoJSON(geoms.mf, { style: { color: '#95a5a6', weight: 1, dashArray: '2, 2', fillOpacity: 0.15 } }),
|
||||||
rotationHandle: L.marker(latlng, {
|
rotationHandle: L.marker(latlng, {
|
||||||
draggable: true,
|
draggable: state.isEditMode,
|
||||||
icon: L.divIcon({
|
icon: L.divIcon({
|
||||||
className: 'rotation-handle',
|
className: 'rotation-handle',
|
||||||
html: `
|
html: `
|
||||||
|
|
@ -437,7 +438,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
updateLabel(turbine, geoms);
|
updateLabel(turbine, geoms);
|
||||||
|
|
||||||
// Click to Edit
|
// Click to Edit
|
||||||
turbine.layers.marker.on('click', () => openEditPanel(turbine));
|
turbine.layers.marker.on('click', () => {
|
||||||
|
if (state.isEditMode) openEditPanel(turbine);
|
||||||
|
});
|
||||||
|
|
||||||
// Drag Update
|
// Drag Update
|
||||||
turbine.layers.marker.on('drag', (e) => {
|
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
|
// UTM Creation Logic
|
||||||
const btnCreateAtUTM = document.getElementById('btnCreateAtUTM');
|
const btnCreateAtUTM = document.getElementById('btnCreateAtUTM');
|
||||||
const inputUtmE = document.getElementById('utm-e');
|
const inputUtmE = document.getElementById('utm-e');
|
||||||
|
|
@ -1207,6 +1224,59 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
layerControl.addOverlay(layer, layerName);
|
layerControl.addOverlay(layer, layerName);
|
||||||
layer.bringToFront(); // Ensure it's on top of local shapefiles
|
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 = `
|
||||||
|
<div class="alkis-label-inner">
|
||||||
|
<span class="owner-name">${lastName}, ${firstName}</span><br>
|
||||||
|
<span class="parcel-info">Flur ${flur}, Flst. ${fst}</span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
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
|
// 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();
|
updateLegend();
|
||||||
console.log("WindPlaner initialisiert.");
|
console.log("WindPlaner initialisiert.");
|
||||||
document.getElementById('statusInfo').innerText = "System bereit. Karte geladen.";
|
document.getElementById('statusInfo').innerText = "System bereit. Karte geladen.";
|
||||||
|
|
|
||||||
28
index.html
28
index.html
|
|
@ -42,6 +42,12 @@
|
||||||
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-dim);">
|
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-dim);">
|
||||||
<input type="checkbox" id="checkShowOwners" checked> Eigentümerzustimmung
|
<input type="checkbox" id="checkShowOwners" checked> Eigentümerzustimmung
|
||||||
</label>
|
</label>
|
||||||
|
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-dim);">
|
||||||
|
<input type="checkbox" id="checkShowOwnersOutline"> Flurstücke (Umriss)
|
||||||
|
</label>
|
||||||
|
<button id="btnToggleEditMode" class="btn-secondary btn-mini" style="margin-top: 8px; display: flex; align-items: center; justify-content: center; gap: 5px; padding: 6px;">
|
||||||
|
<span id="editModeIcon">🔒</span> <span id="editModeText">Bearbeitung gesperrt</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -98,11 +104,11 @@
|
||||||
<h2 style="margin-bottom: 6px;">UTM-Position</h2>
|
<h2 style="margin-bottom: 6px;">UTM-Position</h2>
|
||||||
<div style="display: flex; gap: 6px; margin-bottom: 6px;">
|
<div style="display: flex; gap: 6px; margin-bottom: 6px;">
|
||||||
<div style="flex: 1;">
|
<div style="flex: 1;">
|
||||||
<label class="label-small">Rechts (E)</label>
|
<label for="utm-e" class="label-small">Rechts (E)</label>
|
||||||
<input type="number" id="utm-e" class="input-styled input-small" placeholder="32..." step="0.01">
|
<input type="number" id="utm-e" class="input-styled input-small" placeholder="32..." step="0.01">
|
||||||
</div>
|
</div>
|
||||||
<div style="flex: 1;">
|
<div style="flex: 1;">
|
||||||
<label class="label-small">Hoch (N)</label>
|
<label for="utm-n" class="label-small">Hoch (N)</label>
|
||||||
<input type="number" id="utm-n" class="input-styled input-small" placeholder="5..." step="0.01">
|
<input type="number" id="utm-n" class="input-styled input-small" placeholder="5..." step="0.01">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -145,11 +151,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-rows-container">
|
<div class="edit-rows-container">
|
||||||
<div class="edit-row">
|
<div class="edit-row">
|
||||||
<label>Nr:</label>
|
<label for="edit-wea-nr">Nr:</label>
|
||||||
<input type="text" id="edit-wea-nr" class="edit-input">
|
<input type="text" id="edit-wea-nr" class="edit-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row separator">
|
<div class="edit-row separator">
|
||||||
<label>Hersteller:</label>
|
<label for="edit-wea-manufacturer">Hersteller:</label>
|
||||||
<select id="edit-wea-manufacturer" class="edit-input">
|
<select id="edit-wea-manufacturer" class="edit-input">
|
||||||
<option value="Enercon">Enercon</option>
|
<option value="Enercon">Enercon</option>
|
||||||
<option value="Nordex">Nordex</option>
|
<option value="Nordex">Nordex</option>
|
||||||
|
|
@ -158,23 +164,23 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row separator">
|
<div class="edit-row separator">
|
||||||
<label>Typ:</label>
|
<label for="edit-wea-type">Typ:</label>
|
||||||
<input type="text" id="edit-wea-type" class="edit-input">
|
<input type="text" id="edit-wea-type" class="edit-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row">
|
<div class="edit-row">
|
||||||
<label>RD (m):</label>
|
<label for="edit-wea-rd">RD (m):</label>
|
||||||
<input type="number" id="edit-wea-rd" class="edit-input">
|
<input type="number" id="edit-wea-rd" class="edit-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row separator">
|
<div class="edit-row separator">
|
||||||
<label>NH (m):</label>
|
<label for="edit-wea-nh">NH (m):</label>
|
||||||
<input type="number" id="edit-wea-nh" class="edit-input">
|
<input type="number" id="edit-wea-nh" class="edit-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row">
|
<div class="edit-row">
|
||||||
<label>Fund (m):</label>
|
<label for="edit-wea-fr">Fund (m):</label>
|
||||||
<input type="number" id="edit-wea-fr" class="edit-input">
|
<input type="number" id="edit-wea-fr" class="edit-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row separator">
|
<div class="edit-row separator">
|
||||||
<label>Wink (°):</label>
|
<label for="edit-wea-ksf-angle">Wink (°):</label>
|
||||||
<input type="number" id="edit-wea-ksf-angle" class="edit-input" value="0">
|
<input type="number" id="edit-wea-ksf-angle" class="edit-input" value="0">
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-row" style="margin-top: 5px;">
|
<div class="edit-row" style="margin-top: 5px;">
|
||||||
|
|
@ -215,11 +221,11 @@
|
||||||
<p>Bitte ordnen Sie die Spalten für Namen aus dem Layer "Eigentümer" zu:</p>
|
<p>Bitte ordnen Sie die Spalten für Namen aus dem Layer "Eigentümer" zu:</p>
|
||||||
<div style="display: flex; gap: 15px; justify-content: center; margin-top: 15px;">
|
<div style="display: flex; gap: 15px; justify-content: center; margin-top: 15px;">
|
||||||
<div>
|
<div>
|
||||||
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Vorname</label>
|
<label for="selectFirstName" style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Vorname</label>
|
||||||
<select id="selectFirstName" class="input-styled" style="width: 150px;"></select>
|
<select id="selectFirstName" class="input-styled" style="width: 150px;"></select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Nachname</label>
|
<label for="selectLastName" style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Nachname</label>
|
||||||
<select id="selectLastName" class="input-styled" style="width: 150px;"></select>
|
<select id="selectLastName" class="input-styled" style="width: 150px;"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue