"...asyst-moodle-plugin.git" did not exist on "a9d87f34d1adc48c352d192acb556ac83d85c497"
Commit b0da5bf6 authored by Rosanny Sihombing's avatar Rosanny Sihombing
Browse files

first commit

parent 7abcb82b
No related merge requests found
Showing with 1027 additions and 576 deletions
+1027 -576
venv/
__pycache__/
result/
input/
\ No newline at end of file
# disaggregation # disaggregation - web application
This branch is the web app implementation of the master branch, in which the grids are visualized in a 3D globe using CesiumJS.
Source code for disaggregation ### Demo
\ No newline at end of file http://193.196.55.138/ensource2/
\ No newline at end of file
File moved
"""
@author: Andrés Lalama
"""
from locale import atof, setlocale, LC_NUMERIC from locale import atof, setlocale, LC_NUMERIC
import time import time
from typing import List from typing import List
...@@ -16,7 +12,16 @@ import time ...@@ -16,7 +12,16 @@ import time
import os import os
import platform import platform
from datetime import datetime from datetime import datetime
# Flask
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
# Define the folder of the input data
UPLOAD_FOLDER = 'input'
ALLOWED_EXTENSIONS = {'csv'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
class Segment(object): class Segment(object):
def __init__(self, def __init__(self,
...@@ -35,18 +40,16 @@ class Segment(object): ...@@ -35,18 +40,16 @@ class Segment(object):
self.hasUnusedSegments = True self.hasUnusedSegments = True
self.geometry = geometry self.geometry = geometry
class HeatGrid: class HeatGrid:
def __init__(self, id: int, targetDemand: float = None, segments=[]): def __init__(self, id: int, segmentsFile, targetDemand: float = None, segments=[]):
self.id = id self.id = id
self.c1 = 368 self.c1 = 368
self.c2 = 2602.5 self.c2 = 2602.5
self.a = 0.0725 self.a = 0.0725
# use 'self.targetDemand = targetDemand' in order to use the maximal possible energy demand # use 'self.targetDemand = targetDemand' in order to use the maximal possible energy demand
self.targetDemand = targetDemand self.targetDemand = targetDemand
#self.targetDemand = 33518557 #self.segmentsFile = ".\\heatingDemandAdjusted\\Advanced\\Adjusted_stat_lines_with_industry.csv"
#self.segmentsFile = "ise_files\\stat_lines_with_industry_v2102.csv" self.segmentsFile = segmentsFile
self.segmentsFile = "ise_files\\Rainau_stat_lines_with_industry.csv"
self.accumulatedDemand = 0 self.accumulatedDemand = 0
self.segments = segments self.segments = segments
self.availableSegments = [] self.availableSegments = []
...@@ -68,12 +71,11 @@ class HeatGrid: ...@@ -68,12 +71,11 @@ class HeatGrid:
rightArguments = segmentData rightArguments = segmentData
# setting german locale because of excel files # setting german locale because of excel files
setlocale(LC_NUMERIC, 'German_Germany.1252') setlocale(LC_NUMERIC, 'de_DE')
for index, row in rightArguments.iterrows(): for index, row in rightArguments.iterrows():
length = row['Length'] length = row['Length']
totalDistance = row['Total Distance'] totalDistance = row['Total Distance']
demand = row['Total Yearly Heat+DHW demand'] demand = row['Total Yearly Heat+DHW demand']
if isinstance(length, float) is False: if isinstance(length, float) is False:
length = atof(length) length = atof(length)
if isinstance(totalDistance, float) is False: if isinstance(totalDistance, float) is False:
...@@ -383,7 +385,7 @@ def serialize(obj): ...@@ -383,7 +385,7 @@ def serialize(obj):
segNeighborDic: dict = {} segNeighborDic: dict = {}
grid = HeatGrid(1) #grid = HeatGrid(1)
def gridCost(grid, total_demand_kWh, total_length_m): def gridCost(grid, total_demand_kWh, total_length_m):
...@@ -395,7 +397,7 @@ def gridCost(grid, total_demand_kWh, total_length_m): ...@@ -395,7 +397,7 @@ def gridCost(grid, total_demand_kWh, total_length_m):
# prints all segments of the grid # prints all segments of the grid
def exportResult(): def exportResult(grid):
for segment in grid.segments: for segment in grid.segments:
print(segment.id) print(segment.id)
...@@ -439,41 +441,25 @@ def printResults(grid): ...@@ -439,41 +441,25 @@ def printResults(grid):
print(f'Please Open the the result file in the result Report') print(f'Please Open the the result file in the result Report')
def main(argv): @app.route('/ensource2/', methods = ['GET', 'POST'])
try: def index():
opts, args = getopt.getopt( if request.method == 'GET':
argv, "ht:s:g:k:o:r:", ["target=", "segments=", "grid=", "kommod=", "outfile=", "rabbitmq=", "gui="]) return render_template('form.html')
except getopt.GetoptError: if request.method == 'POST':
print('Did not recognize all of the user arguments. Use \'-h\' for help.') # upload input file
file = request.files['file']
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
filepath = UPLOAD_FOLDER+'/'+filename
# define grid
grid = HeatGrid(1, filepath)
# set/reset grid segments
grid.segments = []
sys.exit(2)
print('==================================') print('==================================')
print(' ENsource Disaggregation') print(' ENsource Disaggregation')
print('==================================') print('==================================')
grid.givenGridAvailable = False grid.givenGridAvailable = False
for opt, arg in opts:
if opt == '-h':
printHelp()
sys.exit()
elif opt in ("-t", "--target"):
target = arg
grid.targetDemand = float(target)
print('Target (kWh) :', target)
elif opt in ("-c1", "--c1"):
grid.c1 = arg
print('Target (kWh) :', target)
elif opt in ("-s", "--segments"):
grid.segmentsFile = arg
print('Segments file :', grid.segmentsFile)
elif opt in ("-g", "--grid"):
givenGridIds = arg
grid.givenGridAvailable = True
print('Grid IDs :', givenGridIds)
elif opt in ("-k", "--kommod"):
komModFile = arg
grid.importKomModFromFile(komModFile)
elif opt in ("-r", "--rabbitmq"):
inputfile = arg
grid.importFromFile() grid.importFromFile()
if grid.givenGridAvailable: if grid.givenGridAvailable:
...@@ -504,19 +490,18 @@ def main(argv): ...@@ -504,19 +490,18 @@ def main(argv):
end = time.time() end = time.time()
print('Runtime: ',end - start ) print('Runtime: ',end - start )
d = datetime.now() d = datetime.now()
folderName = f'result_{d.year}{d.month}{d.day}{d.hour}{d.minute}{d.second}' #folderName = f'result_{d.year}{d.month}{d.day}{d.hour}{d.minute}{d.second}'
filepathHtml = f'{folderName}.html' folderName= 'result'
fileName = f'result_{d.year}{d.month}{d.day}{d.hour}{d.minute}{d.second}'
# create folder for files # create folder for files
os.mkdir(folderName) #os.mkdir(folderName)
# write html file
resultFileHtml = open(folderName+f'/{folderName}.html', 'w')
wholeGrid = json.dumps(grid.availableSegments, wholeGrid = json.dumps(grid.availableSegments,
default=serialize, indent=2) default=serialize, indent=2)
# write csv file # write csv file
resultFileCsv = open(folderName+f'/{folderName}.csv', 'w') resultFileCsv = open(folderName+f'/{fileName}.csv', 'w')
# write headers # write headers
headers = 'Segment ID;Demand (kWh);Length (m);Total Distance (m);Acc. Demand (kWh);Total Grid Length(m);Acc. Grid Cost (EUR);Spec. Grid Cost (EUR/kWh)' headers = 'Segment ID;Demand (kWh);Length (m);Total Distance (m);Acc. Demand (kWh);Total Grid Length(m);Acc. Grid Cost (EUR);Spec. Grid Cost (EUR/kWh)'
resultFileCsv.write(headers) resultFileCsv.write(headers)
...@@ -539,408 +524,13 @@ def main(argv): ...@@ -539,408 +524,13 @@ def main(argv):
delattr(grid, 'availableSegments') delattr(grid, 'availableSegments')
delattr(grid, 'komMod') delattr(grid, 'komMod')
jsonResultGrid = json.dumps(grid, default=serialize, indent=2) jsonResultGrid = json.dumps(grid, default=serialize, indent=2)
resultFileJson = open(folderName+f'/{folderName}.json', 'w') resultFileJson = open(folderName+f'/{fileName}.json', 'w')
resultReport = """<html>
<head>
<meta charset=\"UTF-8\">
<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;
}
input[type=\"file\"] {
z-index: -1;
position: absolute;
visibility: hidden;
}
.button {
float: left;
padding: 12px 18px;
margin-right: 10px;
cursor: pointer;
border-radius: 3px;
background-color: #549925;
font-size: 14px;
font-weight: bold;
color: #fff;
}
.button2 {
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;
}
</style>
</head>
<body>
<h1><span>EN</span>source Disaggregation Report</h1>
<h2 style=\"float:left; width: 100%;\">Run Results</h2>
<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 File</th>
<td id=\"file-name\">N/A</td>
</tr>
<tr>
<th>Segments File</th>
<td id=\"segments-file-name\">"""+grid.segmentsFile+"""</td>
</tr>
<tr>
<th>Available Segments</th>
<td id=\"available-segments\">N/A</td>
</tr>
<tr>
<th>Grid provided</th>
<td id=\"grid-provided\">"""+grid.givenGridStr+"""</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>
<h2 id=\"calculate-grid-title\" style=\"float:left;\">Calculated Grid</h2>
<button class=\"button2\" id=\"toggle-table\" onclick=\"toggleItem('result-table','toggle-table')\">-</button>
<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>
<h2 id=\"calculate-grid-title\" style=\"float:left;\">Grid Visualization</h2>
<button class=\"button2\" id=\"toggle-vis\" onclick=\"toggleItem('canvas-wrapper','toggle-vis')\">-</button>
<div id=\"canvas-wrapper\" style=\"width: 100%;float: left\">
<button class=\"button2\" style=\"width: 100px; margin-left:0px\" onclick=\"toggleResult()\">Toggle Result</button>
<canvas id=\"grid-canvas\" width=\"1280\" height=\"720\"></canvas>
</div>
</body>
<script>
const c1 = """+str(grid.c1)+""";
const c2 = """+str(grid.c2)+""";
const a = """+str(grid.a)+""";
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function (e) {
var contents = e.target.result;
console.log(contents)
setFileName(file);
displayTable(JSON.parse(contents));
drawGrid(JSON.parse(contents))
};
reader.readAsText(file);
}
function setFileName(file) {
const element = document.getElementById('file-name');
element.textContent = file;
}
function rescaleX(x, minMax) {
return ((1270 - 10) * (x - minMax[0]) / (minMax[1] - minMax[0])) + 10
}
function rescaleY(x, minMaY) {
return ((10 - 710) * (x - minMaY[0]) / (minMaY[1] - minMaY[0])) + 710
}
const minMaxX = [Number.POSITIVE_INFINITY, 0];
const minMaxY = [Number.POSITIVE_INFINITY, 0];
function drawBaseGrid(grid) {
const canvas = document.getElementById('grid-canvas');
var ctx = canvas.getContext(\"2d\");
ctx.lineWidth = 1;
ctx.strokeStyle = \"black\";
for (var segment in grid) {
const onlyCoords = grid[segment].geometry.substring(12, grid[segment].geometry.length - 1);
const lines = onlyCoords.split(\",\")
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].trim();
const xyCoords = lines[i].split(\" \")
// check x
// check minimal
if (xyCoords[0] < minMaxX[0]) {
minMaxX[0] = xyCoords[0]
}
// check maximal
if (xyCoords[0] > minMaxX[1]) {
minMaxX[1] = xyCoords[0]
}
// check y
// check minimal
if (xyCoords[1] < minMaxY[0]) {
minMaxY[0] = xyCoords[1]
}
// check maximal
if (xyCoords[1] > minMaxY[1]) {
minMaxY[1] = xyCoords[1]
}
}
}
for (var segment in grid) {
const onlyCoords = grid[segment].geometry.substring(12, grid[segment].geometry.length - 1);
const lines = onlyCoords.split(\",\")
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].trim();
const xyCoords = lines[i].split(\" \")
// console.log(xyCoords)
// if (i === 0)
// ctx.moveTo(xyCoords[0].substring(3), xyCoords[1].substring(3))
// else
// ctx.lineTo(xyCoords[0].substring(3), xyCoords[1].substring(3))
if (i === 0)
ctx.moveTo(rescaleX(xyCoords[0], minMaxX), rescaleY(
xyCoords[1], minMaxY))
else
ctx.lineTo(rescaleX(xyCoords[0], minMaxX), rescaleY(
xyCoords[1], minMaxY))
}
ctx.stroke();
}
}
function drawGrid(grid) {
const canvas = document.getElementById('grid-canvas');
var ctx = canvas.getContext(\"2d\");
for (var segment in grid.segments) {
const onlyCoords = grid.segments[segment].geometry.substring(12, grid.segments[segment].geometry.length - 1);
const lines = onlyCoords.split(\",\")
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle = \"red\";
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].trim();
const xyCoords = lines[i].split(\" \")
if (i === 0)
ctx.moveTo(rescaleX(xyCoords[0], minMaxX), rescaleY(
xyCoords[1], minMaxY))
else
ctx.lineTo(rescaleX(xyCoords[0], minMaxX), rescaleY(
xyCoords[1], minMaxY))
}
ctx.stroke();
}
}
function toggleItem(item, source) {
const x = document.getElementById(item);
const btn = document.getElementById(source);
if (x.style.visibility === \"collapse\") {
x.style.visibility = \"visible\";
btn.textContent = \"-\";
} else {
x.style.visibility = \"collapse\";
btn.textContent = \"+\";
}
}
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 availSegments = document.getElementById('available-segments');
availSegments.textContent = grid.availableSegmentsCount;
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}`;
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)).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 gridCost(total_demand_kWh, total_length_m){
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 init() {
setFileName(\""""+f'{folderName}.json'+"""\");
displayTable(grid);
drawBaseGrid(wholeGrid);
drawGrid(grid)
};
// clear the canvas
var resultVisible = true;
function toggleResult(){
const canvas = document.getElementById('grid-canvas');
var ctx = canvas.getContext(\"2d\");
ctx.clearRect(0,0,canvas.width,canvas.height);
drawBaseGrid(wholeGrid);
if(resultVisible){
resultVisible = false;
}else {
drawGrid(grid);
resultVisible = true;
}
}
const grid = """+jsonResultGrid+""";
const wholeGrid = """+wholeGrid+""";
window.onload = init();
</script>
</html>"""
resultFileHtml.write(resultReport)
resultFileHtml.close()
resultFileJson.write(jsonResultGrid) resultFileJson.write(jsonResultGrid)
resultFileJson.close() resultFileJson.close()
# open results file resultFile = f'{fileName}.json'
# if platform.system() == 'Darwin': # macOS resultFileCsvFormat = f'{fileName}.csv'
# subprocess.call(('open', filepathHtml))
# elif platform.system() == 'Windows': # Windows
# os.startfile(folderName+f'/{filepathHtml}')
# else: # linux variants
# subprocess.call(('xdg-open', filepathHtml))
return render_template('index.html', givenGridIds=givenGridIds, resultFileJson=resultFile, resultFileCsv=resultFileCsvFormat, wholeGrid=wholeGrid, grid=jsonResultGrid)
if __name__ == "__main__": #if __name__ == "__main__":
main(sys.argv[1:]) # app.run(host='0.0.0.0')
This source diff could not be displayed because it is too large. You can view the blob instead.
<html>
<head>
<title>ENsource Disaggregation Report</title>
<meta charset="UTF-8">
<style>
h1 {
text-align: center;
color: #002C55;
}
h2 {
text-align: left;
font-size: 25px;
font-weight: "bold";
color: #002C55;
}
h1 span {
color: #549925;
}
</style>
</head>
<body>
<h1><span>EN</span>source Disaggregation Report</h1>
<h2 style="float:left; width: 100%;">Run Results</h2>
<!-- TO BE ADDED: HELP? -->
<form action = "http://127.0.0.1:5000/ensource2/" method = "POST" enctype = "multipart/form-data">
<p>Input CSV file:
<input type=file name=file required>
</p>
<input type=submit value=Run>
</form>
<br/>
<p><a href="data/sample.csv">Download a sample of input CSV file</a></p>
<p><small><strong>IMPORTANT:</strong> The header of the CSV input file MUST BE named as the following:
<ul>
<li>ID</li>
<li>GMLId</li>
<li>Stat PrimaryUsageZoneType</li>
<li>Stat Class year of construction</li>
<li>Building Count</li>
<li>Total Yearly Heat+DHW demand</li>
<li>January Heating Demand</li>
<li>February Heating Demand</li>
<li>March Heating Demand</li>
<li>April Heating Demand</li>
<li>May Heating Demand</li>
<li>June Heating Demand</li>
<li>July Heating Demand</li>
<li>August Heating Demand</li>
<li>September Heating Demand</li>
<li>October Heating Demand</li>
<li>November Heating Demand</li>
<li>December Heating Demand</li>
<li>Total Distance</li>
<li>Length</li>
<li>geometry</li>
<li>neighbor</li>
</ul>
</small></p>
</body>
</html>
<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>
wsgi.py 0 → 100644
from disaggregation import app
if __name__ == '__main__':
app.run(debug=False)
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment