sf & dplyr:相同地理坐标分组求均值不生效问题求助
Sentinel-2跨瓦片同位置栅格点均值计算解决方案
问题根源
该问题由两类操作误差共同导致:
- 直接按经纬度分组:控制台打印的经纬度为截断显示结果,不同UTM分区的瓦片转WGS84后,同一实际位置的点会存在微米级的浮点尾差,完全相等匹配逻辑无法识别重复点,导致分组失效。
- 固定0.001°精度四舍五入:WGS84坐标系下0.001°对应地表距离约111米,远大于10米的栅格分辨率,会把相邻的多个栅格点错误合并到同一组,导致计算结果不符合预期。
可行解决方案
提供两种兼容现有代码的实现方案,可根据数据量选择:
方案1:空间聚类分组(适合小数据量,无需修改坐标系)
基于点之间的空间距离聚类,设置1米的距离阈值(同一实际位置的点投影误差远小于1米,不会和10米外的其他栅格点混淆):
library(sf) library(dplyr) # 接现有代码,直接使用合并后的sf对象 ras.ds.sf.ll # 计算所有点的距离矩阵 dist_matrix <- st_distance(ras.ds.sf.ll) # 单链接聚类,距离小于1米的点归为同一簇 hc <- hclust(as.dist(dist_matrix), method = "single") ras.ds.sf.ll$cluster_id <- cutree(hc, h = 1) # 按簇分组求均值 result <- ras.ds.sf.ll %>% group_by(cluster_id) %>% summarise( mean_value = mean(values), point_count = n(), geometry = st_centroid(geometry) # 取簇的质心作为该点代表坐标 ) # 输出结果 print(result)
方案2:统一投影后分组(适合大数据量,运算效率更高)
将两个瓦片的点统一转到同一个UTM坐标系,利用UTM的米制单位特性,按10米栅格的精度取整后分组:
library(sf) library(dplyr) # 接现有代码,将合并后的WGS84点统一转到UTM Zone21(EPSG:32721) ras.ds.sf.utm <- st_transform(ras.ds.sf.ll, crs = 32721) # 提取坐标并按米级精度取整(10米栅格的坐标天然为5结尾,取整到个位即可精准匹配) ras.df.utm <- ras.ds.sf.utm %>% mutate( x = round(st_coordinates(.)[,1], 0), y = round(st_coordinates(.)[,2], 0) ) %>% st_drop_geometry() # 按取整后的坐标分组求均值 result <- ras.df.utm %>% group_by(x, y) %>% summarise( mean_value = mean(values), point_count = n() ) # 输出结果 print(result)
两种方案输出的结果均为6条记录,每条对应两个瓦片同位置点的均值,符合预期。
内容的提问来源于stack exchange,提问作者Leprechault
相关产品推荐
相关产品推荐

