Compare commits
No commits in common. "2b1eefe2296744e988b365f75f07a8399dae54f4" and "5682c076c16e66473e5d172e4503b1e9a5001c1a" have entirely different histories.
2b1eefe229
...
5682c076c1
|
|
@ -1,12 +0,0 @@
|
||||||
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
|
|
||||||
38
app.js
38
app.js
|
|
@ -1414,45 +1414,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
a.download = `WindPlan_Projekt_${new Date().toLocaleDateString()}.json`;
|
a.download = `WindPlan_Projekt_${new Date().toLocaleDateString()}.json`;
|
||||||
a.click();
|
a.click();
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
document.getElementById('statusInfo').innerText = "Projekt lokal exportiert.";
|
document.getElementById('statusInfo').innerText = "Projekt 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('/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 = `<span style="color: #2ecc71;">${result.message}</span>`;
|
|
||||||
} else {
|
|
||||||
throw new Error("Fehler beim Speichern in DB");
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
statusEl.innerHTML = `<span style="color: #ff4444;">Fehler beim DB-Sync: ${err.message}</span>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
btnLoad.addEventListener('click', () => projectInput.click());
|
btnLoad.addEventListener('click', () => projectInput.click());
|
||||||
|
|
||||||
projectInput.addEventListener('change', (e) => {
|
projectInput.addEventListener('change', (e) => {
|
||||||
|
|
|
||||||
|
|
@ -120,9 +120,8 @@
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>Projektverwaltung</h2>
|
<h2>Projektverwaltung</h2>
|
||||||
<button class="btn-secondary" id="btnSaveProject">Projekt speichern (Lokal)</button>
|
<button class="btn-secondary" id="btnSaveProject">Projekt speichern</button>
|
||||||
<button class="btn-primary" id="btnSaveDB">In Datenbank speichern</button>
|
<button class="btn-secondary" id="btnLoadProject">Projekt laden</button>
|
||||||
<button class="btn-secondary" id="btnLoadProject">Projekt laden (Lokal)</button>
|
|
||||||
<input type="file" id="projectInput" style="display: none;" accept=".json">
|
<input type="file" id="projectInput" style="display: none;" accept=".json">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
15
package.json
15
package.json
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"name": "bwsamern-ohne-planungstool",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "server.js",
|
|
||||||
"dependencies": {
|
|
||||||
"body-parser": "^1.20.2",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"dotenv": "^16.4.5",
|
|
||||||
"express": "^4.19.2",
|
|
||||||
"pg": "^8.11.5"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "node server.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
95
server.js
95
server.js
|
|
@ -1,95 +0,0 @@
|
||||||
require('dotenv').config();
|
|
||||||
const express = require('express');
|
|
||||||
const { Pool } = require('pg');
|
|
||||||
const bodyParser = require('body-parser');
|
|
||||||
const cors = require('cors');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
const port = process.env.PORT || 3000;
|
|
||||||
|
|
||||||
app.use(cors());
|
|
||||||
app.use(bodyParser.json());
|
|
||||||
|
|
||||||
// Serve static files from the root directory
|
|
||||||
app.use(express.static(path.join(__dirname, './')));
|
|
||||||
|
|
||||||
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 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
|
|
||||||
await client.query('DELETE FROM geodaten.wea_standorte WHERE projekt_id = $1', [projekt_id]);
|
|
||||||
|
|
||||||
for(let t of turbines) {
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Catch-all route to serve index.html for any other request (optional, good for SPAs)
|
|
||||||
app.get('*', (req, res) => {
|
|
||||||
res.sendFile(path.join(__dirname, 'index.html'));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.listen(port, '0.0.0.0', () => {
|
|
||||||
console.log(`Server running at http://0.0.0.0:${port}`);
|
|
||||||
});
|
|
||||||
Loading…
Reference in New Issue