diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55d61a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules/ +.env +backend/node_modules/ +backend/check_db.py +backend/check_db.js +backend/check_db2.js +backend/check_db_admin.js +backend/list_tables.js +backend/check_columns.js +backend/setup_db.py +.vscode/ +*.log diff --git a/app.js b/app.js index c3bc4db..b905b9b 100644 --- a/app.js +++ b/app.js @@ -1414,9 +1414,45 @@ document.addEventListener('DOMContentLoaded', async () => { a.download = `WindPlan_Projekt_${new Date().toLocaleDateString()}.json`; a.click(); URL.revokeObjectURL(url); - document.getElementById('statusInfo').innerText = "Projekt exportiert."; + document.getElementById('statusInfo').innerText = "Projekt lokal exportiert."; }); + const btnSaveDB = document.getElementById('btnSaveDB'); + if (btnSaveDB) { + btnSaveDB.addEventListener('click', async () => { + const statusEl = document.getElementById('statusInfo'); + statusEl.innerText = "Speichere in Datenbank..."; + + const project_id = "BWSamern-Ohne"; // Could be dynamic from config + const turbineData = state.turbines.map(t => ({ + nr: t.nr, + variant: t.variant, + type: t.type, + rd: t.rd, + hh: t.hh, + latlng: t.layers.marker.getLatLng() + })); + + try { + const response = await fetch('http://localhost:3000/api/wea', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ projekt_id, turbines: turbineData }) + }); + + if (response.ok) { + const result = await response.json(); + statusEl.innerHTML = `${result.message}`; + } else { + throw new Error("Fehler beim Speichern in DB"); + } + } catch (err) { + console.error(err); + statusEl.innerHTML = `Fehler beim DB-Sync: ${err.message}`; + } + }); + } + btnLoad.addEventListener('click', () => projectInput.click()); projectInput.addEventListener('change', (e) => { diff --git a/backend/server.js b/backend/server.js new file mode 100644 index 0000000..84db9cc --- /dev/null +++ b/backend/server.js @@ -0,0 +1,90 @@ +require('dotenv').config(); +const express = require('express'); +const { Pool } = require('pg'); +const bodyParser = require('body-parser'); +const cors = require('cors'); + +const app = express(); +const port = process.env.PORT || 3000; + +app.use(cors()); +app.use(bodyParser.json()); + +const pool = new Pool({ + host: process.env.DB_HOST, + port: process.env.DB_PORT, + database: process.env.DB_NAME, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD +}); + +// Test DB Connection +pool.connect() + .then(() => console.log('Connected to PostgreSQL (enwelo_db) successfully')) + .catch(err => console.error('Connection error', err.stack)); + +// API to save turbines +app.post('/api/wea', async (req, res) => { + const { projekt_id, turbines } = req.body; + const client = await pool.connect(); + + try { + await client.query('BEGIN'); + + // Delete existing turbines for this project before saving new state + // (This ensures we always have the latest state on 'Save') + await client.query('DELETE FROM geodaten.wea_standorte WHERE projekt_id = $1', [projekt_id]); + + for(let t of turbines) { + // Mapping frontend data to geodaten.wea_standorte columns: + // wea_nummer, hersteller, anlagentyp, nabenhoehe, rotordurchmesser, ksf_drehung, projekt_id, geom + + await client.query( + `INSERT INTO geodaten.wea_standorte ( + wea_nummer, hersteller, anlagentyp, nabenhoehe, rotordurchmesser, ksf_drehung, projekt_id, geom + ) VALUES ($1, $2, $3, $4, $5, $6, $7, ST_SetSRID(ST_MakePoint($8, $9), 4326))`, + [ + t.nr, + t.hersteller || '', + t.type, + parseInt(t.hh), + parseInt(t.rd), + parseInt(t.ksfAngle || 0), + projekt_id, + t.latlng.lng, + t.latlng.lat + ] + ); + } + + await client.query('COMMIT'); + res.status(200).json({ message: 'Windenergieanlagen erfolgreich in Datenbank gespeichert' }); + } catch (e) { + await client.query('ROLLBACK'); + console.error('Error saving turbines', e); + res.status(500).json({ error: e.message }); + } finally { + client.release(); + } +}); + +// API to load turbines +app.get('/api/wea/:projekt_id', async (req, res) => { + const { projekt_id } = req.params; + try { + const result = await pool.query( + `SELECT wea_nummer as nr, anlagentyp as type, nabenhoehe as hh, rotordurchmesser as rd, ksf_drehung as ksfAngle, + ST_X(geom) as lng, ST_Y(geom) as lat + FROM geodaten.wea_standorte WHERE projekt_id = $1`, + [projekt_id] + ); + res.status(200).json(result.rows); + } catch (e) { + console.error('Error loading turbines', e); + res.status(500).json({ error: e.message }); + } +}); + +app.listen(port, () => { + console.log(`Backend server listening at http://localhost:${port}`); +}); diff --git a/index.html b/index.html index 464fd62..8954b59 100644 --- a/index.html +++ b/index.html @@ -120,8 +120,9 @@