From 1ab964bd3da6909aa950ff2abbf76105716b2ad2 Mon Sep 17 00:00:00 2001
From: ds <ds@gfz-potsdam.de>
Date: Wed, 8 Feb 2023 03:18:34 +0100
Subject: [PATCH] Add the option to process all tiles in the database
 regardless of their ISO code

---
 exposurefinalizer/exposurefinalizer.py | 63 ++++++++++++++++++++------
 1 file changed, 50 insertions(+), 13 deletions(-)

diff --git a/exposurefinalizer/exposurefinalizer.py b/exposurefinalizer/exposurefinalizer.py
index 9c66eb5..b0528fe 100644
--- a/exposurefinalizer/exposurefinalizer.py
+++ b/exposurefinalizer/exposurefinalizer.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 
-# Copyright (C) 2022:
+# Copyright (C) 2022-2023:
 #   Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
 #
 # This program is free software: you can redistribute it and/or modify it
@@ -135,6 +135,18 @@ class ExposureFinalizer:
                 logger.info(f"{num_buildings + 1} buildings retrieved")
         logger.info("All buildings retrieved")
 
+    def get_all_country_iso_codes(self):
+        """
+        Retrieves a list of all country ISO codes of all tiles in the database.
+
+        Returns:
+            List of country ISO codes.
+        """
+
+        sql_statement = f"SELECT DISTINCT country_iso_code FROM {self.exposure_db.tile_view}"
+        self.exposure_db.cursor.execute(sql_statement)
+        return self.exposure_db.cursor.fetchall()
+
     def process_country(self, country_iso_code):
         """
         Create the final exposure values (entities and assets) for the given country. This is
@@ -442,13 +454,19 @@ def command_line_interface():
     command defining what type of database will be used:
         `local` : Exposure will be generated in a local SpatiaLite database.
         `server`: Exposure will be generated in a server-based PostGIS database.
-    The command require these mandatory options:
+    The commands require these mandatory options:
         `-e`: Filepath of the exposure database (`local` only).
         `-c`: Config file (INI-type) describing the access to the tile database. Also needed
               for `local` as the boundaries and tiles will be copied over to the local
               SpatiaLite database.
         `-o`: Filepath of the occupancy map (for simplifying occupancy types).
+    The `server` command requires the following option:
         `-i`: ISO 3166-1 alpha-3 code of the country for which the exposure is to be imported.
+    The `-i` option is optional for the `local` command. If given, buildings for the given
+    country ISO code will be imported and all tiles of that country will be processed. If not
+    given, Finalizer will process all tiles in the local database assuming that all buildings
+    are present (such a file can be created with exposure-share using the `baseline` command
+    and the `-b` option).
     """
 
     # Create the argument parser
@@ -468,13 +486,6 @@ def command_line_interface():
         type=str,
         help="Filepath to the occupancy-map file",
     )
-    parser_shared.add_argument(
-        "-i",
-        "--country-iso-code",
-        required=True,
-        type=str,
-        help="ISO 3166-1 alpha-3 code of the country",
-    )
 
     # Prepare for subparsers
     subparsers = parser.add_subparsers(help="sub-command help", dest="command")
@@ -489,10 +500,24 @@ def command_line_interface():
         type=str,
         help="Filepath to the SpatiaLite exposure database",
     )
+    parser_local.add_argument(
+        "-i",
+        "--country-iso-code",
+        required=False,
+        type=str,
+        help="ISO 3166-1 alpha-3 code of the country",
+    )
     # Create the parser for the 'server' command
-    subparsers.add_parser(
+    parser_server = subparsers.add_parser(
         "server", help="Run builder on a server-based PostGIS database", parents=[parser_shared]
     )
+    parser_server.add_argument(
+        "-i",
+        "--country-iso-code",
+        required=True,
+        type=str,
+        help="ISO 3166-1 alpha-3 code of the country",
+    )
 
     # read arguments from command line.
     args = parser.parse_args()
@@ -536,10 +561,22 @@ def command_line_interface():
             obm_database_object,
             occupancy_map_filepath,
         )
-        if command == "local":
+        # If ISO is not given, assume the buildings are present in the database
+        if (command == "local") and (country_iso_code is not None):
             finalizer.retrieve_buildings(country_iso_code)
-        finalizer.exposure_db.remove_exposure(country_iso_code, delete_reference=False)
-        finalizer.process_country(country_iso_code)
+
+        # If all tiles are processed, identify the country ISO codes of them
+        if (command == "local") and (country_iso_code is None):
+            logger.debug("Retrieving all country ISO codes")
+            iso_codes = finalizer.get_all_country_iso_codes()
+        else:
+            # Set the given ISO code for processing
+            iso_codes = [(country_iso_code,)]
+        # Process all given countries sequentially
+        for iso_code, *_ in iso_codes:
+            logger.info(f"Processing country {iso_code}")
+            finalizer.exposure_db.remove_exposure(iso_code, delete_reference=False)
+            finalizer.process_country(iso_code)
 
         finalizer.exposure_db.commit_and_close()
     else:
-- 
GitLab