From ff3a65fc7260582b64064368ec8752594bc9a8d5 Mon Sep 17 00:00:00 2001 From: shinde Date: Mon, 13 Jun 2022 11:54:52 +0200 Subject: [PATCH] Added additional type for basement presence --- exposurejapan/commercial.py | 112 ++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/exposurejapan/commercial.py b/exposurejapan/commercial.py index 488d188..bbd0c18 100644 --- a/exposurejapan/commercial.py +++ b/exposurejapan/commercial.py @@ -926,6 +926,114 @@ class CommercialAggregatedExposure(SpatialiteDatabase): "main usage and total floor area (in square meters)" ) + def fix_mismatch_total_numbers_basement_presence(self): + """ + Fixes the mismatch of `total` number of buildings between the dataset of construction + material and basement presence. Considering the `number_building` coming from the + dataset of construction material as the true or real value, a new basement presence type + is created called `difference` with `basement_presence_id = 3`. This type is the + difference of the numbers between `total` construction material and sum of all types for + basement presence. This new type with its value is inserted into the `BuildingNumber` + table in query `T`. + + The innermost query `BP_PROP` calculates the proportion of the sum of number of + buildings to the `total` number of buildings. The sum is calculated in query `BP` by + taking type of basement presence as not equal to `total` + (i.e. basement_presence_id != 0) and main usage type as not `total` + (i.e. main_usage_id != 0) and the `total` number of buildings are selected in query + `BP_TOT` by keeping the type of basement presence as `total` + (i.e. basement_presence_id = 0) and the main usage type as `total` + (i.e. main_usage_id = 0). + + The query `BP_PROP` is joined with the query `C` to calculate the number of buildings + obtained from multiplying the proportion from query `BP_PROP` to the `total` number + of buildings for construction material in query `C`. + + The outermost query `T` selects all attributes to be inserted in the + `BuildingNumber` table for the `difference` basement presence type. The number + of buildings selected are the difference of the `total` for basement presence and + the `bp_number_building` from the earlier query. + """ + + # Insert a new basement presence type called `difference`, its corresponding + # building attributes and number_building into the `BuildingNumber` table + sql_statement = """ + INSERT INTO BuildingNumber + ( + district_id, + main_usage_id, + construction_material_id, + basement_presence_id, + eq_resistance_code_presence_id, + total_floor_area_id, + number_building + ) + SELECT T.district_id, + T.main_usage_id, + 0 AS construction_material_id, + 3 AS basement_presence_id, + T.eq_resistance_code_presence_id, + T.total_floor_area_id, + (bp_number_building - sum_number_building_bp) AS difference_number_building + FROM + ( + SELECT *, + (BP_PROP.bp_prop_value * C.number_building) AS bp_number_building + FROM + ( + SELECT *, + (BP.sum_number_building_bp / BP_TOT.number_building) AS bp_prop_value + FROM + ( + SELECT *, + sum(number_building) AS sum_number_building_bp + FROM BuildingNumber + WHERE + ( + basement_presence_id != 0 + AND construction_material_id = -1 + AND eq_resistance_code_presence_id = -1 + AND total_floor_area_id = -1 + AND main_usage_id != 0 + ) + GROUP BY main_usage_id, district_id + ) AS BP + INNER JOIN + ( + SELECT * + FROM BuildingNumber + WHERE + ( + basement_presence_id = 0 + AND construction_material_id = -1 + AND eq_resistance_code_presence_id = -1 + AND total_floor_area_id = -1 + AND main_usage_id = 0 + ) + ) AS BP_TOT + ON BP.district_id = BP_TOT.district_id + ) AS BP_PROP + INNER JOIN + ( + SELECT * + FROM BuildingNumber + WHERE + ( + construction_material_id = 0 + AND main_usage_id = 0 + ) + ) AS C + ON BP_PROP.district_id = C.district_id + ) AS T + """ + logger.debug(sql_statement) + self.cursor.execute(sql_statement) + self.connection.commit() + logger.info( + "Fixed total numbers mismatch for construction material " + "and basement presence datasets" + ) + def import_exposure_data( self, building_numbers_main_usage_construction_material_city_filepath, @@ -1034,6 +1142,10 @@ class CommercialAggregatedExposure(SpatialiteDatabase): # and total floor area (in square meters) and update the BuildingNumber table self.calculate_building_numbers_frequency_distributions_for_total_floor_area() + # Fix the mismatch of total numbers for `main usage and basement presence` + # and `main usage and construction material` + self.fix_mismatch_total_numbers_basement_presence() + # Add the main usage types to the database for main_usage_id, main_usage in enumerate(main_usage_list): self.insert_main_usage(main_usage_id, main_usage) -- GitLab