3

I wrote a specific function to calculte metrics on a catalog but this function (myMetrics) work with a LAS file but don't work with a catalog?

myMetrics = function(las, ...)
{
  UseMethod("myMetrics", las)
}

myMetrics.LAS <- function(las){
  metrics <- list(
    min_x <- min(las@data$X),
    max_x <- max(las@data$X),
    min_y <- min(las@data$Y),
    max_y <- max(las@data$Y),
    min_z <- min(las@data$Z),
    max_z <- max(las@data$Z),
    min_classification <- min(las@data$Classification),
    max_classification <- max(las@data$Classification)
  )
  names(metrics) <- c(
    "min_x", "max_x", "min_y", "max_y", "min_z", "max_z", "min_classification", "max_classification"
  )
  return(metrics)
}

myMetrics.LAScluster <- function(cluster)
{
  las <- readLAS(cluster)                          
  if (is.empty(las)) return(NULL)              

  metrics <- lasmetrics(las, ~myMetrics(las))
  return(metrics)                                  
}

opt_chunk_buffer(ctg) <- 0
opt_chunk_size(ctg) <- 0
opt_output_files(ctg) <- ""
plots_metrics <- catalog_apply(ctg, lasmetrics, func = .myMetrics(ctg))

Error in catalog_apply(las, lasmetrics, func = .myMetrics) : object '.myMetrics' not found

1 Answer 1

1

There are several confusion in your example. You tried to use the "metrics syntax" (if I can called it this way) in a wrong way. When defining a "metric" function the input should be some attributes of a LAS object.

myMetrics <- function(x,y,z,cl) 
{
  metrics <- list(
    min_x <- min(x),
    max_x <- max(x),
    min_y <- min(y),
    max_y <- max(y),
    min_z <- min(z),
    max_z <- max(z),
    min_classification <- min(cl),
    max_classification <- max(cl))
  names(metrics) <- c("min_x", "max_x", "min_y", "max_y", "min_z", "max_z", "min_classification", "max_classification")
  return(metrics)
}

library(lidR)
LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
ctg = readLAScatalog(LASfile)

opt_chunk_buffer(ctg) <- 0
opt_chunk_size(ctg) <- 0
opt_output_files(ctg) <- ""

# lasmetrics supports to be used in catalog_apply.
plots_metrics <- catalog_apply(ctg, lasmetrics, func = ~myMetrics(X,Y,Z,Classification))
plots_metrics <- data.table::rbindlist(plots_metrics)

That being said your "metrics" are not really useful here. Your are processing by file so you are trying to get the bounding box of each file. The bounding box is already given in the header of the files. You can have an immediate access to them (assuming the LAS files are valid).

ctg = readLAScatalog(LASfile)
ctg@data[,22:27]
#>   Max.X    Min.X    Max.Y   Min.Y   Max.Z Min.Z
#> 1 684993.3 684766.4 5018007 5017773 29.97 0

Your metrics *_classification are relevant.

Also you noticed that lasmetrics can be used in catalog_apply. This is a special case actually. To give you a full answer you could have used the following syntax (you were actually close)

f <- function(cluster) {
  las <- readLAS(cluster)                          
  if (is.empty(las)) return(NULL)              

  metrics <- lasmetrics(las, ~myMetrics(X,Y,Z,Classification))
  return(metrics)                                  
}

plots_metrics <- catalog_apply(ctg, f)

Also las$X works. No need to write las@data$X ;-)

1
  • ok, thanks for this explaination. All works now ! Commented Nov 22, 2019 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.