diff --git a/Anlagentypen/Anlagentypen.xlsx b/Anlagentypen/Anlagentypen.xlsx index 823445d..35aaeb4 100644 Binary files a/Anlagentypen/Anlagentypen.xlsx and b/Anlagentypen/Anlagentypen.xlsx differ diff --git a/app.js b/app.js index 35dfddb..3562772 100644 --- a/app.js +++ b/app.js @@ -110,8 +110,7 @@ document.addEventListener('DOMContentLoaded', async () => { const btnDeleteWEA = document.getElementById('btnDeleteWEA'); const editNr = document.getElementById('edit-wea-nr'); - const editManufacturer = document.getElementById('edit-wea-manufacturer'); - const editType = document.getElementById('edit-wea-type'); + const editWeaSelector = document.getElementById('edit-wea-selector'); const editRd = document.getElementById('edit-wea-rd'); const editNh = document.getElementById('edit-wea-nh'); const editFr = document.getElementById('edit-wea-fr'); @@ -127,8 +126,7 @@ document.addEventListener('DOMContentLoaded', async () => { const inputRotor = document.getElementById('rotorDiameter'); const inputHub = document.getElementById('hubHeight'); const inputFoundation = document.getElementById('foundationRadius'); - const inputManufacturer = document.getElementById('turbineManufacturer'); - const inputType = document.getElementById('turbineType'); + const weaTypeSelector = document.getElementById('weaTypeSelector'); let placementMode = false; let measureMode = null; // 'dist' or 'area' @@ -291,8 +289,20 @@ document.addEventListener('DOMContentLoaded', async () => { } activeTurbine = turbine; editNr.value = turbine.nr; - editManufacturer.value = turbine.hersteller || 'Enercon'; - editType.value = turbine.type; + let matched = false; + for (const opt of editWeaSelector.options) { + if (opt.value) { + try { + const data = JSON.parse(opt.value); + if (data.hersteller === turbine.hersteller && data.anlagentyp === turbine.type && data.nabenhoehe === turbine.hh) { + editWeaSelector.value = opt.value; + matched = true; + break; + } + } catch(e) {} + } + } + if (!matched) editWeaSelector.value = ""; editRd.value = turbine.rd; editNh.value = turbine.hh; editFr.value = turbine.fr || 15; @@ -374,8 +384,15 @@ document.addEventListener('DOMContentLoaded', async () => { const rd = overrideData?.rd || Number.parseFloat(inputRotor?.value) || 160; const hh = overrideData?.hh || Number.parseFloat(inputHub?.value) || 165; const fr = overrideData?.fr || Number.parseFloat(inputFoundation?.value) || 15; - const type = overrideData?.type || inputType?.value || "Standard Typ"; - const hersteller = overrideData?.hersteller || inputManufacturer?.value || "Enercon"; + let type = overrideData?.type || "Standard Typ"; + let hersteller = overrideData?.hersteller || "Unbekannt"; + if (!overrideData && weaTypeSelector && weaTypeSelector.value) { + try { + const parsed = JSON.parse(weaTypeSelector.value); + type = parsed.anlagentyp; + hersteller = parsed.hersteller; + } catch(e) {} + } const weaNr = overrideData?.nr || loadedNr || (state.turbines.length + 1).toString(); const ksfAngle = overrideData?.ksfAngle || 0; const ksfMirrored = overrideData?.ksfMirrored || false; @@ -536,8 +553,15 @@ document.addEventListener('DOMContentLoaded', async () => { btnSaveEdit.onclick = () => { if (!activeTurbine) return; const newNr = editNr.value; - const newManufacturer = editManufacturer.value; - const newType = editType.value; + let newManufacturer = activeTurbine.hersteller; + let newType = activeTurbine.type; + if (editWeaSelector && editWeaSelector.value) { + try { + const parsed = JSON.parse(editWeaSelector.value); + newManufacturer = parsed.hersteller; + newType = parsed.anlagentyp; + } catch(e) {} + } const newRd = Number.parseFloat(editRd.value); const newNh = Number.parseFloat(editNh.value); const newFr = Number.parseFloat(editFr.value) || 15; @@ -2164,6 +2188,58 @@ document.addEventListener('DOMContentLoaded', async () => { } // Initialize allowed projects and project selector + window.availableWeaTypes = []; + + async function loadWeaTypes() { + try { + const res = await fetch('/api/wea-types'); + if (!res.ok) throw new Error('Network response was not ok'); + window.availableWeaTypes = await res.json(); + + // Build grouped options + const groups = {}; + window.availableWeaTypes.forEach(wea => { + if (!groups[wea.hersteller]) groups[wea.hersteller] = []; + groups[wea.hersteller].push(wea); + }); + + let html = ''; + for (const h in groups) { + html += ``; + } + + if (weaTypeSelector) { + weaTypeSelector.innerHTML = html; + weaTypeSelector.addEventListener('change', (e) => { + if (!e.target.value) return; + try { + const data = JSON.parse(e.target.value.replace(/"/g, '"')); + inputRotor.value = data.rotordurchmesser; + inputHub.value = data.nabenhoehe; + } catch(err) {} + }); + } + if (editWeaSelector) { + editWeaSelector.innerHTML = html; + editWeaSelector.addEventListener('change', (e) => { + if (!e.target.value) return; + try { + const data = JSON.parse(e.target.value.replace(/"/g, '"')); + editRd.value = data.rotordurchmesser; + editNh.value = data.nabenhoehe; + } catch(err) {} + }); + } + } catch (err) { + console.error('Fehler beim Laden der Anlagentypen:', err); + } + } + async function initializeProjects() { const statusEl = document.getElementById('statusInfo'); try { @@ -2258,6 +2334,7 @@ document.addEventListener('DOMContentLoaded', async () => { } // Start loading process + await loadWeaTypes(); initializeProjects(); // Project Persistence diff --git a/append_pdf.js b/append_pdf.js new file mode 100644 index 0000000..56ed14e --- /dev/null +++ b/append_pdf.js @@ -0,0 +1,97 @@ +const fs = require('fs'); +const js = ` + // --- PDF Export Logic --- + const btnExportPDF = document.getElementById('btnExportPDF'); + if (btnExportPDF) { + btnExportPDF.addEventListener('click', async () => { + const originalText = btnExportPDF.innerText; + btnExportPDF.innerText = 'Exportiere...'; + btnExportPDF.disabled = true; + + try { + if (typeof html2canvas === 'undefined' || typeof jspdf === 'undefined') { + throw new Error('PDF Bibliotheken (html2canvas, jspdf) sind noch nicht geladen.'); + } + + const mapContainer = document.getElementById('map'); + + // Add Overlay + const exportOverlay = document.createElement('div'); + exportOverlay.style.position = 'absolute'; + exportOverlay.style.bottom = '30px'; + exportOverlay.style.left = '30px'; + exportOverlay.style.zIndex = '9999'; + exportOverlay.style.background = 'rgba(255, 255, 255, 0.95)'; + exportOverlay.style.padding = '15px'; + exportOverlay.style.border = '2px solid #333'; + exportOverlay.style.borderRadius = '5px'; + exportOverlay.style.color = '#333'; + exportOverlay.style.fontFamily = 'Arial, sans-serif'; + exportOverlay.style.boxShadow = '0 0 10px rgba(0,0,0,0.3)'; + + const projName = document.getElementById('projectSelector')?.options[document.getElementById('projectSelector')?.selectedIndex]?.text || 'Unbekannt'; + + exportOverlay.innerHTML = \` +