I have successfully classified buildings via a buildings shapefile input for a single las file but I am having trouble with making a function to use this feature in the catalog format.
Here is the code for a single las file that works well. I exported the mixed conifer las data built into the package and used it for this example. Then in QGIS I drew a heart shaped polygon to use as an example.
# Open R Project, then load packages
#---------------------------------
packages <- c("tidyverse","here","lidR","raster","rgdal","sf","sp", "future")
lapply(packages, library, character.only = TRUE)
# load las
file <- here::here("coconutgrove/mixed_conifer/mixedconifer.las")
ctg <- lidR::catalog(file)
lascrs <- crs(ctg)
# load shp
shp_file <- here("coconutgrove/mixed_conifer/mixed_conifer_heart.shp")
shp <- st_read(shp_file)
shp <- sf::st_transform(shp, crs = st_crs(lascrs))
# =============== single las file - classify buildings by shapefile input
start.time <- Sys.time() #start time buildings clip
las <- merge_spatial(las, shp, attribute = "in_poly")
las$Classification[las$in_poly] <- LASBUILDING
las$in_poly <- NULL
# end.time <- Sys.time() #end time
time.taken <- end.time - start.time
print(time.taken) #merge spatial
w <- writeLAS(las, here("coconutgrove/las_out/bldgcls_mixed_conifer.las"))
This code successfully executed merge_spatial
and classified the points within the polygon as buildings. Below is the code based on (https://cran.r-project.org/web/packages/lidR/vignettes/lidR-catalog-apply-examples.html) to create a user defined function to execute the merge_spatial
feature on a las catalog.
# Open R Project, then load packages
#---------------------------------
packages <- c("tidyverse","here","lidR","raster","rgdal","sf","sp", "future")
lapply(packages, library, character.only = TRUE)
# load las
file <- here::here("coconutgrove/mixed_conifer/mixedconifer.las")
ctg <- lidR::catalog(file)
lascrs <- crs(ctg)
# load shp
shp_file <- here("coconutgrove/mixed_conifer/mixed_conifer_heart.shp")
shp <- st_read(shp_file)
shp <- sf::st_transform(shp, crs = st_crs(lascrs))
# Build the user-defined function that applies merge spatial.
# ================= generic function creation ===============================================
shp_merge_spatial = function(las, ...)
{
UseMethod("shp_merge_spatial", las)
}
shp_merge_spatial.LAScluster = function(las)
{
# The function is automatically fed with LAScluster objects
# Here the input 'las' will a LAScluster
las <- readLAS(las) # Read the LAScluster
if (is.empty(las)) return(NULL) # Exit early (see documentation)
las <- merge_spatial(las,shp, attribute = "in_poly") # merge_spatial
las <- las$Classification[las$in_poly] <- LASBUILDING # classify
las$in_poly <- NULL
return(las) # Return the point cloud
}
shp_merge_spatial.LAScatalog = function(las)
{
catalog_apply(las, shp_merge_spatial.LAScluster)
}
# ======= CATALOG OPTIONS
#opt_filter(ctg) <- "-drop_z_below 0"
opt_chunk_buffer(ctg) <- 10
opt_chunk_size(ctg) <- 0
#opt_cores(ctg) <- 2
opt_output_files(ctg) <- here("coconutgrove/mixed_conifer/ctg_out/{*}_bldg_cls")
start.time <- Sys.time() #start time buildings clip
output <- shp_merge_spatial.LAScluster(ctg)
end.time <- Sys.time() #end time
time.taken <- end.time - start.time
print(time.taken) #merge spatial function
Then the only error message that occurs is:
Warning message:
In las$in_poly <- NULL : Coercing LHS to a list
If I comment out that line of code then there are no error messages yet nothing is written to the output folder I designated in opt_output_files
.
Can you advise?
Best Answer
You were almost there but you made some R errors. Below a full reproducible example
This is a bit complex because
merge_spatial
does not haveLAScatalog
variant. But inlidR
3.2.0 that will be released probably next week there isclassify_poi()