r-lidar / lidR

Airborne LiDAR data manipulation and visualisation for forestry application
https://CRAN.R-project.org/package=lidR
GNU General Public License v3.0
571 stars 130 forks source link

automatic merge of catalog_apply fails #733

Closed spono closed 7 months ago

spono commented 7 months ago

Ciao JR, I'm delineating the tree crowns from a large dataset running this:

ctg <- segment_trees(ctg, dalponte2016(chm, ttops)) 

crowns <- crown_metrics(ctg, func = .stdtreemetrics, geom = "convex")

and I got this error:

An error occurred when processing the chunk 22. Try to load this chunk with:
 chunk <- readRDS("C:\Users\...\AppData\Local\Temp\Rtmpy8SNGg/chunk22.rds")
 las <- readLAS(chunk)
no applicable method for 'st_agr<-' applied to an object of class "NULL"

Class attribute on column 5 of item 4 does not match with column 5 of item 1.Warning messages:
1: No tree found. NULL returned. 
2: An error occured during the automatic merge of 'catalog_apply'. Merging is impossible. A list has been returned.

Luckily, your fail-safe code outputs a list of sf objects. As a cross-check, I tried to merge such list with dplyr::bind_rows and it gets merged with no issues, producing an sf object with the crowns from the few processed tiles. I quickly checked the point clouds and I confirm that the tile that failed (i.e. chunk22 mentioned above) didn't have any segmented object in it. So, the warning No tree found is correct but I don't understand why the second one says Merging is impossible.

Is that the desired behaviour? Would be possible to fix it allowing to skip to the next tile or to remove NULL values before merging?

Dealing with high mountain areas it is not rare that a tile covers only high elevation rocky spots with nothing to segment.

Jean-Romain commented 7 months ago

I'm not sure to understand. The code failed while processing chunk 22 or did it process everything and failed at the end while merging the partial outputs?

spono commented 7 months ago

(Sorry, I came back to this only today) I partially updated the previous comment to keep the conversation clean. Anyway, I would say that it processes fine but it fails to merge the tile output to the one coming from the previous tiles due to a NULL. And this blocks the whole process.

BTW, I checked better and I imagine that it might be related to the drop_null option in the catalog_apply engine, which is set to FALSE. If I'm correct, at this point, I ask you how to set it to TRUE when used with functions other than catalog_apply such as, e.g., crown_metrics (my case). In the code you write "not intended to be used by regular users": could it be an idea to expose it as opt_drop_null(ctg) = TRUE ?

Jean-Romain commented 7 months ago

drop null is supposed to be already true. Anyway, you are not supposed to used it. Does the following look like a valid reproducible example ?

library(lidR)
LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
ctg = readLAScatalog(LASfile)
las <- readLAS(LASfile, select = "xyz", filter = "-inside 481250 3812980 481300 3813030")
ttops <- locate_trees(las, lmf(ws = 5))

res = list(ttops, list(NULL), ttops)
engine_merge(ctg, res)
Jean-Romain commented 7 months ago

Fixed. The case was originally handled but moving to sf reintroduced it.