Merge remote-tracking branch 'origin/retrofit_project' into retrofit_project

This commit is contained in:
Pilar Monsalvete 2023-06-06 16:09:44 -04:00
commit bd23185ca3
38 changed files with 45022 additions and 544061 deletions

View File

@ -44,8 +44,8 @@ class Building(CityObject):
self._aliases = None
self._type = 'building'
self._cold_water_temperature = {}
self._heating = {}
self._cooling = {}
self._heating_demand = {}
self._cooling_demand = {}
self._lighting_electrical_demand = {}
self._appliances_electrical_demand = {}
self._domestic_hot_water_heat_demand = {}
@ -84,7 +84,7 @@ class Building(CityObject):
elif surface.type == cte.INTERIOR_SLAB:
self._interior_slabs.append(surface)
else:
logging.error(f'Building {self.name} [{self.aliases}] has an unexpected surface type {surface.type}.\n')
logging.error(f'Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
@property
def shell(self) -> Polyhedron:
@ -289,15 +289,15 @@ class Building(CityObject):
self._cold_water_temperature = value
@property
def heating(self) -> dict:
def heating_demand(self) -> dict:
"""
Get heating demand in Wh
:return: dict{DataFrame(float)}
"""
return self._heating
return self._heating_demand
@heating.setter
def heating(self, value):
@heating_demand.setter
def heating_demand(self, value):
"""
Set heating demand in Wh
:param value: dict{DataFrame(float)}
@ -305,15 +305,15 @@ class Building(CityObject):
self._heating = value
@property
def cooling(self) -> dict:
def cooling_demand(self) -> dict:
"""
Get cooling demand in Wh
:return: dict{DataFrame(float)}
"""
return self._cooling
return self._cooling_demand
@cooling.setter
def cooling(self, value):
@cooling_demand.setter
def cooling_demand(self, value):
"""
Set cooling demand in Wh
:param value: dict{DataFrame(float)}
@ -375,9 +375,9 @@ class Building(CityObject):
:return: dict{DataFrame(float)}
"""
results = {}
if cte.HOUR in self.heating:
if cte.HOUR in self.heating_demand:
monthly_values = PeakLoads().\
peak_loads_from_hourly(self.heating[cte.HOUR][next(iter(self.heating[cte.HOUR]))])
peak_loads_from_hourly(self.heating_demand[cte.HOUR][next(iter(self.heating_demand[cte.HOUR]))])
else:
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
if monthly_values is None:
@ -393,8 +393,8 @@ class Building(CityObject):
:return: dict{DataFrame(float)}
"""
results = {}
if cte.HOUR in self.cooling:
monthly_values = PeakLoads().peak_loads_from_hourly(self.cooling[cte.HOUR][next(iter(self.cooling[cte.HOUR]))])
if cte.HOUR in self.cooling_demand:
monthly_values = PeakLoads().peak_loads_from_hourly(self.cooling_demand[cte.HOUR][next(iter(self.cooling_demand[cte.HOUR]))])
else:
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
if monthly_values is None:
@ -560,8 +560,8 @@ class Building(CityObject):
return: dict
"""
if len(self._heating_consumption) == 0:
for heating_demand_key in self.heating:
demand = self.heating[heating_demand_key][cte.INSEL_MEB]
for heating_demand_key in self.heating_demand:
demand = self.heating_demand[heating_demand_key][cte.INSEL_MEB]
consumption_type = cte.HEATING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
if final_energy_consumed is None:
@ -576,8 +576,8 @@ class Building(CityObject):
return: dict
"""
if len(self._cooling_consumption) == 0:
for cooling_demand_key in self.cooling:
demand = self.cooling[cooling_demand_key][cte.INSEL_MEB]
for cooling_demand_key in self.cooling_demand:
demand = self.cooling_demand[cooling_demand_key][cte.INSEL_MEB]
consumption_type = cte.COOLING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
if final_energy_consumed is None:
@ -656,18 +656,18 @@ class Building(CityObject):
if demand_type.lower() == cte.HEATING.lower():
if _peak_load_type == cte.HEATING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for heating_demand_key in self.heating:
_consumption = [0]*len(self.heating[heating_demand_key][cte.INSEL_MEB])
_demand = self.heating[heating_demand_key][cte.INSEL_MEB]
for heating_demand_key in self.heating_demand:
_consumption = [0]*len(self.heating_demand[heating_demand_key][cte.INSEL_MEB])
_demand = self.heating_demand[heating_demand_key][cte.INSEL_MEB]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[heating_demand_key] = _consumption
if demand_type.lower() == cte.COOLING.lower():
if _peak_load_type == cte.COOLING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for demand_key in self.cooling:
for demand_key in self.cooling_demand:
_consumption = self._distribution_systems_electrical_consumption[demand_key]
_demand = self.cooling[demand_key][cte.INSEL_MEB]
_demand = self.cooling_demand[demand_key][cte.INSEL_MEB]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[demand_key] = _consumption

View File

@ -520,10 +520,10 @@ class ThermalZone:
if _schedules_defined:
_schedules = []
for day, _ in enumerate(_days):
for day_index, day in enumerate(_days):
_schedule = copy.deepcopy(_base_schedule)
_schedule.day_types = [_days[day]]
_schedule.values = values[:day]
_schedule.day_types = [day]
_schedule.values = values[:day_index]
_schedules.append(_schedule)
_internal_gain.average_internal_gain = _average_internal_gain

View File

@ -82,11 +82,19 @@ class City:
@property
def country_code(self):
"""
Get models country code
Get city country code
:return: str
"""
return self._get_location().country
@property
def region_code(self):
"""
Get city region name
:return: str
"""
return self._get_location().region_code
@property
def location(self) -> Location:
"""

File diff suppressed because it is too large Load Diff

2
hub/data/weather/epw/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,7 @@ class SimplifiedRadiosityAlgorithm:
def _export_sra_cli(self):
file = self._city.climate_file
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
WeatherFactory(self._weather_format, self._city, file_name=self._weather_file).enrich()
WeatherFactory(self._weather_format, self._city).enrich()
content = self._city.name + '\n'
content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\n'
content += '\ndm m h G_Dh G_Bn\n'

View File

@ -295,6 +295,7 @@ class GeometryHelper:
distance = math.inf
country = 'Unknown'
city = 'Unknown'
region_code = 'Unknown'
with open(_data_path, 'r', encoding='utf-8') as file:
for _, line in enumerate(file):
fields = line.split('\t')
@ -302,12 +303,16 @@ class GeometryHelper:
file_latitude = float(fields[4])
file_longitude = float(fields[5])
file_country_code = fields[8]
admin1_code = fields[10]
admin2_code = fields[11]
new_distance = math.sqrt(pow((latitude - file_latitude), 2) + pow((longitude - file_longitude), 2))
if distance > new_distance:
distance = new_distance
country = file_country_code
city = file_city_name
return Location(country, city)
region_code = f'{file_country_code}.{admin1_code}.{admin2_code}'
return Location(country, city, region_code)
@staticmethod
def distance_between_points(vertex1, vertex2):

View File

@ -11,20 +11,28 @@ class Location:
"""
Location
"""
def __init__(self, country, city):
def __init__(self, country, city, region_code):
self._country = country
self._city = city
self._region_code = region_code
@property
def city(self):
"""
City name
Get city name
"""
return self._city
@property
def country(self):
"""
Country code
Get country code
"""
return self._country
@property
def region_code(self):
"""
Get region
"""
return self._region_code

View File

@ -35,16 +35,16 @@ class NrcanPhysicsParameters:
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
for building in city.buildings:
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function.keys():
logging.error(f'Building {building.name} has an unknown building function {building.function}\n')
logging.error(f'Building %s has an unknown building function %s', building.name, building.function )
continue
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
try:
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
except KeyError:
logging.error(f'Building {building.name} has unknown construction archetype for building function: {function} '
f'[{building.function}], building year of construction: {building.year_of_construction} '
f'and climate zone {self._climate_zone}\n')
logging.error(f'Building %s has unknown construction archetype for building function: %s '
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, self._climate_zone)
continue
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
@ -100,7 +100,7 @@ class NrcanPhysicsParameters:
thermal_boundary.construction_name = construction_archetype.name
try:
thermal_boundary.window_ratio = 0
if thermal_boundary.type == cte.WALL or thermal_boundary.type == cte.ROOF:
if thermal_boundary.type in ( cte.WALL, cte.ROOF):
if construction_archetype.window is not None:
if -math.sqrt(2) / 2 < math.sin(thermal_boundary.parent_surface.azimuth) < math.sqrt(2) / 2:
if 0 < math.cos(thermal_boundary.parent_surface.azimuth):

View File

@ -32,11 +32,8 @@ class NrelPhysicsParameters:
city = self._city
nrel_catalog = ConstructionCatalogFactory('nrel').catalog
for building in city.buildings:
if building.function not in Dictionaries().hub_function_to_nrel_construction_function.keys():
logging.error(f'Building {building.name} has unknown function [{building.function}]')
continue
if building.function not in Dictionaries().hub_function_to_nrel_construction_function.keys():
logging.error(f'Building {building.name} has unknown function {building.function}\n')
if building.function not in Dictionaries().hub_function_to_nrel_construction_function:
logging.error(f'Building %s has unknown function %s', building.name, building.function)
continue
function = Dictionaries().hub_function_to_nrel_construction_function[building.function]
try:

View File

@ -117,11 +117,11 @@ class InselMonthlyEnergyBalance:
file_name = building.name + '.out'
insel_output_file_path = Path(self._base_path / file_name).resolve()
if insel_output_file_path.is_file():
building.heating[cte.MONTH], building.cooling[cte.MONTH] = self._conditioning_demand(insel_output_file_path)
building.heating[cte.YEAR] = pd.DataFrame(
[building.heating[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB]
building.heating_demand[cte.MONTH], building.cooling_demand[cte.MONTH] = self._conditioning_demand(insel_output_file_path)
building.heating_demand[cte.YEAR] = pd.DataFrame(
[building.heating_demand[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB]
)
building.cooling[cte.YEAR] = pd.DataFrame(
[building.cooling[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB]
building.cooling_demand[cte.YEAR] = pd.DataFrame(
[building.cooling_demand[cte.MONTH][cte.INSEL_MEB].astype(float).sum()], columns=[cte.INSEL_MEB]
)
self._dhw_and_electric_demand()

View File

@ -1,57 +0,0 @@
"""
DatWeatherParameters class to extract weather parameters from a defined region in .dat format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
import sys
from pathlib import Path
import pandas as pd
import hub.helpers.constants as cte
class DatWeatherParameters:
"""
DatWeatherParameters class
"""
def __init__(self, city, path):
self._weather_values = None
self._city = city
self._city_name = city.climate_reference_city
file_name = 'inseldb_' + self._city_name + '.dat'
self._path = Path(path / file_name)
if self._weather_values is None:
try:
self._weather_values = pd.read_csv(self._path, sep=r'\s+', header=None,
names=['hour', 'global_horiz', 'temperature', 'diffuse', 'beam', 'empty'])
except SystemExit:
logging.Logger(f'Error: weather file {self._path} not found\n')
sys.exit()
for building in self._city.buildings:
new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.external_temperature:
building.external_temperature[cte.HOUR] = new_value
else:
pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.global_horizontal:
building.global_horizontal[cte.HOUR] = new_value
else:
pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['diffuse']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.diffuse:
building.diffuse[cte.HOUR] = new_value
else:
pd.concat([building.diffuse[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['beam']].to_numpy(), columns=['inseldb'])
if cte.HOUR not in building.beam:
building.beam[cte.HOUR] = new_value
else:
pd.concat([building.beam[cte.HOUR], new_value], axis=1)

View File

@ -7,8 +7,12 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import logging
import sys
from pathlib import Path
import pandas as pd
import requests
import hub.helpers.constants as cte
from hub.city_model_structure.city import City
from hub.imports.weather.helpers.weather import Weather as wh
@ -16,10 +20,14 @@ class EpwWeatherParameters:
"""
EpwWeatherParameters class
"""
def __init__(self, city, path, file_name):
def __init__(self, city: City):
self._weather_values = None
self._city = city
self._path = Path(path / file_name)
self._url = wh().epw_file(city.region_code)
self._path = (Path(__file__).parent.parent.parent / f'data/weather/epw/{self._url.rsplit("/", 1)[1]}').resolve()
if not self._path.exists():
with open(self._path, 'wb') as epw_file:
epw_file.write(requests.get(self._url, allow_redirects=True).content)
try:
with open(self._path, 'r', encoding='utf8') as file:

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
import math
import calendar as cal
import pandas as pd
@ -17,6 +17,14 @@ class Weather:
Weather class
"""
# todo: this dictionary need to be completed, a data science student task?
_epw_file = {
'CA.02.5935': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/BC/CAN_BC_Summerland.717680_CWEC/CAN_BC_Summerland.717680_CWEC.epw',
'CA.10.06': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Montreal.Intl.AP.716270_CWEC/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw',
'DE.01.082': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/DEU/DEU_Stuttgart.107380_IWEC/DEU_Stuttgart.107380_IWEC.epw',
'US.NY.047': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/USA/NY/USA_NY_New.York.City-Central.Park.94728_TMY/USA_NY_New.York.City-Central.Park.94728_TMY.epw'
}
@staticmethod
def sky_temperature(ambient_temperature):
"""
@ -111,3 +119,13 @@ class Weather:
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=['month'])
def epw_file(self, region_code):
"""
returns the url for the weather file for the given location or default (Montreal data)
:return: str
"""
if region_code not in self._epw_file:
logging.warning('Specific weather data unknown for %s using Montreal data instead', region_code)
return self._epw_file['CA.10.06']
return self._epw_file[region_code]

View File

@ -1,48 +0,0 @@
"""
XlsWeatherParameters class to extract weather parameters from a defined region in .xls format
defined and used by the norm iso 52016-1:2017
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import sys
from pathlib import Path
import pandas as pd
import hub.helpers.constants as cte
class XlsWeatherParameters:
"""
XlsWeatherParameters class
"""
def __init__(self, city, path, name):
self._weather_values = None
self._city = city
self._file_name = name
file_name = self._file_name + '.xls'
self._path = Path(path / file_name)
if self._weather_values is None:
try:
self._weather_values = pd.read_excel(self._path, skiprows=4, nrows=9504,
names=['hours_calc', 'month', 'week', 'day_of_week', 'hours_of_day',
'temperature', 'I_sol_vertical_N', 'I_sol_vertical_E',
'I_sol_vertical_S', 'I_sol_vertical_W', 'I_sol_45_N', 'I_sol_45_S',
'void', 'global_horiz', 'wind_velocity', 'humidity'])
except SystemExit:
sys.stderr.write(f'Error reading weather file {self._path}\n')
sys.exit()
for building in self._city.buildings:
new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['iso52016'])
if cte.HOUR not in building.external_temperature:
building.external_temperature[cte.HOUR] = new_value
else:
pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1)
new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['iso52016'])
if cte.HOUR not in building.global_horizontal:
building.global_horizontal[cte.HOUR] = new_value
else:
pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1)

View File

@ -6,9 +6,9 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from pathlib import Path
from hub.city_model_structure.city import City
from hub.helpers.utils import validate_import_export_type
from hub.imports.weather.epw_weather_parameters import EpwWeatherParameters
from hub.imports.weather.xls_weather_parameters import XlsWeatherParameters
class WeatherFactory:
@ -16,14 +16,10 @@ class WeatherFactory:
WeatherFactory class
"""
def __init__(self, handler, city, base_path=None, file_name=None):
if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/weather')
def __init__(self, handler, city: City):
self._handler = '_' + handler.lower().replace(' ', '_')
validate_import_export_type(WeatherFactory, handler)
self._city = city
self._base_path = base_path
self._file_name = file_name
def _epw(self):
"""
@ -32,15 +28,7 @@ class WeatherFactory:
# EnergyPlus Weather
# to download files: https://energyplus.net/weather
# description of the format: https://energyplus.net/sites/default/files/pdfs_v8.3.0/AuxiliaryPrograms.pdf
_path = Path(self._base_path / 'epw').resolve()
return EpwWeatherParameters(self._city, _path, self._file_name)
def _xls(self):
"""
Enrich the city with ISO_52016_1_BESTEST_ClimData_2016.08.24 weather file
"""
name = 'ISO_52016_1_BESTEST_ClimData_2016.08.24'
return XlsWeatherParameters(self._city, self._base_path, name)
return EpwWeatherParameters(self._city)
def enrich(self):
"""

View File

@ -211,4 +211,3 @@ class DBControl:
:param application_uuid: the id of the application to get
"""
self._application.delete(application_uuid)

View File

@ -22,7 +22,6 @@ class TestCityMerge(TestCase):
"""
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
self._weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
self._executable = 'sra'
def _get_citygml(self, file):

View File

@ -96,8 +96,8 @@ class TestConstructionFactory(TestCase):
self.assertIsNotNone(building.function, 'building function is none')
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
self.assertEqual(len(building.heating_demand), 0, 'building heating is not none')
self.assertEqual(len(building.cooling_demand), 0, 'building cooling is not none')
self.assertIsNotNone(building.eave_height, 'building eave height is none')
self.assertIsNotNone(building.roof_type, 'building roof type is none')
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
@ -264,7 +264,7 @@ class TestConstructionFactory(TestCase):
self._check_thermal_openings(thermal_boundary)
self._check_surfaces(thermal_boundary)
file_path = (self._example_path / 'concordia.geojson').resolve()
file_path = (self._example_path / 'test.geojson').resolve()
self._city = GeometryFactory('geojson',
path=file_path,
height_field='citygml_me',

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
from pathlib import Path
from unittest import TestCase
import pandas as pd
@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance
"""
city = self._get_citygml('one_building_in_kelowna.gml')
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', city).enrich()
for building in city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']])
@ -147,6 +147,6 @@ class TestExports(TestCase):
# export files
try:
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self._output_path, 'MEB_Montreal').export()
except Exception:
print(Exception)
except Exception as err:
logging.exception(err)
self.fail("Insel MonthlyEnergyBalance ExportsFactory raised ExceptionType unexpectedly!")

View File

@ -79,7 +79,7 @@ class Control:
function_to_hub=Dictionaries().alkis_function_to_hub_function).city
ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', self._city).enrich()
ExportsFactory('sra', self._city, output_path, weather_file=weather_file, weather_format='epw').export()
sra_file = str((output_path / f'{self._city.name}_sra.xml').resolve())
subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL)
@ -198,17 +198,17 @@ TestDBFactory
city_objects_id = []
for building in control.city.buildings:
_building = control.database.building_info(building.name, city_id)
if cte.MONTH not in building.cooling:
if cte.MONTH not in building.cooling_demand:
print(f'building {building.name} not calculated')
continue
monthly_cooling_peak_load = building.cooling_peak_load[cte.MONTH]
yearly_cooling_peak_load = building.cooling_peak_load[cte.YEAR]
monthly_heating_peak_load = building.heating_peak_load[cte.MONTH]
yearly_heating_peak_load = building.heating_peak_load[cte.YEAR]
monthly_cooling_demand = building.cooling[cte.MONTH][cte.INSEL_MEB]
yearly_cooling_demand = building.cooling[cte.YEAR][cte.INSEL_MEB]
monthly_heating_demand = building.heating[cte.MONTH][cte.INSEL_MEB]
yearly_heating_demand = building.heating[cte.YEAR][cte.INSEL_MEB]
monthly_cooling_demand = building.cooling_demand[cte.MONTH][cte.INSEL_MEB]
yearly_cooling_demand = building.cooling_demand[cte.YEAR][cte.INSEL_MEB]
monthly_heating_demand = building.heating_demand[cte.MONTH][cte.INSEL_MEB]
yearly_heating_demand = building.heating_demand[cte.YEAR][cte.INSEL_MEB]
monthly_lighting_electrical_demand = building.lighting_electrical_demand[cte.MONTH][cte.INSEL_MEB]
yearly_lighting_electrical_demand = building.lighting_electrical_demand[cte.YEAR][cte.INSEL_MEB]
monthly_appliances_electrical_demand = building.appliances_electrical_demand[cte.MONTH][cte.INSEL_MEB]

View File

@ -58,10 +58,10 @@ class TestExports(TestCase):
self._complete_city.climate_reference_city = 'Summerland'
dummy_measures = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
for building in self._complete_city.buildings:
building.heating[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures})
building.cooling[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures})
building.heating[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]})
building.cooling[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]})
building.heating_demand[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures})
building.cooling_demand[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures})
building.heating_demand[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]})
building.cooling_demand[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]})
return self._complete_city
def _export(self, export_type, from_pickle=False):
@ -110,7 +110,7 @@ class TestExports(TestCase):
ConstructionFactory('nrcan', city).enrich()
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', city).enrich()
try:
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
except Exception:

View File

@ -68,8 +68,8 @@ class TestGeometryFactory(TestCase):
self.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
self.assertEqual(len(building.heating_demand), 0, 'building heating is not none')
self.assertEqual(len(building.cooling_demand), 0, 'building cooling is not none')
self.assertIsNotNone(building.eave_height, 'building eave height is none')
self.assertIsNotNone(building.roof_type, 'building roof type is none')
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
@ -134,25 +134,25 @@ class TestGeometryFactory(TestCase):
"""
Test geojson import
"""
file = Path(self._example_path / '2000_buildings.geojson').resolve()
file = Path(self._example_path / 'test.geojson').resolve()
city = GeometryFactory('geojson',
path=file,
height_field='building_height',
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
aliases_field=['ID_UEV', 'CIVIQUE_DE', 'NOM_RUE'],
function_field='CODE_UTILI',
function_to_hub=MontrealFunctionToHubFunction().dictionary).city
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
for building in city.building_alias('01040584'):
self.assertEqual('0', building.name, 'Wrong building name when looking for alias')
self.assertEqual(14, len(city.building_alias('rue Sherbrooke Ouest (MTL+MTO+WMT)')))
self.assertEqual(1964, len(city.buildings), 'wrong number of buildings')
for building in city.building_alias('01002777'):
self.assertEqual('1', building.name, 'Wrong building name when looking for alias')
self.assertEqual(8, len(city.building_alias('rue Sherbrooke Ouest (MTL+MTO+WMT)')))
self.assertEqual(17, len(city.buildings), 'wrong number of buildings')
def test_map_neighbours(self):
"""
Test neighbours map creation
"""
file = 'neighbours.geojson'
file = 'test.geojson'
city = self._get_city(file, 'geojson',
year_of_construction_field='ANNEE_CONS',
@ -165,12 +165,24 @@ class TestGeometryFactory(TestCase):
info_lod1 = GeometryHelper.city_mapping(city, plot=False)
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
self.assertEqual(info_lod0, info_lod1)
for building in city.buildings:
self.assertEqual(2, len(building.neighbours))
self.assertEqual(2, len(city.city_object('1').neighbours))
self.assertEqual(3, len(city.city_object('2').neighbours))
self.assertEqual(2, len(city.city_object('3').neighbours))
self.assertEqual(2, len(city.city_object('4').neighbours))
self.assertEqual(3, len(city.city_object('5').neighbours))
self.assertEqual(3, len(city.city_object('6').neighbours))
self.assertEqual(1, len(city.city_object('8').neighbours))
self.assertEqual(2, len(city.city_object('9').neighbours))
self.assertEqual(2, len(city.city_object('10').neighbours))
self.assertEqual(2, len(city.city_object('11').neighbours))
self.assertEqual(2, len(city.city_object('12').neighbours))
self.assertEqual(1, len(city.city_object('13').neighbours))
self.assertEqual(2, len(city.city_object('14').neighbours))
self.assertEqual(1, len(city.city_object('15').neighbours))
self.assertEqual(1, len(city.city_object('16').neighbours))
self.assertEqual(2, len(city.city_object('67').neighbours))
self.assertEqual(1, len(city.city_object('68').neighbours))
self.assertEqual('2', city.city_object('1').neighbours[0].name)
self.assertEqual('3', city.city_object('1').neighbours[1].name)
self.assertEqual('1', city.city_object('2').neighbours[0].name)
self.assertEqual('3', city.city_object('2').neighbours[1].name)
self.assertEqual('1', city.city_object('3').neighbours[0].name)
self.assertEqual('2', city.city_object('3').neighbours[1].name)
self.assertEqual('12', city.city_object('8').neighbours[0].name)
self.assertEqual('14', city.city_object('13').neighbours[0].name)
self.assertEqual('14', city.city_object('15').neighbours[0].name)

View File

@ -31,7 +31,7 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', city).enrich()
vegetation_name = 'BaseEco'
soil_thickness = 0.18
soil_name = 'EcoRoofSoil'
@ -73,6 +73,6 @@ class GreeneryInIdf(TestCase):
building.year_of_construction = 2006
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', city).enrich()
_idf = EnergyBuildingsExportsFactory('idf', city, output_path).export()
self.assertIsNotNone(_idf)

View File

@ -83,7 +83,7 @@ class TestExports(TestCase):
export to Insel MonthlyEnergyBalance
"""
city = self._get_citygml('one_building_in_kelowna.gml')
WeatherFactory('epw', city, file_name='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').enrich()
WeatherFactory('epw', city).enrich()
for building in city.buildings:
building.external_temperature[cte.MONTH] = MonthlyValues().\
get_mean_values(building.external_temperature[cte.HOUR][['epw']])

View File

@ -39,8 +39,7 @@ class TestResultsImport(TestCase):
UsageFactory('nrcan', self._city).enrich()
def test_sra_import(self):
weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
ExportsFactory('sra', self._city, self._output_path, weather_file=weather_file, weather_format='epw').export()
ExportsFactory('sra', self._city, self._output_path).export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', self._city, self._output_path).enrich()
@ -50,8 +49,7 @@ class TestResultsImport(TestCase):
self.assertIsNotNone(surface.global_irradiance)
def test_meb_import(self):
weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
ExportsFactory('sra', self._city, self._output_path, weather_file=weather_file, weather_format='epw').export()
ExportsFactory('sra', self._city, self._output_path, weather_file='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw', weather_format='epw').export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', self._city, self._output_path).enrich()
@ -62,15 +60,14 @@ class TestResultsImport(TestCase):
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
# Check that all the buildings have heating and cooling values
for building in self._city.buildings:
self.assertIsNotNone(building.heating[cte.MONTH][cte.INSEL_MEB])
self.assertIsNotNone(building.cooling[cte.MONTH][cte.INSEL_MEB])
self.assertIsNotNone(building.heating[cte.YEAR][cte.INSEL_MEB])
self.assertIsNotNone(building.cooling[cte.YEAR][cte.INSEL_MEB])
self.assertIsNotNone(building.heating_demand[cte.MONTH][cte.INSEL_MEB])
self.assertIsNotNone(building.cooling_demand[cte.MONTH][cte.INSEL_MEB])
self.assertIsNotNone(building.heating_demand[cte.YEAR][cte.INSEL_MEB])
self.assertIsNotNone(building.cooling_demand[cte.YEAR][cte.INSEL_MEB])
def test_peak_loads(self):
# todo: this is not technically a import
weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
ExportsFactory('sra', self._city, self._output_path, weather_file=weather_file, weather_format='epw').export()
ExportsFactory('sra', self._city, self._output_path, weather_file='CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw', weather_format='epw').export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', self._city, self._output_path).enrich()
@ -83,7 +80,7 @@ class TestResultsImport(TestCase):
expected_monthly_list = [0 for _ in range(12)]
expected_monthly_list[0] = 1000
for building in self._city.buildings:
building.heating[cte.HOUR] = pd.DataFrame(values, columns=['dummy'])
building.cooling[cte.HOUR] = pd.DataFrame(values, columns=['dummy'])
building.heating_demand[cte.HOUR] = pd.DataFrame(values, columns=['dummy'])
building.cooling_demand[cte.HOUR] = pd.DataFrame(values, columns=['dummy'])
self.assertIsNotNone(building.heating_peak_load)
self.assertIsNotNone(building.cooling_peak_load)

View File

@ -16,6 +16,7 @@ from hub.exports.exports_factory import ExportsFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.weather_factory import WeatherFactory
from hub.imports.results_factory import ResultFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.energy_systems_factory import EnergySystemsFactory
@ -57,8 +58,8 @@ class TestSystemsFactory(TestCase):
"""
ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich()
weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
ExportsFactory('sra', self._city, self._output_path, weather_file=weather_file, weather_format='epw').export()
WeatherFactory('epw', self._city).enrich()
ExportsFactory('sra', self._city, self._output_path).export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', self._city, self._output_path).enrich()
@ -111,5 +112,4 @@ class TestSystemsFactory(TestCase):
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
print(building.heating_consumption[cte.YEAR][0], building.cooling_consumption[cte.YEAR][0], building.domestic_hot_water_consumption[cte.YEAR][0], building.onsite_electrical_production[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])

View File

@ -59,8 +59,8 @@ class TestUsageFactory(TestCase):
self.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
self.assertIsNotNone(building.function, 'building function is none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
self.assertEqual(len(building.heating_demand), 0, 'building heating is not none')
self.assertEqual(len(building.cooling_demand), 0, 'building cooling is not none')
self.assertIsNotNone(building.eave_height, 'building eave height is none')
self.assertIsNotNone(building.roof_type, 'building roof type is none')
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
@ -130,7 +130,7 @@ class TestUsageFactory(TestCase):
"""
Enrich the city with the usage information from nrcan and verify it
"""
file = 'concordia.geojson'
file = 'test.geojson'
file_path = (self._example_path / file).resolve()
city = GeometryFactory('geojson',
path=file_path,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,594 +0,0 @@
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"id":1,
"geometry":{
"type":"Polygon",
"coordinates":[
[
[
-73.580414175680588,
45.497641136608358
],
[
-73.580414175680588,
45.498641136608358
],
[
-73.581414175680588,
45.498641136608358
],
[
-73.581414175680588,
45.497641136608358
],
[
-73.580414175680588,
45.497641136608358
]
]
]
},
"properties":{
"OBJECTID_12":1,
"gml_id":"1340908",
"gml_parent":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_ta":"http://www.opengis.net/citygml/building/2.0",
"citygml_fe":"cityObjectMember",
"citygml__1":" ",
"citygml__2":" ",
"gml_descri":" ",
"gml_name":" ",
"citygml_cr":" ",
"citygml_te":" ",
"externalRe":" ",
"external_1":" ",
"external_2":" ",
"citygml_ge":" ",
"citygml_re":" ",
"citygml__3":" ",
"citygml_ap":" ",
"citygml_cl":" ",
"citygml__4":" ",
"citygml_fu":" ",
"citygml__5":" ",
"citygml_us":" ",
"citygml__6":" ",
"citygml_ye":" ",
"citygml__7":" ",
"citygml_ro":" ",
"citygml__8":" ",
"citygml_me":21.824000000000002,
"citygml__9":"#m",
"citygml_st":" ",
"citygml_10":" ",
"citygml_11":" ",
"citygml_12":" ",
"citygml_13":" ",
"citygml_14":" ",
"citygml_ou":" ",
"citygml_in":" ",
"citygml_bo":" ",
"citygml_le":" ",
"citygml_15":" ",
"citygml_co":" ",
"citygml_ad":" ",
"Volume":"2783.169",
"parcelle":" ",
"OBJECTID":778,
"gml_id_1":"ebc7f916-d094-4de0-8c35-fc18eb8622f2",
"gml_pare_1":"1340908",
"citygml_16":"http://www.opengis.net/citygml/building/2.0",
"citygml_17":"boundedBy",
"citygml_18":" ",
"citygml_19":" ",
"gml_desc_1":" ",
"gml_name_1":" ",
"citygml_20":" ",
"citygml_21":" ",
"external_3":" ",
"external_4":" ",
"external_5":" ",
"citygml_22":" ",
"citygml_23":" ",
"citygml_24":" ",
"citygml_25":" ",
"citygml_26":" ",
"citygml_op":" ",
"Area":"229.287",
"FID_":0,
"Join_Count":2,
"TARGET_FID":779,
"gml_id_12":"1340908",
"gml_pare_2":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_27":"http://www.opengis.net/citygml/building/2.0",
"citygml_28":"cityObjectMember",
"citygml_29":" ",
"citygml_30":" ",
"gml_desc_2":" ",
"gml_name_2":" ",
"citygml_31":" ",
"citygml_32":" ",
"external_6":" ",
"external_7":" ",
"external_8":" ",
"citygml_33":" ",
"citygml_34":" ",
"citygml_35":" ",
"citygml_36":" ",
"citygml_37":" ",
"citygml_38":" ",
"citygml_39":" ",
"citygml_40":" ",
"citygml_41":" ",
"citygml_42":" ",
"citygml_43":" ",
"citygml_44":" ",
"citygml_45":" ",
"citygml_46":" ",
"citygml_47":21.824000000000002,
"citygml_48":"#m",
"citygml_49":" ",
"citygml_50":" ",
"citygml_51":" ",
"citygml_52":" ",
"citygml_53":" ",
"citygml_54":" ",
"citygml_55":" ",
"citygml_56":" ",
"citygml_57":" ",
"citygml_58":" ",
"citygml_59":" ",
"citygml_60":" ",
"citygml_61":" ",
"Volume_1":"2783.169",
"Field":0,
"Field1":0,
"OBJECTID_1":778,
"gml_id_12_":"ebc7f916-d094-4de0-8c35-fc18eb8622f2",
"gml_pare_3":"1340908",
"citygml_62":"http://www.opengis.net/citygml/building/2.0",
"citygml_63":"boundedBy",
"citygml_64":" ",
"citygml_65":" ",
"gml_desc_3":" ",
"gml_name_3":" ",
"citygml_66":" ",
"citygml_67":" ",
"external_9":" ",
"externa_10":" ",
"externa_11":" ",
"citygml_68":" ",
"citygml_69":" ",
"citygml_70":" ",
"citygml_71":" ",
"citygml_72":" ",
"citygml_73":" ",
"Area_1":"229.287",
"cityGML_hi":0,
"Z_Min":49.0745,
"Z_Max":69.165000000000006,
"Shape_Leng":59.532834838799999,
"ID_UEV":"01002777",
"CIVIQUE_DE":" 1460",
"CIVIQUE_FI":" 1460",
"NOM_RUE":"rue Sherbrooke Ouest (MTL+MTO+WMT)",
"MUNICIPALI":"50",
"ETAGE_HORS":3,
"NOMBRE_LOG":1,
"ANNEE_CONS":1885,
"CODE_UTILI":"5010",
"LIBELLE_UT":"Immeuble commercial",
"CATEGORIE_":"Régulier",
"MATRICULE8":"9839-57-1941-6-000-0000",
"SUPERFICIE":193,
"SUPERFIC_1":609,
"NO_ARROND_":"REM19",
"Shape_Le_1":0.00076452447366199996,
"Shape_Ar_1":2.2162879886799998e-08,
"Z_Min_1":null,
"Z_Max_1":null,
"Shape_Length":59.532834838827348,
"Shape_Area":161.83671944596372
}
},
{
"type":"Feature",
"id":2,
"geometry":{
"type":"Polygon",
"coordinates":[
[
[
-73.581414175680588,
45.497641136608358
]
,
[
-73.581414175680588,
45.498441136608358
],
[
-73.582214175680588,
45.498441136608358
],
[
-73.582214175680588,
45.497641136608358
],
[
-73.581414175680588,
45.497641136608358
]
]
]
},
"properties":{
"OBJECTID_12":2,
"gml_id":"1340974",
"gml_parent":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_ta":"http://www.opengis.net/citygml/building/2.0",
"citygml_fe":"cityObjectMember",
"citygml__1":" ",
"citygml__2":" ",
"gml_descri":" ",
"gml_name":" ",
"citygml_cr":" ",
"citygml_te":" ",
"externalRe":" ",
"external_1":" ",
"external_2":" ",
"citygml_ge":" ",
"citygml_re":" ",
"citygml__3":" ",
"citygml_ap":" ",
"citygml_cl":" ",
"citygml__4":" ",
"citygml_fu":" ",
"citygml__5":" ",
"citygml_us":" ",
"citygml__6":" ",
"citygml_ye":" ",
"citygml__7":" ",
"citygml_ro":" ",
"citygml__8":" ",
"citygml_me":21.643999999999998,
"citygml__9":"#m",
"citygml_st":" ",
"citygml_10":" ",
"citygml_11":" ",
"citygml_12":" ",
"citygml_13":" ",
"citygml_14":" ",
"citygml_ou":" ",
"citygml_in":" ",
"citygml_bo":" ",
"citygml_le":" ",
"citygml_15":" ",
"citygml_co":" ",
"citygml_ad":" ",
"Volume":"8410.522",
"parcelle":" ",
"OBJECTID":779,
"gml_id_1":"96e73b07-262d-43a8-84ce-608133b39f16",
"gml_pare_1":"1340974",
"citygml_16":"http://www.opengis.net/citygml/building/2.0",
"citygml_17":"boundedBy",
"citygml_18":" ",
"citygml_19":" ",
"gml_desc_1":" ",
"gml_name_1":" ",
"citygml_20":" ",
"citygml_21":" ",
"external_3":" ",
"external_4":" ",
"external_5":" ",
"citygml_22":" ",
"citygml_23":" ",
"citygml_24":" ",
"citygml_25":" ",
"citygml_26":" ",
"citygml_op":" ",
"Area":"553.859",
"FID_":0,
"Join_Count":3,
"TARGET_FID":780,
"gml_id_12":"1340974",
"gml_pare_2":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_27":"http://www.opengis.net/citygml/building/2.0",
"citygml_28":"cityObjectMember",
"citygml_29":" ",
"citygml_30":" ",
"gml_desc_2":" ",
"gml_name_2":" ",
"citygml_31":" ",
"citygml_32":" ",
"external_6":" ",
"external_7":" ",
"external_8":" ",
"citygml_33":" ",
"citygml_34":" ",
"citygml_35":" ",
"citygml_36":" ",
"citygml_37":" ",
"citygml_38":" ",
"citygml_39":" ",
"citygml_40":" ",
"citygml_41":" ",
"citygml_42":" ",
"citygml_43":" ",
"citygml_44":" ",
"citygml_45":" ",
"citygml_46":" ",
"citygml_47":21.643999999999998,
"citygml_48":"#m",
"citygml_49":" ",
"citygml_50":" ",
"citygml_51":" ",
"citygml_52":" ",
"citygml_53":" ",
"citygml_54":" ",
"citygml_55":" ",
"citygml_56":" ",
"citygml_57":" ",
"citygml_58":" ",
"citygml_59":" ",
"citygml_60":" ",
"citygml_61":" ",
"Volume_1":"8410.522",
"Field":0,
"Field1":0,
"OBJECTID_1":779,
"gml_id_12_":"96e73b07-262d-43a8-84ce-608133b39f16",
"gml_pare_3":"1340974",
"citygml_62":"http://www.opengis.net/citygml/building/2.0",
"citygml_63":"boundedBy",
"citygml_64":" ",
"citygml_65":" ",
"gml_desc_3":" ",
"gml_name_3":" ",
"citygml_66":" ",
"citygml_67":" ",
"external_9":" ",
"externa_10":" ",
"externa_11":" ",
"citygml_68":" ",
"citygml_69":" ",
"citygml_70":" ",
"citygml_71":" ",
"citygml_72":" ",
"citygml_73":" ",
"Area_1":"553.859",
"cityGML_hi":0,
"Z_Min":47.817900000000002,
"Z_Max":69.462000000000003,
"Shape_Leng":124.143194192,
"ID_UEV":"01002773",
"CIVIQUE_DE":" 1438",
"CIVIQUE_FI":" 1438",
"NOM_RUE":"rue Sherbrooke Ouest (MTL+MTO+WMT)",
"MUNICIPALI":"50",
"ETAGE_HORS":3,
"NOMBRE_LOG":2,
"ANNEE_CONS":1885,
"CODE_UTILI":"1000",
"LIBELLE_UT":"Logement",
"CATEGORIE_":"Régulier",
"MATRICULE8":"9839-57-4570-0-000-0000",
"SUPERFICIE":249,
"SUPERFIC_1":506,
"NO_ARROND_":"REM19",
"Shape_Le_1":0.00099703639048799998,
"Shape_Ar_1":2.8543276304299999e-08,
"Z_Min_1":null,
"Z_Max_1":null,
"Shape_Length":124.143194192441,
"Shape_Area":464.30094602931189
}
},
{
"type":"Feature",
"id":3,
"geometry":{
"type":"Polygon",
"coordinates":[
[
[
-73.581914175680588,
45.498441136608358
],
[
-73.581414175680588,
45.498441136608358
],
[
-73.581414175680588,
45.498641136608358
],
[
-73.580914175680588,
45.498641136608358
],
[
-73.580914175680588,
45.499641136608358
],
[
-73.581914175680588,
45.499641136608358
],
[
-73.581914175680588,
45.498441136608358
]
]
]
},
"properties":{
"OBJECTID_12":3,
"gml_id":"1340910",
"gml_parent":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_ta":"http://www.opengis.net/citygml/building/2.0",
"citygml_fe":"cityObjectMember",
"citygml__1":" ",
"citygml__2":" ",
"gml_descri":" ",
"gml_name":" ",
"citygml_cr":" ",
"citygml_te":" ",
"externalRe":" ",
"external_1":" ",
"external_2":" ",
"citygml_ge":" ",
"citygml_re":" ",
"citygml__3":" ",
"citygml_ap":" ",
"citygml_cl":" ",
"citygml__4":" ",
"citygml_fu":" ",
"citygml__5":" ",
"citygml_us":" ",
"citygml__6":" ",
"citygml_ye":" ",
"citygml__7":" ",
"citygml_ro":" ",
"citygml__8":" ",
"citygml_me":21.916,
"citygml__9":"#m",
"citygml_st":" ",
"citygml_10":" ",
"citygml_11":" ",
"citygml_12":" ",
"citygml_13":" ",
"citygml_14":" ",
"citygml_ou":" ",
"citygml_in":" ",
"citygml_bo":" ",
"citygml_le":" ",
"citygml_15":" ",
"citygml_co":" ",
"citygml_ad":" ",
"Volume":"2257.436",
"parcelle":" ",
"OBJECTID":780,
"gml_id_1":"8222a1c7-e161-421a-8478-22d2a116e0b4",
"gml_pare_1":"1340910",
"citygml_16":"http://www.opengis.net/citygml/building/2.0",
"citygml_17":"boundedBy",
"citygml_18":" ",
"citygml_19":" ",
"gml_desc_1":" ",
"gml_name_1":" ",
"citygml_20":" ",
"citygml_21":" ",
"external_3":" ",
"external_4":" ",
"external_5":" ",
"citygml_22":" ",
"citygml_23":" ",
"citygml_24":" ",
"citygml_25":" ",
"citygml_26":" ",
"citygml_op":" ",
"Area":"144.697",
"FID_":0,
"Join_Count":2,
"TARGET_FID":781,
"gml_id_12":"1340910",
"gml_pare_2":"fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_27":"http://www.opengis.net/citygml/building/2.0",
"citygml_28":"cityObjectMember",
"citygml_29":" ",
"citygml_30":" ",
"gml_desc_2":" ",
"gml_name_2":" ",
"citygml_31":" ",
"citygml_32":" ",
"external_6":" ",
"external_7":" ",
"external_8":" ",
"citygml_33":" ",
"citygml_34":" ",
"citygml_35":" ",
"citygml_36":" ",
"citygml_37":" ",
"citygml_38":" ",
"citygml_39":" ",
"citygml_40":" ",
"citygml_41":" ",
"citygml_42":" ",
"citygml_43":" ",
"citygml_44":" ",
"citygml_45":" ",
"citygml_46":" ",
"citygml_47":21.916,
"citygml_48":"#m",
"citygml_49":" ",
"citygml_50":" ",
"citygml_51":" ",
"citygml_52":" ",
"citygml_53":" ",
"citygml_54":" ",
"citygml_55":" ",
"citygml_56":" ",
"citygml_57":" ",
"citygml_58":" ",
"citygml_59":" ",
"citygml_60":" ",
"citygml_61":" ",
"Volume_1":"2257.436",
"Field":0,
"Field1":0,
"OBJECTID_1":780,
"gml_id_12_":"8222a1c7-e161-421a-8478-22d2a116e0b4",
"gml_pare_3":"1340910",
"citygml_62":"http://www.opengis.net/citygml/building/2.0",
"citygml_63":"boundedBy",
"citygml_64":" ",
"citygml_65":" ",
"gml_desc_3":" ",
"gml_name_3":" ",
"citygml_66":" ",
"citygml_67":" ",
"external_9":" ",
"externa_10":" ",
"externa_11":" ",
"citygml_68":" ",
"citygml_69":" ",
"citygml_70":" ",
"citygml_71":" ",
"citygml_72":" ",
"citygml_73":" ",
"Area_1":"144.697",
"cityGML_hi":0,
"Z_Min":48.983400000000003,
"Z_Max":67.617000000000004,
"Shape_Leng":52.283656634099998,
"ID_UEV":"01002775",
"CIVIQUE_DE":" 1448",
"CIVIQUE_FI":" 1448",
"NOM_RUE":"rue Sherbrooke Ouest (MTL+MTO+WMT)",
"MUNICIPALI":"50",
"ETAGE_HORS":3,
"NOMBRE_LOG":1,
"ANNEE_CONS":1885,
"CODE_UTILI":"5010",
"LIBELLE_UT":"Immeuble commercial",
"CATEGORIE_":"Régulier",
"MATRICULE8":"9839-57-3057-9-000-0000",
"SUPERFICIE":167,
"SUPERFIC_1":354,
"NO_ARROND_":"REM19",
"Shape_Le_1":0.00074417728924999998,
"Shape_Ar_1":1.92186900974e-08,
"Z_Min_1":null,
"Z_Max_1":null,
"Shape_Length":52.283656634094768,
"Shape_Area":123.24449716965384
}
}
]
}

File diff suppressed because one or more lines are too long