146 lines
5.3 KiB
Python
146 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""
|
|
Generated the spherical graph that can then be used to navigate.
|
|
The graph gets serialized to disk at the end of the calculation.
|
|
|
|
Examples:
|
|
Generate a graph and visualize it. Because it makes using it in search algorithms faster, we also include
|
|
the neighbor table. the also prunes by default using the *Earth2014* dataset (variant *TBI*, 1 arc-min
|
|
resolution).
|
|
|
|
.. code-block:: bash
|
|
|
|
./scripts/create_earth_graph.py 500000 earth_graph_500_km.hdf5
|
|
|
|
"""
|
|
|
|
# Standard library
|
|
from argparse import ArgumentDefaultsHelpFormatter
|
|
from argparse import ArgumentParser
|
|
import os.path
|
|
|
|
# Data set access
|
|
from pyrate.common.raster_datasets import DataSetAccess
|
|
from pyrate.common.raster_datasets import transformers_concrete
|
|
|
|
# Graph generation
|
|
from pyrate.plan.graph import create_earth_graph
|
|
from pyrate.plan.graph import min_required_frequency
|
|
|
|
# Script visualize_earth_graph
|
|
try:
|
|
from visualize_earth_graph import dump_2d_plots
|
|
except ImportError:
|
|
# add scripts folder
|
|
import sys
|
|
|
|
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
|
|
del sys
|
|
|
|
from visualize_earth_graph import dump_2d_plots
|
|
|
|
|
|
def calculate_and_save( # pylint: disable=too-many-arguments
|
|
requested_distance: float,
|
|
out_graph_file: str,
|
|
prune_land_areas: bool,
|
|
bathymetric_dataset: str,
|
|
generate_neighbors: bool,
|
|
dump_plots: bool,
|
|
out_visualization_directory: str,
|
|
) -> None:
|
|
"""Calculates and saves the graph with the given node distance while performing some logging.
|
|
|
|
Args:
|
|
requested_distance: the maximum distance between two neighboring nodes, in meters
|
|
out_graph_file: the target file where to save the graph to; usually end in ``.hdf5``
|
|
prune_land_areas: whether to prune by land areas
|
|
bathymetric_dataset: the path to the bathymetric dataset if parameter ``prune_land_areas`` is set to
|
|
``True``; e.g. the Earth2014 dataset with depth in meters
|
|
generate_neighbors: whether to generate and serialize all neighbors too
|
|
dump_plots: whether to dump all plots with the default config using
|
|
:mod:`scripts.visualize_earth_graph` after completing the graph generation
|
|
out_visualization_directory: the target directory (may not yet exist) where to save the visualizations
|
|
to if parameter ``dump_plots`` is set to ``True``
|
|
"""
|
|
|
|
print("Starting generation of earth graph")
|
|
graph = create_earth_graph(min_required_frequency(requested_distance, in_meters=True))
|
|
|
|
if prune_land_areas:
|
|
print("Pruning graph")
|
|
|
|
# generate the "keep condition" and then remove the property afterwards
|
|
data_set = DataSetAccess(bathymetric_dataset)
|
|
mode = transformers_concrete.BathymetricTransformer.Modes.FRACTION_NAVIGABLE
|
|
graph.append_properties(
|
|
[transformers_concrete.BathymetricTransformer(data_set, [mode])], show_progress=True
|
|
)
|
|
# keep all nodes that have more than 0% (i.e. that have any) navigable locations
|
|
keep_condition = graph.node_properties[mode.column_name] >= 0.0
|
|
graph.clear_node_properties()
|
|
|
|
graph.prune_nodes(keep_condition.to_numpy())
|
|
|
|
if generate_neighbors:
|
|
print("Generating neighbor table")
|
|
_ = graph.neighbors
|
|
|
|
print("Completed generation of earth graph")
|
|
|
|
print(f'Serializing to disk: "{out_graph_file}"')
|
|
os.makedirs(os.path.dirname(out_graph_file) or ".", exist_ok=True)
|
|
graph.to_disk(out_graph_file)
|
|
|
|
if dump_plots:
|
|
print(f"Dumping visualizations: {out_visualization_directory}")
|
|
dump_2d_plots(graph, out_visualization_directory)
|
|
|
|
|
|
def _main() -> None:
|
|
"""The main function."""
|
|
parser = ArgumentParser(
|
|
description="Create and serialize a graph of the earth. "
|
|
"Optionally perform pruning of land area, neighbor discovery and "
|
|
"dumping of visualizations.",
|
|
formatter_class=ArgumentDefaultsHelpFormatter,
|
|
)
|
|
parser.add_argument("requested_distance", type=float, help="The max. distance between nodes in meters")
|
|
parser.add_argument("out_graph_file", type=str)
|
|
parser.add_argument("--prune_land_areas", type=bool, default=True)
|
|
parser.add_argument(
|
|
"--bathymetric_dataset",
|
|
type=str,
|
|
default="../data/topography/earth2014/Earth2014.TBI2014.1min.geod.geo.tif",
|
|
)
|
|
parser.add_argument("--generate_neighbors", type=bool, default=True)
|
|
parser.add_argument("--dump_plots", type=bool, default=True)
|
|
parser.add_argument(
|
|
"--visualization_directory",
|
|
type=str,
|
|
default=None,
|
|
help='default: "dirname(out_graph_file)/visualization/"',
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
out_visualization_directory = (
|
|
args.visualization_directory
|
|
if args.visualization_directory is not None
|
|
else os.path.join(os.path.dirname(args.out_graph_file), "visualization")
|
|
)
|
|
|
|
calculate_and_save(
|
|
requested_distance=args.requested_distance,
|
|
out_graph_file=args.out_graph_file,
|
|
prune_land_areas=args.prune_land_areas,
|
|
bathymetric_dataset=args.bathymetric_dataset,
|
|
generate_neighbors=args.generate_neighbors,
|
|
dump_plots=args.dump_plots,
|
|
out_visualization_directory=out_visualization_directory,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
_main()
|