cars 1.0.0rc3__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cars/__init__.py +74 -0
- cars/applications/__init__.py +40 -0
- cars/applications/application.py +117 -0
- cars/applications/application_constants.py +29 -0
- cars/applications/application_template.py +146 -0
- cars/applications/auxiliary_filling/__init__.py +29 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
- cars/applications/dem_generation/__init__.py +30 -0
- cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
- cars/applications/dem_generation/bulldozer_config/base_config.yaml +46 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
- cars/applications/dem_generation/bulldozer_memory.py +55 -0
- cars/applications/dem_generation/dem_generation_algo.py +107 -0
- cars/applications/dem_generation/dem_generation_constants.py +32 -0
- cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
- cars/applications/dense_match_filling/__init__.py +30 -0
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
- cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
- cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
- cars/applications/dense_match_filling/zero_padding_app.py +302 -0
- cars/applications/dense_matching/__init__.py +30 -0
- cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-313-x86_64-linux-gnu.so +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
- cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
- cars/applications/dense_matching/cpp/meson.build +9 -0
- cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
- cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
- cars/applications/dense_matching/dense_matching_algo.py +401 -0
- cars/applications/dense_matching/dense_matching_constants.py +89 -0
- cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
- cars/applications/dense_matching/disparity_grid_algo.py +597 -0
- cars/applications/dense_matching/loaders/__init__.py +23 -0
- cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
- cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
- cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
- cars/applications/dsm_filling/__init__.py +32 -0
- cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
- cars/applications/dsm_filling/border_interpolation_app.py +278 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
- cars/applications/dsm_merging/__init__.py +28 -0
- cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
- cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
- cars/applications/grid_correction/__init__.py +30 -0
- cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
- cars/applications/grid_correction/grid_correction_app.py +557 -0
- cars/applications/grid_generation/__init__.py +30 -0
- cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
- cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
- cars/applications/grid_generation/grid_generation_algo.py +388 -0
- cars/applications/grid_generation/grid_generation_constants.py +46 -0
- cars/applications/grid_generation/transform_grid.py +88 -0
- cars/applications/ground_truth_reprojection/__init__.py +30 -0
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
- cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
- cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
- cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
- cars/applications/rasterization/__init__.py +30 -0
- cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
- cars/applications/rasterization/rasterization_algo.py +534 -0
- cars/applications/rasterization/rasterization_constants.py +38 -0
- cars/applications/rasterization/rasterization_wrappers.py +639 -0
- cars/applications/rasterization/simple_gaussian_app.py +1152 -0
- cars/applications/resampling/__init__.py +28 -0
- cars/applications/resampling/abstract_resampling_app.py +187 -0
- cars/applications/resampling/bicubic_resampling_app.py +760 -0
- cars/applications/resampling/resampling_algo.py +590 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sensors_subsampling/__init__.py +32 -0
- cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
- cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
- cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
- cars/applications/sparse_matching/sift_app.py +724 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
- cars/applications/triangulation/__init__.py +32 -0
- cars/applications/triangulation/abstract_triangulation_app.py +227 -0
- cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +371 -0
- cars/applications/triangulation/triangulation_constants.py +38 -0
- cars/applications/triangulation/triangulation_wrappers.py +259 -0
- cars/bundleadjustment.py +750 -0
- cars/cars.py +179 -0
- cars/conf/__init__.py +23 -0
- cars/conf/geoid/egm96.grd +0 -0
- cars/conf/geoid/egm96.grd.hdr +15 -0
- cars/conf/input_parameters.py +156 -0
- cars/conf/mask_cst.py +35 -0
- cars/core/__init__.py +23 -0
- cars/core/cars_logging.py +402 -0
- cars/core/constants.py +191 -0
- cars/core/constants_disparity.py +50 -0
- cars/core/datasets.py +140 -0
- cars/core/geometry/__init__.py +27 -0
- cars/core/geometry/abstract_geometry.py +1130 -0
- cars/core/geometry/shareloc_geometry.py +604 -0
- cars/core/inputs.py +568 -0
- cars/core/outputs.py +176 -0
- cars/core/preprocessing.py +722 -0
- cars/core/projection.py +843 -0
- cars/core/roi_tools.py +215 -0
- cars/core/tiling.py +774 -0
- cars/core/utils.py +164 -0
- cars/data_structures/__init__.py +23 -0
- cars/data_structures/cars_dataset.py +1544 -0
- cars/data_structures/cars_dict.py +74 -0
- cars/data_structures/corresponding_tiles_tools.py +186 -0
- cars/data_structures/dataframe_converter.py +185 -0
- cars/data_structures/format_transformation.py +297 -0
- cars/devibrate.py +689 -0
- cars/extractroi.py +264 -0
- cars/orchestrator/__init__.py +23 -0
- cars/orchestrator/achievement_tracker.py +125 -0
- cars/orchestrator/cluster/__init__.py +37 -0
- cars/orchestrator/cluster/abstract_cluster.py +250 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
- cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
- cars/orchestrator/cluster/dask_config/README.md +94 -0
- cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
- cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
- cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
- cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
- cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
- cars/orchestrator/cluster/local_dask_cluster.py +116 -0
- cars/orchestrator/cluster/log_wrapper.py +728 -0
- cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
- cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
- cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
- cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
- cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
- cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
- cars/orchestrator/cluster/sequential_cluster.py +139 -0
- cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
- cars/orchestrator/memory_tools.py +47 -0
- cars/orchestrator/orchestrator.py +755 -0
- cars/orchestrator/orchestrator_constants.py +29 -0
- cars/orchestrator/registry/__init__.py +23 -0
- cars/orchestrator/registry/abstract_registry.py +143 -0
- cars/orchestrator/registry/compute_registry.py +106 -0
- cars/orchestrator/registry/id_generator.py +116 -0
- cars/orchestrator/registry/replacer_registry.py +213 -0
- cars/orchestrator/registry/saver_registry.py +363 -0
- cars/orchestrator/registry/unseen_registry.py +118 -0
- cars/orchestrator/tiles_profiler.py +279 -0
- cars/pipelines/__init__.py +26 -0
- cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
- cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +1095 -0
- cars/pipelines/filling/__init__.py +26 -0
- cars/pipelines/filling/filling.py +981 -0
- cars/pipelines/formatting/__init__.py +26 -0
- cars/pipelines/formatting/formatting.py +190 -0
- cars/pipelines/merging/__init__.py +26 -0
- cars/pipelines/merging/merging.py +439 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +256 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
- cars/pipelines/parameters/application_parameters.py +72 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +349 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +435 -0
- cars/pipelines/parameters/sensor_inputs.py +859 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
- cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
- cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
- cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
- cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
- cars/pipelines/pipeline.py +119 -0
- cars/pipelines/pipeline_constants.py +38 -0
- cars/pipelines/pipeline_template.py +135 -0
- cars/pipelines/subsampling/__init__.py +26 -0
- cars/pipelines/subsampling/subsampling.py +358 -0
- cars/pipelines/surface_modeling/__init__.py +26 -0
- cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
- cars/pipelines/tie_points/__init__.py +26 -0
- cars/pipelines/tie_points/tie_points.py +536 -0
- cars/starter.py +167 -0
- cars-1.0.0rc3.dist-info/METADATA +289 -0
- cars-1.0.0rc3.dist-info/RECORD +220 -0
- cars-1.0.0rc3.dist-info/WHEEL +6 -0
- cars-1.0.0rc3.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
This module contains the output definition
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
import logging
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
from json_checker import And, Checker, Or
|
|
30
|
+
from pyproj import CRS
|
|
31
|
+
|
|
32
|
+
import cars.core.constants as cst
|
|
33
|
+
from cars.core.utils import safe_makedirs
|
|
34
|
+
from cars.pipelines.parameters import output_constants
|
|
35
|
+
from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def is_valid_epsg(epsg) -> bool:
|
|
39
|
+
"""
|
|
40
|
+
Check if the given EPSG code is valid using pyproj.
|
|
41
|
+
"""
|
|
42
|
+
if epsg is None:
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
# Try creating a CRS
|
|
47
|
+
CRS(f"EPSG:{epsg}")
|
|
48
|
+
return True
|
|
49
|
+
except Exception:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def check_output_parameters( # noqa: C901 : too complex
|
|
54
|
+
inputs, conf, scaling_coeff=None
|
|
55
|
+
):
|
|
56
|
+
"""
|
|
57
|
+
Check the output json configuration and fill in default values
|
|
58
|
+
|
|
59
|
+
:param conf: configuration of output
|
|
60
|
+
:type conf: dict
|
|
61
|
+
:param scaling_coeff: scaling factor for resolution
|
|
62
|
+
:type scaling_coeff: float
|
|
63
|
+
:param pipeline_name: name of corresponding pipeline
|
|
64
|
+
:type pipeline_name: str
|
|
65
|
+
"""
|
|
66
|
+
overloaded_conf = conf.copy()
|
|
67
|
+
out_dir = conf[output_constants.OUT_DIRECTORY]
|
|
68
|
+
out_dir = os.path.abspath(out_dir)
|
|
69
|
+
# Ensure that output directory and its subdirectories exist
|
|
70
|
+
safe_makedirs(out_dir)
|
|
71
|
+
|
|
72
|
+
# Overload some parameters
|
|
73
|
+
overloaded_conf[output_constants.OUT_DIRECTORY] = out_dir
|
|
74
|
+
|
|
75
|
+
overloaded_conf[output_constants.PRODUCT_LEVEL] = overloaded_conf.get(
|
|
76
|
+
output_constants.PRODUCT_LEVEL, "dsm"
|
|
77
|
+
)
|
|
78
|
+
if isinstance(overloaded_conf[output_constants.PRODUCT_LEVEL], str):
|
|
79
|
+
overloaded_conf[output_constants.PRODUCT_LEVEL] = [
|
|
80
|
+
overloaded_conf[output_constants.PRODUCT_LEVEL]
|
|
81
|
+
]
|
|
82
|
+
for level in overloaded_conf[output_constants.PRODUCT_LEVEL]:
|
|
83
|
+
if level not in ["dsm", "depth_map", "point_cloud"]:
|
|
84
|
+
raise RuntimeError("Unknown product level {}".format(level))
|
|
85
|
+
|
|
86
|
+
overloaded_conf[output_constants.OUT_GEOID] = overloaded_conf.get(
|
|
87
|
+
output_constants.OUT_GEOID, True
|
|
88
|
+
)
|
|
89
|
+
overloaded_conf[output_constants.EPSG] = overloaded_conf.get(
|
|
90
|
+
output_constants.EPSG, None
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
resolution = None
|
|
94
|
+
if overloaded_conf.get(output_constants.RESOLUTION, None) is not None:
|
|
95
|
+
resolution = overloaded_conf[output_constants.RESOLUTION]
|
|
96
|
+
overloaded_scaling_coeff = scaling_coeff
|
|
97
|
+
if scaling_coeff is not None:
|
|
98
|
+
if resolution is not None:
|
|
99
|
+
if resolution < 0.5 * scaling_coeff:
|
|
100
|
+
logging.warning(
|
|
101
|
+
"The requested DSM resolution of "
|
|
102
|
+
f"{overloaded_conf[output_constants.RESOLUTION]} seems "
|
|
103
|
+
"too low for the sensor images' resolution. "
|
|
104
|
+
"The pipeline will still continue with it."
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
resolution = float(0.5 * scaling_coeff)
|
|
108
|
+
logging.info(
|
|
109
|
+
"The resolution of the output DSM will be "
|
|
110
|
+
f"{resolution} meters. "
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
overloaded_conf[output_constants.RESOLUTION] = resolution
|
|
114
|
+
|
|
115
|
+
overloaded_conf[output_constants.SAVE_BY_PAIR] = overloaded_conf.get(
|
|
116
|
+
output_constants.SAVE_BY_PAIR, False
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Load auxiliary and subfields
|
|
120
|
+
overloaded_conf[output_constants.AUXILIARY] = overloaded_conf.get(
|
|
121
|
+
output_constants.AUXILIARY, {}
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Load auxiliary and subfields
|
|
125
|
+
overloaded_conf[output_constants.AUXILIARY][output_constants.AUX_IMAGE] = (
|
|
126
|
+
overloaded_conf[output_constants.AUXILIARY].get(
|
|
127
|
+
output_constants.AUX_IMAGE, True
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
131
|
+
output_constants.AUX_WEIGHTS
|
|
132
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
133
|
+
output_constants.AUX_WEIGHTS, False
|
|
134
|
+
)
|
|
135
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
136
|
+
output_constants.AUX_CLASSIFICATION
|
|
137
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
138
|
+
output_constants.AUX_CLASSIFICATION, False
|
|
139
|
+
)
|
|
140
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
141
|
+
output_constants.AUX_PERFORMANCE_MAP
|
|
142
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
143
|
+
output_constants.AUX_PERFORMANCE_MAP, False
|
|
144
|
+
)
|
|
145
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
146
|
+
output_constants.AUX_CONTRIBUTING_PAIR
|
|
147
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
148
|
+
output_constants.AUX_CONTRIBUTING_PAIR, False
|
|
149
|
+
)
|
|
150
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
151
|
+
output_constants.AUX_FILLING
|
|
152
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
153
|
+
output_constants.AUX_FILLING, False
|
|
154
|
+
)
|
|
155
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
156
|
+
output_constants.AUX_AMBIGUITY
|
|
157
|
+
] = overloaded_conf[output_constants.AUXILIARY].get(
|
|
158
|
+
output_constants.AUX_AMBIGUITY, False
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Check schema
|
|
162
|
+
output_schema = {
|
|
163
|
+
output_constants.OUT_DIRECTORY: str,
|
|
164
|
+
output_constants.PRODUCT_LEVEL: list,
|
|
165
|
+
output_constants.OUT_GEOID: Or(bool, str),
|
|
166
|
+
output_constants.EPSG: And(Or(int, str, None), is_valid_epsg),
|
|
167
|
+
output_constants.RESOLUTION: Or(int, float, None),
|
|
168
|
+
output_constants.SAVE_BY_PAIR: bool,
|
|
169
|
+
output_constants.AUXILIARY: dict,
|
|
170
|
+
}
|
|
171
|
+
checker_output = Checker(output_schema)
|
|
172
|
+
checker_output.validate(overloaded_conf)
|
|
173
|
+
|
|
174
|
+
# check auxiliary keys
|
|
175
|
+
auxiliary_schema = {
|
|
176
|
+
output_constants.AUX_IMAGE: Or(bool, str, list),
|
|
177
|
+
output_constants.AUX_WEIGHTS: bool,
|
|
178
|
+
output_constants.AUX_CLASSIFICATION: Or(bool, dict, list),
|
|
179
|
+
output_constants.AUX_PERFORMANCE_MAP: Or(bool, list),
|
|
180
|
+
output_constants.AUX_CONTRIBUTING_PAIR: bool,
|
|
181
|
+
output_constants.AUX_FILLING: Or(bool, dict),
|
|
182
|
+
output_constants.AUX_AMBIGUITY: bool,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# Check and overload classification parameter
|
|
186
|
+
check_classification_parameter(inputs, overloaded_conf)
|
|
187
|
+
|
|
188
|
+
# Check and overload image parameter
|
|
189
|
+
check_texture_bands(inputs, overloaded_conf)
|
|
190
|
+
|
|
191
|
+
# Check and overload performance_map parameter
|
|
192
|
+
check_performance_classes(overloaded_conf)
|
|
193
|
+
|
|
194
|
+
# Check and overload filling parameter
|
|
195
|
+
check_filling_parameter(overloaded_conf)
|
|
196
|
+
|
|
197
|
+
checker_auxiliary = Checker(auxiliary_schema)
|
|
198
|
+
checker_auxiliary.validate(overloaded_conf[output_constants.AUXILIARY])
|
|
199
|
+
|
|
200
|
+
if "epsg" in overloaded_conf and overloaded_conf["epsg"]:
|
|
201
|
+
spatial_ref = CRS.from_epsg(overloaded_conf["epsg"])
|
|
202
|
+
if spatial_ref.is_geographic:
|
|
203
|
+
if overloaded_conf[output_constants.RESOLUTION] > 10e-3:
|
|
204
|
+
logging.warning(
|
|
205
|
+
"The resolution of the "
|
|
206
|
+
+ "point_cloud_rasterization should be "
|
|
207
|
+
+ "fixed according to the epsg"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return overloaded_conf, overloaded_scaling_coeff
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def check_filling_parameter(overloaded_conf):
|
|
214
|
+
"""
|
|
215
|
+
Check and overload filling parameter
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
filling_param = overloaded_conf[output_constants.AUXILIARY][
|
|
219
|
+
output_constants.AUX_FILLING
|
|
220
|
+
]
|
|
221
|
+
|
|
222
|
+
valid_names = [
|
|
223
|
+
"fill_with_geoid",
|
|
224
|
+
"interpolate_from_borders",
|
|
225
|
+
"fill_with_endogenous_dem",
|
|
226
|
+
"fill_with_exogenous_dem",
|
|
227
|
+
"other",
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
if isinstance(filling_param, dict):
|
|
231
|
+
for _, value in filling_param.items():
|
|
232
|
+
if isinstance(value, str):
|
|
233
|
+
value = [value]
|
|
234
|
+
if any(elem not in valid_names for elem in value):
|
|
235
|
+
raise RuntimeError(
|
|
236
|
+
"Those filling methods are not available in CARS"
|
|
237
|
+
)
|
|
238
|
+
elif filling_param is True:
|
|
239
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
240
|
+
output_constants.AUX_FILLING
|
|
241
|
+
] = {i + 1: name for i, name in enumerate(valid_names)}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def check_texture_bands(inputs, overloaded_conf):
|
|
245
|
+
"""
|
|
246
|
+
Check and overload texture bands
|
|
247
|
+
"""
|
|
248
|
+
texture_bands = overloaded_conf[output_constants.AUXILIARY][
|
|
249
|
+
output_constants.AUX_IMAGE
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
if inputs[sens_cst.SENSORS] is not None:
|
|
253
|
+
first_key = list(inputs[sens_cst.SENSORS].keys())[0]
|
|
254
|
+
image = inputs[sens_cst.SENSORS][first_key][sens_cst.INPUT_IMG]
|
|
255
|
+
bands = set(image["bands"].keys())
|
|
256
|
+
|
|
257
|
+
if isinstance(texture_bands, list):
|
|
258
|
+
for elem in texture_bands:
|
|
259
|
+
if not isinstance(elem, str):
|
|
260
|
+
raise RuntimeError(
|
|
261
|
+
"The image parameter of auxiliary should "
|
|
262
|
+
"be a boolean, a string or a list of string"
|
|
263
|
+
)
|
|
264
|
+
if elem not in bands:
|
|
265
|
+
raise RuntimeError(
|
|
266
|
+
f"The band {elem} is "
|
|
267
|
+
f"not an existing band of "
|
|
268
|
+
f"the input image"
|
|
269
|
+
)
|
|
270
|
+
elif isinstance(texture_bands, str):
|
|
271
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
272
|
+
output_constants.AUX_IMAGE
|
|
273
|
+
] = [texture_bands]
|
|
274
|
+
|
|
275
|
+
if texture_bands not in bands:
|
|
276
|
+
raise RuntimeError(
|
|
277
|
+
f"The band {texture_bands} is "
|
|
278
|
+
f"not an existing band of "
|
|
279
|
+
f"the input image"
|
|
280
|
+
)
|
|
281
|
+
elif texture_bands is True:
|
|
282
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
283
|
+
output_constants.AUX_IMAGE
|
|
284
|
+
] = sorted(bands)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def check_classification_parameter(inputs, overloaded_conf):
|
|
288
|
+
"""
|
|
289
|
+
Check and overload classification parameter
|
|
290
|
+
"""
|
|
291
|
+
classification_formatting = overloaded_conf[output_constants.AUXILIARY][
|
|
292
|
+
output_constants.AUX_CLASSIFICATION
|
|
293
|
+
]
|
|
294
|
+
|
|
295
|
+
if inputs[sens_cst.SENSORS] is not None:
|
|
296
|
+
first_key = list(inputs[sens_cst.SENSORS].keys())[0]
|
|
297
|
+
|
|
298
|
+
if (
|
|
299
|
+
"classification" in inputs[sens_cst.SENSORS][first_key]
|
|
300
|
+
and inputs[sens_cst.SENSORS][first_key]["classification"]
|
|
301
|
+
is not None
|
|
302
|
+
):
|
|
303
|
+
classif = inputs[sens_cst.SENSORS][first_key][
|
|
304
|
+
sens_cst.INPUT_CLASSIFICATION
|
|
305
|
+
]
|
|
306
|
+
bands_classif = classif["values"]
|
|
307
|
+
|
|
308
|
+
if isinstance(classification_formatting, list):
|
|
309
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
310
|
+
output_constants.AUX_CLASSIFICATION
|
|
311
|
+
] = {val: val for val in classification_formatting}
|
|
312
|
+
|
|
313
|
+
for elem in classification_formatting:
|
|
314
|
+
if not isinstance(elem, int):
|
|
315
|
+
raise RuntimeError(
|
|
316
|
+
"The image parameter of auxiliary should "
|
|
317
|
+
"be a boolean, a string or a list of int"
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
if elem not in bands_classif:
|
|
321
|
+
raise RuntimeError(
|
|
322
|
+
f"If you want to use {elem} as a band num, "
|
|
323
|
+
f"you should use a dictionary, not a list"
|
|
324
|
+
)
|
|
325
|
+
elif classification_formatting is True:
|
|
326
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
327
|
+
output_constants.AUX_CLASSIFICATION
|
|
328
|
+
] = {int(name): name for val, name in enumerate(bands_classif)}
|
|
329
|
+
elif isinstance(classification_formatting, dict):
|
|
330
|
+
for _, value in classification_formatting.items():
|
|
331
|
+
if isinstance(value, int):
|
|
332
|
+
value = [value]
|
|
333
|
+
|
|
334
|
+
if any(elem not in bands_classif for elem in value):
|
|
335
|
+
raise RuntimeError(
|
|
336
|
+
f"The band {value} is "
|
|
337
|
+
f"not an existing band of "
|
|
338
|
+
f"the input classification"
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def check_performance_classes(overloaded_conf):
|
|
343
|
+
"""
|
|
344
|
+
Check performance classes
|
|
345
|
+
"""
|
|
346
|
+
performance_map_classes = overloaded_conf[output_constants.AUXILIARY][
|
|
347
|
+
output_constants.AUX_PERFORMANCE_MAP
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
if isinstance(performance_map_classes, list):
|
|
351
|
+
for elem in performance_map_classes:
|
|
352
|
+
if not isinstance(elem, (int, float)):
|
|
353
|
+
raise RuntimeError(
|
|
354
|
+
"The performance_map parameter of auxiliary should"
|
|
355
|
+
"be a boolean or a list of float/int"
|
|
356
|
+
)
|
|
357
|
+
if len(performance_map_classes) < 2:
|
|
358
|
+
raise RuntimeError("Not enough step for performance_map_classes")
|
|
359
|
+
if performance_map_classes:
|
|
360
|
+
previous_step = -1
|
|
361
|
+
for step in performance_map_classes:
|
|
362
|
+
if step < 0:
|
|
363
|
+
raise RuntimeError(
|
|
364
|
+
"All step in performance_map_classes must be >=0"
|
|
365
|
+
)
|
|
366
|
+
if step <= previous_step:
|
|
367
|
+
raise RuntimeError(
|
|
368
|
+
"performance_map_classes list must be ordered."
|
|
369
|
+
)
|
|
370
|
+
previous_step = step
|
|
371
|
+
elif performance_map_classes is True:
|
|
372
|
+
# default classes, in meters:
|
|
373
|
+
default_performance_classes = [
|
|
374
|
+
0,
|
|
375
|
+
0.968,
|
|
376
|
+
1.13375,
|
|
377
|
+
1.295,
|
|
378
|
+
1.604,
|
|
379
|
+
2.423,
|
|
380
|
+
3.428,
|
|
381
|
+
]
|
|
382
|
+
|
|
383
|
+
overloaded_conf[output_constants.AUXILIARY][
|
|
384
|
+
output_constants.AUX_PERFORMANCE_MAP
|
|
385
|
+
] = default_performance_classes
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def intialize_product_index(orchestrator, product_levels, input_pairs):
|
|
389
|
+
"""
|
|
390
|
+
Initialize the index dictionary according to requested levels with None
|
|
391
|
+
values for all paths.
|
|
392
|
+
|
|
393
|
+
:param orchestrator: cars orchestrator
|
|
394
|
+
:type orchestrator: Orchestrator
|
|
395
|
+
:param product_levels: name of corresponding pipeline
|
|
396
|
+
:type product_levels: list
|
|
397
|
+
:param input_pairs: list containing the pair names
|
|
398
|
+
:type input_pairs: list
|
|
399
|
+
"""
|
|
400
|
+
|
|
401
|
+
index = {}
|
|
402
|
+
|
|
403
|
+
if "dsm" in product_levels:
|
|
404
|
+
index["dsm"] = {
|
|
405
|
+
cst.INDEX_DSM_ALT: None,
|
|
406
|
+
cst.INDEX_DSM_COLOR: None,
|
|
407
|
+
cst.INDEX_DSM_MASK: None,
|
|
408
|
+
cst.INDEX_DSM_CLASSIFICATION: None,
|
|
409
|
+
cst.INDEX_DSM_PERFORMANCE_MAP: None,
|
|
410
|
+
cst.INDEX_DSM_CONTRIBUTING_PAIR: None,
|
|
411
|
+
cst.INDEX_DSM_FILLING: None,
|
|
412
|
+
cst.INDEX_DSM_WEIGHTS: None,
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if "point_cloud" in product_levels:
|
|
416
|
+
# Initialize an empty index for point cloud because its content is
|
|
417
|
+
# unknown at this point (tile name, save by pair or not)
|
|
418
|
+
index["point_cloud"] = {}
|
|
419
|
+
|
|
420
|
+
if "depth_map" in product_levels:
|
|
421
|
+
index["depth_map"] = {}
|
|
422
|
+
for pair in input_pairs:
|
|
423
|
+
index["depth_map"][pair] = {
|
|
424
|
+
cst.INDEX_DEPTH_MAP_X: None,
|
|
425
|
+
cst.INDEX_DEPTH_MAP_Y: None,
|
|
426
|
+
cst.INDEX_DEPTH_MAP_Z: None,
|
|
427
|
+
cst.INDEX_DEPTH_MAP_COLOR: None,
|
|
428
|
+
cst.INDEX_DEPTH_MAP_MASK: None,
|
|
429
|
+
cst.INDEX_DEPTH_MAP_CLASSIFICATION: None,
|
|
430
|
+
cst.INDEX_DEPTH_MAP_PERFORMANCE_MAP: None,
|
|
431
|
+
cst.INDEX_DEPTH_MAP_FILLING: None,
|
|
432
|
+
cst.INDEX_DEPTH_MAP_EPSG: None,
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
orchestrator.update_index(index)
|