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
582 stars 130 forks source link

catalog_apply failing because of 'heterogeneous objects' #757

Closed cedricr closed 3 months ago

cedricr commented 3 months ago

Hello,

on some of the french IGN tiles, catalog_apply is failing with the following error:

Error in st_geometry<-.sf(*tmp*, value = res) : is.character(value) || inherits(value, "sfc") is not TRUE In addition: Warning message: The list returned by 'catalog_apply' contains heterogeneous objects. Merging is impossible. A list has been returned.

Here's a minimal reproduction:

library(lidR)

download.file("https://storage.sbg.cloud.ovh.net/v1/AUTH_63234f509d6048bca3c9fd7928720ca1/ppk-lidar/IQ/LHD_FXX_0569_6275_PTS_C_LAMB93_IGN69.copc.laz", "tile1.copc.laz")
download.file("https://storage.sbg.cloud.ovh.net/v1/AUTH_63234f509d6048bca3c9fd7928720ca1/ppk-lidar/IQ/LHD_FXX_0569_6274_PTS_C_LAMB93_IGN69.copc.laz", "tile2.copc.laz")

ctg <- readLAScatalog(c("tile1.copc.laz", "tile2.copc.laz"), filter = "-keep_first")
cbounds <- catalog_boundaries(ctg)

Analysing a bit further, if I run concave_hull on both tiles separately, one returns a Polygon, and the other a MultiPolygon

ctg1 <- readLAScatalog(c("tile1.copc.laz"), filter = "-keep_first")
ctg2 <- readLAScatalog(c("tile2.copc.laz"), filter = "-keep_first")
catalog_map(ctg1, st_concave_hull)

Geometry set for 1 feature Geometry type: MULTIPOLYGON Dimension: XY Bounding box: xmin: 569000 ymin: 6274000 xmax: 570000 ymax: 6275000 Projected CRS: RGF93 v1 / Lambert-93 MULTIPOLYGON (((569000.3 6274580, 569000.4 6274...

catalog_map(ctg2, st_concave_hull)

Geometry set for 1 feature Geometry type: POLYGON Dimension: XY Bounding box: xmin: 569819 ymin: 6273000 xmax: 570000 ymax: 6274000 Projected CRS: RGF93 v1 / Lambert-93 POLYGON ((570000 6273988, 569999.8 6273988, 569...

Jean-Romain commented 3 months ago

Thank you for the reproducible example. I'll investigate.

cedricr commented 3 months ago

FWIW: I’ve tried to run catalog_apply on the tiles of several cities, without the "keep_first" filter, but it nearly always fail with the "heterogeneous objects" error anyway. I can provide other reproductible examples if you feel like you need them.

Jean-Romain commented 3 months ago

Fixed. With the default parameters of st_concave_hull and the first return only you reached a limit case where the polygon produced was invalid on one point. lidR handles invalid cases with sf::st_make_valid() but in this specific case it produced 2 polygons in a MULTIPOLYGON.

I fixed it by casting MULTIPOLYGON into POLYGON + a warning because your are not supposed to get more than 1 polygons.

Now a better way to handle this case would be to change the parameters. Your polygons are overly complex and this brings nothing. Change the parameters to produce less detailed polygons e.g.:

cbounds <- catalog_boundaries(ctg, concavity = 4, length_threshold = 10)

Problem gone and simpler/better/faster result

cedricr commented 3 months ago

Changing the parameters work perfectly indeed, thanks !