forked from s_ranjbar/city_retrofit
Full implementation of basic persistence tasks for the one_shot admin tool.
This commit is contained in:
parent
a34206e6ff
commit
16adfaa1a8
|
@ -6,6 +6,8 @@ Project CoderPeter Yefi peteryefi@gmail.com
|
|||
"""
|
||||
from hub.persistence import City
|
||||
from hub.persistence import Application
|
||||
from hub.persistence import User
|
||||
from hub.persistence import CityObject
|
||||
|
||||
|
||||
class DBFactory:
|
||||
|
@ -16,6 +18,8 @@ class DBFactory:
|
|||
def __init__(self, db_name, app_env, dotenv_path):
|
||||
self._city = City(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._application = Application(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._user = User(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._city_object = CityObject(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
|
||||
def get_city(self, city_id):
|
||||
"""
|
||||
|
@ -41,3 +45,9 @@ class DBFactory:
|
|||
def application_info(self, application_uuid):
|
||||
return self._application.get_by_uuid(application_uuid)
|
||||
|
||||
def user_info(self, name, password, application_id):
|
||||
return self._user.get_by_name_application_and_password(name, password, application_id)
|
||||
|
||||
def building_info(self, name, city_id):
|
||||
return self._city_object.get_by_name_and_city(name, city_id)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ Project CoderPeter Yefi peteryefi@gmail.com
|
|||
"""
|
||||
from hub.city_model_structure.city import City
|
||||
from hub.persistence import City as CityRepository
|
||||
from hub.persistence import SimulationResults
|
||||
|
||||
|
||||
class DBFactory:
|
||||
|
@ -15,10 +16,14 @@ class DBFactory:
|
|||
|
||||
def __init__(self, db_name, dotenv_path, app_env):
|
||||
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, application_id: int, user_id: int, city: City):
|
||||
def persist_city(self, city: City, application_id: int, user_id: int):
|
||||
"""
|
||||
Persist city into postgres database
|
||||
:param city: City to be stored
|
||||
: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)
|
||||
|
||||
|
@ -36,3 +41,13 @@ class DBFactory:
|
|||
:param city_id: the id of the city to get
|
||||
"""
|
||||
self._city_repository.delete(city_id)
|
||||
|
||||
def add_simulation_results(self, name, values, city_id=None, city_object_id=None):
|
||||
"""
|
||||
Add simulation results to the city or to the city_object
|
||||
:param name: simulation and simulation engine name
|
||||
:param values: simulation values in json format
|
||||
:param city_id: city id or None
|
||||
:param city_object_id: city object id or None
|
||||
"""
|
||||
self._simulation_results.insert(name, values,city_id, city_object_id)
|
||||
|
|
|
@ -19,12 +19,18 @@ class CityGml:
|
|||
"""
|
||||
CityGml class
|
||||
"""
|
||||
def __init__(self, path, extrusion_height_field=None, year_of_construction_field=None, function_field=None):
|
||||
def __init__(self,
|
||||
path,
|
||||
extrusion_height_field=None,
|
||||
year_of_construction_field='yearOfConstruction',
|
||||
function_field='function',
|
||||
function_to_hub=None):
|
||||
self._city = None
|
||||
self._lod = None
|
||||
self._lod1_tags = ['lod1Solid', 'lod1MultiSurface']
|
||||
self._lod2_tags = ['lod2Solid', 'lod2MultiSurface', 'lod2MultiCurve']
|
||||
self._extrusion_height_field = extrusion_height_field
|
||||
self._function_to_hub = function_to_hub
|
||||
self._year_of_construction_field = year_of_construction_field
|
||||
if function_field is None:
|
||||
function_field = 'function'
|
||||
|
@ -110,12 +116,15 @@ class CityGml:
|
|||
name = city_object['@id']
|
||||
function = None
|
||||
year_of_construction = None
|
||||
if 'yearOfConstruction' in city_object:
|
||||
year_of_construction = city_object['yearOfConstruction']
|
||||
if 'function' in city_object:
|
||||
if self._year_of_construction_field in city_object:
|
||||
year_of_construction = city_object[self._year_of_construction_field]
|
||||
if self._function_field in city_object:
|
||||
function = city_object[self._function_field]
|
||||
if type(function) != str:
|
||||
function = function['#text']
|
||||
if self._function_to_hub is not None:
|
||||
# use the transformation dictionary to retrieve the proper function
|
||||
function = self._function_to_hub[function]
|
||||
|
||||
if any(key in city_object for key in self._lod1_tags):
|
||||
if self._lod is None or self._lod > 1:
|
||||
|
|
|
@ -26,7 +26,12 @@ class Geojson:
|
|||
X = 0
|
||||
Y = 1
|
||||
|
||||
def __init__(self, path, extrusion_height_field=None, year_of_construction_field=None, function_field=None):
|
||||
def __init__(self,
|
||||
path,
|
||||
extrusion_height_field=None,
|
||||
year_of_construction_field=None,
|
||||
function_field=None,
|
||||
function_to_hub=None):
|
||||
# todo: destination epsg should change according actual the location
|
||||
self._transformer = Transformer.from_crs('epsg:4326', 'epsg:26911')
|
||||
self._min_x = cte.MAX_FLOAT
|
||||
|
@ -38,6 +43,7 @@ class Geojson:
|
|||
self._extrusion_height_field = extrusion_height_field
|
||||
self._year_of_construction_field = year_of_construction_field
|
||||
self._function_field = function_field
|
||||
self._function_to_hub = function_to_hub
|
||||
with open(path) as json_file:
|
||||
self._geojson = json.loads(json_file.read())
|
||||
|
||||
|
@ -118,6 +124,9 @@ class Geojson:
|
|||
function = None
|
||||
if self._function_field is not None:
|
||||
function = feature['properties'][self._function_field]
|
||||
if self._function_to_hub is not None:
|
||||
# use the transformation dictionary to retrieve the proper function
|
||||
function = self._function_to_hub[function]
|
||||
geometry = feature['geometry']
|
||||
if 'id' in feature:
|
||||
building_name = feature['id']
|
||||
|
|
|
@ -26,7 +26,8 @@ class GeometryFactory:
|
|||
data_frame=None,
|
||||
height_field=None,
|
||||
year_of_construction_field=None,
|
||||
function_field=None):
|
||||
function_field=None,
|
||||
function_to_hub=None):
|
||||
self._file_type = '_' + file_type.lower()
|
||||
class_funcs = validate_import_export_type(GeometryFactory)
|
||||
if self._file_type not in class_funcs:
|
||||
|
@ -38,6 +39,7 @@ class GeometryFactory:
|
|||
self._height_field = height_field
|
||||
self._year_of_construction_field = year_of_construction_field
|
||||
self._function_field = function_field
|
||||
self._function_to_hub = function_to_hub
|
||||
|
||||
@property
|
||||
def _citygml(self) -> City:
|
||||
|
@ -45,7 +47,11 @@ class GeometryFactory:
|
|||
Enrich the city by using CityGML information as data source
|
||||
:return: City
|
||||
"""
|
||||
return CityGml(self._path, self._height_field, self._year_of_construction_field, self._function_field).city
|
||||
return CityGml(self._path,
|
||||
self._height_field,
|
||||
self._year_of_construction_field,
|
||||
self._function_field,
|
||||
self._function_to_hub).city
|
||||
|
||||
@property
|
||||
def _obj(self) -> City:
|
||||
|
@ -71,7 +77,11 @@ class GeometryFactory:
|
|||
Enrich the city by using Geojson information as data source
|
||||
:return: City
|
||||
"""
|
||||
return Geojson(self._path, self._height_field, self._year_of_construction_field, self._function_field).city
|
||||
return Geojson(self._path,
|
||||
self._height_field,
|
||||
self._year_of_construction_field,
|
||||
self._function_field,
|
||||
self._function_to_hub).city
|
||||
|
||||
@property
|
||||
def _osm_subway(self) -> City:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from .repository import Repository
|
||||
from .repositories.city import City
|
||||
from .repositories.application import Application
|
||||
from .repositories.simulation_results import SimulationResults
|
||||
from .repositories.city_object import CityObject
|
||||
from .db_setup import DBSetup
|
||||
from .repositories.user import User
|
||||
from .models.user import UserRoles
|
||||
|
|
|
@ -16,6 +16,7 @@ from hub.city_model_structure.city import City as CityHub
|
|||
from hub.hub_logger import logger
|
||||
from hub.persistence import Repository
|
||||
from hub.persistence.models import City as Model
|
||||
from hub.persistence.models import CityObject
|
||||
from hub.version import __version__
|
||||
|
||||
|
||||
|
@ -45,17 +46,35 @@ class City(Repository):
|
|||
db_city = Model(
|
||||
pickle.dumps(city),
|
||||
city.name,
|
||||
city.level_of_detail,
|
||||
city.climate_file,
|
||||
city.level_of_detail.geometry,
|
||||
'None' if city.climate_file is None else city.climate_file,
|
||||
application_id,
|
||||
user_id,
|
||||
__version__)
|
||||
|
||||
self.session.add(db_city)
|
||||
self.session.flush()
|
||||
for building in city.buildings:
|
||||
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()
|
||||
db_city_object = CityObject(db_city.id,
|
||||
building.name,
|
||||
building.alias,
|
||||
building.type,
|
||||
building.year_of_construction,
|
||||
building.function,
|
||||
object_usage,
|
||||
building.volume,
|
||||
building.floor_area)
|
||||
self.session.add(db_city_object)
|
||||
self.session.flush()
|
||||
self.session.commit()
|
||||
return db_city
|
||||
except SQLAlchemyError as err:
|
||||
print(f'An error occurred while creating city: {err}')
|
||||
logger.error(f'An error occurred while creating city: {err}')
|
||||
|
||||
def update(self, city_id: int, city: CityHub):
|
||||
|
|
|
@ -77,7 +77,7 @@ class CityObject(Repository):
|
|||
for usage in internal_zone.usages:
|
||||
object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
|
||||
object_usage = object_usage.rstrip()
|
||||
self.session.query(Model).filter(Model.name == building.name and Model.city_id == city_id).update(
|
||||
self.session.query(Model).filter(Model.name == building.name, Model.city_id == city_id).update(
|
||||
{'name': building.name,
|
||||
'alias': building.alias,
|
||||
'object_type': building.type,
|
||||
|
@ -100,7 +100,7 @@ class CityObject(Repository):
|
|||
:return: None
|
||||
"""
|
||||
try:
|
||||
self.session.query(Model).filter(Model.city_id == city_id and Model.name == name).delete()
|
||||
self.session.query(Model).filter(Model.city_id == city_id, Model.name == name).delete()
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while deleting application: {err}')
|
||||
|
@ -113,8 +113,13 @@ class CityObject(Repository):
|
|||
:return: [CityObject] with the provided name belonging to the city with id city_id
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(Model).where(
|
||||
Model.name == name and Model.city_id == city_id
|
||||
_city_object = self.session.execute(select(Model).where(
|
||||
Model.name == name, Model.city_id == city_id
|
||||
)).first()
|
||||
print(city_id, name, _city_object)
|
||||
if _city_object is None:
|
||||
return None
|
||||
return _city_object[0]
|
||||
except SQLAlchemyError as err:
|
||||
print(err)
|
||||
logger.error(f'Error while fetching application by application_uuid: {err}')
|
||||
|
|
|
@ -74,14 +74,14 @@ class SimulationResults(Repository):
|
|||
"""
|
||||
try:
|
||||
if city_id is not None:
|
||||
self.session.query(Model).filter(Model.name == name and Model.city_id == city_id).update(
|
||||
self.session.query(Model).filter(Model.name == name, Model.city_id == city_id).update(
|
||||
{
|
||||
'values': values,
|
||||
'updated': datetime.datetime.utcnow()
|
||||
})
|
||||
self.session.commit()
|
||||
elif city_object_id is not None:
|
||||
self.session.query(Model).filter(Model.name == name and Model.city_object_id == city_object_id).update(
|
||||
self.session.query(Model).filter(Model.name == name, Model.city_object_id == city_object_id).update(
|
||||
{
|
||||
'values': values,
|
||||
'updated': datetime.datetime.utcnow()
|
||||
|
@ -104,10 +104,10 @@ class SimulationResults(Repository):
|
|||
"""
|
||||
try:
|
||||
if city_id is not None:
|
||||
self.session.query(Model).filter(Model.name == name and Model.city_id == city_id).delete()
|
||||
self.session.query(Model).filter(Model.name == name, Model.city_id == city_id).delete()
|
||||
self.session.commit()
|
||||
elif city_object_id is not None:
|
||||
self.session.query(Model).filter(Model.name == name and Model.city_object_id == city_object_id).delete()
|
||||
self.session.query(Model).filter(Model.name == name, Model.city_object_id == city_object_id).delete()
|
||||
self.session.commit()
|
||||
else:
|
||||
return {'message': 'Missing either city_id or city_object_id'}
|
||||
|
|
|
@ -94,12 +94,12 @@ class User(Repository):
|
|||
"""
|
||||
try:
|
||||
return self.session.execute(
|
||||
select(Model).where(Model.name == name and Model.application_id == application_id)
|
||||
select(Model).where(Model.name == name, Model.application_id == application_id)
|
||||
).first()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching user by name and application: {err}')
|
||||
|
||||
def get_user_by_name_application_and_password(self, name: str, password: str, application_id: int) -> [Model]:
|
||||
def get_by_name_application_and_password(self, name: str, password: str, application_id: int) -> [Model]:
|
||||
"""
|
||||
Fetch user based on the email and password
|
||||
:param name: User name
|
||||
|
@ -110,11 +110,11 @@ class User(Repository):
|
|||
"""
|
||||
try:
|
||||
user = self.session.execute(
|
||||
select(Model).where(Model.name == name and Model.application_id == application_id)
|
||||
select(Model).where(Model.name == name, Model.application_id == application_id)
|
||||
).first()
|
||||
if user:
|
||||
if Auth.check_password(password, user[0].password):
|
||||
return user
|
||||
return user[0]
|
||||
return {'message': 'invalid login information'}
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching user by email: {err}')
|
||||
|
|
Loading…
Reference in New Issue
Block a user