# Install the ForestTools package if it's not already installed if (!require(ForestTools)) install.packages("ForestTools") if (!require(terra)) install.packages("terra") if (!require(sf)) install.packages("sf") if (!require(imager)) install.packages("imager") # Load the necessary libraries library(ForestTools) library(terra) library(sf) library(imager) # Load sample canopy height model provided by ForestTools lin <- function(x) { x * 0.05 + 0.5 } chm_folder <- "/Users/taekim/ecohackathon/first_try_lidar/ForestTools/TryForestTools/first-flight/chm_tiles" # Update this with the path to your CHM tiles folder # List all TIFF files in the directory tile_paths <- list.files(path = chm_folder, pattern = "\\.tif$", full.names = TRUE) print(tile_paths) # Initialize an empty list to store sf objects for each tile crown_polygons_list <- list() for (chm_path in tile_paths) { # Load the CHM file chm <- terra::rast(chm_path) if (nlyr(chm) > 1) { chm <- chm[[1]] # Select the first layer if necessary } # Detect treetops using the VWF algorithm ttops <- vwf(chm, winFun = lin, minHeight = 2) # Create crown polygons using the MCWS method crowns_poly <- mcws(treetops = ttops, CHM = chm, format = "polygons", minHeight = 1.5) # Add the results to the list crown_polygons_list[[chm_path]] <- crowns_poly } # Combine all sf objects into one all_crowns <- do.call(rbind, crown_polygons_list) # Resolve overlapping polygons using spatial union merged_crowns <- st_union(all_crowns) # Compute additional attributes such as area and diameter merged_crowns[["area"]] <- st_area(merged_crowns) merged_crowns[["diameter"]] <- sqrt(merged_crowns[["area"]] / pi) * 2 # Save the combined and merged crown polygons to a shapefile st_write(merged_crowns, "path_to_save/merged_crown_polygons.shp") # Plot the merged crown polygons for visualization plot(merged_crowns$geometry, col = 'green', main = "Merged Crown Polygons")