leveecmd 2.8.0__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 (118) hide show
  1. leveecmd/__init__.py +1 -0
  2. leveecmd/__main__.py +3 -0
  3. leveecmd/app/__init__.py +0 -0
  4. leveecmd/app/cat_ahn/__init__.py +0 -0
  5. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/__init__.py +0 -0
  6. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/buffer_ref_line.py +39 -0
  7. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/clip_rasters.py +65 -0
  8. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/collect_raster_names_to_download.py +34 -0
  9. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/collect_required_raster_names.py +28 -0
  10. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/download_rasters.py +60 -0
  11. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/dijktrajecten/dijktrajecten.cst +1 -0
  12. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/dijktrajecten/dijktrajecten.dbf +0 -0
  13. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/dijktrajecten/dijktrajecten.prj +1 -0
  14. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/dijktrajecten/dijktrajecten.shp +0 -0
  15. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/dijktrajecten/dijktrajecten.shx +0 -0
  16. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/kaart_blad_index/kaart_blad_index.cpg +1 -0
  17. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/kaart_blad_index/kaart_blad_index.dbf +0 -0
  18. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/kaart_blad_index/kaart_blad_index.prj +1 -0
  19. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/kaart_blad_index/kaart_blad_index.shp +0 -0
  20. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/dependencies/kaart_blad_index/kaart_blad_index.shx +0 -0
  21. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/examples/ref_line/mline224.cpg +1 -0
  22. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/examples/ref_line/mline224.dbf +0 -0
  23. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/examples/ref_line/mline224.prj +1 -0
  24. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/examples/ref_line/mline224.shp +0 -0
  25. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/files/examples/ref_line/mline224.shx +0 -0
  26. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/input_form.py +197 -0
  27. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/merge_rasters.py +56 -0
  28. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/test_logic.py +42 -0
  29. leveecmd/app/cat_ahn/tool_download_ahn_langs_kering/tool.py +131 -0
  30. leveecmd/app/cat_assembleren/__init__.py +18 -0
  31. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/__init__.py +0 -0
  32. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/export.py +16 -0
  33. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/export_to_geopackage.py +14 -0
  34. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/import_pfs.py +10 -0
  35. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/request_riskeer_path.py +91 -0
  36. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/test_data/DT16-2_assemblage.risk +0 -0
  37. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/test_logic.py +17 -0
  38. leveecmd/app/cat_assembleren/tool_export_pf_assem_riskeer/tool.py +32 -0
  39. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/__init__.py +0 -0
  40. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/import_in_riskeer.py +47 -0
  41. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/input_form.py +362 -0
  42. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/omzetten_invoer.py +32 -0
  43. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/test_data/DT16-2_assemblage.risk +0 -0
  44. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/test_data/assemblage_B_STPH_change.gpkg +0 -0
  45. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/test_tool.py +37 -0
  46. leveecmd/app/cat_assembleren/tool_importeer_pf_in_riskeer/tool.py +39 -0
  47. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/__init__.py +0 -0
  48. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/files/examples/element_failure_probabilities.xlsx +0 -0
  49. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/input_form.py +379 -0
  50. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/tool.py +48 -0
  51. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/validate_df_faalkansen.py +23 -0
  52. leveecmd/app/cat_assembleren/tool_overzicht_dominante_faalkansen/visualisatie.py +245 -0
  53. leveecmd/app/cat_gis/__init__.py +12 -0
  54. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/__init__.py +0 -0
  55. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/export_result.py +14 -0
  56. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/input_form.py +361 -0
  57. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/toevoegen_dijk_metrering.py +25 -0
  58. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/toevoegen_metrering.py +9 -0
  59. leveecmd/app/cat_gis/tool_voeg_dijk_metrering_toe/tool.py +46 -0
  60. leveecmd/app/cat_main.py +27 -0
  61. leveecmd/app/cat_riskeer/__init__.py +18 -0
  62. leveecmd/app/cat_riskeer/cat_gekb/__init__.py +17 -0
  63. leveecmd/app/cat_riskeer/cat_gekb/tool_export_gekb_calc_settings/__init__.py +0 -0
  64. leveecmd/app/cat_riskeer/cat_gekb/tool_export_gekb_calc_settings/generate_and_export.py +28 -0
  65. leveecmd/app/cat_riskeer/cat_gekb/tool_export_gekb_calc_settings/input_form.py +95 -0
  66. leveecmd/app/cat_riskeer/cat_gekb/tool_export_gekb_calc_settings/tool.py +23 -0
  67. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/__init__.py +0 -0
  68. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/generate_prfl_and_export.py +79 -0
  69. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/import_prfl_data.py +9 -0
  70. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/input_form.py +81 -0
  71. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/test_logic.py +17 -0
  72. leveecmd/app/cat_riskeer/cat_gekb/tool_export_prfls/tool.py +29 -0
  73. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/__init__.py +0 -0
  74. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/export_pnts.py +10 -0
  75. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/import_pnts.py +11 -0
  76. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/input_form.py +81 -0
  77. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/test_logic.py +17 -0
  78. leveecmd/app/cat_riskeer/cat_gekb/tool_export_profile_pnts/tool.py +28 -0
  79. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/__init__.py +0 -0
  80. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/files/tests/berekening_instellingen.xlsx +0 -0
  81. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/files/tests/leeg.risk +0 -0
  82. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/generate_calculations.py +86 -0
  83. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/input_form.py +168 -0
  84. leveecmd/app/cat_riskeer/cat_gekb/tool_import_gekb_calc_settings/tool.py +26 -0
  85. leveecmd/app/check_version.py +73 -0
  86. leveecmd/app/main.py +57 -0
  87. leveecmd/changelog.py +55 -0
  88. leveecmd/cmd_components/__init__.py +0 -0
  89. leveecmd/cmd_components/base_tool.py +0 -0
  90. leveecmd/cmd_components/live_controller.py +234 -0
  91. leveecmd/cmd_components/menu_options.py +206 -0
  92. leveecmd/cmd_components/required_setting.py +145 -0
  93. leveecmd/cmd_components/step_description.py +7 -0
  94. leveecmd/cmd_components/styling.py +7 -0
  95. leveecmd/cmd_components/test_base_tool.py +15 -0
  96. leveecmd/globals.py +7 -0
  97. leveecmd/logic/__init__.py +0 -0
  98. leveecmd/logic/ref_metering.py +58 -0
  99. leveecmd/logic/riskeer/__init__.py +0 -0
  100. leveecmd/logic/riskeer/get_assemblage.py +110 -0
  101. leveecmd/logic/riskeer/get_prfl_data.py +21 -0
  102. leveecmd/logic/riskeer/get_version.py +10 -0
  103. leveecmd/logic/shapely.py +46 -0
  104. leveecmd/utils/__init__.py +0 -0
  105. leveecmd/utils/df_validation/__init__.py +5 -0
  106. leveecmd/utils/df_validation/column.py +11 -0
  107. leveecmd/utils/df_validation/dataframe.py +96 -0
  108. leveecmd/utils/df_validation/filters.py +25 -0
  109. leveecmd/utils/df_validation/requirement.py +48 -0
  110. leveecmd/utils/df_validation/requirements.py +75 -0
  111. leveecmd/utils/other.py +21 -0
  112. leveecmd/utils/unit_tests.py +25 -0
  113. leveecmd/utils/validation_messages.py +40 -0
  114. leveecmd-2.8.0.dist-info/LICENSE +674 -0
  115. leveecmd-2.8.0.dist-info/METADATA +204 -0
  116. leveecmd-2.8.0.dist-info/RECORD +118 -0
  117. leveecmd-2.8.0.dist-info/WHEEL +4 -0
  118. leveecmd-2.8.0.dist-info/entry_points.txt +3 -0
leveecmd/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """ Beschrijving van leveecmd """
leveecmd/__main__.py ADDED
@@ -0,0 +1,3 @@
1
+ if __name__ == "__main__": # pragma: no cover
2
+ from leveecmd.app.main import app
3
+ app()
File without changes
File without changes
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+ import geopandas as gpd
3
+ from shapely.geometry import Polygon, LineString
4
+ import os
5
+ from typing import List, TYPE_CHECKING
6
+ import warnings
7
+
8
+ from leveecmd.cmd_components.live_controller import LiveController, DummyLiveController
9
+ from pathlib import Path
10
+ if TYPE_CHECKING:
11
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
12
+
13
+
14
+ def buffer_ref_line(
15
+ path_to_ref_line: str, buffer_distance: float, dir_to_ref_line_buffer: str, path_to_ref_line_buffer: str):
16
+ # Read ref file (and anticipate measure warning)
17
+ with warnings.catch_warnings():
18
+ warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*")
19
+ lines = gpd.read_file(path_to_ref_line)
20
+
21
+ # Create buffer
22
+ polygons: List[Polygon] = []
23
+ for line in lines.geometry:
24
+ line: LineString
25
+ polygons.append(line.buffer(distance=buffer_distance))
26
+ polygon_gdf = gpd.GeoDataFrame(geometry=polygons, crs=lines.crs)
27
+ os.makedirs(dir_to_ref_line_buffer, exist_ok=True)
28
+ polygon_gdf.to_file(Path(path_to_ref_line_buffer))
29
+
30
+
31
+ def step_buffer_ref_line(
32
+ tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_
33
+ ): # pragma: no cover
34
+ buffer_ref_line(
35
+ path_to_ref_line=tool_input.path_to_ref_line,
36
+ buffer_distance=tool_input.buffer_distance,
37
+ dir_to_ref_line_buffer=tool_input.dir_to_ref_line_buffer,
38
+ path_to_ref_line_buffer=tool_input.path_to_ref_line_buffer)
39
+ live_controller.print(f"Finished buffering ref line")
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+ import geopandas as gpd
4
+ from rasterio.mask import mask
5
+ from shapely.geometry import mapping
6
+ import os
7
+ from shapely.geometry import box
8
+ import os.path
9
+ import rasterio
10
+ from leveecmd.cmd_components.live_controller import DummyLiveController, LiveController
11
+ if TYPE_CHECKING:
12
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
13
+
14
+
15
+ def clip_rasters(path_to_ref_line_buffer: str, export_dir: str, required_raster_names: list[str], ahn_tiles_dir: str):
16
+
17
+ # Load the polygon shapefile
18
+ polygon = gpd.read_file(path_to_ref_line_buffer)
19
+ geoms = [mapping(geom) for geom in polygon.geometry]
20
+
21
+ # Create clip folder
22
+ clips_dir = os.path.join(export_dir, "clips")
23
+ os.makedirs(clips_dir, exist_ok=True)
24
+
25
+ # Create clips
26
+ for raster_file_name in required_raster_names:
27
+ print(f"Now clipping raster: {raster_file_name}.")
28
+
29
+ file_path = os.path.join(ahn_tiles_dir, raster_file_name)
30
+ if not os.path.isfile(file_path): # pragma: no cover
31
+ continue
32
+ if not raster_file_name.endswith(".tif"): # pragma: no cover
33
+ continue
34
+
35
+ # Open the raster file
36
+ with rasterio.open(file_path) as src:
37
+
38
+ raster_bounds = src.bounds
39
+ raster_box = box(*raster_bounds)
40
+ if not polygon.intersects(raster_box).any(): # pragma: no cover
41
+ print(f"{raster_file_name} does not overlap polygon and is skipped")
42
+ continue
43
+
44
+ out_image, out_transform = mask(src, geoms, crop=True)
45
+ out_meta = src.meta.copy()
46
+
47
+ # Update metadata
48
+ out_meta.update({
49
+ "driver": "GTiff",
50
+ "height": out_image.shape[1],
51
+ "width": out_image.shape[2],
52
+ "transform": out_transform
53
+ })
54
+
55
+ # Save the clipped raster
56
+ with rasterio.open(os.path.join(clips_dir, f"clip_{raster_file_name}"), "w", **out_meta) as dest:
57
+ dest.write(out_image)
58
+ print(f" -> Finished clipping raster {raster_file_name}.")
59
+
60
+
61
+ def step_clip_rasters(tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_): # pragma: no cover
62
+ clip_rasters(
63
+ path_to_ref_line_buffer=tool_input.path_to_ref_line_buffer, export_dir=tool_input.export_dir,
64
+ required_raster_names=tool_input.required_raster_names, ahn_tiles_dir=tool_input.ahn_tiles_dir)
65
+ live_controller.print(f" -> Finished clipping all rasters.")
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+ from typing import List, TYPE_CHECKING
3
+ import os
4
+ from leveecmd.cmd_components.live_controller import DummyLiveController, LiveController
5
+ if TYPE_CHECKING:
6
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
7
+
8
+
9
+ def collect_raster_names_to_download(required_raster_names: list[str], ahn_tiles_dir: str):
10
+ # TODO Later Should Middel: Wanneer AHN6 komt, zal deze functie foutief denken dat die al in de storage-folder
11
+ # staat. In werkelijkheid staat daar AHN5. Maar er is geen manier om het versienummer to controleren op dit moment.
12
+
13
+ rasters_to_download: List[str] = []
14
+ for raster_file_name in required_raster_names:
15
+ path_to_ahn_tile = os.path.join(ahn_tiles_dir, raster_file_name)
16
+ if not os.path.exists(path_to_ahn_tile):
17
+ rasters_to_download.append(raster_file_name)
18
+ continue
19
+ return rasters_to_download
20
+
21
+
22
+ def step_collect_raster_names_to_download(
23
+ tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_): # pragma: no cover
24
+ tool_input.rasters_to_download = collect_raster_names_to_download(
25
+ required_raster_names=tool_input.required_raster_names, ahn_tiles_dir=tool_input.ahn_tiles_dir)
26
+
27
+ # Feedback in terminal
28
+ if tool_input.rasters_to_download.__len__() == 0:
29
+ live_controller.print(
30
+ msg=f"Rasters al aanwezig in storage directory ({tool_input.ahn_tiles_dir}).", pinned=True)
31
+ else:
32
+ live_controller.print(
33
+ msg=f"Volgende rasters worden gedownload: {', '.join(tool_input.rasters_to_download)}.\n"
34
+ f"Dit gebeurt naar de directory {tool_input.ahn_tiles_dir}.", pinned=True)
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+ import geopandas as gpd
3
+ from typing import TYPE_CHECKING
4
+ from leveecmd.cmd_components.live_controller import DummyLiveController, LiveController
5
+ from importlib.resources import files
6
+ if TYPE_CHECKING:
7
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
8
+
9
+
10
+ PATH_TO_KAARTBLAD_INDEX_SHP = (
11
+ files('leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.files.dependencies.kaart_blad_index')
12
+ .joinpath('kaart_blad_index.shp'))
13
+ PARTIAL_URL_TO_PDOK = "https://service.pdok.nl/rws/ahn/atom/downloads/dtm_05m/"
14
+
15
+
16
+ def collect_required_raster_names(path_to_ref_line_buffer: str):
17
+ gdf_kaartblad_index = gpd.read_file(PATH_TO_KAARTBLAD_INDEX_SHP)
18
+ gdf_ref_line_buffer = gpd.read_file(path_to_ref_line_buffer)
19
+ pg_ref_line_buffer = gdf_ref_line_buffer.geometry.iloc[0]
20
+ gdf_overlapping: gpd.GeoDataFrame = gdf_kaartblad_index[gdf_kaartblad_index.geometry.intersects(pg_ref_line_buffer)]
21
+ return gdf_overlapping['file_name'].values.tolist()
22
+
23
+
24
+ def step_collect_required_raster_names(
25
+ tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_): # pragma: no cover
26
+ tool_input.required_raster_names = collect_required_raster_names(
27
+ path_to_ref_line_buffer=tool_input.path_to_ref_line_buffer)
28
+ live_controller.print(msg=f"Benodigde rasters: {', '.join(tool_input.required_raster_names)}", pinned=True)
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+ import requests
4
+ import os
5
+ import sys
6
+ from leveecmd.cmd_components.live_controller import DummyLiveController, LiveController
7
+ from leveecmd.utils.other import BColors
8
+ if TYPE_CHECKING:
9
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
10
+
11
+
12
+ def download_raster(raster_file_name: str, ahn_tiles_dir: str):
13
+ url = f"https://service.pdok.nl/rws/ahn/atom/downloads/dtm_05m/{raster_file_name}"
14
+
15
+ # Download raster
16
+ export_path = os.path.join(ahn_tiles_dir, raster_file_name)
17
+ try:
18
+ response = requests.get(url)
19
+ except requests.exceptions.RequestException: # pragma: no cover
20
+ print(f"{BColors.WARNING}Unable to connect to PDOK. Are you sure you are connected to the internet?\n"
21
+ f"Tried connection url was {url}.{BColors.ENDC}")
22
+ sys.exit()
23
+ with open(export_path, "wb") as f:
24
+ f.write(response.content)
25
+
26
+
27
+ def step_download_raster(
28
+ tool_input: InputAHNLangsKering,
29
+ raster_file_name: str,
30
+ live_controller: LiveController = DummyLiveController(),
31
+ **_): # pragma: no cover
32
+ live_controller.print(msg=f"Now downloading {raster_file_name}.")
33
+ download_raster(raster_file_name=raster_file_name, ahn_tiles_dir=tool_input.ahn_tiles_dir)
34
+ live_controller.print(msg=f" -> Downloaded raster {raster_file_name}.")
35
+
36
+
37
+ def download_rasters(rasters_to_download: list[str], ahn_tiles_dir: str):
38
+
39
+ if rasters_to_download.__len__() == 0: # pragma: no cover
40
+ return
41
+
42
+ print(f"Now downloading the following rasters:")
43
+ print(", ".join(rasters_to_download))
44
+ print(f"Note: It may take several minutes per raster.")
45
+
46
+ for raster_file_name in rasters_to_download:
47
+ download_raster(raster_file_name=raster_file_name, ahn_tiles_dir=ahn_tiles_dir)
48
+
49
+
50
+ def step_download_rasters(tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_): # pragma: no cover
51
+
52
+ if tool_input.rasters_to_download.__len__() == 0:
53
+ return
54
+
55
+ live_controller.print(f"Now downloading the following rasters:")
56
+ live_controller.print(", ".join(tool_input.rasters_to_download))
57
+ live_controller.print(f"Note: It may take several minutes per raster.")
58
+
59
+ for raster_file_name in tool_input.rasters_to_download:
60
+ step_download_raster(tool_input=tool_input, raster_file_name=raster_file_name, live_controller=live_controller)
@@ -0,0 +1 @@
1
+ PROJCS["Amersfoort / RD New", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067956, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4289"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 5.387638888888891], PARAMETER["latitude_of_origin", 52.15616055555556], PARAMETER["scale_factor", 0.9999079], PARAMETER["false_easting", 155000.0], PARAMETER["false_northing", 463000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28992"]]
@@ -0,0 +1 @@
1
+ PROJCS["RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Double_Stereographic"],PARAMETER["False_Easting",155000.0],PARAMETER["False_Northing",463000.0],PARAMETER["Central_Meridian",5.38763888888889],PARAMETER["Scale_Factor",0.9999079],PARAMETER["Latitude_Of_Origin",52.1561605555556],UNIT["Meter",1.0]]
@@ -0,0 +1 @@
1
+ PROJCS["RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Double_Stereographic"],PARAMETER["False_Easting",155000.0],PARAMETER["False_Northing",463000.0],PARAMETER["Central_Meridian",5.38763888888889],PARAMETER["Scale_Factor",0.9999079],PARAMETER["Latitude_Of_Origin",52.1561605555556],UNIT["Meter",1.0]]
@@ -0,0 +1,197 @@
1
+ from __future__ import annotations
2
+ from InquirerPy import inquirer
3
+ from leveecmd.cmd_components.live_controller import LiveController
4
+ from leveecmd.utils.other import BColors
5
+ import os
6
+ import shutil
7
+ from typing import Optional
8
+ from typing import TYPE_CHECKING
9
+ from geopandas import GeoDataFrame, read_file
10
+ from shapely.geometry import LineString, MultiLineString
11
+ from importlib.resources import files
12
+ from importlib.resources.readers import MultiplexedPath
13
+ from pathlib import Path
14
+ import importlib.resources
15
+ from leveecmd.utils.other import clear_terminal
16
+ if TYPE_CHECKING:
17
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
18
+
19
+
20
+ def input_ref_line(
21
+ live_controller: LiveController,
22
+ ) -> Optional[str]:
23
+
24
+ shp_file_path: Optional[str] = None
25
+ shp_file_is_valid = False
26
+ live_controller.pause()
27
+ while shp_file_is_valid is False:
28
+ shp_file_path: str = inquirer.text(
29
+ message="Specificeer het volledige bestandspad naar de referentielijn (shapefile). ",
30
+ ).execute()
31
+
32
+ shp_file_path = shp_file_path.replace('"', '')
33
+
34
+ if not shp_file_path.endswith(".shp"):
35
+ print(BColors.WARNING, f"Het bestand met een shapefile zijn, eindigend op .shp. Jouw invoer eindigt op "
36
+ f"extensie .{shp_file_path.split(sep='.')[-1]}.", BColors.ENDC)
37
+ continue
38
+
39
+ shp_file_is_valid = True
40
+ live_controller.print(msg=f"Bestandspad naar opgegeven referentielijn is '{shp_file_path}'.", pinned=True)
41
+ live_controller.resume()
42
+
43
+ return shp_file_path
44
+
45
+
46
+ def input_normtraject_number(
47
+ tool_input: InputAHNLangsKering,
48
+ live_controller: LiveController,
49
+ ) -> Optional[str]:
50
+
51
+ shp_file_path: Optional[str] = None
52
+ traject_number_is_valid = False
53
+ live_controller.pause()
54
+ while traject_number_is_valid is False:
55
+ traject_number: str = inquirer.text(
56
+ message="Specificeer het nummer van het normtraject. ",
57
+ ).execute()
58
+
59
+ # Gather traject numbers
60
+ with importlib.resources.path(
61
+ package='leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.files.dependencies.dijktrajecten',
62
+ resource='dijktrajecten.shp') as shp_path:
63
+ gdf: GeoDataFrame = read_file(shp_path)
64
+ possible_traject_numbers = gdf['TRAJECT_ID'].values.tolist()
65
+ possible_traject_numbers.sort()
66
+
67
+ # Check if number exists
68
+ if traject_number not in possible_traject_numbers:
69
+ print(BColors.WARNING,
70
+ f"Het opgegeven trajectnummer '{traject_number}' is niet beschikbaar. De mogelijke opties zijn "
71
+ f"{', '.join(possible_traject_numbers)}. ", BColors.ENDC)
72
+ continue
73
+
74
+ # Export as shape (for user to verify, plus in line with other input options)
75
+ geom: LineString | MultiLineString = gdf[gdf['TRAJECT_ID'] == traject_number]['geometry'].iloc[0]
76
+ if isinstance(geom, LineString):
77
+ ls: LineString = geom
78
+ else:
79
+ raise NotImplementedError(f"Type {type(geom)} is not yet supported.")
80
+ gdf = GeoDataFrame(geometry=[ls], crs="EPSG:28992")
81
+ file_name = f"mline{traject_number}.shp"
82
+ export_dir_shp = os.path.join(tool_input.export_dir, "ref_line")
83
+ os.makedirs(export_dir_shp, exist_ok=True)
84
+ shp_file_path = os.path.join(export_dir_shp, file_name)
85
+ gdf.to_file(Path(os.path.join(export_dir_shp, file_name)))
86
+
87
+ traject_number_is_valid = True
88
+ live_controller.print(msg=f"Opgegeven trajectnummer is '{traject_number}'.", pinned=True)
89
+ live_controller.print(msg=f"Kopie van referentielijn opgeslagen onder '{shp_file_path}'.", pinned=True)
90
+
91
+ live_controller.resume()
92
+
93
+ return shp_file_path
94
+
95
+
96
+ def input_export_dir(
97
+ live_controller: LiveController,
98
+ ):
99
+
100
+ export_dir_path: Optional[str] = None
101
+ export_dir_is_valid = False
102
+ live_controller.pause()
103
+ while export_dir_is_valid is False:
104
+ export_dir_path: str = inquirer.text(
105
+ message="Specificeer het volledige bestandspad naar de exporteer locatie.",
106
+ ).execute()
107
+
108
+ export_dir_path = export_dir_path.replace('"', '')
109
+
110
+ if not os.path.exists(export_dir_path):
111
+ print(BColors.WARNING, f"De opgegeven map bestaat niet.", BColors.ENDC)
112
+ continue
113
+ if not os.path.isdir(export_dir_path):
114
+ print(BColors.WARNING, f"De opgegeven locatie is geen map.", BColors.ENDC)
115
+ continue
116
+ if os.listdir(export_dir_path):
117
+ print(BColors.WARNING, f"De opgegeven map is niet leeg. ", BColors.ENDC)
118
+ continue
119
+
120
+ export_dir_is_valid = True
121
+ live_controller.print(msg=f"Opgegeven export directory is '{export_dir_path}'.", pinned=True)
122
+
123
+ live_controller.resume()
124
+
125
+ return export_dir_path
126
+
127
+
128
+ def get_path_from_multiplexed_path(multiplexed: MultiplexedPath) -> Path:
129
+ # noinspection PyProtectedMember
130
+ # noinspection PyUnresolvedReferences
131
+ paths: list[Path] = multiplexed._paths
132
+ assert paths.__len__() == 1
133
+ return paths[0]
134
+
135
+
136
+ def input_ref_line_example_or_custom(
137
+ tool_input: InputAHNLangsKering,
138
+ live_controller: LiveController,
139
+ ):
140
+
141
+ live_controller.pause()
142
+ choice = inquirer.select(
143
+ message="Wil je een voorbeeld referentielijn gebruiken? De mline van een normtraject? "
144
+ "Of een eigen shapefile met referentielijn?",
145
+ choices=["Voorbeeld referentielijn", "Normtraject", "Eigen referentielijn"],
146
+ default="Voorbeeld referentielijn",
147
+ ).execute()
148
+ live_controller.resume()
149
+
150
+ live_controller.print(msg=f"Type gekozen referentielijn is '{choice}'.", pinned=True)
151
+ if choice == "Voorbeeld referentielijn":
152
+ shp_dir = files("leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.files.examples.ref_line")
153
+ assert isinstance(shp_dir, MultiplexedPath)
154
+ shp_dir = get_path_from_multiplexed_path(shp_dir)
155
+ assert isinstance(shp_dir, Path), f"Expected type Path from shp_dir, got type {type(shp_dir)}."
156
+ new_dir = os.path.join(tool_input.export_dir, "ref_line")
157
+ shutil.copytree(src=shp_dir, dst=new_dir)
158
+ tool_input.path_to_ref_line = os.path.join(new_dir, "mline224.shp")
159
+ elif choice == "Normtraject":
160
+ tool_input.path_to_ref_line = input_normtraject_number(tool_input=tool_input, live_controller=live_controller)
161
+ elif choice == "Eigen referentielijn":
162
+ tool_input.path_to_ref_line = input_ref_line(live_controller=live_controller)
163
+ else:
164
+ raise ValueError()
165
+
166
+
167
+ def input_buffer_distance(
168
+ tool_input: InputAHNLangsKering,
169
+ live_controller: LiveController,
170
+ ):
171
+
172
+ buffer_distance_is_valid = False
173
+ live_controller.pause()
174
+ while buffer_distance_is_valid is False:
175
+ buffer_afstand: str = inquirer.text(
176
+ message="Specificeer de buffer afstand vanaf referentie lijn in hele meters. ",
177
+ ).execute()
178
+
179
+ try:
180
+ tool_input.buffer_distance = int(buffer_afstand)
181
+ buffer_distance_is_valid = True
182
+ live_controller.print(msg=f"Gekozen buffer distance is '{tool_input.buffer_distance} meter'.", pinned=True)
183
+ except ValueError:
184
+ print(BColors.WARNING, f"De invoer '{buffer_afstand}' is geen geldig geheel getal.", BColors.ENDC)
185
+
186
+ live_controller.resume()
187
+
188
+
189
+ def input_form(
190
+ tool_input: InputAHNLangsKering,
191
+ live_controller: LiveController,
192
+ **_
193
+ ):
194
+ clear_terminal()
195
+ tool_input.export_dir = input_export_dir(live_controller=live_controller)
196
+ input_ref_line_example_or_custom(tool_input=tool_input, live_controller=live_controller)
197
+ input_buffer_distance(tool_input=tool_input, live_controller=live_controller)
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+ import os
4
+ import os.path
5
+ import rasterio
6
+ from rasterio.merge import merge
7
+ from pathlib import Path
8
+ import numpy as np
9
+ from leveecmd.cmd_components.live_controller import DummyLiveController, LiveController
10
+ import shutil
11
+ if TYPE_CHECKING:
12
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.tool import InputAHNLangsKering
13
+
14
+
15
+ def merge_clips(export_dir: str):
16
+
17
+ # Folder containing the clipped rasters
18
+ clips_dir = Path(os.path.join(export_dir, "clips"))
19
+
20
+ # List all TIF files
21
+ clip_files = list(clips_dir.glob("*.tif"))
22
+
23
+ # Open all raster files
24
+ src_files_to_mosaic = [rasterio.open(fp) for fp in clip_files]
25
+
26
+ # Merge the rasters
27
+ mosaic, out_transform = merge(src_files_to_mosaic, nodata=np.nan)
28
+
29
+ # Copy metadata from one of the input files
30
+ out_meta = src_files_to_mosaic[0].meta.copy()
31
+ out_meta.update({
32
+ "height": mosaic.shape[1],
33
+ "width": mosaic.shape[2],
34
+ "transform": out_transform,
35
+ "nodata": np.nan
36
+ })
37
+
38
+ # Save the merged raster
39
+ dir_merged = Path(os.path.join(export_dir, "merged"))
40
+ os.makedirs(dir_merged, exist_ok=True)
41
+ merged_file_path = os.path.join(dir_merged, "merged_output.tif")
42
+ with rasterio.open(merged_file_path, "w", **out_meta) as dest:
43
+ dest.write(mosaic)
44
+
45
+ # Remove redundant files (now the app is done)
46
+ for raster in src_files_to_mosaic:
47
+ raster.close()
48
+ shutil.rmtree(clips_dir)
49
+
50
+ return merged_file_path
51
+
52
+
53
+ def step_merge_clips(tool_input: InputAHNLangsKering, live_controller: LiveController = DummyLiveController(), **_): # pragma: no cover
54
+ merged_file_path = merge_clips(export_dir=tool_input.export_dir)
55
+ live_controller.print(msg=f"Exported to {merged_file_path}", pinned=True)
56
+ live_controller.print(f"Merge completed")
@@ -0,0 +1,42 @@
1
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.buffer_ref_line import buffer_ref_line
2
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.collect_required_raster_names import (
3
+ collect_required_raster_names)
4
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.collect_raster_names_to_download import (
5
+ collect_raster_names_to_download)
6
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.download_rasters import download_rasters
7
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.clip_rasters import clip_rasters
8
+ from leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.merge_rasters import merge_clips
9
+ from importlib.resources import files
10
+ import os
11
+ import pytest
12
+
13
+
14
+ @pytest.mark.slow
15
+ def test_ahn_langs_kering_logic(tmpdir):
16
+
17
+ # TODO: Require internet for this unit test, otherwise end here.
18
+
19
+ # Buffer
20
+ dir_to_ref_line_buffer = os.path.join(tmpdir, "ref_line_buffer")
21
+ path_to_ref_line_buffer = os.path.join(dir_to_ref_line_buffer, "ref_line_buffer.shp")
22
+ path_to_ref_line = str(files(
23
+ "leveecmd.app.cat_ahn.tool_download_ahn_langs_kering.files.examples.ref_line").joinpath("mline224.shp"))
24
+ buffer_ref_line(
25
+ path_to_ref_line=path_to_ref_line, buffer_distance=50, dir_to_ref_line_buffer=dir_to_ref_line_buffer,
26
+ path_to_ref_line_buffer=path_to_ref_line_buffer)
27
+
28
+ # Required rasters
29
+ required_raster_names = collect_required_raster_names(path_to_ref_line_buffer=path_to_ref_line_buffer)
30
+ ahn_tiles_dir = os.path.join(tmpdir, "ahn_tiles")
31
+ os.makedirs(ahn_tiles_dir, exist_ok=True)
32
+ rasters_to_download = collect_raster_names_to_download(
33
+ required_raster_names=required_raster_names, ahn_tiles_dir=ahn_tiles_dir)
34
+ download_rasters(rasters_to_download=rasters_to_download, ahn_tiles_dir=ahn_tiles_dir)
35
+
36
+ # Clip rasters
37
+ clip_rasters(
38
+ path_to_ref_line_buffer=path_to_ref_line_buffer, export_dir=tmpdir,
39
+ required_raster_names=required_raster_names, ahn_tiles_dir=ahn_tiles_dir)
40
+
41
+ # Merge clips
42
+ merge_clips(export_dir=tmpdir)