BERATools 0.2.0__py3-none-any.whl → 0.2.1__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.
- beratools/__init__.py +1 -7
- beratools/core/algo_centerline.py +491 -351
- beratools/core/algo_common.py +497 -0
- beratools/core/algo_cost.py +192 -0
- beratools/core/{dijkstra_algorithm.py → algo_dijkstra.py} +503 -460
- beratools/core/algo_footprint_rel.py +577 -0
- beratools/core/algo_line_grouping.py +944 -0
- beratools/core/algo_merge_lines.py +214 -0
- beratools/core/algo_split_with_lines.py +304 -0
- beratools/core/algo_tiler.py +428 -0
- beratools/core/algo_vertex_optimization.py +469 -0
- beratools/core/constants.py +52 -86
- beratools/core/logger.py +76 -85
- beratools/core/tool_base.py +196 -133
- beratools/gui/__init__.py +11 -15
- beratools/gui/{beratools.json → assets/beratools.json} +2185 -2300
- beratools/gui/batch_processing_dlg.py +513 -463
- beratools/gui/bt_data.py +481 -487
- beratools/gui/bt_gui_main.py +710 -691
- beratools/gui/main.py +26 -0
- beratools/gui/map_window.py +162 -146
- beratools/gui/tool_widgets.py +725 -493
- beratools/tools/Beratools_r_script.r +1120 -1120
- beratools/tools/Ht_metrics.py +116 -116
- beratools/tools/__init__.py +7 -7
- beratools/tools/batch_processing.py +136 -132
- beratools/tools/canopy_threshold_relative.py +672 -670
- beratools/tools/canopycostraster.py +222 -222
- beratools/tools/centerline.py +136 -176
- beratools/tools/common.py +857 -885
- beratools/tools/fl_regen_csf.py +428 -428
- beratools/tools/forest_line_attributes.py +408 -408
- beratools/tools/line_footprint_absolute.py +213 -363
- beratools/tools/line_footprint_fixed.py +436 -282
- beratools/tools/line_footprint_functions.py +733 -720
- beratools/tools/line_footprint_relative.py +73 -64
- beratools/tools/line_grouping.py +45 -0
- beratools/tools/ln_relative_metrics.py +615 -615
- beratools/tools/r_cal_lpi_elai.r +24 -24
- beratools/tools/r_generate_pd_focalraster.r +100 -100
- beratools/tools/r_interface.py +79 -79
- beratools/tools/r_point_density.r +8 -8
- beratools/tools/rpy_chm2trees.py +86 -86
- beratools/tools/rpy_dsm_chm_by.py +81 -81
- beratools/tools/rpy_dtm_by.py +63 -63
- beratools/tools/rpy_find_cellsize.py +43 -43
- beratools/tools/rpy_gnd_csf.py +74 -74
- beratools/tools/rpy_hummock_hollow.py +85 -85
- beratools/tools/rpy_hummock_hollow_raster.py +71 -71
- beratools/tools/rpy_las_info.py +51 -51
- beratools/tools/rpy_laz2las.py +40 -40
- beratools/tools/rpy_lpi_elai_lascat.py +466 -466
- beratools/tools/rpy_normalized_lidar_by.py +56 -56
- beratools/tools/rpy_percent_above_dbh.py +80 -80
- beratools/tools/rpy_points2trees.py +88 -88
- beratools/tools/rpy_vegcoverage.py +94 -94
- beratools/tools/tiler.py +48 -206
- beratools/tools/tool_template.py +69 -54
- beratools/tools/vertex_optimization.py +61 -620
- beratools/tools/zonal_threshold.py +144 -144
- beratools-0.2.1.dist-info/METADATA +109 -0
- beratools-0.2.1.dist-info/RECORD +74 -0
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/WHEEL +1 -1
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/licenses/LICENSE +22 -22
- beratools/gui/cli.py +0 -18
- beratools/gui/gui.json +0 -8
- beratools/gui_tk/ASCII Banners.txt +0 -248
- beratools/gui_tk/__init__.py +0 -20
- beratools/gui_tk/beratools_main.py +0 -515
- beratools/gui_tk/bt_widgets.py +0 -442
- beratools/gui_tk/cli.py +0 -18
- beratools/gui_tk/img/BERALogo.png +0 -0
- beratools/gui_tk/img/closed.gif +0 -0
- beratools/gui_tk/img/closed.png +0 -0
- beratools/gui_tk/img/open.gif +0 -0
- beratools/gui_tk/img/open.png +0 -0
- beratools/gui_tk/img/tool.gif +0 -0
- beratools/gui_tk/img/tool.png +0 -0
- beratools/gui_tk/main.py +0 -14
- beratools/gui_tk/map_window.py +0 -144
- beratools/gui_tk/runner.py +0 -1481
- beratools/gui_tk/tooltip.py +0 -55
- beratools/third_party/pyqtlet2/__init__.py +0 -9
- beratools/third_party/pyqtlet2/leaflet/__init__.py +0 -26
- beratools/third_party/pyqtlet2/leaflet/control/__init__.py +0 -6
- beratools/third_party/pyqtlet2/leaflet/control/control.py +0 -59
- beratools/third_party/pyqtlet2/leaflet/control/draw.py +0 -52
- beratools/third_party/pyqtlet2/leaflet/control/layers.py +0 -20
- beratools/third_party/pyqtlet2/leaflet/core/Parser.py +0 -24
- beratools/third_party/pyqtlet2/leaflet/core/__init__.py +0 -2
- beratools/third_party/pyqtlet2/leaflet/core/evented.py +0 -180
- beratools/third_party/pyqtlet2/leaflet/layer/__init__.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/featuregroup.py +0 -34
- beratools/third_party/pyqtlet2/leaflet/layer/icon/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/layer/icon/icon.py +0 -30
- beratools/third_party/pyqtlet2/leaflet/layer/imageoverlay.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/layer.py +0 -105
- beratools/third_party/pyqtlet2/leaflet/layer/layergroup.py +0 -45
- beratools/third_party/pyqtlet2/leaflet/layer/marker/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/layer/marker/marker.py +0 -91
- beratools/third_party/pyqtlet2/leaflet/layer/tile/__init__.py +0 -2
- beratools/third_party/pyqtlet2/leaflet/layer/tile/gridlayer.py +0 -4
- beratools/third_party/pyqtlet2/leaflet/layer/tile/tilelayer.py +0 -16
- beratools/third_party/pyqtlet2/leaflet/layer/vector/__init__.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/vector/circle.py +0 -15
- beratools/third_party/pyqtlet2/leaflet/layer/vector/circlemarker.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/vector/path.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/vector/polygon.py +0 -14
- beratools/third_party/pyqtlet2/leaflet/layer/vector/polyline.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/vector/rectangle.py +0 -14
- beratools/third_party/pyqtlet2/leaflet/map/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/map/map.py +0 -220
- beratools/third_party/pyqtlet2/mapwidget.py +0 -45
- beratools/third_party/pyqtlet2/web/custom.js +0 -43
- beratools/third_party/pyqtlet2/web/map.html +0 -23
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-shadow.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.css +0 -656
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.js +0 -6
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.codeclimate.yml +0 -14
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.editorconfig +0 -4
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.gitattributes +0 -22
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.travis.yml +0 -43
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/LICENSE +0 -20
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-shadow.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.svg +0 -156
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.css +0 -10
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.js +0 -10
- beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/LICENSE +0 -22
- beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/leaflet.rotatedMarker.js +0 -57
- beratools/tools/forest_line_ecosite.py +0 -216
- beratools/tools/lapis_all.py +0 -103
- beratools/tools/least_cost_path_from_chm.py +0 -152
- beratools-0.2.0.dist-info/METADATA +0 -63
- beratools-0.2.0.dist-info/RECORD +0 -142
- /beratools/gui/{img → assets}/BERALogo.png +0 -0
- /beratools/gui/{img → assets}/closed.gif +0 -0
- /beratools/gui/{img → assets}/closed.png +0 -0
- /beratools/{gui_tk → gui/assets}/gui.json +0 -0
- /beratools/gui/{img → assets}/open.gif +0 -0
- /beratools/gui/{img → assets}/open.png +0 -0
- /beratools/gui/{img → assets}/tool.gif +0 -0
- /beratools/gui/{img → assets}/tool.png +0 -0
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/entry_points.txt +0 -0
beratools/tools/Ht_metrics.py
CHANGED
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import time
|
|
3
|
-
|
|
4
|
-
from beratools.tools.common import *
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class OperationCancelledException(Exception):
|
|
8
|
-
pass
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
try: # integrated R env
|
|
12
|
-
# check R language within env
|
|
13
|
-
current_env_path = os.environ['CONDA_PREFIX']
|
|
14
|
-
# if os.path.isdir(current_env_path):
|
|
15
|
-
os.environ['R_HOME'] = os.path.join(current_env_path, r"Lib\R")
|
|
16
|
-
os.environ['R_USER'] = os.path.expanduser('~')
|
|
17
|
-
os.environ['R_LIBS_USER'] = os.path.join(current_env_path, r"Lib\R\library")
|
|
18
|
-
|
|
19
|
-
except FileNotFoundError:
|
|
20
|
-
print("Warning: Please install R for this process!!")
|
|
21
|
-
exit()
|
|
22
|
-
|
|
23
|
-
import rpy2.robjects as robjects
|
|
24
|
-
from rpy2.robjects.packages import importr, data
|
|
25
|
-
from rpy2.robjects.vectors import StrVector
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def ht_metrics(callback, in_las_folder, cell_size, out_folder, processes, verbose):
|
|
29
|
-
r = robjects.r
|
|
30
|
-
import psutil
|
|
31
|
-
stats = psutil.virtual_memory() # returns a named tuple
|
|
32
|
-
available = getattr(stats, 'available') / 1024000000
|
|
33
|
-
if 2 < processes <= 8:
|
|
34
|
-
if available <= 50:
|
|
35
|
-
rprocesses = 2
|
|
36
|
-
elif 50 < available <= 150:
|
|
37
|
-
rprocesses = 4
|
|
38
|
-
elif 150 < available <= 250:
|
|
39
|
-
rprocesses = 8
|
|
40
|
-
else:
|
|
41
|
-
rprocesses = 8
|
|
42
|
-
|
|
43
|
-
in_las_folder = in_las_folder.replace("\\", "/")
|
|
44
|
-
out_folder = out_folder.replace("\\", "/")
|
|
45
|
-
|
|
46
|
-
# assign R script file to local variable
|
|
47
|
-
Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
|
|
48
|
-
# Defining the R script and loading the instance in Python
|
|
49
|
-
r['source'](Beratools_R_script)
|
|
50
|
-
# Loading the function defined in R script.
|
|
51
|
-
r_ht_metrics_function = robjects.globalenv['ht_metrics_lite']
|
|
52
|
-
# r_pd2cellsize =robjects.globalenv['pd2cellsize']
|
|
53
|
-
# Invoking the R function
|
|
54
|
-
# cell_size=r_pd2cellsize(in_las_folder)
|
|
55
|
-
r_ht_metrics_function(in_las_folder, cell_size, out_folder, rprocesses)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if __name__ == '__main__':
|
|
59
|
-
start_time = time.time()
|
|
60
|
-
print('Height Metrics from LiDAR process.\n'
|
|
61
|
-
'@ {}'.format(time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
|
|
62
|
-
|
|
63
|
-
r = robjects.r
|
|
64
|
-
utils = importr('utils')
|
|
65
|
-
base = importr('base')
|
|
66
|
-
utils.chooseCRANmirror(ind=12) # select the 12th mirror in the list: Canada
|
|
67
|
-
print("Checking R packages ...")
|
|
68
|
-
CRANpacknames = ['lidR', 'rgrass', 'rlas', 'future',
|
|
69
|
-
'terra'] # ,'comprehenr','na.tools','sf','sp']#,'devtools','gdal']#,'fasterRaster']
|
|
70
|
-
CRANnames_to_install = [x for x in CRANpacknames if not robjects.packages.isinstalled(x)]
|
|
71
|
-
|
|
72
|
-
if len(CRANnames_to_install) > 0:
|
|
73
|
-
utils.install_packages(StrVector(CRANnames_to_install))
|
|
74
|
-
packages_found = True
|
|
75
|
-
else:
|
|
76
|
-
packages_found = True
|
|
77
|
-
|
|
78
|
-
# if packages_found:
|
|
79
|
-
# utils.update_packages(checkBuilt = True, ask=False)
|
|
80
|
-
|
|
81
|
-
del CRANpacknames, CRANnames_to_install
|
|
82
|
-
|
|
83
|
-
print("Checking input parameters ...")
|
|
84
|
-
in_args, in_verbose = check_arguments()
|
|
85
|
-
in_las_folder = in_args.input["in_las_folder"]
|
|
86
|
-
try:
|
|
87
|
-
cell_size = float(in_args.input["cell_size"])
|
|
88
|
-
in_args.input["cell_size"] = cell_size
|
|
89
|
-
except ValueError:
|
|
90
|
-
print("Invalid input of cell_size, default value will be used")
|
|
91
|
-
in_args.input["cell_size"] = 1.0
|
|
92
|
-
out_folder = in_args.input["out_folder"]
|
|
93
|
-
|
|
94
|
-
if not os.path.exists(in_las_folder):
|
|
95
|
-
print("Error! Cannot locate Las folder, please check.")
|
|
96
|
-
exit()
|
|
97
|
-
else:
|
|
98
|
-
found = False
|
|
99
|
-
for files in os.listdir(in_las_folder):
|
|
100
|
-
if files.endswith(".las") or files.endswith(".laz"):
|
|
101
|
-
found = True
|
|
102
|
-
break
|
|
103
|
-
if not found:
|
|
104
|
-
print("Error! Cannot locate input LAS file(s), please check!")
|
|
105
|
-
exit()
|
|
106
|
-
|
|
107
|
-
if not os.path.exists(out_folder):
|
|
108
|
-
print("Warning! Cannot locate output folder, It will be created.")
|
|
109
|
-
os.makedirs(out_folder)
|
|
110
|
-
|
|
111
|
-
print("Checking input parameters ... Done")
|
|
112
|
-
|
|
113
|
-
ht_metrics(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
|
|
114
|
-
|
|
115
|
-
print('Height Metrics from LiDAR process is done in {} seconds)'
|
|
116
|
-
.format(round(time.time() - start_time, 5)))
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from beratools.tools.common import *
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class OperationCancelledException(Exception):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
try: # integrated R env
|
|
12
|
+
# check R language within env
|
|
13
|
+
current_env_path = os.environ['CONDA_PREFIX']
|
|
14
|
+
# if os.path.isdir(current_env_path):
|
|
15
|
+
os.environ['R_HOME'] = os.path.join(current_env_path, r"Lib\R")
|
|
16
|
+
os.environ['R_USER'] = os.path.expanduser('~')
|
|
17
|
+
os.environ['R_LIBS_USER'] = os.path.join(current_env_path, r"Lib\R\library")
|
|
18
|
+
|
|
19
|
+
except FileNotFoundError:
|
|
20
|
+
print("Warning: Please install R for this process!!")
|
|
21
|
+
exit()
|
|
22
|
+
|
|
23
|
+
import rpy2.robjects as robjects
|
|
24
|
+
from rpy2.robjects.packages import importr, data
|
|
25
|
+
from rpy2.robjects.vectors import StrVector
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def ht_metrics(callback, in_las_folder, cell_size, out_folder, processes, verbose):
|
|
29
|
+
r = robjects.r
|
|
30
|
+
import psutil
|
|
31
|
+
stats = psutil.virtual_memory() # returns a named tuple
|
|
32
|
+
available = getattr(stats, 'available') / 1024000000
|
|
33
|
+
if 2 < processes <= 8:
|
|
34
|
+
if available <= 50:
|
|
35
|
+
rprocesses = 2
|
|
36
|
+
elif 50 < available <= 150:
|
|
37
|
+
rprocesses = 4
|
|
38
|
+
elif 150 < available <= 250:
|
|
39
|
+
rprocesses = 8
|
|
40
|
+
else:
|
|
41
|
+
rprocesses = 8
|
|
42
|
+
|
|
43
|
+
in_las_folder = in_las_folder.replace("\\", "/")
|
|
44
|
+
out_folder = out_folder.replace("\\", "/")
|
|
45
|
+
|
|
46
|
+
# assign R script file to local variable
|
|
47
|
+
Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
|
|
48
|
+
# Defining the R script and loading the instance in Python
|
|
49
|
+
r['source'](Beratools_R_script)
|
|
50
|
+
# Loading the function defined in R script.
|
|
51
|
+
r_ht_metrics_function = robjects.globalenv['ht_metrics_lite']
|
|
52
|
+
# r_pd2cellsize =robjects.globalenv['pd2cellsize']
|
|
53
|
+
# Invoking the R function
|
|
54
|
+
# cell_size=r_pd2cellsize(in_las_folder)
|
|
55
|
+
r_ht_metrics_function(in_las_folder, cell_size, out_folder, rprocesses)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
start_time = time.time()
|
|
60
|
+
print('Height Metrics from LiDAR process.\n'
|
|
61
|
+
'@ {}'.format(time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
|
|
62
|
+
|
|
63
|
+
r = robjects.r
|
|
64
|
+
utils = importr('utils')
|
|
65
|
+
base = importr('base')
|
|
66
|
+
utils.chooseCRANmirror(ind=12) # select the 12th mirror in the list: Canada
|
|
67
|
+
print("Checking R packages ...")
|
|
68
|
+
CRANpacknames = ['lidR', 'rgrass', 'rlas', 'future',
|
|
69
|
+
'terra'] # ,'comprehenr','na.tools','sf','sp']#,'devtools','gdal']#,'fasterRaster']
|
|
70
|
+
CRANnames_to_install = [x for x in CRANpacknames if not robjects.packages.isinstalled(x)]
|
|
71
|
+
|
|
72
|
+
if len(CRANnames_to_install) > 0:
|
|
73
|
+
utils.install_packages(StrVector(CRANnames_to_install))
|
|
74
|
+
packages_found = True
|
|
75
|
+
else:
|
|
76
|
+
packages_found = True
|
|
77
|
+
|
|
78
|
+
# if packages_found:
|
|
79
|
+
# utils.update_packages(checkBuilt = True, ask=False)
|
|
80
|
+
|
|
81
|
+
del CRANpacknames, CRANnames_to_install
|
|
82
|
+
|
|
83
|
+
print("Checking input parameters ...")
|
|
84
|
+
in_args, in_verbose = check_arguments()
|
|
85
|
+
in_las_folder = in_args.input["in_las_folder"]
|
|
86
|
+
try:
|
|
87
|
+
cell_size = float(in_args.input["cell_size"])
|
|
88
|
+
in_args.input["cell_size"] = cell_size
|
|
89
|
+
except ValueError:
|
|
90
|
+
print("Invalid input of cell_size, default value will be used")
|
|
91
|
+
in_args.input["cell_size"] = 1.0
|
|
92
|
+
out_folder = in_args.input["out_folder"]
|
|
93
|
+
|
|
94
|
+
if not os.path.exists(in_las_folder):
|
|
95
|
+
print("Error! Cannot locate Las folder, please check.")
|
|
96
|
+
exit()
|
|
97
|
+
else:
|
|
98
|
+
found = False
|
|
99
|
+
for files in os.listdir(in_las_folder):
|
|
100
|
+
if files.endswith(".las") or files.endswith(".laz"):
|
|
101
|
+
found = True
|
|
102
|
+
break
|
|
103
|
+
if not found:
|
|
104
|
+
print("Error! Cannot locate input LAS file(s), please check!")
|
|
105
|
+
exit()
|
|
106
|
+
|
|
107
|
+
if not os.path.exists(out_folder):
|
|
108
|
+
print("Warning! Cannot locate output folder, It will be created.")
|
|
109
|
+
os.makedirs(out_folder)
|
|
110
|
+
|
|
111
|
+
print("Checking input parameters ... Done")
|
|
112
|
+
|
|
113
|
+
ht_metrics(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
|
|
114
|
+
|
|
115
|
+
print('Height Metrics from LiDAR process is done in {} seconds)'
|
|
116
|
+
.format(round(time.time() - start_time, 5)))
|
beratools/tools/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
6
|
-
|
|
7
|
-
name = 'tools'
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# import os
|
|
4
|
+
# import sys
|
|
5
|
+
# sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
6
|
+
|
|
7
|
+
name = 'tools'
|
|
@@ -1,132 +1,136 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
task['
|
|
38
|
-
|
|
39
|
-
task['
|
|
40
|
-
|
|
41
|
-
task['
|
|
42
|
-
task['
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
task['
|
|
46
|
-
task['
|
|
47
|
-
|
|
48
|
-
task['
|
|
49
|
-
|
|
50
|
-
task['
|
|
51
|
-
task['
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
task['
|
|
55
|
-
task['
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
step
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"""
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
1
|
+
import csv
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from PyQt5 import QtWidgets
|
|
9
|
+
|
|
10
|
+
import beratools.tools.common as bt_common
|
|
11
|
+
from beratools.gui.batch_processing_dlg import BPDialog
|
|
12
|
+
from beratools.gui.bt_data import BTData
|
|
13
|
+
|
|
14
|
+
bt = BTData()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# TODO: Check input file existence
|
|
18
|
+
def create_tool_batch_csv(project, tool_name, tasks):
|
|
19
|
+
tool_api = tool_name
|
|
20
|
+
proj_path = Path(project)
|
|
21
|
+
script_path = str(proj_path.with_name(proj_path.stem + '_' + tool_api.replace(' ', '_') + '.csv'))
|
|
22
|
+
|
|
23
|
+
param_list = bt.get_bera_tool_parameters_list(tool_name)
|
|
24
|
+
|
|
25
|
+
all_tasks = []
|
|
26
|
+
for item in tasks:
|
|
27
|
+
task = param_list
|
|
28
|
+
in_line = Path(item['in_line'])
|
|
29
|
+
in_chm = Path(item['in_chm'])
|
|
30
|
+
path_line = in_line.with_name(in_line.stem + '_output_line.shp')
|
|
31
|
+
path_footprint = in_line.with_name(in_line.stem + '_footprint.shp')
|
|
32
|
+
path_canopy = in_chm.with_name(in_chm.stem + '_canopy.tif')
|
|
33
|
+
path_cost = in_chm.with_name(in_chm.stem + '_cost.tif')
|
|
34
|
+
|
|
35
|
+
# TODO: change to tool api
|
|
36
|
+
if tool_name == 'Canopy Cost Raster':
|
|
37
|
+
task['in_chm'] = in_chm.as_posix()
|
|
38
|
+
task['out_canopy'] = path_canopy.as_posix()
|
|
39
|
+
task['out_cost'] = path_cost.as_posix()
|
|
40
|
+
elif tool_name == 'Center Line':
|
|
41
|
+
task['in_line'] = in_line.as_posix()
|
|
42
|
+
task['in_cost'] = path_cost.as_posix()
|
|
43
|
+
task['out_line'] = path_line.as_posix()
|
|
44
|
+
elif tool_name == 'Line Footprint by Static Threshold':
|
|
45
|
+
task['in_line'] = path_line.as_posix()
|
|
46
|
+
task['in_canopy'] = path_canopy.as_posix()
|
|
47
|
+
task['in_cost'] = path_cost.as_posix()
|
|
48
|
+
task['out_footprint'] = path_footprint.as_posix()
|
|
49
|
+
elif tool_name == 'Line Footprint by Dynamic Threshold':
|
|
50
|
+
task['in_line'] = path_line.as_posix()
|
|
51
|
+
task['in_chm'] = in_chm.as_posix()
|
|
52
|
+
task['out_footprint'] = in_line.with_name(in_line.stem + '_dyn_footprint.shp')
|
|
53
|
+
elif tool_name == 'Forest Line Attributes':
|
|
54
|
+
task['in_line'] = path_line.as_posix()
|
|
55
|
+
task['in_chm'] = in_chm.as_posix()
|
|
56
|
+
task['in_footprint'] = path_footprint.as_posix()
|
|
57
|
+
task['out_line'] = in_line.with_name(in_line.stem + '_line_attributes.shp').as_posix()
|
|
58
|
+
elif tool_name == 'Raster Line Attributes':
|
|
59
|
+
task['in_line'] = path_line.as_posix()
|
|
60
|
+
task['in_chm'] = in_chm.as_posix()
|
|
61
|
+
task['out_line'] = in_line.with_name(in_line.stem + '_raster_attributes.shp').as_posix()
|
|
62
|
+
|
|
63
|
+
all_tasks.append(task.copy())
|
|
64
|
+
|
|
65
|
+
header = list(task.keys())
|
|
66
|
+
|
|
67
|
+
with open(script_path, 'w', newline='') as csv_file:
|
|
68
|
+
writer = csv.DictWriter(csv_file, fieldnames=header)
|
|
69
|
+
writer.writeheader()
|
|
70
|
+
writer.writerows(all_tasks)
|
|
71
|
+
|
|
72
|
+
return script_path
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def batch_processing(callback, batch_tool_name, in_project, processes, verbose):
|
|
76
|
+
proj_data = None
|
|
77
|
+
if in_project and os.path.exists(in_project):
|
|
78
|
+
with open(in_project, 'r') as project_file:
|
|
79
|
+
proj_data = json.load(project_file)
|
|
80
|
+
|
|
81
|
+
csv_file = create_tool_batch_csv(in_project, batch_tool_name, proj_data['tasks'])
|
|
82
|
+
dialog = BPDialog(batch_tool_name)
|
|
83
|
+
dialog.open_csv(csv_file)
|
|
84
|
+
|
|
85
|
+
flag = dialog.exec()
|
|
86
|
+
|
|
87
|
+
# import tasks data
|
|
88
|
+
data = pd.read_csv(csv_file)
|
|
89
|
+
task_data = data.to_dict(orient='records')
|
|
90
|
+
|
|
91
|
+
if flag == QtWidgets.QDialog.Accepted and task_data:
|
|
92
|
+
steps = len(task_data)
|
|
93
|
+
step = 0
|
|
94
|
+
|
|
95
|
+
print('{} tasks are prepared'.format(steps))
|
|
96
|
+
print('-----------------------------------')
|
|
97
|
+
|
|
98
|
+
step = 0
|
|
99
|
+
total_steps = len(task_data)
|
|
100
|
+
for task in task_data:
|
|
101
|
+
print('Starting task #{} ...'.format(step))
|
|
102
|
+
print(' "PROGRESS_LABEL {} task {} of {}" '.format(batch_tool_name, step, total_steps), flush=True)
|
|
103
|
+
print(' %{} '.format(step / steps * 100), flush=True)
|
|
104
|
+
task = generate_task_params(task)
|
|
105
|
+
code = execute_task(bt.get_bera_tool_api(batch_tool_name), task)
|
|
106
|
+
step += 1
|
|
107
|
+
# task is cancelled
|
|
108
|
+
if code == 2:
|
|
109
|
+
break
|
|
110
|
+
|
|
111
|
+
print(' "PROGRESS_LABEL {} {} tasks finished" '.format(batch_tool_name, total_steps), flush=True)
|
|
112
|
+
print(' %{} '.format(0), flush=True)
|
|
113
|
+
|
|
114
|
+
print('Tasks finished.', flush=True)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def execute_task(tool_api, task):
|
|
118
|
+
# return 2 if task is cancelled
|
|
119
|
+
return bt.run_tool(tool_api, task, None, False)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def generate_task_params(task):
|
|
123
|
+
"""
|
|
124
|
+
When project tool_api is tiler, tool parameters are missing.
|
|
125
|
+
This function will retrieve default arguments
|
|
126
|
+
and generate new file names such as cost/canopy/centerline file names
|
|
127
|
+
"""
|
|
128
|
+
updated_task = task
|
|
129
|
+
return updated_task
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == '__main__':
|
|
133
|
+
in_args, in_verbose = bt_common.check_arguments()
|
|
134
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
135
|
+
batch_processing(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
|
|
136
|
+
sys.exit(app.exec_())
|