BERATools 0.2.3__py3-none-any.whl → 0.2.4__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 (78) hide show
  1. beratools/__init__.py +8 -3
  2. beratools/core/{algo_footprint_rel.py → algo_canopy_footprint_exp.py} +176 -139
  3. beratools/core/algo_centerline.py +61 -77
  4. beratools/core/algo_common.py +48 -57
  5. beratools/core/algo_cost.py +18 -25
  6. beratools/core/algo_dijkstra.py +37 -45
  7. beratools/core/algo_line_grouping.py +100 -100
  8. beratools/core/algo_merge_lines.py +40 -8
  9. beratools/core/algo_split_with_lines.py +289 -304
  10. beratools/core/algo_vertex_optimization.py +25 -46
  11. beratools/core/canopy_threshold_relative.py +755 -0
  12. beratools/core/constants.py +8 -9
  13. beratools/{tools → core}/line_footprint_functions.py +411 -258
  14. beratools/core/logger.py +18 -2
  15. beratools/core/tool_base.py +17 -75
  16. beratools/gui/assets/BERALogo.ico +0 -0
  17. beratools/gui/assets/BERA_Splash.gif +0 -0
  18. beratools/gui/assets/BERA_WizardImage.png +0 -0
  19. beratools/gui/assets/beratools.json +475 -2171
  20. beratools/gui/bt_data.py +585 -234
  21. beratools/gui/bt_gui_main.py +129 -91
  22. beratools/gui/main.py +4 -7
  23. beratools/gui/tool_widgets.py +530 -354
  24. beratools/tools/__init__.py +0 -7
  25. beratools/tools/{line_footprint_absolute.py → canopy_footprint_absolute.py} +81 -56
  26. beratools/tools/canopy_footprint_exp.py +113 -0
  27. beratools/tools/centerline.py +30 -37
  28. beratools/tools/check_seed_line.py +127 -0
  29. beratools/tools/common.py +65 -586
  30. beratools/tools/{line_footprint_fixed.py → ground_footprint.py} +140 -117
  31. beratools/tools/line_footprint_relative.py +64 -35
  32. beratools/tools/tool_template.py +48 -40
  33. beratools/tools/vertex_optimization.py +20 -34
  34. beratools/utility/env_checks.py +53 -0
  35. beratools/utility/spatial_common.py +210 -0
  36. beratools/utility/tool_args.py +138 -0
  37. beratools-0.2.4.dist-info/METADATA +134 -0
  38. beratools-0.2.4.dist-info/RECORD +50 -0
  39. {beratools-0.2.3.dist-info → beratools-0.2.4.dist-info}/WHEEL +1 -1
  40. beratools-0.2.4.dist-info/entry_points.txt +3 -0
  41. beratools-0.2.4.dist-info/licenses/LICENSE +674 -0
  42. beratools/core/algo_tiler.py +0 -428
  43. beratools/gui/__init__.py +0 -11
  44. beratools/gui/batch_processing_dlg.py +0 -513
  45. beratools/gui/map_window.py +0 -162
  46. beratools/tools/Beratools_r_script.r +0 -1120
  47. beratools/tools/Ht_metrics.py +0 -116
  48. beratools/tools/batch_processing.py +0 -136
  49. beratools/tools/canopy_threshold_relative.py +0 -672
  50. beratools/tools/canopycostraster.py +0 -222
  51. beratools/tools/fl_regen_csf.py +0 -428
  52. beratools/tools/forest_line_attributes.py +0 -408
  53. beratools/tools/line_grouping.py +0 -45
  54. beratools/tools/ln_relative_metrics.py +0 -615
  55. beratools/tools/r_cal_lpi_elai.r +0 -25
  56. beratools/tools/r_generate_pd_focalraster.r +0 -101
  57. beratools/tools/r_interface.py +0 -80
  58. beratools/tools/r_point_density.r +0 -9
  59. beratools/tools/rpy_chm2trees.py +0 -86
  60. beratools/tools/rpy_dsm_chm_by.py +0 -81
  61. beratools/tools/rpy_dtm_by.py +0 -63
  62. beratools/tools/rpy_find_cellsize.py +0 -43
  63. beratools/tools/rpy_gnd_csf.py +0 -74
  64. beratools/tools/rpy_hummock_hollow.py +0 -85
  65. beratools/tools/rpy_hummock_hollow_raster.py +0 -71
  66. beratools/tools/rpy_las_info.py +0 -51
  67. beratools/tools/rpy_laz2las.py +0 -40
  68. beratools/tools/rpy_lpi_elai_lascat.py +0 -466
  69. beratools/tools/rpy_normalized_lidar_by.py +0 -56
  70. beratools/tools/rpy_percent_above_dbh.py +0 -80
  71. beratools/tools/rpy_points2trees.py +0 -88
  72. beratools/tools/rpy_vegcoverage.py +0 -94
  73. beratools/tools/tiler.py +0 -48
  74. beratools/tools/zonal_threshold.py +0 -144
  75. beratools-0.2.3.dist-info/METADATA +0 -108
  76. beratools-0.2.3.dist-info/RECORD +0 -74
  77. beratools-0.2.3.dist-info/entry_points.txt +0 -2
  78. beratools-0.2.3.dist-info/licenses/LICENSE +0 -22
@@ -1,80 +0,0 @@
1
- import os
2
- import time
3
-
4
- from beratools.tools.common import *
5
- from beratools.tools.r_interface import *
6
-
7
- def percentage_aboveDBH(callback, in_las_folder, is_normalized, out_folder, DBH, cell_size, processes, verbose):
8
- rprocesses = r_processes(processes)
9
-
10
- # assign R script file to local variable
11
- Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
12
- # Defining the R script and loading the instance in Python
13
- r['source'](Beratools_R_script)
14
- # Loading the function defined in R script.
15
- r_percentage_aboveDBH = robjects.globalenv['percentage_aboveDBH']
16
- # Invoking the R function
17
- r_percentage_aboveDBH(in_las_folder, is_normalized, out_folder, DBH, cell_size, rprocesses)
18
-
19
-
20
- if __name__ == '__main__':
21
- start_time = time.time()
22
- print('Finding percentage returns above DBH height process\n @ {}'
23
- .format(time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
24
-
25
- packages = ['lidR', 'future', 'terra']
26
- check_r_packages_installation(packages)
27
-
28
- print("Checking input parameters ...")
29
- in_args, in_verbose = check_arguments()
30
- in_las_folder = in_args.input["in_las_folder"]
31
-
32
- try:
33
- DBH = float(in_args.input["DBH"])
34
- if DBH < 0:
35
- raise ValueError
36
- else:
37
- in_args.input["DBH"] = DBH
38
- except ValueError:
39
- print("Invalid input of DBH, default value is used")
40
- in_args.input["DBH"] = 1.3
41
-
42
- try:
43
- is_normalized = bool(in_args.input["is_normalized"])
44
-
45
- except ValueError:
46
- print("Invalid input of checking normalized data box, normalize data will be carried")
47
- in_args.input["is_normalized"] = False
48
-
49
- try:
50
- cell_size = float(in_args.input["cell_size"])
51
- in_args.input["cell_size"] = cell_size
52
- except ValueError:
53
- print("Invalid input of cell size, default value is used")
54
- in_args.input["cell_size"] = 5.0
55
-
56
- out_folder = in_args.input["out_folder"]
57
-
58
- if not os.path.exists(in_las_folder):
59
- print("Error! Cannot locate Las folder, please check.")
60
- exit()
61
- else:
62
- found = False
63
- for files in os.listdir(in_las_folder):
64
- if files.endswith(".las") or files.endswith(".laz"):
65
- found = True
66
- break
67
- if not found:
68
- print("Error! Cannot locate input LAS file(s), please check!")
69
- exit()
70
-
71
- if not os.path.exists(out_folder):
72
- print("Warning! Cannot locate output folder, It will be created.")
73
- os.makedirs(out_folder)
74
-
75
- print("Checking input parameters ... Done")
76
-
77
- percentage_aboveDBH(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
78
-
79
- print('Finding percentage returns above DBH height process is done in {} seconds)'
80
- .format(round(time.time() - start_time, 5)))
@@ -1,88 +0,0 @@
1
- import os
2
- import time
3
-
4
- from beratools.tools.common import *
5
- from beratools.tools.r_interface import *
6
-
7
- def points2trees(callback, in_las_folder, is_normalized, hmin, cell_size, do_nCHM, out_folder, processes, verbose):
8
- rprocesses = r_processes(processes)
9
-
10
- # assign R script file to local variable
11
- Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
12
- # Defining the R script and loading the instance in Python
13
- r['source'](Beratools_R_script)
14
- # Loading the function defined in R script.
15
- r_points2trees = robjects.globalenv['points2trees']
16
- r_pd2cellsize = robjects.globalenv['pd2cellsize']
17
- # Invoking the R function
18
- if do_nCHM:
19
- CHMcell_size = r_pd2cellsize(in_las_folder, rprocesses)
20
- print("CHM raster output cell size is: {}m".format(CHMcell_size))
21
- r_points2trees(in_las_folder, is_normalized, hmin, out_folder, rprocesses, CHMcell_size, cell_size)
22
- else:
23
- CHMcell_size = -999
24
- r_points2trees(in_las_folder, is_normalized, hmin, out_folder, rprocesses, CHMcell_size, cell_size)
25
-
26
-
27
- if __name__ == '__main__':
28
- start_time = time.time()
29
- print('Starting tree detection from LAS processing\n @ {}'
30
- .format(time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
31
-
32
- packages = ['lidR', 'rgrass', 'rlas', 'future', 'terra', 'sp']
33
- check_r_packages_installation(packages)
34
-
35
- print("Checking input parameters ...")
36
- in_args, in_verbose = check_arguments()
37
- in_las_folder = in_args.input["in_las_folder"]
38
-
39
- try:
40
- hmin = float(in_args.input["hmin"])
41
- if hmin >= 20:
42
- print("Invalid input of minimum height (<=20) of a tree, maximum is used")
43
- in_args.input["hmin"] = 20.0
44
- else:
45
- in_args.input["hmin"] = hmin
46
- except ValueError:
47
- print("Invalid input of minimum height (<=20) of a tree, default is used")
48
- in_args.input["hmin"] = 3.0
49
-
50
- try:
51
- is_normalized = bool(in_args.input["is_normalized"])
52
-
53
- except ValueError:
54
- print("Invalid input of checking normalized data box, normalize data will be carried")
55
- in_args.input["is_normalized"] = False
56
-
57
- try:
58
- cell_size = float(in_args.input["cell_size"])
59
- in_args.input["cell_size"] = cell_size
60
- except ValueError:
61
- print("Invalid input of minimum height of a tree, default is used")
62
- in_args.input["cell_size"] = 5.0
63
-
64
- out_folder = in_args.input["out_folder"]
65
-
66
- if not os.path.exists(in_las_folder):
67
- print("Error! Cannot locate Las folder, please check.")
68
- exit()
69
- else:
70
- found = False
71
- for files in os.listdir(in_las_folder):
72
- if files.endswith(".las") or files.endswith(".laz"):
73
- found = True
74
- break
75
- if not found:
76
- print("Error! Cannot locate input LAS file(s), please check!")
77
- exit()
78
-
79
- if not os.path.exists(out_folder):
80
- print("Warning! Cannot locate output folder, It will be created.")
81
- os.makedirs(out_folder)
82
-
83
- print("Checking input parameters ... Done")
84
-
85
- points2trees(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
86
-
87
- print('Tree detection from Lidar data processing is done in {} seconds)'
88
- .format(round(time.time() - start_time, 5)))
@@ -1,94 +0,0 @@
1
- import os
2
- import time
3
-
4
- from beratools.tools.common import *
5
- from beratools.tools.r_interface import *
6
-
7
- def veg_cover_percentage(callback, in_las_folder, is_normalized, out_folder, hmin, hmax, cell_size, processes, verbose):
8
- rprocesses = r_processes(processes)
9
-
10
- # assign R script file to local variable
11
- Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
12
- # Defining the R script and loading the instance in Python
13
- r['source'](Beratools_R_script)
14
- # Loading the function defined in R script.
15
- r_veg_metrics = robjects.globalenv['veg_cover_percentage']
16
- # Invoking the R function
17
- r_veg_metrics(in_las_folder, is_normalized, out_folder, hmin, hmax, cell_size, rprocesses)
18
-
19
-
20
- if __name__ == '__main__':
21
- start_time = time.time()
22
- print('Finding Vegetation Coverage from Lidar data process\n @ {}'
23
- .format(time.strftime("%d %b %Y %H:%M:%S", time.localtime())))
24
-
25
- packages = ['lidR', 'future', 'terra']
26
- check_r_packages_installation(packages)
27
-
28
- print("Checking input parameters ...")
29
- in_args, in_verbose = check_arguments()
30
- in_las_folder = in_args.input["in_las_folder"]
31
-
32
- try:
33
- hmin = float(in_args.input["hmin"])
34
- if hmin < 0:
35
- raise ValueError
36
- else:
37
- in_args.input["hmin"] = hmin
38
- except ValueError:
39
- print("Invalid input of minimum height of a tree, default value is used")
40
- in_args.input["hmin"] = 3.0
41
-
42
- try:
43
- hmax = float(in_args.input["hmax"])
44
- if hmax <= hmin:
45
- raise ValueError
46
- else:
47
- in_args.input["hmax"] = hmax
48
- except ValueError:
49
- print("Invalid input of maximum height of a tree, default value is used")
50
- if hmin < 10:
51
- in_args.input["hmax"] = 10.0
52
- else:
53
- in_args.input["hmin"] = 3.0
54
- in_args.input["hmax"] = 10.0
55
-
56
- try:
57
- is_normalized = bool(in_args.input["is_normalized"])
58
-
59
- except ValueError:
60
- print("Invalid input of checking normalized data box, normalize data will be carried")
61
- in_args.input["is_normalized"] = False
62
-
63
- try:
64
- cell_size = float(in_args.input["cell_size"])
65
- in_args.input["cell_size"] = cell_size
66
- except ValueError:
67
- print("Invalid input of cell size, default value is used")
68
- in_args.input["cell_size"] = 5.0
69
-
70
- out_folder = in_args.input["out_folder"]
71
-
72
- if not os.path.exists(in_las_folder):
73
- print("Error! Cannot locate Las folder, please check.")
74
- exit()
75
- else:
76
- found = False
77
- for files in os.listdir(in_las_folder):
78
- if files.endswith(".las") or files.endswith(".laz"):
79
- found = True
80
- break
81
- if not found:
82
- print("Error! Cannot locate input LAS file(s), please check!")
83
- exit()
84
-
85
- if not os.path.exists(out_folder):
86
- print("Warning! Cannot locate output folder, It will be created.")
87
- os.makedirs(out_folder)
88
-
89
- print("Checking input parameters ... Done")
90
-
91
- veg_cover_percentage(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
92
-
93
- print('Finding Vegetation Coverage from Lidar data process is done in {} seconds)'
94
- .format(round(time.time() - start_time, 5)))
beratools/tools/tiler.py DELETED
@@ -1,48 +0,0 @@
1
- """
2
- Copyright (C) 2025 Applied Geospatial Research Group.
3
-
4
- This script is licensed under the GNU General Public License v3.0.
5
- See <https://gnu.org/licenses/gpl-3.0> for full license details.
6
-
7
- Author: Richard Zeng
8
-
9
- Description:
10
- This script is part of the BERA Tools.
11
- Webpage: https://github.com/appliedgrg/beratools
12
-
13
- The purpose of this script is to split input vector and raster data into
14
- smaller tiles based on a specified tile size and buffer distance.
15
- """
16
-
17
- import time
18
-
19
- import beratools.tools.common as bt_common
20
- import beratools.core.algo_tiler as bt_tiler
21
-
22
- def tiler(
23
- in_line,
24
- in_raster,
25
- out_file,
26
- n_clusters,
27
- processes,
28
- verbose,
29
- tile_buffer=50,
30
- in_layer=None,
31
- ):
32
- clustering = bt_tiler.DensityBasedClustering(
33
- in_line=in_line,
34
- in_raster=in_raster,
35
- out_file=out_file,
36
- n_clusters=int(n_clusters),
37
- tile_buffer=tile_buffer,
38
- layer=in_layer,
39
- )
40
-
41
- clustering.run()
42
-
43
-
44
- if __name__ == "__main__":
45
- in_args, in_verbose = bt_common.check_arguments()
46
- start_time = time.time()
47
- tiler(**in_args.input, processes=int(in_args.processes), verbose=in_verbose)
48
- print("Elapsed time: {}".format(time.time() - start_time))
@@ -1,144 +0,0 @@
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,108 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: BERATools
3
- Version: 0.2.3
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.10
37
- Classifier: Programming Language :: Python :: 3.11
38
- Classifier: Programming Language :: Python :: 3.12
39
- Requires-Python: >=3.10
40
- Requires-Dist: bera-centerlines
41
- Requires-Dist: gdal>=3.9.2
42
- Requires-Dist: geopandas
43
- Requires-Dist: pip
44
- Requires-Dist: psutil
45
- Requires-Dist: pyogrio>=0.9.0
46
- Requires-Dist: pyqt5
47
- Requires-Dist: pyqtlet2
48
- Requires-Dist: pytest
49
- Requires-Dist: pyyaml
50
- Requires-Dist: rioxarray
51
- Requires-Dist: scikit-image>=0.24.0
52
- Requires-Dist: tqdm
53
- Requires-Dist: xarray-spatial
54
- Description-Content-Type: text/markdown
55
-
56
- # BERA Tools
57
- <div align="center">
58
- 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.
59
-
60
- [![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)
61
- [![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/)
62
- <br>
63
- [![Conda Version](https://img.shields.io/conda/v/AppliedGRG/beratools?style=for-the-badge&logo=anaconda&color=green)](https://anaconda.org/AppliedGRG/beratools)
64
- [![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/)
65
- <br>
66
- [![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)
67
-
68
- </div>
69
- <!--![Banner](docs/files/images/BERALogo.png)-->
70
-
71
- ## [Quick Start](https://beratools.readthedocs.io/en/latest/installation.html)
72
-
73
- BERA Tools is built upon open-source Python libraries. Anaconda is used to manage runtime environments.
74
-
75
- Installation Steps:
76
-
77
- - Install Miniconda. Download Miniconda from [Miniconda](https://docs.anaconda.com/miniconda/) and install on your machine.
78
- - 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.
79
-
80
- ```bash
81
- $ conda env create -f conda_environment.yml
82
- ```
83
-
84
- Wait until the installation is done.
85
- - Activate the **bera** environment and launch BERA Tools:
86
-
87
- ```bash
88
- $ conda activate bera
89
- $ beratools
90
- ```
91
-
92
-
93
- ## User Guide
94
-
95
- Check the online [User Guide](https://beratools.readthedocs.io/en/latest/) for more information.
96
-
97
- ## Technical Documentation
98
-
99
- BERA Tools provides a series of tools for forest lines processing. Please refer to the technical documentation for programming APIs and algorithms details.
100
-
101
- Check the link for more information: [Technical Documentation](https://beratools.readthedocs.io/en/latest/)
102
-
103
- ## Credits
104
-
105
- 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/).
106
-
107
- ![Logos](docs/files/images/BERALogo.png)
108
- *Copyright (C) 2025 Applied Geospatial Research Group*
@@ -1,74 +0,0 @@
1
- beratools/__init__.py,sha256=Mdv1nAvOXx6fFOvIS_3Qob8L_hjZxvsne1JXzaSm5Ao,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.3.dist-info/METADATA,sha256=OyATzVy44FuXiPdgPs9nPiEMD6g1DlWoQ5oCQFc-ZaM,5117
71
- beratools-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
72
- beratools-0.2.3.dist-info/entry_points.txt,sha256=ph47-gzMqhlWmHogQd9HTl4l8dWQUV8FhSOL2FaRrIM,53
73
- beratools-0.2.3.dist-info/licenses/LICENSE,sha256=IZ1f9V4p0qV6UciLtuKE9nyPJIm6gQiWRBtG0ETDdfY,1069
74
- beratools-0.2.3.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- BERATools = beratools.gui:gui_main
@@ -1,22 +0,0 @@
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
-