created customized imports factory and correspondent test
This commit is contained in:
parent
688ba9bd37
commit
ef6afb0ab4
|
@ -174,6 +174,8 @@ class Building(CityObject):
|
||||||
:return: [ThermalZone]
|
:return: [ThermalZone]
|
||||||
"""
|
"""
|
||||||
if len(self._thermal_zones) == 0:
|
if len(self._thermal_zones) == 0:
|
||||||
|
if self.storeys is None:
|
||||||
|
return []
|
||||||
for storey in self.storeys:
|
for storey in self.storeys:
|
||||||
self._thermal_zones.append(storey.thermal_zone)
|
self._thermal_zones.append(storey.thermal_zone)
|
||||||
return self._thermal_zones
|
return self._thermal_zones
|
||||||
|
@ -194,6 +196,15 @@ class Building(CityObject):
|
||||||
"""
|
"""
|
||||||
return self._year_of_construction
|
return self._year_of_construction
|
||||||
|
|
||||||
|
@year_of_construction.setter
|
||||||
|
def year_of_construction(self, value):
|
||||||
|
"""
|
||||||
|
Set building year of construction
|
||||||
|
:param value: int
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._year_of_construction = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def function(self) -> Union[None, str]:
|
def function(self) -> Union[None, str]:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,99 +5,99 @@
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>assembly</id>
|
<id>assembly</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.15</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.15</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>health</id>
|
<id>health</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.1</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.1</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>20</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">20</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>hotel</id>
|
<id>hotel</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.11</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.11</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>manufacturing</id>
|
<id>manufacturing</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.07</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.07</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>10</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>office</id>
|
<id>office</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.05</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.05</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>restaurant</id>
|
<id>restaurant</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.7</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.7</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>retail</id>
|
<id>retail</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.2</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.2</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>school</id>
|
<id>school</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.25</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.25</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>10</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>lab</id>
|
<id>lab</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.25</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.25</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>10</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
|
@ -105,18 +105,18 @@
|
||||||
<id>residential</id>
|
<id>residential</id>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
<zoneUsageType>
|
<zoneUsageType>
|
||||||
<id>gymnasium</id>
|
<id>gymnasium</id>
|
||||||
<occupancy>
|
<occupancy>
|
||||||
<occupancyDensity>0.3</occupancyDensity>
|
<occupancyDensity units="persons/m2">0.3</occupancyDensity>
|
||||||
</occupancy>
|
</occupancy>
|
||||||
<endUses>
|
<endUses>
|
||||||
<ventilation>
|
<ventilation>
|
||||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||||
</ventilation>
|
</ventilation>
|
||||||
</endUses>
|
</endUses>
|
||||||
</zoneUsageType>
|
</zoneUsageType>
|
||||||
|
|
|
@ -7,6 +7,10 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
||||||
# universal constants
|
# universal constants
|
||||||
KELVIN = 273.15
|
KELVIN = 273.15
|
||||||
|
|
||||||
|
# converters
|
||||||
|
HOUR_TO_MINUTES = 60
|
||||||
|
METERS_TO_FEET = 3.28084
|
||||||
|
|
||||||
# time
|
# time
|
||||||
SECOND = 'second'
|
SECOND = 'second'
|
||||||
MINUTE = 'minute'
|
MINUTE = 'minute'
|
||||||
|
|
|
@ -55,10 +55,13 @@ class EnrichCity:
|
||||||
|
|
||||||
def _construction(self, construction_format):
|
def _construction(self, construction_format):
|
||||||
ConstructionFactory(construction_format, self._city).enrich()
|
ConstructionFactory(construction_format, self._city).enrich()
|
||||||
|
|
||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
# infiltration_rate_system_off is a mandatory parameter.
|
# infiltration_rate_system_off is a mandatory parameter.
|
||||||
# If it is not returned, extract the building from the calculation list
|
# If it is not returned, extract the building from the calculation list
|
||||||
if building.thermal_zones[0].infiltration_rate_system_off is None:
|
if len(building.thermal_zones) == 0:
|
||||||
|
self._city.remove_city_object(building)
|
||||||
|
elif building.thermal_zones[0].infiltration_rate_system_off is None:
|
||||||
self._city.remove_city_object(building)
|
self._city.remove_city_object(building)
|
||||||
if self._city.buildings is None:
|
if self._city.buildings is None:
|
||||||
self._errors.append('no archetype found per construction')
|
self._errors.append('no archetype found per construction')
|
||||||
|
|
|
@ -31,6 +31,7 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
||||||
# it is assumed that all buildings have the same archetypes' keys
|
# it is assumed that all buildings have the same archetypes' keys
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
building_type = ConstructionHelper.nrel_from_function(building.function)
|
building_type = ConstructionHelper.nrel_from_function(building.function)
|
||||||
|
print(building_type)
|
||||||
if building_type is None:
|
if building_type is None:
|
||||||
return
|
return
|
||||||
archetype = self._search_archetype(building_type,
|
archetype = self._search_archetype(building_type,
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
"""
|
||||||
|
Sanam's customized importer Usage helper
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import helpers.constants as cte
|
||||||
|
|
||||||
|
|
||||||
|
class SanamCustomizedUsageHelper:
|
||||||
|
"""
|
||||||
|
SanamCustomizedUsage class
|
||||||
|
"""
|
||||||
|
usage_to_customized = {
|
||||||
|
cte.RESIDENTIAL: 'residential',
|
||||||
|
cte.INDUSTRY: 'manufacturing',
|
||||||
|
cte.OFFICE_ADMINISTRATION: 'office',
|
||||||
|
cte.HOTEL: 'hotel',
|
||||||
|
cte.HEALTH_CARE: 'health',
|
||||||
|
cte.RETAIL: 'retail',
|
||||||
|
cte.HALL: 'assembly',
|
||||||
|
cte.RESTAURANT: 'restaurant',
|
||||||
|
cte.EDUCATION: 'school'
|
||||||
|
}
|
||||||
|
customized_default_value = 'residential'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def customized_from_usage(usage):
|
||||||
|
"""
|
||||||
|
Get customized usage from the given internal usage key
|
||||||
|
:param usage: str
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return SanamCustomizedUsageHelper.usage_to_customized[usage]
|
||||||
|
except KeyError:
|
||||||
|
sys.stderr.write('Error: keyword not found. Returned default HfT usage "residential"\n')
|
||||||
|
return SanamCustomizedUsageHelper.customized_default_value
|
|
@ -8,7 +8,7 @@ import sys
|
||||||
import xmltodict
|
import xmltodict
|
||||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||||
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
import helpers.constants as cte
|
||||||
|
|
||||||
|
|
||||||
class SanamCustomizedUsageParameters:
|
class SanamCustomizedUsageParameters:
|
||||||
|
@ -36,6 +36,11 @@ class SanamCustomizedUsageParameters:
|
||||||
city = self._city
|
city = self._city
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
archetype = self._search_archetype(building.function) # todo: building.function or other translation???????
|
archetype = self._search_archetype(building.function) # todo: building.function or other translation???????
|
||||||
|
height = building.average_storey_height
|
||||||
|
if height is None:
|
||||||
|
raise Exception('Average storey height not defined, ACH cannot be calculated')
|
||||||
|
if height <= 0:
|
||||||
|
raise Exception('Average storey height is zero, ACH cannot be calculated')
|
||||||
if archetype is None:
|
if archetype is None:
|
||||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||||
f' {building.function}, that assigns building usage as '
|
f' {building.function}, that assigns building usage as '
|
||||||
|
@ -44,11 +49,8 @@ class SanamCustomizedUsageParameters:
|
||||||
mix_usage = False
|
mix_usage = False
|
||||||
if not mix_usage:
|
if not mix_usage:
|
||||||
# just one usage_zone
|
# just one usage_zone
|
||||||
for thermal_zone in building.thermal_zones:
|
for usage_zone in building.usage_zones:
|
||||||
usage_zone = UsageZone()
|
self._assign_values(usage_zone, archetype, height)
|
||||||
self._assign_values(usage_zone, archetype)
|
|
||||||
usage_zone.volume = thermal_zone.volume
|
|
||||||
thermal_zone.usage_zones = [usage_zone]
|
|
||||||
|
|
||||||
def _search_archetype(self, building_usage):
|
def _search_archetype(self, building_usage):
|
||||||
for building_archetype in self._usage_archetypes:
|
for building_archetype in self._usage_archetypes:
|
||||||
|
@ -57,20 +59,24 @@ class SanamCustomizedUsageParameters:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _assign_values(usage_zone, archetype):
|
def _assign_values(usage_zone, archetype, height):
|
||||||
usage_zone.usage = archetype.usage
|
usage_zone.usage = archetype.usage
|
||||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||||
# Therefore, this walk around has been done.
|
# Therefore, this walk around has been done.
|
||||||
|
if archetype.occupancy_density is not None:
|
||||||
usage_zone.occupancy_density = archetype.occupancy_density
|
usage_zone.occupancy_density = archetype.occupancy_density
|
||||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
archetype_mechanical_air_change = float(archetype.mechanical_air_change) * float(usage_zone.occupancy_density) \
|
||||||
|
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / height
|
||||||
|
usage_zone.mechanical_air_change = archetype_mechanical_air_change
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_zone_usage_type(usage, zone_usage_type):
|
def _parse_zone_usage_type(usage, zone_usage_type):
|
||||||
occupancy_density = None
|
mechanical_air_change = zone_usage_type['endUses']['ventilation']['minimumVentilationRate']['#text']
|
||||||
if 'occupancy' in zone_usage_type:
|
if 'occupancy' in zone_usage_type:
|
||||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']
|
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']['#text']
|
||||||
mechanical_air_change = zone_usage_type['endUses']['ventilation']['minimumVentilationRate']
|
|
||||||
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
||||||
mechanical_air_change=mechanical_air_change)
|
mechanical_air_change=mechanical_air_change)
|
||||||
|
else:
|
||||||
|
usage_zone_archetype = huza(usage=usage, mechanical_air_change=mechanical_air_change)
|
||||||
return usage_zone_archetype
|
return usage_zone_archetype
|
||||||
|
|
|
@ -8,7 +8,7 @@ from city_model_structure.city import City
|
||||||
from imports.geometry.citygml import CityGml
|
from imports.geometry.citygml import CityGml
|
||||||
from imports.geometry.obj import Obj
|
from imports.geometry.obj import Obj
|
||||||
from imports.geometry.osm_subway import OsmSubway
|
from imports.geometry.osm_subway import OsmSubway
|
||||||
from imports.geometry.rhino import Rhino
|
#from imports.geometry.rhino import Rhino
|
||||||
|
|
||||||
|
|
||||||
class GeometryFactory:
|
class GeometryFactory:
|
||||||
|
@ -43,13 +43,13 @@ class GeometryFactory:
|
||||||
"""
|
"""
|
||||||
return OsmSubway(self._path).city
|
return OsmSubway(self._path).city
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def _rhino(self) -> City:
|
# def _rhino(self) -> City:
|
||||||
"""
|
# """
|
||||||
Enrich the city by using OpenStreetMap information as data source
|
# Enrich the city by using OpenStreetMap information as data source
|
||||||
:return: City
|
# :return: City
|
||||||
"""
|
# """
|
||||||
return Rhino(self._path).city
|
# return Rhino(self._path).city
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def city(self) -> City:
|
def city(self) -> City:
|
||||||
|
@ -59,10 +59,10 @@ class GeometryFactory:
|
||||||
"""
|
"""
|
||||||
return getattr(self, self._file_type, lambda: None)
|
return getattr(self, self._file_type, lambda: None)
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def city_debug(self) -> City:
|
# def city_debug(self) -> City:
|
||||||
"""
|
# """
|
||||||
Enrich the city given to the class using the class given handler
|
# Enrich the city given to the class using the class given handler
|
||||||
:return: City
|
# :return: City
|
||||||
"""
|
# """
|
||||||
return Rhino(self._path).city
|
# return Rhino(self._path).city
|
||||||
|
|
|
@ -8,6 +8,7 @@ from unittest import TestCase
|
||||||
|
|
||||||
from imports.geometry_factory import GeometryFactory
|
from imports.geometry_factory import GeometryFactory
|
||||||
from imports.construction_factory import ConstructionFactory
|
from imports.construction_factory import ConstructionFactory
|
||||||
|
from imports.usage_factory import UsageFactory
|
||||||
from imports.customized_imports_factory import CustomizedImportsFactory
|
from imports.customized_imports_factory import CustomizedImportsFactory
|
||||||
from imports.customized_imports.sanam_customized_usage_parameters import SanamCustomizedUsageParameters as scp
|
from imports.customized_imports.sanam_customized_usage_parameters import SanamCustomizedUsageParameters as scp
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ class TestCustomizedImportsFactory(TestCase):
|
||||||
_city = GeometryFactory('citygml', file_path).city
|
_city = GeometryFactory('citygml', file_path).city
|
||||||
self.assertIsNotNone(_city, 'city is none')
|
self.assertIsNotNone(_city, 'city is none')
|
||||||
ConstructionFactory('nrel', _city).enrich()
|
ConstructionFactory('nrel', _city).enrich()
|
||||||
|
UsageFactory('hft', _city).enrich()
|
||||||
|
|
||||||
return _city
|
return _city
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user