diff --git a/app.js b/app.js
index b6fdba4..de765eb 100644
--- a/app.js
+++ b/app.js
@@ -10,10 +10,23 @@ document.addEventListener('DOMContentLoaded', async () => {
activeVariant: 'A',
bakedData: {}, // Cache for standalone persistence
ownerMapping: { firstName: 'VNA', lastName: 'GNA' }, // Default for ALKIS
- ownerStatuses: {}, // { "Name Vorname": "status" }
+ ownerStatuses: {}, // { "name vorname": { status: "...", notiz: "..." } }
showAuxiliary: true
};
+ const STATUS_MAP = {
+ 'Ablehnung': { color: '#ff0000', desc: 'Der Eigentümer lehnt das Vorhaben strikt ab.' },
+ 'Erwartet Negativ': { color: '#ffa500', desc: 'Erste Signale oder Tendenzen deuten auf eine Ablehnung hin.' },
+ 'Unentschlossen': { color: '#ffff00', desc: 'Rückmeldung ist noch offen oder der Eigentümer zögert.' },
+ 'Unbekannt': { color: '#cccccc', desc: 'Bisher kein Kontakt erfolgt; Status ist völlig offen.' },
+ 'Erwartet Positiv': { color: '#90ee90', desc: 'Eine grundsätzliche Bereitschaft zur Zustimmung wird erwartet.' },
+ 'Zusage (mündlich)': { color: '#008000', desc: 'Klare mündliche Zustimmung liegt vor, der schriftliche Vertrag ist noch offen.' },
+ 'Vertraglich gesichert': { color: '#006400', desc: 'Der Vertrag liegt unterschrieben vor.' },
+ 'In der Projektgesellschaft': { color: '#ff00ff', desc: 'Grundstückseigentümer ist in der Projektgesellschaft.' },
+ 'Fremdplanung': { color: '#c71585', desc: 'Anderes Vorhaben (WEA), keine Kooperation.' },
+ 'Kooperationspartner': { color: '#ffffff', desc: 'Anderes Vorhaben mit dem kooperiert wird.' }
+ };
+
// Removed fetch for config to prevent CORS errors on file:// protocol
console.log("Konfiguration geladen.");
@@ -247,8 +260,7 @@ document.addEventListener('DOMContentLoaded', async () => {
function updateLegend() {
if (!legendContent) return;
- // Items to always show if any turbine exists
- let html = '';
+ let html = '
Anlagen-Geometrien
';
if (state.turbines.length > 0) {
html += `
Rotorfläche
@@ -258,22 +270,25 @@ document.addEventListener('DOMContentLoaded', async () => {
Fundament
Kranstellfläche (KSF)
`;
+ } else {
+ html += 'Keine Anlagen gesetzt
';
}
- // Search for active external layers
- Object.keys(overlays).forEach(name => {
- const layer = overlays[name];
- if (state.map.hasLayer(layer)) {
- // Determine color (heuristic or from layer style)
- let color = '#ccc';
- if (name.includes('Eigentümer')) color = '#2ecc71';
- if (name.includes('Hilfs')) color = '#ffcc00';
-
- html += ` ${name}
`;
- }
+ html += 'Sicherungsstand (ALKIS)
';
+ Object.keys(STATUS_MAP).forEach(status => {
+ const data = STATUS_MAP[status];
+ html += `
+
+
+
+
${status}
+
${data.desc}
+
+
+ `;
});
- legendContent.innerHTML = html || 'Keine aktiven Layer
';
+ legendContent.innerHTML = html;
}
// Toggle Legend collapse
@@ -1210,38 +1225,45 @@ document.addEventListener('DOMContentLoaded', async () => {
}
async function processALKISData(geojson, layerName) {
- const style = getDynamicStyle(layerName) || { color: '#000', weight: 1, fillOpacity: 0.1 };
-
const layer = L.geoJSON(geojson, {
style: (feature) => {
const props = feature.properties;
- const firstName = props.VNA || '';
- const lastName = props.GNA || '';
+ const firstName = (props.VNA || '').trim();
+ const lastName = (props.GNA || '').trim();
const ownerName = `${firstName} ${lastName}`.trim().toLowerCase();
const stored = state.ownerStatuses[ownerName];
- const status = (typeof stored === 'string' ? stored : (stored?.status || props.status || "")).toLowerCase();
+ const status = typeof stored === 'object' ? (stored.status || '') : (stored || props.status || '');
let fillColor = 'transparent';
+ let opacity = 0.1;
- if (status === 'gbr' || status === 'gesichert') fillColor = '#2ecc71';
- else if (status === 'external' || status === 'fremdplanung') fillColor = '#e74c3c';
- else if (status === 'declined' || status === 'ablehnend' || status === 'negative') fillColor = '#e74c3c';
- else if (status === 'undecided' || status === 'unentschlossen') fillColor = '#95a5a6';
- else if (status === 'positive' || status === 'positiv') fillColor = '#5efd9c';
- else if (status === 'in verhandlung') fillColor = '#f1c40f';
+ if (STATUS_MAP[status]) {
+ fillColor = STATUS_MAP[status].color;
+ opacity = 0.7;
+ } else if (status === 'none' || status === '') {
+ fillColor = 'transparent';
+ opacity = 0.1;
+ }
return {
color: '#000',
weight: 1,
- fillOpacity: fillColor === 'transparent' ? 0.1 : 0.7,
+ fillOpacity: opacity,
fillColor: fillColor
};
},
onEachFeature: (feature, layer) => {
if (feature.properties) {
+ const status = feature.properties.status || 'Kein Status';
+ const notiz = feature.properties.notiz || '';
let popup = `${layerName} `;
+ popup += `Eigentümer: ${feature.properties.VNA} ${feature.properties.GNA} `;
+ popup += `Status: ${status} `;
+ if (notiz) popup += `Notiz: ${notiz} `;
+ popup += ` `;
for (let key in feature.properties) {
+ if (['VNA', 'GNA', 'status', 'notiz', 'id'].includes(key)) continue;
const val = feature.properties[key];
if (val !== null && val !== undefined) popup += `${key}: ${val} `;
}
@@ -1432,11 +1454,7 @@ document.addEventListener('DOMContentLoaded', async () => {
Kein Status
- Mitglied der GbR
- Fremdplanung
- Ablehnend
- Positiv
- Unentschlossen
+ ${Object.keys(STATUS_MAP).map(s => `${s} `).join('')}
diff --git a/style.css b/style.css
index f78727d..8e4707d 100644
--- a/style.css
+++ b/style.css
@@ -228,39 +228,95 @@ body {
.floating-panel {
position: absolute;
z-index: 1000;
- background: var(--panel-bg);
+ background: #0a2d2d; /* Dark teal background matching the image */
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
- border: 1px solid var(--border-color);
+ border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.panel-header {
- background: rgba(255, 255, 255, 0.05);
- padding: 10px 15px;
+ background: rgba(0, 0, 0, 0.2);
+ padding: 12px 18px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
- border-bottom: 1px solid var(--border-color);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
font-size: 0.85rem;
- font-weight: 600;
+ font-weight: 700;
+ letter-spacing: 0.5px;
+ color: white;
}
.panel-content {
- padding: 12px;
- max-height: 300px;
+ padding: 18px;
+ max-height: 500px;
overflow-y: auto;
}
/* Floating Legend Specific */
#floatingLegend {
- bottom: 20px;
- right: 20px;
- width: 220px;
+ bottom: 25px;
+ right: 25px;
+ width: 320px;
+}
+
+.legend-section-title {
+ font-size: 0.7rem;
+ font-weight: 800;
+ color: var(--primary-color);
+ margin-bottom: 12px;
+ text-transform: uppercase;
+ letter-spacing: 1.2px;
+ opacity: 0.8;
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ font-size: 0.85rem;
+ margin-bottom: 10px;
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.legend-item-status {
+ display: flex;
+ align-items: flex-start;
+ gap: 15px;
+ margin-bottom: 18px;
+}
+
+.status-dot {
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ flex-shrink: 0;
+ margin-top: 2px;
+ box-shadow: 0 0 10px rgba(0,0,0,0.3);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.status-text-container {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+
+.status-label {
+ font-weight: 800;
+ font-size: 0.95rem;
+ color: white;
+}
+
+.status-desc {
+ font-size: 0.75rem;
+ color: rgba(255, 255, 255, 0.6);
+ line-height: 1.4;
}
#floatingLegend.collapsed .panel-content {
@@ -270,7 +326,7 @@ body {
.toggle-btn {
background: transparent;
border: none;
- color: var(--text-dim);
+ color: white;
cursor: pointer;
font-size: 0.7rem;
transition: transform 0.3s;