from imports.geometry.citygml_base import CityGmlBase from city_model_structure.attributes.surface import Surface from city_model_structure.attributes.polygon import Polygon from imports.geometry.helpers.geometry_helper import GeometryHelper class CityGmlLod2(CityGmlBase): def __init__(self, o): super().__init__() self._o = o self._surfaces = self._identify(self._o) @classmethod def _identify(cls, o): if 'lod2Solid' in o['Building']: return cls._solid(o) elif 'lod2MultiSurface' in o['Building']: print('multi_surface') return cls._multi_surface(o) elif 'lod2MultiCurve' in o['Building']: print('multi_curve') return cls._multi_curve(o) elif 'consistsOfBuildingPart' in o['Building']: raise NotImplementedError @staticmethod def _surface_encoding(surfaces): if 'lod2MultiSurface' in surfaces: return 'lod2MultiSurface', 'MultiSurface' return 'unknown' @classmethod def _solid(cls, o): surfaces = [] for b in o["Building"]["boundedBy"]: surface_type = next(iter(b)) surface_encoding, surface_subtype = cls._surface_encoding(b[surface_type]) for member in b[surface_type][surface_encoding][surface_subtype]['surfaceMember']: sp = cls._solid_points(cls._remove_last_point(member['Polygon']['exterior']['LinearRing']['posList'])) p = Polygon(sp) surface = Surface(p,p, surface_type=GeometryHelper.gml_surface_to_libs(surface_type)) surfaces.append(surface) for p in o["Building"]["consistsOfBuildingPart"]: raise NotImplementedError return surfaces @classmethod def _multi_curve(cls, o): raise NotImplementedError @classmethod def _multi_surface(cls, o): raise NotImplementedError @classmethod def _lod2(cls, bound): surfaces = [] for surface_type in iter(bound): for s in bound[surface_type]['lod2MultiSurface']['MultiSurface']['surfaceMember']: if 'CompositeSurface' in s: surfaces = surfaces + cls._lod2_composite_surface(s) else: surfaces = surfaces + cls._lod2_multi_surface(s, surface_type) return surfaces @classmethod def _lod2_solid_multi_surface(cls, o): polygons = None if 'boundedBy' in o['Building']['consistsOfBuildingPart']['BuildingPart']: if 'RoofSurface' in o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']: if o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']['RoofSurface']['lod2MultiSurface'] != 'None': polygons = [Polygon(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList'])) for s in o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']['RoofSurface'] ['lod2MultiSurface']['MultiSurface']['surfaceMember']] elif 'WallSurface' in o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']: if o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']['WallSurface']['lod2MultiSurface'] != 'None': polygons = [Polygon(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList'])) for s in o['Building']['consistsOfBuildingPart']['BuildingPart']['boundedBy']['WallSurface']['lod2MultiSurface']['MultiSurface']['surfaceMember']] else: polygons = [Polygon(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList'])) for s in o['Building']['lod2MultiSurface']['MultiSurface']['surfaceMember']] return [Surface(p,p) for p in polygons] @classmethod def _lod2_solid(cls, o): for walls in o['Building']['boundedBy']['wallSurface']: print(f'solid') @classmethod def _lod2_solid_composite_surface(cls, o): try: solid_points = [cls._solid_points(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList']['#text'])) for s in o['Building']['lod2Solid']['Solid']['exterior']['CompositeSurface']['surfaceMember']] except TypeError: solid_points = [cls._solid_points(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList'])) for s in o['Building']['lod2Solid']['Solid']['exterior']['CompositeSurface']['surfaceMember']] return [Surface(Polygon(sp),Polygon(sp)) for sp in solid_points] @classmethod def _lod2_composite_surface(cls, s): solid_points = [ cls._solid_points((cls._remove_last_point(sm['Polygon']['exterior']['LinearRing']['posList']))) for sm in s['CompositeSurface']['surfaceMember']] return [Surface(Polygon(sp), Polygon(sp)) for sp in solid_points] @classmethod def _lod2_multi_surface(cls, s, surface_type): # todo: this need to be changed into surface bounded? try: solid_points = [cls._solid_points(cls._remove_last_point( s['Polygon']['exterior']['LinearRing']['posList']['#text']))] except TypeError: solid_points = [cls._solid_points(cls._remove_last_point(s['Polygon']['exterior']['LinearRing']['posList']))] return [Surface(Polygon(sp), Polygon(sp), surface_type=surface_type) for sp in solid_points]