diff --git a/hub/city_model_structure/city.py b/hub/city_model_structure/city.py index be5d954f..f3bf38f7 100644 --- a/hub/city_model_structure/city.py +++ b/hub/city_model_structure/city.py @@ -6,6 +6,8 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Code contributors: Peter Yefi peteryefi@gmail.com """ from __future__ import annotations + +import bz2 import sys import pickle import math @@ -267,6 +269,16 @@ class City: with open(city_filename, 'wb') as file: pickle.dump(self, file) + def save_compressed(self, city_filename): + """ + Save a city into the given filename + :param city_filename: destination city filename + :return: None + """ + + with bz2.BZ2File('bz2_test.pbz2', 'wb') as f: + pickle.dump(self, f) + def region(self, center, radius) -> City: """ Get a region from the city diff --git a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py index 1824cdbe..cf99c41f 100644 --- a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py +++ b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py @@ -167,6 +167,8 @@ class InselMonthlyEnergyBalance(Insel): f'inclination {np.rad2deg(surface.inclination)} (degrees)'] if surface.type != 'Ground': + if cte.MONTH not in surface.global_irradiance: + raise ValueError(f'surface: {surface.name} from building {building.name} has no global irradiance!') global_irradiance = surface.global_irradiance[cte.MONTH] for j in range(0, len(global_irradiance)): parameters.append(f'{j + 1} {global_irradiance.at[j, radiation_calculation_method]}') diff --git a/hub/helpers/data/montreal_function_to_hub_function.py b/hub/helpers/data/montreal_function_to_hub_function.py index 6658ec86..1f8e88ce 100644 --- a/hub/helpers/data/montreal_function_to_hub_function.py +++ b/hub/helpers/data/montreal_function_to_hub_function.py @@ -10,7 +10,7 @@ import hub.helpers.constants as cte class MontrealFunctionToHubFunction: - # Todo: "office" and "hotel/motel" need to be replaced for a constant value. + # Todo: "office" "Mausolée" and "hotel/motel" need to be replaced for a constant value. def __init__(self): self._dictionary = { "Administration publique municipale et régionale": "Office", @@ -542,7 +542,14 @@ class MontrealFunctionToHubFunction: "Église synagogue mosquée et temple": cte.EVENT_LOCATION, "Établissement avec salle de réception ou de banquet": cte.FULL_SERVICE_RESTAURANT, "Établissement avec service de boissons alcoolisées (Bar)": cte.QUICK_SERVICE_RESTAURANT, - "Établissement dont l'activité principale est la danse (discothèque avec service alcool boite de nuit) sans alcool code 7397": cte.QUICK_SERVICE_RESTAURANT + "Établissement dont l'activité principale est la danse (discothèque avec service alcool boite de nuit) sans alcool code 7397": cte.QUICK_SERVICE_RESTAURANT, + "Mausolée": cte.NON_HEATED, + "Auberge ou gîte touristique (Hôtel à caractère familial, d'au plus 3 étages en hauteur de bâtiment)": cte.HOTEL, + "Service de garderie (prématernelle, moins de 50 % de poupons)": cte.PRIMARY_SCHOOL, + "Église, synagogue, mosquée et temple": cte.CONVENTION_CENTER + + + } @property diff --git a/hub/imports/db_factory.py b/hub/imports/db_factory.py index 7ec0e4f4..596aa225 100644 --- a/hub/imports/db_factory.py +++ b/hub/imports/db_factory.py @@ -18,14 +18,15 @@ class DBFactory: self._city_repository = CityRepository(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) self._simulation_results = SimulationResults(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) - def persist_city(self, city: City, application_id: int, user_id: int): + def persist_city(self, city: City, pickle_path, application_id: int, user_id: int): """ Persist city into postgres database :param city: City to be stored + :param pickle_path: Path to save the pickle file :param application_id: Application id owning this city :param user_id: User who create the city """ - return self._city_repository.insert(city, application_id, user_id) + return self._city_repository.insert(city, pickle_path, application_id, user_id) def update_city(self, city_id, city): """ diff --git a/hub/imports/geometry/geojson.py b/hub/imports/geometry/geojson.py index 2735982f..0f240e2e 100644 --- a/hub/imports/geometry/geojson.py +++ b/hub/imports/geometry/geojson.py @@ -134,6 +134,7 @@ class Geojson: building_name = f'building_{building_id}' building_id += 1 polygons = [] + lod = 1 for part, coordinates in enumerate(geometry['coordinates']): polygons = self._get_polygons(polygons, coordinates) for zone, polygon in enumerate(polygons): @@ -142,6 +143,7 @@ class Geojson: year_of_construction, function, [polygon]) + lod = 0 else: if self._max_z < extrusion_height: self._max_z = extrusion_height @@ -154,4 +156,5 @@ class Geojson: self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911') for building in buildings: self._city.add_city_object(building) + self._city.level_of_detail.geometry = lod return self._city diff --git a/hub/persistence/models/city.py b/hub/persistence/models/city.py index dfec2b63..92821723 100644 --- a/hub/persistence/models/city.py +++ b/hub/persistence/models/city.py @@ -17,7 +17,7 @@ class City(Models): """ __tablename__ = 'city' id = Column(Integer, Sequence('city_id_seq'), primary_key=True) - city = Column(PickleType, nullable=False) + pickle_path = Column(String, nullable=False) name = Column(String, nullable=False) level_of_detail = Column(Integer, nullable=False) climate_file = Column(String, nullable=False) @@ -27,8 +27,8 @@ class City(Models): created = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow) - def __init__(self, city, name, level_of_detail, climate_file, application_id, user_id, hub_release): - self.city = city + def __init__(self, pickle_path, name, level_of_detail, climate_file, application_id, user_id, hub_release): + self.pickle_path = str(pickle_path) self.name = name self.level_of_detail = level_of_detail self.climate_file = climate_file diff --git a/hub/persistence/repositories/city.py b/hub/persistence/repositories/city.py index 47f36e94..a1459c96 100644 --- a/hub/persistence/repositories/city.py +++ b/hub/persistence/repositories/city.py @@ -34,17 +34,19 @@ class City(Repository): cls._instance = super(City, cls).__new__(cls) return cls._instance - def insert(self, city: CityHub, application_id, user_id: int) -> Union[Model, Dict]: + def insert(self, city: CityHub, pickle_path, application_id, user_id: int) -> Union[Model, Dict]: """ Inserts a city :param city: The complete city instance + :param pickle_path: Path to the pickle :param application_id: Application id owning the instance :param user_id: User id owning the instance :return: City and Dictionary """ + city.save_compressed(pickle_path) try: db_city = Model( - pickle.dumps(city), + pickle_path, city.name, city.level_of_detail.geometry, 'None' if city.climate_file is None else str(city.climate_file), @@ -54,6 +56,7 @@ class City(Repository): self.session.add(db_city) self.session.flush() + self.session.commit() for building in city.buildings: object_usage = '' for internal_zone in building.internal_zones: