Compare commits
21 Commits
e6b2e151ba
...
ae981362d8
Author | SHA1 | Date | |
---|---|---|---|
ae981362d8 | |||
|
1999449738 | ||
|
7a1a3fbef1 | ||
|
05b45328aa | ||
|
098c9aa338 | ||
9af87fe482 | |||
eb26c48627 | |||
2ca52c157a | |||
62c70b9c9f | |||
a62f5e6f38 | |||
6deffa9323 | |||
c046eacc63 | |||
05b9a42672 | |||
90a7f5648b | |||
4e75024817 | |||
904fe91e5a | |||
|
d2e20312b2 | ||
|
74cf47e3e1 | ||
1a43e65992 | |||
3b5e12efaf | |||
435fc4c679 |
111
district_heating_network.py
Normal file
111
district_heating_network.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
from scripts.district_heating_network.directory_manager import DirectoryManager
|
||||
import subprocess
|
||||
from scripts.ep_run_enrich import energy_plus_workflow
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport
|
||||
from scripts.geojson_creator import process_geojson
|
||||
from scripts import random_assignation
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing import SystemSizing
|
||||
from scripts.solar_angles import CitySolarAngles
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
from scripts.energy_system_retrofit_results import consumption_data, cost_data
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.costs.cost import Cost
|
||||
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_feasibility import pv_feasibility
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from scripts.district_heating_network.district_heating_network_creator import DistrictHeatingNetworkCreator
|
||||
from scripts.district_heating_network.district_heating_factory import DistrictHeatingFactory
|
||||
import json
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# Manage File Path
|
||||
base_path = "./"
|
||||
dir_manager = DirectoryManager(base_path)
|
||||
|
||||
# Input files directory
|
||||
input_files_path = dir_manager.create_directory('input_files')
|
||||
geojson_file_path = input_files_path / 'output_buildings.geojson'
|
||||
pipe_data_file = input_files_path / 'pipe_data.json'
|
||||
|
||||
# Output files directory
|
||||
output_path = dir_manager.create_directory('out_files')
|
||||
|
||||
# Subdirectories for output files
|
||||
energy_plus_output_path = dir_manager.create_directory('out_files/energy_plus_outputs')
|
||||
simulation_results_path = dir_manager.create_directory('out_files/simulation_results')
|
||||
sra_output_path = dir_manager.create_directory('out_files/sra_outputs')
|
||||
cost_analysis_output_path = dir_manager.create_directory('out_files/cost_analysis')
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# Area Under Study
|
||||
location = [45.4934614681437, -73.57982834742518]
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# Create geojson of buildings
|
||||
process_geojson(x=location[1], y=location[0], diff=0.001)
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# Create ciry and run energyplus workflow
|
||||
city = GeometryFactory(file_type='geojson',
|
||||
path=geojson_file_path,
|
||||
height_field='height',
|
||||
year_of_construction_field='year_of_construction',
|
||||
function_field='function',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
|
||||
# SRA
|
||||
ExportsFactory('sra', city, output_path).export()
|
||||
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
|
||||
subprocess.run(['sra', str(sra_path)])
|
||||
ResultFactory('sra', city, output_path).enrich()
|
||||
|
||||
# EP Workflow
|
||||
energy_plus_workflow(city, energy_plus_output_path)
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# District Heating Network Creator
|
||||
central_plant_locations = [(-73.57812571080625, 45.49499447346277)] # Add at least one location
|
||||
|
||||
roads_file = "./input_files/roads.json"
|
||||
|
||||
dhn_creator = DistrictHeatingNetworkCreator(geojson_file_path, roads_file, central_plant_locations)
|
||||
|
||||
network_graph = dhn_creator.run()
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
# Pipe and pump sizing
|
||||
|
||||
with open(pipe_data_file, 'r') as f:
|
||||
pipe_data = json.load(f)
|
||||
|
||||
factory = DistrictHeatingFactory(
|
||||
city=city,
|
||||
graph=network_graph,
|
||||
supply_temperature=80 + 273, # in Kelvin
|
||||
return_temperature=60 + 273, # in Kelvin
|
||||
simultaneity_factor=0.9
|
||||
)
|
||||
|
||||
factory.enrich()
|
||||
factory.sizing()
|
||||
factory.calculate_diameters_and_costs(pipe_data)
|
||||
pipe_groups, total_cost = factory.analyze_costs()
|
||||
|
||||
# Save the pipe groups with total costs to a CSV file
|
||||
factory.save_pipe_groups_to_csv('pipe_groups.csv')
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -92,9 +92,8 @@ for building in city.buildings:
|
|||
fuel_tariffs=['Electricity-D', 'Gas-Energir']).life_cycle
|
||||
lcc_dataframe.to_csv(cost_analysis_output_path / f'{building.name}_retrofitted_lcc.csv')
|
||||
retrofitted_life_cycle_cost[f'{building.name}'] = cost_data(building, lcc_dataframe, cost_retrofit_scenario)
|
||||
for i in range(12):
|
||||
dhw_consumption = 0
|
||||
for building in city.buildings:
|
||||
dhw_consumption += building.domestic_hot_water_consumption[cte.MONTH][i] / 3.6e6
|
||||
EnergySystemRetrofitReport(city, output_path, 'PV Implementation and System Retrofit',
|
||||
current_status_energy_consumption, retrofitted_energy_consumption,
|
||||
current_status_life_cycle_cost, retrofitted_life_cycle_cost).create_report()
|
||||
|
||||
|
||||
|
|
81
input_files/lachine_group_mach_buildings.geojson
Normal file
81
input_files/lachine_group_mach_buildings.geojson
Normal file
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"name": "lachine_group_mach_buildings",
|
||||
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
|
||||
"features": [
|
||||
{ "type": "Feature", "properties": { "id": 1 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665576136530092, 45.435517165119393 ], [ -73.665576136530092, 45.435901290585491 ], [ -73.665308918814546, 45.435901290585491 ], [ -73.665308918814546, 45.435517165119393 ], [ -73.665576136530092, 45.435517165119393 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 2 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665576136530092, 45.43643906623803 ], [ -73.665576136530092, 45.436936759233234 ], [ -73.665302238371666, 45.436936759233234 ], [ -73.665302238371666, 45.43643906623803 ], [ -73.665576136530092, 45.43643906623803 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 3 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665158608849552, 45.436672881739128 ], [ -73.665158608849552, 45.436839892811349 ], [ -73.664574070096791, 45.436839892811349 ], [ -73.664574070096791, 45.436672881739128 ], [ -73.665158608849552, 45.436672881739128 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 4 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664821246483683, 45.436512551109814 ], [ -73.664821246483683, 45.43657434520653 ], [ -73.664590771204018, 45.43657434520653 ], [ -73.664590771204018, 45.436512551109814 ], [ -73.664821246483683, 45.436512551109814 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 5 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664816236151509, 45.436448251847004 ], [ -73.664816236151509, 45.43650253044548 ], [ -73.664592441314738, 45.43650253044548 ], [ -73.664592441314738, 45.436448251847004 ], [ -73.664816236151509, 45.436448251847004 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 6 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664815401096149, 45.436378107196674 ], [ -73.664815401096149, 45.43643489096123 ], [ -73.664594111425458, 45.43643489096123 ], [ -73.664594111425458, 45.436378107196674 ], [ -73.664815401096149, 45.436378107196674 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 7 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664814566040789, 45.436312972878511 ], [ -73.664814566040789, 45.436370591698427 ], [ -73.664594111425458, 45.436370591698427 ], [ -73.664594111425458, 45.436312972878511 ], [ -73.664814566040789, 45.436312972878511 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 8 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664816236151509, 45.436248673615708 ], [ -73.664816236151509, 45.436299611992737 ], [ -73.664592441314738, 45.436299611992737 ], [ -73.664592441314738, 45.436248673615708 ], [ -73.664816236151509, 45.436248673615708 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 9 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664815401096149, 45.436177693910018 ], [ -73.664815401096149, 45.436235312729927 ], [ -73.664592441314738, 45.436235312729927 ], [ -73.664592441314738, 45.436177693910018 ], [ -73.664815401096149, 45.436177693910018 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 10 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664813730985429, 45.436109219370408 ], [ -73.664813730985429, 45.436169343356404 ], [ -73.664593276370098, 45.436169343356404 ], [ -73.664593276370098, 45.436109219370408 ], [ -73.664813730985429, 45.436109219370408 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 11 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665584487083734, 45.436100868816794 ], [ -73.665584487083734, 45.43628124077479 ], [ -73.664913102573422, 45.43628124077479 ], [ -73.664913102573422, 45.436100868816794 ], [ -73.665584487083734, 45.436100868816794 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 11 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66557947675156, 45.43537604076338 ], [ -73.66529722803952, 45.435372700541933 ], [ -73.665293887818066, 45.434841605332281 ], [ -73.665582816973, 45.434661233374285 ], [ -73.66557947675156, 45.43537604076338 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 12 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66516695940318, 45.435753485786591 ], [ -73.66516695940318, 45.435917156637359 ], [ -73.664530647218029, 45.435917156637359 ], [ -73.664530647218029, 45.435753485786591 ], [ -73.66516695940318, 45.435753485786591 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 13 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664857988919579, 45.435593155157257 ], [ -73.664587430982593, 45.435591485046537 ], [ -73.664589101093313, 45.435324267330991 ], [ -73.664857988919579, 45.435157256258769 ], [ -73.664857988919579, 45.435593155157257 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 14 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665409960513287, 45.434485871748457 ], [ -73.665227918444572, 45.434611130052616 ], [ -73.664611647588089, 45.434125127832466 ], [ -73.664788679324644, 45.434004879860467 ], [ -73.665409960513287, 45.434485871748457 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 15 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665122701469073, 45.434667913817172 ], [ -73.664730225449361, 45.434928451089831 ], [ -73.6645598741557, 45.434796512342778 ], [ -73.664954020286132, 45.434537645180839 ], [ -73.665122701469073, 45.434667913817172 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 16 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664749431722669, 45.434258736690239 ], [ -73.66469264795812, 45.434303829679735 ], [ -73.664553193712806, 45.434181911597015 ], [ -73.664611647588089, 45.43413598355216 ], [ -73.664749431722669, 45.434258736690239 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 17 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664679287072332, 45.434305499790462 ], [ -73.664619998141703, 45.434352262890677 ], [ -73.664486389283923, 45.434232014918685 ], [ -73.664543173048472, 45.434189427095269 ], [ -73.664679287072332, 45.434305499790462 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 18 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664606637255915, 45.434355603112124 ], [ -73.664547348325286, 45.434399025990899 ], [ -73.664409564190706, 45.434278778018907 ], [ -73.664464677844535, 45.434234520084765 ], [ -73.664606637255915, 45.434355603112124 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 19 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664533152384152, 45.434401531156986 ], [ -73.664478038730309, 45.434439943703595 ], [ -73.664334409208209, 45.434324706063762 ], [ -73.664396203304932, 45.434279613074267 ], [ -73.664533152384152, 45.434401531156986 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 20 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664464677844535, 45.434442448869675 ], [ -73.664405388913892, 45.434486706803817 ], [ -73.664265099613232, 45.434367293887178 ], [ -73.664323553488515, 45.434325541119122 ], [ -73.664464677844535, 45.434442448869675 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 21 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664389522862038, 45.434490047025257 ], [ -73.664336914374289, 45.434531799793312 ], [ -73.664187439464655, 45.4344140569874 ], [ -73.664248398506018, 45.434373139274705 ], [ -73.664389522862038, 45.434490047025257 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 21 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664316873045621, 45.434532634848672 ], [ -73.664264264557872, 45.434576057727455 ], [ -73.664121470091132, 45.434464160309062 ], [ -73.664179088911041, 45.434421572485647 ], [ -73.664316873045621, 45.434532634848672 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 22 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664525636885912, 45.435077090944098 ], [ -73.663657179310391, 45.435634907925305 ], [ -73.663523570452611, 45.435528020839087 ], [ -73.664385347585252, 45.434956842972106 ], [ -73.664525636885912, 45.435077090944098 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 23 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664248398506032, 45.434890038543216 ], [ -73.664098088541039, 45.434996925629434 ], [ -73.663747365289382, 45.434729707913888 ], [ -73.663901015475815, 45.434632841492004 ], [ -73.664248398506032, 45.434890038543216 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 24 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663470126909502, 45.4355213403962 ], [ -73.663293095172946, 45.435621547039531 ], [ -73.662895608821074, 45.435224060687652 ], [ -73.663089341664843, 45.435087111608432 ], [ -73.663470126909502, 45.4355213403962 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 26 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663733169348234, 45.434914463912534 ], [ -73.663676385583685, 45.43495705173595 ], [ -73.663538601449105, 45.434849329594364 ], [ -73.663588704770774, 45.434804236604869 ], [ -73.663733169348234, 45.434914463912534 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 27 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663665529863991, 45.43495872184667 ], [ -73.663602900711908, 45.435004649891532 ], [ -73.663461776355874, 45.434891082362419 ], [ -73.663518560120437, 45.434848494539004 ], [ -73.663665529863991, 45.43495872184667 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 28 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663592880047574, 45.435007990112979 ], [ -73.663534426172291, 45.435049742881034 ], [ -73.663395806982351, 45.434937845462642 ], [ -73.66345008558082, 45.434896092694586 ], [ -73.663592880047574, 45.435007990112979 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 29 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663516890009717, 45.435051412991754 ], [ -73.663464281521968, 45.43509233070445 ], [ -73.663316476723054, 45.434978763175337 ], [ -73.663381611041217, 45.434937010407282 ], [ -73.663516890009717, 45.435051412991754 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 30 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66344758041474, 45.43509483587053 ], [ -73.663389126539457, 45.435138258749312 ], [ -73.663248002183437, 45.43502302110948 ], [ -73.66330645605872, 45.434979598230697 ], [ -73.66344758041474, 45.43509483587053 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 31 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663374930598323, 45.435141598970752 ], [ -73.663317311778414, 45.435184186794174 ], [ -73.6631736822563, 45.435074794541869 ], [ -73.663237146463743, 45.435028866497007 ], [ -73.663374930598323, 45.435141598970752 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 33 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663299775615826, 45.435188362070974 ], [ -73.663253012515597, 45.435225939562223 ], [ -73.66312775421143, 45.435100681258064 ], [ -73.663164496647326, 45.435074794541869 ], [ -73.663299775615826, 45.435188362070974 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 34 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664583255705864, 45.433868139545069 ], [ -73.664172408468204, 45.434123666485561 ], [ -73.664018758281756, 45.433881500430843 ], [ -73.664464677844592, 45.433757912237397 ], [ -73.664583255705864, 45.433868139545069 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 36 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663997046842368, 45.434095274603287 ], [ -73.663908530974098, 45.434299028111397 ], [ -73.663263868235319, 45.4338180362234 ], [ -73.663449250525488, 45.433677746922733 ], [ -73.663997046842368, 45.434095274603287 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 37 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.6637064475767, 45.434445997854951 ], [ -73.663504364179317, 45.43456624582695 ], [ -73.662851350886925, 45.434083583828233 ], [ -73.663046753841428, 45.433941624416846 ], [ -73.6637064475767, 45.434445997854951 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 38 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662968258637491, 45.434270636229108 ], [ -73.662757824686494, 45.434439317412057 ], [ -73.662552401067657, 45.434307378664997 ], [ -73.662782876347322, 45.434150388257109 ], [ -73.662968258637491, 45.434270636229108 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 39 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66293652653377, 45.434915298967887 ], [ -73.662712731696985, 45.435022186054105 ], [ -73.662311905123659, 45.434559565384056 ], [ -73.662473905863706, 45.434394224422554 ], [ -73.66293652653377, 45.434915298967887 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 40 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663361569712563, 45.434631380145106 ], [ -73.663303950892654, 45.434673132913161 ], [ -73.66315948631518, 45.434562070550136 ], [ -73.66321543502437, 45.434516142505274 ], [ -73.663361569712563, 45.434631380145106 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 41 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663290590006866, 45.434677308189968 ], [ -73.663232136131597, 45.434720731068744 ], [ -73.663091846830923, 45.434609668705718 ], [ -73.663146125429407, 45.434566245826943 ], [ -73.663290590006866, 45.434677308189968 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 42 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663216270079729, 45.434723236234831 ], [ -73.66316449664734, 45.434764153947526 ], [ -73.663019197014521, 45.434652256529134 ], [ -73.66307514572371, 45.434610503761078 ], [ -73.663216270079729, 45.434723236234831 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 43 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663141115097233, 45.434767494168966 ], [ -73.663085166388043, 45.434810917047749 ], [ -73.662943206976649, 45.434697349518636 ], [ -73.662999155685853, 45.434655596750581 ], [ -73.663141115097233, 45.434767494168966 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 44 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663070135391536, 45.434816762435275 ], [ -73.663019197014521, 45.434858515203331 ], [ -73.662871392215592, 45.434744947674218 ], [ -73.662927340924796, 45.434701524795443 ], [ -73.663070135391536, 45.434816762435275 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 45 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662996650519759, 45.434860185314051 ], [ -73.662951557530263, 45.434894422583859 ], [ -73.662833814724351, 45.434779184944027 ], [ -73.662863041661993, 45.434745782729578 ], [ -73.662996650519759, 45.434860185314051 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 46 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.663172847200954, 45.435882293076048 ], [ -73.662980784467905, 45.435974149165773 ], [ -73.662469730586906, 45.435426352848886 ], [ -73.662670143873569, 45.435326146205554 ], [ -73.663172847200954, 45.435882293076048 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 47 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662810433174229, 45.43604596392683 ], [ -73.662235915085787, 45.436202954334718 ], [ -73.662090615452954, 45.436059324812604 ], [ -73.662660123209236, 45.435883963186775 ], [ -73.662810433174229, 45.43604596392683 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 49 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662297709182511, 45.435972479055053 ], [ -73.662105646449461, 45.436029262819609 ], [ -73.661788325412232, 45.435740333664661 ], [ -73.661988738698909, 45.435651817796384 ], [ -73.662297709182511, 45.435972479055053 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 50 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662593318780353, 45.435580838090694 ], [ -73.662531524683629, 45.435615075360495 ], [ -73.662412946822357, 45.435490652111696 ], [ -73.6624805863066, 45.435453909675807 ], [ -73.662593318780353, 45.435580838090694 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 51 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662513153465682, 45.435615910415862 ], [ -73.662448854202879, 45.435650982741024 ], [ -73.66233946195058, 45.435532404879751 ], [ -73.662402091102663, 45.435497332554583 ], [ -73.662513153465682, 45.435615910415862 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 52 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662432988151025, 45.435650982741024 ], [ -73.662369523943582, 45.435684384955472 ], [ -73.662258461580549, 45.435568312260273 ], [ -73.662323595898712, 45.435533239935111 ], [ -73.662432988151025, 45.435650982741024 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 53 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662352822836354, 45.435686890121552 ], [ -73.662289358628911, 45.435719457280634 ], [ -73.662175791099799, 45.435603384585441 ], [ -73.662237585196522, 45.43556914731564 ], [ -73.662352822836354, 45.435686890121552 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 55 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66194114054332, 45.436273098985055 ], [ -73.661677263049199, 45.436343243635385 ], [ -73.661206291825536, 45.435825509311499 ], [ -73.661329880018982, 45.435608394917615 ], [ -73.66194114054332, 45.436273098985055 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 56 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66139668444788, 45.436279779427942 ], [ -73.660862249016759, 45.43652027537194 ], [ -73.660715279273205, 45.436369965406946 ], [ -73.661122786289425, 45.435985839940834 ], [ -73.66139668444788, 45.436279779427942 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 57 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.662522339074641, 45.435170825908394 ], [ -73.662298544237871, 45.435284393437506 ], [ -73.661954501429094, 45.43490360819284 ], [ -73.662118172279875, 45.434716555791951 ], [ -73.662522339074641, 45.435170825908394 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 58 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.661974542757761, 45.435144104136839 ], [ -73.661837593678541, 45.435317795651947 ], [ -73.661937800321866, 45.435448064288281 ], [ -73.661633840170424, 45.435578332924614 ], [ -73.661476849762536, 45.435397960966611 ], [ -73.661857635007209, 45.434987113728951 ], [ -73.661974542757761, 45.435144104136839 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 59 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.661874336114423, 45.434512802283841 ], [ -73.661557015077207, 45.434873546199839 ], [ -73.661276436475873, 45.434596307819952 ], [ -73.661730706592309, 45.434339110768732 ], [ -73.661874336114423, 45.434512802283841 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 60 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.661430086662321, 45.434997134393285 ], [ -73.661279776697313, 45.435174166129841 ], [ -73.660915692559868, 45.434796721106615 ], [ -73.661126126510879, 45.434666452470282 ], [ -73.661430086662321, 45.434997134393285 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 61 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.661116105846546, 45.435397960966611 ], [ -73.660999198095979, 45.435591693810395 ], [ -73.660474783329207, 45.435050577936394 ], [ -73.660688557501658, 45.434916969078614 ], [ -73.661116105846546, 45.435397960966611 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 62 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.660895651231215, 45.435731983111054 ], [ -73.660367896242988, 45.435969138833613 ], [ -73.660204225392206, 45.435808808204278 ], [ -73.660765382594874, 45.435554951374499 ], [ -73.660895651231215, 45.435731983111054 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 63 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.660384597350216, 45.435625096024836 ], [ -73.660144101406217, 45.435728642889615 ], [ -73.65980673904032, 45.435357878309283 ], [ -73.660060595870107, 45.435240970558723 ], [ -73.660384597350216, 45.435625096024836 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 64 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.664149026918068, 45.43368108714418 ], [ -73.664008737617408, 45.433764592680291 ], [ -73.663905190752629, 45.433641004486844 ], [ -73.664022098503182, 45.433567519615067 ], [ -73.664149026918068, 45.43368108714418 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 65 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665702229889732, 45.434185460582285 ], [ -73.665541899260404, 45.434289007447063 ], [ -73.66499076272207, 45.433878160209403 ], [ -73.665151093351398, 45.433767932901738 ], [ -73.665702229889732, 45.434185460582285 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 67 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666320170856977, 45.433948304859719 ], [ -73.666116417348874, 45.434091934381826 ], [ -73.665458393724322, 45.433600921829495 ], [ -73.665672167896759, 45.433420549871499 ], [ -73.666320170856977, 45.433948304859719 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 68 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.667141865332312, 45.433403848764272 ], [ -73.666363593735753, 45.433928263531051 ], [ -73.666186561999197, 45.433787974230384 ], [ -73.666948132488528, 45.433276920349385 ], [ -73.667141865332312, 45.433403848764272 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 69 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666854606288084, 45.43323349747061 ], [ -73.666650852779981, 45.433380467214164 ], [ -73.666386975285874, 45.433193414813275 ], [ -73.666667553887208, 45.43309654839139 ], [ -73.666854606288084, 45.43323349747061 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 70 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666557326579536, 45.433019723298166 ], [ -73.666103056463101, 45.433126610384384 ], [ -73.666062973805765, 45.433086527727056 ], [ -73.66488387563588, 45.433373786771277 ], [ -73.664810390764103, 45.433223476806276 ], [ -73.66597278782676, 45.432929537319168 ], [ -73.665889282290649, 45.432729124032498 ], [ -73.666066314027205, 45.432672340267942 ], [ -73.666557326579536, 45.433019723298166 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 71 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666499707759627, 45.433347900055082 ], [ -73.666428728053944, 45.43336627127303 ], [ -73.666371944289381, 45.433208445809782 ], [ -73.666382800009075, 45.433205940643695 ], [ -73.666499707759627, 45.433347900055082 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 72 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.66641870738961, 45.43336710632839 ], [ -73.666365263846487, 45.433379632158804 ], [ -73.666308480081938, 45.433234332525977 ], [ -73.666358583403607, 45.433215961308029 ], [ -73.66641870738961, 45.43336710632839 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 73 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666347727683913, 45.433381302269531 ], [ -73.66628676864255, 45.433395498210665 ], [ -73.666231654988721, 45.433251868688558 ], [ -73.66628342842111, 45.43322932219381 ], [ -73.666347727683913, 45.433381302269531 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 74 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666273407756776, 45.433394663155305 ], [ -73.666216623992213, 45.433409694151806 ], [ -73.666164850559824, 45.433286105958359 ], [ -73.666220799269027, 45.433265229574332 ], [ -73.666273407756776, 45.433394663155305 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 75 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666198252774265, 45.433413034373253 ], [ -73.666139798898996, 45.433431405591193 ], [ -73.666081345023713, 45.433293621456613 ], [ -73.666144809231156, 45.433272745072586 ], [ -73.666198252774265, 45.433413034373253 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 77 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666128108123942, 45.43343307570192 ], [ -73.666069654248659, 45.433449776809141 ], [ -73.66601454059483, 45.433305312231667 ], [ -73.666063808861139, 45.433289446179806 ], [ -73.666128108123942, 45.43343307570192 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 78 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.666054623252165, 45.433449776809141 ], [ -73.665997839487602, 45.433469818137809 ], [ -73.665944395944493, 45.433337879390749 ], [ -73.666004519930496, 45.433312827729921 ], [ -73.666054623252165, 45.433449776809141 ] ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 79 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -73.665984478601828, 45.433469818137809 ], [ -73.665933540224799, 45.433484014078942 ], [ -73.665870911072716, 45.433348735110442 ], [ -73.665926024726545, 45.433331198947862 ], [ -73.665984478601828, 45.433469818137809 ] ] ] ] } }
|
||||
]
|
||||
}
|
12
input_files/new.geojson
Normal file
12
input_files/new.geojson
Normal file
File diff suppressed because one or more lines are too long
1
input_files/output_roads.geojson
Normal file
1
input_files/output_roads.geojson
Normal file
|
@ -0,0 +1 @@
|
|||
{"type": "FeatureCollection", "features": []}
|
191
input_files/pipe_data.json
Normal file
191
input_files/pipe_data.json
Normal file
|
@ -0,0 +1,191 @@
|
|||
[
|
||||
{
|
||||
"DN": 16,
|
||||
"inner_diameter": 16.1,
|
||||
"outer_diameter": 21.3,
|
||||
"thickness": 2.6,
|
||||
"cost_per_meter": 320
|
||||
},
|
||||
{
|
||||
"DN": 20,
|
||||
"inner_diameter": 21.7,
|
||||
"outer_diameter": 26.9,
|
||||
"thickness": 2.6,
|
||||
"cost_per_meter": 320
|
||||
},
|
||||
{
|
||||
"DN": 25,
|
||||
"inner_diameter": 27.3,
|
||||
"outer_diameter": 33.7,
|
||||
"thickness": 3.2,
|
||||
"cost_per_meter": 320
|
||||
},
|
||||
{
|
||||
"DN": 32,
|
||||
"inner_diameter": 37.2,
|
||||
"outer_diameter": 42.4,
|
||||
"thickness": 2.6,
|
||||
"cost_per_meter": 350
|
||||
},
|
||||
{
|
||||
"DN": 40,
|
||||
"inner_diameter": 43.1,
|
||||
"outer_diameter": 48.3,
|
||||
"thickness": 2.6,
|
||||
"cost_per_meter": 375
|
||||
},
|
||||
{
|
||||
"DN": 50,
|
||||
"inner_diameter": 54.5,
|
||||
"outer_diameter": 60.3,
|
||||
"thickness": 2.9,
|
||||
"cost_per_meter": 400
|
||||
},
|
||||
{
|
||||
"DN": 65,
|
||||
"inner_diameter": 70.3,
|
||||
"outer_diameter": 76.1,
|
||||
"thickness": 2.9,
|
||||
"cost_per_meter": 450
|
||||
},
|
||||
{
|
||||
"DN": 80,
|
||||
"inner_diameter": 82.5,
|
||||
"outer_diameter": 88.9,
|
||||
"thickness": 3.2,
|
||||
"cost_per_meter": 480
|
||||
},
|
||||
{
|
||||
"DN": 90,
|
||||
"inner_diameter": 100.8,
|
||||
"outer_diameter": 108,
|
||||
"thickness": 3.6,
|
||||
"cost_per_meter": 480
|
||||
},
|
||||
{
|
||||
"DN": 100,
|
||||
"inner_diameter": 107.1,
|
||||
"outer_diameter": 114.3,
|
||||
"thickness": 3.6,
|
||||
"cost_per_meter": 550
|
||||
},
|
||||
{
|
||||
"DN": 110,
|
||||
"inner_diameter": 125.8,
|
||||
"outer_diameter": 133,
|
||||
"thickness": 3.6,
|
||||
"cost_per_meter": 550
|
||||
},
|
||||
{
|
||||
"DN": 125,
|
||||
"inner_diameter": 132.5,
|
||||
"outer_diameter": 139.7,
|
||||
"thickness": 3.6,
|
||||
"cost_per_meter": 630
|
||||
},
|
||||
{
|
||||
"DN": 140,
|
||||
"inner_diameter": 151,
|
||||
"outer_diameter": 159,
|
||||
"thickness": 4,
|
||||
"cost_per_meter": 700
|
||||
},
|
||||
{
|
||||
"DN": 150,
|
||||
"inner_diameter": 160.3,
|
||||
"outer_diameter": 168.3,
|
||||
"thickness": 4,
|
||||
"cost_per_meter": 700
|
||||
},
|
||||
{
|
||||
"DN": 180,
|
||||
"inner_diameter": 184.7,
|
||||
"outer_diameter": 193.7,
|
||||
"thickness": 4.5,
|
||||
"cost_per_meter": 700
|
||||
},
|
||||
{
|
||||
"DN": 200,
|
||||
"inner_diameter": 210.1,
|
||||
"outer_diameter": 219.1,
|
||||
"thickness": 4.5,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 250,
|
||||
"inner_diameter": 263,
|
||||
"outer_diameter": 273,
|
||||
"thickness": 5,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 300,
|
||||
"inner_diameter": 312.7,
|
||||
"outer_diameter": 323.9,
|
||||
"thickness": 5.6,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 350,
|
||||
"inner_diameter": 344.4,
|
||||
"outer_diameter": 355.6,
|
||||
"thickness": 5.6,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 400,
|
||||
"inner_diameter": 393.8,
|
||||
"outer_diameter": 406.4,
|
||||
"thickness": 6.3,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 450,
|
||||
"inner_diameter": 444.4,
|
||||
"outer_diameter": 457,
|
||||
"thickness": 6.3,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 500,
|
||||
"inner_diameter": 495.4,
|
||||
"outer_diameter": 508,
|
||||
"thickness": 6.3,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 600,
|
||||
"inner_diameter": 595.8,
|
||||
"outer_diameter": 610,
|
||||
"thickness": 7.1,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 700,
|
||||
"inner_diameter": 696.8,
|
||||
"outer_diameter": 711,
|
||||
"thickness": 7.1,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 800,
|
||||
"inner_diameter": 797,
|
||||
"outer_diameter": 813,
|
||||
"thickness": 8,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 900,
|
||||
"inner_diameter": 894,
|
||||
"outer_diameter": 914,
|
||||
"thickness": 10,
|
||||
"cost_per_meter": 860
|
||||
},
|
||||
{
|
||||
"DN": 1000,
|
||||
"inner_diameter": 996,
|
||||
"outer_diameter": 1016,
|
||||
"thickness": 10,
|
||||
"cost_per_meter": 860
|
||||
}
|
||||
]
|
2848
input_files/processed_output.geojson
Normal file
2848
input_files/processed_output.geojson
Normal file
File diff suppressed because it is too large
Load Diff
628
input_files/processed_roads_output.geojson
Normal file
628
input_files/processed_roads_output.geojson
Normal file
|
@ -0,0 +1,628 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"name": "lachine_roadfs",
|
||||
"crs": {
|
||||
"type": "name",
|
||||
"properties": {
|
||||
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
|
||||
}
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66582797080785,
|
||||
45.43501726460131
|
||||
],
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.436102836222425
|
||||
],
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.436102836222425
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.436102836222425
|
||||
],
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.437203485227165
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.437203485227165
|
||||
],
|
||||
[
|
||||
-73.66583550949966,
|
||||
45.43833428899916
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66583550949966,
|
||||
45.43833428899916
|
||||
],
|
||||
[
|
||||
-73.66679292335995,
|
||||
45.43815336039564
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66679292335995,
|
||||
45.43815336039564
|
||||
],
|
||||
[
|
||||
-73.66676276859269,
|
||||
45.437226101302606
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66676276859269,
|
||||
45.437226101302606
|
||||
],
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.437203485227165
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66676276859269,
|
||||
45.437226101302606
|
||||
],
|
||||
[
|
||||
-73.66677030728451,
|
||||
45.43677377979381
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66677030728451,
|
||||
45.43677377979381
|
||||
],
|
||||
[
|
||||
-73.66753925384947,
|
||||
45.43675116371837
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66753925384947,
|
||||
45.43675116371837
|
||||
],
|
||||
[
|
||||
-73.66756186992491,
|
||||
45.436102836222425
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66756186992491,
|
||||
45.436102836222425
|
||||
],
|
||||
[
|
||||
-73.66582043211604,
|
||||
45.436102836222425
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66756186992491,
|
||||
45.436102836222425
|
||||
],
|
||||
[
|
||||
-73.66754679254127,
|
||||
45.435032341984936
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66754679254127,
|
||||
45.435032341984936
|
||||
],
|
||||
[
|
||||
-73.66582797080785,
|
||||
45.43501726460131
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66754679254127,
|
||||
45.435032341984936
|
||||
],
|
||||
[
|
||||
-73.66858713201151,
|
||||
45.435024803293125
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66858713201151,
|
||||
45.435024803293125
|
||||
],
|
||||
[
|
||||
-73.6694314654946,
|
||||
45.435039880676754
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66858713201151,
|
||||
45.435024803293125
|
||||
],
|
||||
[
|
||||
-73.66860974808695,
|
||||
45.436087758838795
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66860974808695,
|
||||
45.436087758838795
|
||||
],
|
||||
[
|
||||
-73.66862482547057,
|
||||
45.43723363999442
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66862482547057,
|
||||
45.43723363999442
|
||||
],
|
||||
[
|
||||
-73.66944654287822,
|
||||
45.43723363999442
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66944654287822,
|
||||
45.43723363999442
|
||||
],
|
||||
[
|
||||
-73.66943900418642,
|
||||
45.43609529753061
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66943900418642,
|
||||
45.43609529753061
|
||||
],
|
||||
[
|
||||
-73.66860974808695,
|
||||
45.436087758838795
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66943900418642,
|
||||
45.43609529753061
|
||||
],
|
||||
[
|
||||
-73.6694314654946,
|
||||
45.435039880676754
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66862482547057,
|
||||
45.43723363999442
|
||||
],
|
||||
[
|
||||
-73.66770510506936,
|
||||
45.437226101302606
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66770510506936,
|
||||
45.437226101302606
|
||||
],
|
||||
[
|
||||
-73.66676276859269,
|
||||
45.437226101302606
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66770510506936,
|
||||
45.437226101302606
|
||||
],
|
||||
[
|
||||
-73.66771264376118,
|
||||
45.43797243179212
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66771264376118,
|
||||
45.43797243179212
|
||||
],
|
||||
[
|
||||
-73.66679292335995,
|
||||
45.43815336039564
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66771264376118,
|
||||
45.43797243179212
|
||||
],
|
||||
[
|
||||
-73.66863990285421,
|
||||
45.4377915031886
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66863990285421,
|
||||
45.4377915031886
|
||||
],
|
||||
[
|
||||
-73.66862482547057,
|
||||
45.43723363999442
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66863990285421,
|
||||
45.4377915031886
|
||||
],
|
||||
[
|
||||
-73.66945408157004,
|
||||
45.43764826804415
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66945408157004,
|
||||
45.43764826804415
|
||||
],
|
||||
[
|
||||
-73.66944654287822,
|
||||
45.43723363999442
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6694314654946,
|
||||
45.435039880676754
|
||||
],
|
||||
[
|
||||
-73.66938623334372,
|
||||
45.433622606615856
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66938623334372,
|
||||
45.433622606615856
|
||||
],
|
||||
[
|
||||
-73.66870021238871,
|
||||
45.43365276138311
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66870021238871,
|
||||
45.43365276138311
|
||||
],
|
||||
[
|
||||
-73.66868513500509,
|
||||
45.43390907690476
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66868513500509,
|
||||
45.43390907690476
|
||||
],
|
||||
[
|
||||
-73.66870021238871,
|
||||
45.43406738943284
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66868513500509,
|
||||
45.43390907690476
|
||||
],
|
||||
[
|
||||
-73.66839112602436,
|
||||
45.43389399952113
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66870021238871,
|
||||
45.43406738943284
|
||||
],
|
||||
[
|
||||
-73.6681272718109,
|
||||
45.43442924663987
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66870021238871,
|
||||
45.43365276138311
|
||||
],
|
||||
[
|
||||
-73.6676749503021,
|
||||
45.43365276138311
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66938623334372,
|
||||
45.433622606615856
|
||||
],
|
||||
[
|
||||
-73.66930330773377,
|
||||
45.43118007046835
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
}
|
||||
]
|
||||
}
|
43
input_files/roads.geojson
Normal file
43
input_files/roads.geojson
Normal file
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"name": "roads",
|
||||
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
|
||||
"features": [
|
||||
{ "type": "Feature", "properties": { "id": 1 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.665827970807854, 45.435017264601314 ], [ -73.665820432116035, 45.436102836222425 ], [ -73.665820432116035, 45.436102836222425 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 2 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.665820432116035, 45.436102836222425 ], [ -73.665820432116035, 45.437203485227165 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 3 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.665820432116035, 45.437203485227165 ], [ -73.665835509499658, 45.438334288999158 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 4 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.665835509499658, 45.438334288999158 ], [ -73.666792923359949, 45.438153360395638 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 5 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.666792923359949, 45.438153360395638 ], [ -73.66676276859269, 45.437226101302606 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 6 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66676276859269, 45.437226101302606 ], [ -73.665820432116035, 45.437203485227165 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 7 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66676276859269, 45.437226101302606 ], [ -73.666770307284509, 45.43677377979381 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 8 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.666770307284509, 45.43677377979381 ], [ -73.667539253849469, 45.43675116371837 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 8 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667539253849469, 45.43675116371837 ], [ -73.66756186992491, 45.436102836222425 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 9 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66756186992491, 45.436102836222425 ], [ -73.665820432116035, 45.436102836222425 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 10 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66756186992491, 45.436102836222425 ], [ -73.667546792541273, 45.435032341984936 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 11 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667546792541273, 45.435032341984936 ], [ -73.665827970807854, 45.435017264601314 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 12 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667546792541273, 45.435032341984936 ], [ -73.66858713201151, 45.435024803293125 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 13 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66858713201151, 45.435024803293125 ], [ -73.669431465494597, 45.435039880676754 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 14 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66858713201151, 45.435024803293125 ], [ -73.668609748086951, 45.436087758838795 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 15 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668609748086951, 45.436087758838795 ], [ -73.668624825470573, 45.437233639994417 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 17 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668624825470573, 45.437233639994417 ], [ -73.669446542878219, 45.437233639994417 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 18 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669446542878219, 45.437233639994417 ], [ -73.669439004186415, 45.436095297530613 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 19 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669439004186415, 45.436095297530613 ], [ -73.668609748086951, 45.436087758838795 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 20 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669439004186415, 45.436095297530613 ], [ -73.669431465494597, 45.435039880676754 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 21 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668624825470573, 45.437233639994417 ], [ -73.667705105069359, 45.437226101302606 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 22 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667705105069359, 45.437226101302606 ], [ -73.66676276859269, 45.437226101302606 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 23 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667705105069359, 45.437226101302606 ], [ -73.667712643761178, 45.437972431792119 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 24 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667712643761178, 45.437972431792119 ], [ -73.666792923359949, 45.438153360395638 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 24 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.667712643761178, 45.437972431792119 ], [ -73.66863990285421, 45.437791503188599 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 26 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66863990285421, 45.437791503188599 ], [ -73.668624825470573, 45.437233639994417 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 27 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.66863990285421, 45.437791503188599 ], [ -73.669454081570038, 45.43764826804415 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 28 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669454081570038, 45.43764826804415 ], [ -73.669446542878219, 45.437233639994417 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 29 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669431465494597, 45.435039880676754 ], [ -73.669386233343715, 45.433622606615856 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 30 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669386233343715, 45.433622606615856 ], [ -73.668700212388714, 45.433652761383108 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 31 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668700212388714, 45.433652761383108 ], [ -73.668685135005092, 45.433909076904762 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 32 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668685135005092, 45.433909076904762 ], [ -73.668700212388714, 45.43406738943284 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 33 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668685135005092, 45.433909076904762 ], [ -73.66839112602436, 45.433893999521132 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 34 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668700212388714, 45.43406738943284 ], [ -73.668127271810903, 45.434429246639873 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 35 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.668700212388714, 45.433652761383108 ], [ -73.6676749503021, 45.433652761383108 ] ] ] } },
|
||||
{ "type": "Feature", "properties": { "id": 35 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -73.669386233343715, 45.433622606615856 ], [ -73.66930330773377, 45.431180070468351 ] ] ] } }
|
||||
]
|
||||
}
|
900
input_files/roads_output.geojson
Normal file
900
input_files/roads_output.geojson
Normal file
|
@ -0,0 +1,900 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"name": "lachine_roadfs",
|
||||
"crs": {
|
||||
"type": "name",
|
||||
"properties": {
|
||||
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
|
||||
}
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65594139216809,
|
||||
45.43892504130949
|
||||
],
|
||||
[
|
||||
-73.65715220401293,
|
||||
45.43822016359244
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65799428420533,
|
||||
45.43987516845119
|
||||
],
|
||||
[
|
||||
-73.65715220401293,
|
||||
45.43822016359244
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65715220401293,
|
||||
45.43822016359244
|
||||
],
|
||||
[
|
||||
-73.6580217247004,
|
||||
45.43767649878391
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6580217247004,
|
||||
45.43767649878391
|
||||
],
|
||||
[
|
||||
-73.65945549056768,
|
||||
45.436925315231434
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65945549056768,
|
||||
45.436925315231434
|
||||
],
|
||||
[
|
||||
-73.65973332558023,
|
||||
45.437405523895116
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65973332558023,
|
||||
45.437405523895116
|
||||
],
|
||||
[
|
||||
-73.6597607660753,
|
||||
45.43955617269603
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65945549056768,
|
||||
45.436925315231434
|
||||
],
|
||||
[
|
||||
-73.66077606439278,
|
||||
45.43661832469285
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66077606439278,
|
||||
45.43661832469285
|
||||
],
|
||||
[
|
||||
-73.66216180939368,
|
||||
45.43631476421617
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66216180939368,
|
||||
45.43631476421617
|
||||
],
|
||||
[
|
||||
-73.66223898578612,
|
||||
45.43707109286148
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66223898578612,
|
||||
45.43707109286148
|
||||
],
|
||||
[
|
||||
-73.66113450585965,
|
||||
45.437331777564616
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66113450585965,
|
||||
45.437331777564616
|
||||
],
|
||||
[
|
||||
-73.6611486548649,
|
||||
45.438600578893194
|
||||
],
|
||||
[
|
||||
-73.66115508623095,
|
||||
45.43917029073414
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66223898578612,
|
||||
45.43707109286148
|
||||
],
|
||||
[
|
||||
-73.66229386677625,
|
||||
45.43858718021396
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66229386677625,
|
||||
45.43858718021396
|
||||
],
|
||||
[
|
||||
-73.6611486548649,
|
||||
45.438600578893194
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66216180939368,
|
||||
45.43631476421617
|
||||
],
|
||||
[
|
||||
-73.66160281649616,
|
||||
45.435697031508866
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66160281649616,
|
||||
45.435697031508866
|
||||
],
|
||||
[
|
||||
-73.66132155142171,
|
||||
45.43540890631066
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66132155142171,
|
||||
45.43540890631066
|
||||
],
|
||||
[
|
||||
-73.66073158077776,
|
||||
45.43475033442904
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66216180939368,
|
||||
45.43631476421617
|
||||
],
|
||||
[
|
||||
-73.66346191003697,
|
||||
45.43590969534564
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66346191003697,
|
||||
45.43590969534564
|
||||
],
|
||||
[
|
||||
-73.66272101667016,
|
||||
45.435203102597654
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66272101667016,
|
||||
45.435203102597654
|
||||
],
|
||||
[
|
||||
-73.66160281649616,
|
||||
45.435697031508866
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66272101667016,
|
||||
45.435203102597654
|
||||
],
|
||||
[
|
||||
-73.66211732577867,
|
||||
45.43452395034473
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66211732577867,
|
||||
45.43452395034473
|
||||
],
|
||||
[
|
||||
-73.66132155142171,
|
||||
45.43540890631066
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66211732577867,
|
||||
45.43452395034473
|
||||
],
|
||||
[
|
||||
-73.66177431959032,
|
||||
45.43418780428016
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66177431959032,
|
||||
45.43418780428016
|
||||
],
|
||||
[
|
||||
-73.66073158077776,
|
||||
45.43475033442904
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66077606439278,
|
||||
45.43661832469285
|
||||
],
|
||||
[
|
||||
-73.66053949731229,
|
||||
45.436314442647884
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66053949731229,
|
||||
45.436314442647884
|
||||
],
|
||||
[
|
||||
-73.66132155142171,
|
||||
45.43540890631066
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66053949731229,
|
||||
45.436314442647884
|
||||
],
|
||||
[
|
||||
-73.65957907998492,
|
||||
45.435306004454155
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.65957907998492,
|
||||
45.435306004454155
|
||||
],
|
||||
[
|
||||
-73.66073158077776,
|
||||
45.43475033442904
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66346191003697,
|
||||
45.43590969534564
|
||||
],
|
||||
[
|
||||
-73.66442232736433,
|
||||
45.435326584825454
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66442232736433,
|
||||
45.435326584825454
|
||||
],
|
||||
[
|
||||
-73.66471731268632,
|
||||
45.43508648049362
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66471731268632,
|
||||
45.43508648049362
|
||||
],
|
||||
[
|
||||
-73.66579435211771,
|
||||
45.43442104848823
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66272101667016,
|
||||
45.435203102597654
|
||||
],
|
||||
[
|
||||
-73.66391467820559,
|
||||
45.43443476873576
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66391467820559,
|
||||
45.43443476873576
|
||||
],
|
||||
[
|
||||
-73.66471731268632,
|
||||
45.43508648049362
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66442232736433,
|
||||
45.435326584825454
|
||||
],
|
||||
[
|
||||
-73.66444976785941,
|
||||
45.43599887695461
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66444976785941,
|
||||
45.43599887695461
|
||||
],
|
||||
[
|
||||
-73.66444976785941,
|
||||
45.43695929428197
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66444976785941,
|
||||
45.43695929428197
|
||||
],
|
||||
[
|
||||
-73.66575319137512,
|
||||
45.437000455024574
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66444976785941,
|
||||
45.43599887695461
|
||||
],
|
||||
[
|
||||
-73.66576691162264,
|
||||
45.436005737078375
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66391467820559,
|
||||
45.43443476873576
|
||||
],
|
||||
[
|
||||
-73.66305030261097,
|
||||
45.43377619685415
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66305030261097,
|
||||
45.43377619685415
|
||||
],
|
||||
[
|
||||
-73.66211732577867,
|
||||
45.43452395034473
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66391467820559,
|
||||
45.43443476873576
|
||||
],
|
||||
[
|
||||
-73.6651357802361,
|
||||
45.43365271462634
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6651357802361,
|
||||
45.43365271462634
|
||||
],
|
||||
[
|
||||
-73.66387351746299,
|
||||
45.43332342868553
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66387351746299,
|
||||
45.43332342868553
|
||||
],
|
||||
[
|
||||
-73.66305030261097,
|
||||
45.43377619685415
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6651357802361,
|
||||
45.43365271462634
|
||||
],
|
||||
[
|
||||
-73.66565714964237,
|
||||
45.43398886069092
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66565714964237,
|
||||
45.43398886069092
|
||||
],
|
||||
[
|
||||
-73.66579435211771,
|
||||
45.43442104848823
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66579435211771,
|
||||
45.43442104848823
|
||||
],
|
||||
[
|
||||
-73.66576691162264,
|
||||
45.436005737078375
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66576691162264,
|
||||
45.436005737078375
|
||||
],
|
||||
[
|
||||
-73.66575319137512,
|
||||
45.437000455024574
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66387351746299,
|
||||
45.43332342868553
|
||||
],
|
||||
[
|
||||
-73.66611677793476,
|
||||
45.43254823469987
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66611677793476,
|
||||
45.43254823469987
|
||||
],
|
||||
[
|
||||
-73.66736532046032,
|
||||
45.43350179190347
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.66736532046032,
|
||||
45.43350179190347
|
||||
],
|
||||
[
|
||||
-73.66579435211771,
|
||||
45.43442104848823
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6651357802361,
|
||||
45.43365271462634
|
||||
],
|
||||
[
|
||||
-73.6657120306325,
|
||||
45.43328226794293
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6657120306325,
|
||||
45.43328226794293
|
||||
],
|
||||
[
|
||||
-73.6667307590119,
|
||||
45.43303530348731
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6667307590119,
|
||||
45.43303530348731
|
||||
],
|
||||
[
|
||||
-73.66611677793476,
|
||||
45.43254823469987
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
-73.6667307590119,
|
||||
45.43303530348731
|
||||
],
|
||||
[
|
||||
-73.66736532046032,
|
||||
45.43350179190347
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
],
|
||||
[
|
||||
-73.57962787855432,
|
||||
45.496524875557746
|
||||
],
|
||||
[
|
||||
-73.57996357265695,
|
||||
45.49668114195629
|
||||
],
|
||||
[
|
||||
-73.57996427397713,
|
||||
45.496680342403664
|
||||
],
|
||||
[
|
||||
-73.58034707390021,
|
||||
45.49625804233725
|
||||
],
|
||||
[
|
||||
-73.58034697395713,
|
||||
45.496257942524835
|
||||
],
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
"id": 179764,
|
||||
"properties": {
|
||||
"name": "01119274",
|
||||
"address": "rue Guy (MTL) 2157",
|
||||
"function": "Mixed use",
|
||||
"mixed_type_1": "commercial",
|
||||
"mixed_type_1_percentage": 50,
|
||||
"mixed_type_2": "6000",
|
||||
"mixed_type_2_percentage": 50,
|
||||
"height": 62,
|
||||
"year_of_construction": 1954
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
],
|
||||
[
|
||||
-73.57962787855432,
|
||||
45.496524875557746
|
||||
],
|
||||
[
|
||||
-73.57996357265695,
|
||||
45.49668114195629
|
||||
],
|
||||
[
|
||||
-73.57996427397713,
|
||||
45.496680342403664
|
||||
],
|
||||
[
|
||||
-73.58034707390021,
|
||||
45.49625804233725
|
||||
],
|
||||
[
|
||||
-73.58034697395713,
|
||||
45.496257942524835
|
||||
],
|
||||
[
|
||||
-73.58000127109773,
|
||||
45.49613461675315
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
"id": 179764,
|
||||
"properties": {
|
||||
"name": "01119274",
|
||||
"address": "rue Guy (MTL) 2157",
|
||||
"function": "Mixed use",
|
||||
"usages": [{"usage": "commercial", "percentage": 50}, {"usage": "6000", "percentage": 50}],
|
||||
"height": 62,
|
||||
"year_of_construction": 1954
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
64
main.py
64
main.py
|
@ -1,4 +1,5 @@
|
|||
from pathlib import Path
|
||||
from scripts.district_heating_network.directory_manager import DirectoryManager
|
||||
import subprocess
|
||||
from scripts.ep_run_enrich import energy_plus_workflow
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
|
@ -6,47 +7,46 @@ from hub.helpers.dictionaries import Dictionaries
|
|||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport
|
||||
from scripts.geojson_creator import process_geojson
|
||||
from scripts import random_assignation
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing import SystemSizing
|
||||
from scripts.solar_angles import CitySolarAngles
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
from scripts.energy_system_retrofit_results import consumption_data, cost_data
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.costs.cost import Cost
|
||||
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS
|
||||
from scripts.district_heating_network.road_processor import road_processor
|
||||
from scripts.district_heating_network.district_heating_network_creator import DistrictHeatingNetworkCreator
|
||||
from scripts.district_heating_network.geojson_graph_creator import networkx_to_geojson
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_feasibility import pv_feasibility
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
# Specify the GeoJSON file path
|
||||
data = {}
|
||||
input_files_path = (Path(__file__).parent / 'input_files')
|
||||
input_files_path.mkdir(parents=True, exist_ok=True)
|
||||
# geojson_file = process_geojson(x=-73.58001358793511, y=45.496445294438715, diff=0.0001)
|
||||
geojson_file_path = input_files_path / 'test_geojson1.geojson'
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
energy_plus_output_path = output_path / 'energy_plus_outputs'
|
||||
energy_plus_output_path.mkdir(parents=True, exist_ok=True)
|
||||
simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_results').resolve()
|
||||
simulation_results_path.mkdir(parents=True, exist_ok=True)
|
||||
sra_output_path = output_path / 'sra_outputs'
|
||||
sra_output_path.mkdir(parents=True, exist_ok=True)
|
||||
cost_analysis_output_path = output_path / 'cost_analysis'
|
||||
cost_analysis_output_path.mkdir(parents=True, exist_ok=True)
|
||||
from scripts.district_heating_network.district_heating_network_creator import DistrictHeatingNetworkCreator
|
||||
from scripts.district_heating_network.road_processor import road_processor
|
||||
from scripts.district_heating_network.district_heating_factory import DistrictHeatingFactory
|
||||
|
||||
base_path = Path(__file__).parent
|
||||
dir_manager = DirectoryManager(base_path)
|
||||
|
||||
# Input files directory
|
||||
input_files_path = dir_manager.create_directory('input_files')
|
||||
geojson_file_path = input_files_path / 'output_buildings.geojson'
|
||||
|
||||
# Output files directory
|
||||
output_path = dir_manager.create_directory('out_files')
|
||||
|
||||
# Subdirectories for output files
|
||||
energy_plus_output_path = dir_manager.create_directory('out_files/energy_plus_outputs')
|
||||
simulation_results_path = dir_manager.create_directory('out_files/simulation_results')
|
||||
sra_output_path = dir_manager.create_directory('out_files/sra_outputs')
|
||||
cost_analysis_output_path = dir_manager.create_directory('out_files/cost_analysis')
|
||||
|
||||
# Select city area
|
||||
location = [45.53067276979674, -73.70234652694087]
|
||||
process_geojson(x=location[1], y=location[0], diff=0.001)
|
||||
|
||||
# Create city object
|
||||
city = GeometryFactory(file_type='geojson',
|
||||
path=geojson_file_path,
|
||||
height_field='height',
|
||||
year_of_construction_field='year_of_construction',
|
||||
function_field='function',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
# ConstructionFactory('nrcan', city).enrich()
|
||||
# UsageFactory('nrcan', city).enrich()
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
# WeatherFactory('epw', city).enrich()
|
||||
# energy_plus_workflow(city, energy_plus_output_path)
|
||||
# data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9
|
||||
|
@ -83,4 +83,4 @@ city = GeometryFactory(file_type='geojson',
|
|||
# # Save the plot
|
||||
# plt.savefig('plot_nrcan.png', bbox_inches='tight')
|
||||
# plt.close()
|
||||
print('test')
|
||||
print('test')
|
||||
|
|
|
@ -14,7 +14,7 @@ import hub.helpers.constants as cte
|
|||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
# Specify the GeoJSON file path
|
||||
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0005)
|
||||
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
|
||||
file_path = (Path(__file__).parent / 'input_files' / 'output_buildings.geojson')
|
||||
# Specify the output path for the PDF file
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
|
@ -34,7 +34,7 @@ ExportsFactory('sra', city, output_path).export()
|
|||
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
|
||||
subprocess.run(['sra', str(sra_path)])
|
||||
ResultFactory('sra', city, output_path).enrich()
|
||||
energy_plus_workflow(city)
|
||||
energy_plus_workflow(city, output_path=output_path)
|
||||
solar_angles = CitySolarAngles(city.name,
|
||||
city.latitude,
|
||||
city.longitude,
|
||||
|
|
16
scripts/district_heating_network/directory_manager.py
Normal file
16
scripts/district_heating_network/directory_manager.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from pathlib import Path
|
||||
|
||||
|
||||
class DirectoryManager:
|
||||
def __init__(self, base_path):
|
||||
self.base_path = Path(base_path)
|
||||
self.directories = {}
|
||||
|
||||
def create_directory(self, relative_path):
|
||||
full_path = self.base_path / relative_path
|
||||
full_path.mkdir(parents=True, exist_ok=True)
|
||||
self.directories[relative_path] = full_path
|
||||
return full_path
|
||||
|
||||
def get_directory(self, relative_path):
|
||||
return self.directories.get(relative_path, None)
|
248
scripts/district_heating_network/district_heating_factory.py
Normal file
248
scripts/district_heating_network/district_heating_factory.py
Normal file
|
@ -0,0 +1,248 @@
|
|||
import CoolProp.CoolProp as CP
|
||||
import math
|
||||
import logging
|
||||
import numpy as np
|
||||
import csv
|
||||
|
||||
|
||||
class DistrictHeatingFactory:
|
||||
"""
|
||||
DistrictHeatingFactory class
|
||||
|
||||
This class is responsible for managing the district heating network, including
|
||||
enriching the network graph with building data, calculating flow rates,
|
||||
sizing pipes, and analyzing costs.
|
||||
"""
|
||||
|
||||
def __init__(self, city, graph, supply_temperature, return_temperature, simultaneity_factor):
|
||||
"""
|
||||
Initialize the DistrictHeatingFactory object.
|
||||
|
||||
:param city: The city object containing buildings and their heating demands.
|
||||
:param graph: The network graph representing the district heating network.
|
||||
:param supply_temperature: The supply temperature of the heating fluid in the network (°C).
|
||||
:param return_temperature: The return temperature of the heating fluid in the network (°C).
|
||||
:param simultaneity_factor: The simultaneity factor used to adjust flow rates for non-building pipes.
|
||||
"""
|
||||
self._city = city
|
||||
self._network_graph = graph
|
||||
self._supply_temperature = supply_temperature
|
||||
self._return_temperature = return_temperature
|
||||
self.simultaneity_factor = simultaneity_factor
|
||||
self.fluid = "Water" # The fluid used in the heating network
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
Enrich the network graph nodes with the whole building object from the city buildings.
|
||||
|
||||
This method associates each building node in the network graph with its corresponding
|
||||
building object from the city, allowing access to heating demand data during calculations.
|
||||
"""
|
||||
for node_id, node_attrs in self._network_graph.nodes(data=True):
|
||||
if node_attrs.get('type') == 'building':
|
||||
building_name = node_attrs.get('name')
|
||||
building_found = False
|
||||
for building in self._city.buildings:
|
||||
if building.name == building_name:
|
||||
self._network_graph.nodes[node_id]['building_obj'] = building
|
||||
building_found = True
|
||||
break
|
||||
if not building_found:
|
||||
logging.error(msg=f"Building with name '{building_name}' not found in city.")
|
||||
|
||||
def calculate_flow_rates(self, A, Gext):
|
||||
"""
|
||||
Solve the linear system to find the flow rates in each branch.
|
||||
|
||||
:param A: The incidence matrix representing the network connections.
|
||||
:param Gext: The external flow rates for each node in the network.
|
||||
:return: The calculated flow rates for each edge, or None if an error occurs.
|
||||
"""
|
||||
try:
|
||||
G = np.linalg.lstsq(A, Gext, rcond=None)[0]
|
||||
return G
|
||||
except np.linalg.LinAlgError as e:
|
||||
logging.error(f"Error solving the linear system: {e}")
|
||||
return None
|
||||
|
||||
def switch_nodes(self, A, edge_index, node_index, edge):
|
||||
"""
|
||||
Switch the in and out nodes for the given edge in the incidence matrix A.
|
||||
|
||||
:param A: The incidence matrix representing the network connections.
|
||||
:param edge_index: The index of edges in the incidence matrix.
|
||||
:param node_index: The index of nodes in the incidence matrix.
|
||||
:param edge: The edge (u, v) to switch.
|
||||
"""
|
||||
u, v = edge
|
||||
i = node_index[u]
|
||||
j = node_index[v]
|
||||
k = edge_index[edge]
|
||||
A[i, k], A[j, k] = -A[i, k], -A[j, k]
|
||||
|
||||
def sizing(self):
|
||||
"""
|
||||
Calculate the hourly mass flow rates, assign them to the edges, and determine the pipe diameters.
|
||||
|
||||
This method generates the flow rates for each hour, adjusting the incidence matrix as needed to
|
||||
ensure all flow rates are positive. It also applies the simultaneity factor to non-building pipes.
|
||||
"""
|
||||
num_nodes = self._network_graph.number_of_nodes()
|
||||
num_edges = self._network_graph.number_of_edges()
|
||||
A = np.zeros((num_nodes, num_edges)) # Initialize incidence matrix
|
||||
node_index = {node: i for i, node in enumerate(self._network_graph.nodes())}
|
||||
edge_index = {edge: i for i, edge in enumerate(self._network_graph.edges())}
|
||||
|
||||
# Initialize mass flow rate attribute for each edge
|
||||
for u, v, data in self._network_graph.edges(data=True):
|
||||
self._network_graph.edges[u, v]['mass_flow_rate'] = {"hour": [], "peak": None}
|
||||
|
||||
# Get the length of the hourly demand for the first building (assuming all buildings have the same length)
|
||||
building = next(iter(self._city.buildings))
|
||||
num_hours = len(building.heating_demand['hour'])
|
||||
|
||||
# Loop through each hour to generate Gext and solve AG = Gext
|
||||
for hour in range(8760):
|
||||
Gext = np.zeros(num_nodes)
|
||||
|
||||
# Calculate the hourly mass flow rates for each edge and fill Gext
|
||||
for edge in self._network_graph.edges(data=True):
|
||||
u, v, data = edge
|
||||
for node in [u, v]:
|
||||
if self._network_graph.nodes[node].get('type') == 'building':
|
||||
building = self._network_graph.nodes[node].get('building_obj')
|
||||
if building and "hour" in building.heating_demand:
|
||||
hourly_demand = building.heating_demand["hour"][hour] # Get demand for current hour
|
||||
specific_heat_capacity = CP.PropsSI('C', 'T', (self._supply_temperature + self._return_temperature) / 2,
|
||||
'P', 101325, self.fluid)
|
||||
mass_flow_rate = hourly_demand / 3600 / (
|
||||
specific_heat_capacity * (self._supply_temperature - self._return_temperature))
|
||||
Gext[node_index[node]] += mass_flow_rate
|
||||
|
||||
# Update incidence matrix A
|
||||
i = node_index[u]
|
||||
j = node_index[v]
|
||||
k = edge_index[(u, v)]
|
||||
A[i, k] = 1
|
||||
A[j, k] = -1
|
||||
|
||||
# Solve for G (flow rates)
|
||||
G = self.calculate_flow_rates(A, Gext)
|
||||
if G is None:
|
||||
return
|
||||
|
||||
# Check for negative flow rates and adjust A accordingly
|
||||
iterations = 0
|
||||
max_iterations = num_edges * 2
|
||||
while any(flow_rate < 0 for flow_rate in G) and iterations < max_iterations:
|
||||
for idx, flow_rate in enumerate(G):
|
||||
if flow_rate < 0:
|
||||
G[idx] = -G[idx] # Invert the sign directly
|
||||
iterations += 1
|
||||
|
||||
# Store the final flow rates in the edges for this hour
|
||||
for idx, (edge, flow_rate) in enumerate(zip(self._network_graph.edges(), G)):
|
||||
u, v = edge
|
||||
if not (self._network_graph.nodes[u].get('type') == 'building' or self._network_graph.nodes[v].get(
|
||||
'type') == 'building'):
|
||||
flow_rate *= self.simultaneity_factor # Apply simultaneity factor for non-building pipes
|
||||
data = self._network_graph.edges[u, v]
|
||||
data['mass_flow_rate']["hour"].append(flow_rate) # Append the calculated flow rate
|
||||
|
||||
# Calculate the peak flow rate for each edge
|
||||
for u, v, data in self._network_graph.edges(data=True):
|
||||
data['mass_flow_rate']['peak'] = max(data['mass_flow_rate']['hour'])
|
||||
|
||||
def calculate_diameters_and_costs(self, pipe_data):
|
||||
"""
|
||||
Calculate the diameter and costs of the pipes based on the maximum flow rate in each edge.
|
||||
|
||||
:param pipe_data: A list of dictionaries containing pipe specifications, including inner diameters
|
||||
and costs per meter for different nominal diameters (DN).
|
||||
"""
|
||||
for u, v, data in self._network_graph.edges(data=True):
|
||||
flow_rate = data.get('mass_flow_rate', {}).get('peak')
|
||||
if flow_rate is not None:
|
||||
try:
|
||||
# Calculate the density of the fluid
|
||||
density = CP.PropsSI('D', 'T', (self._supply_temperature + self._return_temperature) / 2, 'P', 101325,
|
||||
self.fluid)
|
||||
velocity = 0.9 # Desired fluid velocity in m/s
|
||||
# Calculate the diameter of the pipe required for the given flow rate
|
||||
diameter = math.sqrt((4 * abs(flow_rate)) / (density * velocity * math.pi)) * 1000 # Convert to mm
|
||||
self._network_graph.edges[u, v]['diameter'] = diameter
|
||||
|
||||
# Match to the closest nominal diameter from the pipe data
|
||||
closest_pipe = self.match_nominal_diameter(diameter, pipe_data)
|
||||
self._network_graph.edges[u, v]['nominal_diameter'] = closest_pipe['DN']
|
||||
self._network_graph.edges[u, v]['cost_per_meter'] = closest_pipe['cost_per_meter']
|
||||
except Exception as e:
|
||||
logging.error(f"Error calculating diameter or matching nominal diameter for edge ({u}, {v}): {e}")
|
||||
|
||||
def match_nominal_diameter(self, diameter, pipe_data):
|
||||
"""
|
||||
Match the calculated diameter to the closest nominal diameter.
|
||||
|
||||
:param diameter: The calculated diameter of the pipe (in mm).
|
||||
:param pipe_data: A list of dictionaries containing pipe specifications, including inner diameters
|
||||
and costs per meter for different nominal diameters (DN).
|
||||
:return: The dictionary representing the pipe with the closest nominal diameter.
|
||||
"""
|
||||
closest_pipe = min(pipe_data, key=lambda x: abs(x['inner_diameter'] - diameter))
|
||||
return closest_pipe
|
||||
|
||||
def analyze_costs(self):
|
||||
"""
|
||||
Analyze the costs based on the nominal diameters of the pipes.
|
||||
|
||||
This method calculates the total cost of piping for each nominal diameter group
|
||||
and returns a summary of the grouped pipes and the total cost.
|
||||
|
||||
:return: A tuple containing the grouped pipe data and the total cost of piping.
|
||||
"""
|
||||
pipe_groups = {}
|
||||
total_cost = 0 # Initialize total cost
|
||||
|
||||
for u, v, data in self._network_graph.edges(data=True):
|
||||
dn = data.get('nominal_diameter')
|
||||
if dn is not None:
|
||||
pipe_length = self._network_graph.edges[u, v].get('length', 1) * 2 # Multiply by 2 for supply and return
|
||||
cost_per_meter = data.get('cost_per_meter', 0)
|
||||
|
||||
if dn not in pipe_groups:
|
||||
pipe_groups[dn] = {
|
||||
'DN': dn,
|
||||
'total_length': 0,
|
||||
'cost_per_meter': cost_per_meter
|
||||
}
|
||||
pipe_groups[dn]['total_length'] += pipe_length
|
||||
group_cost = pipe_length * cost_per_meter
|
||||
total_cost += group_cost # Add to total cost
|
||||
|
||||
# Calculate total cost for each group
|
||||
for group in pipe_groups.values():
|
||||
group['total_cost'] = group['total_length'] * group['cost_per_meter']
|
||||
|
||||
return pipe_groups, total_cost # Return both the grouped data and total cost
|
||||
|
||||
def save_pipe_groups_to_csv(self, filename):
|
||||
"""
|
||||
Save the pipe groups and their total lengths to a CSV file.
|
||||
|
||||
:param filename: The name of the CSV file to save the data to.
|
||||
"""
|
||||
pipe_groups, _ = self.analyze_costs()
|
||||
|
||||
with open(filename, mode='w', newline='') as file:
|
||||
writer = csv.writer(file)
|
||||
# Write the header
|
||||
writer.writerow(["Nominal Diameter (DN)", "Total Length (m)", "Cost per Meter", "Total Cost"])
|
||||
|
||||
# Write the data for each pipe group
|
||||
for group in pipe_groups.values():
|
||||
writer.writerow([
|
||||
group['DN'],
|
||||
group['total_length'],
|
||||
group['cost_per_meter'],
|
||||
group['total_cost']
|
||||
])
|
|
@ -0,0 +1,372 @@
|
|||
import json
|
||||
import math
|
||||
import logging
|
||||
import matplotlib.pyplot as plt
|
||||
import networkx as nx
|
||||
from shapely.geometry import Polygon, Point, LineString
|
||||
from typing import List, Tuple
|
||||
from rtree import index
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
logging.getLogger("numexpr").setLevel(logging.ERROR)
|
||||
|
||||
def haversine(lon1, lat1, lon2, lat2):
|
||||
"""
|
||||
Calculate the great-circle distance between two points
|
||||
on the Earth specified by their longitude and latitude.
|
||||
"""
|
||||
R = 6371000 # Radius of the Earth in meters
|
||||
phi1 = math.radians(lat1)
|
||||
phi2 = math.radians(lat2)
|
||||
delta_phi = math.radians(lat2 - lat1)
|
||||
delta_lambda = math.radians(lon2 - lon1)
|
||||
|
||||
a = math.sin(delta_phi / 2.0) ** 2 + \
|
||||
math.cos(phi1) * math.cos(phi2) * \
|
||||
math.sin(delta_lambda / 2.0) ** 2
|
||||
|
||||
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
|
||||
return R * c # Output distance in meters
|
||||
|
||||
class DistrictHeatingNetworkCreator:
|
||||
def __init__(self, buildings_file: str, roads_file: str, central_plant_locations: List[Tuple[float, float]]):
|
||||
"""
|
||||
Initialize the class with paths to the buildings and roads data files, and central plant locations.
|
||||
|
||||
:param buildings_file: Path to the GeoJSON file containing building data.
|
||||
:param roads_file: Path to the GeoJSON file containing roads data.
|
||||
:param central_plant_locations: List of tuples containing the coordinates of central plant locations.
|
||||
"""
|
||||
if len(central_plant_locations) < 1:
|
||||
raise ValueError("The list of central plant locations must have at least one member.")
|
||||
|
||||
self.buildings_file = buildings_file
|
||||
self.roads_file = roads_file
|
||||
self.central_plant_locations = central_plant_locations
|
||||
|
||||
def run(self) -> nx.Graph:
|
||||
"""
|
||||
Main method to execute the district heating network creation process.
|
||||
:return: NetworkX graph with nodes and edges representing the network.
|
||||
"""
|
||||
try:
|
||||
self._load_and_process_data()
|
||||
self._find_nearest_roads()
|
||||
self._find_nearest_points()
|
||||
self._break_down_roads()
|
||||
self._create_graph()
|
||||
self._create_mst()
|
||||
self._iteratively_remove_edges()
|
||||
self._add_centroids_to_mst()
|
||||
self._convert_edge_weights_to_meters()
|
||||
self._create_final_network_graph()
|
||||
return self.network_graph
|
||||
except Exception as e:
|
||||
logging.error(f"Error during network creation: {e}")
|
||||
raise
|
||||
|
||||
def _load_and_process_data(self):
|
||||
"""
|
||||
Load and process the building and road data.
|
||||
"""
|
||||
try:
|
||||
# Load building data
|
||||
with open(self.buildings_file, 'r') as file:
|
||||
city = json.load(file)
|
||||
|
||||
self.centroids = []
|
||||
self.building_names = []
|
||||
self.building_positions = []
|
||||
buildings = city['features']
|
||||
for building in buildings:
|
||||
coordinates = building['geometry']['coordinates'][0]
|
||||
building_polygon = Polygon(coordinates)
|
||||
centroid = building_polygon.centroid
|
||||
self.centroids.append(centroid)
|
||||
self.building_names.append(str(building['id']))
|
||||
self.building_positions.append((centroid.x, centroid.y))
|
||||
|
||||
# Add central plant locations as centroids
|
||||
for i, loc in enumerate(self.central_plant_locations, start=1):
|
||||
centroid = Point(loc)
|
||||
self.centroids.append(centroid)
|
||||
self.building_names.append(f'central_plant_{i}')
|
||||
self.building_positions.append((centroid.x, centroid.y))
|
||||
|
||||
# Load road data
|
||||
with open(self.roads_file, 'r') as file:
|
||||
roads = json.load(file)
|
||||
|
||||
line_features = [feature for feature in roads['features'] if feature['geometry']['type'] == 'LineString']
|
||||
|
||||
self.lines = [LineString(feature['geometry']['coordinates']) for feature in line_features]
|
||||
self.cleaned_lines = [LineString([line.coords[0], line.coords[-1]]) for line in self.lines]
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading and processing data: {e}")
|
||||
raise
|
||||
|
||||
def _find_nearest_roads(self):
|
||||
"""
|
||||
Find the nearest road for each building centroid.
|
||||
"""
|
||||
try:
|
||||
self.closest_roads = []
|
||||
unique_roads_set = set()
|
||||
|
||||
# Create spatial index for roads
|
||||
idx = index.Index()
|
||||
for pos, line in enumerate(self.cleaned_lines):
|
||||
idx.insert(pos, line.bounds)
|
||||
|
||||
for centroid in self.centroids:
|
||||
min_distance = float('inf')
|
||||
closest_road = None
|
||||
for pos in idx.nearest(centroid.bounds, 10):
|
||||
road = self.cleaned_lines[pos]
|
||||
distance = road.distance(centroid)
|
||||
if distance < min_distance:
|
||||
min_distance = distance
|
||||
closest_road = road
|
||||
|
||||
if closest_road and closest_road.wkt not in unique_roads_set:
|
||||
unique_roads_set.add(closest_road.wkt)
|
||||
self.closest_roads.append(closest_road)
|
||||
except Exception as e:
|
||||
logging.error(f"Error finding nearest roads: {e}")
|
||||
raise
|
||||
|
||||
def _find_nearest_points(self):
|
||||
"""
|
||||
Find the nearest point on each closest road for each centroid.
|
||||
"""
|
||||
|
||||
def find_nearest_point_on_line(point: Point, line: LineString) -> Point:
|
||||
return line.interpolate(line.project(point))
|
||||
|
||||
try:
|
||||
self.nearest_points = []
|
||||
for centroid in self.centroids:
|
||||
min_distance = float('inf')
|
||||
closest_road = None
|
||||
for road in self.closest_roads:
|
||||
distance = centroid.distance(road)
|
||||
if distance < min_distance:
|
||||
min_distance = distance
|
||||
closest_road = road
|
||||
|
||||
if closest_road:
|
||||
nearest_point = find_nearest_point_on_line(centroid, closest_road)
|
||||
self.nearest_points.append(nearest_point)
|
||||
except Exception as e:
|
||||
logging.error(f"Error finding nearest points: {e}")
|
||||
raise
|
||||
|
||||
def _break_down_roads(self):
|
||||
"""
|
||||
Break down roads into segments connecting nearest points.
|
||||
"""
|
||||
|
||||
def break_down_roads(closest_roads: List[LineString], nearest_points_list: List[Point]) -> List[LineString]:
|
||||
new_segments = []
|
||||
for road in closest_roads:
|
||||
coords = list(road.coords)
|
||||
points_on_road = [point for point in nearest_points_list if road.distance(point) < 0.000000001]
|
||||
sorted_points = sorted(points_on_road, key=lambda point: road.project(point))
|
||||
sorted_points.insert(0, Point(coords[0]))
|
||||
sorted_points.append(Point(coords[-1]))
|
||||
for i in range(len(sorted_points) - 1):
|
||||
segment = LineString([sorted_points[i], sorted_points[i + 1]])
|
||||
new_segments.append(segment)
|
||||
return new_segments
|
||||
|
||||
try:
|
||||
self.new_segments = break_down_roads(self.closest_roads, self.nearest_points)
|
||||
self.cleaned_lines = [line for line in self.cleaned_lines if line not in self.closest_roads]
|
||||
self.cleaned_lines.extend(self.new_segments)
|
||||
except Exception as e:
|
||||
logging.error(f"Error breaking down roads: {e}")
|
||||
raise
|
||||
|
||||
def _create_graph(self):
|
||||
"""
|
||||
Create a NetworkX graph from the cleaned lines.
|
||||
"""
|
||||
try:
|
||||
self.G = nx.Graph()
|
||||
for line in self.cleaned_lines:
|
||||
coords = list(line.coords)
|
||||
for i in range(len(coords) - 1):
|
||||
u = coords[i]
|
||||
v = coords[i + 1]
|
||||
self.G.add_edge(u, v, weight=Point(coords[i]).distance(Point(coords[i + 1])))
|
||||
except Exception as e:
|
||||
logging.error(f"Error creating graph: {e}")
|
||||
raise
|
||||
|
||||
def _create_mst(self):
|
||||
"""
|
||||
Create a Minimum Spanning Tree (MST) from the graph.
|
||||
"""
|
||||
|
||||
def find_paths_between_nearest_points(g: nx.Graph, nearest_points: List[Point]) -> List[Tuple]:
|
||||
edges = []
|
||||
for i, start_point in enumerate(nearest_points):
|
||||
start = (start_point.x, start_point.y)
|
||||
for end_point in nearest_points[i + 1:]:
|
||||
end = (end_point.x, end_point.y)
|
||||
if nx.has_path(g, start, end):
|
||||
path = nx.shortest_path(g, source=start, target=end, weight='weight')
|
||||
path_edges = list(zip(path[:-1], path[1:]))
|
||||
edges.extend((u, v, g[u][v]['weight']) for u, v in path_edges)
|
||||
return edges
|
||||
|
||||
try:
|
||||
edges = find_paths_between_nearest_points(self.G, self.nearest_points)
|
||||
h = nx.Graph()
|
||||
h.add_weighted_edges_from(edges)
|
||||
mst = nx.minimum_spanning_tree(h, weight='weight')
|
||||
final_edges = []
|
||||
for u, v in mst.edges():
|
||||
if nx.has_path(self.G, u, v):
|
||||
path = nx.shortest_path(self.G, source=u, target=v, weight='weight')
|
||||
path_edges = list(zip(path[:-1], path[1:]))
|
||||
final_edges.extend((x, y, self.G[x][y]['weight']) for x, y in path_edges)
|
||||
self.final_mst = nx.Graph()
|
||||
self.final_mst.add_weighted_edges_from(final_edges)
|
||||
except Exception as e:
|
||||
logging.error(f"Error creating MST: {e}")
|
||||
raise
|
||||
|
||||
def _iteratively_remove_edges(self):
|
||||
"""
|
||||
Iteratively remove edges that do not have any nearest points and have one end with only one connection.
|
||||
Also remove nodes that don't have any connections and street nodes with only one connection.
|
||||
"""
|
||||
nearest_points_tuples = [(point.x, point.y) for point in self.nearest_points]
|
||||
|
||||
def find_edges_to_remove(graph: nx.Graph) -> List[Tuple]:
|
||||
edges_to_remove = []
|
||||
for u, v, d in graph.edges(data=True):
|
||||
if u not in nearest_points_tuples and v not in nearest_points_tuples:
|
||||
if graph.degree(u) == 1 or graph.degree(v) == 1:
|
||||
edges_to_remove.append((u, v, d))
|
||||
return edges_to_remove
|
||||
|
||||
def find_nodes_to_remove(graph: nx.Graph) -> List[Tuple]:
|
||||
nodes_to_remove = []
|
||||
for node in graph.nodes():
|
||||
if graph.degree(node) == 0:
|
||||
nodes_to_remove.append(node)
|
||||
return nodes_to_remove
|
||||
|
||||
try:
|
||||
edges_to_remove = find_edges_to_remove(self.final_mst)
|
||||
self.final_mst_steps = [list(self.final_mst.edges(data=True))]
|
||||
|
||||
while edges_to_remove or find_nodes_to_remove(self.final_mst):
|
||||
self.final_mst.remove_edges_from(edges_to_remove)
|
||||
nodes_to_remove = find_nodes_to_remove(self.final_mst)
|
||||
self.final_mst.remove_nodes_from(nodes_to_remove)
|
||||
edges_to_remove = find_edges_to_remove(self.final_mst)
|
||||
self.final_mst_steps.append(list(self.final_mst.edges(data=True)))
|
||||
|
||||
def find_single_connection_street_nodes(graph: nx.Graph) -> List[Tuple]:
|
||||
single_connection_street_nodes = []
|
||||
for node in graph.nodes():
|
||||
if node not in nearest_points_tuples and graph.degree(node) == 1:
|
||||
single_connection_street_nodes.append(node)
|
||||
return single_connection_street_nodes
|
||||
|
||||
single_connection_street_nodes = find_single_connection_street_nodes(self.final_mst)
|
||||
|
||||
while single_connection_street_nodes:
|
||||
for node in single_connection_street_nodes:
|
||||
neighbors = list(self.final_mst.neighbors(node))
|
||||
self.final_mst.remove_node(node)
|
||||
for neighbor in neighbors:
|
||||
if self.final_mst.degree(neighbor) == 0:
|
||||
self.final_mst.remove_node(neighbor)
|
||||
single_connection_street_nodes = find_single_connection_street_nodes(self.final_mst)
|
||||
self.final_mst_steps.append(list(self.final_mst.edges(data=True)))
|
||||
except Exception as e:
|
||||
logging.error(f"Error iteratively removing edges: {e}")
|
||||
raise
|
||||
|
||||
def _add_centroids_to_mst(self):
|
||||
"""
|
||||
Add centroids to the final MST graph and connect them to their associated node on the graph.
|
||||
"""
|
||||
try:
|
||||
for i, centroid in enumerate(self.centroids):
|
||||
building_name = self.building_names[i]
|
||||
pos = (centroid.x, centroid.y)
|
||||
node_type = 'building' if 'central_plant' not in building_name else 'generation'
|
||||
self.final_mst.add_node(pos, type=node_type, name=building_name, pos=pos)
|
||||
|
||||
nearest_point = None
|
||||
min_distance = float('inf')
|
||||
for node in self.final_mst.nodes():
|
||||
if self.final_mst.nodes[node].get('type') != 'building' and self.final_mst.nodes[node].get('type') != 'generation':
|
||||
distance = centroid.distance(Point(node))
|
||||
if distance < min_distance:
|
||||
min_distance = distance
|
||||
nearest_point = node
|
||||
|
||||
if nearest_point:
|
||||
self.final_mst.add_edge(pos, nearest_point, weight=min_distance)
|
||||
except Exception as e:
|
||||
logging.error(f"Error adding centroids to MST: {e}")
|
||||
raise
|
||||
|
||||
def _convert_edge_weights_to_meters(self):
|
||||
"""
|
||||
Convert all edge weights in the final MST graph to meters using the Haversine formula.
|
||||
"""
|
||||
try:
|
||||
for u, v, data in self.final_mst.edges(data=True):
|
||||
distance = haversine(u[0], u[1], v[0], v[1])
|
||||
self.final_mst[u][v]['weight'] = distance
|
||||
except Exception as e:
|
||||
logging.error(f"Error converting edge weights to meters: {e}")
|
||||
raise
|
||||
|
||||
def _create_final_network_graph(self):
|
||||
"""
|
||||
Create the final network graph with the required attributes from the final MST.
|
||||
"""
|
||||
self.network_graph = nx.Graph()
|
||||
node_id = 1
|
||||
node_mapping = {}
|
||||
for node in self.final_mst.nodes:
|
||||
pos = node
|
||||
if 'type' in self.final_mst.nodes[node]:
|
||||
if self.final_mst.nodes[node]['type'] == 'building':
|
||||
name = self.final_mst.nodes[node]['name']
|
||||
node_type = 'building'
|
||||
elif self.final_mst.nodes[node]['type'] == 'generation':
|
||||
name = self.final_mst.nodes[node]['name']
|
||||
node_type = 'generation'
|
||||
else:
|
||||
name = f'junction_{node_id}'
|
||||
node_type = 'junction'
|
||||
self.network_graph.add_node(node_id, name=name, type=node_type, pos=pos)
|
||||
node_mapping[node] = node_id
|
||||
node_id += 1
|
||||
for u, v, data in self.final_mst.edges(data=True):
|
||||
u_new = node_mapping[u]
|
||||
v_new = node_mapping[v]
|
||||
length = data['weight']
|
||||
self.network_graph.add_edge(u_new, v_new, length=length)
|
||||
|
||||
def plot_network_graph(self):
|
||||
"""
|
||||
Plot the network graph using matplotlib and networkx.
|
||||
"""
|
||||
plt.figure(figsize=(15, 10))
|
||||
pos = {node: data['pos'] for node, data in self.network_graph.nodes(data=True)}
|
||||
nx.draw_networkx_nodes(self.network_graph, pos, node_color='blue', node_size=50)
|
||||
nx.draw_networkx_edges(self.network_graph, pos, edge_color='gray')
|
||||
plt.title('District Heating Network Graph')
|
||||
plt.axis('off')
|
||||
plt.show()
|
61
scripts/district_heating_network/geojson_corrector.py
Normal file
61
scripts/district_heating_network/geojson_corrector.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import json
|
||||
import random
|
||||
|
||||
|
||||
def right_hand_rule(polygon):
|
||||
"""
|
||||
Ensure coordinates follow the right-hand rule for polygons.
|
||||
The right-hand rule implies that the vertices of the exterior ring of the polygon are ordered counterclockwise.
|
||||
"""
|
||||
|
||||
def is_clockwise(coords):
|
||||
total = 0
|
||||
for i in range(len(coords)):
|
||||
x1, y1 = coords[i]
|
||||
x2, y2 = coords[(i + 1) % len(coords)]
|
||||
total += (x2 - x1) * (y2 + y1)
|
||||
return total > 0
|
||||
|
||||
for coords in polygon:
|
||||
if is_clockwise(coords):
|
||||
coords.reverse()
|
||||
|
||||
|
||||
def process_geojson(geojson):
|
||||
for i, feature in enumerate(geojson['features']):
|
||||
# Check and correct the coordinate order
|
||||
if feature['geometry']['type'] == "MultiPolygon":
|
||||
for polygon in feature['geometry']['coordinates']:
|
||||
right_hand_rule(polygon)
|
||||
|
||||
# Change geometry type to Polygon
|
||||
feature['geometry']['type'] = "Polygon"
|
||||
feature['geometry']['coordinates'] = feature['geometry']['coordinates'][0]
|
||||
|
||||
# Remove 'id' attribute from properties
|
||||
if 'id' in feature['properties']:
|
||||
del feature['properties']['id']
|
||||
|
||||
# Add new properties
|
||||
feature['id'] = i + 1
|
||||
feature['properties'].update({
|
||||
"name": str(i + 1),
|
||||
"address": "",
|
||||
"function": random.choice([1000, 6199]),
|
||||
"height": round(random.uniform(13, 30), 2),
|
||||
"year_of_construction": 2023
|
||||
})
|
||||
|
||||
|
||||
# Load the GeoJSON file
|
||||
with open('../../input_files/lachine_group_mach_buildings.geojson', 'r') as file:
|
||||
geojson = json.load(file)
|
||||
|
||||
# Process the GeoJSON data
|
||||
process_geojson(geojson)
|
||||
|
||||
# Save the processed GeoJSON to a new file
|
||||
with open('processed_output.geojson', 'w') as file:
|
||||
json.dump(geojson, file, indent=4)
|
||||
|
||||
print("GeoJSON processing complete.")
|
54
scripts/district_heating_network/geojson_graph_creator.py
Normal file
54
scripts/district_heating_network/geojson_graph_creator.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
import json
|
||||
from shapely import LineString, Point
|
||||
import networkx as nx
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def networkx_to_geojson(graph: nx.Graph) -> Path:
|
||||
"""
|
||||
Convert a NetworkX graph to GeoJSON format.
|
||||
|
||||
:param graph: A NetworkX graph.
|
||||
:return: GeoJSON formatted dictionary.
|
||||
"""
|
||||
features = []
|
||||
|
||||
for u, v, data in graph.edges(data=True):
|
||||
line = LineString([u, v])
|
||||
feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": list(line.coords)
|
||||
},
|
||||
"properties": {
|
||||
"weight": data.get("weight", 1.0)
|
||||
}
|
||||
}
|
||||
features.append(feature)
|
||||
|
||||
for node, data in graph.nodes(data=True):
|
||||
point = Point(node)
|
||||
feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": list(point.coords)[0]
|
||||
},
|
||||
"properties": {
|
||||
"type": data.get("type", "unknown"),
|
||||
"id": data.get("id", "N/A")
|
||||
}
|
||||
}
|
||||
features.append(feature)
|
||||
|
||||
geojson = {
|
||||
"type": "FeatureCollection",
|
||||
"features": features
|
||||
}
|
||||
|
||||
output_geojson_file = Path('./out_files/network_graph.geojson').resolve()
|
||||
with open(output_geojson_file, 'w') as file:
|
||||
json.dump(geojson, file, indent=4)
|
||||
|
||||
return output_geojson_file
|
48
scripts/district_heating_network/road_corrector.py
Normal file
48
scripts/district_heating_network/road_corrector.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
import json
|
||||
import random
|
||||
|
||||
|
||||
# Function to process the GeoJSON for roads
|
||||
def process_roads_geojson(geojson):
|
||||
# Create the new structure
|
||||
new_geojson = {
|
||||
"type": "FeatureCollection",
|
||||
"name": "lachine_roadfs",
|
||||
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}},
|
||||
"features": []
|
||||
}
|
||||
|
||||
for i, feature in enumerate(geojson['features']):
|
||||
# Convert MultiLineString to LineString if necessary
|
||||
coordinates = feature['geometry']['coordinates']
|
||||
if feature['geometry']['type'] == "MultiLineString":
|
||||
coordinates = coordinates[0]
|
||||
|
||||
# Add the new properties
|
||||
new_feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": coordinates
|
||||
},
|
||||
"properties": {
|
||||
}
|
||||
}
|
||||
|
||||
new_geojson['features'].append(new_feature)
|
||||
|
||||
return new_geojson
|
||||
|
||||
|
||||
# Load the original GeoJSON file
|
||||
with open('../../input_files/roads.geojson', 'r') as file:
|
||||
original_geojson = json.load(file)
|
||||
|
||||
# Process the GeoJSON data
|
||||
processed_geojson = process_roads_geojson(original_geojson)
|
||||
|
||||
# Save the processed GeoJSON to a new file
|
||||
with open('../../input_files/processed_roads_output.geojson', 'w') as file:
|
||||
json.dump(processed_geojson, file, indent=4)
|
||||
|
||||
print("GeoJSON roads processing complete.")
|
56
scripts/district_heating_network/road_processor.py
Normal file
56
scripts/district_heating_network/road_processor.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from pathlib import Path
|
||||
from shapely.geometry import Polygon, Point, shape
|
||||
import json
|
||||
|
||||
|
||||
def road_processor(x, y, diff):
|
||||
"""
|
||||
Processes a .JSON file to find roads that have at least one node within a specified polygon.
|
||||
|
||||
Parameters:
|
||||
x (float): The x-coordinate of the center of the selection box.
|
||||
y (float): The y-coordinate of the center of the selection box.
|
||||
diff (float): The half-width of the selection box.
|
||||
|
||||
Returns:
|
||||
str: The file path of the output GeoJSON file containing the selected roads.
|
||||
"""
|
||||
diff += 2 * diff
|
||||
# Define the selection polygon
|
||||
selection_box = Polygon([
|
||||
[x + diff, y - diff],
|
||||
[x - diff, y - diff],
|
||||
[x - diff, y + diff],
|
||||
[x + diff, y + diff]
|
||||
])
|
||||
|
||||
# Define input and output file paths
|
||||
geojson_file = Path("./input_files/roads.geojson").resolve()
|
||||
output_file = Path('./input_files/output_roads.geojson').resolve()
|
||||
|
||||
# Initialize a list to store the roads in the region
|
||||
roads_in_region = []
|
||||
|
||||
# Read the GeoJSON file
|
||||
with open(geojson_file, 'r') as file:
|
||||
roads = json.load(file)
|
||||
line_features = [feature for feature in roads['features'] if feature['geometry']['type'] == 'LineString']
|
||||
|
||||
# Check each road feature
|
||||
for feature in line_features:
|
||||
road_shape = shape(feature['geometry'])
|
||||
# Check if any node of the road is inside the selection box
|
||||
if any(selection_box.contains(Point(coord)) for coord in road_shape.coords):
|
||||
roads_in_region.append(feature)
|
||||
|
||||
# Create a new GeoJSON structure with the selected roads
|
||||
output_geojson = {
|
||||
"type": "FeatureCollection",
|
||||
"features": roads_in_region
|
||||
}
|
||||
|
||||
# Write the selected roads to the output file
|
||||
with open(output_file, 'w') as outfile:
|
||||
json.dump(output_geojson, outfile)
|
||||
|
||||
return output_file
|
86
scripts/district_heating_network/simultinity_factor.py
Normal file
86
scripts/district_heating_network/simultinity_factor.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
class DemandShiftProcessor:
|
||||
def __init__(self, city):
|
||||
self.city = city
|
||||
|
||||
def random_shift(self, series):
|
||||
shift_amount = np.random.randint(0, round(0.005 * len(series)))
|
||||
return series.shift(shift_amount).fillna(series.shift(shift_amount - len(series)))
|
||||
|
||||
def process_demands(self):
|
||||
heating_dfs = []
|
||||
cooling_dfs = []
|
||||
|
||||
for building in self.city.buildings:
|
||||
heating_df = self.convert_building_to_dataframe(building, 'heating')
|
||||
cooling_df = self.convert_building_to_dataframe(building, 'cooling')
|
||||
heating_df.set_index('Date/Time', inplace=True)
|
||||
cooling_df.set_index('Date/Time', inplace=True)
|
||||
shifted_heating_demands = heating_df.apply(self.random_shift, axis=0)
|
||||
shifted_cooling_demands = cooling_df.apply(self.random_shift, axis=0)
|
||||
self.update_building_demands(building, shifted_heating_demands, 'heating')
|
||||
self.update_building_demands(building, shifted_cooling_demands, 'cooling')
|
||||
heating_dfs.append(shifted_heating_demands)
|
||||
cooling_dfs.append(shifted_cooling_demands)
|
||||
|
||||
combined_heating_df = pd.concat(heating_dfs, axis=1)
|
||||
combined_cooling_df = pd.concat(cooling_dfs, axis=1)
|
||||
self.calculate_and_set_simultaneity_factor(combined_heating_df, 'heating')
|
||||
self.calculate_and_set_simultaneity_factor(combined_cooling_df, 'cooling')
|
||||
|
||||
self.save_demands_to_csv(combined_heating_df, 'heating_demands.csv')
|
||||
self.save_demands_to_csv(combined_cooling_df, 'cooling_demands.csv')
|
||||
|
||||
def convert_building_to_dataframe(self, building, demand_type):
|
||||
if demand_type == 'heating':
|
||||
data = {
|
||||
"Date/Time": self.generate_date_time_index(),
|
||||
"Heating_Demand": building.heating_demand["hour"]
|
||||
}
|
||||
else: # cooling
|
||||
data = {
|
||||
"Date/Time": self.generate_date_time_index(),
|
||||
"Cooling_Demand": building.cooling_demand["hour"]
|
||||
}
|
||||
return pd.DataFrame(data)
|
||||
|
||||
def generate_date_time_index(self):
|
||||
# Generate hourly date time index for a full year in 2024
|
||||
date_range = pd.date_range(start="2013-01-01 00:00:00", end="2013-12-31 23:00:00", freq='H')
|
||||
return date_range.strftime('%m/%d %H:%M:%S').tolist()
|
||||
|
||||
def update_building_demands(self, building, shifted_demands, demand_type):
|
||||
if demand_type == 'heating':
|
||||
shifted_series = shifted_demands["Heating_Demand"]
|
||||
building.heating_demand = self.calculate_new_demands(shifted_series)
|
||||
else: # cooling
|
||||
shifted_series = shifted_demands["Cooling_Demand"]
|
||||
building.cooling_demand = self.calculate_new_demands(shifted_series)
|
||||
|
||||
def calculate_new_demands(self, shifted_series):
|
||||
new_demand = {
|
||||
"hour": shifted_series.tolist(),
|
||||
"month": self.calculate_monthly_demand(shifted_series),
|
||||
"year": [shifted_series.sum()]
|
||||
}
|
||||
return new_demand
|
||||
|
||||
def calculate_monthly_demand(self, series):
|
||||
series.index = pd.to_datetime(series.index, format='%m/%d %H:%M:%S')
|
||||
monthly_demand = series.resample('M').sum()
|
||||
return monthly_demand.tolist()
|
||||
|
||||
def calculate_and_set_simultaneity_factor(self, combined_df, demand_type):
|
||||
total_demand_original = combined_df.sum(axis=1)
|
||||
peak_total_demand_original = total_demand_original.max()
|
||||
individual_peak_demands = combined_df.max(axis=0)
|
||||
sum_individual_peak_demands = individual_peak_demands.sum()
|
||||
if demand_type == 'heating':
|
||||
self.city.simultaneity_factor_heating = peak_total_demand_original / sum_individual_peak_demands
|
||||
else: # cooling
|
||||
self.city.simultaneity_factor_cooling = peak_total_demand_original / sum_individual_peak_demands
|
||||
|
||||
def save_demands_to_csv(self, df, filename):
|
||||
df.to_csv(filename)
|
26
scripts/optimization/energy_system_sizing_optimization.py
Normal file
26
scripts/optimization/energy_system_sizing_optimization.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
import random
|
||||
import numpy as np
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
class EnergySystemOptimizer:
|
||||
def __init__(self, building, objectives, population_size=20, number_of_generations=100, crossover_rate=0.8,
|
||||
mutation_rate=0.1):
|
||||
self.building = building
|
||||
self.objectives = objectives
|
||||
self.population_size = population_size
|
||||
self.num_gen = number_of_generations
|
||||
self.crossover_rate = crossover_rate
|
||||
self.mutation_rate = mutation_rate
|
||||
|
||||
# Initialize population
|
||||
def initialize_population(self):
|
||||
population = []
|
||||
for _ in range(self.population_size):
|
||||
individual = [
|
||||
random.uniform(0.1, 10.0), # hp_size
|
||||
random.uniform(0.1, 10.0), # boiler_size
|
||||
random.uniform(0.1, 10.0), # tes_size
|
||||
random.uniform(40, 60) # cutoff_temp
|
||||
]
|
||||
population.append(individual)
|
||||
return population
|
16
scripts/optimization/objectives.py
Normal file
16
scripts/optimization/objectives.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Objective functions
|
||||
MINIMUM_LCC = 1
|
||||
MINIMUM_EC = 2
|
||||
MINIMUM_EMISSIONS = 3
|
||||
MINIMUM_LCC_MINIMUM_EC = 4
|
||||
MINIMUM_LCC_MINIMUM_EMISSIONS = 5
|
||||
MINIMUM_EC_MINIMUM_EMISSIONS = 6
|
||||
MINIMUM_LCC_MINIMUM_EC_MINIMUM_EMISSIONS = 7
|
||||
OBJECTIVE_FUNCTIONS = [MINIMUM_LCC,
|
||||
MINIMUM_EC,
|
||||
MINIMUM_EMISSIONS,
|
||||
MINIMUM_LCC_MINIMUM_EC,
|
||||
MINIMUM_LCC_MINIMUM_EMISSIONS,
|
||||
MINIMUM_EC_MINIMUM_EMISSIONS,
|
||||
MINIMUM_LCC_MINIMUM_EC_MINIMUM_EMISSIONS]
|
||||
|
|
@ -28,8 +28,8 @@ residential_systems_percentage = {'system 1 gas': 15,
|
|||
'system 8 gas': 15,
|
||||
'system 8 electricity': 35}
|
||||
|
||||
residential_new_systems_percentage = {'PV+ASHP+GasBoiler+TES': 100,
|
||||
'PV+4Pipe+DHW': 0,
|
||||
residential_new_systems_percentage = {'PV+ASHP+GasBoiler+TES': 0,
|
||||
'PV+4Pipe+DHW': 100,
|
||||
'PV+ASHP+ElectricBoiler+TES': 0,
|
||||
'PV+GSHP+GasBoiler+TES': 0,
|
||||
'PV+GSHP+ElectricBoiler+TES': 0,
|
||||
|
|
|
@ -5,7 +5,7 @@ from hub.helpers.monthly_values import MonthlyValues
|
|||
|
||||
|
||||
class Archetype13:
|
||||
def __init__(self, building, output_path):
|
||||
def __init__(self, building, output_path, csv_output=True,):
|
||||
self._building = building
|
||||
self._name = building.name
|
||||
self._pv_system = building.energy_systems[0]
|
||||
|
@ -25,6 +25,7 @@ class Archetype13:
|
|||
self._t_out = building.external_temperature[cte.HOUR]
|
||||
self.results = {}
|
||||
self.dt = 900
|
||||
self.csv_output = csv_output
|
||||
|
||||
def hvac_sizing(self):
|
||||
storage_factor = 3
|
||||
|
@ -374,10 +375,11 @@ class Archetype13:
|
|||
MonthlyValues.get_total_month(self._building.domestic_hot_water_consumption[cte.HOUR]))
|
||||
self._building.domestic_hot_water_consumption[cte.YEAR] = [
|
||||
sum(self._building.domestic_hot_water_consumption[cte.MONTH])]
|
||||
file_name = f'energy_system_simulation_results_{self._name}.csv'
|
||||
with open(self._output_path / file_name, 'w', newline='') as csvfile:
|
||||
output_file = csv.writer(csvfile)
|
||||
# Write header
|
||||
output_file.writerow(self.results.keys())
|
||||
# Write data
|
||||
output_file.writerows(zip(*self.results.values()))
|
||||
if self.csv_output:
|
||||
file_name = f'energy_system_simulation_results_{self._name}.csv'
|
||||
with open(self._output_path / file_name, 'w', newline='') as csvfile:
|
||||
output_file = csv.writer(csvfile)
|
||||
# Write header
|
||||
output_file.writerow(self.results.keys())
|
||||
# Write data
|
||||
output_file.writerows(zip(*self.results.values()))
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
from pathlib import Path
|
||||
import subprocess
|
||||
from scripts.ep_run_enrich import energy_plus_workflow
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport
|
||||
from scripts.geojson_creator import process_geojson
|
||||
from scripts import random_assignation
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing import SystemSizing
|
||||
from scripts.solar_angles import CitySolarAngles
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
from scripts.energy_system_retrofit_results import consumption_data, cost_data
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.costs.cost import Cost
|
||||
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_feasibility import pv_feasibility
|
||||
|
||||
# Specify the GeoJSON file path
|
||||
input_files_path = (Path(__file__).parent / 'input_files')
|
||||
input_files_path.mkdir(parents=True, exist_ok=True)
|
||||
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
|
||||
geojson_file_path = input_files_path / 'output_buildings.geojson'
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
energy_plus_output_path = output_path / 'energy_plus_outputs'
|
||||
energy_plus_output_path.mkdir(parents=True, exist_ok=True)
|
||||
simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_results').resolve()
|
||||
simulation_results_path.mkdir(parents=True, exist_ok=True)
|
||||
sra_output_path = output_path / 'sra_outputs'
|
||||
sra_output_path.mkdir(parents=True, exist_ok=True)
|
||||
cost_analysis_output_path = output_path / 'cost_analysis'
|
||||
cost_analysis_output_path.mkdir(parents=True, exist_ok=True)
|
||||
city = GeometryFactory(file_type='geojson',
|
||||
path=geojson_file_path,
|
||||
height_field='height',
|
||||
year_of_construction_field='year_of_construction',
|
||||
function_field='function',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
energy_plus_workflow(city, energy_plus_output_path)
|
||||
random_assignation.call_random(city.buildings, random_assignation.residential_new_systems_percentage)
|
||||
EnergySystemsFactory('montreal_future', city).enrich()
|
||||
for building in city.buildings:
|
||||
EnergySystemsSimulationFactory('archetype1', building=building, output_path=simulation_results_path).enrich()
|
||||
|
749
summer_school.py
Normal file
749
summer_school.py
Normal file
|
@ -0,0 +1,749 @@
|
|||
from pathlib import Path
|
||||
# from scripts.ep_workflow import energy_plus_workflow
|
||||
from hub.helpers.monthly_values import MonthlyValues
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
import hub.helpers.constants as cte
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from hub.helpers.peak_loads import PeakLoads
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.solar_angles import CitySolarAngles
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
from scripts.pv_sizing_and_simulation import PVSizingSimulation
|
||||
import pandas as pd
|
||||
import geopandas as gpd
|
||||
import json
|
||||
|
||||
#%% # -----------------------------------------------
|
||||
# Specify the GeoJSON file path
|
||||
#%% # -----------------------------------------------
|
||||
input_files_path = (Path(__file__).parent / 'input_files')
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
energy_plus_output_path = output_path / 'energy_plus_outputs'
|
||||
energy_plus_output_path.mkdir(parents=True, exist_ok=True)
|
||||
simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_results').resolve()
|
||||
simulation_results_path.mkdir(parents=True, exist_ok=True)
|
||||
sra_output_path = output_path / 'sra_outputs'
|
||||
sra_output_path.mkdir(parents=True, exist_ok=True)
|
||||
cost_analysis_output_path = output_path / 'cost_analysis'
|
||||
cost_analysis_output_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
#%%-----------------------------------------------
|
||||
#"""add geojson paths and create city for Baseline"""
|
||||
#%% # -----------------------------------------------
|
||||
|
||||
geojson_file_path_baseline = output_path / 'updated_buildings_with_all_data_baseline.geojson'
|
||||
geojson_file_path_2024 = output_path / 'updated_buildings_with_all_data_2024.geojson'
|
||||
with open(geojson_file_path_baseline , 'r') as f:
|
||||
building_type_data = json.load(f)
|
||||
with open(geojson_file_path_2024, 'r') as f:
|
||||
building_type_data_2024 = json.load(f)
|
||||
|
||||
# Create city object from GeoJSON file
|
||||
city = GeometryFactory('geojson',
|
||||
path=geojson_file_path_baseline,
|
||||
height_field='maximum_roof_height',
|
||||
year_of_construction_field='year_built',
|
||||
function_field='building_type',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
#%%----------------------------------------------
|
||||
# Enrich city data
|
||||
#%% # ----------------------------------------------
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
# #energy plus is not going to be processed here, as demand has been obtained before
|
||||
# energy_plus_workflow(city)
|
||||
#%% # -----------------------------------------------
|
||||
#"""Enrich city with geojson file data"""
|
||||
#%% # -----------------------------------------------
|
||||
percentage_data = {
|
||||
1646: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2672.550473, "total_floor_area": 26725.50473},
|
||||
1647: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2653.626087, "total_floor_area": 26536.26087},
|
||||
1648: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1056.787496, "total_floor_area": 10567.87496},
|
||||
1649: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1906.620746, "total_floor_area": 19066.20746},
|
||||
1650: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 659.1119416, "total_floor_area": 5272.895533},
|
||||
1651: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1167.208109, "total_floor_area": 9337.664871},
|
||||
1652: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1193.251653, "total_floor_area": 9546.013222},
|
||||
1653: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1491.722543, "total_floor_area": 11933.78035},
|
||||
1654: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1168.005028, "total_floor_area": 9344.040224},
|
||||
1655: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1264.906961, "total_floor_area": 10119.25569},
|
||||
1656: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1281.768818, "total_floor_area": 10254.15054},
|
||||
1657: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 290.3886018, "total_floor_area": 2323.108814},
|
||||
1658: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 847.5095193, "total_floor_area": 6780.076155},
|
||||
1659: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1115.319153, "total_floor_area": 8922.553224},
|
||||
1660: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 469.2918062, "total_floor_area": 3754.33445},
|
||||
1661: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1292.298346, "total_floor_area": 10338.38677},
|
||||
1662: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 625.7828863, "total_floor_area": 5006.263091},
|
||||
1663: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1876.02897, "total_floor_area": 15008.23176},
|
||||
1664: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1118.224781, "total_floor_area": 22364.49562},
|
||||
1665: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1502.787808, "total_floor_area": 30055.75617},
|
||||
1666: {"type1_%": 0.891045711, "type2_%": 0.108954289, "type3_%": 0, "roof_area": 3038.486076, "total_floor_area": 30384.86076},
|
||||
1667: {"type1_%": 0.8, "type2_%": 0.2, "type3_%": 0, "roof_area": 1343.832818, "total_floor_area": 13438.32818},
|
||||
1668: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 961.0996956, "total_floor_area": 4805.498478},
|
||||
1669: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 489.1282111, "total_floor_area": 1956.512845},
|
||||
1673: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1693.141465, "total_floor_area": 5079.424396},
|
||||
1674: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 3248.827576, "total_floor_area": 9746.482729},
|
||||
1675: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 4086.842191, "total_floor_area": 12260.52657},
|
||||
1676: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2786.114146, "total_floor_area": 11144.45658},
|
||||
1677: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 5142.784184, "total_floor_area": 15428.35255},
|
||||
1678: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 6068.664574, "total_floor_area": 18205.99372},
|
||||
1679: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 5646.751407, "total_floor_area": 16940.25422},
|
||||
1680: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1601.765953, "total_floor_area": 4805.297859},
|
||||
1681: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 9728.221797, "total_floor_area": 29184.66539},
|
||||
1687: {"type1_%": 0.606611029, "type2_%": 0.28211422, "type3_%": 0.11127475, "roof_area": 4268.608743, "total_floor_area": 59760.52241},
|
||||
1688: {"type1_%": 0.92, "type2_%": 0.08, "type3_%": 0, "roof_area": 2146.654828, "total_floor_area": 38639.7869},
|
||||
1689: {"type1_%": 0.96, "type2_%": 0.04, "type3_%": 0, "roof_area": 2860.270711, "total_floor_area": 57205.41421},
|
||||
1690: {"type1_%": 0.94, "type2_%": 0.06, "type3_%": 0, "roof_area": 2189.732519, "total_floor_area": 28466.52275},
|
||||
1691: {"type1_%": 0.75, "type2_%": 0.25, "type3_%": 0, "roof_area": 3159.077523, "total_floor_area": 31590.77523},
|
||||
}
|
||||
|
||||
def enrich_buildings_with_geojson_data (building_type_data, city):
|
||||
for building in city.buildings:
|
||||
for idx, feature in enumerate(building_type_data['features']):
|
||||
if feature['properties']['id'] == str(building.name):
|
||||
building.heating_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('heating_demand_kWh', [0])]
|
||||
building.cooling_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('cooling_demand_kWh', [0])]
|
||||
building.domestic_hot_water_heat_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('domestic_hot_water_heat_demand_kWh', [0])]
|
||||
building.appliances_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('appliances_electrical_demand_kWh', [0])]
|
||||
building.lighting_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('lighting_electrical_demand_kWh', [0])]
|
||||
building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR])
|
||||
building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR])
|
||||
building.domestic_hot_water_heat_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.domestic_hot_water_heat_demand[cte.HOUR]))
|
||||
building.appliances_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.appliances_electrical_demand[cte.HOUR]))
|
||||
building.lighting_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.lighting_electrical_demand[cte.HOUR]))
|
||||
building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])]
|
||||
building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])]
|
||||
building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])]
|
||||
building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])]
|
||||
building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])]
|
||||
|
||||
|
||||
|
||||
enrich_buildings_with_geojson_data (building_type_data, city)
|
||||
print('test')
|
||||
|
||||
#%%-----------------------------------------------
|
||||
# """ADD energy systems"""
|
||||
#%% # -----------------------------------------------
|
||||
|
||||
for building in city.buildings:
|
||||
building.energy_systems_archetype_name = 'system 1 electricity'
|
||||
|
||||
EnergySystemsFactory('montreal_custom', city).enrich()
|
||||
|
||||
def baseline_to_dict(building):
|
||||
return {
|
||||
'heating_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.heating_consumption[cte.HOUR]],
|
||||
'cooling_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_consumption[cte.HOUR]],
|
||||
'domestic_hot_water_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_consumption[cte.HOUR]],
|
||||
'appliances_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]],
|
||||
'lighting_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]]
|
||||
}
|
||||
buildings_dic={}
|
||||
for building in city.buildings:
|
||||
buildings_dic[building.name]=baseline_to_dict(building)
|
||||
scenario={}
|
||||
|
||||
scenario['baseline']=buildings_dic
|
||||
print("Scenario 1: Baseline is performed successfully")
|
||||
|
||||
|
||||
|
||||
del city
|
||||
del buildings_dic
|
||||
del building_type_data
|
||||
|
||||
#%%-----------------------------------------------
|
||||
# Scenario 2
|
||||
#%% # -----------------------------------------------
|
||||
|
||||
# Create city object from GeoJSON file
|
||||
city = GeometryFactory('geojson',
|
||||
path=geojson_file_path_2024,
|
||||
height_field='maximum_roof_height',
|
||||
year_of_construction_field='year_built',
|
||||
function_field='building_type',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
#%%-----------------------------------------------
|
||||
# Enrich city data
|
||||
#%% # -----------------------------------------------
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
|
||||
enrich_buildings_with_geojson_data (building_type_data_2024, city)
|
||||
|
||||
def to_dict(building,hourly_pv):
|
||||
return {
|
||||
'heating_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.heating_consumption[cte.HOUR]],
|
||||
'cooling_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_consumption[cte.HOUR]],
|
||||
'domestic_hot_water_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_consumption[cte.HOUR]],
|
||||
'appliances_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]],
|
||||
'lighting_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]],
|
||||
'hourly_pv_kWh': [x /(cte.WATTS_HOUR_TO_JULES * 1000) for x in hourly_pv]
|
||||
}
|
||||
buildings_dic={}
|
||||
|
||||
|
||||
for building in city.buildings:
|
||||
building.energy_systems_archetype_name = 'system 1 electricity pv'
|
||||
|
||||
EnergySystemsFactory('montreal_custom', city).enrich()
|
||||
# #%%-----------------------------------------------
|
||||
# # """SRA"""
|
||||
# #%% # -----------------------------------------------
|
||||
ExportsFactory('sra', city, output_path).export()
|
||||
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
|
||||
subprocess.run(['sra', str(sra_path)])
|
||||
ResultFactory('sra', city, output_path).enrich()
|
||||
solar_angles = CitySolarAngles(city.name,
|
||||
city.latitude,
|
||||
city.longitude,
|
||||
tilt_angle=45,
|
||||
surface_azimuth_angle=180).calculate
|
||||
df = pd.DataFrame()
|
||||
df.index = ['yearly lighting (kWh)', 'yearly appliance (kWh)', 'yearly heating (kWh)', 'yearly cooling (kWh)',
|
||||
'yearly dhw (kWh)', 'roof area (m2)', 'used area for pv (m2)', 'number of panels', 'pv production (kWh)']
|
||||
for building in city.buildings:
|
||||
ghi = [x / cte.WATTS_HOUR_TO_JULES for x in building.roofs[0].global_irradiance[cte.HOUR]]
|
||||
pv_sizing_simulation = PVSizingSimulation(building,
|
||||
solar_angles,
|
||||
tilt_angle=45,
|
||||
module_height=1,
|
||||
module_width=2,
|
||||
ghi=ghi)
|
||||
pv_sizing_simulation.pv_output()
|
||||
yearly_lighting = building.lighting_electrical_demand[cte.YEAR][0] / 1000
|
||||
yearly_appliance = building.appliances_electrical_demand[cte.YEAR][0] / 1000
|
||||
yearly_heating = building.heating_demand[cte.YEAR][0] / (3.6e6 * 3)
|
||||
yearly_cooling = building.cooling_demand[cte.YEAR][0] / (3.6e6 * 4.5)
|
||||
yearly_dhw = building.domestic_hot_water_heat_demand[cte.YEAR][0] / 1000
|
||||
roof_area = building.roofs[0].perimeter_area
|
||||
used_roof = pv_sizing_simulation.available_space()
|
||||
number_of_pv_panels = pv_sizing_simulation.total_number_of_panels
|
||||
yearly_pv = building.onsite_electrical_production[cte.YEAR][0] / (3.6e6)
|
||||
hourly_pv = building.onsite_electrical_production[cte.HOUR]
|
||||
df[f'{building.name}'] = [yearly_lighting, yearly_appliance, yearly_heating, yearly_cooling, yearly_dhw, roof_area,
|
||||
used_roof, number_of_pv_panels, yearly_pv]
|
||||
buildings_dic[building.name]=to_dict(building,hourly_pv)
|
||||
|
||||
# %%-----------------------------------------------
|
||||
# """South facing facades"""
|
||||
# %% # -----------------------------------------------
|
||||
# Function to convert radians to degrees
|
||||
import math
|
||||
def radians_to_degrees(radians):
|
||||
return radians * (180 / math.pi)
|
||||
# Step 1: Create the walls_id dictionary
|
||||
walls_id={}
|
||||
|
||||
for building in city.buildings:
|
||||
ids = {}
|
||||
for walls in building.walls:
|
||||
id=walls.id
|
||||
azimuth_degree=radians_to_degrees(float(walls.azimuth))
|
||||
if azimuth_degree>90.0 or azimuth_degree <float(-90.0):
|
||||
ids[id]= {
|
||||
'azimuth': azimuth_degree,
|
||||
'global_irradiance': walls.global_irradiance[cte.HOUR],
|
||||
'area': walls.perimeter_area
|
||||
}
|
||||
walls_id[building.name] = ids
|
||||
|
||||
# Step 2: Calculate pv_on_facade for each wall
|
||||
for building_id, ids in walls_id.items():
|
||||
for wall_id, wall_data in ids.items():
|
||||
if 'global_irradiance' in wall_data:
|
||||
ghi = [x / cte.WATTS_HOUR_TO_JULES/1000 for x in wall_data['global_irradiance']]
|
||||
wall_data['pv_on_facade'] = [x * 0.6 * wall_data['area']*0.22 for x in ghi]
|
||||
|
||||
|
||||
|
||||
|
||||
walls_dic = output_path / 'walls_id.json'
|
||||
with open(walls_dic , 'w') as json_file:
|
||||
json.dump(walls_id, json_file, indent=4)
|
||||
|
||||
import pandas as pd
|
||||
#### EXPORT
|
||||
# Convert walls_id dictionary to a DataFrame
|
||||
# Convert walls_id dictionary to DataFrames for static and hourly data
|
||||
# def convert_walls_id_to_dfs(walls_id):
|
||||
# static_data = {}
|
||||
# hourly_data = {}
|
||||
#
|
||||
# for building_id, ids in walls_id.items():
|
||||
# for wall_id, wall_data in ids.items():
|
||||
# # Static data
|
||||
# static_data[f"{building_id}_{wall_id}_azimuth"] = wall_data.get('azimuth', None)
|
||||
# static_data[f"{building_id}_{wall_id}_area"] = wall_data.get('area', None)
|
||||
#
|
||||
# if 'pv_on_facade' in wall_data:
|
||||
# hourly_data[f"{building_id}_{wall_id}_pv_on_facade"] = wall_data['pv_on_facade']
|
||||
#
|
||||
# # Create DataFrames
|
||||
# static_df = pd.DataFrame([static_data])
|
||||
# hourly_df = pd.DataFrame(hourly_data)
|
||||
#
|
||||
# return static_df, hourly_df
|
||||
|
||||
|
||||
# output_path_walls_id_dic =output_path / 'walls_id_data.xlsx'
|
||||
#
|
||||
# static_df, hourly_df = convert_walls_id_to_dfs(walls_id)
|
||||
# with pd.ExcelWriter(output_path_walls_id_dic) as writer:
|
||||
# static_df.to_excel(writer, sheet_name='Static Data', index=False)
|
||||
# hourly_df.to_excel(writer, sheet_name='Hourly Data', index=False)
|
||||
|
||||
# print(f"Data successfully exported to {output_path}")
|
||||
# # Save the DataFrame to an Excel file
|
||||
|
||||
|
||||
|
||||
df.to_csv(output_path / 'pv.csv')
|
||||
|
||||
scenario['efficient with PV']=buildings_dic
|
||||
print("Scenario 2: efficient with PV run successfully")
|
||||
|
||||
#%%-----------------------------------------------
|
||||
# Scenario 3
|
||||
#%% # -----------------------------------------------
|
||||
|
||||
for building in city.buildings:
|
||||
building.energy_systems_archetype_name = 'PV+4Pipe+DHW'
|
||||
EnergySystemsFactory('montreal_future', city).enrich()
|
||||
buildings_dic = {}
|
||||
for building in city.buildings:
|
||||
EnergySystemsSimulationFactory('archetype13', building=building, output_path=simulation_results_path).enrich()
|
||||
buildings_dic[building.name] = to_dict(building, hourly_pv)
|
||||
scenario['efficient with PV+4Pipe+DHW']=buildings_dic
|
||||
print("Scenario 3: efficient with PV+4Pipe+DHW run successfully")
|
||||
|
||||
def extract_HP_size(building):
|
||||
dic={
|
||||
# Heat Pump Rated Heating and Cooling Output
|
||||
'hp_heat_size': building.energy_systems[1].generation_systems[1].nominal_heat_output/1000,
|
||||
'hp_cooling_output': building.energy_systems[1].generation_systems[1].nominal_cooling_output/1000,
|
||||
# Boiler Rated Heat Output
|
||||
'boiler_heat_output': building.energy_systems[1].generation_systems[0].nominal_heat_output/1000,
|
||||
# TES characteristics
|
||||
'tes_volume':building.energy_systems[1].generation_systems[0].energy_storage_systems[0].volume,
|
||||
'tes_height':building.energy_systems[1].generation_systems[0].energy_storage_systems[0].height,
|
||||
# DHW HP
|
||||
'dhw_hp_heat_output': building.energy_systems[-1].generation_systems[0].nominal_heat_output/1000,
|
||||
# DHW TES Characteristics
|
||||
'dhw_tes_volume': building.energy_systems[-1].generation_systems[0].energy_storage_systems[0].volume,
|
||||
'dhw_tes_height': building.energy_systems[-1].generation_systems[0].energy_storage_systems[0].height,
|
||||
}
|
||||
|
||||
|
||||
return dic
|
||||
HPs={}
|
||||
for building in city.buildings:
|
||||
HPs[building.name]=extract_HP_size(building)
|
||||
|
||||
#%%-------------------------------------------------------
|
||||
#""""EXPORTERS"""
|
||||
#%%-------------------------------------------------------
|
||||
|
||||
|
||||
# Convert the dictionary to a DataFrame
|
||||
df = pd.DataFrame.from_dict(HPs, orient='index')
|
||||
|
||||
# Save the DataFrame to an Excel file
|
||||
output_path_HPs =output_path/ 'HPs_data.xlsx'
|
||||
df.to_excel(output_path_HPs, index_label='building_id')
|
||||
|
||||
print(f"Data successfully exported to {output_path}")
|
||||
|
||||
import pandas as pd
|
||||
|
||||
districts_demands={}
|
||||
def extract_and_sum_demand_data(scenario, demand_types):
|
||||
|
||||
|
||||
# Conversion factor constant
|
||||
conversion_factor = 1 / (cte.WATTS_HOUR_TO_JULES * 1000)
|
||||
|
||||
# Loop through each scenario
|
||||
for scenario_key, buildings in scenario.items():
|
||||
# Loop through each building in the scenario
|
||||
# Initialize an empty dictionary to store the district demand sums
|
||||
district_demand = {demand_type: [0] * 8760 for demand_type in demand_types}
|
||||
district_demand['hourly_pv_kWh']= [0] * 8760
|
||||
for building_id, building_data in buildings.items():
|
||||
# Loop through each demand type and sum up the data
|
||||
for demand_type in demand_types:
|
||||
if demand_type in building_data:
|
||||
district_demand[demand_type] = [sum(x) for x in zip(district_demand[demand_type], building_data[demand_type])]
|
||||
|
||||
# If PV data is available and relevant
|
||||
if scenario_key == "efficient with PV":
|
||||
district_demand['hourly_pv_kWh'] = [sum(x) for x in zip(district_demand['hourly_pv_kWh'], building_data['hourly_pv_kWh'])]
|
||||
if scenario_key == 'efficient with PV+4Pipe+DHW':
|
||||
district_demand['hourly_pv_kWh'] = districts_demands["efficient with PV"]['hourly_pv_kWh']
|
||||
districts_demands[scenario_key]=district_demand
|
||||
|
||||
return districts_demands
|
||||
|
||||
# Example usage
|
||||
# Assuming 'scenario' is a dictionary with the required structure and 'cte' is defined somewhere with WATTS_HOUR_TO_JULES constant
|
||||
demand_types = [
|
||||
'heating_consumption_kWh',
|
||||
'cooling_consumption_kWh',
|
||||
'domestic_hot_water_consumption_kWh',
|
||||
'appliances_consumption_kWh',
|
||||
'lighting_consumption_kWh',
|
||||
# 'hourly_pv_kWh' # Include this only if you want to consider PV data
|
||||
]
|
||||
|
||||
# # Call the function with your scenario data
|
||||
district_demand = extract_and_sum_demand_data(scenario, demand_types)
|
||||
#
|
||||
# """"EXPORTERS"""
|
||||
# import pandas as pd
|
||||
#
|
||||
#
|
||||
# Export the DataFrame to an Excel file
|
||||
excel_file_path = r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\districts_balance.xlsx'
|
||||
# df.to_excel(excel_file_path, index=True, index_label='Building')
|
||||
|
||||
# Create an Excel writer object
|
||||
with pd.ExcelWriter(excel_file_path, engine='xlsxwriter') as writer:
|
||||
for scenarios,demands in district_demand.items():
|
||||
# Convert demands to a DataFrame
|
||||
df_demands = pd.DataFrame(demands)
|
||||
# Convert building_id to string and check its length
|
||||
sheet_name = str(scenarios)
|
||||
if len(sheet_name) > 31:
|
||||
sheet_name = sheet_name[:31] # Truncate to 31 characters if necessary
|
||||
# Write the DataFrame to a specific sheet named after the building_id
|
||||
df_demands.to_excel(writer, sheet_name=sheet_name, index=False)
|
||||
|
||||
|
||||
print("district balance data is exported successfully")
|
||||
|
||||
|
||||
import pandas as pd
|
||||
|
||||
# Assuming your scenario dictionary is already defined as follows:
|
||||
# scenario = {
|
||||
# 'baseline': { ... },
|
||||
# 'efficient with PV': { ... }
|
||||
# }
|
||||
|
||||
|
||||
def dict_to_df_col_wise(building_data):
|
||||
"""
|
||||
Converts a dictionary of building data to a DataFrame.
|
||||
|
||||
Args:
|
||||
building_data (dict): Dictionary containing building data where keys are building ids and values are dictionaries
|
||||
with hourly data for various demand types.
|
||||
|
||||
Returns:
|
||||
pd.DataFrame: DataFrame with columns for each building and demand type.
|
||||
"""
|
||||
# Create a dictionary to hold DataFrames for each demand type
|
||||
df_dict= {}
|
||||
|
||||
# Loop over each building
|
||||
for building_id, data in building_data.items():
|
||||
# Create a DataFrame for this building's data
|
||||
building_df = pd.DataFrame(data)
|
||||
|
||||
# Rename columns to include building_id
|
||||
building_df.columns = [f"{building_id}_{col}" for col in building_df.columns]
|
||||
|
||||
# Add this DataFrame to the dictionary
|
||||
df_dict[building_id] = building_df
|
||||
|
||||
# Concatenate all building DataFrames column-wise
|
||||
result_df = pd.concat(df_dict.values(), axis=1)
|
||||
|
||||
return result_df
|
||||
|
||||
# Create DataFrames for each scenario
|
||||
baseline_df = dict_to_df_col_wise(scenario['baseline'])
|
||||
efficient_with_pv_df = dict_to_df_col_wise(scenario['efficient with PV'])
|
||||
efficient_with_pv_hps = dict_to_df_col_wise(scenario['efficient with PV+4Pipe+DHW'])
|
||||
|
||||
|
||||
# Write the DataFrames to an Excel file with two separate sheets
|
||||
with pd.ExcelWriter(r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\scenario_data.xlsx') as writer:
|
||||
baseline_df.to_excel(writer, sheet_name='baseline', index=True)
|
||||
efficient_with_pv_df.to_excel(writer, sheet_name='efficient with PV', index=True)
|
||||
efficient_with_pv_hps.to_excel(writer, sheet_name='efficient with HPs', index=True)
|
||||
|
||||
print("hourly data has been successfully exported per building to scenario_data.xlsx")
|
||||
|
||||
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def convert_hourly_to_monthly(hourly_data):
|
||||
"""
|
||||
Converts hourly data to monthly data by summing up the values for each month.
|
||||
|
||||
Args:
|
||||
hourly_data (list): List of hourly data (length 8760).
|
||||
|
||||
Returns:
|
||||
list: List of monthly data (length 12).
|
||||
"""
|
||||
hourly_series = pd.Series(hourly_data, index=pd.date_range(start='1/1/2023', periods=8760, freq='H'))
|
||||
monthly_data = hourly_series.resample('M').sum()
|
||||
return monthly_data.tolist()
|
||||
|
||||
import os
|
||||
def plot_stacked_demands_vs_pv(district_demand, demand_types, output_path, pv_type='hourly_pv_kWh'):
|
||||
"""
|
||||
Plots the stacked monthly demand for each scenario and compares it to the PV data.
|
||||
|
||||
Args:
|
||||
district_demand (dict): Dictionary with scenario keys and demand data.
|
||||
demand_types (list): List of demand types to plot.
|
||||
output_path (str): Path to save the plots.
|
||||
pv_type (str): The PV data type to compare against.
|
||||
"""
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
for scenario_key, demand_data in district_demand.items():
|
||||
# Convert hourly data to monthly data for each demand type
|
||||
monthly_data = {demand_type: convert_hourly_to_monthly(demand_data[demand_type]) for demand_type in
|
||||
demand_types}
|
||||
monthly_pv = convert_hourly_to_monthly(demand_data.get(pv_type, [0] * 8760))
|
||||
|
||||
# Create a DataFrame for easier plotting
|
||||
combined_data = pd.DataFrame(monthly_data)
|
||||
combined_data['Month'] = range(1, 13)
|
||||
combined_data['PV'] = monthly_pv
|
||||
|
||||
# Plotting
|
||||
fig, ax1 = plt.subplots(figsize=(14, 8))
|
||||
|
||||
# Plot stacked demands
|
||||
combined_data.set_index('Month', inplace=True)
|
||||
combined_data[demand_types].plot(kind='bar', stacked=True, ax=ax1, colormap='tab20')
|
||||
|
||||
ax1.set_xlabel('Month')
|
||||
ax1.set_ylabel('Energy Demand (kWh)')
|
||||
ax1.set_title(f'Monthly Energy Demand and PV Generation for {scenario_key}')
|
||||
|
||||
# Plot PV data on the secondary y-axis
|
||||
ax2 = ax1.twinx()
|
||||
ax2.plot(combined_data.index, combined_data['PV'], color='black', linestyle='-', marker='o',
|
||||
label='PV Generation')
|
||||
ax2.set_ylabel('PV Generation (kWh)')
|
||||
|
||||
# Add legends
|
||||
ax1.legend(loc='upper left')
|
||||
ax2.legend(loc='upper right')
|
||||
|
||||
ax1.set_xticks(combined_data.index)
|
||||
ax1.set_xticklabels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])
|
||||
|
||||
# Save the plot
|
||||
plt.savefig(os.path.join(output_path, f'{scenario_key}_monthly_demand_vs_pv.png'))
|
||||
plt.close()
|
||||
|
||||
|
||||
# Example usage
|
||||
# district_demand = extract_and_sum_demand_data(scenario, demand_types)
|
||||
|
||||
# Specify the demand types and PV type
|
||||
demand_types = [
|
||||
'heating_consumption_kWh',
|
||||
'cooling_consumption_kWh',
|
||||
'domestic_hot_water_consumption_kWh',
|
||||
'appliances_consumption_kWh',
|
||||
'lighting_consumption_kWh'
|
||||
]
|
||||
|
||||
# Plot the data
|
||||
plot_stacked_demands_vs_pv(district_demand, demand_types, output_path)
|
||||
# Plot the data
|
||||
print('test')
|
||||
import csv
|
||||
clusters=pd.read_csv(output_path/'clusters.csv')
|
||||
|
||||
|
||||
# Step 2: Extract the demand data for each building
|
||||
def extract_building_demand(city):
|
||||
building_demand = {}
|
||||
for building in city.buildings:
|
||||
demands = {
|
||||
'heating_demand': [x / 1000 * cte.WATTS_HOUR_TO_JULES for x in building.heating_demand[cte.HOUR]],
|
||||
'cooling_demand': [x / 1000 * cte.WATTS_HOUR_TO_JULES for x in building.cooling_demand[cte.HOUR]],
|
||||
'domestic_hot_water_demand': [x / 1000 * cte.WATTS_HOUR_TO_JULES for x in building.domestic_hot_water_heat_demand[cte.HOUR]],
|
||||
'appliances_electrical_demand': [x / 1000 * cte.WATTS_HOUR_TO_JULES for x in building.appliances_electrical_demand[cte.HOUR]],
|
||||
'lighting_electrical_demand': [x / 1000 * cte.WATTS_HOUR_TO_JULES for x in building.lighting_electrical_demand[cte.HOUR]]
|
||||
}
|
||||
building_demand[building.name] = demands
|
||||
return building_demand
|
||||
|
||||
# Step 3: Sum the demand types for each cluster
|
||||
def sum_demands_by_cluster(building_demand, clusters, demand_types):
|
||||
cluster_demands = {cluster: {demand_type: [0] * 8760 for demand_type in demand_types} for cluster in clusters['cluster'].unique()}
|
||||
|
||||
for _, row in clusters.iterrows():
|
||||
building_id = str(row['id'])
|
||||
cluster = row['cluster']
|
||||
if building_id in building_demand:
|
||||
for demand_type in demand_types:
|
||||
cluster_demands[cluster][demand_type] = [sum(x) for x in zip(cluster_demands[cluster][demand_type], building_demand[building_id][demand_type])]
|
||||
|
||||
return cluster_demands
|
||||
|
||||
|
||||
def plot_demands_by_cluster(cluster_demands, demand_types, output_folder):
|
||||
import os
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
for cluster, demands in cluster_demands.items():
|
||||
plt.figure(figsize=(15, 10))
|
||||
for demand_type in demand_types:
|
||||
plt.plot(demands[demand_type], label=demand_type)
|
||||
|
||||
plt.title(f'Summed Demands for Cluster {cluster}')
|
||||
plt.xlabel('Hour of the Year')
|
||||
plt.ylabel('Demand (kWh)')
|
||||
plt.legend(loc='upper right')
|
||||
plt.grid(True)
|
||||
plt.tight_layout()
|
||||
plt.savefig(os.path.join(output_folder, f'cluster_{cluster}_summed_demands.png'))
|
||||
plt.close()
|
||||
|
||||
|
||||
# Example usage
|
||||
demand_types = [
|
||||
'heating_demand',
|
||||
'cooling_demand',
|
||||
'domestic_hot_water_demand',
|
||||
'appliances_electrical_demand',
|
||||
'lighting_electrical_demand'
|
||||
]
|
||||
|
||||
# Extract the building demand data
|
||||
building_demand = extract_building_demand(city)
|
||||
cluster_demands = sum_demands_by_cluster(building_demand, clusters, demand_types)
|
||||
# Create a DataFrame to export the results
|
||||
cluster_demands_df = {f"{cluster}_{demand_type}": data for cluster, demands in cluster_demands.items() for
|
||||
demand_type, data in demands.items()}
|
||||
cluster_demands_df = pd.DataFrame(cluster_demands_df)
|
||||
|
||||
# Save the results to an Excel file
|
||||
|
||||
cluster_demands_df.to_excel(output_path/'cluster_demands.xlsx', index=False)
|
||||
|
||||
print(f"Clustered demand data successfully exported to {output_path}")
|
||||
|
||||
|
||||
|
||||
#%%-----------------------------------------------
|
||||
# Scenario 4
|
||||
#%% # -----------------------------------------------
|
||||
|
||||
del city
|
||||
del buildings_dic
|
||||
|
||||
|
||||
geojson_file_path_clusters= output_path / 'new.geojson'
|
||||
|
||||
with open(geojson_file_path_clusters , 'r') as f:
|
||||
building_type_data_new = json.load(f)
|
||||
|
||||
# Create city object from GeoJSON file
|
||||
city = GeometryFactory('geojson',
|
||||
path=geojson_file_path_clusters,
|
||||
height_field='maximum_roof_height',
|
||||
year_of_construction_field='year_built',
|
||||
function_field='building_type',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
#%%-----------------------------------------------
|
||||
# Enrich city data
|
||||
#%% # -----------------------------------------------
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
|
||||
buildings_clusters={
|
||||
1651: 4,
|
||||
1662: 0,
|
||||
1667: 1,
|
||||
1674: 2,
|
||||
1688: 3
|
||||
}
|
||||
|
||||
for building_id in buildings_clusters:
|
||||
cluster=buildings_clusters[building_id]
|
||||
for idx, feature in enumerate(building_type_data_new['features']):
|
||||
if feature['properties']['id'] == str(building_id):
|
||||
building_type_data_new['features'][idx]['properties']['heating_demand_kWh']=cluster_demands[cluster]['heating_demand']
|
||||
building_type_data_new['features'][idx]['properties']['cooling_demand_kWh'] = cluster_demands[cluster]['cooling_demand']
|
||||
building_type_data_new['features'][idx]['properties']['domestic_hot_water_heat_demand_kWh'] = cluster_demands[cluster]['domestic_hot_water_demand']
|
||||
building_type_data_new['features'][idx]['properties']['appliances_electrical_demand_kWh'] = cluster_demands[cluster]['appliances_electrical_demand']
|
||||
building_type_data_new['features'][idx]['properties']['lighting_electrical_demand_kWh'] = cluster_demands[cluster]['lighting_electrical_demand']
|
||||
|
||||
enrich_buildings_with_geojson_data (building_type_data_new, city)
|
||||
|
||||
|
||||
for building in city.buildings:
|
||||
building.energy_systems_archetype_name = 'PV+4Pipe+DHW'
|
||||
EnergySystemsFactory('montreal_future', city).enrich()
|
||||
buildings_dic = {}
|
||||
for building in city.buildings:
|
||||
EnergySystemsSimulationFactory('archetype13', building=building, output_path=simulation_results_path).enrich()
|
||||
buildings_dic[building.name] = to_dict(building, hourly_pv)
|
||||
scenario['efficient with PV+4Pipe+DHW']=buildings_dic
|
||||
print("Scenario 4: efficient with PV+4Pipe+DHW run successfully for Clusters")
|
||||
|
||||
def extract_HP_size(building):
|
||||
dic={
|
||||
# Heat Pump Rated Heating and Cooling Output
|
||||
'hp_heat_size': building.energy_systems[1].generation_systems[1].nominal_heat_output/1000,
|
||||
'hp_cooling_output': building.energy_systems[1].generation_systems[1].nominal_cooling_output/1000,
|
||||
# Boiler Rated Heat Output
|
||||
'boiler_heat_output': building.energy_systems[1].generation_systems[0].nominal_heat_output/1000,
|
||||
# TES characteristics
|
||||
'tes_volume':building.energy_systems[1].generation_systems[0].energy_storage_systems[0].volume,
|
||||
'tes_height':building.energy_systems[1].generation_systems[0].energy_storage_systems[0].height,
|
||||
# DHW HP
|
||||
'dhw_hp_heat_output': building.energy_systems[-1].generation_systems[0].nominal_heat_output/1000,
|
||||
# DHW TES Characteristics
|
||||
'dhw_tes_volume': building.energy_systems[-1].generation_systems[0].energy_storage_systems[0].volume,
|
||||
'dhw_tes_height': building.energy_systems[-1].generation_systems[0].energy_storage_systems[0].height,
|
||||
}
|
||||
|
||||
|
||||
return dic
|
||||
HPs={}
|
||||
for building in city.buildings:
|
||||
HPs[building.name]=extract_HP_size(building)
|
||||
|
||||
#%%-------------------------------------------------------
|
||||
#""""EXPORTERS"""
|
||||
#%%-------------------------------------------------------
|
||||
|
||||
|
||||
# Convert the dictionary to a DataFrame
|
||||
df = pd.DataFrame.from_dict(HPs, orient='index')
|
||||
|
||||
# Save the DataFrame to an Excel file
|
||||
output_path_HPs =output_path/ 'HPs_data_sc4.xlsx'
|
||||
df.to_excel(output_path_HPs, index_label='building_id')
|
||||
|
||||
print(f"Data successfully exported to {output_path}")
|
Loading…
Reference in New Issue
Block a user