cars 1.0.0rc1__cp313-cp313-musllinux_1_2_i686.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.

Potentially problematic release.


This version of cars might be problematic. Click here for more details.

Files changed (202) hide show
  1. cars/__init__.py +74 -0
  2. cars/applications/__init__.py +37 -0
  3. cars/applications/application.py +117 -0
  4. cars/applications/application_constants.py +29 -0
  5. cars/applications/application_template.py +146 -0
  6. cars/applications/auxiliary_filling/__init__.py +29 -0
  7. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +104 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +630 -0
  10. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
  11. cars/applications/dem_generation/__init__.py +30 -0
  12. cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
  13. cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
  14. cars/applications/dem_generation/bulldozer_dem_app.py +655 -0
  15. cars/applications/dem_generation/bulldozer_memory.py +55 -0
  16. cars/applications/dem_generation/dem_generation_algo.py +107 -0
  17. cars/applications/dem_generation/dem_generation_constants.py +32 -0
  18. cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
  19. cars/applications/dense_match_filling/__init__.py +30 -0
  20. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
  21. cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
  22. cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
  23. cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
  24. cars/applications/dense_match_filling/zero_padding_app.py +302 -0
  25. cars/applications/dense_matching/__init__.py +30 -0
  26. cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
  27. cars/applications/dense_matching/census_mccnn_sgm_app.py +1460 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-313-i386-linux-musl.so +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  31. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  32. cars/applications/dense_matching/cpp/meson.build +9 -0
  33. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  34. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  35. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  36. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  37. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  38. cars/applications/dense_matching/disparity_grid_algo.py +588 -0
  39. cars/applications/dense_matching/loaders/__init__.py +23 -0
  40. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  46. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  47. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  48. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  49. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  50. cars/applications/dsm_filling/__init__.py +32 -0
  51. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  52. cars/applications/dsm_filling/border_interpolation_app.py +270 -0
  53. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  54. cars/applications/dsm_filling/bulldozer_filling_app.py +279 -0
  55. cars/applications/dsm_filling/exogenous_filling_app.py +333 -0
  56. cars/applications/grid_generation/__init__.py +30 -0
  57. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  58. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  59. cars/applications/grid_generation/grid_correction_app.py +496 -0
  60. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  61. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  62. cars/applications/grid_generation/transform_grid.py +88 -0
  63. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  64. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  65. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  66. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  67. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  68. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  69. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  70. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  71. cars/applications/point_cloud_outlier_removal/small_components_app.py +527 -0
  72. cars/applications/point_cloud_outlier_removal/statistical_app.py +531 -0
  73. cars/applications/rasterization/__init__.py +30 -0
  74. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  75. cars/applications/rasterization/rasterization_algo.py +534 -0
  76. cars/applications/rasterization/rasterization_constants.py +38 -0
  77. cars/applications/rasterization/rasterization_wrappers.py +634 -0
  78. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  79. cars/applications/resampling/__init__.py +28 -0
  80. cars/applications/resampling/abstract_resampling_app.py +187 -0
  81. cars/applications/resampling/bicubic_resampling_app.py +762 -0
  82. cars/applications/resampling/resampling_algo.py +614 -0
  83. cars/applications/resampling/resampling_constants.py +36 -0
  84. cars/applications/resampling/resampling_wrappers.py +309 -0
  85. cars/applications/sparse_matching/__init__.py +30 -0
  86. cars/applications/sparse_matching/abstract_sparse_matching_app.py +498 -0
  87. cars/applications/sparse_matching/sift_app.py +735 -0
  88. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  89. cars/applications/sparse_matching/sparse_matching_constants.py +68 -0
  90. cars/applications/sparse_matching/sparse_matching_wrappers.py +238 -0
  91. cars/applications/triangulation/__init__.py +32 -0
  92. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  93. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  94. cars/applications/triangulation/pc_transform.py +552 -0
  95. cars/applications/triangulation/triangulation_algo.py +371 -0
  96. cars/applications/triangulation/triangulation_constants.py +38 -0
  97. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  98. cars/bundleadjustment.py +757 -0
  99. cars/cars.py +177 -0
  100. cars/conf/__init__.py +23 -0
  101. cars/conf/geoid/egm96.grd +0 -0
  102. cars/conf/geoid/egm96.grd.hdr +15 -0
  103. cars/conf/input_parameters.py +156 -0
  104. cars/conf/mask_cst.py +35 -0
  105. cars/core/__init__.py +23 -0
  106. cars/core/cars_logging.py +402 -0
  107. cars/core/constants.py +191 -0
  108. cars/core/constants_disparity.py +50 -0
  109. cars/core/datasets.py +140 -0
  110. cars/core/geometry/__init__.py +27 -0
  111. cars/core/geometry/abstract_geometry.py +1119 -0
  112. cars/core/geometry/shareloc_geometry.py +598 -0
  113. cars/core/inputs.py +568 -0
  114. cars/core/outputs.py +176 -0
  115. cars/core/preprocessing.py +722 -0
  116. cars/core/projection.py +843 -0
  117. cars/core/roi_tools.py +215 -0
  118. cars/core/tiling.py +774 -0
  119. cars/core/utils.py +164 -0
  120. cars/data_structures/__init__.py +23 -0
  121. cars/data_structures/cars_dataset.py +1541 -0
  122. cars/data_structures/cars_dict.py +74 -0
  123. cars/data_structures/corresponding_tiles_tools.py +186 -0
  124. cars/data_structures/dataframe_converter.py +185 -0
  125. cars/data_structures/format_transformation.py +297 -0
  126. cars/devibrate.py +689 -0
  127. cars/extractroi.py +264 -0
  128. cars/orchestrator/__init__.py +23 -0
  129. cars/orchestrator/achievement_tracker.py +125 -0
  130. cars/orchestrator/cluster/__init__.py +37 -0
  131. cars/orchestrator/cluster/abstract_cluster.py +244 -0
  132. cars/orchestrator/cluster/abstract_dask_cluster.py +375 -0
  133. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  134. cars/orchestrator/cluster/dask_config/README.md +94 -0
  135. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  136. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  137. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  138. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  139. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  140. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  141. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  142. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  143. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  144. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  145. cars/orchestrator/cluster/log_wrapper.py +1075 -0
  146. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  147. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  148. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  149. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  150. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  151. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +873 -0
  152. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  153. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  154. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  155. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  156. cars/orchestrator/orchestrator.py +905 -0
  157. cars/orchestrator/orchestrator_constants.py +29 -0
  158. cars/orchestrator/registry/__init__.py +23 -0
  159. cars/orchestrator/registry/abstract_registry.py +143 -0
  160. cars/orchestrator/registry/compute_registry.py +106 -0
  161. cars/orchestrator/registry/id_generator.py +116 -0
  162. cars/orchestrator/registry/replacer_registry.py +213 -0
  163. cars/orchestrator/registry/saver_registry.py +363 -0
  164. cars/orchestrator/registry/unseen_registry.py +118 -0
  165. cars/orchestrator/tiles_profiler.py +279 -0
  166. cars/pipelines/__init__.py +26 -0
  167. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  168. cars/pipelines/conf_resolution/conf_first_resolution.yaml +2 -0
  169. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  170. cars/pipelines/default/__init__.py +26 -0
  171. cars/pipelines/default/default_pipeline.py +786 -0
  172. cars/pipelines/parameters/__init__.py +0 -0
  173. cars/pipelines/parameters/advanced_parameters.py +417 -0
  174. cars/pipelines/parameters/advanced_parameters_constants.py +69 -0
  175. cars/pipelines/parameters/application_parameters.py +71 -0
  176. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  177. cars/pipelines/parameters/dsm_inputs.py +918 -0
  178. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  179. cars/pipelines/parameters/output_constants.py +52 -0
  180. cars/pipelines/parameters/output_parameters.py +454 -0
  181. cars/pipelines/parameters/sensor_inputs.py +842 -0
  182. cars/pipelines/parameters/sensor_inputs_constants.py +49 -0
  183. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  184. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  185. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  186. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  187. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  188. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  189. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  190. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  191. cars/pipelines/pipeline.py +119 -0
  192. cars/pipelines/pipeline_constants.py +31 -0
  193. cars/pipelines/pipeline_template.py +139 -0
  194. cars/pipelines/unit/__init__.py +26 -0
  195. cars/pipelines/unit/unit_pipeline.py +2850 -0
  196. cars/starter.py +167 -0
  197. cars-1.0.0rc1.dist-info/METADATA +292 -0
  198. cars-1.0.0rc1.dist-info/RECORD +202 -0
  199. cars-1.0.0rc1.dist-info/WHEEL +5 -0
  200. cars-1.0.0rc1.dist-info/entry_points.txt +8 -0
  201. cars.libs/libgcc_s-1257a076.so.1 +0 -0
  202. cars.libs/libstdc++-0530927c.so.6.0.32 +0 -0
@@ -0,0 +1,333 @@
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
+ This module contains the exogenous dsm filling application class.
23
+ """
24
+
25
+ import logging
26
+ import os
27
+ import shutil
28
+ import warnings
29
+
30
+ import numpy as np
31
+ import rasterio as rio
32
+ from json_checker import Checker, Or
33
+ from pyproj import CRS
34
+ from rasterio.enums import Resampling
35
+ from rasterio.errors import NodataShadowWarning
36
+ from rasterio.warp import reproject
37
+ from shapely import Polygon
38
+
39
+ from cars.core import inputs, projection
40
+ from cars.orchestrator.cluster.log_wrapper import cars_profile
41
+
42
+ from .abstract_dsm_filling_app import DsmFilling
43
+
44
+
45
+ class ExogenousFilling(DsmFilling, short_name="exogenous_filling"):
46
+ """
47
+ Exogenous filling
48
+ """
49
+
50
+ def __init__(self, conf=None):
51
+ """
52
+ Init function of ExogenousFilling
53
+
54
+ :param conf: configuration for ExogenousFilling
55
+ :return: an application_to_use object
56
+ """
57
+ super().__init__(conf=conf)
58
+
59
+ # check conf
60
+ self.used_method = self.used_config["method"]
61
+ self.classification = self.used_config["classification"]
62
+ self.fill_with_geoid = self.used_config["fill_with_geoid"]
63
+ self.interpolation_method = self.used_config["interpolation_method"]
64
+ self.save_intermediate_data = self.used_config["save_intermediate_data"]
65
+
66
+ def check_conf(self, conf):
67
+
68
+ # init conf
69
+ if conf is not None:
70
+ overloaded_conf = conf.copy()
71
+ else:
72
+ conf = {}
73
+ overloaded_conf = {}
74
+
75
+ # Overload conf
76
+ overloaded_conf["method"] = conf.get("method", "exogenous_filling")
77
+ overloaded_conf["classification"] = conf.get("classification", "nodata")
78
+ if isinstance(overloaded_conf["classification"], str):
79
+ overloaded_conf["classification"] = [
80
+ overloaded_conf["classification"]
81
+ ]
82
+ overloaded_conf["fill_with_geoid"] = conf.get("fill_with_geoid", None)
83
+ overloaded_conf["interpolation_method"] = conf.get(
84
+ "interpolation_method", "bilinear"
85
+ )
86
+
87
+ if overloaded_conf["interpolation_method"] not in ["bilinear", "cubic"]:
88
+ # pylint: disable=inconsistent-quotes
89
+ raise RuntimeError(
90
+ f"Invalid interpolation method"
91
+ f"{overloaded_conf['interpolation_method']}, "
92
+ f"supported modes are bilinear and cubic."
93
+ )
94
+
95
+ overloaded_conf["save_intermediate_data"] = conf.get(
96
+ "save_intermediate_data", False
97
+ )
98
+
99
+ rectification_schema = {
100
+ "method": str,
101
+ "classification": Or(None, [str]),
102
+ "fill_with_geoid": Or(None, [str]),
103
+ "interpolation_method": str,
104
+ "save_intermediate_data": bool,
105
+ }
106
+
107
+ # Check conf
108
+ checker = Checker(rectification_schema)
109
+ checker.validate(overloaded_conf)
110
+
111
+ return overloaded_conf
112
+
113
+ @cars_profile(name="Exogeneous filling")
114
+ def run( # pylint: disable=too-many-positional-arguments # noqa C901
115
+ self,
116
+ dsm_file,
117
+ classif_file,
118
+ filling_file,
119
+ dump_dir,
120
+ roi_polys,
121
+ roi_epsg,
122
+ output_geoid,
123
+ geom_plugin,
124
+ ):
125
+ """
126
+ Run dsm filling using initial elevation and the current dsm
127
+ Replaces dsm.tif by the filled dsm. Adds a new band
128
+ to filling.tif if it exists.
129
+ The old dsm is saved in dump_dir.
130
+
131
+ roi_poly can any of these objects :
132
+ - a list of Shapely Polygons
133
+ - a Shapely Polygon
134
+ """
135
+
136
+ if self.classification is None:
137
+ self.classification = ["nodata"]
138
+
139
+ if self.fill_with_geoid is None:
140
+ self.fill_with_geoid = []
141
+
142
+ interpolation_methods_dict = {
143
+ "bilinear": Resampling.bilinear,
144
+ "cubic": Resampling.cubic,
145
+ }
146
+ interpolation_method = interpolation_methods_dict.get(
147
+ self.interpolation_method, Resampling.bilinear
148
+ )
149
+
150
+ if geom_plugin is None:
151
+ logging.error(
152
+ "No DEM was provided, exogenous_filling will not run."
153
+ )
154
+ return
155
+
156
+ if not os.path.exists(dump_dir):
157
+ os.makedirs(dump_dir)
158
+
159
+ old_dsm_path = os.path.join(dump_dir, "dsm_not_filled.tif")
160
+ new_dsm_path = os.path.join(dump_dir, "dsm_filled.tif")
161
+
162
+ # get dsm to be filled and its metadata
163
+ with rio.open(dsm_file) as in_dsm:
164
+ dsm = in_dsm.read(1)
165
+ dsm_tr = in_dsm.transform
166
+ dsm_crs = in_dsm.crs
167
+ dsm_meta = in_dsm.meta
168
+
169
+ roi_raster = np.ones(dsm.shape)
170
+
171
+ if isinstance(roi_polys, list):
172
+ roi_polys_outepsg = []
173
+ for poly in roi_polys:
174
+ if isinstance(poly, Polygon):
175
+ roi_poly_outepsg = projection.polygon_projection_crs(
176
+ poly, CRS(roi_epsg), dsm_crs
177
+ )
178
+ roi_polys_outepsg.append(roi_poly_outepsg)
179
+
180
+ roi_raster = rio.features.rasterize(
181
+ roi_polys_outepsg, out_shape=roi_raster.shape, transform=dsm_tr
182
+ )
183
+ elif isinstance(roi_polys, Polygon):
184
+ roi_poly_outepsg = projection.polygon_projection_crs(
185
+ roi_polys, CRS(roi_epsg), dsm_crs
186
+ )
187
+ roi_raster = rio.features.rasterize(
188
+ [roi_poly_outepsg], out_shape=roi_raster.shape, transform=dsm_tr
189
+ )
190
+
191
+ # Get the initial elevation
192
+ with rio.open(geom_plugin.dem) as in_elev:
193
+ # Reproject the elevation data to match the DSM
194
+ elev_data = np.empty(dsm.shape, dtype=in_elev.dtypes[0])
195
+
196
+ reproject(
197
+ source=rio.band(in_elev, 1),
198
+ destination=elev_data,
199
+ src_transform=in_elev.transform,
200
+ src_crs=in_elev.crs,
201
+ dst_transform=dsm_tr,
202
+ dst_crs=dsm_crs,
203
+ resampling=interpolation_method,
204
+ )
205
+
206
+ if self.save_intermediate_data:
207
+ reprojected_dem_path = os.path.join(dump_dir, "reprojected_dem.tif")
208
+ with rio.open(reprojected_dem_path, "w", **dsm_meta) as out_elev:
209
+ out_elev.write(elev_data, 1)
210
+
211
+ with rio.open(geom_plugin.geoid) as in_geoid:
212
+ # Reproject the geoid data to match the DSM
213
+ input_geoid_data = np.empty(dsm.shape, dtype=in_geoid.dtypes[0])
214
+
215
+ reproject(
216
+ source=rio.band(in_geoid, 1),
217
+ destination=input_geoid_data,
218
+ src_transform=in_geoid.transform,
219
+ src_crs=in_geoid.crs,
220
+ dst_transform=dsm_tr,
221
+ dst_crs=dsm_crs,
222
+ resampling=interpolation_method,
223
+ )
224
+
225
+ if self.save_intermediate_data:
226
+ reprojected_geoid_path = os.path.join(
227
+ dump_dir, "reprojected_input_geoid.tif"
228
+ )
229
+ with rio.open(reprojected_geoid_path, "w", **dsm_meta) as out_geoid:
230
+ out_geoid.write(input_geoid_data, 1)
231
+
232
+ if isinstance(output_geoid, str):
233
+ with rio.open(output_geoid) as in_geoid:
234
+ # Reproject the geoid data to match the DSM
235
+ output_geoid_data = np.empty(
236
+ dsm.shape, dtype=in_geoid.dtypes[0]
237
+ )
238
+
239
+ reproject(
240
+ source=rio.band(in_geoid, 1),
241
+ destination=output_geoid_data,
242
+ src_transform=in_geoid.transform,
243
+ src_crs=in_geoid.crs,
244
+ dst_transform=dsm_tr,
245
+ dst_crs=dsm_crs,
246
+ resampling=interpolation_method,
247
+ )
248
+
249
+ if self.save_intermediate_data:
250
+ reprojected_geoid_path = os.path.join(
251
+ dump_dir, "reprojected_output_geoid.tif"
252
+ )
253
+ with rio.open(
254
+ reprojected_geoid_path, "w", **dsm_meta
255
+ ) as out_geoid:
256
+ out_geoid.write(input_geoid_data, 1)
257
+
258
+ # Save old dsm
259
+ if self.save_intermediate_data:
260
+ with rio.open(old_dsm_path, "w", **dsm_meta) as out_dsm:
261
+ out_dsm.write(dsm, 1)
262
+
263
+ # Fill DSM for every label
264
+ combined_mask = np.zeros_like(dsm).astype(np.uint8)
265
+ if classif_file is not None:
266
+ classif_descriptions = inputs.get_descriptions_bands(classif_file)
267
+ else:
268
+ classif_descriptions = []
269
+ for label in self.classification:
270
+ if label in classif_descriptions:
271
+ index_classif = classif_descriptions.index(label) + 1
272
+ with rio.open(classif_file) as in_classif:
273
+ classif = in_classif.read(index_classif)
274
+ classif_msk = in_classif.read_masks(1)
275
+ classif[classif_msk == 0] = 0
276
+ filling_mask = np.logical_and(classif, roi_raster > 0)
277
+ elif label == "nodata":
278
+ if classif_file is not None:
279
+ with rio.open(classif_file) as in_classif:
280
+ with warnings.catch_warnings():
281
+ warnings.simplefilter("ignore", NodataShadowWarning)
282
+ classif_msk = in_classif.read_masks(1)
283
+ classif = ~classif_msk
284
+ else:
285
+ with rio.open(dsm_file) as in_dsm:
286
+ dsm_msk = in_dsm.read_masks(1)
287
+ classif = ~dsm_msk
288
+ filling_mask = np.logical_and(classif, roi_raster > 0)
289
+ else:
290
+ logging.error(
291
+ "Label {} not found in classification "
292
+ "descriptions {}".format(label, classif_descriptions)
293
+ )
294
+ continue
295
+
296
+ if label in self.fill_with_geoid:
297
+ logging.info("Filling of {} with geoid".format(label))
298
+ dsm[filling_mask] = 0
299
+ else:
300
+ logging.info("Filling of {} with DEM and geoid".format(label))
301
+ dsm[filling_mask] = elev_data[filling_mask]
302
+
303
+ # apply offset to project on geoid if needed
304
+ if output_geoid is not True:
305
+ if isinstance(output_geoid, bool) and output_geoid is False:
306
+ # out geoid is ellipsoid: add geoid-ellipsoid distance
307
+ dsm[filling_mask] += input_geoid_data[filling_mask]
308
+ elif isinstance(output_geoid, str):
309
+ # out geoid is a new geoid whose path is in output_geoid:
310
+ # add carsgeoid-ellipsoid then add ellipsoid-outgeoid
311
+ dsm[filling_mask] += input_geoid_data[filling_mask]
312
+ dsm[filling_mask] -= output_geoid_data[filling_mask]
313
+
314
+ combined_mask = np.logical_or(combined_mask, filling_mask)
315
+
316
+ with rio.open(dsm_file, "w", **dsm_meta) as out_dsm:
317
+ out_dsm.write(dsm, 1)
318
+ if self.save_intermediate_data:
319
+ shutil.copy2(dsm_file, new_dsm_path)
320
+
321
+ if filling_file is not None:
322
+ with rio.open(filling_file, "r") as src:
323
+ fill_meta = src.meta
324
+ bands = [src.read(i + 1) for i in range(src.count)]
325
+ bands_desc = [src.descriptions[i] for i in range(src.count)]
326
+ fill_meta["count"] += 1
327
+ bands.append(combined_mask)
328
+ bands_desc.append("filling_exogenous")
329
+
330
+ with rio.open(filling_file, "w", **fill_meta) as out:
331
+ for i, band in enumerate(bands):
332
+ out.write(band, i + 1)
333
+ out.set_band_description(i + 1, bands_desc[i])
@@ -0,0 +1,30 @@
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
+ CARS grid_generation module init file
23
+ """
24
+ # flake8: noqa: F401
25
+
26
+ from cars.applications.grid_generation.abstract_grid_generation_app import (
27
+ GridGeneration,
28
+ )
29
+
30
+ from . import epipolar_grid_generation_app
@@ -0,0 +1,142 @@
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
+ this module contains the abstract grid generation application class.
23
+ """
24
+ import logging
25
+ from abc import ABCMeta, abstractmethod
26
+ from typing import Dict
27
+
28
+ from cars.applications.application import Application
29
+ from cars.applications.application_template import ApplicationTemplate
30
+
31
+
32
+ @Application.register("grid_generation")
33
+ class GridGeneration(ApplicationTemplate, metaclass=ABCMeta):
34
+ """
35
+ AbstractGridGeneration
36
+ """
37
+
38
+ available_applications: Dict = {}
39
+ default_application = "epipolar"
40
+
41
+ def __new__(cls, conf=None): # pylint: disable=W0613
42
+ """
43
+ Return the required application
44
+ :raises:
45
+ - KeyError when the required application is not registered
46
+
47
+ :param conf: configuration for grid generation
48
+ :return: a application_to_use object
49
+ """
50
+
51
+ grid_method = cls.default_application
52
+
53
+ if bool(conf) is False or "method" not in conf:
54
+ logging.info(
55
+ "Grid generation method not specified, default "
56
+ " {} is used".format(grid_method)
57
+ )
58
+ else:
59
+ grid_method = conf.get("method", cls.default_application)
60
+
61
+ if grid_method not in cls.available_applications:
62
+ logging.error(
63
+ "No GridGeneration application named {} registered".format(
64
+ grid_method
65
+ )
66
+ )
67
+ raise KeyError(
68
+ "No GridGeneration application named {} registered".format(
69
+ grid_method
70
+ )
71
+ )
72
+
73
+ logging.info(
74
+ "The GridGeneration({}) application will be used".format(
75
+ grid_method
76
+ )
77
+ )
78
+
79
+ return super(GridGeneration, cls).__new__(
80
+ cls.available_applications[grid_method]
81
+ )
82
+
83
+ def __init_subclass__(cls, short_name, **kwargs): # pylint: disable=E0302
84
+ super().__init_subclass__(**kwargs)
85
+ cls.available_applications[short_name] = cls
86
+
87
+ def __init__(self, conf=None):
88
+ """
89
+ Init function of GridGeneration
90
+
91
+ :param conf: configuration
92
+ :return: an application_to_use object
93
+ """
94
+
95
+ super().__init__(conf=conf)
96
+
97
+ @abstractmethod
98
+ def get_save_grids(self):
99
+ """
100
+ Get whether the grid will be saved
101
+
102
+ :return: true is grid saving is activated
103
+ :rtype: bool
104
+ """
105
+
106
+ @abstractmethod
107
+ def run( # pylint: disable=too-many-positional-arguments
108
+ self,
109
+ image_left,
110
+ image_right,
111
+ orchestrator=None,
112
+ pair_folder=None,
113
+ srtm_dir=None,
114
+ default_alt=None,
115
+ geoid_path=None,
116
+ pair_key="PAIR_0",
117
+ ):
118
+ """
119
+ Run EpipolarGridGeneration application
120
+
121
+ Create left and right grid CarsDataset filled with xarray.Dataset ,
122
+ corresponding to left and right epipolar grids.
123
+
124
+ :param image_left: left image
125
+ :type image_left: dict
126
+ :param image_right: right image
127
+ :type image_right: dict
128
+ :param pair_folder: folder used for current pair
129
+ :type pair_folder: str
130
+ :param orchestrator: orchestrator used
131
+ :param srtm_dir: srtm directory
132
+ :type srtm_dir: str
133
+ :param default_alt: default altitude
134
+ :type default_alt: float
135
+ :param geoid_path: geoid path
136
+ :type geoid_path: str
137
+ :param pair_key: pair configuration id
138
+ :type pair_key: str
139
+
140
+ :return: left grid, right grid
141
+ :rtype: Tuple(CarsDataset, CarsDataset)
142
+ """