-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Kia ora Team,
just spotted this issue - as the detect_stem() can fail when running through a large list of individual tree point clouds, its best to write to disk. When the next phase is to derive profiles using stem_diameter_profile(), however, this relies on point clouds that have a "Stem" binary attribute, and the TreeLS package that is used in the background here doesn't natively write the Stem attribute as its not binary.
Here is an example:
list input clouds
itc_list <- list.files(file.path(getwd(), "Input_PCs"), pattern = ".laz$",
full.names = TRUE)
Sequential processing loop
results <- list()
error_log <- file.path(getwd(), "stem_errors_seq.txt")
Sequential processing loop
for (i in seq_along(itc_list )) {
file <- itc_list [i]
message("
tryCatch({
stem_las <- detect_stem(file, min_ht = 0.1, max_diameter = 0.8)
if (is.null(stem_las) || npoints(stem_las) == 0) {
results[[file]] <- list(file = file, status = "empty", out_path = NA,
message = "No stem points")
} else {
out_path <- file.path(out_path_stem,
paste0(tools::file_path_sans_ext(basename(file)), "_stem.laz"))
lidR::writeLAS(stem_las, out_path)
results[[file]] <- list(file = file, status = "ok", out_path = out_path, message = NA)
}
}, error = function(e) {
msg <- paste0("❌ Error with file: ", file, " | ", e$message, "\n")
cat(msg, file = error_log, append = TRUE)
results[[file]] <- list(file = file, status = "error", out_path = NA, message = e$message)
})
}
################# Diameter profiles #################
List all files.
pc_list <- list.files(file.path(getwd(), "Stem_PCs_treenotypR"),
pattern = ".laz$",
full.names = TRUE)
Sequential processing loop
results_2 <- list()
error_log2 <- file.path(getwd(), "seg_errors_seq.txt")
Sequential processing loop
for (i in seq_along(pc_list)) {
file <- pc_list[1]
message("
tryCatch({
las <- lidR::readLAS(file)
profile <- stem_diameter_profile(las,
min_ht = 0.1,
max_diameter = 0.8,
seg_ht = 0.2)
if (is.null(profile) || nrow(profile) == 0) {
results_2[[las]] <- list(file = file, status = "empty", out_path = NA,
message = "No diameter profile generated")
} else {
out_path_p <- file.path(out_path_profile,
paste0(tools::file_path_sans_ext(basename(file)), "_d_profile.csv"))
write.csv(profile, out_path_p, row.names = FALSE)
results_2[[file]] <- list(file = file, status = "ok", out_path = out_path_p, message = NA)
}
}, error = function(e) {
msg <- paste0("❌ Error with file: ", file, " | ", e$message, "\n")
cat(msg, file = error_log2, append = TRUE)
results_2[[file]] <- list(file = file, status = "error", out_path = NA, message = e$message)
})
}
De-bugging found the following error:
Error in validate_las(stem_las, required_cols = c("X", "Y", "Z", "Stem")) :
Invalid input: stem_las LAS object is missing required columns: Stem
I have some code to fix this up, so i will propse a change.
Cheers
RJLH