forked from s_ranjbar/city_retrofit
228 lines
5.7 KiB
Python
228 lines
5.7 KiB
Python
"""
|
|
CityObject module
|
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
|
"""
|
|
from city_model_structure.attributes.sensor import Sensor
|
|
from typing import List, Union
|
|
from city_model_structure.attributes.surface import Surface
|
|
from city_model_structure.attributes.polyhedron import Polyhedron
|
|
from helpers.configuration_helper import ConfigurationHelper
|
|
|
|
import math
|
|
|
|
|
|
class CityObject:
|
|
"""
|
|
class CityObject
|
|
"""
|
|
def __init__(self, name, lod, surfaces, city_lower_corner):
|
|
self._name = name
|
|
self._lod = lod
|
|
self._surfaces = surfaces
|
|
self._city_lower_corner = city_lower_corner
|
|
self._type = None
|
|
self._city_object_lower_corner = None
|
|
self._detailed_polyhedron = None
|
|
self._simplified_polyhedron = None
|
|
self._min_x = ConfigurationHelper().max_coordinate
|
|
self._min_y = ConfigurationHelper().max_coordinate
|
|
self._min_z = ConfigurationHelper().max_coordinate
|
|
self._centroid = None
|
|
self._external_temperature = dict()
|
|
self._global_horizontal = dict()
|
|
self._diffuse = dict()
|
|
self._beam = dict()
|
|
self._sensors = []
|
|
|
|
@property
|
|
def lod(self):
|
|
"""
|
|
City object level of detail 1, 2, 3 or 4
|
|
:return: int
|
|
"""
|
|
lod = math.log(self._lod, 2) + 1
|
|
return lod
|
|
|
|
@property
|
|
def type(self):
|
|
"""
|
|
city object type
|
|
:return: str
|
|
"""
|
|
return self._type
|
|
|
|
@property
|
|
def volume(self):
|
|
"""
|
|
City object volume in cubic meters
|
|
:return: float
|
|
"""
|
|
return self.simplified_polyhedron.volume
|
|
|
|
@property
|
|
def detailed_polyhedron(self) -> Polyhedron:
|
|
"""
|
|
City object polyhedron including details such as holes
|
|
:return: Polyhedron
|
|
"""
|
|
if self._detailed_polyhedron is None:
|
|
polygons = []
|
|
for surface in self.surfaces:
|
|
polygons.append(surface.solid_polygon)
|
|
if surface.holes_polygons is not None:
|
|
for hole_polygon in surface.holes_polygons:
|
|
polygons.append(hole_polygon)
|
|
self._detailed_polyhedron = Polyhedron(polygons)
|
|
return self._detailed_polyhedron
|
|
|
|
@property
|
|
def simplified_polyhedron(self) -> Polyhedron:
|
|
"""
|
|
City object polyhedron, just the simple lod2 representation
|
|
:return: Polyhedron
|
|
"""
|
|
if self._simplified_polyhedron is None:
|
|
polygons = []
|
|
for surface in self.surfaces:
|
|
polygons.append(surface.perimeter_polygon)
|
|
self._simplified_polyhedron = Polyhedron(polygons)
|
|
return self._simplified_polyhedron
|
|
|
|
@property
|
|
def surfaces(self) -> List[Surface]:
|
|
"""
|
|
City object surfaces
|
|
:return: [Surface]
|
|
"""
|
|
return self._surfaces
|
|
|
|
def surface(self, name) -> Union[Surface, None]:
|
|
"""
|
|
Get the city object surface with a given name
|
|
:param name: str
|
|
:return: None or Surface
|
|
"""
|
|
for s in self.surfaces:
|
|
if s.name == name:
|
|
return s
|
|
return None
|
|
|
|
def surface_by_id(self, identification_number) -> Union[Surface, None]:
|
|
"""
|
|
Get the city object surface with a given name
|
|
:param identification_number: str
|
|
:return: None or Surface
|
|
"""
|
|
for s in self.surfaces:
|
|
if str(s.id) == str(identification_number):
|
|
return s
|
|
return None
|
|
|
|
@property
|
|
def centroid(self):
|
|
"""
|
|
City object centroid
|
|
:return: [x,y,z]
|
|
"""
|
|
if self._centroid is None:
|
|
self._centroid = self.simplified_polyhedron.centroid
|
|
return self._centroid
|
|
|
|
@property
|
|
def max_height(self):
|
|
"""
|
|
City object maximal height in meters
|
|
:return: float
|
|
"""
|
|
return self.simplified_polyhedron.max_z
|
|
|
|
@property
|
|
def external_temperature(self) -> dict:
|
|
"""
|
|
external temperature surrounding the city object in grads Celsius
|
|
:return: dict{DataFrame(float)}
|
|
"""
|
|
return self._external_temperature
|
|
|
|
@external_temperature.setter
|
|
def external_temperature(self, value):
|
|
"""
|
|
external temperature surrounding the city object in grads Celsius
|
|
:param value: dict{DataFrame(float)}
|
|
"""
|
|
self._external_temperature = value
|
|
|
|
@property
|
|
def global_horizontal(self) -> dict:
|
|
"""
|
|
global horizontal radiation surrounding the city object in W/m2
|
|
:return: dict{DataFrame(float)}
|
|
"""
|
|
return self._global_horizontal
|
|
|
|
@global_horizontal.setter
|
|
def global_horizontal(self, value):
|
|
"""
|
|
global horizontal radiation surrounding the city object in W/m2
|
|
:param value: dict{DataFrame(float)}
|
|
"""
|
|
self._global_horizontal = value
|
|
|
|
@property
|
|
def diffuse(self) -> dict:
|
|
"""
|
|
diffuse radiation surrounding the city object in W/m2
|
|
:return: dict{DataFrame(float)}
|
|
"""
|
|
return self._diffuse
|
|
|
|
@diffuse.setter
|
|
def diffuse(self, value):
|
|
"""
|
|
diffuse radiation surrounding the city object in W/m2
|
|
:param value: dict{DataFrame(float)}
|
|
"""
|
|
self._diffuse = value
|
|
|
|
@property
|
|
def beam(self) -> dict:
|
|
"""
|
|
beam radiation surrounding the city object in W/m2
|
|
:return: dict{DataFrame(float)}
|
|
"""
|
|
return self._beam
|
|
|
|
@beam.setter
|
|
def beam(self, value):
|
|
"""
|
|
beam radiation surrounding the city object in W/m2
|
|
:param value: dict{DataFrame(float)}
|
|
"""
|
|
self._beam = value
|
|
|
|
@property
|
|
def lower_corner(self):
|
|
"""
|
|
City object lower corner coordinates [x, y, z]
|
|
"""
|
|
if self._city_object_lower_corner is None:
|
|
self._city_object_lower_corner = [self._min_x, self._min_y, self._min_z]
|
|
return self._city_object_lower_corner
|
|
|
|
@property
|
|
def sensors(self) -> List[Sensor]:
|
|
"""
|
|
Sensor list belonging to the city object
|
|
:return: [Sensor]
|
|
"""
|
|
return self._sensors
|
|
|
|
@sensors.setter
|
|
def sensors(self, value):
|
|
"""
|
|
Sensor list belonging to the city object
|
|
:param value: [Sensor]
|
|
"""
|
|
self._sensors = value
|