handleiding_nieuw:sub_spacematrix
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
handleiding_nieuw:sub_spacematrix [2025/05/07 08:46] – support | handleiding_nieuw:sub_spacematrix [2025/05/19 10:26] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 2: | Line 2: | ||
<html lang=" | <html lang=" | ||
< | < | ||
+ | <script src=" | ||
+ | <script src=" | ||
+ | <script src=" | ||
<meta charset=" | <meta charset=" | ||
- | < | + | < |
< | < | ||
body { font-family: | body { font-family: | ||
- | .tabs { display: flex; border-bottom: 2px solid #ccc; margin-bottom: | + | .tabs { display: flex; gap: 10px; margin-bottom: |
- | .tab { padding: 10px 20px; cursor: pointer; border: 1px solid #ccc; border-bottom: | + | .tab { padding: 10px 15px; background: #ddd; cursor: pointer; border-radius: |
- | .tab.active { background: | + | .tab.active { background: |
- | .tabcontent { display: none; border: 1px solid #ccc; padding: | + | .tabcontent { display: none; border: 1px solid #ccc; padding: |
.tabcontent.active { display: block; } | .tabcontent.active { display: block; } | ||
.inputrow { display: flex; align-items: | .inputrow { display: flex; align-items: | ||
- | .inputrow label { width: | + | .inputrow label { width: |
.inputrow input { width: 80px; } | .inputrow input { width: 80px; } | ||
- | table.rekenblok | + | table { border-collapse: |
- | | + | th, td { border: 1px solid #ccc; padding: |
- | | + | th { background: #f0f0f0; } |
- | | + | td:first-child, th:first-child { text-align: |
- | .resultblock { margin-left: 40px; min-width: 200px; | + | .kaartcontainer { position: relative; |
- | .kaartcontainer { position: relative; width: | + | |
.kaartcontainer img { width: 100%; display: block; } | .kaartcontainer img { width: 100%; display: block; } | ||
.stipje { position: absolute; width: 14px; height: 14px; background: red; border-radius: | .stipje { position: absolute; width: 14px; height: 14px; background: red; border-radius: | ||
</ | </ | ||
<script src=" | <script src=" | ||
- | < | ||
- | function switchTab(tabId) { | ||
- | document.querySelectorAll(" | ||
- | document.querySelectorAll(" | ||
- | document.getElementById(tabId).classList.add(" | ||
- | document.querySelector(`.tab[onclick*=' | ||
- | } | ||
- | </ | ||
</ | </ | ||
< | < | ||
- | < | + | < |
<div class=" | <div class=" | ||
- | <div class=" | + | <div class=" |
<div class=" | <div class=" | ||
<div class=" | <div class=" | ||
- | <div class=" | + | <div class=" |
</ | </ | ||
- | <div id="spacematrix" class=" | + | <div id="rekenblok" class=" |
- | <h2>Spacematrix</h2> | + | <div class=" |
- | <div class=" | + | <div class=" |
- | <img src=" | + | <div class=" |
- | <div class=" | + | <label for=" |
+ | < | ||
+ | </ | ||
+ | | ||
+ | <label for=" | ||
+ | <input id=" | ||
+ | </ | ||
+ | <div class=" | ||
+ | <label for=" | ||
+ | <input id=" | ||
+ | </ | ||
+ | <div class=" | ||
+ | < | ||
+ | <span id=" | ||
+ | <input type=" | ||
+ | </div> | ||
+ | | ||
+ | <div class=" | ||
+ | | ||
+ | <div class=" | ||
+ | | ||
</ | </ | ||
- | | + | |
- | <label for="opp">Oppervlak projectgebied (m²):</label> | + | |
- | <input id="opp" | + | <table> |
- | <div class="resultblock" id="lv1"></ | + | < |
+ | < | ||
+ | </ | ||
+ | <tbody id="woningtypes"></ | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <div style=" | ||
+ | < | ||
+ | Dit komt doordat het aantal woningen iteratief wordt bepaald op basis van de beschikbare ruimte, inclusief ruimte voor voorzieningen en parkeren. | ||
+ | Bij het toepassen van voorzieningen wordt eerst een schatting gemaakt op basis van een voorlopig aantal woningen. Daarna wordt het aantal woningen opnieuw berekend met de benodigde ruimte per woning. | ||
+ | Hierdoor ontstaat een klein verschil tussen het oorspronkelijk berekende totaal en de daadwerkelijk ingepaste voorzieningenruimte. | ||
+ | </ | ||
+ | |||
+ | <div id="output"></ | ||
+ | <div id="summary"> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <tr>< | ||
+ | |||
+ | < | ||
+ | <td colspan=" | ||
+ | Kengetallen | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | | ||
</ | </ | ||
+ | | ||
+ | <div style=" | ||
+ | <button onclick=" | ||
+ | 📄 Kickstart Dump downloaden | ||
+ | </ | ||
+ | </ | ||
+ | | ||
+ | </ | ||
+ | |||
+ | <div id=" | ||
<div class=" | <div class=" | ||
- | < | + | < |
- | <input id="fsi" type=" | + | <input id="bewoners_per_woning" type=" |
- | <div class=" | + | |
</ | </ | ||
- | | + | < |
- | <label for=" | + | |
- | <input id=" | + | |
- | <div class=" | + | |
- | </ | + | |
- | <div class=" | + | |
- | <label for=" | + | |
- | <input id=" | + | |
- | <div class=" | + | |
- | </ | + | |
- | + | ||
- | | + | |
< | < | ||
- | <tr> | + | < |
- | | + | |
- | < | + | |
- | | + | |
- | < | + | |
- | | + | |
- | | + | |
</ | </ | ||
- | <tbody id="woningtypes"></ | + | <tbody id="voorzieningentabel"></ |
- | < | + | |
- | <tr class=" | + | |
- | < | + | |
- | <td id=" | + | |
- | <td id=" | + | |
- | <td id=" | + | |
- | <td id=" | + | |
- | </ | + | |
- | </tfoot> | + | |
</ | </ | ||
+ | <div class=" | ||
+ | <button id=" | ||
+ | <div id=" | ||
+ | </ | ||
+ | < | ||
+ | <table id=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | <tbody id=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
- | < | ||
- | <div id=" | ||
- | </ | ||
- | < | + | <div style=" |
- | < | + | <strong>Toelichting:</strong> het weergegeven totaal van de voorzieningenruimte is gebaseerd op een schatting op basis van het huidige aantal woningen. |
- | < | + | Nadat dit oppervlak per woning is berekend, wordt het aantal woningen in het rekenblok opnieuw doorgerekend. Hierdoor kan het werkelijke totaal afwijken. |
- | <input id=" | + | Deze iteratieve aanpak is nodig omdat de benodigde ruimte per woning invloed heeft op hoeveel woningen uiteindelijk in het plan passen. |
- | </ | + | </ |
- | <div id=" | + | |
- | <div id=" | + | |
- | <div style=" | + | |
</ | </ | ||
<div id=" | <div id=" | ||
- | <h2> | + | <h3> |
<div class=" | <div class=" | ||
- | < | + | < |
- | <input id=" | + | <input id=" |
</ | </ | ||
<div class=" | <div class=" | ||
- | < | + | < |
- | <input id="m2_per_pp" type=" | + | <input id="bvo_per_pp" type=" |
</ | </ | ||
<div class=" | <div class=" | ||
- | < | + | < |
- | <input id="perc_bovengronds" type=" | + | <input id="pp_ondergronds" type=" |
</ | </ | ||
- | <div style=" | ||
- | </ | ||
- | |||
- | <div id=" | ||
- | < | ||
- | < | ||
<div class=" | <div class=" | ||
- | < | + | < |
- | <input id="pct_groen" type=" | + | <input id="pp_bovengronds" type=" |
</ | </ | ||
<div class=" | <div class=" | ||
- | <label for=" | + | <button |
- | < | + | <div id="parkeer_resultaat" style=" |
- | | + | |
- | < | + | |
- | <label for=" | + | |
- | < | + | |
- | </ | + | |
- | < | + | |
- | < | + | |
- | - Groen: <span id=" | + | |
- | - Water: <span id=" | + | |
- | - Verharding: <span id=" | + | |
</ | </ | ||
- | <canvas id="ruimteTaart" width=" | + | |
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <div id=" | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <select id=" | ||
+ | <option value=" | ||
+ | <option value=" | ||
+ | <option value=" | ||
+ | <option value=" | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | <p style=" | ||
+ | <div id=" | ||
+ | | ||
</ | </ | ||
< | < | ||
+ | const types = ["egw sociaal", | ||
+ | const voorzieningen = [ | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | { naam: " | ||
+ | ]; | ||
+ | |||
+ | function switchTab(tabId) { | ||
+ | document.querySelectorAll(' | ||
+ | document.querySelectorAll(' | ||
+ | document.querySelector(`.tab[onclick*=" | ||
+ | document.getElementById(tabId).classList.add(' | ||
+ | } | ||
+ | |||
+ | function renderWoningtypes() { | ||
+ | const tbody = document.getElementById(" | ||
+ | tbody.innerHTML = ""; | ||
+ | types.forEach((type, | ||
+ | const row = document.createElement(" | ||
+ | row.innerHTML = ` | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <td id=" | ||
+ | <td id=" | ||
+ | `; | ||
+ | tbody.appendChild(row); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function updateStipje(fsi, | ||
+ | const stip = document.getElementById(" | ||
+ | const x = Math.min(100, | ||
+ | const y = Math.max(0, Math.min(100, | ||
+ | stip.style.left = `${x}%`; | ||
+ | stip.style.top = `${y}%`; | ||
+ | } | ||
+ | |||
+ | function updateSummary(bvoTot, | ||
+ | const pp = parseFloat(document.getElementById(" | ||
+ | const pp_bvo = parseFloat(document.getElementById(" | ||
+ | const pp_bovengronds = parseFloat(document.getElementById(" | ||
+ | const parkerenruimtePerWoning = pp * pp_bvo * (pp_bovengronds / 100); | ||
+ | const parkerenTot = woningen * parkerenruimtePerWoning; | ||
+ | |||
+ | const wonenBVO = bvoTot - voorzTot - parkerenTot; | ||
+ | const parkeerplaatsenTotaal = woningen * pp; | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | } | ||
+ | |||
+ | function updateLaadvermogen() { | ||
+ | const opp = parseFloat(document.getElementById(" | ||
+ | const fsi = parseFloat(document.getElementById(" | ||
+ | const gsi = parseFloat(document.getElementById(" | ||
+ | const bvoTot = opp * fsi; | ||
+ | const voorzieningenruimte = parseFloat(document.getElementById(" | ||
+ | |||
+ | // Nieuw: parkeerinput ophalen | ||
+ | const pp = parseFloat(document.getElementById(" | ||
+ | const pp_bvo = parseFloat(document.getElementById(" | ||
+ | const pp_bovengronds = parseFloat(document.getElementById(" | ||
+ | const parkerenruimte = pp * pp_bvo * (pp_bovengronds / 100); | ||
+ | |||
+ | updateStipje(fsi, | ||
+ | |||
+ | let gewogenBVO = 0; | ||
+ | let totalPerc = 0; | ||
+ | const details = []; | ||
+ | for (let i = 0; i < types.length; | ||
+ | const perc = parseFloat(document.getElementById(`perc_${i}`).value) || 0; | ||
+ | const bvo = parseFloat(document.getElementById(`bvo_${i}`).value) || 0; | ||
+ | gewogenBVO += (perc / 100) * bvo; | ||
+ | totalPerc += perc; | ||
+ | details.push({ i, perc, bvo }); | ||
+ | } | ||
+ | if (gewogenBVO === 0) return; | ||
+ | |||
+ | // Nieuwe berekening met voorzieningen én parkeren | ||
+ | let woningen = Math.floor(bvoTot / (gewogenBVO + voorzieningenruimte + parkerenruimte)); | ||
+ | let sumWon = 0; | ||
+ | let sumBVO = 0; | ||
+ | let wonPerType = []; | ||
+ | let restant = woningen; | ||
+ | |||
+ | for (let i = 0; i < details.length; | ||
+ | const { perc } = details[i]; | ||
+ | let aant = (perc / 100) * woningen; | ||
+ | let afgerond = Math.floor(aant); | ||
+ | wonPerType.push(afgerond); | ||
+ | restant -= afgerond; | ||
+ | } | ||
+ | const decimaalSort = details.map((d, | ||
+ | .sort((a, b) => b.rest - a.rest); | ||
+ | for (let j = 0; j < restant; j++) { | ||
+ | wonPerType[decimaalSort[j].i]++; | ||
+ | } | ||
+ | |||
+ | for (let i = 0; i < details.length; | ||
+ | const aant = wonPerType[i]; | ||
+ | const bvoTot = aant * details[i].bvo; | ||
+ | document.getElementById(`aantal_${i}`).innerText = aant; | ||
+ | document.getElementById(`totbvo_${i}`).innerText = bvoTot.toFixed(0); | ||
+ | sumWon += aant; | ||
+ | sumBVO += bvoTot; | ||
+ | } | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | |||
+ | document.getElementById(" | ||
+ | `< | ||
+ | |||
+ | const voorzieningenTot = sumWon * voorzieningenruimte; | ||
+ | const wonenRuimte = bvoTot - voorzieningenTot - (sumWon * parkerenruimte); | ||
+ | updateSummary(bvoTot, | ||
+ | |||
+ | // Extra update voor parkeren per woning | ||
+ | document.getElementById(" | ||
+ | } | ||
+ | |||
+ | function maakVoorzieningentabel() { | ||
+ | const tbody = document.getElementById(" | ||
+ | voorzieningen.forEach((v, | ||
+ | const row = document.createElement(" | ||
+ | row.innerHTML = ` | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | `; | ||
+ | tbody.appendChild(row); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | function berekenVoorzieningenruimte() { | ||
+ | updateLaadvermogen(); | ||
+ | |||
+ | const bewonersPerWoning = parseFloat(document.getElementById(" | ||
+ | const woningen = parseFloat(document.getElementById(" | ||
+ | const totaalBewoners = woningen * bewonersPerWoning; | ||
+ | |||
+ | const resultDiv = document.getElementById(" | ||
+ | const btn = document.getElementById(" | ||
+ | |||
+ | if (woningen === 0) { | ||
+ | resultDiv.innerHTML = `<span style=" | ||
+ | btn.style.border = "1px solid #a00"; | ||
+ | btn.style.background = "# | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | let totaal_m2 = 0; | ||
+ | voorzieningen.forEach((v, | ||
+ | const checked = document.getElementById(`vchk_${i}`).checked; | ||
+ | if (checked) { | ||
+ | totaal_m2 += v.norm * totaalBewoners / 1000; | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | const m2_per_woning = totaal_m2 / woningen; | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | |||
+ | resultDiv.innerHTML = `<span style=" | ||
+ | btn.style.border = "1px solid #0a0"; | ||
+ | btn.style.background = "# | ||
+ | |||
+ | updateLaadvermogen(); | ||
+ | |||
+ | // Toon tabel met voorzieningen en m2 | ||
+ | const summaryBody = document.getElementById(" | ||
+ | const summaryTotal = document.getElementById(" | ||
+ | summaryBody.innerHTML = ""; | ||
+ | let subtotal = 0; | ||
+ | |||
+ | voorzieningen.forEach((v, | ||
+ | const checked = document.getElementById(`vchk_${i}`).checked; | ||
+ | if (checked) { | ||
+ | const v_m2 = v.norm * totaalBewoners / 1000; | ||
+ | subtotal += v_m2; | ||
+ | const row = document.createElement(" | ||
+ | row.innerHTML = `< | ||
+ | summaryBody.appendChild(row); | ||
+ | } | ||
+ | }); | ||
+ | summaryTotal.innerText = `${subtotal.toFixed(1)} m²`; | ||
+ | |||
+ | } | ||
+ | |||
+ | function berekenParkeerruimte() { | ||
+ | const pp = parseFloat(document.getElementById(" | ||
+ | const bvo_per_pp = parseFloat(document.getElementById(" | ||
+ | const bovengronds = parseFloat(document.getElementById(" | ||
+ | const woningen = parseFloat(document.getElementById(" | ||
+ | |||
+ | const ruimte_per_woning = pp * bvo_per_pp * (bovengronds / 100); | ||
+ | const totaal_ruimte = ruimte_per_woning * woningen; | ||
+ | |||
+ | // Toon het resultaat en vinkje | ||
+ | const resultDiv = document.getElementById(" | ||
+ | resultDiv.innerHTML = `<span style=" | ||
+ | |||
+ | // Visuele feedback op de knop | ||
+ | const btn = document.getElementById(" | ||
+ | btn.style.border = "1px solid #0a0"; | ||
+ | btn.style.background = "# | ||
+ | |||
+ | // Update berekening | ||
+ | updateLaadvermogen(); | ||
+ | |||
+ | const totaal_pp = woningen * pp; | ||
+ | const pp_boven_aantal = totaal_pp * (bovengronds / 100); | ||
+ | const ondergronds = parseFloat(document.getElementById(" | ||
+ | const pp_onder_aantal = totaal_pp * (ondergronds / 100); | ||
+ | |||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | document.getElementById(" | ||
+ | |||
+ | } | ||
+ | |||
+ | function updateOpenbareRuimte() { | ||
+ | const opp = parseFloat(document.getElementById(" | ||
+ | const gsi = parseFloat(document.getElementById(" | ||
+ | const bebouwd = opp * gsi; | ||
+ | const onbebouwd = opp - bebouwd; | ||
+ | |||
const types = [ | const types = [ | ||
- | "egw sociaal", "egw goedkoop", "egw midden", "egw duur", "egw top", | + | |
- | "mgw sociaal", "mgw goedkoop", "mgw midden", "mgw duur", "mgw top" | + | { id: "water", |
+ | { id: "tuinen", label: " | ||
+ | | ||
+ | { id: "trottoirs", | ||
+ | { id: " | ||
+ | { id: "pleinen", | ||
]; | ]; | ||
- | const voorzieningenData | + | |
- | | + | types.forEach(type => { |
- | | + | |
- | | + | |
- | | + | }); |
- | | + | |
- | | + | if (totaal !== 100) { |
- | | + | document.getElementById("warning_openbareruimte").innerText = `⚠️ Totaal is ${totaal}%. Dit moet 100% zijn.`; |
- | | + | |
- | | + | } else { |
- | | + | document.getElementById("warning_openbareruimte").innerText = "" |
+ | } | ||
+ | |||
+ | types.forEach(type => { | ||
+ | | ||
+ | const m2 = (perc / 100) * onbebouwd; | ||
+ | document.getElementById(`m2_${type.id}`).innerText = `${m2.toFixed(0)} m²`; | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | let openbareRuimteChart = null; | ||
+ | |||
+ | function updateOpenbareRuimte() { | ||
+ | const opp = parseFloat(document.getElementById("opp").value); | ||
+ | const gsi = parseFloat(document.getElementById("gsi").value); | ||
+ | const bebouwd = opp * gsi; | ||
+ | const onbebouwd = opp - bebouwd; | ||
+ | |||
+ | const types = [ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
]; | ]; | ||
- | | + | |
- | | + | let data = []; |
+ | |||
+ | types.forEach(type => { | ||
+ | const perc = parseFloat(document.getElementById(`perc_${type.id}`).value) || 0; | ||
+ | totaal += perc; | ||
+ | }); | ||
+ | |||
+ | if (totaal !== 100) { | ||
+ | | ||
+ | document.getElementById(" | ||
+ | return; | ||
+ | } else { | ||
+ | document.getElementById(" | ||
} | } | ||
- | | + | |
- | const stip = document.getElementById(" | + | types.forEach(type => { |
- | const x = Math.min(100, Math.max(0, gsi * 190)); | + | const perc = parseFloat(document.getElementById(`perc_${type.id}`).value) || 0; |
- | const y = Math.max(0, Math.min(100, (3 - fsi) * 35)); | + | const m2 = (perc / 100) * onbebouwd; |
- | stip.style.left = `${x}%`; | + | document.getElementById(`m2_${type.id}`).innerText = `${m2.toFixed(0)} m²`; |
- | | + | data.push({ label: type.label, value: m2 }); |
+ | }); | ||
+ | |||
+ | // Totaal m² | ||
+ | | ||
+ | | ||
+ | |||
+ | // Vergelijking met onbebouwd oppervlak | ||
+ | const verschil = Math.abs(totaal_m2 - onbebouwd); | ||
+ | const totaalCell = document.getElementById(" | ||
+ | if (verschil > 1) { | ||
+ | | ||
+ | totaalCell.title | ||
+ | } else { | ||
+ | totaalCell.style.color = ""; | ||
+ | totaalCell.title = "" | ||
} | } | ||
- | | + | |
- | const tbody = document.getElementById(" | + | const ctx = document.getElementById(" |
- | types.forEach((type, i) => { | + | const labels = data.map(d => d.label); |
- | const row = document.createElement(" | + | const values |
- | if (i === 5) row.className | + | |
- | row.innerHTML | + | |
- | < | + | openbareRuimteChart.data.labels |
- | | + | |
- | | + | |
- | < | + | } else { |
- | | + | openbareRuimteChart = new Chart(ctx, { |
- | | + | |
- | tbody.appendChild(row); | + | data: { |
+ | | ||
+ | datasets: [{ | ||
+ | data: values, | ||
+ | backgroundColor: | ||
+ | '# | ||
+ | '# | ||
+ | ] | ||
+ | | ||
+ | }, | ||
+ | options: { | ||
+ | | ||
+ | legend: { position: ' | ||
+ | title: | ||
+ | display: true, | ||
+ | text: ' | ||
+ | } | ||
+ | } | ||
+ | | ||
}); | }); | ||
} | } | ||
+ | } | ||
- | | + | |
- | const lijst = document.getElementById(" | + | function |
- | | + | const type = document.getElementById(" |
- | < | + | let waarden |
- | | + | |
+ | if (type === " | ||
+ | waarden | ||
+ | } else if (type === "gemengd") { | ||
+ | waarden | ||
+ | } else if (type === "suburbaan" | ||
+ | waarden = { groen: 30, water: 15, tuinen: 25, rijbanen: 15, trottoirs: 8, parkeren: 5, pleinen: 2 }; | ||
+ | } else { | ||
+ | | ||
+ | return; | ||
} | } | ||
- | | + | |
- | const opp = parseFloat(document.getElementById(" | + | document.getElementById(`perc_${id}`).value = waarden[id]; |
- | | + | }); |
- | const gsi = parseFloat(document.getElementById(" | + | |
- | const voorzieningPerc = parseFloat(document.getElementById(" | + | |
- | const laadvermogen = Math.round(opp * fsi); | + | updateOpenbareRuimte(); |
- | const bvoVoorzieningen = Math.round(laadvermogen * voorzieningPerc); | + | } |
- | const bvoWonen = laadvermogen - bvoVoorzieningen; | + | |
- | document.getElementById(" | + | // 👇 Bouw de volledige woningtype + parkeren-tabel met eerste kolom labels, geschikt voor Kladblok |
- | | + | function buildWoningtypesTableTXT() { |
- | | + | const types = ["egw sociaal", "egw goedkoop", |
- | | + | " |
+ | const parkeerkolommen = [" | ||
+ | const kolommen = [...types, ...parkeerkolommen]; | ||
+ | const colWidth | ||
+ | const labelWidth = 18; | ||
- | updateStipje(fsi, gsi); | + | const pad = (val) => val.toString().padStart(colWidth); |
- | | + | const head = (val) => val.toString().padEnd(colWidth); |
- | } | + | |
- | | + | |
- | const laadvermogen | + | const perc = types.map((_, i) => document.getElementById(`perc_${i}`)?.value || " |
- | const woonBVO | + | const bvo = types.map((_, |
+ | const aantallen = types.map((_, | ||
+ | const vormfactor = types.map((_, | ||
+ | const bvo_tot = bvo.map((b, i) => b * aantallen[i]); | ||
+ | const gbo = bvo.map((b, i) => (b * vormfactor[i]).toFixed(1)); | ||
- | let gewogenBVO | + | // PARKEERREGELS berekenen |
- | let totalPerc | + | const pp = parseFloat(document.getElementById(" |
- | const details | + | const woningen |
+ | const bvo_pp = parseFloat(document.getElementById(" | ||
+ | const perc_boven = parseFloat(document.getElementById(" | ||
+ | const perc_onder = parseFloat(document.getElementById(" | ||
+ | const pp_boven = Math.round(woningen * pp * (perc_boven / 100)); | ||
+ | const pp_onder = Math.round(woningen * pp * (perc_onder / 100)); | ||
+ | const bvo_boven = pp_boven * bvo_pp; | ||
+ | const bvo_onder | ||
- | for (let i = 0; i < types.length; | + | // PARKEERGEGEVENS toevoegen |
- | | + | perc.push(" |
- | | + | bvo.push(bvo_pp, bvo_pp); |
- | | + | aantallen.push(pp_boven, |
- | | + | |
- | | + | |
- | } | + | gbo.push((bvo_pp * 1.00).toFixed(1), (bvo_pp * 1.00).toFixed(1)); |
- | if (gewogenBVO | + | // TABEL opbouwen |
+ | const r = []; | ||
+ | r.push(label(" | ||
+ | r.push("" | ||
+ | r.push(label(" | ||
+ | r.push(label(" | ||
+ | r.push(label(" | ||
+ | r.push(label(" | ||
+ | r.push(label(" | ||
+ | r.push(label(" | ||
- | | + | // GEMIDDELDES (alleen woningtypes, |
- | let sumWon | + | |
- | let sumBVO | + | const totale_bvo |
- | let wonPerType | + | const totale_gbo |
+ | const totaal_woningen | ||
- | let restant | + | const gemiddelde_bvo |
- | for (let i = 0; i < details.length; | + | const gemiddelde_gbo |
- | const { perc } = details[i]; | + | |
- | let aant = (perc / 100) * totaalWoningenExact; | + | |
- | let afgerond = Math.floor(aant); | + | |
- | wonPerType.push(afgerond); | + | |
- | restant -= afgerond; | + | |
- | } | + | |
- | const decimaalSort = details.map((d, i) => ({ | + | r.push("" |
- | i, rest: ((d.perc / 100) * totaalWoningenExact) % 1 | + | r.push(`Totale aantal woningen: ${totaal_woningen}`); |
- | | + | r.push(`Gemiddelde BVO per woning: ${gemiddelde_bvo}`); |
+ | r.push(`Gemiddelde GBO per woning: ${gemiddelde_gbo}`); | ||
- | for (let j = 0; j < restant; j++) { | + | return r.join(" |
- | wonPerType[decimaalSort[j].i]++; | + | } |
- | } | + | |
- | for (let i = 0; i < details.length; | + | async function downloadKickstartDump() { |
- | const aant = wonPerType[i]; | + | |
- | const bvoTot = aant * details[i].bvo; | + | |
- | document.getElementById(`aantal_${i}`).innerText = formatGetal(aant); | + | |
- | document.getElementById(`totbvo_${i}`).innerText = formatGetal(bvoTot); | + | |
- | sumWon += aant; | + | |
- | sumBVO += bvoTot; | + | |
- | } | + | |
- | document.getElementById(" | + | try { |
- | | + | const response = await fetch(' |
- | document.getElementById(" | + | |
- | document.getElementById(" | + | |
- | let waarschuwing | + | let template |
- | | + | |
- | | + | |
+ | const bvo_per_pp = parseFloat(document.getElementById(" | ||
+ | const pp_bovengronds = parseFloat(document.getElementById(" | ||
+ | const pp_ondergronds = parseFloat(document.getElementById(" | ||
+ | const woningen = parseFloat(document.getElementById(" | ||
+ | const pp = parseFloat(document.getElementById(" | ||
+ | |||
+ | const bvo_per_pp_boven = bvo_per_pp.toFixed(1); | ||
+ | const bvo_per_pp_onder = bvo_per_pp.toFixed(1); | ||
+ | |||
+ | const parkeeropp_totaal = woningen * pp * bvo_per_pp; | ||
+ | const parkeeropp_boven = parkeeropp_totaal * (pp_bovengronds / 100); | ||
+ | const parkeeropp_onder = parkeeropp_totaal * (pp_ondergronds / 100); | ||
+ | |||
+ | const data = { | ||
+ | | ||
+ | aantal_woningen: | ||
+ | bvo_per_woning: | ||
+ | pp_boven: document.getElementById(" | ||
+ | pp_onder: document.getElementById(" | ||
+ | bvo_boven: document.getElementById(" | ||
+ | bvo_onder: " | ||
+ | bvo_per_pp_boven: | ||
+ | bvo_per_pp_onder: | ||
+ | totbvo_boven: | ||
+ | totbvo_onder: | ||
+ | woningtypes_table: | ||
+ | voorzieningen_table: | ||
+ | plankaart_table: | ||
+ | grex_table: buildGrexTableTXT() | ||
+ | }; | ||
+ | |||
+ | for (let i = 0; i < 10; i++) { | ||
+ | data[`perc_${i}`] | ||
+ | data[`bvo_${i}`] = document.getElementById(`bvo_${i}`)? | ||
+ | data[`aantal_${i}`] = document.getElementById(`aantal_${i}`)?.innerText || " | ||
+ | data[`totbvo_${i}`] = document.getElementById(`totbvo_${i}`)? | ||
} | } | ||
- | | + | |
- | ${waarschuwing} | + | |
- | | + | }); |
- | < | + | |
- | | + | |
- | } | + | |
- | function init() { | + | const blob = new Blob([template], |
- | | + | |
- | | + | |
- | | + | } catch (error) { |
+ | console.error("❌ Fout bij genereren:", | ||
+ | | ||
} | } | ||
+ | } | ||
- | | + | function buildVoorzieningenTableTXT() { |
+ | let output = ""; | ||
+ | const rows = document.querySelectorAll("# | ||
+ | rows.forEach(row => { | ||
+ | const cells = row.querySelectorAll(" | ||
+ | if (cells.length === 2) { | ||
+ | const naam = cells[0].innerText.trim(); | ||
+ | const m2 = cells[1].innerText.trim(); | ||
+ | output += `| ${naam.padEnd(25)} | ${m2.padStart(14)} |\n`; | ||
+ | } | ||
+ | }); | ||
+ | return output || "| Geen voorzieningen geselecteerd | – |"; | ||
+ | } | ||
+ | |||
+ | function buildPlankaartTableTXT() { | ||
+ | const opp = parseFloat(document.getElementById(" | ||
+ | const gsi = parseFloat(document.getElementById(" | ||
+ | const footprint = gsi * opp; | ||
+ | const tuin = getVal(" | ||
+ | const uitgeefbaar = tuin + footprint; | ||
+ | |||
+ | return `Omschrijving | ||
+ | ----------------------------|---------------- | ||
+ | Totaal bruto plangebied | ||
+ | ----------------------------|---------------- | ||
+ | Tuinen | ||
+ | Footprint (GSI x opp) | ${footprint.toFixed(0)} | ||
+ | ----------------------------|---------------- | ||
+ | Totaal uitgeefbaar | ||
+ | Rijbanen | ||
+ | Trottoirs | ||
+ | Parkeren (bovengr.) | ||
+ | Pleinen | ||
+ | ----------------------------|---------------- | ||
+ | Totaal verharding | ||
+ | Groen | ${getVal(" | ||
+ | Water | ${getVal(" | ||
+ | } | ||
+ | |||
+ | function buildGrexTableTXT() { | ||
+ | return `Categorie | ||
+ | --------------------|----------------------------------------|---------------- | ||
+ | Verwerving | ||
+ | Grondwerk | ||
+ | Bouwrijp maken | Bouwstraten | ||
+ | Woonrijp maken | Rijbanen | ||
+ | Woonrijp maken | Trottoirs | ||
+ | Woonrijp maken | Parkeren | ||
+ | Woonrijp maken | Pleinen | ||
+ | Woonrijp maken | Groen | ${getVal(" | ||
+ | Woonrijp maken | Bomen en groenstructuur | ||
+ | Woonrijp maken | Verdere aankleding openbare ruimte | ||
+ | Nazorg | ||
+ | Onvoorzien | ||
+ | } | ||
+ | |||
+ | function getVal(id) { | ||
+ | const el = document.getElementById(id); | ||
+ | return el ? parseFloat(el.innerText.replace(" | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | window.onload = () => { | ||
+ | renderWoningtypes(); | ||
+ | maakVoorzieningentabel(); | ||
+ | updateLaadvermogen(); | ||
+ | }; | ||
</ | </ | ||
+ | |||
</ | </ | ||
</ | </ | ||
- |
handleiding_nieuw/sub_spacematrix.1746607569.txt.gz · Last modified: 2025/05/07 08:46 by support