-
Hey, I would appreciate help for the following problem. I have many tiles of lidar data for which I want to create a hillshade of the terrain. For this I tried to follow your advices on the LAScatalog processing engine. However, I am still struggling. I guess there is still some things which I misunderstood, here is my code: library(here)
library(lidR)
create_hillshade <- function(chunk)
{
las <- readLAS(chunk)
if (is.empty(las)) return(NULL)
dtm <- rasterize_terrain(las, 0.25, tin(), pkg = "terra")
dtm_prod <- terra::terrain(dtm, v = c("slope", "aspect"), unit = "radians")
dtm_hillshade <- terra::shade(slope = dtm_prod$slope, aspect = dtm_prod$aspect)
rastershade <- crop(dtm_hillshade, ext(las))
return(rastershade)
}
hillshade <- function(las)
{
if (is(las, "LAScatalog")) {
options <- list(automerge = FALSE, need_buffer = TRUE)
catalog_apply(las, create_hillshade, .options = options)
}
else if (is(las, "LAScluster")) {
las <- readLAS(las)
if (is.empty(las)) return(NULL)
create_hillshade(las)
}
else if (is(las, "LAS")) {
dtm <- rasterize_terrain(las, 0.25, tin(), pkg = "terra")
dtm_prod <- terra::terrain(dtm, v = c("slope", "aspect"), unit = "radians")
rastershade <- terra::shade(slope = dtm_prod$slope, aspect = dtm_prod$aspect)
return(rastershade)
}
else {
stop("This type is not supported.")
}
}
# set up parallel processing
library(future)
plan(multisession)
load("lidr-catalog.RData")
temp_path <- here("data")
opt_output_files(ctg) <- paste0(temp_path, "/{ORIGINALFILENAME}_hillshade")
opt_chunk_buffer(ctg) <- 30
opt_chunk_size(ctg) <- 0 # Set 0 use the tiling pattern (processing by file)
opt_select(ctg) <- "xyzc"
opt_filter(ctg) <- "-keep_class 2"
opt_merge(ctg) <- FALSE
summary(ctg)
# test function for selected tiles
ctg$processed <- FALSE
ctg$processed[1:3] <- TRUE
hillshade(ctg) which results in What is the problem(s)? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
Sure. Your issue is unexpected. Your code looks pretty good at first glance. I spotted one error but that is not related to your problem rastershade <- crop(dtm_hillshade, ext(chunk)) |
Beta Was this translation helpful? Give feedback.
-
The following minimal reproducible example works for me library(lidR)
create_hillshade <- function(chunk)
{
las <- readLAS(chunk)
if (is.empty(las)) return(NULL)
dtm <- rasterize_terrain(las, 0.25, tin(), pkg = "terra")
dtm_prod <- terra::terrain(dtm, v = c("slope", "aspect"), unit = "radians")
dtm_hillshade <- terra::shade(slope = dtm_prod$slope, aspect = dtm_prod$aspect)
rastershade <- crop(dtm_hillshade, ext(chunk))
return(rastershade)
}
hillshade <- function(las)
{
if (is(las, "LAScatalog")) {
options <- list(automerge = FALSE, need_buffer = TRUE)
catalog_apply(las, create_hillshade, .options = options)
}
else if (is(las, "LAScluster")) {
las <- readLAS(las)
if (is.empty(las)) return(NULL)
create_hillshade(las)
}
else if (is(las, "LAS")) {
dtm <- rasterize_terrain(las, 0.25, tin(), pkg = "terra")
dtm_prod <- terra::terrain(dtm, v = c("slope", "aspect"), unit = "radians")
rastershade <- terra::shade(slope = dtm_prod$slope, aspect = dtm_prod$aspect)
return(rastershade)
}
else {
stop("This type is not supported.")
}
}
# set up parallel processing
library(future)
plan(multisession)
LASfile <- system.file("extdata", "Topography.laz", package="lidR")
ctg = readLAScatalog(LASfile)
opt_output_files(ctg) <- paste0(tempdir(), "/{ID}_hillshade")
opt_chunk_buffer(ctg) <- 30
opt_chunk_size(ctg) <- 150
opt_select(ctg) <- "xyzc"
opt_filter(ctg) <- "-keep_class 2"
opt_merge(ctg) <- FALSE
plot(ctg, chunk = T)
sdtm = hillshade(ctg)
plot(terra::rast(sdtm[[1]]), col = gray(0:50/50)) |
Beta Was this translation helpful? Give feedback.
-
OK, I found the problem. Recreating the entire catalog solved the problem! with the old catalog the following drivers were supported:
with the new catalog this looks as following:
|
Beta Was this translation helpful? Give feedback.
OK, I found the problem.
Since its a huge catalog I created the catalog once and stored it as RData object. I created it with lidR <4.0.0 and now read it with lidR >=4.0.0. I wasnt aware there were changes introduced related to the catalog creation.
Recreating the entire catalog solved the problem!
This also explains why my first attempt from above worked were I recreated the catalog for only part of the tile collection to test it.
with the old catalog the following drivers were supported:
with the new catalog th…