# 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") install.packages("dplyr") install.packages("ggplot2") # Load the necessary libraries library(ForestTools) library(terra) library(sf) library(imager) library(ggplot2) # Load sample canopy height model provided by ForestTools lin <- function(x) { x * 0.08 + 0.8 } chm_folder <- "/Users/taekim/ecohackathon/WeCanopy/TryForestTools/first-flight/chm_tiles_shiftxy" # 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() counter <- 0 for (chm_path in tile_paths) { print(counter) counter <- counter + 1 chm <- terra::rast(chm_path) if (nlyr(chm) > 1) { chm <- chm[[1]] # Select the first layer if necessary } ttops <- vwf(chm, winFun = lin, minHeight = 2) crowns_poly <- mcws(treetops = ttops, CHM = chm, format = "polygons", minHeight = 5) crowns_sf <- st_as_sf(crowns_poly) crowns_sf$tile_path <- chm_path heights_list <- lapply(seq_len(nrow(crowns_sf)), function(i) { crown_mask <- mask(chm, crowns_sf[i, ]) max(crown_mask[], na.rm = TRUE) }) heights <- unlist(heights_list) print(heights) base_name <- tools::file_path_sans_ext(basename(chm_path)) output_file_path <- file.path("/Users/taekim/ecohackathon/WeCanopy/TryForestTools/first-flight/result_polygons_shiftxy", paste0(base_name, "_crowns.geojson")) st_write(crowns_sf, output_file_path, driver = "GeoJSON") crown_polygons_list[[chm_path]] <- crowns_sf }