Add geojson exporter

This commit is contained in:
Guille Gutierrez 2023-10-24 08:00:48 +02:00
parent a31281cae7
commit 6ee1466b8e
3 changed files with 64 additions and 16 deletions

View File

@ -47,28 +47,66 @@ class Geojson:
def _export(self): def _export(self):
for building in self._city.buildings: for building in self._city.buildings:
feature = self._feature_skeleton.copy() if len(building.grounds) == 1:
ground = building.grounds[0]
feature = self._polygon(ground)
else:
feature = self._multipolygon(building.grounds)
feature['id'] = building.name feature['id'] = building.name
feature['properties']['height'] = f'{building.max_height}' feature['properties']['height'] = f'{building.max_height - building.lower_corner[2]}'
feature['properties']['function'] = f'{building.function}' feature['properties']['function'] = f'{building.function}'
feature['properties']['year_of_construction'] = f'{building.year_of_construction}' feature['properties']['year_of_construction'] = f'{building.year_of_construction}'
feature['properties']['aliases'] = building.aliases feature['properties']['aliases'] = building.aliases
feature['properties']['elevation'] = f'{building.lower_corner[2]}' feature['properties']['elevation'] = f'{building.lower_corner[2]}'
for ground in building.grounds:
ground_coordinates = []
for coordinate in ground.solid_polygon.coordinates:
gps_coordinate = self._to_gps.transform(coordinate[0], coordinate[1])
ground_coordinates.insert(0, [gps_coordinate[1], gps_coordinate[0]])
first_gps_coordinate = self._to_gps.transform(
ground.solid_polygon.coordinates[0][0],
ground.solid_polygon.coordinates[0][1]
)
ground_coordinates.insert(0, [first_gps_coordinate[1], first_gps_coordinate[0]])
feature['geometry']['coordinates'].append(ground_coordinates)
self._geojson_skeleton['features'].append(feature) self._geojson_skeleton['features'].append(feature)
with open(self._file_path, 'w', encoding='utf-8') as f: with open(self._file_path, 'w', encoding='utf-8') as f:
json.dump(self._geojson_skeleton, f, indent=2) json.dump(self._geojson_skeleton, f, indent=2)
def _polygon(self, ground):
feature = {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': []
},
'properties': {}
}
ground_coordinates = []
for coordinate in ground.solid_polygon.coordinates:
gps_coordinate = self._to_gps.transform(coordinate[0], coordinate[1])
ground_coordinates.insert(0, [gps_coordinate[1], gps_coordinate[0]])
first_gps_coordinate = self._to_gps.transform(
ground.solid_polygon.coordinates[0][0],
ground.solid_polygon.coordinates[0][1]
)
ground_coordinates.insert(0, [first_gps_coordinate[1], first_gps_coordinate[0]])
feature['geometry']['coordinates'].append(ground_coordinates)
return feature
def _multipolygon(self, grounds):
feature = {
'type': 'Feature',
'geometry': {
'type': 'MultiPolygon',
'coordinates': []
},
'properties': {}
}
polygons = []
for ground in grounds:
ground_coordinates = []
for coordinate in ground.solid_polygon.coordinates:
gps_coordinate = self._to_gps.transform(coordinate[0], coordinate[1])
ground_coordinates.insert(0, [gps_coordinate[1], gps_coordinate[0]])
first_gps_coordinate = self._to_gps.transform(
ground.solid_polygon.coordinates[0][0],
ground.solid_polygon.coordinates[0][1]
)
ground_coordinates.insert(0, [first_gps_coordinate[1], first_gps_coordinate[0]])
polygons.append(ground_coordinates)
feature['geometry']['coordinates'].append(polygons)
return feature

View File

@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
""" """
import logging
import numpy as np import numpy as np
import xmltodict import xmltodict
@ -79,6 +80,7 @@ class CityGml:
self._srs_name = envelope['@srsName'] self._srs_name = envelope['@srsName']
else: else:
# If not coordinate system given assuming hub standard # If not coordinate system given assuming hub standard
logging.warning('gml file contains no coordinate system assuming EPSG:26911 (North america with 4m error)')
self._srs_name = "EPSG:26911" self._srs_name = "EPSG:26911"
else: else:
# get the boundary from the city objects instead # get the boundary from the city objects instead

View File

@ -100,7 +100,15 @@ class TestExports(TestCase):
def test_geojson_export(self): def test_geojson_export(self):
self._export('geojson', False) self._export('geojson', False)
self.assertTrue(False, "False is not True") geojson_file = Path(self._output_path / f'{self._city.name}.geojson')
self.assertTrue(geojson_file.exists(), f'{geojson_file} doesn\'t exists')
with open(geojson_file, 'r') as f:
geojson = json.load(f)
self.assertEqual(1, len(geojson['features']), 'Wrong number of buildings')
geometry = geojson['features'][0]['geometry']
self.assertEqual('Polygon', geometry['type'], 'Wrong geometry type')
self.assertEqual(1, len(geometry['coordinates']), 'Wrong polygon structure')
self.assertEqual(11, len(geometry['coordinates'][0]), 'Wrong number of vertices')
def test_energy_ade_export(self): def test_energy_ade_export(self):
""" """