diff --git a/app.js b/app.js
index e0a7d14..13a52df 100644
--- a/app.js
+++ b/app.js
@@ -1112,7 +1112,48 @@ document.addEventListener('DOMContentLoaded', async () => {
document.getElementById('statusInfo').innerHTML += ` | ALKIS-Layer Fehler`;
}
- statusEl.innerText = "Layer geladen (ALKIS DB integriert).";
+ // Artennachweis laden
+ console.log("Lade Artennachweis-Layer aus Datenbank...");
+ const artenResp = await fetch('/api/layers/artennachweis').catch(err => {
+ console.error("Netzwerkfehler beim Laden des Artennachweis-Layers:", err);
+ return null;
+ });
+
+ if (artenResp?.ok) {
+ const data = await artenResp.json();
+ console.log(`Artennachweis API: ${data.features ? data.features.length : 0} Features erhalten.`);
+ if (data.features && data.features.length > 0) {
+ const artenLayer = L.geoJSON(data, {
+ pointToLayer: (feature, latlng) => {
+ return L.circleMarker(latlng, {
+ radius: 5,
+ fillColor: "#ff4444",
+ color: "#ffffff",
+ weight: 2,
+ opacity: 1,
+ fillOpacity: 0.8
+ });
+ },
+ onEachFeature: (feature, layer) => {
+ if (feature.properties && feature.properties.art) {
+ layer.bindTooltip(feature.properties.art, {
+ permanent: true,
+ direction: 'top',
+ className: 'arten-label'
+ });
+ layer.bindPopup(`Vogelart: ${feature.properties.art}`);
+ }
+ }
+ });
+ overlays["Artennachweis"] = artenLayer;
+ state.map.addLayer(artenLayer);
+ layerControl.addOverlay(artenLayer, "Artennachweis");
+ }
+ } else {
+ console.warn("Artennachweis-Layer konnte nicht geladen werden.");
+ }
+
+ statusEl.innerText = "Layer geladen (ALKIS DB & Artennachweis integriert).";
} catch (e) {
if (!isLocalFile) console.error("Layer-Init fehlgeschlagen:", e);
}
diff --git a/server.js b/server.js
index 8a1909b..b256976 100644
--- a/server.js
+++ b/server.js
@@ -248,6 +248,33 @@ app.get('/api/layers/alkis', async (req, res) => {
}
});
+// NEU: API zum Laden des Artennachweis-Layers als GeoJSON
+app.get('/api/layers/artennachweis', async (req, res) => {
+ log("Lade Artennachweis-Layer aus Datenbank...");
+ try {
+ const result = await pool.query(
+ `SELECT jsonb_build_object(
+ 'type', 'FeatureCollection',
+ 'features', COALESCE(jsonb_agg(features.feature), '[]'::jsonb)
+ )
+ FROM (
+ SELECT jsonb_build_object(
+ 'type', 'Feature',
+ 'geometry', ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb,
+ 'properties', jsonb_build_object(
+ 'art', art
+ )
+ ) AS feature
+ FROM geodaten.artennachweis
+ ) features`
+ );
+ res.json(result.rows[0].jsonb_build_object);
+ } catch (err) {
+ log(`FEHLER beim Laden des Artennachweis-Layers: ${err.message}`);
+ res.status(500).json({ error: err.message });
+ }
+});
+
// API für Projekt-Statistiken (Fortschrittsanzeige)
app.get('/api/stats/:projekt_id', async (req, res) => {
const { projekt_id } = req.params;
diff --git a/style.css b/style.css
index ef63116..339e9fc 100644
--- a/style.css
+++ b/style.css
@@ -857,4 +857,23 @@ body {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
}
+}
+
+/* Artennachweis Labels */
+.arten-label {
+ background: rgba(255, 68, 68, 0.85) !important;
+ border: 1px solid rgba(255, 255, 255, 0.8) !important;
+ color: white !important;
+ font-weight: 700 !important;
+ font-size: 0.75rem !important;
+ border-radius: 4px !important;
+ padding: 2px 6px !important;
+ pointer-events: none !important;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.4) !important;
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.6);
+ white-space: nowrap;
+}
+
+.arten-label::before {
+ border-top-color: rgba(255, 68, 68, 0.85) !important;
}
\ No newline at end of file