Skip to content
Snippets Groups Projects
Commit dd95ab73 authored by Laurens Oostwegel's avatar Laurens Oostwegel Committed by Laurens Oostwegel
Browse files

Change the computation of building properties from building average to per square meter

parent 109911cd
No related branches found
No related tags found
1 merge request!23Resolve "Add the average floorspace and stories to the taxonomy"
Pipeline #64531 passed
......@@ -8,6 +8,7 @@ from OpenQuake exposure files.
| Version | Description |
|---------|-------------------------------------------------------------------------------------------------------|
| 1.0.0 | Code used for the 2023.01 exposure data release. First published version of the exposure-initializer. |
| 2.0.0 | Scaling of floor-space area for each building is used. |
## How to install
First, the package registry needs to be added to the pip index urls, so the package (and its dependencies) can be found.
......
......@@ -175,9 +175,10 @@ class ExposureInitializer:
asset (dict):
Asset to be added to `asset_dict` under the key `taxonomy_id`.
Each asset contains of:
number : number of buildings or proportion of building
structural: structural costs of the asset
night : nighttime population of the asset
number : number of buildings or proportion of building
structural : structural costs of the asset
night : nighttime population of the asset
floorspace (optional): average floorspace of the asset
Returns:
The asset dictionary with the new asset added
......@@ -189,10 +190,14 @@ class ExposureInitializer:
"structural": asset["structural"],
"night": asset["night"],
}
if "floorspace" in asset:
asset_dict[taxonomy_id]["floorspace"] = asset["floorspace"]
else:
asset_dict[taxonomy_id]["number"] += asset["number"]
asset_dict[taxonomy_id]["structural"] += asset["structural"]
asset_dict[taxonomy_id]["night"] += asset["night"]
if "floorspace" in asset_dict[taxonomy_id]:
asset_dict[taxonomy_id]["floorspace"] += asset["floorspace"]
return asset_dict
def process_district(self, boundary_id, country_iso_code, asset_dict):
......@@ -270,17 +275,21 @@ class ExposureInitializer:
if entity_id is None:
entity_id = self.exposure_db.insert_reference_entity(quadkey, country_iso_code)
# Add the respective assets by proportion of built area to `AssetReference`
# Add the respective assets by proportion of built area to `AssetReference`. The
# structural and night values per square meter are added, if the total built
# area is known
proportion = built_area_size / total_built_area
reference_assets = [
[
entity_id,
taxonomy_id,
float(value["number"]) * proportion,
float(value["structural"]) * proportion,
float(value["night"]) * proportion,
asset["number"] * proportion,
asset["structural"] * proportion,
self.asset_value_per_sqm(asset, "structural"),
asset["night"] * proportion,
self.asset_value_per_sqm(asset, "night"),
]
for taxonomy_id, value in asset_dict.items()
for taxonomy_id, asset in asset_dict.items()
]
self.exposure_db.insert_reference_assets(reference_assets)
self.exposure_db.connection.commit()
......@@ -343,6 +352,18 @@ class ExposureInitializer:
"structural": float(row["COST_STRUCTURAL_EUR"]),
"night": float(row["OCCUPANTS_PER_ASSET_NIGHT"]),
}
# Store the total floorspace, if it is given as a value per building
if "AREA_PER_BUILDING_SQM" in row:
asset["floorspace"] = float(row["AREA_PER_BUILDING_SQM"]) * asset["number"]
# For residential assets, the total number of dwellings and the average
# floorspace per dwelling is given. The floorspace is the multiplication of the
# two.
elif "DWELLINGS" in row and "AREA_PER_DWELLING_SQM" in row:
dwellings = float(row["DWELLINGS"])
area_per_dwelling = float(row["AREA_PER_DWELLING_SQM"])
asset["floorspace"] = dwellings * area_per_dwelling
# Store the asset in a location-based list and country-based list
asset_dict = self.add_asset_to_dict(asset_dict, taxonomy_id, asset)
country_asset_dict = self.add_asset_to_dict(
......@@ -354,22 +375,25 @@ class ExposureInitializer:
logger.info("Assign the country-average assets")
# Normalize the country-average asset distribution
sum_number = 0
for taxonomy_id, value in country_asset_dict.items():
sum_number += value["number"]
for taxonomy_id, asset in country_asset_dict.items():
sum_number += asset["number"]
# Assign the country-average asset distribution to the country assets
for taxonomy_id, value in country_asset_dict.items():
for taxonomy_id, asset in country_asset_dict.items():
sql_statement = f"""
INSERT INTO AssetCountry
(country_iso_code, taxonomy_id, number, number_normalized, structural,
structural_normalized, night, night_normalized)
structural_per_sqm, structural_normalized, night, night_per_sqm,
night_normalized)
VALUES ('{country_iso_code}',
{int(taxonomy_id)},
{float(value["number"])},
{float(value["number"]) / sum_number},
{float(value["structural"])},
{float(value["structural"]) / sum_number},
{float(value["night"])},
{float(value["night"]) / sum_number})
{asset["number"]},
{asset["number"] / sum_number},
{asset["structural"]},
{self.asset_value_per_sqm(asset, "structural")},
{asset["structural"] / sum_number},
{asset["night"]},
{self.asset_value_per_sqm(asset, "night")},
{asset["night"] / sum_number})
"""
self.exposure_db.cursor.execute(sql_statement)
self.exposure_db.connection.commit()
......@@ -395,7 +419,7 @@ class ExposureInitializer:
# Get the assets of the average building in the country
sql_statement = f"""
SELECT taxonomy_id, number, structural, night
SELECT taxonomy_id, number, structural, structural_per_sqm, night, night_per_sqm
FROM AssetCountry
WHERE country_iso_code = '{country_iso_code}'
"""
......@@ -451,11 +475,20 @@ class ExposureInitializer:
[
entity_id,
int(taxonomy_id),
float(number) * proportion,
float(structural) * proportion,
float(night) * proportion,
number * proportion,
structural * proportion,
structural_per_sqm if structural_per_sqm else "NULL",
night * proportion,
night_per_sqm if night_per_sqm else "NULL",
]
for taxonomy_id, number, structural, night in country_asset_list
for (
taxonomy_id,
number,
structural,
structural_per_sqm,
night,
night_per_sqm,
) in country_asset_list
]
self.exposure_db.insert_reference_assets(reference_assets)
self.exposure_db.connection.commit()
......@@ -499,6 +532,27 @@ class ExposureInitializer:
self.exposure_db.connection.commit()
logger.debug("Geometry entry for view %s created" % name)
@staticmethod
def asset_value_per_sqm(asset, value):
"""
Computes value per square meter of one attribute of the asset.
Args:
asset:
The asset.
value:
The value that should be divided by the floorspace (e.g. `night` /
`structural`).
Returns:
The value per square meter, or a `NULL` value if the floorspace does not exist.
"""
if "floorspace" in asset:
return asset[value] / asset["floorspace"]
else:
return "NULL"
def command_line_interface():
"""
......
......@@ -29,8 +29,8 @@ setup(
license="AGPLv3+",
install_requires=[
"numpy",
"exposurelib==1.0.0",
"taxonomylib==1.0.0",
"exposurelib>=2.0.1",
"taxonomylib>=1.1.0",
],
extras_require={
"tests": tests_require,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment