Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make output of lasclip() a catalog() instead of a list() #266

Closed
ptompalski opened this issue Jul 23, 2019 · 3 comments
Closed

Make output of lasclip() a catalog() instead of a list() #266

ptompalski opened this issue Jul 23, 2019 · 3 comments
Assignees
Labels
Feature request Asking for a new feature

Comments

@ptompalski
Copy link
Contributor

When processing the point cloud data to create wall-to-wall forest inventory layers, the first step is to calculate point cloud metrics for reference plots. It is a simple task that consist of several steps:

  1. create a catalog containing all point cloud data
  2. load plot data (e.g. as sf() object)
  3. Use lasclip() to clip point clouds to plot borders
  4. Calculate metrics using lasmetrics()

The issue here is that the output of lasclip() is a list(). Therefore to calculate metrics we cannot use lasmetrics(clipped_plots, .stdmetrics), but rather calculate the metrics using lapply or a simple for loop. This is not consistent with other functions in lidR, that in most cases accept either a single las file as input, or catalog.

I suggest two changes:

  • change the output of lasclip from a list() to a catalog(). This would allow to use functions like catalog_apply(), use multi-core processing etc. (all benefits of catalogs). Such catalog would not be a wall-to-wall object of course, and should processed file-by-file.
  • allow lasmetrics() to accept catalog() as input. In that case the function would run on every plot returning an output similar to grid_metrics().
@Jean-Romain
Copy link
Collaborator

Jean-Romain commented Jul 24, 2019

Your requests makes a lot of sense however your first request already exists.

library(lidR)

# Load a LAScatalog
LASfile <- system.file("extdata", "Megaplot.laz", package = "lidR")
ctg <- readLAScatalog(LASfile)

# Load the plot centers
plots = matrix(c(684800, 684850, 5017850, 5017900), ncol = 2)
plots = SpatialPointsDataFrame(plots, data.frame(NAME = c("P1", "P2")))

# Visual check
plot(ctg)
plot(plots, add = T)

# Set output_files option to write the results on disk
opt_output_files(ctg) <- paste0(tempdir(), "/{NAME}")

# new_ctg is a LAScatalog
new_ctg <- lasclip(ctg, plots, radius = 10)
plot(new_ctg)

Notice that in the specific case of lasclip there is an internal hack to bypass regular catalog_apply behavior. The point cloud is not loaded in memory at all. The points are streamed from input files to output files.

Your second requests is also pertinent however I cannot implement it for consistency reasons. Indeed what you are asking has a meaning only for the specific case of not wall-to-wall catalog of plots. But in the general case there is no meaning at computing lasmetrics on a LAScatalog. This why I won't add this capability to lasmetrics.

However I can modify lasmetrics to allows the following:

opt_chunk_buffer(new_ctg) <- 0
opt_chunk_size(new_ctg) <- 0
opt_filter(new_ctg) <- "-keep_first"
opt_output_files(new_ctg) <- ""
output <- catalog_apply(new_ctg, lasmetrics, func = .stdmetrics)
output <- data.table::rbindlist(output)

plots@data <- cbind(plot@data, output)

This is equivalent to lasmetrics(new_ctg, .stdmetrics) but force the user to use catalog_apply and thus master the LAScatalog processing engine.

@Jean-Romain Jean-Romain self-assigned this Jul 24, 2019
@Jean-Romain Jean-Romain added the Feature request Asking for a new feature label Jul 24, 2019
Jean-Romain added a commit that referenced this issue Jul 24, 2019
@Jean-Romain
Copy link
Collaborator

Done in lidR 2.1.1

@ptompalski
Copy link
Contributor Author

this is great JR! thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature request Asking for a new feature
Projects
None yet
Development

No branches or pull requests

2 participants