created customized imports factory and correspondent test
This commit is contained in:
parent
2af8bf5db3
commit
3adf8c9604
|
@ -174,6 +174,8 @@ class Building(CityObject):
|
|||
:return: [ThermalZone]
|
||||
"""
|
||||
if len(self._thermal_zones) == 0:
|
||||
if self.storeys is None:
|
||||
return []
|
||||
for storey in self.storeys:
|
||||
self._thermal_zones.append(storey.thermal_zone)
|
||||
return self._thermal_zones
|
||||
|
@ -194,6 +196,15 @@ class Building(CityObject):
|
|||
"""
|
||||
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
|
||||
def function(self) -> Union[None, str]:
|
||||
"""
|
||||
|
|
|
@ -5,99 +5,99 @@
|
|||
<zoneUsageType>
|
||||
<id>assembly</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.15</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.15</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>health</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.1</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.1</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>20</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">20</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>hotel</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.11</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.11</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>manufacturing</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.07</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.07</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>10</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>office</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.05</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.05</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>restaurant</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.7</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.7</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>retail</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.2</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.2</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>school</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.25</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.25</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>10</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>lab</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.25</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.25</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>10</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">10</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
|
@ -105,18 +105,18 @@
|
|||
<id>residential</id>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
<zoneUsageType>
|
||||
<id>gymnasium</id>
|
||||
<occupancy>
|
||||
<occupancyDensity>0.3</occupancyDensity>
|
||||
<occupancyDensity units="persons/m2">0.3</occupancyDensity>
|
||||
</occupancy>
|
||||
<endUses>
|
||||
<ventilation>
|
||||
<minimumVentilationRate>7.5</minimumVentilationRate>
|
||||
<minimumVentilationRate units="cfm/person">7.5</minimumVentilationRate>
|
||||
</ventilation>
|
||||
</endUses>
|
||||
</zoneUsageType>
|
||||
|
|
|
@ -7,6 +7,10 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
# universal constants
|
||||
KELVIN = 273.15
|
||||
|
||||
# converters
|
||||
HOUR_TO_MINUTES = 60
|
||||
METERS_TO_FEET = 3.28084
|
||||
|
||||
# time
|
||||
SECOND = 'second'
|
||||
MINUTE = 'minute'
|
||||
|
|
|
@ -55,10 +55,13 @@ class EnrichCity:
|
|||
|
||||
def _construction(self, construction_format):
|
||||
ConstructionFactory(construction_format, self._city).enrich()
|
||||
|
||||
for building in self._city.buildings:
|
||||
# infiltration_rate_system_off is a mandatory parameter.
|
||||
# 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)
|
||||
if self._city.buildings is None:
|
||||
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
|
||||
for building in city.buildings:
|
||||
building_type = ConstructionHelper.nrel_from_function(building.function)
|
||||
print(building_type)
|
||||
if building_type is None:
|
||||
return
|
||||
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
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||
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:
|
||||
|
@ -36,6 +36,11 @@ class SanamCustomizedUsageParameters:
|
|||
city = self._city
|
||||
for building in city.buildings:
|
||||
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:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
|
@ -44,11 +49,8 @@ class SanamCustomizedUsageParameters:
|
|||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
for thermal_zone in building.thermal_zones:
|
||||
usage_zone = UsageZone()
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
for usage_zone in building.usage_zones:
|
||||
self._assign_values(usage_zone, archetype, height)
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
|
@ -57,20 +59,24 @@ class SanamCustomizedUsageParameters:
|
|||
return None
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype):
|
||||
def _assign_values(usage_zone, archetype, height):
|
||||
usage_zone.usage = archetype.usage
|
||||
# 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.
|
||||
# Therefore, this walk around has been done.
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
if archetype.occupancy_density is not None:
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
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
|
||||
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:
|
||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']
|
||||
mechanical_air_change = zone_usage_type['endUses']['ventilation']['minimumVentilationRate']
|
||||
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']['#text']
|
||||
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
else:
|
||||
usage_zone_archetype = huza(usage=usage, mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
|
|
|
@ -8,7 +8,7 @@ from city_model_structure.city import City
|
|||
from imports.geometry.citygml import CityGml
|
||||
from imports.geometry.obj import Obj
|
||||
from imports.geometry.osm_subway import OsmSubway
|
||||
from imports.geometry.rhino import Rhino
|
||||
#from imports.geometry.rhino import Rhino
|
||||
|
||||
|
||||
class GeometryFactory:
|
||||
|
@ -43,13 +43,13 @@ class GeometryFactory:
|
|||
"""
|
||||
return OsmSubway(self._path).city
|
||||
|
||||
@property
|
||||
def _rhino(self) -> City:
|
||||
"""
|
||||
Enrich the city by using OpenStreetMap information as data source
|
||||
:return: City
|
||||
"""
|
||||
return Rhino(self._path).city
|
||||
# @property
|
||||
# def _rhino(self) -> City:
|
||||
# """
|
||||
# Enrich the city by using OpenStreetMap information as data source
|
||||
# :return: City
|
||||
# """
|
||||
# return Rhino(self._path).city
|
||||
|
||||
@property
|
||||
def city(self) -> City:
|
||||
|
@ -59,10 +59,10 @@ class GeometryFactory:
|
|||
"""
|
||||
return getattr(self, self._file_type, lambda: None)
|
||||
|
||||
@property
|
||||
def city_debug(self) -> City:
|
||||
"""
|
||||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
"""
|
||||
return Rhino(self._path).city
|
||||
# @property
|
||||
# def city_debug(self) -> City:
|
||||
# """
|
||||
# Enrich the city given to the class using the class given handler
|
||||
# :return: City
|
||||
# """
|
||||
# return Rhino(self._path).city
|
||||
|
|
|
@ -8,6 +8,7 @@ from unittest import TestCase
|
|||
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.customized_imports_factory import CustomizedImportsFactory
|
||||
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
|
||||
self.assertIsNotNone(_city, 'city is none')
|
||||
ConstructionFactory('nrel', _city).enrich()
|
||||
UsageFactory('hft', _city).enrich()
|
||||
|
||||
return _city
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user