diff --git a/city_model_structure/building.py b/city_model_structure/building.py index 58386b0e..8a3bc5a9 100644 --- a/city_model_structure/building.py +++ b/city_model_structure/building.py @@ -33,7 +33,7 @@ class Building(CityObject): self._year_of_construction = year_of_construction self._function = function self._average_storey_height = None - self._storeys_above_ground = None + self._storeys_above_ground = 1 self._floor_area = None self._roof_type = None self._thermal_zones = [] @@ -111,19 +111,11 @@ class Building(CityObject): Get city object usage zones :return: [UsageZone] """ + if len(self._usage_zones) == 0: + for thermal_zone in self.thermal_zones: + self._usage_zones.extend(thermal_zone.usage_zones) return self._usage_zones - @usage_zones.setter - def usage_zones(self, values): - """ - Set city objects usage zones - :param values: [UsageZones] - :return: None - """ - self._usage_zones = values - for thermal_zone in self.thermal_zones: - thermal_zone.usage_zones = values - @property def terrains(self) -> List[Surface]: """ @@ -180,6 +172,9 @@ class Building(CityObject): City object thermal zones :return: [ThermalZone] """ + if len(self._thermal_zones) == 0: + for storey in self.storeys: + self._thermal_zones.append(storey.thermal_zone) return self._thermal_zones @property @@ -307,7 +302,10 @@ class Building(CityObject): number_of_storeys, height = self._calculate_number_storeys_and_height(self.average_storey_height, self.eave_height, self.storeys_above_ground) if number_of_storeys == 0: - return Storey('storey_0', self.surfaces, [None, None]) + raise Exception(f'Number of storeys cannot be 0') + + if number_of_storeys == 1: + return [Storey('storey_0', self.surfaces, [None, None])] storeys = [] surfaces_child_last_storey = [] diff --git a/city_model_structure/building_demand/storey.py b/city_model_structure/building_demand/storey.py index 590bcaba..602806be 100644 --- a/city_model_structure/building_demand/storey.py +++ b/city_model_structure/building_demand/storey.py @@ -94,5 +94,5 @@ class Storey: :return: ThermalZone """ if self._thermal_zone is None: - self._thermal_zone = ThermalZone(self.virtual_surfaces) + self._thermal_zone = ThermalZone(self.thermal_boundaries) return self._thermal_zone diff --git a/city_model_structure/building_demand/surface.py b/city_model_structure/building_demand/surface.py index eb162ad6..028ec372 100644 --- a/city_model_structure/building_demand/surface.py +++ b/city_model_structure/building_demand/surface.py @@ -260,8 +260,11 @@ class Surface: new_solid_polygon = Polygon(self.solid_polygon.inverse) new_perimeter_polygon = Polygon(self.perimeter_polygon.inverse) new_holes_polygons = [] - for hole in self.holes_polygons: - new_holes_polygons.append(Polygon(hole.inverse)) + if self.holes_polygons is not None: + for hole in self.holes_polygons: + new_holes_polygons.append(Polygon(hole.inverse)) + else: + new_holes_polygons = None self._inverse = Surface(new_solid_polygon, new_perimeter_polygon, new_holes_polygons, cte.VIRTUAL_INTERNAL) return self._inverse diff --git a/city_model_structure/building_demand/thermal_zone.py b/city_model_structure/building_demand/thermal_zone.py index f6db43c4..188f3f69 100644 --- a/city_model_structure/building_demand/thermal_zone.py +++ b/city_model_structure/building_demand/thermal_zone.py @@ -17,10 +17,9 @@ class ThermalZone: """ ThermalZone class """ - def __init__(self, surfaces): - self._surfaces = surfaces + def __init__(self, thermal_boundaries): self._floor_area = None - self._bounded = None + self._bounded = thermal_boundaries self._is_mechanically_ventilated = None self._additional_thermal_bridge_u_value = None self._effective_thermal_capacity = None @@ -92,7 +91,8 @@ class ThermalZone: """ if self._floor_area is None: self._floor_area = 0 - for s in self._surfaces: + for thermal_boundary in self.bounded: + s = thermal_boundary.surface if s.type == 'Ground': self._floor_area += s.perimeter_polygon.area return self._floor_area @@ -105,24 +105,6 @@ class ThermalZone: """ return self._bounded - @bounded.setter - def bounded(self, value): - """ - Set thermal boundaries bounding with the thermal zone - :param value: [ThermalBoundary] - :return: None - """ - self._bounded = value - - @property - def surfaces(self) -> List[Surface]: - # todo: This property should be erased (@Guille: why??) - """ - Get thermal zone surfaces - :return: [Surface] - """ - return self._surfaces - @property def additional_thermal_bridge_u_value(self): """ diff --git a/imports/usage/hft_usage_parameters.py b/imports/usage/hft_usage_parameters.py index 4c968481..4d5d198e 100644 --- a/imports/usage/hft_usage_parameters.py +++ b/imports/usage/hft_usage_parameters.py @@ -40,9 +40,10 @@ class HftUsageParameters(HftUsageInterface): mix_usage = False if not mix_usage: # just one usage_zone - usage_zone = UsageZone() - self._assign_values(usage_zone, archetype) - building.usage_zones = [usage_zone] + for thermal_zone in building.thermal_zones: + usage_zone = UsageZone() + self._assign_values(usage_zone, archetype) + thermal_zone.usage_zone = [usage_zone] def _search_archetype(self, building_usage): for building_archetype in self._usage_archetypes: diff --git a/non_functional_tests/test_construction_factory.py b/non_functional_tests/test_construction_factory.py index 8b8a3432..15653227 100644 --- a/non_functional_tests/test_construction_factory.py +++ b/non_functional_tests/test_construction_factory.py @@ -35,6 +35,7 @@ class TestConstructionFactory(TestCase): :return: None """ + # todo: file = 'pluto_building.gml' -> it has 0 surfaces!! file = 'pluto_building.gml' city = self._get_citygml(file) for building in city.buildings: diff --git a/non_functional_tests/test_geometry_factory.py b/non_functional_tests/test_geometry_factory.py index 5f283d84..aad6a893 100644 --- a/non_functional_tests/test_geometry_factory.py +++ b/non_functional_tests/test_geometry_factory.py @@ -53,7 +53,9 @@ class TestGeometryFactory(TestCase): Test city objects in the city :return: None """ - file = 'one_building_in_kelowna.gml' + # todo @Guille: when reading gml, pluto_building.gml has no surfaces + #file = 'one_building_in_kelowna.gml' + file = 'pluto_building.gml' city = self._get_citygml(file) self.assertTrue(len(city.buildings) == 1) for building in city.buildings: @@ -68,9 +70,7 @@ class TestGeometryFactory(TestCase): self.assertIsNone(building.basement_heated, 'building basement_heated is not none') self.assertIsNone(building.attic_heated, 'building attic_heated is not none') self.assertIsNotNone(building.terrains, 'building terrains is none') - self.assertIsNotNone(building.usage_zones, 'building usage_zones is none') self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none') - self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none') self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined') self.assertIsNotNone(building.type, 'building type is none') self.assertIsNotNone(building.max_height, 'building max_height is none') @@ -110,7 +110,6 @@ class TestGeometryFactory(TestCase): for building in city.buildings: self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined') for thermal_zone in building.thermal_zones: - self.assertIsNotNone(thermal_zone.surfaces, 'thermal_zone surfaces is none') self.assertIsNotNone(thermal_zone.bounded, 'thermal_zone bounded is none') self.assertIsNotNone(thermal_zone.floor_area, 'thermal_zone floor_area is none') self.assertIsNotNone(thermal_zone.is_heated, 'thermal_zone heated is none') @@ -140,11 +139,11 @@ class TestGeometryFactory(TestCase): for thermal_zone in building.thermal_zones: self.assertIsNot(len(thermal_zone.bounded), 0, 'no building thermal_boundaries defined') for thermal_boundary in thermal_zone.bounded: + print(thermal_boundary.surface.type) + print(thermal_boundary.surface.area_above_ground) self.assertIsNotNone(thermal_boundary.surface, 'thermal_boundary surface is none') self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none') self.assertIsNotNone(thermal_boundary.area, 'thermal_boundary area is none') - self.assertIsNotNone(thermal_boundary.area_above_ground, 'thermal_boundary area_above_ground is none') - self.assertIsNotNone(thermal_boundary.area_below_ground, 'thermal_boundary area_below_ground is none') self.assertIsNotNone(thermal_boundary.azimuth, 'thermal_boundary azimuth is none') self.assertIsNotNone(thermal_boundary.delimits, 'thermal_boundary delimits is none') self.assertIsNotNone(thermal_boundary.inclination, 'thermal_boundary inclination is none')