4

I'm building a pretty complex function to rasterise some parameters of my point cloud using grid_metrics (lidR version 2.2.2).

no_fun = function(x,y,z,cl){
  require('lidR')
  require('dplyr')

  metrics = list(
    Prom_class = integer(),
    Tree_ht = numeric(),
    TreeCov = numeric())

  if(length( z[z > 0]) <= 5){return(metrics)}

  [...]
}

(The four variables x,y,z and cl are meant to recreate an internal LAS for an easier handling of the points through the process).

Running the following code:

ctg = readLAScatalog(file.path(wdir,'test.laz')
opt_chunk_size(ctg) <- 30 # to limit the size of an intermediate clustering step
opt_chunk_buffer(ctg) <- 0
opt_select(ctg) <- "xyzc"
opt_filter(ctg) <- "-keep_scan_angle -90 90 -drop_z_above 55"

fuel_metrics = grid_metrics(ctg, ~no_fun(X,Y,Z,Classification), res=10)

I get the aforementioned error:

chunk <- readRDS("\Temp\Rtmpgjmsxy/chunk176.rds")
 las <- readLAS(chunk)
nrow(coords) > 0 is not TRUE

I filled the whole function with a bunch of "warnings" in order to avoid the situation of having less than 5 points and, checking the file, it happens to have almost 20 points (10 of which >0)...

On the web I saw it might be related to the raster package but I don't have any rasterization within the function. I think it might be related to the rasterisation of the outputs and, hence, maybe related with assignment of empty variables (i.e. integer() VS NULL; the former choice seems necessary to avoid another error where the first empty variable's format has to be assigned somehow).

UPDATE 1

Below a full reproducible example with lidR's own data:

no_fun = function(x,y,z,cl){
  require('lidR')
  require('dplyr')

  metrics = list(
    Prom_class = integer(),
    TreeCov = numeric())

  if(length( z[z > 0]) <= 5){return(metrics)}


  # create las
  inplas = data.frame(X=x, Y=y, Z=z, Classification=cl)
  inplas = LAS(data=inplas, proj4string=sp::CRS(projectCRS))
  inplas = lasrescale(inplas, xscale = 0.01, yscale = 0.01, zscale = 0.01) # fix accordingly with the original one

  inplas = lasfilter(inplas, Z > 0)

  if(is.empty(inplas) | nrow(inplas@data)<5) return(metrics)
  crs(inplas) = projectCRS


  las = lasfilter(inplas, Classification != 2)
  if(is.empty(las) | nrow(las@data)<5) return(metrics)

  # initialise output variables
  cl = integer()
  TC = numeric()

  ### other stuff happening here 

  # final output
  metrics = list(
    Prom_class = cl,
    TreeCov = TC)

  return(metrics)
}


library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
ctg = readLAScatalog(LASfile)
opt_chunk_size(ctg) <- 50
opt_select(ctg) <- "xyzc"
opt_filter(ctg) <- "-keep_scan_angle -90 90 -drop_z_above 55"

projectCRS = '+proj=utm +zone=17 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0'


fuel_metrics = grid_metrics(ctg, ~no_fun(X,Y,Z,Classification), res=10)

UPDATE 2

a workaround is to set empty variables as follows:

  metrics = list(
    Prom_class = as.integer(NA),
    TreeCov = as.numeric(NA))
5
  • Start by updating the package if not done. This error has already been encountered in version 2.0.1 and has been fixed in v2.0.2 see this issue. If the error persists it is likely to come from your code and it means that somehow a raster with 0 cells has been created.
    – JRR
    Feb 7, 2020 at 20:33
  • The package gave you the two lines of code to copy paste to load the exact point cloud that triggered the error. Start by loading this region of interest and apply grid_metrics() on it. Then try to debug your function. The full error you mentioned includes An error occurred when processing the chunk 176. Try to load this chunk
    – JRR
    Feb 7, 2020 at 20:35
  • the version used is 2.2.2 and I have no rasterization step within my function (that's why I thought it could have been related to the initial splitting into "cells" or the rasterisation of the results). Running grid_metrics(las, ~no_fun(X,Y,Z,Classification), res=10) on the single chunk returns Error in .bboxCoords(coords) : nrow(coords) > 0 is not TRUE, while running the single lines of my function on the loaded chunk, I get no error at all.
    – Nico
    Feb 10, 2020 at 19:26
  • I'm not sure to understand. Did it failed or not? Edit your question to include the new information you have.
    – JRR
    Feb 10, 2020 at 22:39
  • updated the post with reproducible example
    – Nico
    Feb 18, 2020 at 16:53

1 Answer 1

3

As I said in comment the error comes from your code and it means that somehow a raster with 0 cells has been created

This appended here

metrics = list(
  Prom_class = integer(),
  TreeCov = numeric())

if(length( z[z > 0]) <= 5){return(metrics)}

You returned nothing and internally grid_metrics tried to build a raster out of nothing. You can return NA instead.

metrics = list(
 Prom_class = NA_integer_,
 TreeCov = NA_real_)

You will have another error in chunk 21

Error in points2grid(points, tolerance, round) : 
  cannot derive grid parameters from a single point! 

Which can be solve the same way

# initialise output variables
cl = NA_integer_
TC = NA_real_

Your specific case will be better handled internally in next releases.

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.