Partial completion of new persistence.
Results are still missing and need to be added to the final commit. including the db table creation that seems to be missing
This commit is contained in:
parent
48dddae525
commit
a33bf0b366
|
@ -246,7 +246,9 @@ class Polygon:
|
|||
polygon = shapley_polygon(coordinates)
|
||||
|
||||
try:
|
||||
|
||||
vertices_2d, faces = trimesh.creation.triangulate_polygon(polygon, engine='triangle')
|
||||
|
||||
mesh = Trimesh(vertices=vertices, faces=faces)
|
||||
|
||||
# check orientation
|
||||
|
|
|
@ -92,7 +92,6 @@ class Polyhedron:
|
|||
points = polygon.coordinates
|
||||
if len(points) != 3:
|
||||
sub_polygons = polygon.triangles
|
||||
# todo: I modified this! To be checked @Guille
|
||||
if len(sub_polygons) >= 1:
|
||||
for sub_polygon in sub_polygons:
|
||||
face = []
|
||||
|
|
|
@ -494,6 +494,8 @@ class Building(CityObject):
|
|||
"""
|
||||
_usage = ''
|
||||
for internal_zone in self.internal_zones:
|
||||
if internal_zone.usages is None:
|
||||
continue
|
||||
for usage in internal_zone.usages:
|
||||
_usage = f'{_usage}{usage.name}_{usage.percentage} '
|
||||
return _usage.rstrip()
|
||||
|
|
|
@ -77,7 +77,7 @@ class InselMonthlyEnergyBalance(Insel):
|
|||
if levels_of_detail.weather < 1:
|
||||
raise Exception(f'Level of detail of weather = {levels_of_detail.weather}. Required minimum level 1')
|
||||
if levels_of_detail.surface_radiation is None:
|
||||
raise Exception(f'Level of detail of usage not assigned')
|
||||
raise Exception(f'Level of detail of surface radiation not assigned')
|
||||
if levels_of_detail.surface_radiation < 1:
|
||||
raise Exception(f'Level of detail of surface radiation = {levels_of_detail.surface_radiation}. '
|
||||
f'Required minimum level 1')
|
||||
|
|
|
@ -37,7 +37,7 @@ class DBFactory:
|
|||
def user_info(self, name, password, application_id):
|
||||
"""
|
||||
Retrieve the user info for the given name and password and application_id
|
||||
:param name: the user name
|
||||
:param name: the username
|
||||
:param password: the user password
|
||||
:param application_id: the application id
|
||||
:return: User or None
|
||||
|
@ -47,7 +47,7 @@ class DBFactory:
|
|||
def user_login(self, name, password, application_uuid):
|
||||
"""
|
||||
Retrieve the user info
|
||||
:param name: the user name
|
||||
:param name: the username
|
||||
:param password: the user password
|
||||
:param application_uuid: the application uuid
|
||||
:return: User or None
|
||||
|
|
|
@ -4,10 +4,11 @@ import os
|
|||
import sys
|
||||
|
||||
|
||||
def get_logger(file_logger=False):
|
||||
def get_logger(file_logger=False, debug_level=logger.ERROR):
|
||||
"""
|
||||
Returns a logging object
|
||||
:param file_logger: a boolean to indicate the kind of logging
|
||||
:param debug_level: the value for the logger level (default error)
|
||||
object to return, true (default) means a file logger is required
|
||||
:return:
|
||||
"""
|
||||
|
@ -21,11 +22,11 @@ def get_logger(file_logger=False):
|
|||
os.mkdir(log_dir)
|
||||
with open(log_file, 'x'):
|
||||
pass
|
||||
logger.basicConfig(filename=log_file, format=log_format, level=logger.DEBUG)
|
||||
logger.basicConfig(filename=log_file, format=log_format, level=debug_level)
|
||||
return logger
|
||||
except IOError as err:
|
||||
print(f'I/O exception: {err}')
|
||||
else:
|
||||
logger.getLogger().addHandler(logger.StreamHandler(stream=sys.stdout))
|
||||
logger.getLogger().setLevel(logger.DEBUG)
|
||||
logger.getLogger().setLevel(debug_level)
|
||||
return logger.getLogger()
|
||||
|
|
|
@ -35,6 +35,10 @@ class NrcanPhysicsParameters:
|
|||
city = self._city
|
||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||
for building in city.buildings:
|
||||
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function.keys():
|
||||
logger.error(f'Building {building.name} has an unknown building function {building.function}\n')
|
||||
sys.stderr.write(f'Building {building.name} has an unknown building function {building.function}\n')
|
||||
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)
|
||||
|
|
|
@ -35,21 +35,27 @@ 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():
|
||||
logger.error(f'Building {building.name} has unknown function [{building.function}]')
|
||||
sys.stderr.write(f'Building {building.name} has unknown function [{building.function}]\n')
|
||||
continue
|
||||
if building.function not in Dictionaries().hub_function_to_nrel_construction_function.keys():
|
||||
logger.error(f'Building {building.name} has unknown function {building.function}\n')
|
||||
sys.stderr.write(f'Building {building.name} has unknown function {building.function}\n')
|
||||
continue
|
||||
function = Dictionaries().hub_function_to_nrel_construction_function[building.function]
|
||||
try:
|
||||
archetype = self._search_archetype(nrel_catalog, function, building.year_of_construction,
|
||||
self._climate_zone)
|
||||
archetype = self._search_archetype(nrel_catalog, function, building.year_of_construction, self._climate_zone)
|
||||
except KeyError:
|
||||
logger.error(f'Building {building.name} has unknown construction archetype for building function: '
|
||||
f'{function} [{building.function}], building year of construction: {building.year_of_construction} '
|
||||
f'and climate zone {self._climate_zone}\n')
|
||||
f'{function} [{building.function}], building year of construction: {building.year_of_construction}'
|
||||
f' and climate zone {self._climate_zone}\n')
|
||||
sys.stderr.write(f'Building {building.name} has unknown construction archetype for building function: '
|
||||
f'{function} [{building.function}], '
|
||||
f'building year of construction: {building.year_of_construction} '
|
||||
f'and climate zone {self._climate_zone}\n')
|
||||
|
||||
continue
|
||||
|
||||
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
||||
# one thermal zone per storey is assigned
|
||||
if len(building.internal_zones) == 1:
|
||||
|
|
|
@ -13,6 +13,7 @@ from sqlalchemy import DateTime
|
|||
from hub.city_model_structure.building import Building
|
||||
from hub.persistence.configuration import Models
|
||||
|
||||
|
||||
class CityObject(Models):
|
||||
"""
|
||||
A model representation of an application
|
||||
|
@ -46,3 +47,23 @@ class CityObject(Models):
|
|||
self.usage = building.usages_percentage
|
||||
self.volume = building.volume
|
||||
self.area = building.floor_area
|
||||
storeys = building.storeys_above_ground
|
||||
if storeys is None:
|
||||
print(building.average_storey_height)
|
||||
storeys = building.max_height / building.average_storey_height
|
||||
self.total_heating_area = building.floor_area * storeys
|
||||
wall_area = 0
|
||||
for wall in building.walls:
|
||||
wall_area += wall.solid_polygon.area
|
||||
self.wall_area = wall_area
|
||||
window_ratio = 0
|
||||
for internal_zone in building.internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
window_ratio = thermal_boundary.window_ratio
|
||||
break
|
||||
self.windows_area = wall_area * window_ratio
|
||||
system_name = building.energy_systems_archetype_name
|
||||
if system_name is None:
|
||||
system_name = ''
|
||||
self.system_name = system_name
|
||||
|
|
|
@ -76,7 +76,8 @@ class City(Repository):
|
|||
"""
|
||||
try:
|
||||
now = datetime.datetime.utcnow()
|
||||
self.session.query(Model).filter(Model.id == city_id).update({'name': city.name,'updated': now})
|
||||
print(f'{now}')
|
||||
self.session.query(Model).filter(Model.id == city_id).update({'name': city.name, 'updated': now})
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while updating city: {err}')
|
||||
|
|
|
@ -41,20 +41,8 @@ class CityObject(Repository):
|
|||
city_object = self.get_by_name_and_city(building.name, city_id)
|
||||
if city_object is None:
|
||||
try:
|
||||
object_usage = ''
|
||||
for internal_zone in building.internal_zones:
|
||||
for usage in internal_zone.usages:
|
||||
object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
|
||||
object_usage = object_usage.rstrip()
|
||||
city_object = Model(city_id=city_id,
|
||||
name=building.name,
|
||||
alias=building.alias,
|
||||
object_type=building.type,
|
||||
year_of_construction=building.year_of_construction,
|
||||
function=building.function,
|
||||
usage=object_usage,
|
||||
volume=building.volume,
|
||||
area=building.floor_area)
|
||||
building=building)
|
||||
self.session.add(city_object)
|
||||
self.session.flush()
|
||||
self.session.commit()
|
||||
|
|
|
@ -284,12 +284,3 @@ class TestConstructionFactory(TestCase):
|
|||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
self._check_surfaces(thermal_boundary)
|
||||
|
||||
def test_archetype_not_found(self):
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.year_of_construction = 1990
|
||||
building.function = 'office'
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ from pathlib import Path
|
|||
import sqlalchemy.exc
|
||||
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.db_factory import DBFactory as ImportDBFactory
|
||||
from hub.imports.user_factory import UserFactory
|
||||
from hub.exports.db_factory import DBFactory as ExportDBFactory
|
||||
|
@ -18,29 +20,34 @@ from hub.persistence.repository import Repository
|
|||
from sqlalchemy import create_engine
|
||||
from hub.persistence.models import City, Application, CityObject
|
||||
from hub.persistence.models import User, UserRoles
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from sqlalchemy.exc import ProgrammingError
|
||||
import uuid
|
||||
|
||||
class Configure:
|
||||
|
||||
class Configure:
|
||||
_skip_test = False
|
||||
_skip_reason = 'PostgreSQL not properly installed in host machine'
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Test
|
||||
setup
|
||||
:return: None
|
||||
"""
|
||||
Test
|
||||
setup
|
||||
:return: None
|
||||
"""
|
||||
self._skip_test = False
|
||||
# Create test database
|
||||
dotenv_path = str(Path("{}/.local/etc/hub/.env".format(os.path.expanduser('~'))).resolve())
|
||||
repository = Repository(db_name='hub_unittest', app_env='TEST', dotenv_path=dotenv_path)
|
||||
dotenv_path = Path("{}/.local/etc/hub/.env".format(os.path.expanduser('~'))).resolve()
|
||||
if not dotenv_path.exists():
|
||||
self._skip_test = True
|
||||
self._skip_reason = f'.env file missing at {dotenv_path}'
|
||||
return
|
||||
dotenv_path = str(dotenv_path)
|
||||
repository = Repository(db_name='hub_unittests', app_env='TEST', dotenv_path=dotenv_path)
|
||||
engine = create_engine(repository.configuration.connection_string)
|
||||
try:
|
||||
# delete test database if it exists
|
||||
connection = engine.connect()
|
||||
connection.execute('commit')
|
||||
connection.close()
|
||||
except ProgrammingError:
|
||||
print(f'Database does not exist. Nothing to delete')
|
||||
|
@ -55,7 +62,12 @@ class Configure:
|
|||
CityObject.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
|
||||
city_file = "tests_data/FZK_Haus_LoD_2.gml"
|
||||
self._city = GeometryFactory('citygml', city_file).city
|
||||
self._city = GeometryFactory('citygml',
|
||||
city_file,
|
||||
function_to_hub=Dictionaries().alkis_function_to_hub_function).city
|
||||
ConstructionFactory('nrcan', self._city).enrich()
|
||||
UsageFactory('nrcan', self._city).enrich()
|
||||
|
||||
self._import_db_factory = ImportDBFactory(
|
||||
db_name=repository.configuration.db_name,
|
||||
app_env='TEST',
|
||||
|
@ -103,7 +115,7 @@ class Configure:
|
|||
|
||||
@property
|
||||
def message(self):
|
||||
return self._skip_message
|
||||
return self._skip_reason
|
||||
|
||||
@property
|
||||
def city(self):
|
||||
|
@ -113,12 +125,14 @@ class Configure:
|
|||
def pickle_path(self):
|
||||
return self._pickle_path
|
||||
|
||||
|
||||
configure = Configure()
|
||||
|
||||
|
||||
class TestDBFactory(TestCase):
|
||||
"""
|
||||
TestDBFactory
|
||||
"""
|
||||
TestDBFactory
|
||||
"""
|
||||
|
||||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_save_application(self):
|
||||
|
@ -129,43 +143,29 @@ class TestDBFactory(TestCase):
|
|||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_save_city(self):
|
||||
configure.city.name = "Montreal"
|
||||
saved_city = configure.import_db_factory.persist_city(
|
||||
city = configure.import_db_factory.persist_city(
|
||||
configure.city,
|
||||
configure.pickle_path,
|
||||
configure.application.id,
|
||||
configure.user.id)
|
||||
self.assertEqual(saved_city.name, 'Montreal')
|
||||
self.assertEqual(saved_city.pickle_path, self.pickle_path)
|
||||
self.assertEqual(saved_city.level_of_detail, self.city.level_of_detail.geometry)
|
||||
self._db_factory.delete_city(saved_city.id)
|
||||
|
||||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_get_city_by_name(self):
|
||||
city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
|
||||
retrieved_city = self._export_db_factory.get_city_by_name(city.name)
|
||||
self.assertEqual(retrieved_city[0].application_id, 1)
|
||||
self.assertEqual(retrieved_city[0].user_id, self._user.id)
|
||||
self._db_factory.delete_city(city.id)
|
||||
|
||||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_get_city_by_user(self):
|
||||
city = self._import_db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
|
||||
retrieved_city = self._export_db_factory.get_city_by_user(self._user.id)
|
||||
self.assertEqual(retrieved_city[0].pickle_path, self.pickle_path)
|
||||
self._db_factory.delete_city(city.id)
|
||||
|
||||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_get_city_by_id(self):
|
||||
city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
|
||||
retrieved_city = self._export_db_factory.get_city(city.id)
|
||||
self.assertEqual(retrieved_city.level_of_detail, self.city.level_of_detail.geometry)
|
||||
self._db_factory.delete_city(city.id)
|
||||
self.assertEqual(city.name, 'Montreal')
|
||||
self.assertEqual(city.pickle_path, configure.pickle_path)
|
||||
self.assertEqual(city.level_of_detail, configure.city.level_of_detail.geometry)
|
||||
configure.import_db_factory.delete_city(city.id)
|
||||
|
||||
@unittest.skipIf(configure.skip_test, configure.skip_reason)
|
||||
def test_get_update_city(self):
|
||||
city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
|
||||
self.city.name = "Ottawa"
|
||||
self._db_factory.update_city(city.id, self.city)
|
||||
updated_city = self._export_db_factory.get_city(city.id)
|
||||
self.assertEqual(updated_city.name, self.city.name)
|
||||
self._db_factory.delete_city(city.id)
|
||||
city = configure.import_db_factory.persist_city(configure.city,
|
||||
configure.pickle_path,
|
||||
configure.application.id,
|
||||
configure._user.id)
|
||||
city.name = "Ottawa"
|
||||
configure.import_db_factory.update_city(city.id, configure.city)
|
||||
cities = configure.export_db_factory.cities_by_user_and_application(
|
||||
configure.user.id,
|
||||
configure.application.id)
|
||||
for updated_city in cities:
|
||||
if updated_city.id == city.id:
|
||||
self.assertEqual(updated_city.name, city.name)
|
||||
break
|
||||
configure.import_db_factory.delete_city(city.id)
|
||||
|
|
|
@ -63,6 +63,7 @@ class TestExports(TestCase):
|
|||
:parameter city: city
|
||||
:return: none
|
||||
"""
|
||||
city.level_of_detail.surface_radiation = 2
|
||||
for radiation in self._read_sra_file:
|
||||
city_object_name = radiation.columns.values.tolist()[1].split(':')[1]
|
||||
building = city.city_object(city_object_name)
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user