city_retrofit/tests/test_city_merge.py

110 lines
4.9 KiB
Python

"""
TestCityMerge test and validate the merge of several cities into one
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import copy
import distutils.spawn
import subprocess
from pathlib import Path
from unittest import TestCase
import pandas as pd
from hub.city_model_structure.city import City
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.results_factory import ResultFactory
from hub.exports.exports_factory import ExportsFactory
import hub.helpers.constants as cte
class TestCityMerge(TestCase):
"""
Functional TestCityMerge
"""
def setUp(self) -> None:
"""
Test setup
:return: None
"""
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
self._executable = 'sra'
def test_merge(self):
file_path = Path(self._example_path / 'test.geojson').resolve()
full_city = GeometryFactory('geojson', file_path, height_field='citygml_me').city
self.assertEqual(17, len(full_city.buildings), 'Wrong number of buildings')
odd_city = City(full_city.lower_corner, full_city.upper_corner, full_city.srs_name)
even_city = City(full_city.lower_corner, full_city.upper_corner, full_city.srs_name)
for building in full_city.buildings:
if int(building.name) % 2 == 0:
even_city.add_city_object(copy.deepcopy(building))
else:
odd_city.add_city_object(copy.deepcopy(building))
self.assertEqual(8, len(odd_city.buildings), 'Wrong number of odd buildings')
self.assertEqual(9, len(even_city.buildings), 'Wrong number of par buildings')
merged_city = odd_city.merge(even_city)
self.assertEqual(17, len(merged_city.buildings), 'Wrong number of buildings in merged city')
merged_city = even_city.merge(odd_city)
self.assertEqual(17, len(merged_city.buildings), 'Wrong number of buildings in merged city')
merged_city = full_city.merge(odd_city).merge(even_city)
self.assertEqual(17, len(merged_city.buildings), 'Wrong number of buildings in merged city')
def test_merge_with_radiation(self):
sra = distutils.spawn.find_executable('sra')
file_path = Path(self._example_path / 'test.geojson').resolve()
full_city = GeometryFactory('geojson', file_path, height_field='citygml_me').city
even_city = City(full_city.lower_corner, full_city.upper_corner, full_city.srs_name)
for building in full_city.buildings:
if int(building.name) % 2 == 0:
even_city.add_city_object(copy.deepcopy(building))
ExportsFactory('sra', full_city, self._output_path).export()
sra_file = str((self._output_path / f'{full_city.name}_sra.xml').resolve())
subprocess.run([sra, sra_file], stdout=subprocess.DEVNULL)
ResultFactory('sra', full_city, self._output_path).enrich()
self.assertEqual(17, len(full_city.buildings), 'Wrong number of buildings')
merged_city = full_city.merge(even_city)
full_city_building_total_radiation = 0
for building in merged_city.buildings:
for surface in building.surfaces:
if surface.global_irradiance:
full_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
merged_city_building_total_radiation = 0
for building in merged_city.buildings:
for surface in building.surfaces:
if surface.global_irradiance:
merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
self.assertEqual(full_city_building_total_radiation, merged_city_building_total_radiation)
merged_city = even_city.merge(full_city)
merged_city_building_total_radiation = 0
for building in merged_city.buildings:
for surface in building.surfaces:
if surface.global_irradiance:
merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
self.assertEqual(full_city_building_total_radiation, merged_city_building_total_radiation)
for building in even_city.buildings:
for surface in building.surfaces:
surface.global_irradiance[cte.YEAR] = pd.DataFrame([3], columns=['sra_mockup_value'])
merged_city = full_city.merge(even_city)
first_merged_city_building_total_radiation = 0
for building in merged_city.buildings:
for surface in building.surfaces:
if surface.global_irradiance:
first_merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
merged_city = even_city.merge(full_city)
second_merged_city_building_total_radiation = 0
for building in merged_city.buildings:
for surface in building.surfaces:
if surface.global_irradiance:
second_merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
self.assertEqual(first_merged_city_building_total_radiation, second_merged_city_building_total_radiation)