Commit 648a9073 authored by Cecilia Nievas's avatar Cecilia Nievas
Browse files

Added feature to interpret number of storeys from building class string

parent 1266a21b
Pipeline #38877 passed with stage
in 3 minutes and 30 seconds
......@@ -26,6 +26,7 @@ import pyproj
from gdeimporter.exposureentity import ExposureEntity
from gdeimporter.dataunit import DataUnit
from gdeimporter.tools.spatial import SpatialTools
from gdeimporter.tools.buildingtaxonomy import GEMTaxonomy_v3
logger = logging.getLogger()
......@@ -818,7 +819,9 @@ class ExposureModelESRM20(AggregatedExposureModel):
(
building_classes_proportions_and_properties,
_,
) = self._retrieve_building_classes(data_table, exposure_entity_name, True)
) = self._retrieve_building_classes(
data_table, exposure_entity_name, occupancy_case, True
)
# Create new DataUnit object
self.exposure_entities[exposure_entity_name].occupancy_cases[occupancy_case][
"data_units"
......@@ -1459,6 +1462,10 @@ class ExposureModelESRM20(AggregatedExposureModel):
total_cost_per_building (float):
Total replacement cost per building, including costs of structural and
non-structural components as well as contents.
storeys_min (int):
Minimum number of storeys of the building class.
storeys_max (int):
Maximum number of storeys of the building class.
"""
proportions_and_properties = {}
......@@ -1472,7 +1479,7 @@ class ExposureModelESRM20(AggregatedExposureModel):
proportions_and_properties[data_unit_id],
warning_in_properties,
) = self._retrieve_building_classes(
data_filtered_data_unit, exposure_entity_name, weighted_average
data_filtered_data_unit, exposure_entity_name, occupancy_case, weighted_average
)
# Log information (if found; otherwise 'warning_in_properties' is empty)
......@@ -1488,7 +1495,9 @@ class ExposureModelESRM20(AggregatedExposureModel):
return proportions_and_properties
def _retrieve_building_classes(self, data_table, exposure_entity_name, weighted_average):
def _retrieve_building_classes(
self, data_table, exposure_entity_name, occupancy_case, weighted_average
):
"""This function retrieves the proportions of building classes from the whole of
'data_table', as well as their associated total replacement costs and total census
people per building. If 'weighted_average' is True, these are calculated as the weighted
......@@ -1513,6 +1522,9 @@ class ExposureModelESRM20(AggregatedExposureModel):
ExposureEntity and occupancy_case.
exposure_entity_name (str):
Name of the ExposureEntity to which data_units_ids belong.
occupancy_case (str):
Name of the occupancy case (e.g. "residential", "commercial", "industrial") to
which data_table corresponds.
weighted_average (bool):
If True, the total replacement costs and total census people per building are
calculated as the average of all the entries of the building class in
......@@ -1546,6 +1558,10 @@ class ExposureModelESRM20(AggregatedExposureModel):
total_cost_per_building (float):
Total replacement cost per building, including costs of structural and
non-structural components as well as contents.
storeys_min (int):
Minimum number of storeys of the building class.
storeys_max (int):
Maximum number of storeys of the building class.
warning_in_properties (list of str):
It specifies the names of the columns of 'data_table' for which different values
of total replacement costs and total census people per building have been found
......@@ -1665,6 +1681,27 @@ class ExposureModelESRM20(AggregatedExposureModel):
for j, col in enumerate(building_output_properties_fields):
unique_vals[col] = aux_output_properties[:, j]
(
unique_vals["storeys_min"],
unique_vals["storeys_max"],
interpret_storeys_problems,
) = GEMTaxonomy_v3.interpret_number_storeys_collective(
unique_vals["building_class_name"]
)
if numpy.any(interpret_storeys_problems):
which = numpy.where(interpret_storeys_problems)[0]
classes_with_problems = list(
numpy.unique(unique_vals["building_class_name"][which])
)
aux_str = ", ".join(classes_with_problems)
logger.warning(
"ExposureModelESRM20._retrieve_building_classes for %s %s: "
"The number of storeys could not be interpreted for the following building "
"classes: %s. Minimum and maximum values of 1 and 9999 were assigned."
% (occupancy_case, exposure_entity_name, aux_str)
)
proportions_and_properties = pandas.DataFrame(unique_vals)
return proportions_and_properties, warning_in_properties
......
......@@ -106,6 +106,10 @@ class DataUnit:
total_cost_per_building (float):
Total replacement cost per building, including costs of structural and
non-structural components as well as contents.
storeys_min (int):
Minimum number of storeys of the building class.
storeys_max (int):
Maximum number of storeys of the building class.
self.data_unit_tiles (GeoPandas GeoDataFrame):
Definition of the data-unit tiles associated with the data unit. It is filled in by
ExposureEntity.create_data_unit_tiles(), processing all the data units associated
......@@ -190,7 +194,10 @@ class DataUnit:
time of the day).
total_cost_per_building (float):
Total replacement cost per building, including costs of structural and
non-structural components as well as contents.
storeys_min (int):
Minimum number of storeys of the building class.
storeys_max (int):
Maximum number of storeys of the building class.
"""
# Check that the keys of total_people are the expected ones
......@@ -450,6 +457,10 @@ class DataUnit:
total_cost_per_building (float):
Total replacement cost of a building of this class, including costs of
structural and non-structural components as well as contents.
storeys_min (int):
Minimum number of storeys of the building class.
storeys_max (int):
Maximum number of storeys of the building class.
aggregated_source_id (int):
ID of the source of the aggregated exposure model.
occupancy_case (str):
......
#!/usr/bin/env python3
# Copyright (C) 2021:
# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
import numpy
class GEMTaxonomy_v3:
"""
This class contains methods that carry out operations associated with building classes
defined by the GEM Building Taxonomy v3.0.
"""
@staticmethod
def interpret_number_storeys(building_class):
"""
This function interprets the minimum and maximum number of storeys from a string that
defines a building class as per the GEM Building Taxonomy.
In the GEM Building Taxonomy, number of storeys above ground are specified as:
- "H:n": the exact number of storeys above ground is "n"
- "HBET:a-b": the number of storeys above ground is a range between "a" (upper bound)
and "b" (lower bound).
- "HAPP:n": the number of storeys above ground is "n", but as an approximation.
This function assumes that "H:", "HBET:" or "HAPP:" only appear once in
'building_class', which is to be expected. If none of these appear in 'building_class',
or if there is any other error in the syntax of 'building_class', the function returns 1
nd 9999 as the minimum and maximum number of storeys, respectively. Any problem found in
interpreting the number of storeys from 'building_class' results in the output boolean
'could_not_interpret' being True.
Examples:
- If 'building_class' is "CR/LFINF+CDM/H:1", the result is 'num_storeys_min' = 1 and
'num_storeys_max' = 1.
- If 'building_class' is "CR/LFINF+CDM/HBET:1-4", the result is 'num_storeys_min' = 1
and 'num_storeys_max' = 4.
- If 'building_class' is "CR/LFINF+CDM/HBET:4-", the result is 'num_storeys_min' = 4 and
'num_storeys_max' = 9999. The number 9999 is used to represent an unbounded upper limit.
Args:
building_class (str):
Building class as per the GEM Building Taxonomy.
Returns:
num_storeys_min (int):
Minimum number of storeys of the building class.
num_storeys_max (int):
Maximum number of storeys of the building class.
could_not_interpret (bool):
If True, the function could not interpret the number of storeys from the input
'building_class'. If False, no problems were encountered.
"""
could_not_interpret = False
if "H:" in building_class:
(
num_storeys_min,
num_storeys_max,
could_not_interpret,
) = GEMTaxonomy_v3._interpret_single_value_of_storeys(building_class, "H:")
elif "HAPP:" in building_class:
(
num_storeys_min,
num_storeys_max,
could_not_interpret,
) = GEMTaxonomy_v3._interpret_single_value_of_storeys(building_class, "HAPP:")
elif "HBET:" in building_class:
(
num_storeys_min,
num_storeys_max,
could_not_interpret,
) = GEMTaxonomy_v3._interpret_range_of_storeys(building_class, "HBET:")
else:
could_not_interpret = True
num_storeys_min = 1
num_storeys_max = 9999
return num_storeys_min, num_storeys_max, could_not_interpret
def _interpret_single_value_of_storeys(building_class, separator):
"""
This auxiliary function interprets the cases in which using the 'separator' to split
'building_class' is expected to lead to one single value of number of storeys, as is the
case when 'separator' is "H:" or "HAPP:". If the content of 'building_class' is such
that the interpretation fails, a boolean output variable ('could_not_interpret')
indicates so.
Examples of contents of 'building_class' with correct syntax that will lead to a
successful interpretation: "xxx/H:N" (separator "H:"), "xxx/HAPP:N" (separator "HAPP:"),
where N is an integer and "xxx" stands for all other parameters in 'building_class'.
Examples of contents of 'building_class' with incorrect syntax that will lead to an
unsuccessful interpretation: "xxx/H:N-M", "xxx/H:-N", "xxx/H:N-", "xxx/HAPP:N-M",
"xxx/HAPP:-N", "xxx/HAPP:N-".
Unsuccessful interpretations result in the function returning 1 and 9999 as the minimum
and maximum number of storeys, respectively.
Args:
building_class (str):
Building class as per the GEM Building Taxonomy.
Returns:
num_storeys_min (int):
Minimum number of storeys of the building class.
num_storeys_max (int):
Maximum number of storeys of the building class.
could_not_interpret (bool):
If True, the function could not interpret the number of storeys from the input
'building_class'. If False, no problems were encountered.
"""
num_storeys = building_class.split(separator)[-1].split("/")[0]
if num_storeys.isnumeric():
could_not_interpret = False
num_storeys_min = int(building_class.split(separator)[-1].split("/")[0])
num_storeys_max = int(building_class.split(separator)[-1].split("/")[0])
else:
could_not_interpret = True
num_storeys_min = 1
num_storeys_max = 9999
return num_storeys_min, num_storeys_max, could_not_interpret
def _interpret_range_of_storeys(building_class, separator):
"""
This auxiliary function interprets the cases in which using the 'separator' to split
'building_class' is expected to lead to a range of numbers of storeys, as is the case
when 'separator' is "HBET:". If the content of 'building_class' is such that the
interpretation fails, a boolean output variable ('could_not_interpret') indicates so.
Examples of contents of 'building_class' with correct syntax that will lead to a
successful interpretation (separator "HBET:" in all cases): "xxx/H:N-M", "xxx/H:N-",
"xxx/H:-M", where N, M are integers and "xxx" stands for all other parameters in
'building_class'.
Examples of contents of 'building_class' with incorrect syntax that will lead to an
unsuccessful interpretation: "xxx/HBET:N", "xxx/HBET:N.M-L", "xxx/HBET:-N-M",
"xxx/HBET:-", etc.
Unsuccessful interpretations result in the function returning 1 and 9999 as the minimum
and maximum number of storeys, respectively.
Args:
building_class (str):
Building class as per the GEM Building Taxonomy.
Returns:
num_storeys_min (int):
Minimum number of storeys of the building class.
num_storeys_max (int):
Maximum number of storeys of the building class.
could_not_interpret (bool):
If True, the function could not interpret the number of storeys from the input
'building_class'. If False, no problems were encountered.
"""
could_not_interpret = False
num_storeys_range = building_class.split(separator)[-1].split("/")[0]
if (
("-" not in num_storeys_range)
or ("." in num_storeys_range)
or (len(num_storeys_range.split("-")) > 2)
):
could_not_interpret = True
num_storeys_min = 1
num_storeys_max = 9999
return num_storeys_min, num_storeys_max, could_not_interpret
# Lower bound
lower_bound_str = num_storeys_range.split("-")[0]
if lower_bound_str == "": # no lower bound specified
num_storeys_min = 1
else:
num_storeys_min = int(num_storeys_range.split("-")[0])
# Upper bound
upper_bound_str = num_storeys_range.split("-")[1]
if upper_bound_str == "": # no upper bound specified
num_storeys_max = 9999
else:
num_storeys_max = int(upper_bound_str)
if lower_bound_str == "" and upper_bound_str == "":
could_not_interpret = True
if num_storeys_min > num_storeys_max:
could_not_interpret = True
num_storeys_min = 1
num_storeys_max = 9999
return num_storeys_min, num_storeys_max, could_not_interpret
@staticmethod
def interpret_number_storeys_collective(building_classes):
"""
This function interprets the minimum and maximum number of storeys from each string that
belongs to 'building_classes'
Args:
building_classes (arr of str):
1-D array containing strings that define building classes as per the GEM
Building Taxonomy.
Returns:
num_storeys_min (arr of int):
1-D array with the minimum number of storeys of each of the building classes in
'building_classes'.
num_storeys_max (arr of int):
1-D array with the maximum number of storeys of each of the building classes in
'building_classes'.
could_not_interpret (arr of bool):
1-D array indicating whether the function could (False) or not (True) interpret
the number of storeys for each corresponding element of 'building_class'.
"""
num_storeys_min = numpy.zeros([len(building_classes)], dtype=int)
num_storeys_max = numpy.zeros([len(building_classes)], dtype=int)
could_not_interpret = numpy.array([False for i in range(len(building_classes))])
for i in range(len(building_classes)):
(
num_storeys_min[i],
num_storeys_max[i],
could_not_interpret[i],
) = GEMTaxonomy_v3.interpret_number_storeys(building_classes[i])
return num_storeys_min, num_storeys_max, could_not_interpret
LON,LAT,TAXONOMY,SETTLEMENT_TYPE,OCCUPANCY_TYPE,BUILDINGS,ID_1,AREA_PER_BUILDING_SQM,COST_PER_AREA_EUR,TOTAL_REPL_COST_EUR,COST_STRUCTURAL_EUR,COST_NONSTRUCTURAL_EUR,COST_CONTENTS_EUR,OCCUPANTS_PER_ASSET,OCCUPANTS_PER_ASSET_DAY,OCCUPANTS_PER_ASSET_NIGHT,OCCUPANTS_PER_ASSET_TRANSIT,OCCUPANTS_PER_ASSET_AVERAGE
20.1,47.3,A,BIG_CITY,ALL,35.2,Unit_X,90,1400,316800000,126720000,63360000,126720000,1056,844.8,105.6,211.2,387.2
20.1,47.3,B,RURAL,ALL,12.7,Unit_X,120,1050,114300000,45720000,22860000,45720000,381,304.8,38.1,76.2,139.7
20.1,47.3,C,BIG_CITY,ALL,8.9,Unit_X,85,1300,80100000,32040000,16020000,32040000,267,213.6,26.7,53.4,97.9
20.1,47.3,C,BIG_CITY,ALL,5.7,Unit_X,90,1400,51300000,20520000,10260000,20520000,171,136.8,17.1,34.2,62.7
19.8,47.4,A,RURAL,ALL,25.6,Unit_Y,110,980,230400000,92160000,46080000,92160000,768,614.4,76.8,153.6,281.6
19.8,47.4,A,URBAN,ALL,7.9,Unit_Y,95,1280,71100000,28440000,14220000,28440000,237,189.6,23.7,47.4,86.9
19.8,47.4,B,RURAL,ALL,23.5,Unit_Y,120,1050,211500000,84600000,42300000,84600000,705,564,70.5,141,258.5
20.4,46.9,A,BIG_CITY,ALL,40.2,Unit_Z,90,1400,361800000,144720000,72360000,144720000,1206,964.8,120.6,241.2,442.2
20.4,46.9,B,BIG_CITY,ALL,16.3,Unit_Z,110,1100,146700000,58680000,29340000,58680000,489,391.2,48.9,97.8,179.3
20.4,46.9,C,RURAL,ALL,33.4,Unit_Z,115,1200,300600000,120240000,60120000,120240000,1002,801.6,100.2,200.4,367.4
20.1,47.3,A/HBET:2-5,BIG_CITY,ALL,35.2,Unit_X,90,1400,316800000,126720000,63360000,126720000,1056,844.8,105.6,211.2,387.2
20.1,47.3,B/HBET:4-,RURAL,ALL,12.7,Unit_X,120,1050,114300000,45720000,22860000,45720000,381,304.8,38.1,76.2,139.7
20.1,47.3,C/H:3,BIG_CITY,ALL,8.9,Unit_X,85,1300,80100000,32040000,16020000,32040000,267,213.6,26.7,53.4,97.9
20.1,47.3,C/H:3,BIG_CITY,ALL,5.7,Unit_X,90,1400,51300000,20520000,10260000,20520000,171,136.8,17.1,34.2,62.7
19.8,47.4,A/HBET:2-5,RURAL,ALL,25.6,Unit_Y,110,980,230400000,92160000,46080000,92160000,768,614.4,76.8,153.6,281.6
19.8,47.4,A/HBET:2-5,URBAN,ALL,7.9,Unit_Y,95,1280,71100000,28440000,14220000,28440000,237,189.6,23.7,47.4,86.9
19.8,47.4,B/HBET:4-,RURAL,ALL,23.5,Unit_Y,120,1050,211500000,84600000,42300000,84600000,705,564,70.5,141,258.5
20.4,46.9,A/HBET:2-5,BIG_CITY,ALL,40.2,Unit_Z,90,1400,361800000,144720000,72360000,144720000,1206,964.8,120.6,241.2,442.2
20.4,46.9,B/HBET:4-,BIG_CITY,ALL,16.3,Unit_Z,110,1100,146700000,58680000,29340000,58680000,489,391.2,48.9,97.8,179.3
20.4,46.9,C/H:4,RURAL,ALL,33.4,Unit_Z,115,1200,300600000,120240000,60120000,120240000,1002,801.6,100.2,200.4,367.4
LON,LAT,TAXONOMY,BUILDINGS,SETTLEMENT_TYPE,OCCUPANCY_TYPE,ID_1,DWELLINGS,AREA_PER_DWELLING_SQM,COST_PER_AREA_EUR,TOTAL_REPL_COST_EUR,COST_STRUCTURAL_EUR,COST_NONSTRUCTURAL_EUR,COST_CONTENTS_EUR,OCCUPANTS_PER_ASSET,OCCUPANTS_PER_ASSET_DAY,OCCUPANTS_PER_ASSET_NIGHT,OCCUPANTS_PER_ASSET_TRANSIT,OCCUPANTS_PER_ASSET_AVERAGE
20.1,47.3,A,35.2,BIG_CITY,Apartment,Unit_1,105.6,90,1400,158400000,79200000,47520000,31680000,264,39.6,184.8,52.8,92.4
20.1,47.3,B,12.7,BIG_CITY,Apartment,Unit_1,38.1,110,1100,57150000,28575000,17145000,11430000,95.25,14.2875,66.675,19.05,33.3375
20.1,47.3,C,8.9,BIG_CITY,Apartment,Unit_1,26.7,85,1300,40050000,20025000,12015000,8010000,66.75,10.0125,46.725,13.35,23.3625
20.1,47.3,C,5.7,BIG_CITY,Single,Unit_1,17.1,95,1380,25650000,12825000,7695000,5130000,42.75,6.4125,29.925,8.55,14.9625
19.8,47.4,A,25.6,URBAN,Apartment,Unit_2,76.8,95,1280,115200000,57600000,34560000,23040000,192,28.8,134.4,38.4,67.2
19.8,47.4,A,7.9,URBAN,Apartment,Unit_2,23.7,95,1280,35550000,17775000,10665000,7110000,59.25,8.8875,41.475,11.85,20.7375
19.8,47.4,B,23.5,RURAL,Apartment,Unit_2,70.5,120,1050,105750000,52875000,31725000,21150000,176.25,26.4375,123.375,35.25,61.6875
20.4,46.9,A,40.2,BIG_CITY,Apartment,Unit_3,120.6,90,1400,180900000,90450000,54270000,36180000,301.5,45.225,211.05,60.3,105.525
20.4,46.9,B,16.3,BIG_CITY,Apartment,Unit_3,48.9,110,1100,73350000,36675000,22005000,14670000,122.25,18.3375,85.575,24.45,42.7875
20.4,46.9,C,33.4,RURAL,Single,Unit_3,100.2,115,1200,150300000,75150000,45090000,30060000,250.5,37.575,175.35,50.1,87.675
20.1,47.3,A/H:2,35.2,BIG_CITY,Apartment,Unit_1,105.6,90,1400,158400000,79200000,47520000,31680000,264,39.6,184.8,52.8,92.4
20.1,47.3,B/HBET:2-3,12.7,BIG_CITY,Apartment,Unit_1,38.1,110,1100,57150000,28575000,17145000,11430000,95.25,14.2875,66.675,19.05,33.3375
20.1,47.3,C/HBET:2-,8.9,BIG_CITY,Apartment,Unit_1,26.7,85,1300,40050000,20025000,12015000,8010000,66.75,10.0125,46.725,13.35,23.3625
20.1,47.3,C/HBET:2-,5.7,BIG_CITY,Single,Unit_1,17.1,95,1380,25650000,12825000,7695000,5130000,42.75,6.4125,29.925,8.55,14.9625
19.8,47.4,A/H:1,25.6,URBAN,Apartment,Unit_2,76.8,95,1280,115200000,57600000,34560000,23040000,192,28.8,134.4,38.4,67.2
19.8,47.4,A/H:1,7.9,URBAN,Apartment,Unit_2,23.7,95,1280,35550000,17775000,10665000,7110000,59.25,8.8875,41.475,11.85,20.7375
19.8,47.4,B/HBET:2-3,23.5,RURAL,Apartment,Unit_2,70.5,120,1050,105750000,52875000,31725000,21150000,176.25,26.4375,123.375,35.25,61.6875
20.4,46.9,A/H:2,40.2,BIG_CITY,Apartment,Unit_3,120.6,90,1400,180900000,90450000,54270000,36180000,301.5,45.225,211.05,60.3,105.525
20.4,46.9,B/HBET:2-3,16.3,BIG_CITY,Apartment,Unit_3,48.9,110,1100,73350000,36675000,22005000,14670000,122.25,18.3375,85.575,24.45,42.7875
20.4,46.9,C/HBET:2-,33.4,RURAL,Single,Unit_3,100.2,115,1200,150300000,75150000,45090000,30060000,250.5,37.575,175.35,50.1,87.675
LON,LAT,TAXONOMY,BUILDINGS,OCCUPANCY_TYPE,ID_2,AREA_PER_BUILDING_SQM,COST_PER_AREA_EUR,TOTAL_REPL_COST_EUR,COST_STRUCTURAL_EUR,COST_NONSTRUCTURAL_EUR,COST_CONTENTS_EUR,OCCUPANTS_PER_ASSET,OCCUPANTS_PER_ASSET_DAY,OCCUPANTS_PER_ASSET_NIGHT,OCCUPANTS_PER_ASSET_TRANSIT,OCCUPANTS_PER_ASSET_AVERAGE
20.6,46.8,A,38.72,Offices,Unit_A,150,1400,348480000,139392000,69696000,139392000,1161.6,929.28,116.16,232.32,425.92
20.6,46.8,B,13.97,Offices,Unit_A,200,1300,125730000,50292000,25146000,50292000,419.1,335.28,41.91,83.82,153.67
20.6,46.8,B,9.79,Hotels,Unit_A,500,1200,88110000,35244000,17622000,35244000,293.7,234.96,29.37,58.74,107.69
20.6,46.8,C,6.27,Trade,Unit_A,300,1100,56430000,22572000,11286000,22572000,188.1,150.48,18.81,37.62,68.97
20.3,46.9,A,28.16,Offices,Unit_B,150,1400,253440000,101376000,50688000,101376000,844.8,675.84,84.48,168.96,309.76
20.3,46.9,C,8.69,Trade,Unit_B,400,1500,78210000,31284000,15642000,31284000,260.7,208.56,26.07,52.14,95.59
20.3,46.9,C,25.85,Offices,Unit_B,250,1350,232650000,93060000,46530000,93060000,775.5,620.4,77.55,155.1,284.35
20.9,46.4,A,44.22,Offices,Unit_C,150,1400,397980000,159192000,79596000,159192000,1326.6,1061.28,132.66,265.32,486.42
20.9,46.4,B,17.93,Hotels,Unit_C,500,1200,161370000,64548000,32274000,64548000,537.9,430.32,53.79,107.58,197.23
20.9,46.4,C,36.74,Trade,Unit_C,300,1100,330660000,132264000,66132000,132264000,1102.2,881.76,110.22,220.44,404.14
20.6,46.8,A/H:4,38.72,Offices,Unit_A,150,1400,348480000,139392000,69696000,139392000,1161.6,929.28,116.16,232.32,425.92
20.6,46.8,B/H:3,13.97,Offices,Unit_A,200,1300,125730000,50292000,25146000,50292000,419.1,335.28,41.91,83.82,153.67
20.6,46.8,B/HBET:4-6,9.79,Hotels,Unit_A,500,1200,88110000,35244000,17622000,35244000,293.7,234.96,29.37,58.74,107.69
20.6,46.8,C/H:2,6.27,Trade,Unit_A,300,1100,56430000,22572000,11286000,22572000,188.1,150.48,18.81,37.62,68.97
20.3,46.9,A/H:4,28.16,Offices,Unit_B,150,1400,253440000,101376000,50688000,101376000,844.8,675.84,84.48,168.96,309.76
20.3,46.9,C/H:2,8.69,Trade,Unit_B,400,1500,78210000,31284000,15642000,31284000,260.7,208.56,26.07,52.14,95.59
20.3,46.9,C/HBET:2-3,25.85,Offices,Unit_B,250,1350,232650000,93060000,46530000,93060000,775.5,620.4,77.55,155.1,284.35
20.9,46.4,A/H:4,44.22,Offices,Unit_C,150,1400,397980000,159192000,79596000,159192000,1326.6,1061.28,132.66,265.32,486.42
20.9,46.4,B/HBET:4-6,17.93,Hotels,Unit_C,500,1200,161370000,64548000,32274000,64548000,537.9,430.32,53.79,107.58,197.23
20.9,46.4,C/H:2,36.74,Trade,Unit_C,300,1100,330660000,132264000,66132000,132264000,1102.2,881.76,110.22,220.44,404.14
entity_names,occupancy_names,Data_Unit_ID,building_class_name,settlement_type,occupancy_subtype,proportions,census_people_per_building,total_cost_per_building
Entity_1,residential,Unit_1,A,BIG_CITY,Apartment,0.5632,7.5,378000
Entity_1,residential,Unit_1,B,BIG_CITY,Apartment,0.2032,7.5,363000
Entity_1,residential,Unit_1,C,BIG_CITY,Apartment,0.1424,7.5,331500
Entity_1,residential,Unit_1,C,BIG_CITY,Single,0.0912,7.5,393300
Entity_1,residential,Unit_2,A,URBAN,Apartment,0.587719298,7.5,364800
Entity_1,residential,Unit_2,B,RURAL,Apartment,0.412280702,7.5,378000
Entity_1,residential,Unit_3,A,BIG_CITY,Apartment,0.447163515,7.5,378000
Entity_1,residential,Unit_3,B,BIG_CITY,Apartment,0.18131257,7.5,363000
Entity_1,residential,Unit_3,C,RURAL,Single,0.371523915,7.5,414000
Entity_1,residential,residential_FILLER,A,BIG_CITY,Apartment,0.360076409,7.5,378000
Entity_1,residential,residential_FILLER,A,URBAN,Apartment,0.159980898,7.5,364800
Entity_1,residential,residential_FILLER,B,BIG_CITY,Apartment,0.138490926,7.5,363000
Entity_1,residential,residential_FILLER,B,RURAL,Apartment,0.112225406,7.5,378000
Entity_1,residential,residential_FILLER,C,BIG_CITY,Apartment,0.042502388,7.5,331500
Entity_1,residential,residential_FILLER,C,BIG_CITY,Single,0.02722063,7.5,393300
Entity_1,residential,residential_FILLER,C,RURAL,Single,0.159503343,7.5,414000
Entity_1,commercial,Unit_X,A,BIG_CITY,ALL,0.5632,30,126000
Entity_1,commercial,Unit_X,B,RURAL,ALL,0.2032,30,126000
Entity_1,commercial,Unit_X,C,BIG_CITY,ALL,0.2336,30,116551.3699
Entity_1,commercial,Unit_Y,A,RURAL,ALL,0.449122807,30,107800
Entity_1,commercial,Unit_Y,A,URBAN,ALL,0.138596491,30,121600
Entity_1,commercial,Unit_Y,B,RURAL,ALL,0.412280702,30,126000
Entity_1,commercial,Unit_Z,A,BIG_CITY,ALL,0.447163515,30,126000
Entity_1,commercial,Unit_Z,B,BIG_CITY,ALL,0.18131257,30,121000
Entity_1,commercial,Unit_Z,C,RURAL,ALL,0.371523915,30,138000
Entity_1,commercial,commercial_FILLER,A,BIG_CITY,ALL,0.360076409,30,126000
Entity_1,commercial,commercial_FILLER,A,RURAL,ALL,0.122254059,30,107800
Entity_1,commercial,commercial_FILLER,A,URBAN,ALL,0.037726839,30,121600
Entity_1,commercial,commercial_FILLER,B,BIG_CITY,ALL,0.077841452,30,121000
Entity_1,commercial,commercial_FILLER,B,RURAL,ALL,0.172874881,30,126000
Entity_1,commercial,commercial_FILLER,C,BIG_CITY,ALL,0.069723018,30,116551.3699
Entity_1,commercial,commercial_FILLER,C,RURAL,ALL,0.159503343,30,138000
Entity_2,commercial,Unit_A,A,ALL,Offices,0.5632,30,210000
Entity_2,commercial,Unit_A,B,ALL,Offices,0.2032,30,260000
Entity_2,commercial,Unit_A,B,ALL,Hotels,0.1424,30,600000
Entity_2,commercial,Unit_A,C,ALL,Trade,0.0912,30,330000
Entity_2,commercial,Unit_B,A,ALL,Offices,0.449122807,30,210000
Entity_2,commercial,Unit_B,C,ALL,Trade,0.138596491,30,600000
Entity_2,commercial,Unit_B,C,ALL,Offices,0.412280702,30,337500
Entity_2,commercial,Unit_C,A,ALL,Offices,0.447163515,30,210000
Entity_2,commercial,Unit_C,B,ALL,Hotels,0.18131257,30,600000
Entity_2,commercial,Unit_C,C,ALL,Trade,0.371523915,30,330000
Entity_2,commercial,commercial_FILLER,A,ALL,Offices,0.48233047,30,210000
Entity_2,commercial,commercial_FILLER,B,ALL,Hotels,0.12034384,30,600000
Entity_2,commercial,commercial_FILLER,B,ALL,Offices,0.06064947,30,260000
Entity_2,commercial,commercial_FILLER,C,ALL,Offices,0.11222541,30,337500
Entity_2,commercial,commercial_FILLER,C,ALL,Trade,0.22445081,30,375382.9787
entity_names,occupancy_names,Data_Unit_ID,building_class_name,settlement_type,occupancy_subtype,proportions,census_people_per_building,total_cost_per_building,storeys_min,storeys_max
Entity_1,residential,Unit_1,A/H:2,BIG_CITY,Apartment,0.5632,7.5,378000,2,2
Entity_1,residential,Unit_1,B/HBET:2-3,BIG_CITY,Apartment,0.2032,7.5,363000,2,3
Entity_1,residential,Unit_1,C/HBET:2-,BIG_CITY,Apartment,0.1424,7.5,331500,2,9999
Entity_1,residential,Unit_1,C/HBET:2-,BIG_CITY,Single,0.0912,7.5,393300,2,9999
Entity_1,residential,Unit_2,A/H:1,URBAN,Apartment,0.587719298,7.5,364800,1,1
Entity_1,residential,Unit_2,B/HBET:2-3,RURAL,Apartment,0.412280702,7.5,378000,2,3
Entity_1,residential,Unit_3,A/H:2,BIG_CITY,Apartment,0.447163515,7.5,378000,2,2
Entity_1,residential,Unit_3,B/HBET:2-3,BIG_CITY,Apartment,0.18131257,7.5,363000,2,3
Entity_1,residential,Unit_3,C/HBET:2-,RURAL,Single,0.371523915,7.5,414000,2,9999
Entity_1,residential,residential_FILLER,A/H:2,BIG_CITY,Apartment,0.360076409,7.5,378000,2,2
Entity_1,residential,residential_FILLER,A/H:1,URBAN,Apartment,0.159980898,7.5,364800,1,1
Entity_1,residential,residential_FILLER,B/HBET:2-3,BIG_CITY,Apartment,0.138490926,7.5,363000,2,3
Entity_1,residential,residential_FILLER,B/HBET:2-3,RURAL,Apartment,0.112225406,7.5,378000,2,3
Entity_1,residential,residential_FILLER,C/HBET:2-,BIG_CITY,Apartment,0.042502388,7.5,331500,2,9999
Entity_1,residential,residential_FILLER,C/HBET:2-,BIG_CITY,Single,0.02722063,7.5,393300,2,9999
Entity_1,residential,residential_FILLER,C/HBET:2-,RURAL,Single,0.159503343,7.5,414000,2,9999
Entity_1,commercial,Unit_X,A/HBET:2-5,BIG_CITY,ALL,0.5632,30,126000,2,5
Entity_1,commercial,Unit_X,B/HBET:4-,RURAL,ALL,0.2032,30,126000,4,9999
Entity_1,commercial,Unit_X,C/H:3,BIG_CITY,ALL,0.2336,30,116551.3699,3,3
Entity_1,commercial,Unit_Y,A/HBET:2-5,RURAL,ALL,0.449122807,30,107800,2,5
Entity_1,commercial,Unit_Y,A/HBET:2-5,URBAN,ALL,0.138596491,30,121600,2,5
Entity_1,commercial,Unit_Y,B/HBET:4-,RURAL,ALL,0.412280702,30,126000,4,9999
Entity_1,commercial,Unit_Z,A/HBET:2-5,BIG_CITY,ALL,0.447163515,30,126000,2,5
Entity_1,commercial,Unit_Z,B/HBET:4-,BIG_CITY,ALL,0.18131257,30,121000,4,9999
Entity_1,commercial,Unit_Z,C/H:4,RURAL,ALL,0.371523915,30,138000,4,4
Entity_1,commercial,commercial_FILLER,A/HBET:2-5,BIG_CITY,ALL,0.360076409,30,126000,2,5
Entity_1,commercial,commercial_FILLER,A/HBET:2-5,RURAL,ALL,0.122254059,30,107800,2,5
Entity_1,commercial,commercial_FILLER,A/HBET:2-5,URBAN,ALL,0.037726839,30,121600,2,5
Entity_1,commercial,commercial_FILLER,B/HBET:4-,BIG_CITY,ALL,0.077841452,30,121000,4,9999
Entity_1,commercial,commercial_FILLER,B/HBET:4-,RURAL,ALL,0.172874881,30,126000,4,9999
Entity_1,commercial,commercial_FILLER,C/H:3,BIG_CITY,ALL,0.069723018,30,116551.3699,3,3
Entity_1,commercial,commercial_FILLER,C/H:4,RURAL,ALL,0.159503343,30,138000,4,4
Entity_2,commercial,Unit_A,A/H:4,ALL,Offices,0.5632,30,210000,4,4
Entity_2,commercial,Unit_A,B/H:3,ALL,Offices,0.2032,30,260000,3,3
Entity_2,commercial,Unit_A,B/HBET:4-6,ALL,Hotels,0.1424,30,600000,4,6
Entity_2,commercial,Unit_A,C/H:2,ALL,Trade,0.0912,30,330000,2,2
Entity_2,commercial,Unit_B,A/H:4,ALL,Offices,0.449122807,30,210000,4,4
Entity_2,commercial,Unit_B,C/H:2,ALL,Trade,0.138596491,30,600000,2,2
Entity_2,commercial,Unit_B,C/HBET:2-3,ALL,Offices,0.412280702,30,337500,2,3
Entity_2,commercial,Unit_C,A/H:4,ALL,Offices,0.447163515,30,210000,4,4
Entity_2,commercial,Unit_C,B/HBET:4-6,ALL,Hotels,0.18131257,30,600000,4,6
Entity_2,commercial,Unit_C,C/H:2,ALL,Trade,0.371523915,30,330000,2,2
Entity_2,commercial,commercial_FILLER,A/H:4,ALL,Offices,0.48233047,30,210000,4,4
Entity_2,commercial,commercial_FILLER,B/HBET:4-6,ALL,Hotels,0.12034384,30,600000,4,6
Entity_2,commercial,commercial_FILLER,B/H:3,ALL,Offices,0.06064947,30,260000,3,3
Entity_2,commercial,commercial_FILLER,C/HBET:2-3,ALL,Offices,0.11222541,30,337500,2,3
Entity_2,commercial,commercial_FILLER,C/H:2,ALL,Trade,0.22445081,30,375382.9787,2,2
......@@ -515,6 +515,20 @@ def test_ExposureModelESRM20(test_db):
4,
)
assert (
returned_proportions_and_properties["storeys_min"].to_numpy()[j]
== expected_results_proportions_and_properties["storeys_min"].to_numpy()[
rows_entity_occupancy
][rows_data_unit][which_in_expected]
)
assert (
returned_proportions_and_properties["storeys_max"].to_numpy()[j]
== expected_results_proportions_and_properties["storeys_max"].to_numpy()[
rows_entity_occupancy
][rows_data_unit][which_in_expected]
)
# Compare values written to the database with expected ones
which_in_db_query = numpy.where(
numpy.logical_and(
......
#!/usr/bin/env python3
# Copyright (C) 2021:
# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
import numpy
from gdeimporter.tools.buildingtaxonomy import GEMTaxonomy_v3
def test_interpret_number_storeys_individual_and_collective():
building_classes = numpy.array(
[
"CR/LFINF+CDN/HBET:4-10",
"CR/LFINF+CDN/HBET:4-10/Res",
"CR/LFINF+CDN/HBET:4-",
"CR/LFINF+CDN/HBET:-10",
"CR/LFINF+CDN/H:6",
"CR/LFINF+CDN/HAPP:5",
"CR/LFINF+CDN/HBET:4.0-10",
"CR/LFINF+CDN/HBET:-4-10",
"CR/LFINF+CDN/HBET:-",
"CR/LFINF+CDN/HBET:4-2",