lidR计算Rumple Index报错求助:xmin>=xmax无效范围
问题诊断与解决方案
核心错误分析
- 过滤条件与表面点筛选矛盾:你的
opt_filter参数仅保留植被类(3/4/5/12),但filter_surfacepoints(las, 1)试图筛选分类为1的地面点,导致过滤后无点可用,最终生成空栅格引发invalid extent: xmin >= xmax错误。 - 错误的空对象判断:
is.na(las)不能用于LAS S4对象的空值判断,会触发is.na() applied to non-(list or vector) of type 'S4'警告。 - 依赖已停用的raster包:lidR 4.x版本已全面转向terra包,继续使用raster的
extent和crop会引发兼容性问题。
修正后的代码
1. 修复自定义函数
#========================================= # Rumple Index Function using point cloud #========================================= rumple_index_surface = function(cluster, res) { las = readLAS(cluster) # 正确判断空LAS对象或无数据情况 if (is.null(las) || is.empty(las)) return(NULL) # 调整表面点筛选逻辑: # 若需基于地面点计算,请在opt_filter中保留class 1,取消下一行注释 # las <- filter_surfacepoints(las, 1) # 若基于冠层点计算,直接跳过地面点筛选 # 计算Rumple Index栅格 rumple <- grid_metrics(las, ~rumple_index(X,Y,Z), res) # 无有效栅格时直接返回 if (is.null(rumple)) return(NULL) # 使用terra包处理范围裁剪(替代raster包) bbox <- cluster_extent(cluster) rumple <- terra::crop(rumple, bbox) return(rumple) }
2. 调整LAS Catalog配置
#------------------------------------------------------- # Read in Normalized LAS data via creating a lascatalog #------------------------------------------------------- las.ctg.norm <- readLAScatalog(Ntile_path) #---------------------------- #Set Options and filters #---------------------------- opt_progress(las.ctg.norm) <- TRUE opt_chunk_buffer(las.ctg.norm) <- 1 # 若需保留地面点用于表面筛选,修改filter添加class 1 # opt_filter(las.ctg.norm) <- "-keep_class 1 3 4 5 12 -drop_z_below 0.1 -drop_z_above 48" opt_filter(las.ctg.norm) <- "-keep_class 3 4 5 12 -drop_z_below 0.1 -drop_z_above 48" opt_select(las.ctg.norm) <- "xyz" # 移除多余括号 #------------------------------------- #Save individual tile metrics to disk #------------------------------------ opt_output_files(las.ctg.norm) <- file.path(Tile_metrics_path,"{*}_RI_GT0_metrics") #------------------- # Calculate Rumple #------------------- rumple <- catalog_apply(las.ctg.norm, rumple_index_surface, res = 25)
关键调整说明
- 修正空对象判断:用
is.null(las) || is.empty(las)替代is.na(las),符合lidR对LAS对象的判断逻辑。 - 解决过滤矛盾:要么在
opt_filter中保留地面类(class 1),要么删除filter_surfacepoints(las, 1)语句(若Rumple Index基于冠层点计算)。 - 替换为terra包:用
cluster_extent(cluster)获取范围,terra::crop执行裁剪,适配lidR 4.x的新版本要求。 - 增加空栅格判断:在计算后检查
rumple是否为空,避免后续裁剪操作出错。
内容的提问来源于stack exchange,提问作者MEW
相关产品推荐
相关产品推荐

