Skip to content
Snippets Groups Projects

Resolve "Add the functionality to aggregate over tiles for the tile export"

All threads resolved!
@@ -34,28 +34,32 @@ def command_line_interface():
"""
Command-line interface of the exposure-share program. The first command-line option is the
command defining what type of extract will be created:
`full`: Full exposure will be extracted. This includes level-18 tile entities and
building entities.
`tile`: Exposure will be extracted at level-18 quad-tree tiles by aggregating all
entities (`building` and `residual`) within each tile.
The command require these mandatory options:
`full`: Full exposure will be extracted. This includes level-18 tile entities
and building entities.
`tile`: Exposure will be extracted at level-18 Quadtree tiles by aggregating
all entities (`building` and `residual`) within each tile.
`aggregated`: Exposure will be extracted and the aggregated to a multi-resolution
Quadtree grid by aggregating all entities (`building` and `residual`)
such that each tile contains at least a minimum number of buildings as
specified by `-b`. The aggregation is stopped at a minimum zoom level
specified by `-z`.
`aggregate-only`: Same as `aggregated` but without the extraction from the server.
All commands require this mandatory option:
`-e`: Filepath of the exposure database.
The commands `full`, `tile`, and `aggregated` require these mandatory options:
`-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.
`-i`: ISO 3166-1 alpha-3 code of the country for which the exposure is to be imported.
The commands `aggregated` and `aggregate-only` offer additionally these options:
`-b`: Minimum number of buildings per tile below which the tile will be aggregated with
its neighbors into a parent tile (optional, default: 10).
+1
`-z`: Minimum zoom level at which the aggregation stops (optional, default: 12).
"""
# Create the argument parser
parser = argparse.ArgumentParser(description="Exposure-Share")
parser_shared = argparse.ArgumentParser(add_help=False)
parser_shared.add_argument(
"-i",
"--country-iso-code",
required=True,
type=str,
help="ISO 3166-1 alpha-3 code of the country",
)
parser_shared.add_argument(
"-e",
"--exposure-database",
@@ -63,13 +67,39 @@ def command_line_interface():
type=str,
help="Filepath to the SpatiaLite exposure database",
)
parser_shared.add_argument(
parser_download_shared = argparse.ArgumentParser(add_help=False)
parser_download_shared.add_argument(
"-i",
"--country-iso-code",
required=True,
type=str,
help="ISO 3166-1 alpha-3 code of the country",
)
parser_download_shared.add_argument(
"-c",
"--config-file",
required=True,
type=str,
help="Filepath of the config file for accessing the Tiles database",
)
parser_aggregate_shared = argparse.ArgumentParser(add_help=False)
parser_aggregate_shared.add_argument(
"-b",
"--min-number-buildings",
required=False,
default=10,
type=float,
help="Minimum number of buildings per tile below which the tile will be aggregated "
+ "with its neighbors into a parent tile.",
)
parser_aggregate_shared.add_argument(
"-z",
"--min-zoom-level",
required=False,
default=12,
type=int,
help="Minimum zoom level at which the aggregation stops.",
)
# Prepare for subparsers
subparsers = parser.add_subparsers(help="sub-command help", dest="command")
@@ -78,46 +108,82 @@ def command_line_interface():
"full",
help="Full exposure will be extracted. "
+ "This includes level-18 tile entities and building entities.",
parents=[parser_shared],
parents=[parser_shared, parser_download_shared],
)
# Create the parser for the 'tile' command
subparsers.add_parser(
"tile",
help="Exposure will be extracted at level-18 quad-tree tiles "
help="Exposure will be extracted at level-18 Quadtree tiles "
+ "by aggregating all entities (`building` and `residual`) within each tile.",
parents=[parser_shared],
parents=[parser_shared, parser_download_shared],
)
subparsers.add_parser(
"aggregated",
help="Exposure will be extracted at Quadtree tiles between level 18 and a minimum zoom "
+ "level defined by `-z` so that each tile contains at least a minimum number of "
+ "buildings defined by `-b`. Below the minimum zoom level, tiles will not be further "
+ "aggregated, even if they contain fewer buildings than defined by `-b`.",
parents=[parser_shared, parser_download_shared, parser_aggregate_shared],
)
subparsers.add_parser(
"aggregate-only",
help="Exposure will be aggregated on tiles between level 18 (or smaller depending on "
+ "the data) and a minimum zoom level defined by `-z` so that each tile contains at "
+ "least a minimum number of buildings defined by `-b`. Below the minimum zoom level, "
+ "tiles will not be further aggregated, even if they contain fewer buildings than "
+ "defined by `-b`.",
parents=[parser_shared, parser_aggregate_shared],
)
# Read arguments from command line.
args = parser.parse_args()
postgis_config = configparser.ConfigParser()
postgis_config.read(args.config_file)
# Initialize database
output_database_object = SpatiaLiteExposure(args.exposure_database)
output_database_object.connect()
output_database_object.create_tables()
exposure_source_db_config = dict(postgis_config["Exposure"])
obm_source_db_config = dict(postgis_config["OBM"])
# Check options
if (args.command == "aggregated") or (args.command == "aggregate-only"):
if args.min_number_buildings <= 0:
raise ValueError("Minimum number of buildings must be larger than 0")
if (args.min_zoom_level > 17) or (args.min_zoom_level < 1):
raise ValueError("Minimum zoom level must be in the range from 1 to 17")
start_time = datetime.datetime.now()
logger.info("Start time: %s" % start_time)
if args.command == "full":
output_database_object.import_from_postgis(
exposure_source_db_config,
obm_source_db_config,
country_iso_code=args.country_iso_code,
copy_buildings=False,
)
elif args.command == "tile":
output_database_object.import_tile_exposure_from_postgis(
exposure_source_db_config, args.country_iso_code
)
# Initialize database
output_database_object = SpatiaLiteExposure(args.exposure_database)
output_database_object.connect()
if not (args.command == "aggregate-only"):
postgis_config = configparser.ConfigParser()
postgis_config.read(args.config_file)
exposure_source_db_config = dict(postgis_config["Exposure"])
obm_source_db_config = dict(postgis_config["OBM"])
output_database_object.create_tables()
if args.command == "full":
output_database_object.import_from_postgis(
exposure_source_db_config,
obm_source_db_config,
country_iso_code=args.country_iso_code,
copy_buildings=False,
)
elif args.command == "tile":
output_database_object.import_tile_exposure_from_postgis(
exposure_source_db_config, args.country_iso_code
)
elif args.command == "aggregated":
output_database_object.import_tile_exposure_from_postgis(
exposure_source_db_config, args.country_iso_code
)
output_database_object.aggregate_exposure_entities(
min_number_buildings=args.min_number_buildings,
min_zoom_level=args.min_zoom_level,
)
else:
raise ValueError(f"Unknown command `{args.command}`")
else:
raise ValueError(f"Unknown option `{args.command}`")
output_database_object.aggregate_exposure_entities(
min_number_buildings=args.min_number_buildings,
min_zoom_level=args.min_zoom_level,
)
logger.info("Execution time: %s" % (datetime.datetime.now() - start_time))
Loading