You were almost there but you made some R errors. Below a full reproducible example
shp_merge_spatial = function(las, shp) UseMethod("shp_merge_spatial", las)
shp_merge_spatial.LAScluster = function(las, shp) {
# 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$Classification[las$in_poly] <- LASBUILDING # classify
return(las) # Return the point cloud
}
shp_merge_spatial.LAScatalog = function(las, shp){
opt_chunk_buffer(las) <- 0
catalog_sapply(las, shp_merge_spatial, shp = shp)
}
library(lidR)
LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
ctg = readLAScatalog(LASfile, chunk_size = 150)
shp <- system.file("extdata", "lake_polygons_UTM17.shp", package = "lidR")
lakes <- sf::st_read(shp)
opt_output_files(ctg) <-"{tempdir()}/{ID}_bldg_cls"
output <- shp_merge_spatial(ctg, lakes)
plot(output)
las = readLAS(output)
plot(las, color = "Classification")
This is a bit complex because merge_spatial
does not have LAScatalog
variant. But in lidR
3.2.0 that will be released probably next week there is classify_poi()
library(lidR)
LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
ctg = readLAScatalog(LASfile, chunk_size = 150)
shp <- system.file("extdata", "lake_polygons_UTM17.shp", package = "lidR")
lakes <- sf::st_read(shp)
opt_chunk_size(ctg) <- 150
opt_output_files(ctg) <-"{tempdir()}/{ID}_bldg_cls"
output = classify_poi(ctg, LASBUILDING, roi = lakes)
plot(output)
las = readLAS(output)
plot(las, color = "Classification")
Best Answer
Use
sf::st_as_sf
instead ofas(ctg, "sf")
before to write withsf::st_write
Note:
sf::st_as_sf
simply returnsctg@data
which IS ansf
object.