cars 1.0.0rc2__cp312-cp312-win_amd64.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 (225) hide show
  1. cars/__init__.py +86 -0
  2. cars/applications/__init__.py +40 -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 +105 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -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 +641 -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 +1461 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
  31. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  32. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  33. cars/applications/dense_matching/cpp/meson.build +9 -0
  34. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  35. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  36. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  37. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  38. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  39. cars/applications/dense_matching/disparity_grid_algo.py +597 -0
  40. cars/applications/dense_matching/loaders/__init__.py +23 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  46. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  47. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  48. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  49. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  50. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  51. cars/applications/dsm_filling/__init__.py +32 -0
  52. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  53. cars/applications/dsm_filling/border_interpolation_app.py +278 -0
  54. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  55. cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
  56. cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
  57. cars/applications/dsm_merging/__init__.py +28 -0
  58. cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
  59. cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
  60. cars/applications/grid_correction/__init__.py +30 -0
  61. cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
  62. cars/applications/grid_correction/grid_correction_app.py +557 -0
  63. cars/applications/grid_generation/__init__.py +30 -0
  64. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  65. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  66. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  67. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  68. cars/applications/grid_generation/transform_grid.py +88 -0
  69. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  70. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  71. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  72. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  73. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  74. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  75. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  76. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  77. cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
  78. cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
  79. cars/applications/rasterization/__init__.py +30 -0
  80. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  81. cars/applications/rasterization/rasterization_algo.py +534 -0
  82. cars/applications/rasterization/rasterization_constants.py +38 -0
  83. cars/applications/rasterization/rasterization_wrappers.py +639 -0
  84. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  85. cars/applications/resampling/__init__.py +28 -0
  86. cars/applications/resampling/abstract_resampling_app.py +187 -0
  87. cars/applications/resampling/bicubic_resampling_app.py +760 -0
  88. cars/applications/resampling/resampling_algo.py +590 -0
  89. cars/applications/resampling/resampling_constants.py +36 -0
  90. cars/applications/resampling/resampling_wrappers.py +309 -0
  91. cars/applications/sensors_subsampling/__init__.py +32 -0
  92. cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
  93. cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
  94. cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
  95. cars/applications/sparse_matching/__init__.py +30 -0
  96. cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
  97. cars/applications/sparse_matching/sift_app.py +724 -0
  98. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  99. cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
  100. cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
  101. cars/applications/triangulation/__init__.py +32 -0
  102. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  103. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  104. cars/applications/triangulation/pc_transform.py +552 -0
  105. cars/applications/triangulation/triangulation_algo.py +371 -0
  106. cars/applications/triangulation/triangulation_constants.py +38 -0
  107. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  108. cars/bundleadjustment.py +750 -0
  109. cars/cars.py +179 -0
  110. cars/conf/__init__.py +23 -0
  111. cars/conf/geoid/egm96.grd +0 -0
  112. cars/conf/geoid/egm96.grd.hdr +15 -0
  113. cars/conf/input_parameters.py +156 -0
  114. cars/conf/mask_cst.py +35 -0
  115. cars/core/__init__.py +23 -0
  116. cars/core/cars_logging.py +402 -0
  117. cars/core/constants.py +191 -0
  118. cars/core/constants_disparity.py +50 -0
  119. cars/core/datasets.py +140 -0
  120. cars/core/geometry/__init__.py +27 -0
  121. cars/core/geometry/abstract_geometry.py +1119 -0
  122. cars/core/geometry/shareloc_geometry.py +598 -0
  123. cars/core/inputs.py +568 -0
  124. cars/core/outputs.py +176 -0
  125. cars/core/preprocessing.py +722 -0
  126. cars/core/projection.py +843 -0
  127. cars/core/roi_tools.py +215 -0
  128. cars/core/tiling.py +774 -0
  129. cars/core/utils.py +164 -0
  130. cars/data_structures/__init__.py +23 -0
  131. cars/data_structures/cars_dataset.py +1544 -0
  132. cars/data_structures/cars_dict.py +74 -0
  133. cars/data_structures/corresponding_tiles_tools.py +186 -0
  134. cars/data_structures/dataframe_converter.py +185 -0
  135. cars/data_structures/format_transformation.py +297 -0
  136. cars/devibrate.py +689 -0
  137. cars/extractroi.py +264 -0
  138. cars/orchestrator/__init__.py +23 -0
  139. cars/orchestrator/achievement_tracker.py +125 -0
  140. cars/orchestrator/cluster/__init__.py +37 -0
  141. cars/orchestrator/cluster/abstract_cluster.py +250 -0
  142. cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
  143. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  144. cars/orchestrator/cluster/dask_config/README.md +94 -0
  145. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  146. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  147. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  148. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  149. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  150. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  151. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  152. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  153. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  154. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  155. cars/orchestrator/cluster/log_wrapper.py +728 -0
  156. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  157. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  158. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  159. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  160. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  161. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
  162. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  163. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  164. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  165. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  166. cars/orchestrator/memory_tools.py +47 -0
  167. cars/orchestrator/orchestrator.py +755 -0
  168. cars/orchestrator/orchestrator_constants.py +29 -0
  169. cars/orchestrator/registry/__init__.py +23 -0
  170. cars/orchestrator/registry/abstract_registry.py +143 -0
  171. cars/orchestrator/registry/compute_registry.py +106 -0
  172. cars/orchestrator/registry/id_generator.py +116 -0
  173. cars/orchestrator/registry/replacer_registry.py +213 -0
  174. cars/orchestrator/registry/saver_registry.py +363 -0
  175. cars/orchestrator/registry/unseen_registry.py +118 -0
  176. cars/orchestrator/tiles_profiler.py +279 -0
  177. cars/pipelines/__init__.py +26 -0
  178. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  179. cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
  180. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  181. cars/pipelines/default/__init__.py +26 -0
  182. cars/pipelines/default/default_pipeline.py +1088 -0
  183. cars/pipelines/filling/__init__.py +26 -0
  184. cars/pipelines/filling/filling.py +981 -0
  185. cars/pipelines/formatting/__init__.py +26 -0
  186. cars/pipelines/formatting/formatting.py +186 -0
  187. cars/pipelines/merging/__init__.py +26 -0
  188. cars/pipelines/merging/merging.py +439 -0
  189. cars/pipelines/parameters/__init__.py +0 -0
  190. cars/pipelines/parameters/advanced_parameters.py +256 -0
  191. cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
  192. cars/pipelines/parameters/application_parameters.py +72 -0
  193. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  194. cars/pipelines/parameters/dsm_inputs.py +349 -0
  195. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  196. cars/pipelines/parameters/output_constants.py +52 -0
  197. cars/pipelines/parameters/output_parameters.py +438 -0
  198. cars/pipelines/parameters/sensor_inputs.py +859 -0
  199. cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
  200. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  201. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  202. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  203. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  204. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  205. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  206. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  207. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  208. cars/pipelines/pipeline.py +119 -0
  209. cars/pipelines/pipeline_constants.py +38 -0
  210. cars/pipelines/pipeline_template.py +135 -0
  211. cars/pipelines/subsampling/__init__.py +26 -0
  212. cars/pipelines/subsampling/subsampling.py +358 -0
  213. cars/pipelines/surface_modeling/__init__.py +26 -0
  214. cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
  215. cars/pipelines/tie_points/__init__.py +26 -0
  216. cars/pipelines/tie_points/tie_points.py +536 -0
  217. cars/starter.py +167 -0
  218. cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
  219. cars-1.0.0rc2.dist-info/METADATA +289 -0
  220. cars-1.0.0rc2.dist-info/RECORD +225 -0
  221. cars-1.0.0rc2.dist-info/WHEEL +4 -0
  222. cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
  223. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  224. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  225. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
@@ -0,0 +1,183 @@
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 PointCloudRasterization 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("point_cloud_rasterization")
33
+ class PointCloudRasterization(ApplicationTemplate, metaclass=ABCMeta):
34
+ """
35
+ PointCloudRasterization
36
+ """
37
+
38
+ available_applications: Dict = {}
39
+ default_application = "simple_gaussian"
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 rasterization
48
+ :return: a application_to_use object
49
+ """
50
+
51
+ rasterization_method = cls.default_application
52
+ if bool(conf) is False or "method" not in conf:
53
+ logging.info(
54
+ "Rasterisation method not specified, "
55
+ "default {} is used".format(rasterization_method)
56
+ )
57
+ else:
58
+ rasterization_method = conf.get("method", cls.default_application)
59
+
60
+ if rasterization_method not in cls.available_applications:
61
+ logging.error(
62
+ "No rasterization application named {} registered".format(
63
+ rasterization_method
64
+ )
65
+ )
66
+ raise KeyError(
67
+ "No rasterization application named {} registered".format(
68
+ rasterization_method
69
+ )
70
+ )
71
+
72
+ logging.info(
73
+ "The PointCloudRasterization({}) application will be used".format(
74
+ rasterization_method
75
+ )
76
+ )
77
+
78
+ return super(PointCloudRasterization, cls).__new__(
79
+ cls.available_applications[rasterization_method]
80
+ )
81
+
82
+ def __init_subclass__(cls, short_name, **kwargs): # pylint: disable=E0302
83
+ super().__init_subclass__(**kwargs)
84
+ cls.available_applications[short_name] = cls
85
+
86
+ def __init__(self, conf=None):
87
+ """
88
+ Init function of PointCloudRasterization
89
+
90
+ :param conf: configuration
91
+ :return: an application_to_use object
92
+ """
93
+
94
+ super().__init__(conf=conf)
95
+
96
+ @abstractmethod
97
+ def get_margins(self, resolution):
98
+ """
99
+ Get the margin to use for terrain tiles
100
+
101
+ :param resolution: resolution of raster data (in target CRS unit)
102
+ :type epsg: float
103
+
104
+ :return: margin in meters or degrees
105
+ """
106
+
107
+ @abstractmethod
108
+ def get_optimal_tile_size(
109
+ self,
110
+ max_ram_per_worker,
111
+ superposing_point_clouds=1,
112
+ point_cloud_resolution=0.5,
113
+ ):
114
+ """
115
+ Get the optimal tile size to use, depending on memory available
116
+
117
+ :param max_ram_per_worker: maximum ram available
118
+ :type max_ram_per_worker: int
119
+ :param superposing_point_clouds: number of point clouds superposing
120
+ :type superposing_point_clouds: int
121
+ :param point_cloud_resolution: resolution of point cloud
122
+ :type point_cloud_resolution: float
123
+
124
+ :return: optimal tile size in meter
125
+ :rtype: float
126
+
127
+ """
128
+
129
+ @abstractmethod
130
+ def run( # pylint: disable=too-many-positional-arguments
131
+ self,
132
+ point_clouds,
133
+ epsg,
134
+ output_crs,
135
+ resolution,
136
+ orchestrator=None,
137
+ dsm_file_name=None,
138
+ weights_file_name=None,
139
+ color_file_name=None,
140
+ classif_file_name=None,
141
+ performance_map_file_name=None,
142
+ ambiguity_file_name=None,
143
+ contributing_pair_file_name=None,
144
+ filling_file_name=None,
145
+ color_dtype=None,
146
+ dump_dir=None,
147
+ ):
148
+ """
149
+ Run PointCloudRasterisation application.
150
+
151
+ Creates a CarsDataset filled with dsm tiles.
152
+
153
+ :param point_clouds: merged point cloud
154
+ :type point_clouds: CarsDataset filled with pandas.DataFrame
155
+ :param epsg: epsg of raster data
156
+ :type epsg: str
157
+ :param resolution: resolution of raster data (in target CRS unit)
158
+ :type epsg: float
159
+ :param orchestrator: orchestrator used
160
+ :param dsm_file_name: path of dsm
161
+ :type dsm_file_name: str
162
+ :param weights_file_name: path of dsm weights
163
+ :type weights_file_name: str
164
+ :param color_file_name: path of color
165
+ :type color_file_name: str
166
+ :param classif_file_name: path of color
167
+ :type classif_file_name: str
168
+ :param performance_map_file_name: path of confidence file
169
+ :type performance_map_file_name: str
170
+ :param ambiguity_file_name: path to the ambiguity
171
+ :type ambiguity_file_name: str
172
+ :param contributing_pair_file_name: path of contributing pair file
173
+ :type contributing_pair_file_name: str
174
+ :param filling_file_name: path of filling file
175
+ :type filling_file_name: str
176
+ :param color_dtype: output color image type
177
+ :type color_dtype: str (numpy type)
178
+ :param dump_dir: directory used for outputs with no associated filename
179
+ :type dump_dir: str
180
+
181
+ :return: raster DSM
182
+ :rtype: CarsDataset filled with xr.Dataset
183
+ """
@@ -0,0 +1,534 @@
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
+ # pylint: disable=too-many-lines
22
+
23
+ """
24
+ This module is responsible for the rasterization step:
25
+ - it contains all functions related to 3D representation on a 2D raster grid
26
+ TODO: refactor in several files and remove too-many-lines
27
+ """
28
+
29
+
30
+ # Standard imports
31
+ import logging
32
+ from typing import List, Tuple, Union
33
+
34
+ import numpy as np
35
+ import pandas
36
+
37
+ # cars-rasterize
38
+ import rasterize as crasterize # pylint:disable=E0401
39
+ import xarray as xr
40
+
41
+ from cars.applications.rasterization import rasterization_wrappers as rast_wrap
42
+ from cars.core import constants as cst
43
+
44
+ # CARS imports
45
+ from cars.data_structures import cars_dataset
46
+
47
+
48
+ # pylint: disable=too-many-positional-arguments
49
+ def simple_rasterization_dataset_wrapper(
50
+ cloud: pandas.DataFrame,
51
+ resolution: float,
52
+ epsg: int,
53
+ xstart: float = None,
54
+ ystart: float = None,
55
+ xsize: int = None,
56
+ ysize: int = None,
57
+ sigma: float = None,
58
+ radius: int = 1,
59
+ dsm_no_data: int = np.nan,
60
+ texture_no_data: int = np.nan,
61
+ msk_no_data: int = 255,
62
+ list_computed_layers: List[str] = None,
63
+ source_pc_names: List[str] = None,
64
+ performance_map_classes: List[float] = None,
65
+ cloud_global_id: int = None,
66
+ ) -> xr.Dataset:
67
+ """
68
+ Wrapper of simple_rasterization
69
+ that has xarray.Dataset as inputs and outputs.
70
+
71
+ :param cloud: cloud to rasterize
72
+ :param resolution: Resolution of rasterized cells,
73
+ expressed in cloud CRS units or None
74
+ :param epsg: epsg code for the CRS of the final raster
75
+ :param color_list: Additional list of images
76
+ with bands to rasterize (same size as cloud_list), or None
77
+ :param xstart: xstart of the rasterization grid
78
+ (if None, will be estimated by the function)
79
+ :param ystart: ystart of the rasterization grid
80
+ (if None, will be estimated by the function)
81
+ :param xsize: xsize of the rasterization grid
82
+ (if None, will be estimated by the function)
83
+ :param ysize: ysize of the rasterization grid
84
+ (if None, will be estimated by the function)
85
+ :param sigma: sigma for gaussian interpolation.
86
+ (If None, set to resolution)
87
+ :param radius: Radius for hole filling.
88
+ :param dsm_no_data: no data value to use in the final raster
89
+ :param texture_no_data: no data value to use in the final colored raster
90
+ :param msk_no_data: no data value to use in the final mask image
91
+ :param list_computed_layers: list of computed output data
92
+ :param source_pc_names: list of names of point cloud before merging :
93
+ name of sensors pair or name of point cloud file
94
+ :param performance_map_classes: list for step defining border of class
95
+ :type performance_map_classes: list or None
96
+ :param cloud_global_id: global id of pair
97
+ :type cloud_global_id: int
98
+ :return: Rasterized cloud
99
+ """
100
+
101
+ # combined clouds
102
+ roi = (
103
+ resolution is not None
104
+ and xstart is not None
105
+ and ystart is not None
106
+ and xsize is not None
107
+ and ysize is not None
108
+ )
109
+
110
+ # compute roi from the combined clouds if it is not set
111
+ if not roi:
112
+ (
113
+ xstart,
114
+ ystart,
115
+ xsize,
116
+ ysize,
117
+ ) = rast_wrap.compute_xy_starts_and_sizes(resolution, cloud)
118
+
119
+ # rasterize clouds
120
+ raster = rasterize(
121
+ cloud,
122
+ resolution,
123
+ epsg,
124
+ x_start=xstart,
125
+ y_start=ystart,
126
+ x_size=xsize,
127
+ y_size=ysize,
128
+ sigma=sigma,
129
+ radius=radius,
130
+ hgt_no_data=dsm_no_data,
131
+ texture_no_data=texture_no_data,
132
+ msk_no_data=msk_no_data,
133
+ list_computed_layers=list_computed_layers,
134
+ source_pc_names=source_pc_names,
135
+ performance_map_classes=performance_map_classes,
136
+ cloud_global_id=cloud_global_id,
137
+ )
138
+
139
+ return raster
140
+
141
+
142
+ # pylint: disable=too-many-positional-arguments
143
+ def compute_vector_raster_and_stats(
144
+ cloud: pandas.DataFrame,
145
+ x_start: float,
146
+ y_start: float,
147
+ x_size: int,
148
+ y_size: int,
149
+ resolution: float,
150
+ sigma: float,
151
+ radius: int,
152
+ list_computed_layers: List[str] = None,
153
+ cloud_global_id: int = None,
154
+ ) -> Tuple[
155
+ np.ndarray,
156
+ np.ndarray,
157
+ np.ndarray,
158
+ np.ndarray,
159
+ np.ndarray,
160
+ np.ndarray,
161
+ List[str],
162
+ Union[None, np.ndarray, list, dict],
163
+ ]:
164
+ """
165
+ Compute vectorized raster and its statistics.
166
+
167
+ :param cloud: Combined cloud
168
+ as returned by the create_combined_cloud function
169
+ :param x_start: x start of the rasterization grid
170
+ :param y_start: y start of the rasterization grid
171
+ :param x_size: x size of the rasterization grid
172
+ :param y_size: y size of the rasterization grid
173
+ :param resolution: Resolution of rasterized cells,
174
+ expressed in cloud CRS units or None.
175
+ :param sigma: Sigma for gaussian interpolation. If None, set to resolution
176
+ :param radius: Radius for hole filling.
177
+ :param list_computed_layers: list of computed output data
178
+ :param cloud_global_id: global id of pair
179
+ :return: a tuple with rasterization results and statistics.
180
+ """
181
+ # get points corresponding to (X, Y positions) + data_valid
182
+ points = cloud.loc[:, [cst.X, cst.Y]].values.T
183
+ nb_points = points.shape[1]
184
+ valid = np.ones((1, nb_points))
185
+ # create values: 1. altitudes and colors, 2. ambiguity, 3. masks
186
+ # split_indexes allows to keep indexes separating values
187
+ split_indexes = []
188
+
189
+ # 1. altitudes and colors
190
+ values_bands = [cst.Z] if cst.Z in cloud else []
191
+
192
+ clr_indexes = rast_wrap.find_indexes_in_point_cloud(
193
+ cloud, cst.POINT_CLOUD_CLR_KEY_ROOT
194
+ )
195
+ values_bands.extend(clr_indexes)
196
+ split_indexes.append(len(values_bands))
197
+
198
+ # 2. ambiguity
199
+ ambiguity_indexes = rast_wrap.find_indexes_in_point_cloud(
200
+ cloud, cst.POINT_CLOUD_AMBIGUITY_KEY_ROOT, list_computed_layers
201
+ )
202
+
203
+ values_bands.extend(ambiguity_indexes)
204
+ split_indexes.append(len(ambiguity_indexes))
205
+
206
+ # sanity check
207
+ assert len(ambiguity_indexes) <= 1
208
+
209
+ # 3. sup and inf layers interval
210
+ layer_inf_sup_indexes = rast_wrap.find_indexes_in_point_cloud(
211
+ cloud, cst.POINT_CLOUD_LAYER_SUP_OR_INF_ROOT, list_computed_layers
212
+ )
213
+
214
+ values_bands.extend(layer_inf_sup_indexes)
215
+ split_indexes.append(len(layer_inf_sup_indexes))
216
+
217
+ # 4. mask
218
+ msk_indexes = rast_wrap.find_indexes_in_point_cloud(
219
+ cloud, cst.POINT_CLOUD_MSK, list_computed_layers
220
+ )
221
+ values_bands.extend(msk_indexes)
222
+ split_indexes.append(len(msk_indexes))
223
+
224
+ # 5. classification
225
+ classif_indexes = rast_wrap.find_indexes_in_point_cloud(
226
+ cloud, cst.POINT_CLOUD_CLASSIF_KEY_ROOT, list_computed_layers
227
+ )
228
+
229
+ values_bands.extend(classif_indexes)
230
+ split_indexes.append(len(classif_indexes))
231
+
232
+ # 6. source point cloud
233
+ # Fill the dataframe with additional columns :
234
+ # each column refers to a point cloud id
235
+ number_of_pc = cars_dataset.get_attributes(cloud)["number_of_pc"]
236
+ if (cloud_global_id is not None) and (
237
+ list_computed_layers is None
238
+ or rast_wrap.substring_in_list(
239
+ list_computed_layers, cst.POINT_CLOUD_SOURCE_KEY_ROOT
240
+ )
241
+ ):
242
+ for pc_id in range(number_of_pc):
243
+ # Create binary list that indicates from each point whether it comes
244
+ # from point cloud number "pc_id"
245
+ if pc_id == cloud_global_id:
246
+ point_is_from_pc = np.ones(cloud.shape[0], dtype=int)
247
+ else:
248
+ point_is_from_pc = np.zeros(cloud.shape[0], dtype=int)
249
+ pc_key = "{}{}".format(cst.POINT_CLOUD_SOURCE_KEY_ROOT, pc_id)
250
+ cloud[pc_key] = point_is_from_pc
251
+
252
+ source_pc_indexes = rast_wrap.find_indexes_in_point_cloud(
253
+ cloud, cst.POINT_CLOUD_SOURCE_KEY_ROOT, list_computed_layers
254
+ )
255
+ values_bands.extend(source_pc_indexes)
256
+ split_indexes.append(len(source_pc_indexes))
257
+
258
+ # 7. filling
259
+ filling_indexes = rast_wrap.find_indexes_in_point_cloud(
260
+ cloud, cst.POINT_CLOUD_FILLING_KEY_ROOT, list_computed_layers
261
+ )
262
+ values_bands.extend(filling_indexes)
263
+ split_indexes.append(len(filling_indexes))
264
+
265
+ # 8. Performance map from risk and intervals
266
+ performance_map_indexes = rast_wrap.find_indexes_in_point_cloud(
267
+ cloud, cst.POINT_CLOUD_PERFORMANCE_MAP_ROOT, list_computed_layers
268
+ )
269
+ values_bands.extend(performance_map_indexes)
270
+
271
+ values = (
272
+ cloud.loc[:, values_bands].values.T
273
+ if len(values_bands) > 0
274
+ else np.empty((0, nb_points))
275
+ )
276
+
277
+ (out, weights_sum, mean, stdev, nb_pts_in_disc, nb_pts_in_cell) = (
278
+ crasterize.pc_to_dsm(
279
+ points,
280
+ values,
281
+ valid,
282
+ x_start,
283
+ y_start,
284
+ x_size,
285
+ y_size,
286
+ resolution,
287
+ float(radius),
288
+ sigma,
289
+ )
290
+ )
291
+
292
+ # pylint: disable=unbalanced-tuple-unpacking
293
+ (
294
+ out,
295
+ ambiguity,
296
+ interval,
297
+ msk,
298
+ classif,
299
+ source_pc,
300
+ filling,
301
+ performance_map,
302
+ ) = np.split(out, np.cumsum(split_indexes), axis=-1)
303
+
304
+ ambiguity_out = None
305
+ if len(ambiguity_indexes) > 0:
306
+ ambiguity_out = ambiguity
307
+
308
+ layers_inf_sup_out = None
309
+ layers_inf_sup_stat_index = None
310
+ if len(layer_inf_sup_indexes) > 0:
311
+ layers_inf_sup_out = interval
312
+ layers_inf_sup_stat_index = [
313
+ values_bands.index(int_ind) for int_ind in layer_inf_sup_indexes
314
+ ]
315
+
316
+ msk_out = None
317
+ if len(msk_indexes) > 0:
318
+ msk_out = np.ceil(msk)
319
+
320
+ classif_out = None
321
+ if len(classif_indexes) > 0:
322
+ classif_out = np.ceil(classif)
323
+
324
+ source_pc_out = None
325
+ if len(source_pc_indexes) > 0:
326
+ source_pc_out = np.ceil(source_pc)
327
+
328
+ filling_out = None
329
+ if len(filling_indexes) > 0:
330
+ filling_out = np.ceil(filling)
331
+
332
+ if len(performance_map_indexes) == 0:
333
+ performance_map = None
334
+
335
+ return (
336
+ out,
337
+ weights_sum,
338
+ mean,
339
+ stdev,
340
+ nb_pts_in_disc,
341
+ nb_pts_in_cell,
342
+ msk_out,
343
+ clr_indexes,
344
+ classif_out,
345
+ classif_indexes,
346
+ ambiguity_out,
347
+ layers_inf_sup_out,
348
+ layers_inf_sup_stat_index,
349
+ layer_inf_sup_indexes,
350
+ source_pc_out,
351
+ filling_out,
352
+ filling_indexes,
353
+ performance_map,
354
+ performance_map_indexes,
355
+ )
356
+
357
+
358
+ def rasterize( # pylint: disable=too-many-positional-arguments
359
+ cloud: pandas.DataFrame,
360
+ resolution: float,
361
+ epsg: int,
362
+ x_start: float,
363
+ y_start: float,
364
+ x_size: int,
365
+ y_size: int,
366
+ sigma: float = None,
367
+ radius: int = 1,
368
+ hgt_no_data: int = -32768,
369
+ texture_no_data: int = 0,
370
+ msk_no_data: int = 255,
371
+ list_computed_layers: List[str] = None,
372
+ source_pc_names: List[str] = None,
373
+ performance_map_classes: List[float] = None,
374
+ cloud_global_id: int = None,
375
+ ) -> Union[xr.Dataset, None]:
376
+ """
377
+ Rasterize a point cloud with its color bands to a Dataset
378
+ that also contains quality statistics.
379
+
380
+ :param cloud: Combined cloud
381
+ as returned by the create_combined_cloud function
382
+ :param resolution: Resolution of rasterized cells,
383
+ expressed in cloud CRS units or None.
384
+ :param epsg: epsg code for the CRS of the final raster
385
+ :param x_start: x start of the rasterization grid
386
+ :param y_start: y start of the rasterization grid
387
+ :param x_size: x size of the rasterization grid
388
+ :param y_size: y size of the rasterization grid
389
+ :param sigma: sigma for gaussian interpolation. If None, set to resolution
390
+ :param radius: Radius for hole filling.
391
+ :param hgt_no_data: no data value to use for height
392
+ :param texture_no_data: no data value to use for color
393
+ :param msk_no_data: no data value to use in the final mask image
394
+ :param list_computed_layers: list of computed output data
395
+ :param source_pc_names: list of source pc names
396
+ :param performance_map_classes: list for step defining border of class
397
+ :type performance_map_classes: list or None
398
+ :param cloud_global_id: global id of pair
399
+ :return: Rasterized cloud color and statistics.
400
+ """
401
+
402
+ if sigma is None:
403
+ sigma = resolution
404
+
405
+ # If no valid points are found in cloud, return default values
406
+ if cloud.size == 0:
407
+ logging.debug("No points to rasterize, returning None")
408
+ return None
409
+
410
+ logging.debug(
411
+ "Rasterization grid: start=[{},{}], size=[{},{}], resolution={}".format(
412
+ x_start, y_start, x_size, y_size, resolution
413
+ )
414
+ )
415
+
416
+ (
417
+ out,
418
+ weights_sum,
419
+ mean,
420
+ stdev,
421
+ n_pts,
422
+ n_in_cell,
423
+ msk,
424
+ clr_indexes,
425
+ classif,
426
+ classif_indexes,
427
+ ambiguity,
428
+ layer_inf_sup,
429
+ layer_inf_sup_stats_indexes,
430
+ layer_inf_sup_indexes,
431
+ source_pc,
432
+ filling,
433
+ filling_indexes,
434
+ performance_map_raw,
435
+ performance_map_raw_indexes,
436
+ ) = compute_vector_raster_and_stats(
437
+ cloud,
438
+ x_start,
439
+ y_start,
440
+ x_size,
441
+ y_size,
442
+ resolution,
443
+ sigma,
444
+ radius,
445
+ list_computed_layers,
446
+ cloud_global_id=cloud_global_id,
447
+ )
448
+
449
+ # reshape data as a 2d grid.
450
+ shape_out = (y_size, x_size)
451
+ out = out.reshape(shape_out + (-1,))
452
+ mean = mean.reshape(shape_out + (-1,))
453
+ stdev = stdev.reshape(shape_out + (-1,))
454
+ n_pts = n_pts.reshape(shape_out)
455
+ n_in_cell = n_in_cell.reshape(shape_out)
456
+
457
+ out = out.reshape(shape_out + (-1,))
458
+ out = np.moveaxis(out, 2, 0)
459
+
460
+ weights_sum = weights_sum.reshape(shape_out)
461
+
462
+ if classif is not None:
463
+ classif = classif.reshape(shape_out + (-1,))
464
+ classif = np.moveaxis(classif, 2, 0)
465
+
466
+ if msk is not None:
467
+ msk = msk.reshape(shape_out)
468
+ else:
469
+ msk = np.isnan(out[0, :, :])
470
+
471
+ if ambiguity is not None:
472
+ ambiguity = ambiguity.reshape(shape_out + (-1,))
473
+ ambiguity = np.moveaxis(ambiguity, 2, 0)
474
+
475
+ if layer_inf_sup is not None:
476
+ layer_inf_sup = layer_inf_sup.reshape(shape_out + (-1,))
477
+ layer_inf_sup = np.moveaxis(layer_inf_sup, 2, 0)
478
+
479
+ if source_pc is not None:
480
+ source_pc = source_pc.reshape(shape_out + (-1,))
481
+ source_pc = np.moveaxis(source_pc, 2, 0)
482
+
483
+ if filling is not None:
484
+ filling = filling.reshape(shape_out + (-1,))
485
+ filling = np.moveaxis(filling, 2, 0)
486
+
487
+ performance_map_classified = None
488
+ performance_map_classified_indexes = None
489
+ if performance_map_raw is not None:
490
+ performance_map_raw = performance_map_raw.reshape(shape_out + (-1,))
491
+ performance_map_raw = np.moveaxis(performance_map_raw, 2, 0)
492
+ if not isinstance(performance_map_classes, bool):
493
+ (performance_map_classified, performance_map_classified_indexes) = (
494
+ rast_wrap.classify_performance_map(
495
+ performance_map_raw, performance_map_classes, msk_no_data
496
+ )
497
+ )
498
+
499
+ # build output dataset
500
+ raster_out = rast_wrap.create_raster_dataset(
501
+ out,
502
+ weights_sum,
503
+ x_start,
504
+ y_start,
505
+ x_size,
506
+ y_size,
507
+ resolution,
508
+ hgt_no_data,
509
+ texture_no_data,
510
+ msk_no_data,
511
+ epsg,
512
+ mean,
513
+ stdev,
514
+ n_pts,
515
+ n_in_cell,
516
+ msk,
517
+ clr_indexes,
518
+ classif,
519
+ classif_indexes,
520
+ ambiguity,
521
+ layer_inf_sup,
522
+ layer_inf_sup_stats_indexes,
523
+ layer_inf_sup_indexes,
524
+ source_pc,
525
+ source_pc_names,
526
+ filling,
527
+ filling_indexes,
528
+ performance_map_raw,
529
+ performance_map_classified,
530
+ performance_map_classified_indexes,
531
+ performance_map_raw_indexes,
532
+ )
533
+
534
+ return raster_out