summer_course_2024/city_model_structure/city.py

78 lines
2.2 KiB
Python

from city_model_structure.city_object import CityObject
from typing import List, Union
import pyproj
import reverse_geocoder as rg
class City:
def __init__(self, lower_corner, upper_corner, srs_name, city_objects=None):
self._city_objects = None
self._name = None
self._lower_corner = lower_corner
self._upper_corner = upper_corner
self._city_objects = city_objects
self._srs_name = srs_name
# todo: right now extracted at city level, in the future should be extracted also at building level if exist
self._location = None
@property
def location(self):
if self._location is None:
gps = pyproj.CRS('EPSG:4326') # LatLon with WGS84 datum used by GPS units and Google Earth
input_reference = None
try:
input_reference = pyproj.CRS(self.srs_name) # Projected coordinate system from input data
except pyproj.exceptions.CRSError:
print('Invalid projection reference system, please check the input data. (e.g. in CityGML files: srs_name)')
quit()
coordinates = pyproj.transform(input_reference, gps, self.lower_corner[0], self.lower_corner[1])
self._location = rg.search(coordinates)
return self._location
@property
def country_code(self):
return self.location[0]['cc']
@property
def name(self):
if self._name is None:
self._name = self.location[0]['name']
return self._name
@property
def city_objects(self) -> Union[List[CityObject], None]:
return self._city_objects
@property
def lower_corner(self):
return self._lower_corner
@property
def upper_corner(self):
return self._upper_corner
def city_object(self, name) -> Union[CityObject, None]:
for c in self.city_objects:
if c.name == name:
return c
return None
def add_city_object(self, new_city_object):
if self._city_objects is None:
self._city_objects = []
for city_object in self.city_objects:
# ToDo: Check for shared walls.
for surface in city_object.surfaces:
for surface2 in new_city_object.surfaces:
surface.shared(surface2)
self._city_objects.append(new_city_object)
@property
def srs_name(self):
return self._srs_name
@name.setter
def name(self, value):
self._name = value