diff --git a/city_model_structure/attributes/surface.py b/city_model_structure/attributes/surface.py index da44b94b..c52039d4 100644 --- a/city_model_structure/attributes/surface.py +++ b/city_model_structure/attributes/surface.py @@ -23,26 +23,19 @@ class Surface: self._name = name self._swr = swr self._points = None - self._points_list = None self._holes_points = None - self._holes_points_list = None self._perimeter_points = None - self._perimeter_points_list = None self._azimuth = None self._inclination = None self._area_above_ground = None self._area_below_ground = None self._parent = None - self._min_x = None - self._min_y = None - self._min_z = None - self._max_x = None - self._max_y = None - self._max_z = None + self._envelope_lower_corner = None + self._envelope_upper_corner = None self._shared_surfaces = [] self._global_irradiance = dict() self._perimeter_polygon = None - self._hole_polygons = None + self._holes_polygons = None self._solid_polygons = None def parent(self, parent, surface_id): @@ -138,42 +131,6 @@ class Surface: self._perimeter_points = pv return self._perimeter_points - @property - def points_list(self) -> np.ndarray: - """ - Solid surface point coordinates list [x, y, z, x, y, z,...] - :return: np.ndarray - """ - if self._points_list is None: - s = self.points - self._points_list = np.reshape(s, len(s) * 3) - return self._points_list - - @property - def holes_points_list(self) -> np.ndarray: - """ - Holes surfaces point coordinates list [x, y, z, x, y, z,...] - :return: np.ndarray - """ - if self._holes_coordinates is not None: - self._holes_points_list = np.array([]) - for hole_points in self.holes_points: - s = hole_points - hole_points_list = np.reshape(s, len(s) * 3) - np.add(self._holes_points_list, hole_points_list) - return self._holes_points_list - - @property - def perimeter_points_list(self) -> np.ndarray: - """ - Solid surface point coordinates list [x, y, z, x, y, z,...] - :return: np.ndarray - """ - if self._perimeter_points_list is None: - s = self.perimeter_points - self._perimeter_points_list = np.reshape(s, len(s) * 3) - return self._perimeter_points_list - def _max_coord(self, axis): if axis == 'x': axis = 0 @@ -205,64 +162,16 @@ class Surface: return min_coordinate @property - def max_x(self): - """ - Surface maximal x value - :return: float - """ - if self._max_x is None: - self._max_x = self._max_coord('x') - return self._max_x + def envelope_lower_corner(self): + if self._envelope_lower_corner is None: + self._envelope_lower_corner = [self._min_coord('x'), self._min_coord('y'), self._min_coord('z')] + return self._envelope_lower_corner @property - def max_y(self): - """ - Surface maximal y value - :return: float - """ - if self._max_y is None: - self._max_y = self._max_coord('y') - return self._max_y - - @property - def max_z(self): - """ - Surface maximal z value - :return: float - """ - if self._max_z is None: - self._max_z = self._max_coord('z') - return self._max_z - - @property - def min_x(self): - """ - Surface minimal x value - :return: float - """ - if self._min_x is None: - self._min_x = self._min_coord('x') - return self._min_x - - @property - def min_y(self): - """ - Surface minimal y value - :return: float - """ - if self._min_y is None: - self._min_y = self._min_coord('y') - return self._min_y - - @property - def min_z(self): - """ - Surface minimal z value - :return: float - """ - if self._min_z is None: - self._min_z = self._min_coord('z') - return self._min_z + def envelope_upper_corner(self): + if self._envelope_upper_corner is None: + self._envelope_upper_corner = [self._max_coord('x'), self._max_coord('y'), self._max_coord('z')] + return self._envelope_upper_corner @property def area_above_ground(self): @@ -378,7 +287,7 @@ class Surface: return self._solid_polygons @property - def hole_polygons(self) -> [Polygon]: + def holes_polygons(self) -> [Polygon]: """ hole surfaces, a list of hole polygons found in the surface :return: None, [] or [Polygon] @@ -386,11 +295,11 @@ class Surface: [] -> no holes in the surface [Polygon] -> one or more holes in the surface """ - if self._hole_polygons is None: + if self._holes_polygons is None: if self.holes_points is None: - self._hole_polygons = None + self._holes_polygons = None else: - self._hole_polygons = [] + self._holes_polygons = [] for hole_points in self.holes_points: - self._hole_polygons.append(Polygon(hole_points)) - return self._hole_polygons + self._holes_polygons.append(Polygon(hole_points)) + return self._holes_polygons diff --git a/city_model_structure/building.py b/city_model_structure/building.py index b0f66b8a..fe5ff362 100644 --- a/city_model_structure/building.py +++ b/city_model_structure/building.py @@ -53,9 +53,9 @@ class Building(CityObject): for t_zones in self._thermal_zones: t_zones.bounded = [ThermalBoundary(s, [t_zones]) for s in t_zones.surfaces] for surface in self.surfaces: - self._min_x = min(self._min_x, surface.min_x) - self._min_y = min(self._min_y, surface.min_y) - self._min_z = min(self._min_z, surface.min_z) + self._min_x = min(self._min_x, surface.envelope_lower_corner[0]) + self._min_y = min(self._min_y, surface.envelope_lower_corner[1]) + self._min_z = min(self._min_z, surface.envelope_lower_corner[2]) if surface.type == 'Ground': self._grounds.append(surface) elif surface.type == 'Wall': diff --git a/city_model_structure/city_object.py b/city_model_structure/city_object.py index 21d58490..ed5855d8 100644 --- a/city_model_structure/city_object.py +++ b/city_model_structure/city_object.py @@ -67,8 +67,8 @@ class CityObject: polygons = [] for surface in self.surfaces: polygons.append(surface.solid_polygon) - if surface.hole_polygons is not None: - for hole_polygon in surface.hole_polygons: + 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 diff --git a/exports/formats/energy_ade.py b/exports/formats/energy_ade.py index 2b927032..11c24cb8 100644 --- a/exports/formats/energy_ade.py +++ b/exports/formats/energy_ade.py @@ -210,8 +210,10 @@ class EnergyAde: 'gml:boundedBy': { 'gml:Envelope': { '@srsName': city.srs_name, - 'gml:lowerCorner': f'{surface.min_x} {surface.min_y} {surface.min_z}', - 'gml:upperCorner': f'{surface.max_x} {surface.max_y} {surface.max_z}' + 'gml:lowerCorner': f'{surface.envelope_lower_corner[0]} {surface.envelope_lower_corner[1]}' + f' {surface.envelope_lower_corner[2]}', + 'gml:upperCorner': f'{surface.envelope_upper_corner[0]} {surface.envelope_upper_corner[1]}' + f' {surface.envelope_upper_corner[2]}' } }, 'bldg:lod2MultiSurface': { @@ -228,7 +230,8 @@ class EnergyAde: 'gml:posList': { '@srsDimension': '3', '@count': len(surface.points) + 1, - '#text': f'{" ".join(map(str, surface.points_list))} {" ".join(map(str, surface.points[0]))}' + '#text': f'{" ".join(map(str, surface.solid_polygon.points_list))} ' + f'{" ".join(map(str, surface.points[0]))}' } } } @@ -340,7 +343,7 @@ class EnergyAde: 'gml:posList': { '@srsDimension': '3', '@count': len(thermal_boundary.surface.points) + 1, - '#text': f'{" ".join(map(str, thermal_boundary.surface.points_list))} ' + '#text': f'{" ".join(map(str, thermal_boundary.surface.solid_polygon.points_list))} ' f'{" ".join(map(str, thermal_boundary.surface.points[0]))}' } } diff --git a/tests/test_geometry_factory.py b/tests/test_geometry_factory.py index 38cb3410..c9fb0624 100644 --- a/tests/test_geometry_factory.py +++ b/tests/test_geometry_factory.py @@ -120,12 +120,11 @@ class TestGeometryFactory(TestCase): self.assertIsNotNone(surface.perimeter_points_list, 'surface perimeter_points_list is none') self.assertIsNotNone(surface.global_irradiance, 'monthly irradiance is none') self.assertIsNone(surface.swr, 'surface swr is not none') - self.assertIsNotNone(surface.min_x, 'surface min_x is none') - self.assertIsNotNone(surface.min_y, 'surface min_y is none') - self.assertIsNotNone(surface.min_z, 'surface min_z is none') + self.assertIsNotNone(surface.envelope_lower_corner, 'surface envelope_lower_corner is none') + self.assertIsNotNone(surface.envelope_upper_corner, 'surface envelope_upper_corner is none') self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none') self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none') - self.assertIsNone(surface.hole_polygons, 'surface hole_polygons is not none') + self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none') self.assertIsNotNone(surface.solid_polygon, 'surface solid_polygon is none') def test_citygml_thermal_zone(self): @@ -235,10 +234,10 @@ class TestGeometryFactory(TestCase): print(surface.holes_points) print('perimeter:', surface.perimeter_points) for i in range(0, len(holes_coordinates)): - print(surface.hole_polygons[i].area) + print(surface.holes_polygons[i].area) print('perimeter:', surface.perimeter_polygon.area) print('solid:', surface.solid_polygon.area) for i in range(0, len(holes_coordinates)): - print(surface.hole_polygons[i].normal) + print(surface.holes_polygons[i].normal) print('perimeter:', surface.perimeter_polygon.normal) print('solid:', surface.solid_polygon.normal)