feature: add pipe sizing to dhn analysis
This commit is contained in:
parent
2ca52c157a
commit
eb26c48627
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')
|
||||
|
||||
#%% --------------------------------------------------------------------------------------------------------------------
|
||||
|
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
|
||||
}
|
||||
]
|
1
main.py
1
main.py
@ -25,6 +25,7 @@ from scripts.pv_feasibility import pv_feasibility
|
||||
import matplotlib.pyplot as plt
|
||||
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)
|
||||
|
@ -1,32 +1,248 @@
|
||||
import networkx as nx
|
||||
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):
|
||||
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 attributes from the city buildings.
|
||||
"""
|
||||
Enrich the network graph nodes with the whole building object from the city buildings.
|
||||
|
||||
for node in self._network_graph.nodes(data=True):
|
||||
node_id, node_attrs = node
|
||||
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:
|
||||
building_attrs = vars(building)
|
||||
for attr, value in building_attrs.items():
|
||||
if attr not in self._network_graph.nodes[node_id]:
|
||||
self._network_graph.nodes[node_id][attr] = value
|
||||
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.")
|
||||
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']
|
||||
])
|
||||
|
@ -8,9 +8,8 @@ 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)
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
logging.getLogger("numexpr").setLevel(logging.ERROR)
|
||||
|
||||
def haversine(lon1, lat1, lon2, lat2):
|
||||
"""
|
||||
@ -30,17 +29,21 @@ def haversine(lon1, lat1, lon2, lat2):
|
||||
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):
|
||||
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.
|
||||
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:
|
||||
"""
|
||||
@ -57,7 +60,8 @@ class DistrictHeatingNetworkCreator:
|
||||
self._iteratively_remove_edges()
|
||||
self._add_centroids_to_mst()
|
||||
self._convert_edge_weights_to_meters()
|
||||
return self.final_mst
|
||||
self._create_final_network_graph()
|
||||
return self.network_graph
|
||||
except Exception as e:
|
||||
logging.error(f"Error during network creation: {e}")
|
||||
raise
|
||||
@ -73,6 +77,7 @@ class DistrictHeatingNetworkCreator:
|
||||
|
||||
self.centroids = []
|
||||
self.building_names = []
|
||||
self.building_positions = []
|
||||
buildings = city['features']
|
||||
for building in buildings:
|
||||
coordinates = building['geometry']['coordinates'][0]
|
||||
@ -80,6 +85,14 @@ class DistrictHeatingNetworkCreator:
|
||||
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:
|
||||
@ -184,7 +197,9 @@ class DistrictHeatingNetworkCreator:
|
||||
for line in self.cleaned_lines:
|
||||
coords = list(line.coords)
|
||||
for i in range(len(coords) - 1):
|
||||
self.G.add_edge(coords[i], coords[i + 1], weight=Point(coords[i]).distance(Point(coords[i + 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
|
||||
@ -284,24 +299,22 @@ class DistrictHeatingNetworkCreator:
|
||||
"""
|
||||
try:
|
||||
for i, centroid in enumerate(self.centroids):
|
||||
centroid_tuple = (centroid.x, centroid.y)
|
||||
building_name = self.building_names[i]
|
||||
|
||||
# Add the centroid node with its attributes
|
||||
self.final_mst.add_node(centroid_tuple, type='building', name=building_name)
|
||||
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':
|
||||
node_point = Point(node)
|
||||
distance = centroid.distance(node_point)
|
||||
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(centroid_tuple, nearest_point, weight=min_distance)
|
||||
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
|
||||
@ -312,22 +325,48 @@ class DistrictHeatingNetworkCreator:
|
||||
"""
|
||||
try:
|
||||
for u, v, data in self.final_mst.edges(data=True):
|
||||
lon1, lat1 = u
|
||||
lon2, lat2 = v
|
||||
distance = haversine(lon1, lat1, lon2, lat2)
|
||||
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: (node[0], node[1]) for node in self.final_mst.nodes()}
|
||||
nx.draw_networkx_nodes(self.final_mst, pos, node_color='blue', node_size=50)
|
||||
nx.draw_networkx_edges(self.final_mst, pos, edge_color='gray')
|
||||
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()
|
||||
|
@ -1,54 +0,0 @@
|
||||
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
|
@ -1,80 +0,0 @@
|
||||
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')
|
||||
|
||||
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
|
@ -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()
|
||||
|
@ -1,675 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "initial_id",
|
||||
"metadata": {
|
||||
"collapsed": true,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:38:47.230085Z",
|
||||
"start_time": "2024-07-31T21:38:47.206748Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"from pathlib import Path\n",
|
||||
"from scripts.district_heating_network.directory_manager import DirectoryManager\n",
|
||||
"import subprocess\n",
|
||||
"from scripts.ep_run_enrich import energy_plus_workflow\n",
|
||||
"from hub.imports.geometry_factory import GeometryFactory\n",
|
||||
"from hub.helpers.dictionaries import Dictionaries\n",
|
||||
"from hub.imports.construction_factory import ConstructionFactory\n",
|
||||
"from hub.imports.usage_factory import UsageFactory\n",
|
||||
"from hub.imports.weather_factory import WeatherFactory\n",
|
||||
"from hub.imports.results_factory import ResultFactory\n",
|
||||
"from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport\n",
|
||||
"from scripts.geojson_creator import process_geojson\n",
|
||||
"from scripts import random_assignation\n",
|
||||
"from hub.imports.energy_systems_factory import EnergySystemsFactory\n",
|
||||
"from scripts.energy_system_sizing import SystemSizing\n",
|
||||
"from scripts.solar_angles import CitySolarAngles\n",
|
||||
"from scripts.pv_sizing_and_simulation import PVSizingSimulation\n",
|
||||
"from scripts.energy_system_retrofit_results import consumption_data, cost_data\n",
|
||||
"from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory\n",
|
||||
"from scripts.costs.cost import Cost\n",
|
||||
"from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS\n",
|
||||
"import hub.helpers.constants as cte\n",
|
||||
"from hub.exports.exports_factory import ExportsFactory\n",
|
||||
"from scripts.pv_feasibility import pv_feasibility\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import numpy as np"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 110
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:38:47.861524Z",
|
||||
"start_time": "2024-07-31T21:38:47.843529Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"base_path = \"./\"\n",
|
||||
"dir_manager = DirectoryManager(base_path)\n",
|
||||
"\n",
|
||||
"# Input files directory\n",
|
||||
"input_files_path = dir_manager.create_directory('input_files')\n",
|
||||
"geojson_file_path = input_files_path / 'output_buildings.geojson'\n",
|
||||
"\n",
|
||||
"# Output files directory\n",
|
||||
"output_path = dir_manager.create_directory('out_files')\n",
|
||||
"\n",
|
||||
"# Subdirectories for output files\n",
|
||||
"energy_plus_output_path = dir_manager.create_directory('out_files/energy_plus_outputs')\n",
|
||||
"simulation_results_path = dir_manager.create_directory('out_files/simulation_results')\n",
|
||||
"sra_output_path = dir_manager.create_directory('out_files/sra_outputs')\n",
|
||||
"cost_analysis_output_path = dir_manager.create_directory('out_files/cost_analysis')"
|
||||
],
|
||||
"id": "7d895f0e4ec2b851",
|
||||
"outputs": [],
|
||||
"execution_count": 111
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:39:02.661096Z",
|
||||
"start_time": "2024-07-31T21:38:48.727802Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"location = [45.53067276979674, -73.70234652694087]\n",
|
||||
"process_geojson(x=location[1], y=location[0], diff=0.001)"
|
||||
],
|
||||
"id": "20dfb8fa42189fc2",
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"WindowsPath('C:/Users/ab_reza/Majid/Concordia/Repositories/energy_system_modelling_workflow/input_files/output_buildings.geojson')"
|
||||
]
|
||||
},
|
||||
"execution_count": 112,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"execution_count": 112
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:39:02.992446Z",
|
||||
"start_time": "2024-07-31T21:39:02.663422Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"city = GeometryFactory(file_type='geojson',\n",
|
||||
" path=geojson_file_path,\n",
|
||||
" height_field='height',\n",
|
||||
" year_of_construction_field='year_of_construction',\n",
|
||||
" function_field='function',\n",
|
||||
" function_to_hub=Dictionaries().montreal_function_to_hub_function).city"
|
||||
],
|
||||
"id": "c03ae7cae09d4b21",
|
||||
"outputs": [],
|
||||
"execution_count": 113
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:39:03.340164Z",
|
||||
"start_time": "2024-07-31T21:39:02.993466Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "ConstructionFactory('nrcan', city).enrich()",
|
||||
"id": "c7d73638802e40d9",
|
||||
"outputs": [],
|
||||
"execution_count": 114
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:39:04.079698Z",
|
||||
"start_time": "2024-07-31T21:39:03.342163Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "UsageFactory('nrcan', city).enrich()",
|
||||
"id": "4a8e272413233cc9",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"C:\\Users\\ab_reza\\Majid\\Concordia\\Repositories\\energy_system_modelling_workflow\\hub\\catalog_factories\\usage\\comnet_catalog.py:193: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n",
|
||||
" usage_type = usage_parameters[0]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 115
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:39:04.648022Z",
|
||||
"start_time": "2024-07-31T21:39:04.081700Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "WeatherFactory('epw', city).enrich()",
|
||||
"id": "f66c01cb42c33b64",
|
||||
"outputs": [],
|
||||
"execution_count": 116
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:40:39.688386Z",
|
||||
"start_time": "2024-07-31T21:39:04.650024Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "energy_plus_workflow(city, energy_plus_output_path)",
|
||||
"id": "c966b769566c173b",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"exporting:\n",
|
||||
" idf exported...\n",
|
||||
"\r\n",
|
||||
"C:/EnergyPlusV23-2-0\\energyplus.exe --weather C:\\Users\\ab_reza\\Majid\\Concordia\\Repositories\\energy_system_modelling_workflow\\hub\\data\\weather\\epw\\CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw --output-directory C:\\Users\\ab_reza\\Majid\\Concordia\\Repositories\\energy_system_modelling_workflow\\out_files\\energy_plus_outputs --idd C:\\Users\\ab_reza\\Majid\\Concordia\\Repositories\\energy_system_modelling_workflow\\hub\\exports\\building_energy\\idf_files\\Energy+.idd --expandobjects --readvars --output-prefix Laval_ C:\\Users\\ab_reza\\Majid\\Concordia\\Repositories\\energy_system_modelling_workflow\\out_files\\energy_plus_outputs\\Laval_602570.idf\r\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 117
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:53:14.440222Z",
|
||||
"start_time": "2024-07-31T21:53:10.290860Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"from scripts.district_heating_network.district_heating_network_creator import DistrictHeatingNetworkCreator\n",
|
||||
"from scripts.district_heating_network.road_processor import road_processor\n",
|
||||
"from pathlib import Path\n",
|
||||
"import time\n",
|
||||
"from scripts.district_heating_network.geojson_graph_creator import networkx_to_geojson\n",
|
||||
"roads_file = road_processor(location[1], location[0], 0.001)\n",
|
||||
"\n",
|
||||
"dhn_creator = DistrictHeatingNetworkCreator(geojson_file_path, roads_file)\n",
|
||||
"\n",
|
||||
"network_graph = dhn_creator.run()"
|
||||
],
|
||||
"id": "8403846b0831b51d",
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "AttributeError",
|
||||
"evalue": "'Graph' object has no attribute 'building_names'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
|
||||
"\u001B[1;31mAttributeError\u001B[0m Traceback (most recent call last)",
|
||||
"Cell \u001B[1;32mIn[121], line 11\u001B[0m\n\u001B[0;32m 8\u001B[0m dhn_creator \u001B[38;5;241m=\u001B[39m DistrictHeatingNetworkCreator(geojson_file_path, roads_file)\n\u001B[0;32m 10\u001B[0m network_graph \u001B[38;5;241m=\u001B[39m dhn_creator\u001B[38;5;241m.\u001B[39mrun()\n\u001B[1;32m---> 11\u001B[0m \u001B[43mnetwork_graph\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mbuilding_names\u001B[49m\n",
|
||||
"\u001B[1;31mAttributeError\u001B[0m: 'Graph' object has no attribute 'building_names'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 121
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:43:05.521839Z",
|
||||
"start_time": "2024-07-31T21:43:05.503748Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"for node_id, attrs in network_graph.nodes(data=True):\n",
|
||||
" print(f\"Node {node_id} has attributes: {list(attrs.keys())}\")"
|
||||
],
|
||||
"id": "9c4c32ed4a5b5434",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Node (-73.70263014634182, 45.52966550204674) has attributes: []\n",
|
||||
"Node (-73.70252245592799, 45.52959782722166) has attributes: []\n",
|
||||
"Node (-73.70277983402246, 45.52975956880018) has attributes: []\n",
|
||||
"Node (-73.70292834674622, 45.52985289718704) has attributes: []\n",
|
||||
"Node (-73.70299601156968, 45.52989541912497) has attributes: []\n",
|
||||
"Node (-73.70304798829301, 45.52992808234479) has attributes: []\n",
|
||||
"Node (-73.70315317772048, 45.52999418549968) has attributes: []\n",
|
||||
"Node (-73.70322951375971, 45.530042156604246) has attributes: []\n",
|
||||
"Node (-73.70334527410391, 45.53011490273612) has attributes: []\n",
|
||||
"Node (-73.70388612860485, 45.530454786598085) has attributes: []\n",
|
||||
"Node (-73.70321670301797, 45.53098320823811) has attributes: []\n",
|
||||
"Node (-73.70309371940914, 45.53090572804479) has attributes: []\n",
|
||||
"Node (-73.70336752508702, 45.53107818505422) has attributes: []\n",
|
||||
"Node (-73.70300302780161, 45.53115122842582) has attributes: []\n",
|
||||
"Node (-73.70298632291501, 45.53083806779961) has attributes: []\n",
|
||||
"Node (-73.70284664272657, 45.53075006869057) has attributes: []\n",
|
||||
"Node (-73.70282694240179, 45.530737657402696) has attributes: []\n",
|
||||
"Node (-73.70268296446567, 45.530646950694454) has attributes: []\n",
|
||||
"Node (-73.70262035905371, 45.53060750902034) has attributes: []\n",
|
||||
"Node (-73.70250974072788, 45.53053781900757) has attributes: []\n",
|
||||
"Node (-73.70248122664219, 45.530519855013075) has attributes: []\n",
|
||||
"Node (-73.70237692791034, 45.53045414637121) has attributes: []\n",
|
||||
"Node (-73.70241425825014, 45.52952983362164) has attributes: []\n",
|
||||
"Node (-73.70258909924681, 45.53147671471601) has attributes: []\n",
|
||||
"Node (-73.70246956317335, 45.531401341489406) has attributes: []\n",
|
||||
"Node (-73.70281850395438, 45.53162108764596) has attributes: []\n",
|
||||
"Node (-73.70235595692806, 45.53165968576366) has attributes: []\n",
|
||||
"Node (-73.70235908646175, 45.53133168062488) has attributes: []\n",
|
||||
"Node (-73.70226538550632, 45.5312725976791) has attributes: []\n",
|
||||
"Node (-73.7022262934011, 45.531247948232114) has attributes: []\n",
|
||||
"Node (-73.70218216283965, 45.53122012179686) has attributes: []\n",
|
||||
"Node (-73.7020876584622, 45.53116053225497) has attributes: []\n",
|
||||
"Node (-73.70208089954498, 45.53115627043355) has attributes: []\n",
|
||||
"Node (-73.70195718026818, 45.531078259496624) has attributes: []\n",
|
||||
"Node (-73.7019336727694, 45.53106343689135) has attributes: []\n",
|
||||
"Node (-73.70183972286668, 45.53100419697237) has attributes: []\n",
|
||||
"Node (-73.70182154258106, 45.53099273343045) has attributes: []\n",
|
||||
"Node (-73.70170504466955, 45.530919275910655) has attributes: []\n",
|
||||
"Node (-73.70169068527439, 45.5309102216234) has attributes: []\n",
|
||||
"Node (-73.70191018896638, 45.53200952628766) has attributes: []\n",
|
||||
"Node (-73.70343390828414, 45.5311199883841) has attributes: []\n",
|
||||
"Node (-73.70308928370066, 45.53179149942939) has attributes: []\n",
|
||||
"Node (-73.70154615235963, 45.53081908668964) has attributes: []\n",
|
||||
"Node (-73.70149535566978, 45.53078705694076) has attributes: []\n",
|
||||
"Node (-73.70139243548935, 45.530722160831516) has attributes: []\n",
|
||||
"Node (-73.70235555653572, 45.5304406823149) has attributes: []\n",
|
||||
"Node (-73.70223631048641, 45.530365556799865) has attributes: []\n",
|
||||
"Node (-73.70218808966641, 45.53033517747947) has attributes: []\n",
|
||||
"Node (-73.7020516180255, 45.53024919976893) has attributes: []\n",
|
||||
"Node (-73.70202483520858, 45.530232326481084) has attributes: []\n",
|
||||
"Node (-73.70189576536478, 45.53015101193401) has attributes: []\n",
|
||||
"Node (-73.70188535693748, 45.53014445458083) has attributes: []\n",
|
||||
"Node (-73.70176137113975, 45.53006634300427) has attributes: []\n",
|
||||
"Node (-73.70171679336974, 45.53003825882077) has attributes: []\n",
|
||||
"Node (-73.70161674578377, 45.52997522841877) has attributes: []\n",
|
||||
"Node (-73.70157021391765, 45.52994591314646) has attributes: []\n",
|
||||
"Node (-73.70145508528618, 45.52987338162208) has attributes: []\n",
|
||||
"Node (-73.7015262783945, 45.53176766055835) has attributes: []\n",
|
||||
"Node (-73.70142255824699, 45.531702316306436) has attributes: []\n",
|
||||
"Node (-73.70132694890151, 45.53164208190352) has attributes: []\n",
|
||||
"Node (-73.70249378379357, 45.529882494691094) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70236957992, 45.530697070843594) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7023772579133, 45.52982887967387) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70310348189996, 45.530242710105696) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70219141578475, 45.5309810002753) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015878987858, 45.53110506016847) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70197756808213, 45.531335127032875) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70171824652937, 45.53119684899265) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70181225980849, 45.53125598840158) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70212216033907, 45.53141309516707) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70224797036111, 45.531522088920134) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70319066728962, 45.53075184355254) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70309318391786, 45.53066844829803) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70326346262547, 45.53124343502157) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70289161913149, 45.53100954740511) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7031243168426, 45.52969124795911) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70332165936908, 45.531298238343524) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70291683392738, 45.531464843960194) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70257423757026, 45.53123533603945) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70246354979903, 45.53116600989907) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70137270924536, 45.53098156462814) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70228611728258, 45.52973374332967) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70192277090158, 45.530832193189546) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70247403248253, 45.530300013163604) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70233258364674, 45.53021274328478) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70150159992788, 45.530157998392504) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70178207574742, 45.53033147043354) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70279118480165, 45.53007116190442) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70290386342012, 45.53015742711493) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70199360008198, 45.529972641218336) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7032815855412, 45.52978985115031) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70166271484868, 45.53063422765041) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015006171488, 45.530550593136034) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70265213028476, 45.529962782747816) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7029326957311, 45.53056979610127) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70166661687237, 45.5297928936099) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70193452736822, 45.53043505670828) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70320906423977, 45.53033165241546) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70242433058544, 45.531020523149344) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70229173916934, 45.53104634226288) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70164581777142, 45.53024975981883) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70181323564402, 45.52988517687263) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70207977647193, 45.53050710203167) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70180201572698, 45.53073366018695) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70260551746348, 45.53038579346295) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015368490746, 45.531520903846236) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70277909755795, 45.530494359508104) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7016306503588, 45.531601992190964) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.703188128229, 45.531634438129004) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70225201894137, 45.5306050266003) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70250211711432, 45.53079519337939) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70143287673753, 45.53147394391961) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015564456529, 45.52971249323039) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70213321668199, 45.530060293550356) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70205098392802, 45.53092949418992) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70273955351598, 45.53092005042424) has attributes: ['type', 'id']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 119
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:29:21.717811Z",
|
||||
"start_time": "2024-07-31T21:29:21.697811Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"from scripts.district_heating_network.district_heating_factory import DistrictHeatingFactory\n",
|
||||
"\n",
|
||||
"DistrictHeatingFactory(city=city, graph=network_graph)"
|
||||
],
|
||||
"id": "25e14bd5433e3d95",
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "TypeError",
|
||||
"evalue": "__init__() got an unexpected keyword argument 'graph'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
|
||||
"\u001B[1;31mTypeError\u001B[0m Traceback (most recent call last)",
|
||||
"Cell \u001B[1;32mIn[94], line 3\u001B[0m\n\u001B[0;32m 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mscripts\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdistrict_heating_network\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdistrict_heating_factory\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m DistrictHeatingFactory\n\u001B[1;32m----> 3\u001B[0m \u001B[43mDistrictHeatingFactory\u001B[49m\u001B[43m(\u001B[49m\u001B[43mcity\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcity\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mgraph\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mnetwork_graph\u001B[49m\u001B[43m)\u001B[49m\n",
|
||||
"\u001B[1;31mTypeError\u001B[0m: __init__() got an unexpected keyword argument 'graph'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 94
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T21:18:46.818842Z",
|
||||
"start_time": "2024-07-31T21:18:46.799573Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"for node_id, attrs in network_graph.nodes(data=True):\n",
|
||||
" print(f\"Node {node_id} has attributes: {list(attrs.keys())}\")"
|
||||
],
|
||||
"id": "ad48fbc87a598b85",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Node (-73.70263014634182, 45.52966550204674) has attributes: []\n",
|
||||
"Node (-73.70252245592799, 45.52959782722166) has attributes: []\n",
|
||||
"Node (-73.70277983402246, 45.52975956880018) has attributes: []\n",
|
||||
"Node (-73.70292834674622, 45.52985289718704) has attributes: []\n",
|
||||
"Node (-73.70299601156968, 45.52989541912497) has attributes: []\n",
|
||||
"Node (-73.70304798829301, 45.52992808234479) has attributes: []\n",
|
||||
"Node (-73.70315317772048, 45.52999418549968) has attributes: []\n",
|
||||
"Node (-73.70322951375971, 45.530042156604246) has attributes: []\n",
|
||||
"Node (-73.70334527410391, 45.53011490273612) has attributes: []\n",
|
||||
"Node (-73.70388612860485, 45.530454786598085) has attributes: []\n",
|
||||
"Node (-73.70321670301797, 45.53098320823811) has attributes: []\n",
|
||||
"Node (-73.70309371940914, 45.53090572804479) has attributes: []\n",
|
||||
"Node (-73.70336752508702, 45.53107818505422) has attributes: []\n",
|
||||
"Node (-73.70300302780161, 45.53115122842582) has attributes: []\n",
|
||||
"Node (-73.70298632291501, 45.53083806779961) has attributes: []\n",
|
||||
"Node (-73.70284664272657, 45.53075006869057) has attributes: []\n",
|
||||
"Node (-73.70282694240179, 45.530737657402696) has attributes: []\n",
|
||||
"Node (-73.70268296446567, 45.530646950694454) has attributes: []\n",
|
||||
"Node (-73.70262035905371, 45.53060750902034) has attributes: []\n",
|
||||
"Node (-73.70250974072788, 45.53053781900757) has attributes: []\n",
|
||||
"Node (-73.70248122664219, 45.530519855013075) has attributes: []\n",
|
||||
"Node (-73.70237692791034, 45.53045414637121) has attributes: []\n",
|
||||
"Node (-73.70241425825014, 45.52952983362164) has attributes: []\n",
|
||||
"Node (-73.70258909924681, 45.53147671471601) has attributes: []\n",
|
||||
"Node (-73.70246956317335, 45.531401341489406) has attributes: []\n",
|
||||
"Node (-73.70281850395438, 45.53162108764596) has attributes: []\n",
|
||||
"Node (-73.70235595692806, 45.53165968576366) has attributes: []\n",
|
||||
"Node (-73.70235908646175, 45.53133168062488) has attributes: []\n",
|
||||
"Node (-73.70226538550632, 45.5312725976791) has attributes: []\n",
|
||||
"Node (-73.7022262934011, 45.531247948232114) has attributes: []\n",
|
||||
"Node (-73.70218216283965, 45.53122012179686) has attributes: []\n",
|
||||
"Node (-73.7020876584622, 45.53116053225497) has attributes: []\n",
|
||||
"Node (-73.70208089954498, 45.53115627043355) has attributes: []\n",
|
||||
"Node (-73.70195718026818, 45.531078259496624) has attributes: []\n",
|
||||
"Node (-73.7019336727694, 45.53106343689135) has attributes: []\n",
|
||||
"Node (-73.70183972286668, 45.53100419697237) has attributes: []\n",
|
||||
"Node (-73.70182154258106, 45.53099273343045) has attributes: []\n",
|
||||
"Node (-73.70170504466955, 45.530919275910655) has attributes: []\n",
|
||||
"Node (-73.70169068527439, 45.5309102216234) has attributes: []\n",
|
||||
"Node (-73.70191018896638, 45.53200952628766) has attributes: []\n",
|
||||
"Node (-73.70343390828414, 45.5311199883841) has attributes: []\n",
|
||||
"Node (-73.70308928370066, 45.53179149942939) has attributes: []\n",
|
||||
"Node (-73.70154615235963, 45.53081908668964) has attributes: []\n",
|
||||
"Node (-73.70149535566978, 45.53078705694076) has attributes: []\n",
|
||||
"Node (-73.70139243548935, 45.530722160831516) has attributes: []\n",
|
||||
"Node (-73.70235555653572, 45.5304406823149) has attributes: []\n",
|
||||
"Node (-73.70223631048641, 45.530365556799865) has attributes: []\n",
|
||||
"Node (-73.70218808966641, 45.53033517747947) has attributes: []\n",
|
||||
"Node (-73.7020516180255, 45.53024919976893) has attributes: []\n",
|
||||
"Node (-73.70202483520858, 45.530232326481084) has attributes: []\n",
|
||||
"Node (-73.70189576536478, 45.53015101193401) has attributes: []\n",
|
||||
"Node (-73.70188535693748, 45.53014445458083) has attributes: []\n",
|
||||
"Node (-73.70176137113975, 45.53006634300427) has attributes: []\n",
|
||||
"Node (-73.70171679336974, 45.53003825882077) has attributes: []\n",
|
||||
"Node (-73.70161674578377, 45.52997522841877) has attributes: []\n",
|
||||
"Node (-73.70157021391765, 45.52994591314646) has attributes: []\n",
|
||||
"Node (-73.70145508528618, 45.52987338162208) has attributes: []\n",
|
||||
"Node (-73.7015262783945, 45.53176766055835) has attributes: []\n",
|
||||
"Node (-73.70142255824699, 45.531702316306436) has attributes: []\n",
|
||||
"Node (-73.70132694890151, 45.53164208190352) has attributes: []\n",
|
||||
"Node (-73.70249378379357, 45.529882494691094) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70236957992, 45.530697070843594) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7023772579133, 45.52982887967387) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70310348189996, 45.530242710105696) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70219141578475, 45.5309810002753) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015878987858, 45.53110506016847) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70197756808213, 45.531335127032875) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70171824652937, 45.53119684899265) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70181225980849, 45.53125598840158) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70212216033907, 45.53141309516707) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70224797036111, 45.531522088920134) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70319066728962, 45.53075184355254) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70309318391786, 45.53066844829803) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70326346262547, 45.53124343502157) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70289161913149, 45.53100954740511) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7031243168426, 45.52969124795911) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70332165936908, 45.531298238343524) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70291683392738, 45.531464843960194) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70257423757026, 45.53123533603945) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70246354979903, 45.53116600989907) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70137270924536, 45.53098156462814) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70228611728258, 45.52973374332967) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70192277090158, 45.530832193189546) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70247403248253, 45.530300013163604) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70233258364674, 45.53021274328478) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70150159992788, 45.530157998392504) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70178207574742, 45.53033147043354) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70279118480165, 45.53007116190442) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70290386342012, 45.53015742711493) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70199360008198, 45.529972641218336) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7032815855412, 45.52978985115031) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70166271484868, 45.53063422765041) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015006171488, 45.530550593136034) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70265213028476, 45.529962782747816) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7029326957311, 45.53056979610127) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70166661687237, 45.5297928936099) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70193452736822, 45.53043505670828) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70320906423977, 45.53033165241546) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70242433058544, 45.531020523149344) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70229173916934, 45.53104634226288) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70164581777142, 45.53024975981883) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70181323564402, 45.52988517687263) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70207977647193, 45.53050710203167) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70180201572698, 45.53073366018695) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70260551746348, 45.53038579346295) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015368490746, 45.531520903846236) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70277909755795, 45.530494359508104) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7016306503588, 45.531601992190964) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.703188128229, 45.531634438129004) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70225201894137, 45.5306050266003) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70250211711432, 45.53079519337939) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70143287673753, 45.53147394391961) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.7015564456529, 45.52971249323039) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70213321668199, 45.530060293550356) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70205098392802, 45.53092949418992) has attributes: ['type', 'id']\n",
|
||||
"Node (-73.70273955351598, 45.53092005042424) has attributes: ['type', 'id']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 80
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T20:23:57.446448Z",
|
||||
"start_time": "2024-07-31T20:23:57.431469Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"for building in city.buildings:\n",
|
||||
" print(building.name)"
|
||||
],
|
||||
"id": "5b96a042e349e0eb",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"65418\n",
|
||||
"70816\n",
|
||||
"73478\n",
|
||||
"82649\n",
|
||||
"84906\n",
|
||||
"87241\n",
|
||||
"87719\n",
|
||||
"88675\n",
|
||||
"88747\n",
|
||||
"89061\n",
|
||||
"89062\n",
|
||||
"89251\n",
|
||||
"91214\n",
|
||||
"92337\n",
|
||||
"92399\n",
|
||||
"92520\n",
|
||||
"92979\n",
|
||||
"93149\n",
|
||||
"95265\n",
|
||||
"95266\n",
|
||||
"95465\n",
|
||||
"95704\n",
|
||||
"96241\n",
|
||||
"96579\n",
|
||||
"96580\n",
|
||||
"96930\n",
|
||||
"96931\n",
|
||||
"96996\n",
|
||||
"96997\n",
|
||||
"97648\n",
|
||||
"98087\n",
|
||||
"98666\n",
|
||||
"98667\n",
|
||||
"102035\n",
|
||||
"103043\n",
|
||||
"103740\n",
|
||||
"103795\n",
|
||||
"107302\n",
|
||||
"108296\n",
|
||||
"108297\n",
|
||||
"109211\n",
|
||||
"109305\n",
|
||||
"109773\n",
|
||||
"110561\n",
|
||||
"110873\n",
|
||||
"113368\n",
|
||||
"116927\n",
|
||||
"118062\n",
|
||||
"118250\n",
|
||||
"119143\n",
|
||||
"120435\n",
|
||||
"124177\n",
|
||||
"125538\n",
|
||||
"128322\n",
|
||||
"129429\n",
|
||||
"130498\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 75
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-07-31T19:35:10.949715Z",
|
||||
"start_time": "2024-07-31T19:35:09.846007Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "",
|
||||
"id": "2bb88967eb45bcec",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"IOPub data rate exceeded.\n",
|
||||
"The Jupyter server will temporarily stop sending output\n",
|
||||
"to the client in order to avoid crashing it.\n",
|
||||
"To change this limit, set the config variable\n",
|
||||
"`--ServerApp.iopub_data_rate_limit`.\n",
|
||||
"\n",
|
||||
"Current values:\n",
|
||||
"ServerApp.iopub_data_rate_limit=1000000.0 (bytes/sec)\n",
|
||||
"ServerApp.rate_limit_window=3.0 (secs)\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 52
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"execution_count": null,
|
||||
"source": "",
|
||||
"id": "f7c0742941b4f2d1"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
Loading…
Reference in New Issue
Block a user