123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
from persistence.models import Building
|
|
from city_model_structure.building_demand.surface import Surface
|
|
from typing import Dict, List, Union
|
|
import numpy as np
|
|
|
|
|
|
class CityUtil(object):
|
|
# holds a single instance of this class
|
|
_instance = None
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __new__(cls):
|
|
"""
|
|
Implemented for a singleton pattern
|
|
"""
|
|
if cls._instance is None:
|
|
cls._instance = super(CityUtil, cls).__new__(cls)
|
|
return cls._instance
|
|
|
|
def _class_object_to_dict(self, class_obj) -> Union[Dict, None]:
|
|
"""
|
|
converts a class object to a dictionary
|
|
:param class_obj: the class object
|
|
:return:
|
|
"""
|
|
if class_obj is None:
|
|
return None
|
|
if type(class_obj) is not dict:
|
|
return vars(class_obj)
|
|
return class_obj
|
|
|
|
def _ndarray_to_list(self, key, building_dict) -> Union[Dict, None]:
|
|
"""
|
|
Converts a numpy array to dictionary
|
|
:param key: the key to the dictionary value
|
|
:param building_dict: the dictionary
|
|
:return:
|
|
"""
|
|
if dict is not None:
|
|
if type(building_dict[key]) is np.ndarray:
|
|
return building_dict[key].tolist()
|
|
else:
|
|
return building_dict[key]
|
|
return None
|
|
|
|
def object_list_to_dict_list(self, object_list):
|
|
"""
|
|
converts a list of objects to a list of dictionaries
|
|
:param object_list: a list of objects
|
|
:return:
|
|
"""
|
|
if object_list is None:
|
|
return []
|
|
return [self._class_object_to_dict(obj) for obj in object_list]
|
|
|
|
def _serialize_points(self, points) -> List:
|
|
"""
|
|
Deserializes arry of Point objects to array of dictionarier
|
|
:param points: a Point object
|
|
:return a list of points []:
|
|
"""
|
|
if points is None:
|
|
return None
|
|
serialized_points = []
|
|
for i in range(len(points)):
|
|
point = self._class_object_to_dict(points[i])
|
|
point['_coordinates'] = self._ndarray_to_list('_coordinates', point)
|
|
serialized_points.append(point)
|
|
return serialized_points
|
|
|
|
def extract_building_data(self, building: Building) -> Dict:
|
|
"""
|
|
Extracts various values from a building
|
|
:param building: the building object
|
|
:return: a dictionary {} of building attributes
|
|
"""
|
|
dict_building = {}
|
|
for key, value in vars(building).items():
|
|
if key in ['_name', '_year_of_construction', '_function', '_floor_area']:
|
|
continue
|
|
if type(value) is list:
|
|
if len(value) == 0:
|
|
dict_building[key] = []
|
|
elif len(value) > 0:
|
|
if type(value[0]) is Surface:
|
|
try:
|
|
surfaces = []
|
|
for surface in value:
|
|
surface_dict = vars(surface)
|
|
perimeter_polygon = self._class_object_to_dict(surface_dict['_perimeter_polygon'])
|
|
solid_polygon = self._class_object_to_dict(surface_dict['_solid_polygon'])
|
|
holes_polygon = self._class_object_to_dict(surface_dict['_holes_polygons'])
|
|
|
|
if perimeter_polygon is not None:
|
|
perimeter_polygon['_coordinates'] = self._ndarray_to_list('_coordinates', perimeter_polygon)
|
|
perimeter_polygon['_points'] = self._serialize_points(perimeter_polygon['_points'])
|
|
surface_dict['_perimeter_polygon'] = perimeter_polygon
|
|
|
|
if holes_polygon is not None:
|
|
holes_polygon['_coordinates'] = self._ndarray_to_list('_coordinates', holes_polygon)
|
|
holes_polygon['_points'] = self._serialize_points(holes_polygon['_points'])
|
|
surface_dict['_holes_polygons'] = holes_polygon
|
|
|
|
if solid_polygon is not None:
|
|
solid_polygon['_coordinates'] = self._ndarray_to_list('_coordinates', solid_polygon)
|
|
solid_polygon['_points'] = self._serialize_points(solid_polygon['_points'])
|
|
surface_dict['_solid_polygon'] = solid_polygon
|
|
|
|
surfaces.append(surface_dict)
|
|
dict_building[key] = surfaces
|
|
except KeyError as err:
|
|
print(f'Dictionary key error: {err}')
|
|
elif value is None:
|
|
dict_building[key] = None
|
|
elif type(value) in [str, int, dict, np.float64]:
|
|
dict_building[key] = value
|
|
elif type(value) is np.ndarray:
|
|
dict_building[key] = value.tolist()
|
|
|
|
return dict_building
|