将经纬度定义的sf多边形转换为UTM的问题排查
问题根源分析
我一眼就发现问题出在哪了——你在初始化空间对象时搞混了坐标系的设置!你的原始lats和lons是WGS84经纬度(GPS通用的度数格式),但你直接在st_as_sf里指定了crs = 3578(育空阿尔伯斯投影),这相当于告诉R:"这些数字已经是育空阿尔伯斯投影下的平面坐标了",但实际上它们是经纬度,所以R把错误的坐标解析到了太平洋区域。
修正方案
下面是一步步的修复代码和解释:
1. 正确创建空间多边形对象
先以WGS84坐标系(EPSG:4326)导入经纬度数据,再转换到你需要的投影:
library(sf) library(dplyr) library(tmap) # 原始经纬度数据(WGS84格式) lats <- c(64.25086, 64.24937, 63.24105, 63.22868) lons <- c(-140.9985, -136.9171, -137.0050, -141.0260) df <- data.frame(lon = lons, lat = lats) # 核心修正:先以EPSG:4326作为初始CRS,再转换到育空阿尔伯斯投影 polygon <- df %>% st_as_sf(coords = c('lon', 'lat'), crs = 4326) %>% # 这里是关键!匹配原始数据的坐标系 summarise(geometry = st_combine(geometry)) %>% st_cast('POLYGON') %>% st_transform(crs = 3578) # 现在再转成育空阿尔伯斯投影
2. 正确转换到UTM投影
育空地区大部分属于UTM带7N,对应的EPSG代码是32607,用标准EPSG代码比手动写proj字符串更可靠:
# 转换到UTM带7N(育空适用) poly_utm <- st_transform(polygon, crs = 32607)
3. 修复绘图代码
确保使用修正后的polygon对象绘图,还可以加上底图验证位置:
# 绘制修正后的多边形 m <- tm_shape(polygon) + tm_borders(col = 'black', lwd = 5, zindex = 1000) # 叠加OpenStreetMap底图确认位置 m + tm_basemap(server = "OpenStreetMap")
为什么之前的UTM转换失败?
因为你最初的sf对象CRS设置错误(把经纬度当成了3578投影坐标),st_transform是在错误的坐标基础上进行转换,自然得不到正确结果。只有先把初始CRS匹配原始数据的坐标系,后续的投影转换才会生效。
内容的提问来源于stack exchange,提问作者tamarack
相关产品推荐
相关产品推荐

