Bug fix in geojson import

This commit is contained in:
Guille Gutierrez 2022-11-25 14:39:35 -05:00
parent 2e9fa9f1b7
commit 5b932a8ac6
3 changed files with 3224 additions and 70 deletions

View File

@ -53,33 +53,41 @@ class Geojson:
self._min_y = y
@staticmethod
def _create_building_lod0(name, year_of_construction, function, surfaces_coordinates):
def _create_buildings_lod0(name, year_of_construction, function, surfaces_coordinates):
surfaces = []
for surface_coordinates in surfaces_coordinates:
buildings = []
for zone, surface_coordinates in enumerate(surfaces_coordinates):
points = GeometryHelper.points_from_string(GeometryHelper.remove_last_point_from_string(surface_coordinates))
polygon = Polygon(points)
surfaces.append(Surface(polygon, polygon))
return Building(name, 0, surfaces, year_of_construction, function)
buildings.append(Building(f'{name}_zone_{zone}', 0, surfaces, year_of_construction, function))
return buildings
@staticmethod
def _create_building_lod1(name, year_of_construction, function, height, surface_coordinates):
lod0_building = Geojson._create_building_lod0(name, year_of_construction, function, surface_coordinates)
def _create_buildings_lod1(name, year_of_construction, function, height, surface_coordinates):
print(f'create lod 1 {name}')
lod0_buildings = Geojson._create_buildings_lod0(name, year_of_construction, function, surface_coordinates)
surfaces = []
for surface in lod0_building.surfaces:
shapely_polygon = ShapelyPolygon(surface.solid_polygon.coordinates)
if not shapely_polygon.is_valid:
print(surface.solid_polygon.area)
print('error?', name, surface_coordinates)
continue
mesh = trimesh.creation.extrude_polygon(shapely_polygon, height)
for face in mesh.faces:
points = []
for vertex_index in face:
points.append(mesh.vertices[vertex_index])
polygon = Polygon(points)
surface = Surface(polygon, polygon)
surfaces.append(surface)
return Building(name, 1, surfaces, year_of_construction, function)
buildings = []
for zone, lod0_building in enumerate(lod0_buildings):
print(len(lod0_building.surfaces))
for surface in lod0_building.surfaces:
shapely_polygon = ShapelyPolygon(surface.solid_polygon.coordinates)
if not shapely_polygon.is_valid:
print(surface.solid_polygon.area)
print('error?', name, surface_coordinates)
continue
mesh = trimesh.creation.extrude_polygon(shapely_polygon, height)
for face in mesh.faces:
points = []
for vertex_index in face:
points.append(mesh.vertices[vertex_index])
polygon = Polygon(points)
surface = Surface(polygon, polygon)
surfaces.append(surface)
print(f'{name}_zone_{zone}_surface_{zone}')
buildings.append(Building(f'{name}_zone_{zone}', 1, surfaces, year_of_construction, function))
return buildings
def _get_polygons(self, polygons, coordinates):
if type(coordinates[0][self.X]) != float:
@ -121,25 +129,24 @@ class Geojson:
building_name = f'building_{building_id}'
building_id += 1
polygons = []
for coordinates in geometry['coordinates']:
for part, coordinates in enumerate(geometry['coordinates']):
polygons = self._get_polygons(polygons, coordinates)
for polygon in polygons:
for zone, polygon in enumerate(polygons):
if extrusion_height == 0:
buildings.append(Geojson._create_building_lod0(building_name,
year_of_construction,
function,
[polygon]))
buildings = buildings + Geojson._create_buildings_lod0(f'{building_name}_part_{part}_zone{zone}',
year_of_construction,
function,
[polygon])
else:
if self._max_z < extrusion_height:
self._max_z = extrusion_height
buildings.append(Geojson._create_building_lod1(building_name,
year_of_construction,
function,
extrusion_height,
[polygon]))
buildings = buildings + Geojson._create_buildings_lod1(f'{building_name}_part_{part}',
year_of_construction,
function,
extrusion_height,
[polygon])
self._city = City([self._min_x, self._min_y, 0.0], [self._max_x, self._max_y, self._max_z], 'epsg:26911')
for building in buildings:
self._city.add_city_object(building)
return self._city

View File

@ -9,8 +9,9 @@ from unittest import TestCase
from numpy import inf
from imports.geometry_factory import GeometryFactory
import exports.exports_factory
from imports.construction_factory import ConstructionFactory
from imports.geometry_factory import GeometryFactory
class TestGeometryFactory(TestCase):
@ -25,29 +26,15 @@ class TestGeometryFactory(TestCase):
"""
self._city = None
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
def _get_citygml(self, file):
def _get_city(self, file, file_type, height_field=None, year_of_construction_field=None, function_field=None):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('citygml', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_geojson(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('gpandas', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_obj(self, file):
# todo: solve the incongruities between city and city_debug
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('obj', path=file_path).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
def _get_rhino(self, file):
file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('rhino', path=file_path).city
self._city = GeometryFactory(file_type,
path=file_path,
height_field=height_field,
year_of_construction_field=year_of_construction_field,
function_field=function_field).city
self.assertIsNotNone(self._city, 'city is none')
return self._city
@ -60,7 +47,6 @@ class TestGeometryFactory(TestCase):
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
self.assertIsNotNone(building.centroid, 'building centroid is none')
self.assertIsNotNone(building.max_height, 'building max_height is none')
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
@ -79,8 +65,6 @@ 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.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
self.assertIsNotNone(building.function, 'building function 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.assertEqual(len(building.heating), 0, 'building heating is not none')
@ -117,8 +101,8 @@ class TestGeometryFactory(TestCase):
Test city objects in the city
:return: None
"""
file = 'one_building_in_kelowna.gml'
city = self._get_citygml(file)
file = 'FZK_Haus_LoD_2.gml'
city = self._get_city(file, 'citygml', year_of_construction_field='yearOfConstruction')
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
@ -126,13 +110,12 @@ class TestGeometryFactory(TestCase):
building.year_of_construction = 2006
city = ConstructionFactory('nrel', city).enrich()
# rhino
def test_import_rhino(self):
"""
Test rhino import
"""
file = 'dompark.3dm'
city = self._get_rhino(file)
city = self._get_city(file, 'rhino')
self.assertIsNotNone(city, 'city is none')
self.assertTrue(len(city.buildings) == 36)
i = 0
@ -140,14 +123,12 @@ class TestGeometryFactory(TestCase):
self.assertIsNot(building.volume, inf, 'open volume')
i += 1
# obj
def test_import_obj(self):
"""
Test obj import
"""
file = 'kelowna.obj'
city = self._get_obj(file)
self.assertIsNotNone(city, 'city is none')
city = self._get_city(file, 'obj')
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
@ -158,12 +139,36 @@ class TestGeometryFactory(TestCase):
Test geopandas import
"""
file = 'sample.geojson'
city = self._get_geojson(file)
self.assertIsNotNone(city, 'city is none')
city = self._get_city(file, 'gpandas')
self.assertTrue(len(city.buildings) == 1)
self._check_buildings(city)
for building in city.buildings:
self._check_surfaces(building)
self.assertEqual(1912.0898135701814, building.volume)
self.assertEqual(146.19493345171213, building.floor_area)
def test_import_geojson(self):
"""
Test geojson import
"""
file = 'concordia.geojson'
city = self._get_city(file, 'geojson',
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
function_field='LIBELLE_UT')
for building in city.buildings:
print(building.name, building.volume)
exports.exports_factory.ExportsFactory('obj', city, self._output_path).export_debug()
self.assertEqual(203, len(city.buildings), 'wrong number of buildings')
self._check_buildings(city)
def test_subway(self):
"""
Test subway parsing
:return:
"""
file = 'subway.osm'
city = self._get_city(file, 'osm_subway')
self.assertIsNotNone(city, 'subway entrances is none')
self.assertEqual(len(city.city_objects), 20, 'Wrong number of subway entrances')

File diff suppressed because it is too large Load Diff