Citygml can now generate the envelop out of the buildings
This commit is contained in:
parent
88eb9006ea
commit
920d95eef2
|
@ -115,7 +115,7 @@ class Idf:
|
|||
lower_z = lower_corner[2]
|
||||
points_list = []
|
||||
for point in points:
|
||||
point_tuple = (point[0]-lower_x, point[1]-lower_y, point[2]-lower_z)
|
||||
point_tuple = (point[0] - lower_x, point[1] - lower_y, point[2] - lower_z)
|
||||
points_list.append(point_tuple)
|
||||
return points_list
|
||||
|
||||
|
@ -279,7 +279,7 @@ class Idf:
|
|||
def _add_window_construction_and_material(self, thermal_opening):
|
||||
for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
|
||||
if window_material['UFactor'] == thermal_opening.overall_u_value and \
|
||||
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
|
||||
window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value:
|
||||
return
|
||||
|
||||
order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1)
|
||||
|
@ -407,7 +407,11 @@ class Idf:
|
|||
Reporting_Frequency="Hourly",
|
||||
)
|
||||
self._idf.match()
|
||||
self._idf.intersect_match()
|
||||
try:
|
||||
self._idf.intersect_match()
|
||||
except IndexError:
|
||||
# seems to be a bug from geomeppy when surfaces cannot be intersected
|
||||
pass
|
||||
self._idf.saveas(str(self._output_file))
|
||||
return self._idf
|
||||
|
||||
|
@ -482,7 +486,7 @@ class Idf:
|
|||
for material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]:
|
||||
if material['Name'] == glazing:
|
||||
if material['UFactor'] == opening.overall_u_value and \
|
||||
material['Solar_Heat_Gain_Coefficient'] == opening.g_value:
|
||||
material['Solar_Heat_Gain_Coefficient'] == opening.g_value:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import math
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
import xmltodict
|
||||
from city_model_structure.city import City
|
||||
|
@ -22,6 +25,8 @@ class CityGml:
|
|||
self._city = None
|
||||
self._lod1_tags = ['lod1Solid', 'lod1MultiSurface']
|
||||
self._lod2_tags = ['lod2Solid', 'lod2MultiSurface', 'lod2MultiCurve']
|
||||
self._lower_corner = None
|
||||
self._upper_corner = None
|
||||
with open(path) as gml:
|
||||
# Clean the namespaces is an important task to prevent wrong ns:field due poor citygml_classes implementations
|
||||
force_list = ('cityObjectMember', 'curveMember', 'boundedBy', 'surfaceMember', 'consistsOfBuildingPart')
|
||||
|
@ -48,17 +53,45 @@ class CityGml:
|
|||
|
||||
self._city_objects = None
|
||||
self._geometry = GeometryHelper()
|
||||
|
||||
for bound in self._gml['CityModel']['boundedBy']:
|
||||
envelope = bound['Envelope']
|
||||
if '#text' in envelope['lowerCorner']:
|
||||
self._lower_corner = np.fromstring(envelope['lowerCorner']['#text'], dtype=float, sep=' ')
|
||||
self._upper_corner = np.fromstring(envelope['upperCorner']['#text'], dtype=float, sep=' ')
|
||||
else:
|
||||
self._lower_corner = np.fromstring(envelope['lowerCorner'], dtype=float, sep=' ')
|
||||
self._upper_corner = np.fromstring(envelope['upperCorner'], dtype=float, sep=' ')
|
||||
if '@srsName' in envelope:
|
||||
self._srs_name = envelope['@srsName']
|
||||
if 'boundedBy' in self._gml['CityModel']:
|
||||
for bound in self._gml['CityModel']['boundedBy']:
|
||||
envelope = bound['Envelope']
|
||||
if '#text' in envelope['lowerCorner']:
|
||||
self._lower_corner = np.fromstring(envelope['lowerCorner']['#text'], dtype=float, sep=' ')
|
||||
self._upper_corner = np.fromstring(envelope['upperCorner']['#text'], dtype=float, sep=' ')
|
||||
else:
|
||||
self._lower_corner = np.fromstring(envelope['lowerCorner'], dtype=float, sep=' ')
|
||||
self._upper_corner = np.fromstring(envelope['upperCorner'], dtype=float, sep=' ')
|
||||
if '@srsName' in envelope:
|
||||
self._srs_name = envelope['@srsName']
|
||||
else:
|
||||
# get the boundary from the city objects instead
|
||||
for city_object_member in self._gml['CityModel']['cityObjectMember']:
|
||||
city_object = city_object_member['Building']
|
||||
if 'boundedBy' in city_object:
|
||||
for bound in city_object['boundedBy']:
|
||||
if 'Envelope' not in bound:
|
||||
continue
|
||||
envelope = bound['Envelope']
|
||||
self._srs_name = envelope['@srsName']
|
||||
lower_corner = None
|
||||
upper_corner = None
|
||||
if '#text' in envelope['lowerCorner']:
|
||||
lower_corner = np.fromstring(envelope['lowerCorner']['#text'], dtype=float, sep=' ')
|
||||
upper_corner = np.fromstring(envelope['upperCorner']['#text'], dtype=float, sep=' ')
|
||||
else:
|
||||
lower_corner = np.fromstring(envelope['lowerCorner'], dtype=float, sep=' ')
|
||||
upper_corner = np.fromstring(envelope['upperCorner'], dtype=float, sep=' ')
|
||||
if self._lower_corner is None:
|
||||
self._lower_corner = lower_corner
|
||||
self._upper_corner = upper_corner
|
||||
else:
|
||||
self._lower_corner[0] = min(self._lower_corner[0], lower_corner[0])
|
||||
self._lower_corner[1] = min(self._lower_corner[1], lower_corner[1])
|
||||
self._lower_corner[2] = min(self._lower_corner[2], lower_corner[2])
|
||||
self._upper_corner[0] = max(self._upper_corner[0], upper_corner[0])
|
||||
self._upper_corner[1] = max(self._upper_corner[1], upper_corner[1])
|
||||
self._upper_corner[2] = max(self._upper_corner[2], upper_corner[2])
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
|
|
|
@ -48,19 +48,26 @@ class CityGmlLod2(CityGmlBase):
|
|||
try:
|
||||
surface_encoding, surface_subtype = cls._surface_encoding(bounded[surface_type])
|
||||
except NotImplementedError:
|
||||
|
||||
continue
|
||||
for member in bounded[surface_type][surface_encoding][surface_subtype]['surfaceMember']:
|
||||
if '@srsDimension' in member['Polygon']['exterior']['LinearRing']['posList']:
|
||||
gml_points = member['Polygon']['exterior']['LinearRing']['posList']["#text"]
|
||||
if 'CompositeSurface' in member:
|
||||
for composite_members in member['CompositeSurface']['surfaceMember']:
|
||||
for composite_member in composite_members['CompositeSurface']['surfaceMember']:
|
||||
surfaces.append(cls._add_member_surface(composite_member, surface_type))
|
||||
else:
|
||||
gml_points = member['Polygon']['exterior']['LinearRing']['posList']
|
||||
solid_points = cls._solid_points(cls._remove_last_point(gml_points))
|
||||
polygon = Polygon(solid_points)
|
||||
surface = Surface(polygon, polygon, surface_type=GeometryHelper.gml_surface_to_libs(surface_type))
|
||||
surfaces.append(surface)
|
||||
surfaces.append(cls._add_member_surface(member, surface_type))
|
||||
return surfaces
|
||||
|
||||
@classmethod
|
||||
def _add_member_surface(cls, member, surface_type):
|
||||
if '@srsDimension' in member['Polygon']['exterior']['LinearRing']['posList']:
|
||||
gml_points = member['Polygon']['exterior']['LinearRing']['posList']["#text"]
|
||||
else:
|
||||
gml_points = member['Polygon']['exterior']['LinearRing']['posList']
|
||||
solid_points = cls._solid_points(cls._remove_last_point(gml_points))
|
||||
polygon = Polygon(solid_points)
|
||||
return Surface(polygon, polygon, surface_type=GeometryHelper.gml_surface_to_libs(surface_type))
|
||||
|
||||
@classmethod
|
||||
def _multi_curve(cls, city_object_member):
|
||||
raise NotImplementedError('multi curve')
|
||||
|
|
|
@ -66,4 +66,4 @@ class GeometryFactory:
|
|||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
"""
|
||||
return Rhino(self._path).city
|
||||
return CityGml(self._path).city
|
||||
|
|
|
@ -41,7 +41,7 @@ class TestGeometryFactory(TestCase):
|
|||
|
||||
def _get_rhino(self, file):
|
||||
file_path = (self._example_path / file).resolve()
|
||||
self._city = GeometryFactory('rhino', file_path).city_debug
|
||||
self._city = GeometryFactory('rhino', file_path).city
|
||||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
|
|
|
@ -14,4 +14,4 @@ class TestConstructionCatalog(TestCase):
|
|||
catalog = UsageCatalogFactory('comnet').catalog
|
||||
self.assertIsNotNone(catalog, 'catalog is none')
|
||||
content = catalog.entries()
|
||||
self.assertEqual(len(content.usages), 33, 'Wrong number of usages')
|
||||
self.assertEqual(len(content.usages), 32, 'Wrong number of usages')
|
||||
|
|
Loading…
Reference in New Issue
Block a user