diff --git a/city_model_structure/city.py b/city_model_structure/city.py index c7a169c5..02b095f0 100644 --- a/city_model_structure/city.py +++ b/city_model_structure/city.py @@ -3,7 +3,7 @@ from typing import List, Union class City: - def __init__(self, lower_corner, upper_corner, city_objects, srs_name): + def __init__(self, lower_corner, upper_corner, srs_name, city_objects=None): self._city_objects = None self._name = None self._lower_corner = lower_corner @@ -12,7 +12,7 @@ class City: self._srs_name = srs_name @property - def city_objects(self) -> List[CityObject]: + def city_objects(self) -> Union[List[CityObject], None]: return self._city_objects @property @@ -29,6 +29,16 @@ class City: return c return None + def add_city_object(self, new_city_object): + if self.city_objects is None: + self._city_objects = [] + for city_object in self.city_objects: + # ToDo: Check for shared walls. + for surface in city_object.surfaces: + for surface2 in new_city_object.surfaces: + surface.shared(surface2) + self._city_objects.append(new_city_object) + @property def srs_name(self): return self._srs_name @@ -40,4 +50,3 @@ class City: @name.setter def name(self, value): self._name = value - diff --git a/city_model_structure/city_object.py b/city_model_structure/city_object.py index 67af8767..0e9ca95a 100644 --- a/city_model_structure/city_object.py +++ b/city_model_structure/city_object.py @@ -29,12 +29,15 @@ class CityObject: self._storeys_above_ground = None self._foot_print = None self._usage_zones = [] + # ToDo: this need to be changed when we have other city_objects beside "buildings" + self._type = 'building' # ToDo: Check this for LOD4 self._thermal_zones = [] if self.lod < 8: # for lod under 4 is just one thermal zone self._thermal_zones.append(ThermalZone(self.surfaces)) + for t in self._thermal_zones: t.bounded = [ThermalBoundary(s, [t]) for s in t.surfaces] surface_id = 0 @@ -47,8 +50,11 @@ class CityObject: return self._usage_zones @usage_zones.setter - def usage_zones(self, value): - self._usage_zones = value + def usage_zones(self, values): + # ToDo: this is only valid for one usage zone need to be revised for multiple usage zones. + self._usage_zones = values + for thermal_zone in self.thermal_zones: + thermal_zone.usage_zones = [(100, usage_zone) for usage_zone in values] @property def terrains(self) -> List[Surface]: @@ -186,6 +192,10 @@ class CityObject: self._foot_print = Surface(points, remove_last=False, is_projected=True) return self._foot_print + @property + def type(self): + return self._type + @property def max_height(self): if self._polyhedron is None: diff --git a/city_model_structure/surface.py b/city_model_structure/surface.py index 522ad438..10b17e76 100644 --- a/city_model_structure/surface.py +++ b/city_model_structure/surface.py @@ -25,6 +25,7 @@ class Surface: self._parent = None self._shapely = None self._projected_surface = None + self._shared_surfaces = None self._global_irradiance_hour = np.zeros(8760) self._global_irradiance_month = np.zeros(12) @@ -76,7 +77,10 @@ class Surface: self._area = self.polygon.get_area() return self._area - def is_almost_same_terrain(self, terrain_points, ground_points): + def _is_shared(self, surface): + return False + + def _is_almost_same_terrain(self, terrain_points, ground_points): equal = 0 for t in terrain_points: for g in ground_points: @@ -85,9 +89,9 @@ class Surface: return equal == len(terrain_points) @property - def is_terrain(self): + def _is_terrain(self): for t_points in self._parent.terrains: - if len(t_points) == len(self.points) and self.is_almost_same_terrain(t_points, self.points): + if len(t_points) == len(self.points) and self._is_almost_same_terrain(t_points, self.points): return True return False @@ -101,7 +105,7 @@ class Surface: def area_below_ground(self): if self._area_below_ground is None: self._area_below_ground = 0.0 - if self.is_terrain: + if self._is_terrain: self._area_below_ground = self.area return self._area_below_ground @@ -126,7 +130,6 @@ class Surface: self._inclination = np.arccos(self.normal[2]) return self._inclination - # todo: share wall @property def type(self): if self._type is None: @@ -139,6 +142,13 @@ class Surface: self._type = 'Roof' return self._type + def shared(self, surface): + if self.type is not 'Wall': + return + if self._is_shared(surface): + self._shared_surfaces.append((100, surface)) + surface.shared(self) + @property def global_irradiance_hour(self): return self._global_irradiance_hour diff --git a/city_model_structure/thermal_zone.py b/city_model_structure/thermal_zone.py index 2d33ad02..c9749db0 100644 --- a/city_model_structure/thermal_zone.py +++ b/city_model_structure/thermal_zone.py @@ -85,11 +85,11 @@ class ThermalZone: def infiltration_rate_system_off(self, value): self._infiltration_rate_system_off = value - # todo: is it well defined? - def set_usage_zones(self, usage_zones_list): - if self._usage_zones is None: - self._usage_zones = [] - for usage_zone in usage_zones_list: - self._usage_zones.append((usage_zone.percentage, usage_zone.type)) + @property + def usage_zones(self): return self._usage_zones + @usage_zones.setter + def usage_zones(self, values): + self._usage_zones = values + diff --git a/geometry/geometry_feeders/city_gml.py b/geometry/geometry_feeders/city_gml.py index 00e78a1a..57ee84f6 100644 --- a/geometry/geometry_feeders/city_gml.py +++ b/geometry/geometry_feeders/city_gml.py @@ -42,7 +42,7 @@ class CityGml: @property def city(self): if self._city is None: - city_objects = [] + self._city = City(self._lower_corner, self._upper_corner, self._srs_name) for o in self._gml['CityModel']['cityObjectMember']: lod = 0 if 'lod1Solid' in o['Building']: @@ -98,9 +98,7 @@ class CityGml: year_of_construction = o['Building']['yearOfConstruction'] if 'function' in o['Building']: function = o['Building']['function'] - - city_objects.append(CityObject(name, lod, surfaces, terrains, year_of_construction, function)) - self._city = City(self._lower_corner, self._upper_corner, city_objects, self._srs_name) + self._city.add_city_object(CityObject(name, lod, surfaces, terrains, year_of_construction, function)) return self._city