在R中使用terra与sf:为何得到不合逻辑的距离测量结果?
问题:用terra计算多边形内曲线距离时结果与直线距离逻辑矛盾
问题概述
我使用terra计算美国德州国会选区多边形内随机点的受限曲线距离(路径不能超出多边形边界),并将其与直线距离对比,结果直线距离始终严格长于曲线距离——这显然不符合几何逻辑(直线是两点间最短路径,曲线距离应≥直线距离)。偶然发现将曲线距离乘以2后结果符合预期,但找不到代码层面的原因,请求排查问题。
操作步骤与代码
1. 加载德州选区地图数据
texas = dget("https://raw.githubusercontent.com/BajczA475/random-data/main/texascongressmaps") ggplot() + geom_sf(data = texas$geometry)
2. 创建结果存储变量
longest.dist.district.straight = rep(NA, 36) longest.dist.district.curved = rep(NA, 36)
3. 遍历36个选区计算距离
for(c in 1:36) { #Texas had 36 districts. if(c %% 3 == 0) {print(c)} # 进度提示 this.district = texas[c, ] # 获取当前选区 # 生成选区内100个随机采样点 rand.ptsDistrict = sf::st_sample(this.district, size = 100, type = 'random', exact = TRUE) # 计算点间最长直线距离 longest.dist.district.straight[c] = max(sf::st_distance(rand.ptsDistrict)) # 计算受限曲线距离:模拟沿选区边界内的路径,依次以每个点为目标计算到其他点的最长距离 current.raster = terra::ext(this.district) # 基于选区范围创建栅格 current.raster = terra::rast(current.raster, nrow=100, ncol=100, crs = crs(this.district), vals = 1) current.raster = terra::mask(current.raster, # 用选区多边形掩膜栅格,超出部分设为NA terra::vect(this.district), updatevalue = NA) point.locs = terra::cellFromXY(current.raster, # 获取采样点在栅格中的单元格位置 sf::st_coordinates(rand.ptsDistrict)) longest.dists.i = rep(NA, 100) # 存储单个点对应的最长曲线距离 for(i in 1:100) { point.i.loc = cellFromXY(current.raster, # 当前目标点的栅格位置 st_coordinates(rand.ptsDistrict[i])) point.noni.loc = cellFromXY(current.raster, # 其余所有点的栅格位置 st_coordinates(rand.ptsDistrict[-i])) terra::values(current.raster)[point.i.loc] = 2 # 将目标点标记为特殊值2 all.dists = terra::gridDistance(current.raster, # 计算所有单元格到目标点的路径距离 target = 2, scale = 1) longest.dists.i[i] = max(values(all.dists)[point.noni.loc], na.rm=TRUE) # 提取当前目标点到其他点的最长距离 terra::values(current.raster)[point.i.loc] = 1 # 恢复栅格值 } longest.dist.district.curved[c] = max(longest.dists.i) # 记录当前选区的最长曲线距离 }
异常结果示例
> (cbind(longest.dist.district.straight, longest.dist.district.curved)) longest.dist.district.straight longest.dist.district.curved [1,] 239285.77 121703.64 [2,] 63249.88 48238.89 ...(省略其余结果)
核心疑问
- 为何曲线距离会系统性地短于直线距离?
- 手动将曲线距离乘以2后结果符合预期,但找不到代码中导致此偏差的原因,求解释。
内容的提问来源于stack exchange,提问作者Bajcz
相关产品推荐
相关产品推荐

