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
@@ -0,0 +1,55 @@
1
+ """
2
+ Photogrammetry worksite to writing in rpc.
3
+ """
4
+ import os
5
+ from pathlib import Path, PureWindowsPath
6
+ from borea.format.rpc import Rpc
7
+ from borea.worksite.worksite import Worksite
8
+ from borea.datastruct.dtm import Dtm
9
+
10
+
11
+ def write(name: str, folder_rpc: str, param_rpc: dict, work: Worksite) -> None:
12
+ """
13
+ Converte Worksite in RPC class and save it in txt.
14
+
15
+ Args:
16
+ name (str): Name of file begin.
17
+ folder_rpc (str): Path of folder to registration file .txt.
18
+ param_rpc (dict): Dictionary of parameters for rpc calculation.
19
+ key;
20
+ "size_grid"; size of the grip to calcule rpc.
21
+ "order"; order of the polynome of the rpc.
22
+ "fact_rpc"; rpc factor for world coordinate when src is not WGS84.
23
+ work (Worksite): The site to be recorded.
24
+ """
25
+ _ = name
26
+ keys = ["ERR_BIAS", "ERR_RAND", "LINE_OFF", "SAMP_OFF",
27
+ "LAT_OFF", "LONG_OFF", "HEIGHT_OFF", "LINE_SCALE",
28
+ "SAMP_SCALE", "LAT_SCALE", "LONG_SCALE",
29
+ "HEIGHT_SCALE"]
30
+
31
+ work.set_unit_shot(type_z=Dtm().type_dtm)
32
+
33
+ for name_shot, shot in work.shots.items():
34
+ cam = work.cameras[shot.name_cam]
35
+
36
+ rpc = Rpc.from_shot(shot, cam, param_rpc,
37
+ {"unit_z_data": work.type_z_data, "unit_z_shot": work.type_z_shot})
38
+
39
+ list_txt_rpc = [f"{key}: {rpc.param_rpc[key]}" for key in keys]
40
+
41
+ for idx, val in enumerate(rpc.param_rpc["LINE_NUM_COEFF"]):
42
+ list_txt_rpc += [f"LINE_NUM_COEFF_{idx + 1}: {val}"]
43
+
44
+ for idx, val in enumerate(rpc.param_rpc["LINE_DEN_COEFF"]):
45
+ list_txt_rpc += [f"LINE_DEN_COEFF_{idx + 1}: {val}"]
46
+
47
+ for idx, val in enumerate(rpc.param_rpc["SAMP_NUM_COEFF"]):
48
+ list_txt_rpc += [f"SAMP_NUM_COEFF_{idx + 1}: {val}"]
49
+
50
+ for idx, val in enumerate(rpc.param_rpc["SAMP_DEN_COEFF"]):
51
+ list_txt_rpc += [f"SAMP_DEN_COEFF_{idx + 1}: {val}"]
52
+
53
+ path_rpc = os.path.join(Path(PureWindowsPath(folder_rpc)),
54
+ f"{name_shot}_RPC.TXT")
55
+ Path(path_rpc).write_text("\n".join(list_txt_rpc), encoding="UTF-8")
File without changes
@@ -0,0 +1,33 @@
1
+ """
2
+ Main to control opk file
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_func.p_control import args_control, process_args_control # noqa: E402
12
+
13
+
14
+ def opk_control():
15
+ """
16
+ Controls the accuracy of an OPK file with support points.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Photogrammetric site control opk file')
19
+
20
+ # Args for implement control opk
21
+ parser = args_reading_opk(parser)
22
+ parser = args_control(parser)
23
+
24
+ args = parser.parse_args()
25
+
26
+ # Process to read data
27
+ work = process_args_read_opk(args)
28
+ # Process to control data
29
+ process_args_control(args, work)
30
+
31
+
32
+ if __name__ == "__main__":
33
+ opk_control()
@@ -0,0 +1,33 @@
1
+ """
2
+ Main to convert opk file to an light conical file (it's an xml file for GEOVIEW IGN France)
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_format.p_write_con import args_write_con, process_args_write_con # noqa: E402
12
+
13
+
14
+ def opk_to_conl():
15
+ """
16
+ Converts an OPK file into an light conical (IGN format) file.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Photogrammetric site conversion '
19
+ 'opk to conical file.')
20
+ # Args for implement opk to conl
21
+ parser = args_reading_opk(parser)
22
+ parser = args_write_con(parser)
23
+
24
+ args = parser.parse_args()
25
+
26
+ # Process to read data
27
+ work = process_args_read_opk(args)
28
+ # Process to write conl
29
+ process_args_write_con(args, work)
30
+
31
+
32
+ if __name__ == "__main__":
33
+ opk_to_conl()
@@ -0,0 +1,33 @@
1
+ """
2
+ Main to convert opk file to an other opk file
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position, line-too-long
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_format.p_write_opk import args_writing_opk, process_args_write_opk # noqa: E402, E501
12
+
13
+
14
+ def opk_to_opk():
15
+ """
16
+ Converts an OPK file into an OPK file.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Photogrammetric site conversion'
19
+ ' and manipulation software opk to opk.')
20
+ # Args for implement opk to opk
21
+ parser = args_reading_opk(parser)
22
+ parser = args_writing_opk(parser)
23
+
24
+ args = parser.parse_args()
25
+
26
+ # Process to read data
27
+ work = process_args_read_opk(args)
28
+ # Process to write opk
29
+ process_args_write_opk(args, work)
30
+
31
+
32
+ if __name__ == "__main__":
33
+ opk_to_opk()
@@ -0,0 +1,33 @@
1
+ """
2
+ Main to convert opk file to Rpc
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position, line-too-long
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_format.p_write_rpc import args_writing_rpc, process_args_write_rpc # noqa: E402, E501
12
+
13
+
14
+ def opk_to_rpc():
15
+ """
16
+ Converts an OPK file into an RPC file.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Photogrammetric site conversion'
19
+ ' and manipulation software opk to rpc.')
20
+ # Args for implement opk to rpc
21
+ parser = args_reading_opk(parser)
22
+ parser = args_writing_rpc(parser)
23
+
24
+ args = parser.parse_args()
25
+
26
+ # Process to read data
27
+ work = process_args_read_opk(args)
28
+ # Process to write rpc
29
+ process_args_write_rpc(args, work)
30
+
31
+
32
+ if __name__ == "__main__":
33
+ opk_to_rpc()
@@ -0,0 +1,32 @@
1
+ """
2
+ Main to calculate image coodinate of the ground point.
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_add_data.p_add_shot import args_add_shot, process_add_shot # noqa: E402
11
+ from borea.process.p_add_data.p_pt2d import args_add_pt2d, process_image_world # noqa: E402
12
+
13
+
14
+ def pt_image_to_world():
15
+ """
16
+ Converts a image point into an terrain point.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Calculate image coodinate of the ground point.')
19
+ # Args for implement pt image to world
20
+ parser = args_add_shot(parser)
21
+ parser = args_add_pt2d(parser)
22
+
23
+ args = parser.parse_args()
24
+
25
+ # Process to read data
26
+ work = process_add_shot(args)
27
+ # Process to transform image to world
28
+ process_image_world(args, work)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ pt_image_to_world()
@@ -0,0 +1,32 @@
1
+ """
2
+ Main to calculate world coodinate of the image point.
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_add_data.p_add_shot import args_add_shot, process_add_shot # noqa: E402
11
+ from borea.process.p_add_data.p_pt3d import args_add_pt3d, process_world_image # noqa: E402
12
+
13
+
14
+ def pt_world_to_image():
15
+ """
16
+ Converts a terrain point into an image point.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Calculate world coodinate of the image point.')
19
+ # Args for implement pt world to image
20
+ parser = args_add_shot(parser)
21
+ parser = args_add_pt3d(parser)
22
+
23
+ args = parser.parse_args()
24
+
25
+ # Process to read data
26
+ work = process_add_shot(args)
27
+ # Process to transform world to image
28
+ process_world_image(args, work)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ pt_world_to_image()
@@ -0,0 +1,32 @@
1
+ """
2
+ Main to calculate world coodinate with opk.
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_func.p_image_world import args_image_world, process_image_world # noqa: E402
12
+
13
+
14
+ def ptfile_image_to_world():
15
+ """
16
+ Converts a image point file into an terrain point file.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Calculate ground coodinate of the image point.')
19
+ # Args for implement ptfile image to world
20
+ parser = args_reading_opk(parser)
21
+ parser = args_image_world(parser)
22
+
23
+ args = parser.parse_args()
24
+
25
+ # Process to read data
26
+ work = process_args_read_opk(args)
27
+ # Process to transform image to world
28
+ process_image_world(args, work)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ ptfile_image_to_world()
@@ -0,0 +1,32 @@
1
+ """
2
+ Main to calculate image coodinate with opk.
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_format.p_read_opk import args_reading_opk, process_args_read_opk # noqa: E402
11
+ from borea.process.p_func.p_world_image import args_world_image, process_world_image # noqa: E402
12
+
13
+
14
+ def ptfile_world_to_image():
15
+ """
16
+ Converts a terrain point file into an image point file.
17
+ """
18
+ parser = argparse.ArgumentParser(description='Calculate image coodinate of the ground point.')
19
+ # Args for implement ptfile world to image
20
+ parser = args_reading_opk(parser)
21
+ parser = args_world_image(parser)
22
+
23
+ args = parser.parse_args()
24
+
25
+ # Process to read data
26
+ work = process_args_read_opk(args)
27
+ # Process to transform world to image
28
+ process_world_image(args, work)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ ptfile_world_to_image()
@@ -0,0 +1,34 @@
1
+ """
2
+ Main to calculate 6 externals parameters of shots and save in opk file.
3
+ """
4
+ # pylint: disable=import-error, wrong-import-position, line-too-long
5
+ import argparse
6
+ import sys
7
+ import os
8
+
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
10
+ from borea.process.p_func.p_spaceresection import args_space_resection, process_space_resection # noqa: E402, E501
11
+ from borea.process.p_format.p_write_opk import args_writing_opk, process_args_write_opk # noqa: E402, E501
12
+
13
+
14
+ def spaceresection_opk():
15
+ """
16
+ Permet d'obtenir un fichier OPK à partir de point de liaison sur les images et de leur
17
+ coordonnées terrain (calcule les 6 paramètres externes pour chaque image qui dispose d'un point)
18
+ """
19
+ parser = argparse.ArgumentParser(description='Space resection of point file image and world'
20
+ ' to calculate 6 externals parameters of shots')
21
+ # Args for implement space resection( opk
22
+ parser = args_space_resection(parser)
23
+ parser = args_writing_opk(parser)
24
+
25
+ args = parser.parse_args()
26
+
27
+ # Process to read data
28
+ work = process_space_resection(args)
29
+ # Process to space resection
30
+ process_args_write_opk(args, work)
31
+
32
+
33
+ if __name__ == "__main__":
34
+ spaceresection_opk()
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Institut National de l'Information Géographique et Forestière
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.1
2
+ Name: ign-borea
3
+ Version: 0.1.5
4
+ Summary: A package to manipulate orientation files
5
+ Author-email: Antoine Cornu <antoine.cornu@ign.fr>, Nicolas Laurain <nicolas.laurain@ign.fr>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Institut National de l'Information Géographique et Forestière
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Github, https://github.com/ACornuIGN/Pink_Lady
29
+ Keywords: ign-borea,borea,aero,ign
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Programming Language :: Python :: 3.9
32
+ Classifier: Programming Language :: Python :: 3.10
33
+ Classifier: Operating System :: Microsoft :: Windows
34
+ Classifier: Operating System :: Unix
35
+ Classifier: Operating System :: MacOS
36
+ Requires-Python: >=3.9
37
+ Description-Content-Type: text/markdown
38
+ License-File: LICENSE
39
+ Requires-Dist: numpy <=1.26.4
40
+ Requires-Dist: dataclasses
41
+ Requires-Dist: pyproj
42
+ Requires-Dist: scipy
43
+ Requires-Dist: pandas
44
+ Provides-Extra: dev
45
+ Requires-Dist: numpy <=1.26.4 ; extra == 'dev'
46
+ Requires-Dist: pylint ; extra == 'dev'
47
+ Requires-Dist: pytest ; extra == 'dev'
48
+ Requires-Dist: pytest-shutil ; extra == 'dev'
49
+ Requires-Dist: flake8 ; extra == 'dev'
50
+ Requires-Dist: sphinx ; extra == 'dev'
51
+ Requires-Dist: furo ; extra == 'dev'
52
+ Requires-Dist: dataclasses ; extra == 'dev'
53
+ Requires-Dist: pyproj ; extra == 'dev'
54
+ Requires-Dist: scipy ; extra == 'dev'
55
+ Requires-Dist: pandas ; extra == 'dev'
56
+ Requires-Dist: build ; extra == 'dev'
57
+ Requires-Dist: twine ; extra == 'dev'
58
+
59
+ [![IGNF badge](https://img.shields.io/badge/IGNF-8cbd3a)](https://www.ign.fr/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ign-borea.svg?label=PyPI%20downloads)](
60
+ https://pypi.org/project/ign-borea/)
61
+
62
+ Borea is an open-source python package tools-box photogrammetric conversion format and transformation coordinate of image and terrain.
63
+ Why Borea? **B** for Box and **orea** is a back slang of aero.
64
+
65
+ ## Installation
66
+
67
+ #### Pip
68
+
69
+ Due to different dependency used installation of the library require `GDAL>=3.3.2`, which is not included in the dependency.
70
+ ```
71
+ pip install ign-borea
72
+ ```
73
+ For GDAL installation you need `libgdal-dev`:
74
+ ```
75
+ sudo apt-get install libgdal-dev
76
+ ```
77
+ Please note that the `GDAL` version depends on the `libgdal-dev` version.
78
+ ```
79
+ apt-cache show libgdal-dev
80
+ # or if you are ogr
81
+ ogrinfo --version
82
+ ```
83
+ ```
84
+ pip install GDAL==<GDAL VERSION FROM OGRINFO>
85
+ ```
86
+ You can find more information on [mothergeo-py](https://mothergeo-py.readthedocs.io/en/latest/development/how-to/gdal-ubuntu-pkg.html) if you have problems installing GDAL.
87
+
88
+ #### In the QGIS environment
89
+
90
+ View the doc on [borea github docs/installation/In_QGIS.md](https://github.com/IGNF/Borea/tree/main/docs/installation/In_QGIS.md).
91
+
92
+ ## Tools
93
+
94
+ Some tools are already implemented in the library:
95
+ * Conversion OPK to OPK: `opk-to-opk -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_opk_to_opk.md) (OPK = Omega Phi Kappa)
96
+ * Control OPK file: `opk-control -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_opk_control.md)
97
+ * Conversion OPK to RPC: `opk-to-rpc -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_opk_to_rpc.md)
98
+ * Conversion OPK to Conl: `opk-to-conl -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_opk_to_conl.md) (Conl = light conical file, IGN France format)
99
+ * Transforms coordinates terrain from image: `pt-image-to-world -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_pt_image_to_world.md)
100
+ * Transforms coordinates image from terrain: `pt-world-to-image -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_pt_world_to_image.md)
101
+ * Transforms coordinates file terrain from image: `ptfile-image-to-world -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_ptfile_image_to_world.md)
102
+ * Transforms coordinates file image from terrain: `ptfile-world-to-image -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_ptfile_world_to_image.md)
103
+ * Calculates opk by space resection: `spaceresection-opk -h` [doc](https://github.com/IGNF/Borea/tree/main/borea_tools/docs_tools/README_spaceresection_opk.md)
104
+
105
+ ## Read data and instantiate worksite
106
+
107
+ Creation of a worksite object from a worksite file (.opk) to be read by `reader_orientation(pathfile, arg_dict)` with `from borea.reader.orientation.manage_reader import reader_orientation`.
108
+ `arg_dict` is a dictionary for different args:
109
+ * `"interval":[first_line, last_line]` is an list of int that specifies the number of lines you want to read. `first_line` allows you to skip the file header, which must not be taken into account when reading the file, as specified in the `header` variable. If `first_line = None` skips everything up to `last_line`, if `lastline = None` skips everything from `first_line` to the end, and if both are None reads the entire file.
110
+ * `"header":header` described in the section above, is a list of str e.g. `['N', 'X', 'Y', 'Z', 'O', 'P', 'K', 'C'] = list("NXYZOPKC")`, detail of letter at section [header of file opk](#header-of-file-opk) below.
111
+ * `"unit_angle": "degree"` degree or radian.
112
+ * `"linear_alteration": True` boolean saying True if z shots are corrected by linear alteration.
113
+ * `"order_axe: "opk"` string to define the order of angle to calculate rotation matrix.
114
+
115
+ Once the object has been created, you can add other data to it:
116
+
117
+ * Setup the projection of the worksite `work.set_proj(epsg, path_geoid)`, with:
118
+ * `epsg` the code epsg e.g. 2154
119
+ * `path_geoid` path to the file pyproj GeoTIFF of geoid
120
+
121
+ * The camera with `read_camera([filepath], worksite)` in `from borea.reader.reader_camera import read_camera`, this function only reads txt and xml files referencing camera data, and can take several camera files if there are several.
122
+
123
+ * Link points with `read_file_pt(filepath, header, type_point, worksite)` in `from borea.reader.reader_point import read_file_pt`. this function reads all .txt, .mes, .app and other file types, as long as the data structure in the file is column-based and delimited by spaces. The first args is the file path of one file. The second is the column type in the file detail of letter at section [header of point file](#header-of-point-file) below. The third is the type of point **'co_points'** for connecting points, **'gcp2d'** for coordinnate of gcp in images and **'gcp3d'** for gcp coordinate in the ground. And the last args is the worksite where data will be save.
124
+
125
+ * Add Dtm to your worksite `work.set_dtm(path_dtm, type_dtm)`, It converts z data between gcp and acquisition position if these are not in the same unit (one in altitude and one in height). `type_dtm` is the unit of the dtm 'altitude' or 'height'.
126
+
127
+ Examples in section [examples](#examples) below.
128
+
129
+ ## Different process
130
+
131
+ * Set different parameters for shots (projection system of shot and z_nadir), mandatory if data is to be processed afterwards. `work.set_param_shot()`.
132
+
133
+ * Can calculate the position of image points in world with `ImageWorldWork(worksite).manage_image_world(type_point, type_process, type_control)` in `from borea.transform_world_image.transform_worksite.image_world_work import ImageWorldWork`.
134
+ * `type_point` is the type of point you want to calcule `co_points` or `gcp2d`.
135
+ * `type_process` is the type of process you want to use intersection with key `inter` or least square methode with key `square`.
136
+ * `type_control` egal None by default, is used if the type_point = gcp2d and if you want just one type code point, else None to process on all point.
137
+
138
+ The result can be found in `worksite.co_pts_world['name_point']` when type_point = co_points or `worksite.img_pts_world['name_point]` when type_point = gcp2d.
139
+
140
+ * Can calculate the position of terrain points in images with `WorldImageWork(work).calculate_world_to_image(type_control)` in `from borea.transform_world_image.transform_worksite.world_image_work import WorldImageWork`, with `type_control` egal None by default, is used if the type_point = gcp2d and if you want just one type code point, else None to process on all point. . The result can be found in `worksite.shots['name_shot'].gcps['name_gcp']` for each image and each gcps.
141
+
142
+ * Can calculate spatial resection for each shot in worksite with `SpaceResection(work).space_resection_on_worksite(add_pixel = (0,0))` in `from borea.transform_world_image.transform_worksite.space_resection import SpaceResection`. `add_pixel` is used to add a mainiation to the position of the points to modify the shot's 6 external parameters for data conversion.
143
+
144
+ * Can calculate spatial resection in poitn of shot for creating worksite with `SpaceResection(work).space_resection_to_worksite(pt2d, pt3d, pinit)` in `from borea.transform_world_image.transform_worksite.space_resection import SpaceResection`.
145
+ The DataFrame **pt2d** is a table with 4 column and n line. The id of column must be:
146
+ * `id_pt`: the id of the point
147
+ * `id_shot`: the name of the shot where the point is located
148
+ * `column`: column coordinate in pixel of the point in the image
149
+ * `line`: line coordinate in pixel of the point in the image
150
+
151
+ it can be created with the function `read_file_pt_dataframe(path_file_pt,header_file,"pt2d")`
152
+ The DataFrame **pt3d** is a table with 5 column and n line. The id of column must be:
153
+ * `id_pt`: the id of the point
154
+ * `type`: if point is gcp with type else None
155
+ * `x`: x coordinate in your projection system of the point
156
+ * `y`: y coordinate in your projection system of the point
157
+ * `z`: z coordinate in your projection system of the point
158
+
159
+ it can be created with the function `read_file_pt_dataframe(path_file_pt,header_file,"pt3d")`
160
+ The dictionary **pinit** which give the initialization point X, Y, Z. A point on the worksite with a z at an approximate flying height. The name of the key in the dictionary is `coor_init`.
161
+ Example at the end of explanation of function [file](https://github.com/IGNF/Borea/tree/main/docs/functions/Space_resection.md).
162
+
163
+ * You can calculate some control point statistics to see how accurate your site is `stat = Stat(work, pathreturn, control_type)` to init the object and run for all stat with `stat.main_stat_and_save()`. Make stat on function image to world and world to image, if there are data. And save result on *pathreturn/Stat_{Name_worksite}.txt*.
164
+
165
+ Examples in section [examples](#examples) below.
166
+
167
+ ## Write data
168
+
169
+ * Can write worksite object as different format OPK, RPC, Conical for GEOVIEW. The function is `manager_reader(writer, name, pathreturn, args, work)` in `from borea.writer.manage_writer import manager_writer`:
170
+ * `writer` (str), is the type of output `"opk"`, `"rpc"`, `"con"`.
171
+ * `name` (str), name of file to save, just to save in opk, for other format this args isn't read.
172
+ * `pathreturn` (str), path of folder where you want to save data.
173
+ * `args` (dict), Dictionary with different args for the format to save, detail at setion [args for writing file](#args-for-writing-file) below.
174
+ * `work` (Worksite), the worksite to save.
175
+
176
+ Examples in section [examples](#examples) below.
177
+
178
+ ## Examples
179
+
180
+ All examples are in [borea github ./examples/](https://github.com/IGNF/Borea/tree/main/examples):
181
+ * For build main class Worksite with file **eg_build_worksite_by_file.py** and with data **eg_build_worksite_by_data.py**.
182
+ * To make transformation image to world **eg_image_to_world.py**.
183
+ * To make transformation world to image **eg_world_to_image.py**.
184
+ * To make space resection on point to determine worksite **eg_space_resection.py**.
185
+ * To convert format opk to an other format opk rpc con **eg_opk_to_format.py**.
186
+
187
+ Examples of the different formats of file can be found in [borea github ./dataset/](https://github.com/IGNF/Borea/tree/main/dataset):
188
+ * An opk file **23FD1305_alt_test.OPK** with z unit is altitude.
189
+ * Cameras filesformat **Camera1.txt** and **Camera2.txt**.
190
+ * Geotiff of the French geoid for pyproj fr_ign_RAF20.tif** detail at section [info projection](#info-projection) below.
191
+ * Crops geotiff of the French DTM **MNT_France_25m_h_crop.tif** in height unit.
192
+ * Ground Control Point (GCP) in terrian **GCP_test.app** unit z in height.
193
+ * Ground Control Point (GCP) in image **terrain_test.mes**.
194
+ * Connecting points in image **liaisons_test.mes**.
195
+ * Image point to transform terrain coordinates to image coordinates to find out in which image the points are located **terrain_test0.mes**.
196
+
197
+ ## Detail
198
+
199
+ ### Header of file opk
200
+ `header` is used to describe the format of the opk file read. It provides information on what's in each column, and gives the data unit for Z and angles.
201
+ Type is:
202
+ | Symbol | Details |
203
+ | :----: | :------ |
204
+ | S | to ignore the column |
205
+ | N | name of shot |
206
+ | X | coordinate x of the shot position |
207
+ | Y | coordinate y of the shot position |
208
+ | Z | coordinate z altitude of the shot position |
209
+ | H | coordinate z height of the shot position |
210
+ | O | omega rotation angle |
211
+ | P | phi rotation angle |
212
+ | K | kappa rotation angle |
213
+ | C | name of the camera |
214
+
215
+ ### Header of point file
216
+
217
+ `header` is used to describe the format of the point file read. It provides information on what's in each column.
218
+ Type is:
219
+ | Symbol | Details |
220
+ | :----: | :------ |
221
+ | S | to ignore the column |
222
+ | P | name of the point |
223
+ | N | name of shot |
224
+ | T | type of point |
225
+ | X | coordinate x of the shot position |
226
+ | Y | coordinate y of the shot position |
227
+ | Z | coordinate z altitude of the shot position |
228
+
229
+ ### Camera file format
230
+
231
+ The camera file is a txt file, containing 6 pieces of information about the camera : its **name** (str), **ppax** (float), **ppay** (float), **focal** (float), image size: **width** (int) and **height** (int) in pixels.
232
+ **Ppax** and **ppay** are the main points of image deformation in x and y directions.
233
+ Each line of the file corresponds to a piece of information, starting with the **type = info**.
234
+ ```
235
+ name = UCE-M3-f120-s06
236
+ ppax = 13210.00
237
+ ppay = 8502.00
238
+ focal = 30975.00
239
+ width = 26460
240
+ height = 17004
241
+ ```
242
+ Only these 7 pieces of information will be read. You can add comments with a # in the first element of the line or other type = info, but they will not be read by the tool, unless the attribute has been added to the Camera class in *borea/datastruct/camera.py*.
243
+ An example file can be found in repository *./dataset/Camera1.txt*.
244
+ No camera-related distortion is taken into account (distortion-free camera).
245
+
246
+ ### Info projection
247
+
248
+ This library can transform and process 3D data with a z in altitude or height. This is done by the pyproj library, which needs the geoid at site level to change units.
249
+
250
+ The varaible in example for adding a geoid is path_geoid, a list which contains paths of geoids, where you can enter the paths to the various geoids. If the file is stored in pyproj's native folder (pyproj.datadir.get_data_dir(), *usr/share/proj* or *env_name_folder/lib/python3.10/site-packages/pyproj/proj_dir/share/proj*) the file name is sufficient pyproj will find it on its own.
251
+ Geoids file can be found on pyproj's github (https://github.com/OSGeo/PROJ-data).
252
+
253
+ ### Args for writing file
254
+
255
+ #### OPK
256
+
257
+ There are 4 keys in the dictionary:
258
+ * "order_axe" (str): **Order of rotation matrix axes**.
259
+ * "header" (list): **List of column type** file (same to read opk).
260
+ * "unit_angle" (str): Unit of angle **'degree' or 'radian'**.
261
+ * "linear_alteration" (bool): **True** if data corrected by linear alteration or else **False**.
262
+
263
+ #### RPC
264
+
265
+ There are 3 keys in the dictionary:
266
+ * "size_grid" (int): **size of the grip** to calcule rpc.
267
+ * "order" (int): order of the polynome of the rpc. **[1, 2, 3]**
268
+ * "fact_rpc" (float): rpc factor for world coordinate when not src, we recommend **None**.
269
+
270
+ #### CON
271
+
272
+ There is no need for an additional argument, you can set **None** to the argument.
273
+
274
+ ![logo ign](docs/image/logo_ign.png) ![logo fr](docs/image/Republique_Francaise_Logo.png)