Commit 4ec7c2d5 authored by Danijel Schorlemmer's avatar Danijel Schorlemmer
Browse files

Added the function to write the exposure data for each building

parent 10d1f34c
Pipeline #20661 passed with stage
in 1 minute and 46 seconds
......@@ -21,6 +21,7 @@ import logging
import sqlite3
import csv
import geopandas
import numpy
from collections import namedtuple
from shapely import wkt
from pygeotile.tile import Tile
......@@ -40,8 +41,8 @@ class Database:
File path of the Spatialite extension.
Attributes:
self.database_filepath (str): Spatialite database file path.
self.spatialite_filepath (str): File path to the Spatialite extension.
database_filepath (str): Spatialite database file path.
spatialite_filepath (str): File path to the Spatialite extension.
"""
def __init__(self, database_filepath, spatialite_filepath="mod_spatialite"):
......@@ -92,8 +93,8 @@ class CoquimboDatabase(Database):
File path of the Spatialite extension.
Attributes:
self.database_filepath (str): Spatialite database file path.
self.spatialite_filepath (str): File path to the Spatialite extension.
database_filepath (str): Spatialite database file path.
spatialite_filepath (str): File path to the Spatialite extension.
"""
def __init__(self, database_filepath, spatialite_filepath="mod_spatialite"):
......@@ -108,31 +109,33 @@ class CoquimboDatabase(Database):
def create_tables(self):
"""
Creates all necessary tables in the database. These are:
Location : Stores the locations of the SARA exposure data
Asset : Stores the assets per location
Voronoi : Stores the Voronoi cells around each location
Buildings: Stores the OpenStreetMap buildings
Exposure : Stores the resulting exposure assets for each building
Location : Stores the locations of the SARA exposure data
Asset : Stores the assets per location
Voronoi : Stores the Voronoi cells around each location
Buildings: Stores the OpenStreetMap buildings
Exposure : Stores the resulting exposure assets for each building
"""
# Create table Locations
sql_statement = "CREATE TABLE Locations ("
sql_statement = "CREATE TABLE Location ("
sql_statement += "idx INTEGER PRIMARY KEY AUTOINCREMENT, "
sql_statement += "occupancy TEXT, "
sql_statement += "id INTEGER, "
sql_statement += "name TEXT)"
self.connection.execute(sql_statement)
sql_statement = "SELECT AddGeometryColumn('Locations', 'geom', 4326, 'POINT', 'XY')"
sql_statement = "SELECT AddGeometryColumn('Location', 'geom', 4326, 'POINT', 'XY')"
self.connection.execute(sql_statement)
logger.debug("Table Locations created")
# Create table Asset
sql_statement = "CREATE TABLE Assets ("
sql_statement += "location_idx INTEGER, "
sql_statement += "taxonomy TEXT, "
sql_statement += "number REAL, "
sql_statement += "structural REAL, "
sql_statement += "night REAL)"
sql_statement = "CREATE TABLE Asset ("
sql_statement += "location_idx INTEGER, "
sql_statement += "taxonomy TEXT, "
sql_statement += "number REAL, "
sql_statement += "structural REAL, "
sql_statement += "night REAL, "
sql_statement += "structural_per_building REAL, "
sql_statement += "night_per_building REAL)"
self.connection.execute(sql_statement)
logger.debug("Table Assets created")
......@@ -145,15 +148,15 @@ class CoquimboDatabase(Database):
logger.debug("Table Voronoi created")
# Create table Buildings
sql_statement = "CREATE TABLE Buildings ("
sql_statement = "CREATE TABLE Building ("
sql_statement += "idx INTEGER PRIMARY KEY AUTOINCREMENT, "
sql_statement += "location_idx INTEGER, "
sql_statement += "quadkey TEXT)"
self.connection.execute(sql_statement)
sql_statement = "SELECT AddGeometryColumn('Buildings', "
sql_statement = "SELECT AddGeometryColumn('Building', "
sql_statement += "'geom', 4326, 'MULTIPOLYGON', 'XY')"
self.connection.execute(sql_statement)
sql_statement = "SELECT AddGeometryColumn('Buildings', 'centroid', 4326, 'POINT', 'XY')"
sql_statement = "SELECT AddGeometryColumn('Building', 'centroid', 4326, 'POINT', 'XY')"
self.connection.execute(sql_statement)
logger.debug("Table Buildings created")
......@@ -182,7 +185,7 @@ class CoquimboDatabase(Database):
Index of inserted dataset (Locations.idx)
"""
sql_statement = "INSERT INTO Locations "
sql_statement = "INSERT INTO Location "
sql_statement += "(occupancy, geom, id, name) "
sql_statement += "VALUES ('%s', %s, %s, '%s')" % dataset
self.cursor.execute(sql_statement)
......@@ -204,9 +207,10 @@ class CoquimboDatabase(Database):
Index of inserted dataset (Buildings.idx)
"""
sql_statement = "INSERT INTO Assets "
sql_statement += "(location_idx, taxonomy, number, structural, night) "
sql_statement += "VALUES (%s, '%s', %s, %s, %s)" % dataset
sql_statement = "INSERT INTO Asset "
sql_statement += "(location_idx, taxonomy, number, structural, night, "
sql_statement += "structural_per_building, night_per_building) "
sql_statement += "VALUES (%s, '%s', %s, %s, %s, %f, %f)" % dataset
self.cursor.execute(sql_statement)
def insert_building(self, dataset):
......@@ -215,18 +219,34 @@ class CoquimboDatabase(Database):
Args:
dataset (tuple):
(location_index corresponsing to Locations.idx,
(location_index corresponding to Locations.idx,
quadkey of the level 18 tile of the building centroid,
building_geometry,
centroid_geometry)
"""
sql_statement = "INSERT INTO Buildings "
sql_statement = "INSERT INTO Building "
sql_statement += "(location_idx, quadkey, geom, centroid) "
sql_statement += "VALUES (%d, %s, %s, %s)" % dataset
self.cursor.execute(sql_statement)
return self.cursor.lastrowid
def insert_exposure(self, dataset):
"""
Inserts a dataset in the Exposure table.
Args:
dataset (tuple):
(building_index corresponding to Buildings.idx,
taxonomy,
number,
structural,
night)
"""
sql_statement = "INSERT INTO Exposure (building_idx, taxonomy, number, "
sql_statement += "structural, night) VALUES (%d, '%s', %f, %f, %f)" % dataset
self.cursor.execute(sql_statement)
def read_sara_exposure(self, exposure_filepath):
"""
Reads a SARA exposure file into the tables Locations and Assets.
......@@ -260,22 +280,24 @@ class CoquimboDatabase(Database):
dataset = (row[4], location, row[2], row[3])
location_idx = self.insert_location(dataset)
logger.debug("Location %d created" % location_count)
dataset = (location_idx, row[5], row[6], row[7], row[8])
self.insert_asset(dataset)
asset_count += 1
logger.debug(
"Asset %d for location %d created" % (asset_count, location_count)
)
last_longitude = row[0]
last_latitude = row[1]
else:
# Add asset to current location
dataset = (location_idx, row[5], row[6], row[7], row[8])
self.insert_asset(dataset)
asset_count += 1
logger.debug(
"Asset %d for location %d created" % (asset_count, location_count)
)
# Add asset to current location
structural_per_building = float(row[7]) / float(row[6])
night_per_building = float(row[8]) / float(row[6])
dataset = (
location_idx,
row[5],
row[6],
row[7],
row[8],
structural_per_building,
night_per_building,
)
self.insert_asset(dataset)
asset_count += 1
logger.debug("Asset %d for location %d created" % (asset_count, location_count))
self.connection.commit()
logger.info("Number of locations created: %d." % location_count)
logger.info("Number of assets created: %d." % asset_count)
......@@ -287,7 +309,7 @@ class CoquimboDatabase(Database):
"""
# Create the multipolygon of all Voronoi cells
sql_statement = "SELECT ST_AsText(ST_VoronojDiagram(ST_Collect(geom))) FROM Locations"
sql_statement = "SELECT ST_AsText(ST_VoronojDiagram(ST_Collect(geom))) FROM Location"
self.cursor.execute(sql_statement)
self.connection.commit()
fetch_result = self.cursor.fetchall()
......@@ -303,7 +325,7 @@ class CoquimboDatabase(Database):
logger.debug("Voronoi cells added to the Voronoi table.")
# Associate each Voronoi cell with its respective location
sql_statement = "SELECT idx, ST_AsText(geom) FROM Locations"
sql_statement = "SELECT idx, ST_AsText(geom) FROM Location"
self.cursor.execute(sql_statement)
locations = self.cursor.fetchall()
for location in locations:
......@@ -370,5 +392,56 @@ class CoquimboDatabase(Database):
dataset = (location_index, quadkey, building_geometry, centroid_geometry)
building_idx = self.insert_building(dataset)
self.cursor.execute(sql_statement)
logger.debug("Building %d added to location %d " % (building_idx, location_index))
logger.debug("Building %d added to location %d" % (building_idx, location_index))
self.connection.commit()
def classify_buildings(self):
"""
Selects all buildings per location (within its Voronoi cell) and assigns
each building proportionally (scaled down to one building) to the assets
of the location.
"""
# Loop over all SARA locations (extent defined by Voronoi cells)
sql_statement = "SELECT idx FROM Location"
self.cursor.execute(sql_statement)
locations = self.cursor.fetchall()
for location in locations:
# Retrieve all assets at the given location
sql_statement = "SELECT taxonomy, number, structural, night, "
sql_statement += "structural_per_building, night_per_building FROM Asset "
sql_statement += "WHERE location_idx = %d" % location[0]
self.cursor.execute(sql_statement)
assets = self.cursor.fetchall()
# Extract exposure values (structural, night)
taxonomies = numpy.array(assets)[:, 0]
numbers = numpy.array(assets)[:, 1].astype(numpy.float)
exposure_values = numpy.asarray(assets)[:, 2:].astype(numpy.float)
# Calculate the proportions of building numbers per taxonomy
number_buildings_per_location = numbers.sum()
proportions = numbers / number_buildings_per_location
logger.debug("Exposure values computed for location %d" % location[0])
# Select all buildings in the Voronoi cell for the current location
sql_statement = "SELECT idx FROM Building WHERE location_idx = %d" % location[0]
self.cursor.execute(sql_statement)
building_indices = self.cursor.fetchall()
for building_index in building_indices:
# Write exposure data for the building
for counter in range(taxonomies.shape[0]):
dataset = (
building_index[0],
taxonomies[counter],
proportions[counter],
exposure_values[counter, 2] * proportions[counter],
exposure_values[counter, 3] * proportions[counter],
)
self.insert_exposure(dataset)
logger.debug(
"Exposure values added for building %d at location %d"
% (building_index[0], location[0])
)
self.cursor.execute(sql_statement)
self.connection.commit()
......@@ -92,6 +92,7 @@ def main():
db.read_sara_exposure(exposure_filepath)
db.add_voronoi_cells()
db.add_buildings(buildings_filepath)
db.classify_buildings()
logger.info("Exposure model created.")
else:
logger.warning("Command not recognized. Exiting ...")
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment