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.
Files changed (153) hide show
  1. beratools/__init__.py +1 -7
  2. beratools/core/algo_centerline.py +491 -351
  3. beratools/core/algo_common.py +497 -0
  4. beratools/core/algo_cost.py +192 -0
  5. beratools/core/{dijkstra_algorithm.py → algo_dijkstra.py} +503 -460
  6. beratools/core/algo_footprint_rel.py +577 -0
  7. beratools/core/algo_line_grouping.py +944 -0
  8. beratools/core/algo_merge_lines.py +214 -0
  9. beratools/core/algo_split_with_lines.py +304 -0
  10. beratools/core/algo_tiler.py +428 -0
  11. beratools/core/algo_vertex_optimization.py +469 -0
  12. beratools/core/constants.py +52 -86
  13. beratools/core/logger.py +76 -85
  14. beratools/core/tool_base.py +196 -133
  15. beratools/gui/__init__.py +11 -15
  16. beratools/gui/{beratools.json → assets/beratools.json} +2185 -2300
  17. beratools/gui/batch_processing_dlg.py +513 -463
  18. beratools/gui/bt_data.py +481 -487
  19. beratools/gui/bt_gui_main.py +710 -691
  20. beratools/gui/main.py +26 -0
  21. beratools/gui/map_window.py +162 -146
  22. beratools/gui/tool_widgets.py +725 -493
  23. beratools/tools/Beratools_r_script.r +1120 -1120
  24. beratools/tools/Ht_metrics.py +116 -116
  25. beratools/tools/__init__.py +7 -7
  26. beratools/tools/batch_processing.py +136 -132
  27. beratools/tools/canopy_threshold_relative.py +672 -670
  28. beratools/tools/canopycostraster.py +222 -222
  29. beratools/tools/centerline.py +136 -176
  30. beratools/tools/common.py +857 -885
  31. beratools/tools/fl_regen_csf.py +428 -428
  32. beratools/tools/forest_line_attributes.py +408 -408
  33. beratools/tools/line_footprint_absolute.py +213 -363
  34. beratools/tools/line_footprint_fixed.py +436 -282
  35. beratools/tools/line_footprint_functions.py +733 -720
  36. beratools/tools/line_footprint_relative.py +73 -64
  37. beratools/tools/line_grouping.py +45 -0
  38. beratools/tools/ln_relative_metrics.py +615 -615
  39. beratools/tools/r_cal_lpi_elai.r +24 -24
  40. beratools/tools/r_generate_pd_focalraster.r +100 -100
  41. beratools/tools/r_interface.py +79 -79
  42. beratools/tools/r_point_density.r +8 -8
  43. beratools/tools/rpy_chm2trees.py +86 -86
  44. beratools/tools/rpy_dsm_chm_by.py +81 -81
  45. beratools/tools/rpy_dtm_by.py +63 -63
  46. beratools/tools/rpy_find_cellsize.py +43 -43
  47. beratools/tools/rpy_gnd_csf.py +74 -74
  48. beratools/tools/rpy_hummock_hollow.py +85 -85
  49. beratools/tools/rpy_hummock_hollow_raster.py +71 -71
  50. beratools/tools/rpy_las_info.py +51 -51
  51. beratools/tools/rpy_laz2las.py +40 -40
  52. beratools/tools/rpy_lpi_elai_lascat.py +466 -466
  53. beratools/tools/rpy_normalized_lidar_by.py +56 -56
  54. beratools/tools/rpy_percent_above_dbh.py +80 -80
  55. beratools/tools/rpy_points2trees.py +88 -88
  56. beratools/tools/rpy_vegcoverage.py +94 -94
  57. beratools/tools/tiler.py +48 -206
  58. beratools/tools/tool_template.py +69 -54
  59. beratools/tools/vertex_optimization.py +61 -620
  60. beratools/tools/zonal_threshold.py +144 -144
  61. beratools-0.2.1.dist-info/METADATA +109 -0
  62. beratools-0.2.1.dist-info/RECORD +74 -0
  63. {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/WHEEL +1 -1
  64. {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/licenses/LICENSE +22 -22
  65. beratools/gui/cli.py +0 -18
  66. beratools/gui/gui.json +0 -8
  67. beratools/gui_tk/ASCII Banners.txt +0 -248
  68. beratools/gui_tk/__init__.py +0 -20
  69. beratools/gui_tk/beratools_main.py +0 -515
  70. beratools/gui_tk/bt_widgets.py +0 -442
  71. beratools/gui_tk/cli.py +0 -18
  72. beratools/gui_tk/img/BERALogo.png +0 -0
  73. beratools/gui_tk/img/closed.gif +0 -0
  74. beratools/gui_tk/img/closed.png +0 -0
  75. beratools/gui_tk/img/open.gif +0 -0
  76. beratools/gui_tk/img/open.png +0 -0
  77. beratools/gui_tk/img/tool.gif +0 -0
  78. beratools/gui_tk/img/tool.png +0 -0
  79. beratools/gui_tk/main.py +0 -14
  80. beratools/gui_tk/map_window.py +0 -144
  81. beratools/gui_tk/runner.py +0 -1481
  82. beratools/gui_tk/tooltip.py +0 -55
  83. beratools/third_party/pyqtlet2/__init__.py +0 -9
  84. beratools/third_party/pyqtlet2/leaflet/__init__.py +0 -26
  85. beratools/third_party/pyqtlet2/leaflet/control/__init__.py +0 -6
  86. beratools/third_party/pyqtlet2/leaflet/control/control.py +0 -59
  87. beratools/third_party/pyqtlet2/leaflet/control/draw.py +0 -52
  88. beratools/third_party/pyqtlet2/leaflet/control/layers.py +0 -20
  89. beratools/third_party/pyqtlet2/leaflet/core/Parser.py +0 -24
  90. beratools/third_party/pyqtlet2/leaflet/core/__init__.py +0 -2
  91. beratools/third_party/pyqtlet2/leaflet/core/evented.py +0 -180
  92. beratools/third_party/pyqtlet2/leaflet/layer/__init__.py +0 -5
  93. beratools/third_party/pyqtlet2/leaflet/layer/featuregroup.py +0 -34
  94. beratools/third_party/pyqtlet2/leaflet/layer/icon/__init__.py +0 -1
  95. beratools/third_party/pyqtlet2/leaflet/layer/icon/icon.py +0 -30
  96. beratools/third_party/pyqtlet2/leaflet/layer/imageoverlay.py +0 -18
  97. beratools/third_party/pyqtlet2/leaflet/layer/layer.py +0 -105
  98. beratools/third_party/pyqtlet2/leaflet/layer/layergroup.py +0 -45
  99. beratools/third_party/pyqtlet2/leaflet/layer/marker/__init__.py +0 -1
  100. beratools/third_party/pyqtlet2/leaflet/layer/marker/marker.py +0 -91
  101. beratools/third_party/pyqtlet2/leaflet/layer/tile/__init__.py +0 -2
  102. beratools/third_party/pyqtlet2/leaflet/layer/tile/gridlayer.py +0 -4
  103. beratools/third_party/pyqtlet2/leaflet/layer/tile/tilelayer.py +0 -16
  104. beratools/third_party/pyqtlet2/leaflet/layer/vector/__init__.py +0 -5
  105. beratools/third_party/pyqtlet2/leaflet/layer/vector/circle.py +0 -15
  106. beratools/third_party/pyqtlet2/leaflet/layer/vector/circlemarker.py +0 -18
  107. beratools/third_party/pyqtlet2/leaflet/layer/vector/path.py +0 -5
  108. beratools/third_party/pyqtlet2/leaflet/layer/vector/polygon.py +0 -14
  109. beratools/third_party/pyqtlet2/leaflet/layer/vector/polyline.py +0 -18
  110. beratools/third_party/pyqtlet2/leaflet/layer/vector/rectangle.py +0 -14
  111. beratools/third_party/pyqtlet2/leaflet/map/__init__.py +0 -1
  112. beratools/third_party/pyqtlet2/leaflet/map/map.py +0 -220
  113. beratools/third_party/pyqtlet2/mapwidget.py +0 -45
  114. beratools/third_party/pyqtlet2/web/custom.js +0 -43
  115. beratools/third_party/pyqtlet2/web/map.html +0 -23
  116. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers-2x.png +0 -0
  117. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers.png +0 -0
  118. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon-2x.png +0 -0
  119. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon.png +0 -0
  120. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-shadow.png +0 -0
  121. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.css +0 -656
  122. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.js +0 -6
  123. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.codeclimate.yml +0 -14
  124. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.editorconfig +0 -4
  125. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.gitattributes +0 -22
  126. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.travis.yml +0 -43
  127. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/LICENSE +0 -20
  128. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers-2x.png +0 -0
  129. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers.png +0 -0
  130. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon-2x.png +0 -0
  131. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon.png +0 -0
  132. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-shadow.png +0 -0
  133. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet-2x.png +0 -0
  134. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.png +0 -0
  135. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.svg +0 -156
  136. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.css +0 -10
  137. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.js +0 -10
  138. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/LICENSE +0 -22
  139. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/leaflet.rotatedMarker.js +0 -57
  140. beratools/tools/forest_line_ecosite.py +0 -216
  141. beratools/tools/lapis_all.py +0 -103
  142. beratools/tools/least_cost_path_from_chm.py +0 -152
  143. beratools-0.2.0.dist-info/METADATA +0 -63
  144. beratools-0.2.0.dist-info/RECORD +0 -142
  145. /beratools/gui/{img → assets}/BERALogo.png +0 -0
  146. /beratools/gui/{img → assets}/closed.gif +0 -0
  147. /beratools/gui/{img → assets}/closed.png +0 -0
  148. /beratools/{gui_tk → gui/assets}/gui.json +0 -0
  149. /beratools/gui/{img → assets}/open.gif +0 -0
  150. /beratools/gui/{img → assets}/open.png +0 -0
  151. /beratools/gui/{img → assets}/tool.gif +0 -0
  152. /beratools/gui/{img → assets}/tool.png +0 -0
  153. {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/entry_points.txt +0 -0
@@ -1,144 +1,144 @@
1
- from multiprocessing.pool import Pool
2
- import geopandas
3
- import json
4
- import argparse
5
- import time
6
- import pandas
7
- import numpy
8
- import shapely
9
-
10
- from beratools.tools.common import *
11
-
12
- corridor_th_field = 'CorridorTh'
13
-
14
-
15
- class OperationCancelledException(Exception):
16
- pass
17
-
18
-
19
- def zonal_threshold(callback, in_line, in_canopy_raster, canopy_search_r, min_canopy_th, max_canopy_th,
20
- out_line, processes, verbose):
21
- line_seg = geopandas.GeoDataFrame.from_file(in_line)
22
- # check coordinate systems between line and raster features
23
- with rasterio.open(in_canopy_raster) as in_canopy:
24
- if line_seg.crs.to_epsg() != in_canopy.crs.to_epsg():
25
- print("Line and raster spatial references are not same, please check.")
26
- exit()
27
-
28
- del in_canopy
29
-
30
- if not corridor_th_field in line_seg.columns.array:
31
- print("Cannot find {} column in input data.\n '{}' column will be create".format(corridor_th_field,
32
- corridor_th_field))
33
- line_seg[corridor_th_field] = numpy.nan
34
-
35
- # copy original line input to another Geodataframe
36
- line_buffer = geopandas.GeoDataFrame.copy((line_seg))
37
- # buffer the input lines
38
- buffer = shapely.buffer(line_buffer['geometry'], float(canopy_search_r), cap_style=1, quad_segs=16)
39
- # replace line geometry by polygon geometry
40
- line_buffer['geometry'] = buffer
41
- # create a New column for Zonal Mean
42
- line_buffer['ZonMean'] = numpy.nan
43
- print('%{}'.format(10))
44
- print("Line preparing... ")
45
- #
46
- line_arg = []
47
-
48
- for row in line_buffer.index:
49
- list_items = [row] # 0
50
- list_items.append(line_buffer.iloc[[row]]) # 1
51
- # list_items.append(line_buffer) #1
52
- list_items.append(in_canopy_raster) # 2
53
- list_items.append(canopy_search_r) # 3
54
- list_items.append(min_canopy_th) # 4
55
- list_items.append(max_canopy_th) # 5
56
- list_items.append(corridor_th_field) # 6
57
-
58
- line_arg.append(list_items)
59
- print('%{}'.format(60))
60
- print("Calculating zonal statistic ...")
61
- features = []
62
- # for row in range(0,len(line_arg)):
63
- # features.append(zonal_prepare(line_arg[row]))
64
- features = execute_multiprocessing(line_arg)
65
- print("Merging results ...")
66
- results = geopandas.GeoDataFrame(pandas.concat(features))
67
- results['geometry'] = line_seg['geometry']
68
-
69
- print("Saving output ...")
70
- print('%{}'.format(100))
71
- # Debug save
72
- geopandas.GeoDataFrame.to_file(results, out_line)
73
- callback('Zonal Threshold tool done.')
74
-
75
-
76
- # task executed in a worker process
77
- def zonal_prepare(task_data):
78
- # report a message
79
- row_index = task_data[0]
80
- df = task_data[1]
81
- in_canopy_raster = task_data[2]
82
- corridor_th_field = task_data[6]
83
- MinValue = float(task_data[4])
84
- MaxValue = float(task_data[5])
85
-
86
- line_buffer = df['geometry']
87
-
88
- with rasterio.open(in_canopy_raster) as in_canopy:
89
- # clipped the chm base on polygon of line buffer or footprint
90
- clipped_canopy, out_transform = rasterio.mask.mask(in_canopy, line_buffer, crop=True,
91
- nodata=BT_NODATA, filled=True)
92
- clipped_canopy = numpy.squeeze(clipped_canopy, axis=0)
93
-
94
- # mask out all -9999 value cells
95
- zonal_canopy = numpy.ma.masked_where(clipped_canopy == BT_NODATA, clipped_canopy)
96
-
97
- # Calculate the zonal mean and threshold
98
- zonal_mean = numpy.ma.mean(zonal_canopy)
99
- threshold = MinValue + (zonal_mean * zonal_mean) * (MaxValue - MinValue)
100
- # return the generated value
101
- df.loc[df.index == row_index, 'ZonMean'] = zonal_mean
102
- df.loc[df.index == row_index, corridor_th_field] = threshold
103
-
104
- return df
105
-
106
-
107
- # protect the entry point
108
- def execute_multiprocessing(line_args):
109
- # create and configure the process pool
110
- # data = [[random() for n in range(100)] for i in range(300)]
111
- try:
112
- total_steps = len(line_args)
113
- features = []
114
- with Pool(processes=int(args.processes)) as pool:
115
- step = 0
116
- # execute tasks in order, process results out of order
117
- for result in pool.imap_unordered(zonal_prepare, line_args):
118
- if BT_DEBUGGING:
119
- print('Got result: {}'.format(result), flush=True)
120
- features.append(result)
121
- step += 1
122
- print('%{}'.format(step / total_steps * 100))
123
- return features
124
- except OperationCancelledException:
125
- print("Operation cancelled")
126
-
127
-
128
- if __name__ == '__main__':
129
- start_time = time.time()
130
- print('Starting zonal threshold calculation processing @ {}'.format(
131
- time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
132
-
133
- parser = argparse.ArgumentParser()
134
- parser.add_argument('-i', '--input', type=json.loads)
135
- parser.add_argument('-p', '--processes')
136
- parser.add_argument('-v', '--verbose')
137
- args = parser.parse_args()
138
-
139
- verbose = True if args.verbose == 'True' else False
140
- zonal_threshold(print, **args.input, processes=int(args.processes), verbose=verbose)
141
-
142
- print('%{}'.format(100))
143
- print('Finishing zonal threshold calculation processing @ {} (or in {} second)'.format(
144
- time.strftime("%d %b %Y %H:%M:%S", time.localtime()), round(time.time() - start_time, 5)))
1
+ from multiprocessing.pool import Pool
2
+ import geopandas
3
+ import json
4
+ import argparse
5
+ import time
6
+ import pandas
7
+ import numpy
8
+ import shapely
9
+
10
+ from beratools.tools.common import *
11
+
12
+ corridor_th_field = 'CorridorTh'
13
+
14
+
15
+ class OperationCancelledException(Exception):
16
+ pass
17
+
18
+
19
+ def zonal_threshold(callback, in_line, in_canopy_raster, canopy_search_r, min_canopy_th, max_canopy_th,
20
+ out_line, processes, verbose):
21
+ line_seg = geopandas.GeoDataFrame.from_file(in_line)
22
+ # check coordinate systems between line and raster features
23
+ with rasterio.open(in_canopy_raster) as in_canopy:
24
+ if line_seg.crs.to_epsg() != in_canopy.crs.to_epsg():
25
+ print("Line and raster spatial references are not same, please check.")
26
+ exit()
27
+
28
+ del in_canopy
29
+
30
+ if not corridor_th_field in line_seg.columns.array:
31
+ print("Cannot find {} column in input data.\n '{}' column will be create".format(corridor_th_field,
32
+ corridor_th_field))
33
+ line_seg[corridor_th_field] = numpy.nan
34
+
35
+ # copy original line input to another Geodataframe
36
+ line_buffer = geopandas.GeoDataFrame.copy((line_seg))
37
+ # buffer the input lines
38
+ buffer = shapely.buffer(line_buffer['geometry'], float(canopy_search_r), cap_style=1, quad_segs=16)
39
+ # replace line geometry by polygon geometry
40
+ line_buffer['geometry'] = buffer
41
+ # create a New column for Zonal Mean
42
+ line_buffer['ZonMean'] = numpy.nan
43
+ print('%{}'.format(10))
44
+ print("Line preparing... ")
45
+ #
46
+ line_arg = []
47
+
48
+ for row in line_buffer.index:
49
+ list_items = [row] # 0
50
+ list_items.append(line_buffer.iloc[[row]]) # 1
51
+ # list_items.append(line_buffer) #1
52
+ list_items.append(in_canopy_raster) # 2
53
+ list_items.append(canopy_search_r) # 3
54
+ list_items.append(min_canopy_th) # 4
55
+ list_items.append(max_canopy_th) # 5
56
+ list_items.append(corridor_th_field) # 6
57
+
58
+ line_arg.append(list_items)
59
+ print('%{}'.format(60))
60
+ print("Calculating zonal statistic ...")
61
+ features = []
62
+ # for row in range(0,len(line_arg)):
63
+ # features.append(zonal_prepare(line_arg[row]))
64
+ features = execute_multiprocessing(line_arg)
65
+ print("Merging results ...")
66
+ results = geopandas.GeoDataFrame(pandas.concat(features))
67
+ results['geometry'] = line_seg['geometry']
68
+
69
+ print("Saving output ...")
70
+ print('%{}'.format(100))
71
+ # Debug save
72
+ geopandas.GeoDataFrame.to_file(results, out_line)
73
+ callback('Zonal Threshold tool done.')
74
+
75
+
76
+ # task executed in a worker process
77
+ def zonal_prepare(task_data):
78
+ # report a message
79
+ row_index = task_data[0]
80
+ df = task_data[1]
81
+ in_canopy_raster = task_data[2]
82
+ corridor_th_field = task_data[6]
83
+ MinValue = float(task_data[4])
84
+ MaxValue = float(task_data[5])
85
+
86
+ line_buffer = df['geometry']
87
+
88
+ with rasterio.open(in_canopy_raster) as in_canopy:
89
+ # clipped the chm base on polygon of line buffer or footprint
90
+ clipped_canopy, out_transform = rasterio.mask.mask(in_canopy, line_buffer, crop=True,
91
+ nodata=BT_NODATA, filled=True)
92
+ clipped_canopy = numpy.squeeze(clipped_canopy, axis=0)
93
+
94
+ # mask out all -9999 value cells
95
+ zonal_canopy = numpy.ma.masked_where(clipped_canopy == BT_NODATA, clipped_canopy)
96
+
97
+ # Calculate the zonal mean and threshold
98
+ zonal_mean = numpy.ma.mean(zonal_canopy)
99
+ threshold = MinValue + (zonal_mean * zonal_mean) * (MaxValue - MinValue)
100
+ # return the generated value
101
+ df.loc[df.index == row_index, 'ZonMean'] = zonal_mean
102
+ df.loc[df.index == row_index, corridor_th_field] = threshold
103
+
104
+ return df
105
+
106
+
107
+ # protect the entry point
108
+ def execute_multiprocessing(line_args):
109
+ # create and configure the process pool
110
+ # data = [[random() for n in range(100)] for i in range(300)]
111
+ try:
112
+ total_steps = len(line_args)
113
+ features = []
114
+ with Pool(processes=int(args.processes)) as pool:
115
+ step = 0
116
+ # execute tasks in order, process results out of order
117
+ for result in pool.imap_unordered(zonal_prepare, line_args):
118
+ if BT_DEBUGGING:
119
+ print('Got result: {}'.format(result), flush=True)
120
+ features.append(result)
121
+ step += 1
122
+ print('%{}'.format(step / total_steps * 100))
123
+ return features
124
+ except OperationCancelledException:
125
+ print("Operation cancelled")
126
+
127
+
128
+ if __name__ == '__main__':
129
+ start_time = time.time()
130
+ print('Starting zonal threshold calculation processing @ {}'.format(
131
+ time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
132
+
133
+ parser = argparse.ArgumentParser()
134
+ parser.add_argument('-i', '--input', type=json.loads)
135
+ parser.add_argument('-p', '--processes')
136
+ parser.add_argument('-v', '--verbose')
137
+ args = parser.parse_args()
138
+
139
+ verbose = True if args.verbose == 'True' else False
140
+ zonal_threshold(print, **args.input, processes=int(args.processes), verbose=verbose)
141
+
142
+ print('%{}'.format(100))
143
+ print('Finishing zonal threshold calculation processing @ {} (or in {} second)'.format(
144
+ time.strftime("%d %b %Y %H:%M:%S", time.localtime()), round(time.time() - start_time, 5)))
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: BERATools
3
+ Version: 0.2.1
4
+ Summary: An advanced forest line feature analysis platform
5
+ Project-URL: Homepage, https://github.com/RichardQZeng/BTools
6
+ Author-email: AppliedGRG <appliedgrg@gmail.com>, Richard Zeng <richardqzeng@gmail.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2023, AppliedGRG
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ License-File: LICENSE
30
+ Keywords: BERA,Line
31
+ Classifier: Development Status :: 2 - Pre-Alpha
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Natural Language :: English
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.9
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Requires-Python: >=3.9
41
+ Requires-Dist: bera-centerlines
42
+ Requires-Dist: gdal==3.9.3
43
+ Requires-Dist: geopandas
44
+ Requires-Dist: pip
45
+ Requires-Dist: psutil
46
+ Requires-Dist: pyogrio>=0.9.0
47
+ Requires-Dist: pyqt5
48
+ Requires-Dist: pyqtlet2
49
+ Requires-Dist: pytest
50
+ Requires-Dist: pyyaml
51
+ Requires-Dist: rioxarray
52
+ Requires-Dist: scikit-image>=0.24.0
53
+ Requires-Dist: tqdm
54
+ Requires-Dist: xarray-spatial
55
+ Description-Content-Type: text/markdown
56
+
57
+ # BERA Tools
58
+ <div align="center">
59
+ BERA Tools is successor of [Forest Line Mapper](https://github.com/appliedgrg/flm). It is a toolset for enhanced delineation and attribution of linear disturbances in forests.
60
+
61
+ [![GitHub Workflow Status (Build)](https://img.shields.io/github/actions/workflow/status/appliedgrg/bera-tools/python-tests.yml?branch=develop&style=for-the-badge)](https://github.com/appliedgrg/bera-tools/actions/workflows/python-tests.yml)
62
+ [![Read the Docs](https://img.shields.io/readthedocs/bera-tools?style=for-the-badge&logo=readthedocs&logoColor=white)](https://bera-tools.readthedocs.io/en/latest/)
63
+ <br>
64
+ [![Conda Version](https://img.shields.io/conda/v/AppliedGRG/beratools?style=for-the-badge&logo=anaconda&color=green)](https://anaconda.org/AppliedGRG/beratools)
65
+ [![Python - Version](https://img.shields.io/badge/PYTHON-3.9+-blue?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/downloads/release/python-390/)
66
+ <br>
67
+ [![License: MIT](https://img.shields.io/github/license/appliedgrg/bera-tools?style=for-the-badge&color=blue)](https://github.com/appliedgrg/bera-tools/blob/main/LICENSE)
68
+
69
+ </div>
70
+ <!--![Banner](docs/files/images/BERALogo.png)-->
71
+
72
+ ## [Quick Start](https://beratools.readthedocs.io/en/latest/installation.html)
73
+
74
+ BERA Tools is built upon open-source Python libraries. Anaconda is used to manage runtime environments.
75
+
76
+ Installation Steps:
77
+
78
+ - Install Miniconda. Download Miniconda from [Miniconda](https://docs.anaconda.com/miniconda/) and install on your machine.
79
+ - Launch **Anaconda Prompt**. Run the following command to create a new environment. **BERA Tools** will be installed in the new environment at the same time. Download the file [conda_environment.yml](https://github.com/RichardQZeng/BTools/blob/main/conda_environment.yml) first.
80
+
81
+ ```bash
82
+ $ conda env create -f conda_environment.yml
83
+ ```
84
+
85
+ Wait until the installation is done.
86
+ - Activate the **bera** environment and launch BERA Tools:
87
+
88
+ ```bash
89
+ $ conda activate bera
90
+ $ beratools
91
+ ```
92
+
93
+
94
+ ## User Guide
95
+
96
+ Check the online [User Guide](https://beratools.readthedocs.io/en/latest/) for more information.
97
+
98
+ ## Technical Documentation
99
+
100
+ BERA Tools provides a series of tools for forest lines processing. Please refer to the technical documentation for programming APIs and algorithms details.
101
+
102
+ Check the link for more information: [Technical Documentation](https://beratools.readthedocs.io/en/latest/)
103
+
104
+ ## Credits
105
+
106
+ This tool is part of the [**Boreal Ecosystem Recovery and Assessment (BERA)**](http://www.beraproject.org/) Project, and is being actively developed by the [**Applied Geospatial Research Group**](https://www.appliedgrg.ca/).
107
+
108
+ ![Logos](docs/files/images/BERALogo.png)
109
+ *Copyright (C) 2025 Applied Geospatial Research Group*
@@ -0,0 +1,74 @@
1
+ beratools/__init__.py,sha256=bxGARlBLvDGHbhhxHoDs1wo5dQujuUZNXWOfGctjdDg,90
2
+ beratools/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ beratools/core/algo_centerline.py,sha256=mIHUsda68Pya7I51ZAb_xtF-5DYW1jebzh72r9tjSas,15582
4
+ beratools/core/algo_common.py,sha256=klM19p56VYcbH_h-_PyxJhqJMiF7hlqpG64QVMLVRJc,14965
5
+ beratools/core/algo_cost.py,sha256=qL-eVr14CFaMBAbiokB2Yr1lWwqT3jSfnXwyHFUoGrU,6345
6
+ beratools/core/algo_dijkstra.py,sha256=w_vcAOmr8bLhxWZhNRaT8V-BK-VhodZqt7v3i4HwLLk,15249
7
+ beratools/core/algo_footprint_rel.py,sha256=Nc1gzGVw3RxXnyBrnk0ie-Acjw8UuiCiHU1W3oF7EaE,20565
8
+ beratools/core/algo_line_grouping.py,sha256=Fp9ekoYf91bYE1bD49vCjxyMwpfgNN2m2KXUZ7AMJHA,32914
9
+ beratools/core/algo_merge_lines.py,sha256=1ptv8UAO-W2kYRYgbuUCdH6QX-qiYZQUjRavvRudmxE,6876
10
+ beratools/core/algo_split_with_lines.py,sha256=k1_E2H02Bxn6nzrWJstalQyZ_c5e-PWzl7jwTLmx3HE,11552
11
+ beratools/core/algo_tiler.py,sha256=Leo4WJ0h6pIJFPmsByPVRq8HpKFk3fDxR8yammtvbRo,16747
12
+ beratools/core/algo_vertex_optimization.py,sha256=kaRfaVs13BCfn_ASEQ1RfI6SFWc5FWfqWHU-4VzKRDs,15629
13
+ beratools/core/constants.py,sha256=SEu9czHJu5r4nWfHeoHOvPuxsaum3-D8hATsGktPP1k,1157
14
+ beratools/core/logger.py,sha256=0QnK800fLdUV8krzEIuKQ_cflqeIoZmi2G61gu-fGP4,2334
15
+ beratools/core/tool_base.py,sha256=0D_2Y9TDQYJDwk3OG6PHEKIEm24gR6biNVThWvH6gDw,6911
16
+ beratools/gui/__init__.py,sha256=zYIIWtPF73iVlXdH9euMUQ4DH7f-jg5yLgjn3qCQ36o,151
17
+ beratools/gui/batch_processing_dlg.py,sha256=44jOC3wL1_8XioFphGdiLua54D0cfUhvXfkD7rSL344,19286
18
+ beratools/gui/bt_data.py,sha256=dbwd6yeG1bAYZMubFV7ZiwIJZ7QhXMKRmcH9fLsSGzM,17292
19
+ beratools/gui/bt_gui_main.py,sha256=MM9-Z0e5bJ_J7F6_sNq1mehyFssDhxEqCy0oPOR6AVE,25125
20
+ beratools/gui/main.py,sha256=A4ZR3XI6Eea9Din1Wvhlp5WlNfeYHKAcJwhd3oFmPJc,644
21
+ beratools/gui/map_window.py,sha256=nyAQtWtDFT6QOttfyC_yE9LLNzpIsyB7T6lTDVIfMu0,5374
22
+ beratools/gui/tool_widgets.py,sha256=XmvBGsT8et7K9lDc5pgAqg57pjkN7WOK3HpI7STHAIo,27593
23
+ beratools/gui/assets/BERALogo.png,sha256=hnGLSL7Jv2ljDn6Z8ad5ekzH9k1PEuq7xe7Hh8bXZkE,6660
24
+ beratools/gui/assets/beratools.json,sha256=dvjfMgTmUZgAue4ir_jGtcjWeH7V7ZKrD5ar5hl7Ygg,120640
25
+ beratools/gui/assets/closed.gif,sha256=T9BBGl286-FdSRYbWVt68HwPRF0geWoowtBzeYsk_bI,592
26
+ beratools/gui/assets/closed.png,sha256=FRSAh3wzASowFUEt88zHhk1BQmwRbjoCs50Ff8KpJNQ,311
27
+ beratools/gui/assets/gui.json,sha256=kRD3Ozim9IotcY8P3fapgs4qqj5vebQHLxmss_SOJdY,329
28
+ beratools/gui/assets/open.gif,sha256=o8LL1OaDNkQ0Gcc9dO-1f1UZFAQ3ALc4svtqiUuWJPY,1062
29
+ beratools/gui/assets/open.png,sha256=v0OOwfTNGMmtdFbffCbxdYLaNZeRC9Cy5whAwi71oVw,524
30
+ beratools/gui/assets/tool.gif,sha256=2KGcUI_b-qFdrJJhgbx9pMZ8pExX7zH8nYvweRiQs6U,555
31
+ beratools/gui/assets/tool.png,sha256=35Txwum2l_aKeazF_I97ZaZAKHsrKQCGG-LZxEIFyZw,714
32
+ beratools/tools/Beratools_r_script.r,sha256=bc2Y4pI9q9IKpHAYPlMjqqnL1fVSxWErlBKVKKsUwcw,42502
33
+ beratools/tools/Ht_metrics.py,sha256=kQXPcsgLy80YOA4IAuuS5rR5QWEm1xROZdOcx_rIs4Y,4069
34
+ beratools/tools/__init__.py,sha256=lii4UkW4D105ZHpuoLi0REiZ_SA6le8T109Rl2qwkaU,129
35
+ beratools/tools/batch_processing.py,sha256=r7iXGwqr_rvXgnGdZj08kpCwKIcbJHTFBxNc8NCgJL4,4975
36
+ beratools/tools/canopy_threshold_relative.py,sha256=ZdUXJmMRytTeOvLg6lq8-9_PxS-mjsUDtsy0R5QEqA8,29116
37
+ beratools/tools/canopycostraster.py,sha256=ZS6lUIamr5hGfMGlxcantp7Kh8GYCiQHAmxyhDBAA6E,8079
38
+ beratools/tools/centerline.py,sha256=yWXAXS1XzpDMx5kKW58drHfcbmRQ2CSuOXxQJSlrOOQ,4045
39
+ beratools/tools/common.py,sha256=lIwPt7-XDNHpxiHsEQhsNiHzKGjxvQc_R9jPNTKhqzg,26615
40
+ beratools/tools/fl_regen_csf.py,sha256=omAkhQNGjkW263muX4o_w6YurNintUNI3UKrePK5OAk,16062
41
+ beratools/tools/forest_line_attributes.py,sha256=ioS6xOp9Lb323WSyEM0JgwRQqkFUtlGEqM_Q0hM2LxQ,14568
42
+ beratools/tools/line_footprint_absolute.py,sha256=bq0REhxAuv5sJ_9JcBlzS9TpQopJLQoOZSdyDPWtlME,6311
43
+ beratools/tools/line_footprint_fixed.py,sha256=H3ntIjgIRdCjzGrkxoqa6A5fK_cDzA5OzK2lHlcYayk,14045
44
+ beratools/tools/line_footprint_functions.py,sha256=KT1HkRUi923HUXIbadf2HQsdPXotVjoyB-6sIKsWmKg,30771
45
+ beratools/tools/line_footprint_relative.py,sha256=0UBO0q-7PYj6SVhgJlVSwGeQ4mhUMm-vZdXpnC_hGWw,3178
46
+ beratools/tools/line_grouping.py,sha256=kUqlVvKY0u4Kjf4VYOGxwcN1s7Ebjab9IuuZnKYkVGg,1296
47
+ beratools/tools/ln_relative_metrics.py,sha256=Iq3AkmX9yvjEUKBvoJwkLOcZ2Rm86lFwLlKzJp-XD9k,24874
48
+ beratools/tools/r_cal_lpi_elai.r,sha256=IizjOgbAdDaFdHwVY54uvmjYfi-jhTwzbu2oYzubtJY,676
49
+ beratools/tools/r_generate_pd_focalraster.r,sha256=2gCtcYk5Qt_Z_MRYHR_rtECfDoZVNnZhHFcvfWXq70E,3591
50
+ beratools/tools/r_interface.py,sha256=dKsujqUrTG1PFVnMAebWYSYZcdaEV2jGuZgkd270VnA,2473
51
+ beratools/tools/r_point_density.r,sha256=lzlFA_lz5QVAoJ03wC7HFOqr4NqVnwjTTFWCqVDt7mo,206
52
+ beratools/tools/rpy_chm2trees.py,sha256=aLSrD06Pnhwvx5Zp9doaalLR-2x_S_hpmeIZap1Po8o,3064
53
+ beratools/tools/rpy_dsm_chm_by.py,sha256=BNztSKtKR95LtJQPLWQxj_iuZF2swQPUqxyFl3atSPU,2819
54
+ beratools/tools/rpy_dtm_by.py,sha256=RrTcNGpqphT3Vy8DYm6n9gyn_fFA0-hMAgs9VwgZip0,2292
55
+ beratools/tools/rpy_find_cellsize.py,sha256=rSkUMR7Et77l8Sn_LN_BAhwotYZjZrMmbVP1F9tzDXk,1534
56
+ beratools/tools/rpy_gnd_csf.py,sha256=--cpvopOyms8zh_oSuCJLW8WbQ5M1v8htDHgAEUsWn8,2831
57
+ beratools/tools/rpy_hummock_hollow.py,sha256=eN-zVZepNuzNQGQ9dy8kgL7CenlJuLrvO-2aAWYaQ6U,3026
58
+ beratools/tools/rpy_hummock_hollow_raster.py,sha256=_Qq5S1_8VICeIxIizNv9CqlxshuIGjsgLWmg4CYByA8,2647
59
+ beratools/tools/rpy_las_info.py,sha256=8b4WfNg46dqXnbefjmaKZSyIfHrKN4xhKQuqYPwZpJw,1731
60
+ beratools/tools/rpy_laz2las.py,sha256=GAZn-B5tXMe7SXdi9HoNgrR-fm5i4brb-hlyVPPtcDI,1392
61
+ beratools/tools/rpy_lpi_elai_lascat.py,sha256=QXGlFMtIWaZLsgl636ea73nq4L2HO7mWKQaPyUMS7BE,19205
62
+ beratools/tools/rpy_normalized_lidar_by.py,sha256=kbhrX0Vcpj2SsXXyUq07gZJJzMaXDLojJ31zqoHo8cg,2080
63
+ beratools/tools/rpy_percent_above_dbh.py,sha256=ybRPBjuBYHmY8qolY2zlqSU0fCujWYoIg8bedh7-eww,2854
64
+ beratools/tools/rpy_points2trees.py,sha256=Q3f_qLiFZI1KC1ApcTw8y_K-U6bRIWfh7zccsLYpxuc,3346
65
+ beratools/tools/rpy_vegcoverage.py,sha256=lwCMzCNrS2FjcHmpJFBqctJ7ou2B68JkuK8OU9L8p6k,3308
66
+ beratools/tools/tiler.py,sha256=jwYUzO_z18-1LxLbrdIXkt_FSw9tzeJ38IHS9WBPYdI,1224
67
+ beratools/tools/tool_template.py,sha256=mPqrQG5WJmrih0vjGH8HhDVEloWJQxgNmi8Nslxi0To,1734
68
+ beratools/tools/vertex_optimization.py,sha256=w9ZqH0bHM3K6XyM3DgdMBLAd-upinfNG2fAKIfrEin8,1430
69
+ beratools/tools/zonal_threshold.py,sha256=4GPnKoaV1CmH0NnbCdsfpp4s2I4eMnqDxP-9mHIMhEQ,5361
70
+ beratools-0.2.1.dist-info/METADATA,sha256=ntM39IJfYLuYQ1t8uCKYwPbZpLzUbKLH2GGd-aoAAs8,5166
71
+ beratools-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
72
+ beratools-0.2.1.dist-info/entry_points.txt,sha256=ph47-gzMqhlWmHogQd9HTl4l8dWQUV8FhSOL2FaRrIM,53
73
+ beratools-0.2.1.dist-info/licenses/LICENSE,sha256=IZ1f9V4p0qV6UciLtuKE9nyPJIm6gQiWRBtG0ETDdfY,1069
74
+ beratools-0.2.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,22 +1,22 @@
1
- MIT License
2
-
3
- Copyright (c) 2023, AppliedGRG
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.
22
-
1
+ MIT License
2
+
3
+ Copyright (c) 2023, AppliedGRG
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.
22
+
beratools/gui/cli.py DELETED
@@ -1,18 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- """Console script for BERA tools."""
4
- import sys
5
- import click
6
-
7
-
8
- @click.command()
9
- def main(args=None):
10
- """Console script for BERA tools."""
11
- click.echo("Replace this message by putting your code into "
12
- "BERA_tools.cli.main")
13
- click.echo("See click documentation at http://click.pocoo.org/")
14
- return 0
15
-
16
-
17
- if __name__ == "__main__":
18
- sys.exit(main()) # pragma: no cover
beratools/gui/gui.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "ascii_art": [
3
- " ____ ____ ____ __ ____ _____ _____ __ ___ \n",
4
- "( _ \\( ___)( _ \\ /__\\ (_ _)( _ )( _ )( ) / __) \n",
5
- " ) _ < )__) ) / /(__)\\ )( )(_)( )(_)( )(__ \\__ \\ \n",
6
- "(____/(____)(_)\\_)(__)(__) (__) (_____)(_____)(____)(___/ \n"
7
- ]
8
- }