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

st_buffer投影至WGS84时结果严重失真的技术问询

问题:WGS84坐标下缓冲区转换后纬度范围异常

我以经纬度(28.5, 86.5)为中心点,要绘制100海里的缓冲区。按1度约等于60海里估算,经纬度最大最小值差应该略超3度。
用以下代码创建185200米(1海里=1852米)的缓冲区后:

test_point = st_as_sf(data.frame(Lat=28.5,Lon=86.5),coords=c("Lat","Lon"),remove=FALSE)
st_crs(test_point) = 4326
buff1 = st_buffer(test_point,100*1852)
buff2 = st_transform(buff1,crs=4326)

buff1的坐标范围符合预期(差值约200海里),但转换为WGS84的buff2纬度范围变成了0.24至56.78,明显异常,而经度范围84.85至88.16是合理的。

附输出信息:

buff1
#Simple feature collection with 1 feature and 2 fields
#Geometry type: POLYGON
#Dimension:     XY
#Bounding box:  xmin: 667639.2 ymin: 9981165 xmax: 1038039 ymax: 10351570
#CRS:           +proj=utm +zone=16
#   Lat  Lon                       geometry
#1 28.5 86.5 POLYGON ((1038039 10166365,...

#(Note that (10351570-9981165)/1852 is about 200 and (1038039-667639.2)/1852 is about 200 too.

buff2
#Simple feature collection with 1 feature and 2 fields
#Geometry type: POLYGON
#Dimension:     XY
#Bounding box:  xmin: 0.2407929 ymin: 84.84537 xmax: 56.77518 ymax: 88.15623
#Geodetic CRS:  WGS 84
#   Lat  Lon                       geometry
#1 28.5 86.5 POLYGON ((20.35843 84.95627...

# Note how far apart the xmin and xmax are.
原因排查与修正方案

核心问题:坐标顺序搞反了

  • sf包默认的坐标顺序是经度(Lon)在前,纬度(Lat)在后,但你在st_as_sf的coords参数里写的是c("Lat","Lon"),直接把原始点的坐标解析成了(纬度=28.5, 经度=86.5),完全搞反了。
  • 自动投影转换时,错误的坐标被分到了UTM 16N带,而86.5经度实际属于UTM 45N带,错误的投影带导致后续转换回WGS84时出现纬度范围异常。

修正后的最简代码

直接调整坐标顺序,同时推荐使用geodesic=TRUE参数,基于地理坐标系创建缓冲区,避免投影转换的麻烦:

# 修正坐标顺序:先Lon后Lat
test_point = st_as_sf(data.frame(Lat=28.5,Lon=86.5), coords=c("Lon","Lat"), remove=FALSE)
st_crs(test_point) = 4326
# 用geodesic模式创建缓冲区,直接在WGS84下生成正确的圆形缓冲区
buff_wgs84 = st_buffer(test_point, dist = 100*1852, geodesic = TRUE)

可选:用正确UTM投影创建缓冲区

如果非要用投影坐标系做缓冲区,先手动转换到对应区域的UTM带(86.5经度对应UTM 45N,EPSG代码32645):

test_point = st_as_sf(data.frame(Lat=28.5,Lon=86.5), coords=c("Lon","Lat"), remove=FALSE)
st_crs(test_point) = 4326
# 转换到正确的UTM投影
test_point_utm = st_transform(test_point, crs=32645)
# 创建缓冲区
buff_utm = st_buffer(test_point_utm, 100*1852)
# 转换回WGS84
buff_wgs84 = st_transform(buff_utm, crs=4326)

这样得到的缓冲区纬度范围会和预期一致,差值约3.3度,符合100海里的估算。

内容的提问来源于stack exchange,提问作者James S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:23:17