Example code snippets from past projects. Full scripts can be found on my Github here.
======================================================Code snippet from Wetzin'kwa Community Forest Project: Tree detection and segmentation======================================================library(lidR)library(terra)library(sf)library(tidyverse)#=====================================#STEP 1: IMPORT LIDAR DATA#=====================================#import lidar datalas_data <- readLAScatalog("Data/LAS_data") #Optional: check lidar data and view CRSlas_check(las_data)st_crs(las_data) #==========================================================#STEP 2: CONVERT CRS and CLIP LAZ FILES TO AREA OF INTEREST#==========================================================#convert KML files to same CRSstand_kml_converted <- st_transform(stand_union_kml, st_crs(las_data))#clip .las data to the roilas_clipped <- clip_roi(las_data, stand_kml_converted)#=======================================================#STEP 3: NORMALIZE HEIGHTS AND FILTER OUTLIERS #=======================================================#normalize the data using DEMlas_norm <- normalize_height(las_clipped, wetzinkwa_dem)#filter undesired data pointsrange(las_norm$Z, na.rm = TRUE)las_norm<- filter_poi(las_norm, Z >= 0 & Z <= 20)#======================================#STEP 4: CREATE CANOPY HEIGHT MODEL#======================================#create simple CHM with a 0.5m resolution using p2r CHMchm <- rasterize_canopy(las_norm, res = 0.5, algorithm = p2r(0.15)) plot(chm)#apply a mean smoothing filterchm_smoothed <- focal(chm, w = matrix(1,3,3), fun = mean, na.rm = TRUE)#plot a 3D chmplot_dtm3d(chm, color="green")#=======================================#STEP 5: TREE SEGMENTATION#=======================================#define a variable window size f <- function(h) { pmax(1.0, pmin(6.0, 1.5 + 0.05 * h))}#locate treesttops <- locate_trees(chm, lmf(f)) plot(chm) plot(ttops, add=TRUE, col="red") crowns_dal <- segment_trees(las_norm, dalponte2016(chm_smoothed, ttops, th_tree = 6)) plot(crowns_dal, color = "treeID")
=====================================================Code Snippet from Fire Analysis from Landsat Data=====================================================#generate a fire polygon for the Prouton fireprouton_fire_polygon <- fire_polygons %>% filter(FIRE_NO == "C30870") %>% summarise()#list.dirs for Landsat foldersfolders <- list.dirs("data/Landsat 8 OLI_TIRS C2 L2", full.names = TRUE, recursive = FALSE)#create an output directoryout_dir <- "data/output"dir.create(out_dir, showWarnings = FALSE)#create one large for loop to iterate through the folders,#separate files, crop and mask to QA PIXEL, calculate ndvi and nbr, #then save outputs into three separate foldersfor (f in folders) { prod_id <- basename(f) #Extract Date Using lubridate date_string <- stringr::str_sub(prod_id, 18, 25) acq_date <- lubridate::as_date(date_string, format = "%Y%m%d") # Create a clean filename base clean_name <- format(acq_date, "%Y%m%d") files <- list.files(f, full.names = TRUE, pattern = "TIF$", recursive = TRUE) # extract sr + qa files # Select only SR_B1 ... SR_B7 sr_files <- files[grepl("SR_B[1-7]", files)] #build sr stack sr_stack <- terra::rast(sr_files) qa_files <- terra::rast(files[grepl("QA_PIXEL", files)]) # Set CRS and crop rasters to fire polygon prouton_fire_polygon <- st_transform(prouton_fire_polygon, crs(sr_stack)) # crop by polygon and then create the clear mask qa_crop <- terra::crop(qa_files, prouton_fire_polygon, mask = TRUE) clear_mask <- qa_crop == 21824 #crop sr files by polygon, then mask using the clear mask sr_crop <- terra::crop(sr_stack, prouton_fire_polygon, mask = TRUE) sr_mask <- mask(sr_crop, clear_mask, maskvalues = 0) # calculate ndvi and nbr ndvi <- (sr_mask[[5]] - sr_mask[[4]]) / (sr_mask[[5]] + sr_mask[[4]]) nbr <- (sr_mask[[5]] - sr_mask[[7]]) / (sr_mask[[5]] + sr_mask[[7]]) # create directories sr_dir <- file.path(out_dir, "SR") ndvi_dir <- file.path(out_dir, "NDVI") nbr_dir <- file.path(out_dir, "NBR") dir.create(sr_dir, showWarnings = FALSE) dir.create(ndvi_dir, showWarnings = FALSE) dir.create(nbr_dir, showWarnings = FALSE) # write with date writeRaster(sr_mask, file.path(sr_dir, paste0(clean_name,"_SR.tif")), overwrite = TRUE) writeRaster(ndvi, file.path(ndvi_dir, paste0(clean_name,"_NDVI.tif")), overwrite = TRUE) writeRaster(nbr, file.path(nbr_dir, paste0(clean_name,"_NBR.tif")), overwrite = TRUE)