BERATools 0.2.0__py3-none-any.whl → 0.2.2__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.2.dist-info/METADATA +108 -0
  62. beratools-0.2.2.dist-info/RECORD +74 -0
  63. {beratools-0.2.0.dist-info → beratools-0.2.2.dist-info}/WHEEL +1 -1
  64. {beratools-0.2.0.dist-info → beratools-0.2.2.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.2.dist-info}/entry_points.txt +0 -0
@@ -1,25 +1,25 @@
1
- #create a 'rlpi_elai' function
2
- library(terra)
3
-
4
- rlpi_elai <- function(pdTotal, pdGround, radius, scan_angle, out_lpi, out_elai) {
5
-
6
- total_focal <- rast(pdTotal)
7
- ground_focal <- rast(pdGround)
8
-
9
- # pdTotal_SpatRaster <- rast(pdTotal)Aug 24
10
- # pdGround_SpatRaster <- rast(pdGround)
11
- ground_focal <- extend(ground_focal, ext(total_focal))
12
-
13
- # lpi
14
- lpi = ground_focal / total_focal
15
- #lpi
16
- lpi[is.infinite(lpi)] = NA
17
-
18
- elai = -cos(((scan_angle / 2.0) / 180) * pi) / 0.5 * log(lpi)
19
- elai[is.infinite(elai)] = NA
20
- elai[elai == 0 | elai == -0] = 0
21
-
22
- writeRaster(lpi, out_lpi, overwrite = TRUE)
23
- writeRaster(elai, out_elai, overwrite = TRUE)
24
-
1
+ #create a 'rlpi_elai' function
2
+ library(terra)
3
+
4
+ rlpi_elai <- function(pdTotal, pdGround, radius, scan_angle, out_lpi, out_elai) {
5
+
6
+ total_focal <- rast(pdTotal)
7
+ ground_focal <- rast(pdGround)
8
+
9
+ # pdTotal_SpatRaster <- rast(pdTotal)Aug 24
10
+ # pdGround_SpatRaster <- rast(pdGround)
11
+ ground_focal <- extend(ground_focal, ext(total_focal))
12
+
13
+ # lpi
14
+ lpi = ground_focal / total_focal
15
+ #lpi
16
+ lpi[is.infinite(lpi)] = NA
17
+
18
+ elai = -cos(((scan_angle / 2.0) / 180) * pi) / 0.5 * log(lpi)
19
+ elai[is.infinite(elai)] = NA
20
+ elai[elai == 0 | elai == -0] = 0
21
+
22
+ writeRaster(lpi, out_lpi, overwrite = TRUE)
23
+ writeRaster(elai, out_elai, overwrite = TRUE)
24
+
25
25
  }
@@ -1,101 +1,101 @@
1
- #create a 'generate_pd' function
2
- generate_pd <- function(ctg, radius_fr_CHM, focal_radius, cell_size, cache_folder,
3
- cut_ht, PD_Ground_folder, PD_Total_folder, rprocesses) {
4
- library(terra)
5
- library(lidR)
6
-
7
- plan(multisession, workers = rprocesses)
8
- set_lidr_threads(rprocesses)
9
-
10
- opts <- paste0("-drop_class 7")
11
-
12
- print("Processing using R packages.")
13
-
14
- folder <- paste0(cache_folder, "/nlidar/n_{*}")
15
- opt_output_files(ctg) <- opt_output_files(ctg) <- folder
16
- opt_laz_compression(ctg) <- FALSE
17
- opt_filter(ctg) <- "-drop_class 7"
18
- opt_chunk_alignment(ctg) <- c(0, 0)
19
-
20
-
21
- #normalized LAS with pulse info
22
- print("Indexing LAS Tiles ...")
23
- lidR:::catalog_laxindex(ctg)
24
- print("Normalize point cloud using K-nearest neighbour IDW ...")
25
- normalize_height(ctg, algorithm = knnidw())
26
-
27
- print("Generating point density (total focal sum) raster ...")
28
-
29
- pd_total <- function(chunk, radius, cell_size)
30
- {
31
- las <- readLAS(chunk)
32
- if (is.empty(las)) return(NULL)
33
-
34
- las_1 <- filter_poi(readLAS(chunk), buffer == 0)
35
- hull <- st_convex_hull(las_1)
36
- # bbox <- ext(las_1)
37
-
38
- # convert to SpatialPolygons
39
- bbox <- vect(hull)
40
-
41
- las <- filter_poi(las, Classification != 7L)
42
- #las <- retrieve_pulses(las)
43
- density_raster_total <- rasterize_density(las, res = cell_size, pkg = "terra")[[1]]
44
-
45
- tfw <- focalMat(density_raster_total, radius, "circle")
46
-
47
- tfw[tfw > 0] = 1
48
- tfw[tfw == 0] = NA
49
-
50
- Total_focal <- focal(density_raster_total, w = tfw, fun = "sum", na.rm = TRUE, na.policy = "omit", fillvalue = NA, expand = FALSE)
51
- Total_focal <- crop(Total_focal, bbox)
52
- }
53
-
54
- opt <- list(need_output_file =TRUE, autocrop = TRUE)
55
- opt_chunk_alignment(ctg) <- c(0,0)
56
- ctg@output_options$drivers$SpatRaster$param$overwrite <- TRUE
57
- opt_output_files(ctg) <- paste0(PD_Total_folder,"/{*}_PD_Tfocalsum")
58
- opt_stop_early(ctg) <- FALSE
59
- catalog_apply(ctg, pd_total, radius = focal_radius, cell_size = cell_size, .options = opt)
60
-
61
- #load normalized LAS for ground point density
62
- ht <- paste0("-drop_class 7 -drop_z_above ", cut_ht)
63
- ctg2 <- readLAScatalog(paste0(cache_folder, "/nlidar"), filter = ht)
64
- lidR:::catalog_laxindex(ctg2)
65
-
66
-
67
- print("Generating point density (ground focal sum) raster ...")
68
-
69
- pd_ground <- function(chunk, radius, cell_size, cut_ht)
70
- {
71
- las <- readLAS(chunk)
72
- if (is.empty(las)) return(NULL)
73
-
74
- las_1 <- filter_poi(readLAS(chunk), buffer == 0)
75
- hull <- st_convex_hull(las_1)
76
-
77
- # convert to SpatialPolygons
78
- bbox <- vect(hull)
79
- # bbox <- ext(las_1)
80
-
81
- #las <- retrieve_pulses(las)
82
- density_raster_ground <- rasterize_density(las, res = cell_size, pkg = "terra")[[1]]
83
-
84
-
85
- gfw <- focalMat(density_raster_ground, radius, "circle")
86
- gfw[gfw > 0] = 1
87
- gfw[gfw == 0] = NA
88
-
89
- Ground_focal <- focal(density_raster_ground, w = gfw, fun = "sum", na.policy = "omit", na.rm = TRUE, fillvalue = NA, expand = FALSE)
90
- ground_focal <- crop(Ground_focal, bbox)
91
-
92
- }
93
- opt <- list(need_output_file =TRUE, autocrop = TRUE)
94
- opt_chunk_alignment(ctg2) <- c(0,0)
95
- ctg2@output_options$drivers$SpatRaster$param$overwrite <- TRUE
96
- opt_output_files(ctg2) <- paste0(PD_Ground_folder,"/{*}_PD_Gfocalsum")
97
- opt_stop_early(ctg2) <- FALSE
98
- catalog_apply(ctg2, pd_ground,radius=focal_radius,cell_size=cell_size,cut_ht=cut_ht,.options=opt)
99
- # reset R mutilsession back to default
100
- plan("default")
1
+ #create a 'generate_pd' function
2
+ generate_pd <- function(ctg, radius_fr_CHM, focal_radius, cell_size, cache_folder,
3
+ cut_ht, PD_Ground_folder, PD_Total_folder, rprocesses) {
4
+ library(terra)
5
+ library(lidR)
6
+
7
+ plan(multisession, workers = rprocesses)
8
+ set_lidr_threads(rprocesses)
9
+
10
+ opts <- paste0("-drop_class 7")
11
+
12
+ print("Processing using R packages.")
13
+
14
+ folder <- paste0(cache_folder, "/nlidar/n_{*}")
15
+ opt_output_files(ctg) <- opt_output_files(ctg) <- folder
16
+ opt_laz_compression(ctg) <- FALSE
17
+ opt_filter(ctg) <- "-drop_class 7"
18
+ opt_chunk_alignment(ctg) <- c(0, 0)
19
+
20
+
21
+ #normalized LAS with pulse info
22
+ print("Indexing LAS Tiles ...")
23
+ lidR:::catalog_laxindex(ctg)
24
+ print("Normalize point cloud using K-nearest neighbour IDW ...")
25
+ normalize_height(ctg, algorithm = knnidw())
26
+
27
+ print("Generating point density (total focal sum) raster ...")
28
+
29
+ pd_total <- function(chunk, radius, cell_size)
30
+ {
31
+ las <- readLAS(chunk)
32
+ if (is.empty(las)) return(NULL)
33
+
34
+ las_1 <- filter_poi(readLAS(chunk), buffer == 0)
35
+ hull <- st_convex_hull(las_1)
36
+ # bbox <- ext(las_1)
37
+
38
+ # convert to SpatialPolygons
39
+ bbox <- vect(hull)
40
+
41
+ las <- filter_poi(las, Classification != 7L)
42
+ #las <- retrieve_pulses(las)
43
+ density_raster_total <- rasterize_density(las, res = cell_size, pkg = "terra")[[1]]
44
+
45
+ tfw <- focalMat(density_raster_total, radius, "circle")
46
+
47
+ tfw[tfw > 0] = 1
48
+ tfw[tfw == 0] = NA
49
+
50
+ Total_focal <- focal(density_raster_total, w = tfw, fun = "sum", na.rm = TRUE, na.policy = "omit", fillvalue = NA, expand = FALSE)
51
+ Total_focal <- crop(Total_focal, bbox)
52
+ }
53
+
54
+ opt <- list(need_output_file =TRUE, autocrop = TRUE)
55
+ opt_chunk_alignment(ctg) <- c(0,0)
56
+ ctg@output_options$drivers$SpatRaster$param$overwrite <- TRUE
57
+ opt_output_files(ctg) <- paste0(PD_Total_folder,"/{*}_PD_Tfocalsum")
58
+ opt_stop_early(ctg) <- FALSE
59
+ catalog_apply(ctg, pd_total, radius = focal_radius, cell_size = cell_size, .options = opt)
60
+
61
+ #load normalized LAS for ground point density
62
+ ht <- paste0("-drop_class 7 -drop_z_above ", cut_ht)
63
+ ctg2 <- readLAScatalog(paste0(cache_folder, "/nlidar"), filter = ht)
64
+ lidR:::catalog_laxindex(ctg2)
65
+
66
+
67
+ print("Generating point density (ground focal sum) raster ...")
68
+
69
+ pd_ground <- function(chunk, radius, cell_size, cut_ht)
70
+ {
71
+ las <- readLAS(chunk)
72
+ if (is.empty(las)) return(NULL)
73
+
74
+ las_1 <- filter_poi(readLAS(chunk), buffer == 0)
75
+ hull <- st_convex_hull(las_1)
76
+
77
+ # convert to SpatialPolygons
78
+ bbox <- vect(hull)
79
+ # bbox <- ext(las_1)
80
+
81
+ #las <- retrieve_pulses(las)
82
+ density_raster_ground <- rasterize_density(las, res = cell_size, pkg = "terra")[[1]]
83
+
84
+
85
+ gfw <- focalMat(density_raster_ground, radius, "circle")
86
+ gfw[gfw > 0] = 1
87
+ gfw[gfw == 0] = NA
88
+
89
+ Ground_focal <- focal(density_raster_ground, w = gfw, fun = "sum", na.policy = "omit", na.rm = TRUE, fillvalue = NA, expand = FALSE)
90
+ ground_focal <- crop(Ground_focal, bbox)
91
+
92
+ }
93
+ opt <- list(need_output_file =TRUE, autocrop = TRUE)
94
+ opt_chunk_alignment(ctg2) <- c(0,0)
95
+ ctg2@output_options$drivers$SpatRaster$param$overwrite <- TRUE
96
+ opt_output_files(ctg2) <- paste0(PD_Ground_folder,"/{*}_PD_Gfocalsum")
97
+ opt_stop_early(ctg2) <- FALSE
98
+ catalog_apply(ctg2, pd_ground,radius=focal_radius,cell_size=cell_size,cut_ht=cut_ht,.options=opt)
99
+ # reset R mutilsession back to default
100
+ plan("default")
101
101
  }
@@ -1,80 +1,80 @@
1
- import os
2
- import psutil
3
-
4
-
5
- # def check_r_env():
6
- try: # integrated R env
7
- # check R language within env
8
- current_env_path = os.environ['CONDA_PREFIX']
9
- # if os.path.isdir(current_env_path):
10
- os.environ['R_HOME'] = os.path.join(current_env_path, r"Lib\R")
11
- os.environ['R_USER'] = os.path.expanduser('~')
12
- os.environ['R_LIBS_USER'] = os.path.join(current_env_path, r"Lib\R\library")
13
-
14
- except FileNotFoundError:
15
- print("Warning: Please install R for this process!!")
16
- exit()
17
-
18
- import rpy2.robjects as robjects
19
- from rpy2.robjects.packages import importr, data
20
- from rpy2.robjects.vectors import StrVector
21
-
22
- r = robjects.r
23
-
24
- def r_processes(processes):
25
- stats = psutil.virtual_memory() # returns a named tuple
26
- available = getattr(stats, 'available') / 1024000000
27
- rprocesses = processes
28
-
29
- if 2 < processes <= 8:
30
- if available <= 50:
31
- rprocesses = 2
32
- elif 50 < available <= 150:
33
- rprocesses = 4
34
- elif 150 < available <= 250:
35
- rprocesses = 8
36
- else:
37
- rprocesses = 8
38
-
39
- return rprocesses
40
-
41
-
42
- def check_las_files_existence(folder):
43
- if not os.path.exists(folder):
44
- print("Error! Cannot locate Las folder, please check.")
45
- exit()
46
- else:
47
- found = False
48
- for files in os.listdir(folder):
49
- if files.endswith(".las") or files.endswith(".laz"):
50
- found = True
51
- break
52
- if not found:
53
- print("Error! Cannot locate input LAS file(s), please check!")
54
- exit()
55
-
56
-
57
- def check_r_packages_installation(packages):
58
- utils = importr('utils')
59
- base = importr('base')
60
- utils.chooseCRANmirror(ind=12) # select the 12th mirror in the list: Canada
61
- print("Checking R packages....")
62
-
63
- cran_names_to_install = [x for x in packages if not robjects.packages.isinstalled(x)]
64
- need_fasterRaster = False
65
- if len(cran_names_to_install) > 0:
66
- if not 'fasterRaster' in cran_names_to_install:
67
- utils.install_packages(StrVector(cran_names_to_install))
68
- else:
69
- cran_names_to_install.remove('fasterRaster')
70
- need_fasterRaster = True
71
- utils.install_packages(StrVector(cran_names_to_install))
72
- packages_found = True
73
- else:
74
- packages_found = True
75
-
76
- if need_fasterRaster:
77
- devtools=importr('devtools')
78
- devtools.install_github("adamlilith/fasterRaster", dependencies=True)
79
-
1
+ import os
2
+ import psutil
3
+
4
+
5
+ # def check_r_env():
6
+ try: # integrated R env
7
+ # check R language within env
8
+ current_env_path = os.environ['CONDA_PREFIX']
9
+ # if os.path.isdir(current_env_path):
10
+ os.environ['R_HOME'] = os.path.join(current_env_path, r"Lib\R")
11
+ os.environ['R_USER'] = os.path.expanduser('~')
12
+ os.environ['R_LIBS_USER'] = os.path.join(current_env_path, r"Lib\R\library")
13
+
14
+ except FileNotFoundError:
15
+ print("Warning: Please install R for this process!!")
16
+ exit()
17
+
18
+ import rpy2.robjects as robjects
19
+ from rpy2.robjects.packages import importr, data
20
+ from rpy2.robjects.vectors import StrVector
21
+
22
+ r = robjects.r
23
+
24
+ def r_processes(processes):
25
+ stats = psutil.virtual_memory() # returns a named tuple
26
+ available = getattr(stats, 'available') / 1024000000
27
+ rprocesses = processes
28
+
29
+ if 2 < processes <= 8:
30
+ if available <= 50:
31
+ rprocesses = 2
32
+ elif 50 < available <= 150:
33
+ rprocesses = 4
34
+ elif 150 < available <= 250:
35
+ rprocesses = 8
36
+ else:
37
+ rprocesses = 8
38
+
39
+ return rprocesses
40
+
41
+
42
+ def check_las_files_existence(folder):
43
+ if not os.path.exists(folder):
44
+ print("Error! Cannot locate Las folder, please check.")
45
+ exit()
46
+ else:
47
+ found = False
48
+ for files in os.listdir(folder):
49
+ if files.endswith(".las") or files.endswith(".laz"):
50
+ found = True
51
+ break
52
+ if not found:
53
+ print("Error! Cannot locate input LAS file(s), please check!")
54
+ exit()
55
+
56
+
57
+ def check_r_packages_installation(packages):
58
+ utils = importr('utils')
59
+ base = importr('base')
60
+ utils.chooseCRANmirror(ind=12) # select the 12th mirror in the list: Canada
61
+ print("Checking R packages....")
62
+
63
+ cran_names_to_install = [x for x in packages if not robjects.packages.isinstalled(x)]
64
+ need_fasterRaster = False
65
+ if len(cran_names_to_install) > 0:
66
+ if not 'fasterRaster' in cran_names_to_install:
67
+ utils.install_packages(StrVector(cran_names_to_install))
68
+ else:
69
+ cran_names_to_install.remove('fasterRaster')
70
+ need_fasterRaster = True
71
+ utils.install_packages(StrVector(cran_names_to_install))
72
+ packages_found = True
73
+ else:
74
+ packages_found = True
75
+
76
+ if need_fasterRaster:
77
+ devtools=importr('devtools')
78
+ devtools.install_github("adamlilith/fasterRaster", dependencies=True)
79
+
80
80
  print("Checking R packages....Done")
@@ -1,9 +1,9 @@
1
- pd_routine <- function(chunk) {
2
- las <- readLAS(chunk)
3
-
4
- if (is.empty(las)) return(NULL)
5
- las <- retrieve_pulses(las)
6
- output <- density(las)[1]
7
- # output is a list
8
- return(list(output))
1
+ pd_routine <- function(chunk) {
2
+ las <- readLAS(chunk)
3
+
4
+ if (is.empty(las)) return(NULL)
5
+ las <- retrieve_pulses(las)
6
+ output <- density(las)[1]
7
+ # output is a list
8
+ return(list(output))
9
9
  }
@@ -1,86 +1,86 @@
1
- import os
2
- import time
3
- from multiprocessing.pool import Pool
4
-
5
- from beratools.tools.common import *
6
- from beratools.tools.r_interface import *
7
-
8
-
9
- def chm2trees(callback, in_chm_folder, Min_ws, hmin, out_folder, processes, verbose):
10
- rprocesses = r_processes(processes)
11
-
12
- # assign R script file to local variable
13
- Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
14
- # Defining the R script and loading the instance in Python
15
- r['source'](Beratools_R_script)
16
- # Loading the function defined in R script.
17
- r_chm2trees = robjects.globalenv['chm2trees']
18
-
19
- args_list = []
20
- for root, dirs, files in sorted(os.walk(in_chm_folder)):
21
- for file in files:
22
- if file.endswith(".tif"):
23
- result = []
24
- chm_file = os.path.join(root, file)
25
- chm_file = chm_file.replace("\\", "/")
26
- result.append(chm_file)
27
- result.append(Min_ws)
28
- result.append(hmin)
29
- result.append(out_folder)
30
- result.append(rprocesses)
31
- args_list.append(result)
32
- # Invoking the R function
33
- r_chm2trees(chm_file, Min_ws, hmin, out_folder, rprocesses)
34
-
35
- del root, dirs, files
36
-
37
-
38
- if __name__ == '__main__':
39
- start_time = time.time()
40
- print('Starting tree detection from CHM processing\n @ {}'
41
- .format(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())))
42
-
43
- packages = ['lidR', 'rgrass', 'rlas', 'future', 'terra']
44
- check_r_packages_installation(packages)
45
-
46
- print("Checking input parameters....")
47
- in_args, in_verbose = check_arguments()
48
- in_chm_folder = in_args.input["in_chm_folder"]
49
- try:
50
- ws = float(in_args.input["Min_ws"])
51
- in_args.input["Min_ws"] = ws
52
- except ValueError:
53
- print("Invalid input of circular diameter, default is used")
54
- in_args.input["Min_ws"] = 2.5
55
- try:
56
- hmin = float(in_args.input["hmin"])
57
- in_args.input["hmin"] = hmin
58
- except ValueError:
59
- print("Invalid input of minimum height of a tree, default is used")
60
- in_args.input["hmin"] = 3.0
61
-
62
- out_folder = in_args.input["out_folder"]
63
-
64
- if not os.path.exists(in_chm_folder):
65
- print("Error! Cannot locate CHM raster folder, please check.")
66
- exit()
67
- else:
68
- found = False
69
- for files in os.listdir(in_chm_folder):
70
- if files.endswith(".tif"):
71
- found = True
72
- break
73
- if not found:
74
- print("Error! Cannot locate input CHM raster file(s), please check!")
75
- exit()
76
-
77
- if not os.path.exists(out_folder):
78
- print("Warning! Cannot locate output folder, It will be created.")
79
- os.makedirs(out_folder)
80
-
81
- print("Checking input parameters....Done")
82
-
83
- chm2trees(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
84
-
85
- print('Tree detection from CHM raster data processing is done in {} seconds)'
86
- .format(round(time.time() - start_time, 5)))
1
+ import os
2
+ import time
3
+ from multiprocessing.pool import Pool
4
+
5
+ from beratools.tools.common import *
6
+ from beratools.tools.r_interface import *
7
+
8
+
9
+ def chm2trees(callback, in_chm_folder, Min_ws, hmin, out_folder, processes, verbose):
10
+ rprocesses = r_processes(processes)
11
+
12
+ # assign R script file to local variable
13
+ Beratools_R_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Beratools_r_script.r')
14
+ # Defining the R script and loading the instance in Python
15
+ r['source'](Beratools_R_script)
16
+ # Loading the function defined in R script.
17
+ r_chm2trees = robjects.globalenv['chm2trees']
18
+
19
+ args_list = []
20
+ for root, dirs, files in sorted(os.walk(in_chm_folder)):
21
+ for file in files:
22
+ if file.endswith(".tif"):
23
+ result = []
24
+ chm_file = os.path.join(root, file)
25
+ chm_file = chm_file.replace("\\", "/")
26
+ result.append(chm_file)
27
+ result.append(Min_ws)
28
+ result.append(hmin)
29
+ result.append(out_folder)
30
+ result.append(rprocesses)
31
+ args_list.append(result)
32
+ # Invoking the R function
33
+ r_chm2trees(chm_file, Min_ws, hmin, out_folder, rprocesses)
34
+
35
+ del root, dirs, files
36
+
37
+
38
+ if __name__ == '__main__':
39
+ start_time = time.time()
40
+ print('Starting tree detection from CHM processing\n @ {}'
41
+ .format(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())))
42
+
43
+ packages = ['lidR', 'rgrass', 'rlas', 'future', 'terra']
44
+ check_r_packages_installation(packages)
45
+
46
+ print("Checking input parameters....")
47
+ in_args, in_verbose = check_arguments()
48
+ in_chm_folder = in_args.input["in_chm_folder"]
49
+ try:
50
+ ws = float(in_args.input["Min_ws"])
51
+ in_args.input["Min_ws"] = ws
52
+ except ValueError:
53
+ print("Invalid input of circular diameter, default is used")
54
+ in_args.input["Min_ws"] = 2.5
55
+ try:
56
+ hmin = float(in_args.input["hmin"])
57
+ in_args.input["hmin"] = hmin
58
+ except ValueError:
59
+ print("Invalid input of minimum height of a tree, default is used")
60
+ in_args.input["hmin"] = 3.0
61
+
62
+ out_folder = in_args.input["out_folder"]
63
+
64
+ if not os.path.exists(in_chm_folder):
65
+ print("Error! Cannot locate CHM raster folder, please check.")
66
+ exit()
67
+ else:
68
+ found = False
69
+ for files in os.listdir(in_chm_folder):
70
+ if files.endswith(".tif"):
71
+ found = True
72
+ break
73
+ if not found:
74
+ print("Error! Cannot locate input CHM raster file(s), please check!")
75
+ exit()
76
+
77
+ if not os.path.exists(out_folder):
78
+ print("Warning! Cannot locate output folder, It will be created.")
79
+ os.makedirs(out_folder)
80
+
81
+ print("Checking input parameters....Done")
82
+
83
+ chm2trees(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
84
+
85
+ print('Tree detection from CHM raster data processing is done in {} seconds)'
86
+ .format(round(time.time() - start_time, 5)))