Partial correction in persistence and geometry_helper.py

This commit is contained in:
Guille Gutierrez 2023-05-18 16:15:57 -04:00
parent 1c4920d0b0
commit 5fb361e74c
9 changed files with 97 additions and 69 deletions

View File

@ -12,6 +12,7 @@ import numpy as np
from PIL import Image from PIL import Image
from trimesh import Trimesh from trimesh import Trimesh
from trimesh import intersections from trimesh import intersections
from typing import Dict
from hub.city_model_structure.attributes.polygon import Polygon 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
@ -25,10 +26,16 @@ class MapPoint:
@property @property
def x(self): def x(self):
"""
Get X Coordinate
"""
return self._x return self._x
@property @property
def y(self): def y(self):
"""
Get Y Coordinate
"""
return self._y return self._y
def __str__(self): def __str__(self):
@ -57,6 +64,10 @@ class GeometryHelper:
@staticmethod @staticmethod
def factor(): def factor():
"""
Set minimap resolution
:return: None
"""
return 0.5 return 0.5
def __init__(self, delta=0, area_delta=0): def __init__(self, delta=0, area_delta=0):
@ -65,15 +76,24 @@ class GeometryHelper:
@staticmethod @staticmethod
def coordinate_to_map_point(coordinate, city): def coordinate_to_map_point(coordinate, city):
"""
Transform a real world coordinate to a minimap one
:param coordinate: real world coordinate
:param city: current city
:return: None
"""
factor = GeometryHelper.factor() factor = GeometryHelper.factor()
return MapPoint( return MapPoint(
((coordinate[0] - city.lower_corner[0]) * factor), ((coordinate[1] - city.lower_corner[1]) * factor) ((coordinate[0] - city.lower_corner[0]) * factor), ((coordinate[1] - city.lower_corner[1]) * factor)
) )
@staticmethod @staticmethod
def city_mapping(city, building_names=None, plot=False): def city_mapping(city, building_names=None, plot=False) -> Dict:
""" """
Returns a shared_information dictionary :param city: city to be mapped
:param building_names: list of building names to be mapped or None
:param plot: True if minimap image should be displayed
:return: shared_information dictionary
""" """
lines_information = {} lines_information = {}
if building_names is None: if building_names is None:
@ -182,7 +202,8 @@ class GeometryHelper:
@staticmethod @staticmethod
def segment_list_to_trimesh(lines) -> Trimesh: def segment_list_to_trimesh(lines) -> Trimesh:
""" """
Transform a list of segments into a Trimesh :param lines: lines
:return: Transform a list of segments into a Trimesh
""" """
# todo: trimesh has a method for this # todo: trimesh has a method for this
line_points = [lines[0][0], lines[0][1]] line_points = [lines[0][0], lines[0][1]]
@ -262,6 +283,9 @@ class GeometryHelper:
def get_location(latitude, longitude) -> Location: def get_location(latitude, longitude) -> Location:
""" """
Get Location from latitude and longitude Get Location from latitude and longitude
:param latitude: Latitude
:param longitude: Longitude
:return: Location
""" """
_data_path = Path(Path(__file__).parent.parent / 'data/geolocation/cities15000.txt').resolve() _data_path = Path(Path(__file__).parent.parent / 'data/geolocation/cities15000.txt').resolve()
latitude = float(latitude) latitude = float(latitude)

View File

@ -36,7 +36,6 @@ class CityObject(Models):
created = Column(DateTime, default=datetime.datetime.utcnow) created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow)
# def __init__(self, city_id, name, alias, object_type, year_of_construction, function, usage, volume, area):
def __init__(self, city_id, building: Building): def __init__(self, city_id, building: Building):
self.city_id = city_id self.city_id = city_id
self.name = building.name self.name = building.name
@ -49,7 +48,6 @@ class CityObject(Models):
self.area = building.floor_area self.area = building.floor_area
storeys = building.storeys_above_ground storeys = building.storeys_above_ground
if storeys is None: if storeys is None:
print(building.average_storey_height)
storeys = building.max_height / building.average_storey_height storeys = building.max_height / building.average_storey_height
self.total_heating_area = building.floor_area * storeys self.total_heating_area = building.floor_area * storeys
wall_area = 0 wall_area = 0

View File

@ -5,12 +5,12 @@ Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
""" """
import logging
import datetime import datetime
from typing import Union, Dict import logging
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from hub.persistence import Repository from hub.persistence import Repository
from hub.persistence.models import Application as Model from hub.persistence.models import Application as Model
@ -32,33 +32,33 @@ class Application(Repository):
cls._instance = super(Application, cls).__new__(cls) cls._instance = super(Application, cls).__new__(cls)
return cls._instance return cls._instance
def insert(self, name: str, description: str, application_uuid: str) -> Union[Model, Dict]: def insert(self, name: str, description: str, application_uuid: str):
""" """
Inserts a new application Inserts a new application
:param name: Application name :param name: Application name
:param description: Application description :param description: Application description
:param application_uuid: Unique identifier for the application :param application_uuid: Unique identifier for the application
:return: application and dictionary :return: None
""" """
application = self.get_by_uuid(application_uuid) application = self.get_by_uuid(application_uuid)
if application is None: if application is not None:
raise SQLAlchemyError('application already exists')
try: try:
application = Model(name=name, description=description, application_uuid=application_uuid) application = Model(name=name, description=description, application_uuid=application_uuid)
self.session.add(application) self.session.add(application)
self.session.commit() self.session.commit()
return application
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('An error occurred while creating application: %s', err) error_message = f'An error occurred while creating application: {err}'
return {'message': f'An error occurred while creating application {application_uuid}'} logging.error(error_message)
raise SQLAlchemyError(error_message)
def update(self, application_uuid: str, name: str, description: str) -> Union[Dict, None]: def update(self, application_uuid: str, name: str, description: str):
""" """
Updates an application Updates an application
:param application_uuid: the application uuid of the application to be updated :param application_uuid: the application uuid of the application to be updated
:param name: the application name :param name: the application name
:param description: the application description :param description: the application description
:return: :return: None
""" """
try: try:
self.session.query(Model).filter( self.session.query(Model).filter(
@ -66,9 +66,9 @@ class Application(Repository):
).update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()}) ).update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()})
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while updating application %s', err) error_message = f'Error while updating application {err}'
return {'message': 'Error occurred while updating application'} logging.error(error_message)
return None raise SQLAlchemyError(error_message)
def delete(self, application_uuid: str): def delete(self, application_uuid: str):
""" """
@ -81,21 +81,27 @@ class Application(Repository):
self.session.flush() self.session.flush()
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while deleting application: %s', err) error_message = f'Error while deleting application {err}'
logging.error(error_message)
raise SQLAlchemyError(error_message)
def get_by_uuid(self, application_uuid: str) -> Union[Model, None]: def get_by_uuid(self, application_uuid: str) -> Model:
""" """
Fetch Application based on the application uuid Fetch Application based on the application uuid
:param application_uuid: the application uuid :param application_uuid: the application uuid
:return: Application with the provided application_uuid or None :return: Application with the provided application_uuid
""" """
result_set = None
try: try:
result_set = self.session.execute(select(Model).where( result_set = self.session.execute(select(Model).where(
Model.application_uuid == application_uuid) Model.application_uuid == application_uuid)
).first() ).first()
except SQLAlchemyError as err:
logging.error('Error while fetching application by application_uuid: %s', err)
if result_set is None:
return None
return result_set[0] return result_set[0]
except SQLAlchemyError as err:
error_message = f'Error while fetching application by application_uuid {err}'
logging.error(error_message)
raise SQLAlchemyError(error_message)
except IndexError as err:
error_message = f'Error while fetching application, empty result {err}'
logging.error(error_message)
raise IndexError(error_message)

View File

@ -4,9 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
import logging
import datetime import datetime
from typing import Union import logging
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
@ -35,14 +34,14 @@ class City(Repository):
cls._instance = super(City, cls).__new__(cls) cls._instance = super(City, cls).__new__(cls)
return cls._instance return cls._instance
def insert(self, city: CityHub, pickle_path, application_id, user_id: int) -> Union[Model, None]: def insert(self, city: CityHub, pickle_path, application_id, user_id: int):
""" """
Inserts a city Inserts a city
:param city: The complete city instance :param city: The complete city instance
:param pickle_path: Path to the pickle :param pickle_path: Path to the pickle
:param application_id: Application id owning the instance :param application_id: Application id owning the instance
:param user_id: User id owning the instance :param user_id: User id owning the instance
:return: City and None :return: None
""" """
city.save_compressed(pickle_path) city.save_compressed(pickle_path)
try: try:
@ -64,39 +63,43 @@ class City(Repository):
self.session.add(db_city_object) self.session.add(db_city_object)
self.session.flush() self.session.flush()
self.session.commit() self.session.commit()
return db_city
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('An error occurred while creating city: %s', err) error_message = f'An error occurred while creating a city: {err}'
return None logging.error(error_message)
raise SQLAlchemyError(error_message)
def update(self, city_id: int, city: CityHub): def update(self, city_id: int, city: CityHub):
""" """
Updates a city name (other updates makes no sense) Updates a city name (other updates makes no sense)
:param city_id: the id of the city to be updated :param city_id: the id of the city to be updated
:param city: the city object :param city: the city object
:return: :return: None
""" """
try: try:
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
self.session.query(Model).filter(Model.id == city_id).update({'name': city.name, 'updated': now}) self.session.query(Model).filter(Model.id == city_id).update({'name': city.name, 'updated': now})
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while updating city: %s', err) error_message = f'Error while updating city {err}'
logging.error(error_message)
raise SQLAlchemyError(error_message)
def delete(self, city_id: int): def delete(self, city_id: int):
""" """
Deletes a City with the id Deletes a City with the id
:param city_id: the city id :param city_id: the city id
:return: a city :return: None
""" """
try: try:
self.session.query(CityObject).filter(CityObject.city_id == city_id).delete() self.session.query(CityObject).filter(CityObject.city_id == city_id).delete()
self.session.query(Model).filter(Model.id == city_id).delete() self.session.query(Model).filter(Model.id == city_id).delete()
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while fetching city: %s', err) error_message = f'Error while fetching city {err}'
logging.error(error_message)
raise SQLAlchemyError(error_message)
def get_by_user_id_application_id_and_name(self, user_id, application_id, city_name): def get_by_user_id_application_id_and_name(self, user_id, application_id, city_name) -> Model:
""" """
Fetch city based on the user who created it Fetch city based on the user who created it
:param user_id: the user id :param user_id: the user id
@ -113,8 +116,9 @@ class City(Repository):
result_set = result_set[0] result_set = result_set[0]
return result_set return result_set
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while fetching city by name: %s', err) error_message = f'Error while fetching city by name {err}'
return None logging.error(error_message)
raise SQLAlchemyError(error_message)
def get_by_user_id_and_application_id(self, user_id, application_id) -> [Model]: def get_by_user_id_and_application_id(self, user_id, application_id) -> [Model]:
""" """
@ -129,5 +133,6 @@ class City(Repository):
) )
return [r[0] for r in result_set] return [r[0] for r in result_set]
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while fetching city by name: %s', err) error_message = f'Error while fetching city by name {err}'
return None logging.error(error_message)
raise SQLAlchemyError(error_message)

View File

@ -30,15 +30,16 @@ class CityObject(Repository):
cls._instance = super(CityObject, cls).__new__(cls) cls._instance = super(CityObject, cls).__new__(cls)
return cls._instance return cls._instance
def insert(self, city_id: int, building: Building) -> Union[Model, Dict]: def insert(self, city_id: int, building: Building):
""" """
Inserts a new city object Inserts a new city object
:param city_id: city id for the city owning this city object :param city_id: city id for the city owning this city object
:param building: the city object (only building for now) to be inserted :param building: the city object (only building for now) to be inserted
return CityObject model and dictionary return None
""" """
city_object = self.get_by_name_and_city(building.name, city_id) city_object = self.get_by_name_and_city(building.name, city_id)
if city_object is None: if city_object is not None:
raise SQLAlchemyError(f'A city_object named {building.name} already exists in that city')
try: try:
city_object = Model(city_id=city_id, city_object = Model(city_id=city_id,
building=building) building=building)
@ -47,10 +48,9 @@ class CityObject(Repository):
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('An error occurred while creating city_object: %s', err) error_message = f'An error occurred while creating city_object {err}'
else: logging.error(error_message)
return {'message': f'A city_object named {building.name} already exists in that city'} raise SQLAlchemyError(error_message)
return city_object
def update(self, city_id: int, building: Building) -> Union[Dict, None]: def update(self, city_id: int, building: Building) -> Union[Dict, None]:
""" """

View File

@ -18,13 +18,11 @@ class TestCostsCatalog(TestCase):
self.assertIsNotNone(catalog, 'catalog is none') self.assertIsNotNone(catalog, 'catalog is none')
content = catalog.entries() content = catalog.entries()
self.assertTrue(len(content.archetypes) == 2) self.assertTrue(len(content.archetypes) == 2)
print(catalog)
# retrieving all the entries should not raise any exceptions # retrieving all the entries should not raise any exceptions
for category in catalog_categories: for category in catalog_categories:
for value in catalog_categories[category]: for value in catalog_categories[category]:
catalog.get_entry(value) catalog.get_entry(value)
print(value)
with self.assertRaises(IndexError): with self.assertRaises(IndexError):
catalog.get_entry('unknown') catalog.get_entry('unknown')

View File

@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
import logging
import os import os
import unittest import unittest
from unittest import TestCase from unittest import TestCase
@ -48,7 +49,7 @@ class Control:
connection = engine.connect() connection = engine.connect()
connection.close() connection.close()
except ProgrammingError: except ProgrammingError:
print(f'Database does not exist. Nothing to delete') logging.info('Database does not exist. Nothing to delete')
except sqlalchemy.exc.OperationalError as operational_error: except sqlalchemy.exc.OperationalError as operational_error:
self._skip_test = True self._skip_test = True
self._skip_reason = f'{operational_error}' self._skip_reason = f'{operational_error}'

View File

@ -86,7 +86,6 @@ class TestGeometryFactory(TestCase):
elif input_key == 'hft': elif input_key == 'hft':
for building in city.buildings: for building in city.buildings:
building.function = Dictionaries().hft_function_to_hub_function[building.function] building.function = Dictionaries().hft_function_to_hub_function[building.function]
print(construction_key, usage_key)
ConstructionFactory(construction_key, city).enrich() ConstructionFactory(construction_key, city).enrich()
UsageFactory(usage_key, city).enrich() UsageFactory(usage_key, city).enrich()

View File

@ -14,9 +14,6 @@ class TestSystemsCatalog(TestCase):
def test_montreal_custom_catalog(self): def test_montreal_custom_catalog(self):
catalog = EnergySystemsCatalogFactory('montreal_custom').catalog catalog = EnergySystemsCatalogFactory('montreal_custom').catalog
catalog_categories = catalog.names() catalog_categories = catalog.names()
for archetype in catalog.entries('archetypes'):
for equipment in archetype.equipments:
print(equipment._equipment_id)
archetypes = catalog.names('archetypes') archetypes = catalog.names('archetypes')
self.assertEqual(18, len(archetypes['archetypes'])) self.assertEqual(18, len(archetypes['archetypes']))
equipments = catalog.names('equipments') equipments = catalog.names('equipments')