""" City info SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca Code contributors: Peter Yefi peteryefi@gmail.com """ import json from flask import Response, request, g from flask_restful import Resource from hub_api.helpers.auth import role_required from persistence.models import UserRoles from hub_logger import logger from imports.geometry_factory import GeometryFactory from pathlib import Path import os from hub_api.config import Config class CityInfo(Resource, Config): def __init__(self): super().__init__() @role_required([UserRoles.Admin.value]) def get(self, city_id): city = self.get_city(city_id) # TODO: this is only for dompark project and need to be removed in future versions. floor_area = 0 wall_construction = 'unknown' floor_construction = 'unknown' roof_construction = 'unknown' window_type = 'unknown' building_dic = {} for building in city.buildings: usages = [] # This is only valid for dompark project as all the building have the same usage if building.lower_corner[2] == 0: floor_area += building.floor_area for internal_zone in building.internal_zones: for usage_zone in internal_zone.usage_zones: usages.append({'percentage': usage_zone.percentage, 'usage': usage_zone.usage}) for thermal_zone in internal_zone.thermal_zones: for thermal_boundary in thermal_zone.thermal_boundaries: if thermal_boundary.parent_surface.type == 'Ground': floor_construction = thermal_boundary.construction_name elif thermal_boundary.parent_surface.type == 'Wall': wall_construction = thermal_boundary.construction_name for thermal_opening in thermal_boundary.thermal_openings: if thermal_opening.construction_name is not None: window_type = thermal_opening.construction_name break else: roof_construction = thermal_boundary.construction_name name = building.human_readable_name year_of_construction = str(building.year_of_construction) building_dic = { 'name': str(name), 'floor_area': str(floor_area), 'year_of_construction': str(year_of_construction), 'usages': usages, 'wall_construction': wall_construction, 'floor_construction': floor_construction, 'roof_construction': roof_construction, 'window_type': window_type, 'default_archetype': 'industry ASHRAE_2004:4A non_standard_dompark' } buildings = [building_dic] response = {'city_name': city.name, 'climate_reference_city': str(city.climate_reference_city), 'buildings': buildings } return Response(json.dumps(response), status=200) class City(Resource, Config): def __init__(self): super().__init__() @role_required([UserRoles.Admin.value]) def post(self): allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'} try: city_file = request.files['city_file'] ext = city_file.filename.rsplit('.', 1)[1].lower() if ext in allowed_ext: city_file_type = ext if ext == 'gml': city_file_type = 'citygml' elif ext == '3dm': city_file_type = 'rhino' file_path = (Path(__file__).parent.parent / 'data/uploaded_city/{}'.format(city_file.filename)).resolve() city_file.save(file_path) city = GeometryFactory(city_file_type, file_path).city saved_city = self.import_db_factory.persist_city(g.user['id'], city) if os.path.exists(file_path): os.remove(file_path) if type(saved_city) is not dict: return Response(response=json.dumps({ 'id': saved_city.id, 'name': saved_city.name, 'srs_name': saved_city.srs_name, 'time_zone': saved_city.time_zone, 'version': saved_city.city_version, 'country': saved_city.country_code, 'lat': saved_city.latitude, 'lon': saved_city.longitude, 'lower_corner': saved_city.lower_corner, 'upper_corner': saved_city.upper_corner, 'created': saved_city.created, 'updated': saved_city.updated, 'user': {'id': saved_city.user.id, 'name': saved_city.user.name, 'email': saved_city.user.email, 'role': saved_city.user.role.value} }, default=str), status=201) return Response(response=json.dumps(saved_city), status=200) else: return Response(response=json.dumps({'err_msg': 'Unknown city file type'}), status=400) except Exception as err: logger.error(err) return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while creating city'}), status=400)