Bug fix in geojson import
This commit is contained in:
parent
2e9fa9f1b7
commit
5b932a8ac6
|
@ -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
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user