Performance improvements completed
This commit is contained in:
parent
2781696f95
commit
927771081d
|
@ -26,8 +26,6 @@ class Polygon:
|
||||||
"""
|
"""
|
||||||
Polygon class
|
Polygon class
|
||||||
"""
|
"""
|
||||||
# todo: review with @Guille: Points, Coordinates, Vertices, Faces
|
|
||||||
|
|
||||||
def __init__(self, coordinates):
|
def __init__(self, coordinates):
|
||||||
self._area = None
|
self._area = None
|
||||||
self._points = None
|
self._points = None
|
||||||
|
|
|
@ -234,6 +234,10 @@ class City:
|
||||||
else:
|
else:
|
||||||
if city_object in self._buildings:
|
if city_object in self._buildings:
|
||||||
self._buildings.remove(city_object)
|
self._buildings.remove(city_object)
|
||||||
|
# regenerate hash map
|
||||||
|
self._city_objects_dictionary.clear()
|
||||||
|
for i, city_object in enumerate(self._buildings):
|
||||||
|
self._city_objects_dictionary[city_object.name] = i
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def srs_name(self) -> Union[None, str]:
|
def srs_name(self) -> Union[None, str]:
|
||||||
|
|
|
@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Concordia CERC group
|
Copyright © 2022 Concordia CERC group
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -39,7 +40,7 @@ class StoreysGeneration:
|
||||||
number_of_storeys, height = self._calculate_number_storeys_and_height(self._building.average_storey_height,
|
number_of_storeys, height = self._calculate_number_storeys_and_height(self._building.average_storey_height,
|
||||||
self._building.eave_height,
|
self._building.eave_height,
|
||||||
self._building.storeys_above_ground)
|
self._building.storeys_above_ground)
|
||||||
number_of_storeys = 1
|
|
||||||
if not self._divide_in_storeys or number_of_storeys == 1:
|
if not self._divide_in_storeys or number_of_storeys == 1:
|
||||||
storey = Storey('storey_0', self._building.surfaces, [None, None], self._internal_zone.volume,
|
storey = Storey('storey_0', self._building.surfaces, [None, None], self._internal_zone.volume,
|
||||||
self._internal_zone, self._floor_area)
|
self._internal_zone, self._floor_area)
|
||||||
|
@ -55,7 +56,6 @@ class StoreysGeneration:
|
||||||
else:
|
else:
|
||||||
thermal_zones = [storey.neighbours[1], storey.thermal_zone]
|
thermal_zones = [storey.neighbours[1], storey.thermal_zone]
|
||||||
thermal_boundary.thermal_zones = thermal_zones
|
thermal_boundary.thermal_zones = thermal_zones
|
||||||
|
|
||||||
return [storey.thermal_zone]
|
return [storey.thermal_zone]
|
||||||
|
|
||||||
if number_of_storeys == 0:
|
if number_of_storeys == 0:
|
||||||
|
|
|
@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Concordia CERC group
|
Copyright © 2022 Concordia CERC group
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
import math
|
import math
|
||||||
import sys
|
import sys
|
||||||
from hub.hub_logger import logger
|
from hub.hub_logger import logger
|
||||||
|
@ -37,17 +37,21 @@ class NrcanPhysicsParameters:
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
try:
|
try:
|
||||||
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||||
|
|
||||||
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
|
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error(f'Building {building.name} has unknown construction archetype for building function: '
|
logger.error(f'Building {building.name} has unknown construction archetype for building function: '
|
||||||
f'{building.function}, building year of construction: {building.year_of_construction} '
|
f'{function} [{building.function}], building year of construction: {building.year_of_construction} '
|
||||||
f'and climate zone {self._climate_zone}\n')
|
f'and climate zone {self._climate_zone}\n')
|
||||||
sys.stderr.write(f'Building {building.name} has unknown construction archetype for building function: '
|
sys.stderr.write(f'Building {building.name} has unknown construction archetype for building function: '
|
||||||
f'{building.function}, building year of construction: {building.year_of_construction} '
|
f'{function} [{building.function}], building year of construction: {building.year_of_construction} '
|
||||||
f'and climate zone {self._climate_zone}\n')
|
f'and climate zone {self._climate_zone}\n')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
||||||
# one thermal zone per storey is assigned
|
# one thermal zone per storey is assigned
|
||||||
|
|
||||||
if len(building.internal_zones) == 1:
|
if len(building.internal_zones) == 1:
|
||||||
if building.internal_zones[0].thermal_zones is None:
|
if building.internal_zones[0].thermal_zones is None:
|
||||||
self._create_storeys(building, archetype, self._divide_in_storeys)
|
self._create_storeys(building, archetype, self._divide_in_storeys)
|
||||||
|
@ -63,7 +67,6 @@ class NrcanPhysicsParameters:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._assign_values(internal_zone.thermal_zones, archetype)
|
self._assign_values(internal_zone.thermal_zones, archetype)
|
||||||
for thermal_zone in internal_zone.thermal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
@ -74,7 +77,7 @@ class NrcanPhysicsParameters:
|
||||||
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
||||||
for building_archetype in nrcan_archetypes:
|
for building_archetype in nrcan_archetypes:
|
||||||
construction_period_limits = building_archetype.construction_period.split('_')
|
construction_period_limits = building_archetype.construction_period.split('_')
|
||||||
if int(construction_period_limits[0]) <= year_of_construction < int(construction_period_limits[1]):
|
if int(construction_period_limits[0]) <= year_of_construction <= int(construction_period_limits[1]):
|
||||||
if (str(function) == str(building_archetype.function)) and \
|
if (str(function) == str(building_archetype.function)) and \
|
||||||
(climate_zone == str(building_archetype.climate_zone)):
|
(climate_zone == str(building_archetype.climate_zone)):
|
||||||
return building_archetype
|
return building_archetype
|
||||||
|
|
|
@ -70,7 +70,8 @@ class Geojson:
|
||||||
points = igh.invert_points(points)
|
points = igh.invert_points(points)
|
||||||
polygon = Polygon(points)
|
polygon = Polygon(points)
|
||||||
polygon.area = igh.ground_area(points)
|
polygon.area = igh.ground_area(points)
|
||||||
surfaces.append(Surface(polygon, polygon))
|
surface = Surface(polygon, polygon)
|
||||||
|
surfaces.append(surface)
|
||||||
buildings.append(Building(f'{name}_zone_{zone}', surfaces, year_of_construction, function))
|
buildings.append(Building(f'{name}_zone_{zone}', surfaces, year_of_construction, function))
|
||||||
return buildings
|
return buildings
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ class Geojson:
|
||||||
|
|
||||||
for zone, lod0_building in enumerate(lod0_buildings):
|
for zone, lod0_building in enumerate(lod0_buildings):
|
||||||
for surface in lod0_building.grounds:
|
for surface in lod0_building.grounds:
|
||||||
|
|
||||||
volume = surface.solid_polygon.area * height
|
volume = surface.solid_polygon.area * height
|
||||||
surfaces.append(surface)
|
surfaces.append(surface)
|
||||||
roof_coordinates = []
|
roof_coordinates = []
|
||||||
|
@ -91,6 +93,7 @@ class Geojson:
|
||||||
# insert the roof rotated already
|
# insert the roof rotated already
|
||||||
roof_coordinates.insert(0, roof_coordinate)
|
roof_coordinates.insert(0, roof_coordinate)
|
||||||
polygon = Polygon(roof_coordinates)
|
polygon = Polygon(roof_coordinates)
|
||||||
|
polygon.area = surface.solid_polygon.area
|
||||||
roof = Surface(polygon, polygon)
|
roof = Surface(polygon, polygon)
|
||||||
surfaces.append(roof)
|
surfaces.append(roof)
|
||||||
# adding a wall means add the point coordinates and the next point coordinates with Z's height and 0
|
# adding a wall means add the point coordinates and the next point coordinates with Z's height and 0
|
||||||
|
|
|
@ -4,14 +4,12 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Concordia CERC group
|
Copyright © 2022 Concordia CERC group
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
import datetime
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from hub.helpers.geometry_helper import GeometryHelper
|
|
||||||
|
|
||||||
from numpy import inf
|
|
||||||
|
|
||||||
import hub.exports.exports_factory
|
import hub.exports.exports_factory
|
||||||
|
from hub.helpers.dictionaries import MontrealFunctionToHubFunction
|
||||||
|
from hub.helpers.geometry_helper import GeometryHelper
|
||||||
from hub.imports.construction_factory import ConstructionFactory
|
from hub.imports.construction_factory import ConstructionFactory
|
||||||
from hub.imports.geometry_factory import GeometryFactory
|
from hub.imports.geometry_factory import GeometryFactory
|
||||||
|
|
||||||
|
@ -21,6 +19,7 @@ class TestGeometryFactory(TestCase):
|
||||||
Non-functional TestGeometryFactory
|
Non-functional TestGeometryFactory
|
||||||
Load testing
|
Load testing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
"""
|
"""
|
||||||
Test setup
|
Test setup
|
||||||
|
@ -36,7 +35,8 @@ class TestGeometryFactory(TestCase):
|
||||||
path=file_path,
|
path=file_path,
|
||||||
height_field=height_field,
|
height_field=height_field,
|
||||||
year_of_construction_field=year_of_construction_field,
|
year_of_construction_field=year_of_construction_field,
|
||||||
function_field=function_field).city
|
function_field=function_field,
|
||||||
|
).city
|
||||||
self.assertIsNotNone(self._city, 'city is none')
|
self.assertIsNotNone(self._city, 'city is none')
|
||||||
return self._city
|
return self._city
|
||||||
|
|
||||||
|
@ -134,20 +134,14 @@ class TestGeometryFactory(TestCase):
|
||||||
"""
|
"""
|
||||||
Test geojson import
|
Test geojson import
|
||||||
"""
|
"""
|
||||||
file = '10000_buildings.geojson'
|
file = '2000_buildings.geojson'
|
||||||
start = datetime.datetime.now()
|
city = GeometryFactory('geojson',
|
||||||
city = self._get_city(file, 'geojson',
|
path=(self._example_path / file).resolve(),
|
||||||
height_field='building_height',
|
height_field='building_height',
|
||||||
year_of_construction_field='ANNEE_CONS',
|
year_of_construction_field='ANNEE_CONS',
|
||||||
function_field='CODE_UTILI')
|
function_field='CODE_UTILI',
|
||||||
end = datetime.datetime.now()
|
function_to_hub=MontrealFunctionToHubFunction().dictionary).city
|
||||||
print(f'geometry load in {end-start} s')
|
|
||||||
start = datetime.datetime.now()
|
|
||||||
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
|
|
||||||
end = datetime.datetime.now()
|
|
||||||
print(f'geometry export in {end - start} s')
|
|
||||||
self.assertEqual(2356, len(city.buildings), 'wrong number of buildings')
|
self.assertEqual(2356, len(city.buildings), 'wrong number of buildings')
|
||||||
self._check_buildings(city)
|
|
||||||
|
|
||||||
def test_map_neighbours(self):
|
def test_map_neighbours(self):
|
||||||
"""
|
"""
|
||||||
|
@ -162,15 +156,16 @@ class TestGeometryFactory(TestCase):
|
||||||
city = self._get_city(file, 'geojson',
|
city = self._get_city(file, 'geojson',
|
||||||
year_of_construction_field='ANNEE_CONS',
|
year_of_construction_field='ANNEE_CONS',
|
||||||
function_field='LIBELLE_UT')
|
function_field='LIBELLE_UT')
|
||||||
|
|
||||||
info_lod0 = GeometryHelper.city_mapping(city, plot=False)
|
info_lod0 = GeometryHelper.city_mapping(city, plot=False)
|
||||||
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
|
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
|
||||||
self.assertEqual(info_lod0, info_lod1)
|
self.assertEqual(info_lod0, info_lod1)
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
self.assertEqual(2, len(building.neighbours))
|
self.assertEqual(2, len(building.neighbours))
|
||||||
|
|
||||||
self.assertEqual('2_part_0_zone_0',city.city_object('1_part_0_zone_0').neighbours[0].name)
|
self.assertEqual('2_part_0_zone_0', city.city_object('1_part_0_zone_0').neighbours[0].name)
|
||||||
self.assertEqual('3_part_0_zone_0',city.city_object('1_part_0_zone_0').neighbours[1].name)
|
self.assertEqual('3_part_0_zone_0', city.city_object('1_part_0_zone_0').neighbours[1].name)
|
||||||
self.assertEqual('1_part_0_zone_0',city.city_object('2_part_0_zone_0').neighbours[0].name)
|
self.assertEqual('1_part_0_zone_0', city.city_object('2_part_0_zone_0').neighbours[0].name)
|
||||||
self.assertEqual('3_part_0_zone_0',city.city_object('2_part_0_zone_0').neighbours[1].name)
|
self.assertEqual('3_part_0_zone_0', city.city_object('2_part_0_zone_0').neighbours[1].name)
|
||||||
self.assertEqual('1_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[0].name)
|
self.assertEqual('1_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[0].name)
|
||||||
self.assertEqual('2_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[1].name)
|
self.assertEqual('2_part_0_zone_0', city.city_object('3_part_0_zone_0').neighbours[1].name)
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user