You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:05:21