在R中结合栅格与Shapefile约束采样随机点的问题
解决栅格非NA区域+多边形内的随机采样问题
针对你需要同时满足「栅格非NA单元格内」和「Shapefile多边形内部」的随机采样需求,以下是两种可行的解决方案:
方法1:构建精确掩码后采样
通过mask()函数的touches=FALSE参数,只保留完全被多边形包含的栅格单元格,后续采样的点必然同时满足两个条件:
library(terra) set.seed(1) # 加载数据 elev_rast <- rast(system.file("ex/elev.tif", package="terra")) lux_vect <- vect(system.file("ex/lux.shp", package="terra")) lux_vect <- subset(lux_vect, NAME_2 != "Mersch") # 生成仅包含多边形内部完整栅格单元格的掩码 masked_rast <- mask(crop(elev_rast, lux_vect), lux_vect, touches = FALSE) # 执行采样 sampled_points <- spatSample(masked_rast, 1000, method="random", replace=FALSE, na.rm=TRUE, as.points=TRUE, xy=TRUE) # 可视化验证 plot(masked_rast) plot(lux_vect, add = TRUE) plot(sampled_points, add = TRUE, col="darkred", pch=16, cex=0.5)
方法2:采样后过滤多边形外的点
如果需要保留与多边形部分重叠的栅格单元格(仅要求采样点本身在多边形内),可以先采样再过滤,循环补充直到达到目标数量:
library(terra) set.seed(1) elev_rast <- rast(system.file("ex/elev.tif", package="terra")) lux_vect <- vect(system.file("ex/lux.shp", package="terra")) lux_vect <- subset(lux_vect, NAME_2 != "Mersch") cropped_rast <- crop(elev_rast, lux_vect) target_count <- 1000 final_points <- NULL while(nrow(final_points) < target_count){ # 采样一批点(多采一些备用) temp_points <- spatSample(cropped_rast, (target_count - nrow(final_points)) * 2, method="random", replace=FALSE, na.rm=TRUE, as.points=TRUE, xy=TRUE) # 过滤出多边形内部的点 valid_points <- temp_points[is.inside(temp_points, lux_vect), ] # 合并到结果 final_points <- rbind(final_points, valid_points) } # 截取到目标采样数 final_points <- final_points[1:target_count, ] # 可视化验证 plot(cropped_rast) plot(lux_vect, add = TRUE) plot(final_points, add = TRUE, col="steelblue", pch=16, cex=0.5)
关键说明
- 方法1的
touches=FALSE是核心:它会排除那些仅与多边形边界接触的栅格单元格,确保采样范围完全在多边形内部。 - 方法2适合需要更精细控制的场景,允许采样点位于与多边形部分重叠的栅格单元格中,但严格保证点本身在多边形内。
内容的提问来源于stack exchange,提问作者Marine
相关产品推荐
相关产品推荐

