index.html 16.96 KiB
<html>
    <head>
        <title>ENsource Disaggregation Report</title>
        <meta charset="UTF-8">
        <!-- Include the CesiumJS JavaScript and CSS files -->
        <script src="https://cesium.com/downloads/cesiumjs/releases/1.78/Build/Cesium/Cesium.js"></script>
        <link href="https://cesium.com/downloads/cesiumjs/releases/1.78/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
        <!-- Terraformer and WKT Parser -->
        <script src="https://unpkg.com/terraformer@1.0.7/terraformer.js"></script>
        <script src="https://unpkg.com/terraformer-wkt-parser@1.1.2/terraformer-wkt-parser.js"></script>
        <!-- proj4js -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.7.2/proj4.min.js" integrity="sha512-dNFx8aqYHHdVRrTfm7fzMSakZd+cD8Bf24ZqvAIh799ORCeyVdzN1w4wiqLtLON7VPkZ1vQmMi+CJRF/b3v/7A==" crossorigin="anonymous"></script>
        <style>
            h1 {
                text-align: center;
                color: #002C55;
            h2 {
                text-align: left;
                font-size: 25px;
                font-weight: "bold";
                color: #002C55;
            h1 span {
                color: #549925;
            table {
                border-collapse: collapse;
                border: 1px solid #DFDCDC;
                border-spacing: 0;
            th {
                background-color: #549925;
                color: white;
                text-align: left;
                padding: 8px;
            td {
                text-align: left;
                padding: 8px;
            tr:nth-child(even) {
                background-color: #e7f4d9;
            table th,
            table td {
                border-top: 1px #efe9e3;
                border-right: 0px #efe9e3;
                border-bottom: 0px #efe9e3;
                border-left: 1px #efe9e3;
            .button {
                float: left;
                padding: 6px 9px;
                cursor: pointer;
                margin-top: 20px;
                margin-left: 15px;
                border-radius: 5px;
                background-color: #549925;
                font-size: 12px;
                font-weight: bold;
                color: #fff;
                width: 30px;
.collapsible { background-color: #549925; color: #002C55; cursor: pointer; padding: 18px; width: 100%; border: none; text-align: left; outline: none; font-size: 25px; font-weight: bold; } .active, .collapsible:hover { background-color: #BAD6A7; } .collapsible:after { content: '\002B'; /* Unicode character for "plus" sign (+) */ color: #002C55; font-weight: bold; float: right; margin-left: 5px; } .active:after { content: "\2212"; /* Unicode character for "minus" sign (-) */ } .content { padding: 0 18px; display: none; overflow: hidden; } </style> </head> <body> <h1><span>EN</span>source Disaggregation Report</h1> <h2 style="float:left; width: 100%;">Run Results</h2> <form action = "http://127.0.0.1:5000//ensource2/" method = "POST" enctype = "multipart/form-data"> <input type=file name=file required> <input type=submit value=Run> </form> <table style="float:left; width: 49%; margin-right: 10;"> <tr> <th>Target Demand (kWh)</th> <td id="target-demand">N/A</td> </tr> <tr> <th>Results Files</th> <td id="file-name"><a id="jsonResult" href=#></a> | <a id="csvResult" href=#></a></td> </tr> <tr> <th>Segments File</th> <td id="segments-file-name">N/A</td> </tr> <tr> <th>Available Segments</th> <td id="available-segments">N/A</td> </tr> <tr> <th>Grid provided</th> <td id="grid-provided">N/A</td> </tr> </table> <table style="float:left;width: 49%;">
<tr> <th>Accumulated demand (kWh)</th> <td id="accumulated-demand">N/A</td> </tr> <tr> <th>Investment cost (EUR)</th> <td id="investment-cost">N/A</td> </tr> <tr> <th>Total grid length (m)</th> <td id="total-length">N/A</td> </tr> <tr> <th>Used segments</th> <td id="used-segments">N/A</td> </tr> <tr> <th>Grid provided IDs</th> <td id="grid-provided-ids">{{ givenGridIds }}</td> </tr> </table> <button type="button" class="collapsible">Calculated Grid</button> <div class="content"> <table id="result-table" border=1 style="width: 99%;"> <tr> <th> Segment ID </th> <th> Demand (kWh)</th> <th> Length (m)</th> <th> Acc. Demand (kWh)</th> <th> Acc. Length (m)</th> <th> Acc. Grid Cost (EUR)</th> </table> </div> <button type="button" class="collapsible">Grid Visualization</button> <!-- span>+</span --> <div class="content"> <div id="toolbar" style="position: absolute; padding: 25px; z-index: 1;"> <!-- select id="myColor" onchange="doStyling()"> <option value="1">Show/hide grids</option> <option value="2">Color grids by segment demand (kWh)</option> <option value="0">Show/hide buildings</option> </select --> </div> <div id="cesiumContainer"></div> </div> <script> //var myViewer var myWholeGrid var myGrid // collapsible var coll = document.getElementsByClassName("collapsible") var i for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { this.classList.toggle("active") var content = this.nextElementSibling if (content.style.display === "block") { content.style.display = "none" } else { content.style.display = "block" } }) } /* function doStyling() { let id = document.getElementById("myColor").value if (id == 0) {
// show/hide buildings } else if(id == 1) { // show/hide grids } else if(id == 2) { for (var segment in myGrid.segments) { let linesReprojected = myGrid.segments[segment].geometryReprojected for (let i = 0; i < (linesReprojected.length-1); i++) { myViewer.entities.add({ polyline: { positions: Cesium.Cartesian3.fromDegreesArray([linesReprojected[i][0], linesReprojected[i][1], linesReprojected[i+1][0], linesReprojected[i+1][1]]), width: 5, material: Cesium.Color.GREEN, clampToGround: true, } }); } } } } */ function gridCost(total_demand_kWh, total_length_m, a, c1, c2){ const q_s = (total_demand_kWh/(10**6))*3600; const d_a = 0.0486 * Math.log(q_s / total_length_m) + 0.0007; grid_investment_cost_EUR = a*(c1 + c2 * d_a) * total_length_m; return grid_investment_cost_EUR; } function displayTable(grid) { const table = document.getElementById('result-table'); table.children = null; //element.texContent = JSON.stringify(result); const tblBody = document.createElement("tbody"); let accDemand = 0; let accLength = 0; // creating all cells const target = document.getElementById('target-demand'); target.textContent = grid.targetDemand; const segmentsFile = document.getElementById('segments-file-name'); segmentsFile.textContent = grid.segmentsFile; const availSegments = document.getElementById('available-segments'); availSegments.textContent = grid.availableSegmentsCount; const gridProvided = document.getElementById('grid-provided'); gridProvided.textContent = grid.givenGridStr; const accumulatedDemand = document.getElementById('accumulated-demand'); accumulatedDemand.textContent = grid.accumulatedDemand; const investmentCost = document.getElementById('investment-cost'); investmentCost.textContent = grid.investmentCost.toFixed(3); const totalLength = document.getElementById('total-length'); totalLength.textContent = grid.totalLength; const calcGridTitle = document.getElementById('used-segments'); //calcGridTitle.textContent = `${grid.segments.length}`; calcGridTitle.textContent = grid.segments.length; for (var segment in grid.segments) { var row = document.createElement("tr"); const id = document.createElement("td"); let cellText = document.createTextNode(grid.segments[segment].id); id.appendChild(cellText); const demand = document.createElement("td"); cellText = document.createTextNode(grid.segments[segment].demand); demand.appendChild(cellText); const length = document.createElement("td"); cellText = document.createTextNode(grid.segments[segment].length); length.appendChild(cellText);
var accDemandCell = document.createElement("td"); cellText = document.createTextNode(accDemand += grid.segments[segment].demand); accDemandCell.appendChild(cellText); var accLengthCell = document.createElement("td"); cellText = document.createTextNode((accLength += grid.segments[segment].length).toFixed(3)); accLengthCell.appendChild(cellText); var accCostCell = document.createElement("td"); cellText = document.createTextNode((gridCost(accDemand,accLength, grid.a, grid.c1, grid.c2)).toFixed(3)); accCostCell.appendChild(cellText); row.appendChild(id); row.appendChild(demand); row.appendChild(length); row.appendChild(accDemandCell); row.appendChild(accLengthCell); row.appendChild(accCostCell); // add the row to the end of the table body tblBody.appendChild(row); } // put the <tbody> in the <table> if (table.children[1]) table.children[1].replaceWith(tblBody); else table.appendChild(tblBody); } function drawBaseGrid(viewer, wholeGrid) { // todo: clear entities for (var segment in wholeGrid) { // parse a WKT string, converting it into a Terraformer.Primitive let geojsonLineString = Terraformer.WKT.parse(wholeGrid[segment].geometry) let coordinates = [] for (let i = 0; i < (geojsonLineString.coordinates.length); i++) { let projWebCoordinate = reprojectCoordinate(geojsonLineString.coordinates[i]) coordinates.push(projWebCoordinate) } // draw grids based on coordinates for (let i = 0; i < (coordinates.length-1); i++) { viewer.entities.add({ id: "BaseGrid"+"_Segment-"+wholeGrid[segment].id+"-"+i, polyline: { positions: Cesium.Cartesian3.fromDegreesArray([coordinates[i][0], coordinates[i][1], coordinates[i+1][0], coordinates[i+1][1]]), width: 2, material: Cesium.Color.BLACK, clampToGround: true, } }) } } } function drawGrid(viewer, grid) { for (var segment in grid.segments) { // parse a WKT string, converting it into a Terraformer.Primitive let geojsonLineString = Terraformer.WKT.parse(grid.segments[segment].geometry) let coordinates = [] for (let i = 0; i < (geojsonLineString.coordinates.length); i++) { let projWebCoordinate = reprojectCoordinate(geojsonLineString.coordinates[i]) coordinates.push(projWebCoordinate) } // draw grids based on coordinates for (let i = 0; i < (coordinates.length-1); i++) { viewer.entities.add({
id: "Grid"+"_Segment-"+grid.segments[segment].id+"-"+i, polyline: { positions: Cesium.Cartesian3.fromDegreesArray([coordinates[i][0], coordinates[i][1], coordinates[i+1][0], coordinates[i+1][1]]), width: 5, material: Cesium.Color.RED, clampToGround: true, }, }); } } } function reprojectCoordinate(coordinate) { let firstProj = "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs"; // EPSG:31467 let secondProj = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"; // EPSG:4326 // convert the passed coordinate to geographic coordinate let geoCoordinate = Terraformer.Tools.positionToGeographic(coordinate) // converts the passed coordinate to web mercator spatial reference. let webCoordinate = Terraformer.Tools.positionToMercator(geoCoordinate) // project coordinate to EPSG 4326 let projWebCoordinate = proj4(firstProj, secondProj, webCoordinate) return projWebCoordinate } function init() { // set links to the result files let aJson = document.getElementById('jsonResult') let resultJsonFilename = {{ resultFileJson | tojson }} aJson.href = "result/"+resultJsonFilename aJson.textContent = resultJsonFilename let aCsv = document.getElementById('csvResult') let resultCsvFilename = {{ resultFileCsv | tojson }} aCsv.href = "result/"+resultCsvFilename aCsv.textContent = resultCsvFilename // load cesiumjs Cesium.Ion.defaultAccessToken = 'put-your-cesium-token-here' let viewer = new Cesium.Viewer("cesiumContainer", { animation: false, timeline: false, terrainProvider: Cesium.createWorldTerrain(), imageryProvider : new Cesium.OpenStreetMapImageryProvider({ url : 'https://a.tile.openstreetmap.org/'}) }); // Add Cesium OSM buildings to the scene //viewer.scene.primitives.add(Cesium.createOsmBuildings()); //myViewer = viewer myWholeGrid = JSON.parse({{ wholeGrid | tojson }}) myGrid = JSON.parse({{ grid | tojson }}) displayTable(myGrid) drawBaseGrid(viewer, myWholeGrid) drawGrid(viewer, myGrid) viewer.zoomTo(viewer.entities) } init() </script> </body> </html>