From ed821296f33c51e6af5ba7274571661b936ef27f Mon Sep 17 00:00:00 2001 From: Johannes Baumeister Date: Thu, 25 Jun 2026 09:25:39 +0200 Subject: [PATCH] feat: filter artennachweis, restriktionen, gebaeude, and wohngebaeude by project (either by project ID or within 5km of project parcels) --- app.js | 8 ++-- server.js | 125 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 111 insertions(+), 22 deletions(-) diff --git a/app.js b/app.js index f02787c..05f8be6 100644 --- a/app.js +++ b/app.js @@ -1252,7 +1252,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Artennachweis laden console.log("Lade Artennachweis-Layer aus Datenbank..."); - const artenResp = await fetch('/api/layers/artennachweis').catch(err => { + const artenResp = await fetch(`/api/layers/artennachweis?project=${encodeURIComponent(projId)}`).catch(err => { console.error("Netzwerkfehler beim Laden des Artennachweis-Layers:", err); return null; }); @@ -1293,7 +1293,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Artennachweis Restriktionsabstände laden console.log("Lade Artennachweise-Restriktionen aus Datenbank..."); - const restriktionResp = await fetch('/api/layers/artennachweise_restriktionen').catch(err => { + const restriktionResp = await fetch(`/api/layers/artennachweise_restriktionen?project=${encodeURIComponent(projId)}`).catch(err => { console.error("Netzwerkfehler beim Laden der Restriktionsabstände:", err); return null; }); @@ -1368,7 +1368,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Gebäude laden console.log("Lade Gebäude aus Datenbank..."); - const gebaudeResp = await fetch('/api/layers/gebaeude').catch(err => { + const gebaudeResp = await fetch(`/api/layers/gebaeude?project=${encodeURIComponent(projId)}`).catch(err => { console.error("Netzwerkfehler beim Laden der Gebäude:", err); return null; }); @@ -1401,7 +1401,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Wohngebäude laden console.log("Lade Wohngebäude aus Datenbank..."); - const wohngebaudeResp = await fetch('/api/layers/wohngebeaude').catch(err => { + const wohngebaudeResp = await fetch(`/api/layers/wohngebeaude?project=${encodeURIComponent(projId)}`).catch(err => { console.error("Netzwerkfehler beim Laden der Wohngebäude:", err); return null; }); diff --git a/server.js b/server.js index 0532cc9..468da5f 100644 --- a/server.js +++ b/server.js @@ -269,9 +269,25 @@ 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..."); + const projectParam = req.query.project || req.query.projekt_id || req.query.projekt; + log(`Lade Artennachweis-Layer aus Datenbank für Projekt: ${projectParam || 'alle'}`); + const client = await pool.connect(); try { - const result = await pool.query( + let whereClause = ''; + const params = []; + + if (projectParam) { + const projId = await resolveProjectId(client, projectParam); + whereClause = `WHERE projekt_id = $1`; + params.push(projectParam); // e.g. 'test' or 'BWSamern-Ohne' + + if (projId) { + whereClause += ` OR projekt_id = $2`; + params.push(projId); + } + } + + const result = await client.query( `SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', COALESCE(jsonb_agg(features.feature), '[]'::jsonb) @@ -285,20 +301,43 @@ app.get('/api/layers/artennachweis', async (req, res) => { ) ) AS feature FROM geodaten.artennachweise - ) features` + ${whereClause} + ) features`, + params ); 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 }); + } finally { + client.release(); } }); // NEU: API zum Laden der Artennachweis Restriktionsabstände app.get('/api/layers/artennachweise_restriktionen', async (req, res) => { - log("Lade Artennachweise-Restriktionen aus Datenbank..."); + const projectParam = req.query.project || req.query.projekt_id || req.query.projekt; + log(`Lade Artennachweise-Restriktionen aus Datenbank für Projekt: ${projectParam || 'alle'}`); + const client = await pool.connect(); try { - const result = await pool.query( + let whereClause = ''; + const params = []; + + if (projectParam) { + const projId = await resolveProjectId(client, projectParam); + if (projId) { + whereClause = `WHERE EXISTS ( + SELECT 1 + FROM geodaten.flaecheneigentuemer_alkis alkis + JOIN geodaten.flaecheneigentuemer_alkis_zuweisung z ON alkis."FSK" = z.fsk + WHERE z.projekt_id = $1 + AND ST_DWithin(a.geom, alkis.geom, 5000) + )`; + params.push(projId); + } + } + + const result = await client.query( `SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', COALESCE(jsonb_agg(features.feature), '[]'::jsonb) @@ -306,16 +345,20 @@ app.get('/api/layers/artennachweise_restriktionen', async (req, res) => { FROM ( SELECT jsonb_build_object( 'type', 'Feature', - 'geometry', ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb, + 'geometry', ST_AsGeoJSON(ST_Transform(a.geom, 4326))::jsonb, 'properties', jsonb_build_object() ) AS feature - FROM geodaten.artennachweise_restriktion_abstand - ) features` + FROM geodaten.artennachweise_restriktion_abstand a + ${whereClause} + ) features`, + params ); res.json(result.rows[0].jsonb_build_object); } catch (err) { log(`FEHLER beim Laden der Restriktionen: ${err.message}`); res.status(500).json({ error: err.message }); + } finally { + client.release(); } }); @@ -371,9 +414,28 @@ app.get('/api/layers/leitungsverlaeufe', async (req, res) => { // NEU: API zum Laden der Gebäude app.get('/api/layers/gebaeude', async (req, res) => { - log("Lade Gebäude aus Datenbank..."); + const projectParam = req.query.project || req.query.projekt_id || req.query.projekt; + log(`Lade Gebäude aus Datenbank für Projekt: ${projectParam || 'alle'}`); + const client = await pool.connect(); try { - const result = await pool.query( + let whereClause = ''; + const params = []; + + if (projectParam) { + const projId = await resolveProjectId(client, projectParam); + if (projId) { + whereClause = `WHERE EXISTS ( + SELECT 1 + FROM geodaten.flaecheneigentuemer_alkis alkis + JOIN geodaten.flaecheneigentuemer_alkis_zuweisung z ON alkis."FSK" = z.fsk + WHERE z.projekt_id = $1 + AND ST_DWithin(g.geom, alkis.geom, 5000) + )`; + params.push(projId); + } + } + + const result = await client.query( `SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', COALESCE(jsonb_agg(features.feature), '[]'::jsonb) @@ -381,24 +443,47 @@ app.get('/api/layers/gebaeude', async (req, res) => { FROM ( SELECT jsonb_build_object( 'type', 'Feature', - 'geometry', ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb, + 'geometry', ST_AsGeoJSON(ST_Transform(g.geom, 4326))::jsonb, 'properties', jsonb_build_object() ) AS feature - FROM geodaten.gebaeude - ) features` + FROM geodaten.gebaeude g + ${whereClause} + ) features`, + params ); res.json(result.rows[0].jsonb_build_object); } catch (err) { log(`FEHLER beim Laden der Gebäude: ${err.message}`); res.status(500).json({ error: err.message }); + } finally { + client.release(); } }); // NEU: API zum Laden der Wohngebäude app.get('/api/layers/wohngebeaude', async (req, res) => { - log("Lade Wohngebäude aus Datenbank..."); + const projectParam = req.query.project || req.query.projekt_id || req.query.projekt; + log(`Lade Wohngebäude aus Datenbank für Projekt: ${projectParam || 'alle'}`); + const client = await pool.connect(); try { - const result = await pool.query( + let whereClause = ''; + const params = []; + + if (projectParam) { + const projId = await resolveProjectId(client, projectParam); + if (projId) { + whereClause = `WHERE EXISTS ( + SELECT 1 + FROM geodaten.flaecheneigentuemer_alkis alkis + JOIN geodaten.flaecheneigentuemer_alkis_zuweisung z ON alkis."FSK" = z.fsk + WHERE z.projekt_id = $1 + AND ST_DWithin(w.geom, alkis.geom, 5000) + )`; + params.push(projId); + } + } + + const result = await client.query( `SELECT jsonb_build_object( 'type', 'FeatureCollection', 'features', COALESCE(jsonb_agg(features.feature), '[]'::jsonb) @@ -406,16 +491,20 @@ app.get('/api/layers/wohngebeaude', async (req, res) => { FROM ( SELECT jsonb_build_object( 'type', 'Feature', - 'geometry', ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb, + 'geometry', ST_AsGeoJSON(ST_Transform(w.geom, 4326))::jsonb, 'properties', jsonb_build_object() ) AS feature - FROM geodaten.wohngebeaude - ) features` + FROM geodaten.wohngebeaude w + ${whereClause} + ) features`, + params ); res.json(result.rows[0].jsonb_build_object); } catch (err) { log(`FEHLER beim Laden der Wohngebäude: ${err.message}`); res.status(500).json({ error: err.message }); + } finally { + client.release(); } });