ign-borea 0.1.5__py3-none-any.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.
Files changed (98) hide show
  1. borea/__init__.py +0 -0
  2. borea/datastruct/__init__.py +0 -0
  3. borea/datastruct/camera.py +25 -0
  4. borea/datastruct/dtm.py +119 -0
  5. borea/datastruct/gcp.py +22 -0
  6. borea/datastruct/shot.py +222 -0
  7. borea/datastruct/workdata.py +220 -0
  8. borea/format/__init__.py +0 -0
  9. borea/format/conl.py +143 -0
  10. borea/format/rpc.py +244 -0
  11. borea/geodesy/__init__.py +0 -0
  12. borea/geodesy/approx_euclidean_proj.py +91 -0
  13. borea/geodesy/euclidean_proj.py +25 -0
  14. borea/geodesy/local_euclidean_proj.py +127 -0
  15. borea/geodesy/proj_engine.py +70 -0
  16. borea/geodesy/projectionlist/__init__.py +0 -0
  17. borea/geodesy/projectionlist/search_proj.py +60 -0
  18. borea/geodesy/transform_geodesy.py +114 -0
  19. borea/process/__init__.py +0 -0
  20. borea/process/p_add_data/__init__.py +0 -0
  21. borea/process/p_add_data/p_add_shot.py +63 -0
  22. borea/process/p_add_data/p_file_gcp2d.py +55 -0
  23. borea/process/p_add_data/p_file_gcp3d.py +53 -0
  24. borea/process/p_add_data/p_gen_param.py +76 -0
  25. borea/process/p_add_data/p_pt2d.py +48 -0
  26. borea/process/p_add_data/p_pt3d.py +48 -0
  27. borea/process/p_add_data/p_unit_shot.py +48 -0
  28. borea/process/p_add_data/p_write.py +23 -0
  29. borea/process/p_format/__init__.py +0 -0
  30. borea/process/p_format/p_read_opk.py +78 -0
  31. borea/process/p_format/p_write_con.py +36 -0
  32. borea/process/p_format/p_write_opk.py +64 -0
  33. borea/process/p_format/p_write_rpc.py +48 -0
  34. borea/process/p_func/__init__.py +0 -0
  35. borea/process/p_func/p_control.py +67 -0
  36. borea/process/p_func/p_image_world.py +48 -0
  37. borea/process/p_func/p_spaceresection.py +51 -0
  38. borea/process/p_func/p_world_image.py +49 -0
  39. borea/reader/__init__.py +0 -0
  40. borea/reader/orientation/__init__.py +0 -0
  41. borea/reader/orientation/manage_reader.py +33 -0
  42. borea/reader/orientation/reader_opk.py +58 -0
  43. borea/reader/reader_camera.py +52 -0
  44. borea/reader/reader_point.py +113 -0
  45. borea/stat/__init__.py +0 -0
  46. borea/stat/statistics.py +215 -0
  47. borea/transform_world_image/__init__.py +0 -0
  48. borea/transform_world_image/transform_dtm/__init__.py +0 -0
  49. borea/transform_world_image/transform_dtm/world_image_dtm.py +47 -0
  50. borea/transform_world_image/transform_shot/__init__.py +0 -0
  51. borea/transform_world_image/transform_shot/conversion_coor_shot.py +58 -0
  52. borea/transform_world_image/transform_shot/image_world_shot.py +153 -0
  53. borea/transform_world_image/transform_shot/world_image_shot.py +117 -0
  54. borea/transform_world_image/transform_worksite/__init__.py +0 -0
  55. borea/transform_world_image/transform_worksite/image_world_intersection.py +154 -0
  56. borea/transform_world_image/transform_worksite/image_world_least_square.py +184 -0
  57. borea/transform_world_image/transform_worksite/image_world_work.py +49 -0
  58. borea/transform_world_image/transform_worksite/space_resection.py +343 -0
  59. borea/transform_world_image/transform_worksite/world_image_work.py +43 -0
  60. borea/utils/__init__.py +0 -0
  61. borea/utils/check/__init__.py +0 -0
  62. borea/utils/check/check_args_opk.py +59 -0
  63. borea/utils/check/check_args_reader_pt.py +44 -0
  64. borea/utils/check/check_array.py +56 -0
  65. borea/utils/check/check_header.py +90 -0
  66. borea/utils/check/check_order_axe.py +50 -0
  67. borea/utils/miscellaneous/__init__.py +0 -0
  68. borea/utils/miscellaneous/miscellaneous.py +83 -0
  69. borea/utils/miscellaneous/param_bundle.py +36 -0
  70. borea/utils/miscellaneous/sparse.py +31 -0
  71. borea/utils/singleton/__init__.py +0 -0
  72. borea/utils/singleton/singleton.py +23 -0
  73. borea/utils/xml/__init__.py +0 -0
  74. borea/utils/xml/xml.py +63 -0
  75. borea/worksite/__init__.py +0 -0
  76. borea/worksite/worksite.py +240 -0
  77. borea/writer/__init__.py +0 -0
  78. borea/writer/manage_writer.py +23 -0
  79. borea/writer/writer_con.py +29 -0
  80. borea/writer/writer_df_to_txt.py +32 -0
  81. borea/writer/writer_opk.py +70 -0
  82. borea/writer/writer_rpc.py +55 -0
  83. borea_tools/__init__.py +0 -0
  84. borea_tools/opk_control.py +33 -0
  85. borea_tools/opk_to_conl.py +33 -0
  86. borea_tools/opk_to_opk.py +33 -0
  87. borea_tools/opk_to_rpc.py +33 -0
  88. borea_tools/pt_image_to_world.py +32 -0
  89. borea_tools/pt_world_to_image.py +32 -0
  90. borea_tools/ptfile_image_to_world.py +32 -0
  91. borea_tools/ptfile_world_to_image.py +32 -0
  92. borea_tools/spaceresection_opk.py +34 -0
  93. ign_borea-0.1.5.dist-info/LICENSE +21 -0
  94. ign_borea-0.1.5.dist-info/METADATA +274 -0
  95. ign_borea-0.1.5.dist-info/RECORD +98 -0
  96. ign_borea-0.1.5.dist-info/WHEEL +5 -0
  97. ign_borea-0.1.5.dist-info/entry_points.txt +10 -0
  98. ign_borea-0.1.5.dist-info/top_level.txt +2 -0
borea/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,25 @@
1
+ """
2
+ Camera data class module.
3
+ """
4
+ from dataclasses import dataclass, field
5
+
6
+
7
+ @dataclass
8
+ class Camera:
9
+ """
10
+ Camera class definition.
11
+
12
+ Args:
13
+ name_camera (str): Name of the camera.
14
+ ppax (float): Center of distortion in x.
15
+ ppay (float): Center of distortion in y.
16
+ focal (float): Focal of the camera.
17
+ width (int): Width of the image in pixel.
18
+ height (int): Height of the image in pixel.
19
+ """
20
+ name_camera: str
21
+ ppax: float = field(default=None)
22
+ ppay: float = field(default=None)
23
+ focal: float = field(default=None)
24
+ width: int = field(default=None)
25
+ height: int = field(default=None)
@@ -0,0 +1,119 @@
1
+ """
2
+ A module for manipulating a digital elevation model.
3
+ """
4
+ from pathlib import Path, PureWindowsPath
5
+ import numpy as np
6
+ from osgeo import gdal
7
+ from scipy import ndimage
8
+ from borea.transform_world_image.transform_dtm.world_image_dtm import WorldImageDtm
9
+ from borea.utils.singleton.singleton import Singleton
10
+ gdal.UseExceptions()
11
+
12
+
13
+ # pylint: disable-next=too-many-instance-attributes
14
+ class Dtm(WorldImageDtm, metaclass=Singleton):
15
+ """
16
+ Represents a digital elevation model.
17
+
18
+ Args:
19
+ path_dtm (str): Path to the dtm file. If None Dtm.get() always returns 0.
20
+ order (int): The method of interpolation to perform.
21
+ 0 : nearest, 1 : slinear, 3 : cubic, 5 : quintic.
22
+ cval (int): Value to fill past edges of dtm.
23
+ If None raise an error for any point outside the dtm.
24
+ keep_in_memory (bool): Store all data in memory.
25
+
26
+ .. note::
27
+ All gdal formats are supported. The file must contain georeferencing information.
28
+ """
29
+ def __init__(self):
30
+ self.path_dtm = None
31
+ self.type_dtm = None
32
+ self.order = 1
33
+ self.keep_in_memory = False
34
+ self.cval = np.nan
35
+ self.img = None
36
+ self.rb = None
37
+ self.nodata = None
38
+ self.dtm_array = None
39
+ WorldImageDtm.__init__(self, None)
40
+
41
+ def set_dtm(self, path_dtm: str, type_dtm: str) -> None:
42
+ """
43
+ Set the dtm path for reading dtm.
44
+
45
+ Args:
46
+ path_dtm (str): Path to the dtm file.
47
+ type (str): Type of dtm "a" altitude, "h" height.
48
+ """
49
+ if path_dtm:
50
+ gdal.AllRegister()
51
+ self.type_dtm = type_dtm
52
+ self.path_dtm = Path(PureWindowsPath(path_dtm))
53
+ self.img = gdal.Open(self.path_dtm.as_posix())
54
+ self.rb = self.img.GetRasterBand(1)
55
+ self.nodata = self.rb.GetNoDataValue()
56
+ if self.keep_in_memory:
57
+ self.dtm_array = self.rb.ReadAsArray()
58
+ WorldImageDtm.__init__(self, self.img.GetGeoTransform())
59
+ else:
60
+ self.path_dtm = path_dtm
61
+
62
+ def set_order(self, order: int) -> None:
63
+ """
64
+ The method of interpolation to perform.
65
+ 0:nearest 1:bilinear 3:cubic 5:quintic.
66
+
67
+ Args:
68
+ order (int): The method of interpolation to perform.
69
+ """
70
+ self.order = order
71
+
72
+ def set_cval(self, cval: int) -> None:
73
+ """
74
+ Value to fill past edges of dtm or nodata.
75
+ If None raise an error for any point outside the dtm or Nodata.
76
+
77
+ Args
78
+ cval (int): Value to fill past edges of dtm or nodata.
79
+ """
80
+ self.cval = cval if cval else np.nan
81
+
82
+ def set_keep_memory(self, keep_memory: bool) -> None:
83
+ """
84
+ Store all image in memory.
85
+
86
+ Args:
87
+ keep_in_memory (bool): Store all image in memory.
88
+ """
89
+ self.keep_in_memory = keep_memory
90
+
91
+ def get_z_world(self, coor_2d: np.ndarray) -> np.ndarray:
92
+ """
93
+ Extract value in the Dtm.
94
+
95
+ Args:
96
+ coor_2d (np.array): World coordinate 2D [X, Y].
97
+
98
+ Returns:
99
+ np.array: z value.
100
+ """
101
+ if self.path_dtm is None:
102
+ return np.zeros_like(coor_2d[0])
103
+ col, line = self.world_to_image(coor_2d)
104
+ if not self.keep_in_memory:
105
+ z = []
106
+ if isinstance(col, float):
107
+ col, line = [col], [line]
108
+ for colt, linet in zip(col, line):
109
+ try:
110
+ z += [self.rb.ReadAsArray(colt, linet, 1, 1, resample_alg=self.order)]
111
+ except RuntimeError:
112
+ z += [self.cval]
113
+ else:
114
+ z = ndimage.map_coordinates(self.dtm_array, np.vstack([line, col]),
115
+ order=self.order, mode="constant", cval=self.cval)
116
+ if np.any(np.isnan(z)):
117
+ raise IndexError(f"Out dtm {coor_2d[0]} {coor_2d[1]}")
118
+
119
+ return np.round(np.array(z, dtype=float), 3)
@@ -0,0 +1,22 @@
1
+ """
2
+ Ground Control Point (GCP) class.
3
+ """
4
+ from dataclasses import dataclass
5
+ import numpy as np
6
+
7
+
8
+ @dataclass
9
+ class GCP:
10
+ """
11
+ Ground Control Point class.
12
+
13
+ Args:
14
+ name_gcp (str): Name of the gcp.
15
+ code (str): IGN code to differentiate between support points (1, 2, 3)
16
+ and control points (11, 12, 13)
17
+ 1 means precision in Z, 2 in X and Y and 3 in X, Y, Z.
18
+ coor (numpy.array): Array of ground coordinate [X, Y, Z].
19
+ """
20
+ name_gcp: str
21
+ code: str
22
+ coor: np.ndarray
@@ -0,0 +1,222 @@
1
+ """
2
+ Acquisition data class module.
3
+ """
4
+ import numpy as np
5
+ from scipy.spatial.transform import Rotation as R
6
+ from borea.geodesy.proj_engine import ProjEngine
7
+ from borea.geodesy.approx_euclidean_proj import ApproxEuclideanProj
8
+ from borea.geodesy.local_euclidean_proj import LocalEuclideanProj
9
+ from borea.utils.check.check_order_axe import check_order_axe
10
+
11
+
12
+ # pylint: disable=too-many-instance-attributes too-many-arguments
13
+ class Shot:
14
+ """
15
+ Shot class definition.
16
+
17
+ Args:
18
+ name_shot (str): Name of the shot.
19
+ pos_shot (numpy.array): Array of coordinate position [X, Y, Z].
20
+ ori_shot (numpy.array): Array of orientation of the shot [Omega, Phi, Kappa] in degree.
21
+ name_cam (str): Name of the camera.
22
+ unit_angle (str): Unit of angle 'degrees', 'radian'.
23
+ linear_alteration (bool): True if z shot is correct of linear alteration.
24
+ order_axe (str): Order of rotation matrix axes.
25
+ """
26
+ def __init__(self, name_shot: str, pos_shot: np.ndarray,
27
+ ori_shot: np.ndarray, name_cam: str,
28
+ unit_angle: str, linear_alteration: bool,
29
+ order_axe: str) -> None:
30
+ self.name_shot = name_shot
31
+ self.pos_shot = pos_shot
32
+ self.pos_shot_eucli = None
33
+ self.linear_alteration = linear_alteration
34
+ self.ori_shot = ori_shot
35
+ self.unit_angle = unit_angle
36
+ self.name_cam = name_cam
37
+ self.order_axe = order_axe
38
+ self.z_nadir = None
39
+ self.co_points = {}
40
+ self.gcp2d = {}
41
+ self.gcp3d = {}
42
+ self.mat_rot = self.set_rot_shot()
43
+ self.mat_rot_eucli = None
44
+ self.projeucli = None
45
+ self.approxeucli = False
46
+ self.f_sys = lambda x_shot, y_shot, z_shot: (x_shot, y_shot, z_shot)
47
+ self.f_sys_inv = lambda x_shot, y_shot, z_shot: (x_shot, y_shot, z_shot)
48
+
49
+ @classmethod
50
+ def from_param_euclidean(cls, name_shot: str, pos_eucli: np.ndarray,
51
+ mat_ori_eucli: np.ndarray, name_cam: str,
52
+ unit_angle: str, linear_alteration: bool,
53
+ order_axe: str, approx: bool) -> None:
54
+ """
55
+ Construction of a shot object using the Euclidean position.
56
+
57
+ Args:
58
+ name_shot (str): Name of the shot.
59
+ pos_eucli (np.array): Euclidean position of the shot.
60
+ mat_ori_eucli (np.array): Euclidean rotation matrix of the shot.
61
+ name_cam (str): Name of the camera.
62
+ unit_angle (str): Unit of angle 'degrees', 'radian'.
63
+ linear_alteration (bool): True if z shot is correct of linear alteration.
64
+ order_axe (str): Order of rotation matrix axes.
65
+ approx (bool): True if you want to use approx euclidean system.
66
+
67
+ Returns:
68
+ Shot: The shot.
69
+ """
70
+ shot = cls(name_shot, np.array([0, 0, 0]), np.array([0, 0, 0]),
71
+ name_cam, unit_angle, linear_alteration, order_axe)
72
+ shot.pos_shot_eucli = pos_eucli
73
+ shot.approxeucli = approx
74
+ if approx:
75
+ shot.projeucli = ApproxEuclideanProj(pos_eucli[0], pos_eucli[1])
76
+ else:
77
+ shot.projeucli = LocalEuclideanProj(pos_eucli[0], pos_eucli[1])
78
+ unitori = shot.unit_angle == "degree"
79
+ shot.pos_shot = shot.projeucli.eucli_to_world(pos_eucli)
80
+ shot.co_points = {}
81
+ shot.gcp3d = {}
82
+ shot.gcp2d = {}
83
+ shot.mat_rot = shot.projeucli.mat_eucli_to_mat(shot.pos_shot[0], shot.pos_shot[1],
84
+ mat_ori_eucli)
85
+ shot.mat_rot_eucli = mat_ori_eucli
86
+ order_xyz = check_order_axe(order_axe)
87
+ shot.ori_shot = -(R.from_euler("x", np.pi) *
88
+ R.from_matrix(shot.mat_rot)).as_euler(order_xyz, degrees=unitori)
89
+
90
+ shot.f_sys = lambda x_shot, y_shot, z_shot: (x_shot, y_shot, z_shot)
91
+ shot.f_sys_inv = lambda x_shot, y_shot, z_shot: (x_shot, y_shot, z_shot)
92
+
93
+ return shot
94
+
95
+ def set_rot_shot(self) -> np.ndarray:
96
+ """
97
+ Build the rotation matrix with omega phi kappa.
98
+
99
+ Returns:
100
+ np.array: The rotation matrix.
101
+ """
102
+ order_xyz = check_order_axe(self.order_axe)
103
+ rot = R.from_euler(order_xyz, -np.array(self.ori_shot), degrees=self.unit_angle == "degree")
104
+ rot = R.from_euler("x", np.pi) * rot
105
+ return rot.as_matrix()
106
+
107
+ def set_param_eucli_shot(self, approx: bool) -> None:
108
+ """
109
+ Setting up Euclidean parameters projeucli, pos_shot_eucli, mat_rot_eucli.
110
+
111
+ Args:
112
+ approx (bool): True if you want to use approx euclidean system.
113
+ """
114
+ if approx:
115
+ self.projeucli = ApproxEuclideanProj(self.pos_shot[0], self.pos_shot[1])
116
+ else:
117
+ self.projeucli = LocalEuclideanProj(self.pos_shot[0], self.pos_shot[1])
118
+
119
+ self.mat_rot_eucli = self.projeucli.mat_to_mat_eucli(self.pos_shot[0],
120
+ self.pos_shot[1],
121
+ self.mat_rot)
122
+ self.approxeucli = approx
123
+ self.pos_shot_eucli = self.projeucli.world_to_eucli(self.pos_shot)
124
+
125
+ def set_z_nadir(self, z_nadir: float) -> None:
126
+ """
127
+ Give z nadir to the shot.
128
+
129
+ Args:
130
+ z_nadir (flaot): z_nadir of the shot.
131
+ """
132
+ self.z_nadir = z_nadir
133
+
134
+ def set_unit_angle(self, unit_angle: str) -> None:
135
+ """
136
+ Allows you to change the orientation angle unit.
137
+
138
+ Args:
139
+ unit_angle (str): Unit angle.
140
+ """
141
+ if unit_angle != self.unit_angle:
142
+ self.unit_angle = unit_angle
143
+ if unit_angle == "radian":
144
+ self.ori_shot = self.ori_shot*np.pi/180
145
+ else:
146
+ self.ori_shot = self.ori_shot*180/np.pi
147
+
148
+ def set_type_z(self, type_z: str) -> None:
149
+ """
150
+ Allows you to change the type of z.
151
+
152
+ Args:
153
+ type_z (str): z type height or altitude.
154
+ """
155
+ if type_z == "height":
156
+ self.pos_shot[2] = ProjEngine().tranform_height(self.pos_shot)
157
+ else:
158
+ self.pos_shot[2] = ProjEngine().tranform_altitude(self.pos_shot)
159
+
160
+ def set_linear_alteration(self, linear_alteration: bool) -> None:
161
+ """
162
+ Allows you to correct or de-correct the linear alteration.
163
+
164
+ Args:
165
+ linear_alteration (bool): Linear alteration boolean.
166
+ """
167
+ if linear_alteration != self.linear_alteration:
168
+ self.linear_alteration = linear_alteration
169
+ if linear_alteration:
170
+ self.pos_shot[2] = self.get_z_add_scale_factor()
171
+ else:
172
+ self.pos_shot[2] = self.get_z_remove_scale_factor()
173
+
174
+ def set_order_axe(self, order_axe: str) -> None:
175
+ """
176
+ Allows to change order of axe for the matrice and angle.
177
+
178
+ Args:
179
+ order_axe (str): New order axe.
180
+ """
181
+ if order_axe != self.order_axe:
182
+ self.order_axe = order_axe
183
+ order_xyz = check_order_axe(self.order_axe)
184
+ unitori = self.unit_angle == "degree"
185
+ self.ori_shot = -(R.from_euler("x", np.pi) *
186
+ R.from_matrix(self.mat_rot)).as_euler(order_xyz, degrees=unitori)
187
+
188
+ def get_z_remove_scale_factor(self) -> float:
189
+ """
190
+ Return Z after removing the scale factor. The Z of the object is NOT modified.
191
+
192
+ Returns:
193
+ float: z without linear alteration.
194
+ """
195
+ if self.z_nadir:
196
+ scale_factor = ProjEngine().get_scale_factor(self.pos_shot[0],
197
+ self.pos_shot[1])
198
+ new_z = (self.pos_shot[2] + scale_factor * self.z_nadir) / (1 + scale_factor)
199
+ else:
200
+ raise ValueError(f"No removing linear alteration of the z shot {self.name_shot}, "
201
+ "because no dtm or no set z_nadir of shot. For setting z_nadir "
202
+ "of shots make dtm or add work.set_z_nadir_shot()")
203
+
204
+ return new_z
205
+
206
+ def get_z_add_scale_factor(self) -> float:
207
+ """
208
+ Return Z after adding the scale factor. The Z of the object is NOT modified.
209
+
210
+ Returns:
211
+ float: z with linear alteration.
212
+ """
213
+ if self.z_nadir:
214
+ scale_factor = ProjEngine().get_scale_factor(self.pos_shot[0],
215
+ self.pos_shot[1])
216
+ new_z = self.pos_shot[2] + scale_factor * (self.pos_shot[2] - self.z_nadir)
217
+ else:
218
+ raise ValueError(f"No adding linear alteration of the z shot {self.name_shot}, "
219
+ "because no dtm or no set z_nadir of shot. For setting z_nadir "
220
+ "of shots make dtm or add work.set_z_nadir_shot()")
221
+
222
+ return new_z
@@ -0,0 +1,220 @@
1
+ """
2
+ Workdata data class module.
3
+ """
4
+ import numpy as np
5
+ from pyproj import CRS, exceptions
6
+ from borea.datastruct.shot import Shot
7
+ from borea.datastruct.camera import Camera
8
+ from borea.datastruct.gcp import GCP
9
+ from borea.geodesy.proj_engine import ProjEngine
10
+ from borea.datastruct.dtm import Dtm
11
+
12
+
13
+ # pylint: disable-next=too-many-instance-attributes
14
+ class Workdata:
15
+ """
16
+ Workdata class.
17
+ """
18
+ def __init__(self, name: str) -> None:
19
+ """
20
+ Class definition of Workdata.
21
+
22
+ Args:
23
+ name (str): Name of the worksite.
24
+ """
25
+ self.name = name
26
+ self.shots = {}
27
+ self.cameras = {}
28
+ self.co_points = {}
29
+ self.gcp2d = {}
30
+ self.gcp3d = {}
31
+ self.co_pts_world = {}
32
+ self.gcp2d_in_world = {}
33
+ self.type_z_data = None
34
+ self.type_z_shot = None
35
+ self.approxeucli = False
36
+
37
+ # pylint: disable-next=too-many-arguments
38
+ def add_shot(self, name_shot: str, pos_shot: np.ndarray,
39
+ ori_shot: np.ndarray, name_cam: str,
40
+ unit_angle: str, linear_alteration: bool,
41
+ order_axe: str) -> None:
42
+ """
43
+ Add Shot to the attribut Shots.
44
+
45
+ Args:
46
+ name_shot (str): Name of the shot.
47
+ pos_shot (np.array): Array of coordinate position [X, Y, Z].
48
+ ori_shot (np.array): Array of orientation of the shot [Omega, Phi, Kappa].
49
+ name_cam (str): Name of the camera.
50
+ unit_angle (str): Unit of angle 'degrees', 'radian'.
51
+ linear_alteration (bool): True if z shot is correct of linear alteration.
52
+ order_axe (str): Order of rotation matrix axes,
53
+ """
54
+ self.shots[name_shot] = Shot(name_shot=name_shot,
55
+ pos_shot=pos_shot,
56
+ ori_shot=ori_shot,
57
+ name_cam=name_cam,
58
+ unit_angle=unit_angle,
59
+ linear_alteration=linear_alteration,
60
+ order_axe=order_axe)
61
+
62
+ def set_proj(self, epsg: int, path_geoid: list = None) -> None:
63
+ """
64
+ Setup a projection system to the worksite.
65
+
66
+ Args:
67
+ epsg (int): Code epsg of the porjection ex: 2154.
68
+ path_geoid (str): List of GeoTIFF which represents the geoid in grid form.
69
+ """
70
+ ProjEngine.clear()
71
+ try: # Check if the epsg exist
72
+ crs = CRS.from_epsg(epsg)
73
+ del crs
74
+ except exceptions.CRSError as e_info:
75
+ raise exceptions.CRSError(f"Your EPSG:{epsg} doesn't exist") from e_info
76
+
77
+ ProjEngine().set_epsg(epsg, path_geoid)
78
+
79
+ # pylint: disable-next=too-many-arguments
80
+ def add_camera(self, name_camera: str, ppax: float, ppay: float,
81
+ focal: float, width: int, height: int) -> None:
82
+ """
83
+ Add data camera in the Worksite.
84
+
85
+ Args:
86
+ name_camera (str): Name of the camera.
87
+ ppax (float): Center of distortion in x.
88
+ ppay (float): Center of distortion in y.
89
+ focal (float): Focal of the camera.
90
+ width (int): Width of the image camera.
91
+ height (int): Height of the image camera.
92
+ """
93
+ self.cameras[name_camera] = Camera(name_camera=name_camera,
94
+ ppax=ppax,
95
+ ppay=ppay,
96
+ focal=focal,
97
+ width=width,
98
+ height=height)
99
+
100
+ def add_co_point(self, name_point: str, name_shot: str, coor2d: np.ndarray) -> None:
101
+ """
102
+ Add linking point between acquisition in two part.
103
+ One in self.co_points a dict with name_point the key and list of acquisition the result.
104
+ And One in self.shot[name_shot].co_points a dict whit
105
+ name_point the key and list of coordinate x (column) y (line) the result in list.
106
+
107
+ Agrs:
108
+ name_point (str): Name of the connecting point.
109
+ name_shot (str): Name of the acquisition.
110
+ coor2d (array): Pixel position in the shot [x, y] = [column, line]
111
+ """
112
+ if name_shot not in self.shots:
113
+ raise ValueError(f"The shot {name_shot} doesn't exist in list of shots.")
114
+
115
+ if name_point not in self.co_points:
116
+ self.co_points[name_point] = []
117
+
118
+ if name_point not in self.shots[name_shot].co_points:
119
+ self.shots[name_shot].co_points[name_point] = coor2d
120
+ else:
121
+ print("\n :--------------------------:")
122
+ print("Warning : connecting point duplicate.")
123
+ print(f"The point {name_point} already exists in the shot {name_shot}.")
124
+ print("Keep first point with coordinates " +
125
+ f"{self.shots[name_shot].co_points[name_point]}.")
126
+ print(":--------------------------:")
127
+
128
+ self.co_points[name_point].append(name_shot)
129
+
130
+ def add_gcp2d(self, name_point: str, name_shot: str, coor2d: np.ndarray) -> None:
131
+ """
132
+ Add linking point between acquisition in two part.
133
+ One in self.gcp2d a dict with name_point the key
134
+ and list of acquisition the result.
135
+ And One in self.shot[name_shot].gcp2d a dict whit
136
+ name_point the key and list of coordinate x (column) y (line) the result in list.
137
+
138
+ Agrs:
139
+ name_point (str): Name of the connecting point.
140
+ name_shot (str): Name of the acquisition.
141
+ coor2d (array): Pixel position in the shot [x, y] = [column, line]
142
+ """
143
+ try:
144
+ self.shots[name_shot]
145
+ except KeyError as e_info:
146
+ raise ValueError(f"The shot {name_shot} doesn't exist in list of shots.") from e_info
147
+
148
+ if name_point not in self.gcp2d:
149
+ self.gcp2d[name_point] = []
150
+
151
+ if name_point not in self.shots[name_shot].gcp2d:
152
+ self.shots[name_shot].gcp2d[name_point] = coor2d
153
+ else:
154
+ print("\n :--------------------------:")
155
+ print("Warning : connecting point duplicate.")
156
+ print(f"The point {name_point} already exists in the shot {name_shot}.")
157
+ print("Keep first point with coordinates " +
158
+ f"{self.shots[name_shot].gcp2d[name_point]}.")
159
+ print(":--------------------------:")
160
+
161
+ self.gcp2d[name_point].append(name_shot)
162
+
163
+ def add_gcp3d(self, name_gcp: str, code_gcp: str, coor_gcp: np.ndarray) -> None:
164
+ """
165
+ Add GCP in the Worksite.
166
+
167
+ Args:
168
+ name_gcp (str): Name of the gcp.
169
+ code_gcp (str): IGN code to differentiate between support points (1, 2, 3)
170
+ and control points (11, 12, 13).
171
+ 1 means precision in Z, 2 in X and Y and 3 in X, Y, Z.
172
+ coor_gcp (numpy.array): Array of ground coordinate [X, Y, Z].
173
+ """
174
+ self.gcp3d[name_gcp] = GCP(name_gcp, code_gcp, coor_gcp)
175
+
176
+ def set_dtm(self, path_dtm: str, type_dtm: str) -> None:
177
+ """
178
+ Set class DtM to the worksite.
179
+
180
+ Args:
181
+ path_dtm (str): Path to the dtm.
182
+ type (str): Type of the dtm "altitude" or "height".
183
+ """
184
+ if path_dtm:
185
+ if type_dtm not in ["altitude", "height"]:
186
+ raise ValueError(f"The dtm's type {type_dtm} isn't correct"
187
+ " ('altitude' or 'height')")
188
+
189
+ Dtm.clear()
190
+ Dtm().set_dtm(path_dtm, type_dtm)
191
+
192
+ def set_approx_eucli_proj(self, approx: bool) -> None:
193
+ """
194
+ Setup approxeucli in worksite.
195
+
196
+ Args:
197
+ apprx (bool): True if there are not projengine.
198
+ """
199
+ self.approxeucli = approx
200
+
201
+ def set_type_z_shot(self, type_z_shot: str) -> None:
202
+ """
203
+ Setup type_z_shot in worksite.
204
+
205
+ Args:
206
+ type_z_shot (str): altitude or height.
207
+ """
208
+ self.type_z_shot = type_z_shot
209
+
210
+ def set_type_z_data(self, type_z_data: str) -> None:
211
+ """
212
+ Setup type_z_data with one condition if is None.
213
+
214
+ Args:
215
+ type_z_data (str): altitude or height.
216
+ """
217
+ if type_z_data:
218
+ self.type_z_data = type_z_data
219
+ else:
220
+ self.type_z_data = self.type_z_shot
File without changes