working version after creating polygon.py

This commit is contained in:
Pilar 2021-03-08 18:27:14 -05:00
parent 70a02b28d4
commit 74732355d4
9 changed files with 171 additions and 158 deletions

View File

@ -15,18 +15,27 @@ class Polygon:
Polygon class Polygon class
""" """
def __init__(self, vertices): def __init__(self, points):
self._vertices = vertices
self._area = None self._area = None
self._points = None self._points = points
self._points_list = None
self._normal = None self._normal = None
@property @property
def points(self) -> np.ndarray: def points(self) -> np.ndarray:
if self._points is None:
self._points = self._vertices
return self._points return self._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 @property
def area(self): def area(self):
""" """

View File

@ -9,18 +9,17 @@ import numpy as np
from trimesh import Trimesh from trimesh import Trimesh
from helpers.geometry_helper import GeometryHelper from helpers.geometry_helper import GeometryHelper
from helpers.configuration_helper import ConfigurationHelper from helpers.configuration_helper import ConfigurationHelper
from city_model_structure.attributes.surface import Surface from city_model_structure.attributes.polygon import Polygon
from helpers.geometry_helper import GeometryHelper as gh
class Polyhedron: class Polyhedron:
# todo: modify class to call polygons better than surfaces
""" """
Polyhedron class Polyhedron class
""" """
def __init__(self, surfaces): def __init__(self, polygons):
self._surfaces = list(surfaces) self._polygons = polygons
self._polygons = [s.polygon for s in surfaces]
self._polyhedron = None self._polyhedron = None
self._triangulated_polyhedron = None self._triangulated_polyhedron = None
self._volume = None self._volume = None
@ -52,7 +51,7 @@ class Polyhedron:
""" """
if self._vertices is None: if self._vertices is None:
vertices, self._vertices = [], [] vertices, self._vertices = [], []
_ = [vertices.extend(s.points) for s in self._surfaces] _ = [vertices.extend(s.points) for s in self._polygons]
for vertex_1 in vertices: for vertex_1 in vertices:
found = False found = False
for vertex_2 in self._vertices: for vertex_2 in self._vertices:
@ -65,18 +64,14 @@ class Polyhedron:
self._vertices = np.asarray(self._vertices) self._vertices = np.asarray(self._vertices)
return self._vertices return self._vertices
@staticmethod def _triangulate(self, polygon) -> [Polygon]:
def _point(coordinates):
return coordinates[0], coordinates[1], coordinates[2]
def _triangulate(self, surface):
""" """
triangulates a polygon following the ear clipping methodology triangulates a polygon following the ear clipping methodology
:param surface: surface :param polygon: polygon
:return: list[triangles] :return: list[triangles]
""" """
points_list = surface.points_list points_list = polygon.points_list
normal = surface.normal normal = polygon.normal
# are points concave or convex? # are points concave or convex?
total_points_list, concave_points, convex_points = self._starting_lists(points_list, normal) total_points_list, concave_points, convex_points = self._starting_lists(points_list, normal)
@ -87,7 +82,7 @@ class Polyhedron:
ear = self._triangle(points_list, total_points_list, concave_points[i]) ear = self._triangle(points_list, total_points_list, concave_points[i])
rest_points = [] rest_points = []
for p in total_points_list: for p in total_points_list:
rest_points.append(list(surface.points[p])) rest_points.append(list(polygon.points[p]))
if self._is_ear(ear, rest_points): if self._is_ear(ear, rest_points):
ears.append(ear) ears.append(ear)
point_to_remove = concave_points[i] point_to_remove = concave_points[i]
@ -115,8 +110,8 @@ class Polyhedron:
continue continue
break break
if len(total_points_list) <= 3 and len(convex_points) > 0: if len(total_points_list) <= 3 and len(convex_points) > 0:
sys.stderr.write(f'Not able to triangulate surface type {surface.type}\n') sys.stderr.write(f'Not able to triangulate polygon\n')
return [surface] return [polygon]
last_ear = self._triangle(points_list, total_points_list, concave_points[1]) last_ear = self._triangle(points_list, total_points_list, concave_points[1])
ears.append(last_ear) ears.append(last_ear)
return ears return ears
@ -215,16 +210,18 @@ class Polyhedron:
""" """
is_concave = False is_concave = False
accepted_error = 0.1 accepted_error = 0.1
points = ' '.join(str(e) for e in [*previous_point[:], *point[:], *next_point[:]]) points = np.append(previous_point, point)
triangle = Surface(points, remove_last=False) points = np.append(points, next_point)
points = gh.to_points_matrix(points)
triangle = Polygon(points)
error_sum = 0 error_sum = 0
for i in range(0, len(normal)): for i in range(0, len(normal)):
error_sum += triangle.perimeter_surface.normal[i] - normal[i] error_sum += triangle.normal[i] - normal[i]
if np.abs(error_sum) < accepted_error: if np.abs(error_sum) < accepted_error:
is_concave = True is_concave = True
return is_concave return is_concave
def _triangle(self, points_list, total_points_list, point_position): def _triangle(self, points_list, total_points_list, point_position) -> Polygon:
""" """
creates a triangular polygon out of three points creates a triangular polygon out of three points
:param points_list: points_list :param points_list: points_list
@ -234,10 +231,11 @@ class Polyhedron:
""" """
index = point_position * 3 index = point_position * 3
previous_point_index, next_point_index = self._enveloping_points_indices(point_position, total_points_list) previous_point_index, next_point_index = self._enveloping_points_indices(point_position, total_points_list)
points = ' '.join(str(e) for e in [*points_list[previous_point_index:previous_point_index + 3], points = points_list[previous_point_index:previous_point_index + 3]
*points_list[index:index + 3], points = np.append(points, points_list[index:index + 3])
*points_list[next_point_index:next_point_index + 3]]) points = np.append(points, points_list[next_point_index:next_point_index + 3])
triangle = Surface(points, remove_last=False) points = gh.to_points_matrix(points)
triangle = Polygon(points)
return triangle return triangle
@staticmethod @staticmethod
@ -288,11 +286,11 @@ class Polyhedron:
def _is_ear(ear, points) -> bool: def _is_ear(ear, points) -> bool:
""" """
finds whether a triangle is an ear of the polygon finds whether a triangle is an ear of the polygon
:param ear: surface :param ear: polygon
:param points: [point] :param points: [point]
:return: boolean :return: boolean
""" """
area_ear = ear.perimeter_surface.area area_ear = ear.area
for point in points: for point in points:
area_points = 0 area_points = 0
point_is_not_vertex = True point_is_not_vertex = True
@ -303,11 +301,16 @@ class Polyhedron:
if point_is_not_vertex: if point_is_not_vertex:
for i in range(0, 3): for i in range(0, 3):
if i != 2: if i != 2:
new_points = ' '.join(str(e) for e in [*ear.points[i][:], *ear.points[i + 1][:], *point[:]]) new_points = ear.points[i][:]
new_points = np.append(new_points, ear.points[i + 1][:])
new_points = np.append(new_points, point[:])
else: else:
new_points = ' '.join(str(e) for e in [*ear.points[i][:], *point[:], *ear.points[0][:]]) new_points = ear.points[i][:]
new_triangle = Surface(new_points, remove_last=False) new_points = np.append(new_points, point[:])
area_points += new_triangle.perimeter_surface.area new_points = np.append(new_points, ear.points[0][:])
new_points = gh.to_points_matrix(new_points)
new_triangle = Polygon(new_points)
area_points += new_triangle.area
if abs(area_points - area_ear) < 1e-6: if abs(area_points - area_ear) < 1e-6:
# point_inside_ear = True # point_inside_ear = True
return False return False
@ -324,17 +327,17 @@ class Polyhedron:
if self._faces is None: if self._faces is None:
self._faces = [] self._faces = []
for surface in self._surfaces: for polygon in self._polygons:
face = [] face = []
points = surface.points points = polygon.points
if len(points) != 3: if len(points) != 3:
sub_surfaces = self._triangulate(surface) sub_polygons = self._triangulate(polygon)
# todo: I modified this! To be checked @Guille # todo: I modified this! To be checked @Guille
if len(sub_surfaces) >= 1: if len(sub_polygons) >= 1:
for sub_surface in sub_surfaces: for sub_polygon in sub_polygons:
face = [] face = []
points = sub_surface.points points = sub_polygon.points
for point in points: for point in points:
face.append(self._position_of(point, face)) face.append(self._position_of(point, face))
self._faces.append(face) self._faces.append(face)
@ -371,8 +374,8 @@ class Polyhedron:
""" """
if self._max_z is None: if self._max_z is None:
self._max_z = ConfigurationHelper().min_coordinate self._max_z = ConfigurationHelper().min_coordinate
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
if self._max_z < point[2]: if self._max_z < point[2]:
self._max_z = point[2] self._max_z = point[2]
return self._max_z return self._max_z
@ -385,8 +388,8 @@ class Polyhedron:
""" """
if self._max_y is None: if self._max_y is None:
self._max_y = ConfigurationHelper().min_coordinate self._max_y = ConfigurationHelper().min_coordinate
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
if self._max_y < point[1]: if self._max_y < point[1]:
self._max_y = point[1] self._max_y = point[1]
return self._max_y return self._max_y
@ -399,8 +402,8 @@ class Polyhedron:
""" """
if self._max_x is None: if self._max_x is None:
self._max_x = ConfigurationHelper().min_coordinate self._max_x = ConfigurationHelper().min_coordinate
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
self._max_x = max(self._max_x, point[0]) self._max_x = max(self._max_x, point[0])
return self._max_x return self._max_x
@ -412,8 +415,8 @@ class Polyhedron:
""" """
if self._min_z is None: if self._min_z is None:
self._min_z = self.max_z self._min_z = self.max_z
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
if self._min_z > point[2]: if self._min_z > point[2]:
self._min_z = point[2] self._min_z = point[2]
return self._min_z return self._min_z
@ -426,8 +429,8 @@ class Polyhedron:
""" """
if self._min_y is None: if self._min_y is None:
self._min_y = self.max_y self._min_y = self.max_y
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
if self._min_y > point[1]: if self._min_y > point[1]:
self._min_y = point[1] self._min_y = point[1]
return self._min_y return self._min_y
@ -440,8 +443,8 @@ class Polyhedron:
""" """
if self._min_x is None: if self._min_x is None:
self._min_x = self.max_x self._min_x = self.max_x
for surface in self._surfaces: for polygon in self._polygons:
for point in surface.points: for point in polygon.points:
if self._min_x > point[0]: if self._min_x > point[0]:
self._min_x = point[0] self._min_x = point[0]
return self._min_x return self._min_x

View File

@ -27,6 +27,7 @@ class Surface:
self._holes_points = None self._holes_points = None
self._holes_points_list = None self._holes_points_list = None
self._perimeter_points = None self._perimeter_points = None
self._perimeter_points_list = None
self._azimuth = None self._azimuth = None
self._inclination = None self._inclination = None
self._area_above_ground = None self._area_above_ground = None
@ -37,9 +38,9 @@ class Surface:
self._min_z = None self._min_z = None
self._shared_surfaces = [] self._shared_surfaces = []
self._global_irradiance = dict() self._global_irradiance = dict()
self._perimeter_surface = None self._perimeter_polygon = None
self._hole_surfaces = None self._hole_polygons = None
self._solid_surface = None self._solid_polygons = None
def parent(self, parent, surface_id): def parent(self, parent, surface_id):
""" """
@ -103,6 +104,37 @@ class Surface:
self._holes_points.append(hole_points) self._holes_points.append(hole_points)
return self._holes_points return self._holes_points
@property
def perimeter_points(self) -> np.ndarray:
"""
Matrix of points of the perimeter in the same order as in coordinates [[x, y, z],[x, y, z],...]
:return: np.ndarray
"""
if self._perimeter_points is None:
if self.holes_points is None:
self._perimeter_points = self.points
else:
_perimeter_coordinates = self._coordinates
for hole_points in self.holes_points:
_hole = np.append(hole_points, hole_points[0])
_closed_hole = ' '.join(str(e) for e in [*_hole[:]])
# add a mark 'M' to ensure that the recombination of points does not provoke errors in finding holes
_perimeter_coordinates = _perimeter_coordinates.replace(_closed_hole, 'M')
_perimeter_coordinates = _perimeter_coordinates.replace('M', '')
self._perimeter_points = np.fromstring(_perimeter_coordinates, dtype=float, sep=' ')
self._perimeter_points = gh.to_points_matrix(self._perimeter_points)
# remove duplicated points
pv = np.array([self._perimeter_points[0]])
for point in self._perimeter_points:
duplicated_point = False
for p in pv:
if gh().almost_equal(0.0, p, point):
duplicated_point = True
if not duplicated_point:
pv = np.append(pv, [point], axis=0)
self._perimeter_points = pv
return self._perimeter_points
@property @property
def points_list(self) -> np.ndarray: def points_list(self) -> np.ndarray:
""" """
@ -128,6 +160,17 @@ class Surface:
np.add(self._holes_points_list, hole_points_list) np.add(self._holes_points_list, hole_points_list)
return self._holes_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 _min_coord(self, axis): def _min_coord(self, axis):
if axis == 'x': if axis == 'x':
axis = 0 axis = 0
@ -180,7 +223,7 @@ class Surface:
:return: float :return: float
""" """
if self._area_above_ground is None: if self._area_above_ground is None:
self._area_above_ground = self.perimeter_surface.area - self.area_below_ground self._area_above_ground = self.perimeter_polygon.area - self.area_below_ground
return self._area_above_ground return self._area_above_ground
# todo: to be implemented # todo: to be implemented
@ -199,7 +242,7 @@ class Surface:
:return: float :return: float
""" """
if self._azimuth is None: if self._azimuth is None:
normal = self.perimeter_surface.normal normal = self.perimeter_polygon.normal
self._azimuth = np.arctan2(normal[1], normal[0]) self._azimuth = np.arctan2(normal[1], normal[0])
return self._azimuth return self._azimuth
@ -210,7 +253,7 @@ class Surface:
:return: float :return: float
""" """
if self._inclination is None: if self._inclination is None:
self._inclination = np.arccos(self.perimeter_surface.normal[2]) self._inclination = np.arccos(self.perimeter_polygon.normal[2])
return self._inclination return self._inclination
@property @property
@ -236,7 +279,7 @@ class Surface:
:param intersection_area: :param intersection_area:
:return: :return:
""" """
percent = intersection_area / self.perimeter_surface.area percent = intersection_area / self.perimeter_polygon.area
self._shared_surfaces.append((percent, surface)) self._shared_surfaces.append((percent, surface))
# todo reimplement # todo reimplement
@ -267,27 +310,27 @@ class Surface:
self._global_irradiance = value self._global_irradiance = value
@property @property
def perimeter_surface(self) -> Polygon: def perimeter_polygon(self) -> Polygon:
""" """
total surface defined by the perimeter, merging solid and holes total surface defined by the perimeter, merging solid and holes
:return: Polygon :return: Polygon
""" """
if self._perimeter_surface is None: if self._perimeter_polygon is None:
self._perimeter_surface = Polygon(self.perimeter_points) self._perimeter_polygon = Polygon(self.perimeter_points)
return self._perimeter_surface return self._perimeter_polygon
@property @property
def solid_surface(self) -> Polygon: def solid_polygon(self) -> Polygon:
""" """
solid surface solid surface
:return: Polygon :return: Polygon
""" """
if self._solid_surface is None: if self._solid_polygons is None:
self._solid_surface = Polygon(self.points) self._solid_polygons = Polygon(self.points)
return self._solid_surface return self._solid_polygons
@property @property
def hole_surfaces(self) -> [Polygon]: def hole_polygons(self) -> [Polygon]:
""" """
hole surfaces, a list of hole polygons found in the surface hole surfaces, a list of hole polygons found in the surface
:return: None, [] or [Polygon] :return: None, [] or [Polygon]
@ -295,42 +338,11 @@ class Surface:
[] -> no holes in the surface [] -> no holes in the surface
[Polygon] -> one or more holes in the surface [Polygon] -> one or more holes in the surface
""" """
if self._hole_surfaces is None: if self._hole_polygons is None:
if self.holes_points is None: if self.holes_points is None:
self._hole_surfaces = None self._hole_polygons = None
else: else:
self._hole_surfaces = [] self._hole_polygons = []
for hole_points in self.holes_points: for hole_points in self.holes_points:
self._hole_surfaces.append(Polygon(hole_points)) self._hole_polygons.append(Polygon(hole_points))
return self._hole_surfaces return self._hole_polygons
@property
def perimeter_points(self) -> np.ndarray:
"""
Matrix of points of the perimeter in the same order as in coordinates [[x, y, z],[x, y, z],...]
:return: np.ndarray
"""
if self._perimeter_points is None:
if self.holes_points is None:
self._perimeter_points = self.points
else:
_perimeter_coordinates = self._coordinates
for hole_points in self.holes_points:
_hole = np.append(hole_points, hole_points[0])
_closed_hole = ' '.join(str(e) for e in [*_hole[:]])
# add a mark 'M' to ensure that the recombination of points does not provoke errors in finding holes
_perimeter_coordinates = _perimeter_coordinates.replace(_closed_hole, 'M')
_perimeter_coordinates = _perimeter_coordinates.replace('M', '')
self._perimeter_points = np.fromstring(_perimeter_coordinates, dtype=float, sep=' ')
self._perimeter_points = gh.to_points_matrix(self._perimeter_points)
# remove duplicated points
pv = np.array([self._perimeter_points[0]])
for point in self._perimeter_points:
duplicated_point = False
for p in pv:
if gh().almost_equal(0.0, p, point):
duplicated_point = True
if not duplicated_point:
pv = np.append(pv, [point], axis=0)
self._perimeter_points = pv
return self._perimeter_points

View File

@ -19,7 +19,7 @@ class ThermalBoundary:
self._surface = surface self._surface = surface
self._delimits = delimits self._delimits = delimits
# ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary, review for LOD3 and LOD4 # ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary, review for LOD3 and LOD4
self._thermal_openings = [ThermalOpening] self._thermal_openings = [ThermalOpening()]
self._layers = None self._layers = None
self._outside_solar_absorptance = None self._outside_solar_absorptance = None
self._outside_thermal_absorptance = None self._outside_thermal_absorptance = None
@ -83,7 +83,7 @@ class ThermalBoundary:
Thermal boundary area in square meters Thermal boundary area in square meters
:return: float :return: float
""" """
return self._surface.area return self._surface.solid_polygon.area
@property @property
def area_above_ground(self): def area_above_ground(self):

View File

@ -57,7 +57,7 @@ class ThermalZone:
self._floor_area = 0 self._floor_area = 0
for s in self._surfaces: for s in self._surfaces:
if s.type == 'Ground': if s.type == 'Ground':
self._floor_area += s.area self._floor_area += s.perimeter_polygon.area
return self._floor_area return self._floor_area
@property @property

View File

@ -19,7 +19,8 @@ class CityObject:
self._name = name self._name = name
self._lod = lod self._lod = lod
self._surfaces = surfaces self._surfaces = surfaces
self._polyhedron = None self._detailed_polyhedron = None
self._simplified_polyhedron = None
self._geometry = GeometryHelper() self._geometry = GeometryHelper()
@property @property
@ -37,17 +38,36 @@ class CityObject:
City object volume in cubic meters City object volume in cubic meters
:return: float :return: float
""" """
return self.polyhedron.volume return self.detailed_polyhedron.volume
@property @property
def polyhedron(self): def detailed_polyhedron(self):
""" """
City object polyhedron City object polyhedron including details such as holes
:return: Polyhedron :return: Polyhedron
""" """
if self._polyhedron is None: if self._detailed_polyhedron is None:
self._polyhedron = Polyhedron(self.surfaces) polygons = []
return self._polyhedron for surface in self.surfaces:
polygons.append(surface.solid_polygon)
if surface.hole_polygons is not None:
for hole_polygon in surface.hole_polygons:
polygons.append(hole_polygon)
self._detailed_polyhedron = Polyhedron(polygons)
return self._detailed_polyhedron
@property
def simplified_polyhedron(self):
"""
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 @property
def surfaces(self) -> List[Surface]: def surfaces(self) -> List[Surface]:
@ -74,32 +94,7 @@ class CityObject:
City object location City object location
:return: [x,y,z] :return: [x,y,z]
""" """
if self._polyhedron is None: return self.simplified_polyhedron.center
self._polyhedron = Polyhedron(self.surfaces)
return self._polyhedron.center
def stl_export(self, path):
"""
Export the city object to stl file (city_object_name.stl) to the given path
:param path: str
:return: None
"""
# todo: this is a method just for debugging, it will be soon removed
if self._polyhedron is None:
self._polyhedron = Polyhedron(self.surfaces)
full_path = (Path(path) / (self._name + '.stl')).resolve()
self._polyhedron.stl_export(full_path)
def obj_export(self, path):
if self._polyhedron is None:
self._polyhedron = Polyhedron(self.surfaces)
full_path = (Path(path) / (self._name + '.obj')).resolve()
self._polyhedron.obj_export(full_path)
def show(self):
if self._polyhedron is None:
self._polyhedron = Polyhedron(self.surfaces)
self._polyhedron.show()
@property @property
def max_height(self): def max_height(self):
@ -107,6 +102,4 @@ class CityObject:
City object maximal height in meters City object maximal height in meters
:return: float :return: float
""" """
if self._polyhedron is None: return self.simplified_polyhedron.max_z
self._polyhedron = Polyhedron(self.surfaces)
return self._polyhedron.max_z

View File

@ -120,7 +120,7 @@ class CityGml:
terrains = [] terrains = []
for curve in curves: for curve in curves:
curve_points = np.fromstring(curve, dtype=float, sep=' ') curve_points = np.fromstring(curve, dtype=float, sep=' ')
curve_points = self._geometry.to_points_matrix(curve_points, True) curve_points = self._geometry.to_points_matrix(curve_points)
terrains.append(curve_points) terrains.append(curve_points)
return terrains return terrains
@ -136,7 +136,7 @@ class CityGml:
@staticmethod @staticmethod
def _lod1_multi_surface(o): def _lod1_multi_surface(o):
surfaces = [Surface(CityGml._remove_last_point((s['Polygon']['exterior']['LinearRing']['posList'])) surfaces = [Surface(CityGml._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList']))
for s in o['Building']['lod1MultiSurface']['MultiSurface']['surfaceMember']] for s in o['Building']['lod1MultiSurface']['MultiSurface']['surfaceMember']]
return surfaces return surfaces
@ -178,4 +178,4 @@ class CityGml:
def _remove_last_point(points): def _remove_last_point(points):
array = points.split(' ') array = points.split(' ')
res = " " res = " "
return res.join(array[0:len(array) -3]) return res.join(array[0:len(array) - 3])

View File

@ -85,7 +85,6 @@ class TestGeometryFactory(TestCase):
print('volume', building.name, building.volume) print('volume', building.name, building.volume)
if str(building.volume) == 'inf': if str(building.volume) == 'inf':
counter += 1 counter += 1
building.stl_export(self._output_path)
print('total number of buildings with volume inf', counter) print('total number of buildings with volume inf', counter)
def test_citygml_buildings(self): def test_citygml_buildings(self):
@ -123,7 +122,6 @@ class TestGeometryFactory(TestCase):
:return: None :return: None
""" """
city = self._get_citygml() city = self._get_citygml()
print(city)
for building in city.buildings: for building in city.buildings:
for surface in building.surfaces: for surface in building.surfaces:
self.assertIsNotNone(surface.name, 'surface name is none') self.assertIsNotNone(surface.name, 'surface name is none')
@ -139,8 +137,6 @@ class TestGeometryFactory(TestCase):
self.assertIsNotNone(surface.min_x, 'surface min_x is 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_y, 'surface min_y is none')
self.assertIsNotNone(surface.min_z, 'surface min_z is none') self.assertIsNotNone(surface.min_z, 'surface min_z is none')
print('points', surface.points)
print('coordinates', surface._coordinates)
def test_citygml_thermal_zone(self): def test_citygml_thermal_zone(self):
""" """
@ -257,10 +253,10 @@ class TestGeometryFactory(TestCase):
print(surface.holes_points) print(surface.holes_points)
print('perimeter:', surface.perimeter_points) print('perimeter:', surface.perimeter_points)
for i in range(0, len(holes_coordinates)): for i in range(0, len(holes_coordinates)):
print(surface.hole_surfaces[i].area) print(surface.hole_polygons[i].area)
print('perimeter:', surface.perimeter_surface.area) print('perimeter:', surface.perimeter_polygon.area)
print('solid:', surface.solid_surface.area) print('solid:', surface.solid_polygon.area)
for i in range(0, len(holes_coordinates)): for i in range(0, len(holes_coordinates)):
print(surface.hole_surfaces[i].normal) print(surface.hole_polygons[i].normal)
print('perimeter:', surface.perimeter_surface.normal) print('perimeter:', surface.perimeter_polygon.normal)
print('solid:', surface.solid_surface.normal) print('solid:', surface.solid_polygon.normal)

Binary file not shown.