2

edit: This question does share an answer with an existing question, and the problem is the same: lastrees() does not work on LAScatalogs. However, I'm going to leave this question up, because I think the code and error message makes it easier to find.

I'm using lidR 2.0.3 (from the rocker/geospatial image). I would like to perform tree segmentation on an entire LAScatalog using the Li 2012 algorithm:


#### setup #####################################################################

# load packages
library(here)
library(lidR)

# load normalized point cloud catalog (just a pointer to the tiled point 
# clouds)
normalized_als = 
  readRDS(here::here('02-data',
                   'lidar',
                   'aerial',
                   'normalized_als_catalog.rds'))



#### configure catalog #########################################################
# set catalog output path 
lidR::opt_output_files(normalized_als) = 
  here::here('02-data',
             'lidar',
             'aerial',
             '02-segmented',
             '{ID}_segmented')

# don't use any points with Z below 0 when making the CHM
lidR::opt_filter(normalized_als) = 
  paste0(lidR::opt_filter(normalized_als), ', drop_z_below 0')

# use n-2 cores to process
lidR::opt_cores(normalized_als) = as.integer(parallel::detectCores()-2L)

# use a 20m buffer
lidR::opt_chunk_buffer(normalized_als) = 20

# process by files - this may preserve the lasheader?
lidR::opt_chunk_size(normalized_als) = 0

# run the algorithm, writing the segmented point cloud to disc
segmented_als = 
  lidR::lastrees(normalized_als,
               algorithm = li2012())

The last call to lastrees returns:

Error in algorithm(las):
    no slot of name "header" for this object of class "LAScatalog"

I've confirmed that the individual las files DO have valid headers, but it seems that lidR::li2012() is assuming that "las" is a LAS object, not a LAScatalog. The call fails at line 219 of lidR/R/algorithm-its.R:

 if (las@header@PHB$`Max Z` < hmin)

My question is: Is my code incorrect, or is this a bug in lidR::li2012()? I'm trying to follow the examples on the wiki, but I don't 100% understand how lidR maps LAS-based functions over LAScatalogs, and it's very possible that I am misusing the lastrees function. (Is there some catalog_apply() approach that I should be using?) The li2012() function seems to expect a LAS object specifically, not a LAScatalog (which doesn't have a comparable header slot). How can I pass an actual LAS object to li2012()? I would just iterate over the separate tiles, but would like to use the buffering functionality offered by LAScatalogs. Alternatively, was the data validation checking for li2012() written with a LAS object in mind, and causing it to break when given a LAScatalog or a LAScluster?

I would be happy to email a reproducible dataset, but I believe the issue should be reproducible with an arbitrary catalog: Either my code is written incorrectly, or li2012() can't currently be used on LAScatalogs.

0

1 Answer 1

2

The documentation of lastrees() states:

las An object of class LAS.

lastrees() does not support LAScatalog inputs. You may found more details here. The reason why lastrees() does not support catalog wide processing is currently the following:

the difficulty come with the edge of the processed chunks. Processing the dataset into independent chunks implies that there is no easy wall-to-wall continuity. At the edge of a chunk you will have the first half of a tree labelled 123 and the second half of the same tree from another chunk will be labelled 456. Wall-to-wall continuity is the reason why lastrees() does not have a LAscatalog version yet.

This may change in future releases of the package for now you can't compute lastrees() on a LAScatalog. At least not with built-in function.

1
  • Thanks JRR! For anyone reading this in the future: As a workaround, I was able to clip the catalog by the different AOI polygons, writing a new LAS file for each. Then you can run lastrees separately on each AOI LASfile. Commented Jul 18, 2019 at 13:59

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