Merge pull request 'optimization' (#10) from optimization into main
Reviewed-on: https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub/pulls/10
This commit is contained in:
commit
053a866443
|
@ -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
|
||||||
|
|
|
@ -60,6 +60,7 @@ class City:
|
||||||
self._stations = []
|
self._stations = []
|
||||||
self._lca_materials = None
|
self._lca_materials = None
|
||||||
self._level_of_detail = LevelOfDetail()
|
self._level_of_detail = LevelOfDetail()
|
||||||
|
self._city_objects_dictionary = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fuels(self) -> [Fuel]:
|
def fuels(self) -> [Fuel]:
|
||||||
|
@ -198,9 +199,8 @@ class City:
|
||||||
:param name:str
|
:param name:str
|
||||||
:return: None or CityObject
|
:return: None or CityObject
|
||||||
"""
|
"""
|
||||||
for city_object in self.buildings:
|
if name in self._city_objects_dictionary:
|
||||||
if str(city_object.name) == str(name):
|
return self.buildings[self._city_objects_dictionary[name]]
|
||||||
return city_object
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_city_object(self, new_city_object):
|
def add_city_object(self, new_city_object):
|
||||||
|
@ -213,6 +213,7 @@ class City:
|
||||||
if self._buildings is None:
|
if self._buildings is None:
|
||||||
self._buildings = []
|
self._buildings = []
|
||||||
self._buildings.append(new_city_object)
|
self._buildings.append(new_city_object)
|
||||||
|
self._city_objects_dictionary[new_city_object.name] = len(self._buildings) - 1
|
||||||
elif new_city_object.type == 'energy_system':
|
elif new_city_object.type == 'energy_system':
|
||||||
if self._energy_systems is None:
|
if self._energy_systems is None:
|
||||||
self._energy_systems = []
|
self._energy_systems = []
|
||||||
|
@ -233,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]:
|
||||||
|
|
|
@ -6,9 +6,6 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import trimesh.exchange.obj
|
|
||||||
from hub.exports.formats.triangular import Triangular
|
|
||||||
from hub.imports.geometry_factory import GeometryFactory
|
|
||||||
|
|
||||||
|
|
||||||
class Obj:
|
class Obj:
|
||||||
|
@ -38,6 +35,8 @@ class Obj:
|
||||||
faces = []
|
faces = []
|
||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
obj.write(f'# building {building.name}\n')
|
obj.write(f'# building {building.name}\n')
|
||||||
|
obj.write(f'g {building.name}\n')
|
||||||
|
obj.write('s off\n')
|
||||||
for surface in building.surfaces:
|
for surface in building.surfaces:
|
||||||
obj.write(f'# surface {surface.name}\n')
|
obj.write(f'# surface {surface.name}\n')
|
||||||
face = 'f '
|
face = 'f '
|
||||||
|
@ -56,6 +55,3 @@ class Obj:
|
||||||
faces.append(f'{face} {face.split(" ")[1]}\n')
|
faces.append(f'{face} {face.split(" ")[1]}\n')
|
||||||
obj.writelines(faces)
|
obj.writelines(faces)
|
||||||
faces = []
|
faces = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import math
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import requests
|
import requests
|
||||||
|
from PIL import Image
|
||||||
from trimesh import Trimesh
|
from trimesh import Trimesh
|
||||||
from trimesh import intersections
|
from trimesh import intersections
|
||||||
|
|
||||||
|
@ -16,8 +17,6 @@ from hub.city_model_structure.attributes.polygon import Polygon
|
||||||
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
||||||
from hub.helpers.location import Location
|
from hub.helpers.location import Location
|
||||||
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
|
|
||||||
class MapPoint:
|
class MapPoint:
|
||||||
def __init__(self, x, y):
|
def __init__(self, x, y):
|
||||||
|
@ -88,6 +87,7 @@ class GeometryHelper:
|
||||||
for ground in building.grounds:
|
for ground in building.grounds:
|
||||||
length = len(ground.perimeter_polygon.coordinates) - 1
|
length = len(ground.perimeter_polygon.coordinates) - 1
|
||||||
for i, coordinate in enumerate(ground.perimeter_polygon.coordinates):
|
for i, coordinate in enumerate(ground.perimeter_polygon.coordinates):
|
||||||
|
|
||||||
j = i + 1
|
j = i + 1
|
||||||
if i == length:
|
if i == length:
|
||||||
j = 0
|
j = 0
|
||||||
|
@ -167,10 +167,53 @@ class GeometryHelper:
|
||||||
elif building not in neighbour.neighbours:
|
elif building not in neighbour.neighbours:
|
||||||
neighbour.neighbours.append(building)
|
neighbour.neighbours.append(building)
|
||||||
line += 1
|
line += 1
|
||||||
|
|
||||||
if plot:
|
if plot:
|
||||||
img.show()
|
img.show()
|
||||||
return lines_information
|
return lines_information
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def fast_city_mapping(city, building_names=None):
|
||||||
|
lines_information = {}
|
||||||
|
if building_names is None:
|
||||||
|
building_names = [b.name for b in city.buildings]
|
||||||
|
x = int((city.upper_corner[0] - city.lower_corner[0]) * 0.5) + 1
|
||||||
|
y = int((city.upper_corner[1] - city.lower_corner[1]) * 0.5) + 1
|
||||||
|
city_map = [['' for _ in range(y + 1)] for _ in range(x + 1)]
|
||||||
|
for building_name in building_names:
|
||||||
|
building = city.city_object(building_name)
|
||||||
|
line = 0
|
||||||
|
for ground in building.grounds:
|
||||||
|
length = len(ground.perimeter_polygon.coordinates) - 1
|
||||||
|
for i, coordinate in enumerate(ground.perimeter_polygon.coordinates):
|
||||||
|
j = i + 1
|
||||||
|
if i == length:
|
||||||
|
j = 0
|
||||||
|
next_coordinate = ground.perimeter_polygon.coordinates[j]
|
||||||
|
point = GeometryHelper.coordinate_to_map_point(coordinate, city)
|
||||||
|
distance = int(GeometryHelper.distance_between_points(coordinate, next_coordinate))
|
||||||
|
if distance == 0:
|
||||||
|
continue
|
||||||
|
delta_x = (coordinate[0] - next_coordinate[0]) / (distance / 0.5)
|
||||||
|
delta_y = (coordinate[1] - next_coordinate[1]) / (distance / 0.5)
|
||||||
|
for k in range(0, distance):
|
||||||
|
x = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).x
|
||||||
|
y = MapPoint(point.x + (delta_x * k), point.y + (delta_y * k)).y
|
||||||
|
if city_map[x][y] == '':
|
||||||
|
city_map[x][y] = building.name
|
||||||
|
elif city_map[x][y] != building.name:
|
||||||
|
neighbour = city.city_object(city_map[x][y])
|
||||||
|
if building.neighbours is None:
|
||||||
|
building.neighbours = [neighbour]
|
||||||
|
elif neighbour not in building.neighbours:
|
||||||
|
building.neighbours.append(neighbour)
|
||||||
|
if neighbour.neighbours is None:
|
||||||
|
neighbour.neighbours = [building]
|
||||||
|
elif building not in neighbour.neighbours:
|
||||||
|
neighbour.neighbours.append(building)
|
||||||
|
line += 1
|
||||||
|
return lines_information
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def segment_list_to_trimesh(lines) -> Trimesh:
|
def segment_list_to_trimesh(lines) -> Trimesh:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Concordia CERC group
|
Copyright © 2022 Concordia CERC group
|
||||||
Project Coder Guillermo Gutierrez Guillermo.GutierrezMorote@concordia.ca
|
Project Coder Guillermo Gutierrez Guillermo.GutierrezMorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -67,7 +68,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
|
||||||
|
|
||||||
|
@ -79,6 +81,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 = []
|
||||||
|
@ -88,6 +91,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
|
||||||
|
@ -177,6 +181,7 @@ class Geojson:
|
||||||
Get city out of a Geojson file
|
Get city out of a Geojson file
|
||||||
"""
|
"""
|
||||||
if self._city is None:
|
if self._city is None:
|
||||||
|
start = datetime.datetime.now()
|
||||||
missing_functions = []
|
missing_functions = []
|
||||||
buildings = []
|
buildings = []
|
||||||
building_id = 0
|
building_id = 0
|
||||||
|
@ -225,12 +230,18 @@ class Geojson:
|
||||||
[polygon])
|
[polygon])
|
||||||
|
|
||||||
self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911')
|
self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911')
|
||||||
|
print(f'features: {datetime.datetime.now()-start}')
|
||||||
|
|
||||||
for building in buildings:
|
for building in buildings:
|
||||||
self._city.add_city_object(building)
|
self._city.add_city_object(building)
|
||||||
self._city.level_of_detail.geometry = lod
|
self._city.level_of_detail.geometry = lod
|
||||||
if lod == 1:
|
if lod == 1:
|
||||||
lines_information = GeometryHelper.city_mapping(self._city)
|
start = datetime.datetime.now()
|
||||||
|
lines_information = GeometryHelper.city_mapping(self._city, plot=False)
|
||||||
|
print(f'mapping: {datetime.datetime.now() - start}')
|
||||||
|
start = datetime.datetime.now()
|
||||||
self._store_shared_percentage_to_walls(self._city, lines_information)
|
self._store_shared_percentage_to_walls(self._city, lines_information)
|
||||||
|
print(f'shared_walls: {datetime.datetime.now() - start}')
|
||||||
if len(missing_functions) > 0:
|
if len(missing_functions) > 0:
|
||||||
print(f'There are unknown functions {missing_functions}')
|
print(f'There are unknown functions {missing_functions}')
|
||||||
return self._city
|
return self._city
|
||||||
|
|
|
@ -105,11 +105,3 @@ class GeometryHelper:
|
||||||
cosine = -1
|
cosine = -1
|
||||||
alpha = math.acos(cosine)
|
alpha = math.acos(cosine)
|
||||||
return alpha
|
return alpha
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def invert_points(points):
|
|
||||||
res = []
|
|
||||||
for point in points:
|
|
||||||
res.insert(0,point)
|
|
||||||
return res
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
@ -135,19 +135,13 @@ class TestGeometryFactory(TestCase):
|
||||||
Test geojson import
|
Test geojson import
|
||||||
"""
|
"""
|
||||||
file = '2000_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