from city_model_structure.city_object import CityObject from typing import List, Union import pyproj from pyproj import Transformer 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() transformer = Transformer.from_crs(input_reference, gps) coordinates = transformer.transform(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: 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