ggplot borders函数绘制美西南部地图时边界错位问题求助
问题:美国西南部放大地图中,州边界与Stadia底图偏差明显,缩小后恢复正常
问题描述
尝试以Stadia地图为底图叠加州边界制作美国西南部地图时,放大区域(zoom=8)内的内华达、犹他、新墨西哥州边界出现明显偏差;但将地图范围扩展至全美(zoom=4)时,边界显示恢复正常。
原放大地图代码
#register api key register_stadiamaps(key = "your key") #create zoomed in base map base <- get_stadiamap(bbox = c(left = -120, bottom =31.25, right = -108.5, top = 42), zoom = 8, maptype = "stamen_terrain_background") #plot map with state borders ggmap(base)+ borders("state",colour="black")

原缩小全美地图代码
#create zoomed out map of the whole US base_out<- get_stadiamap(bbox = c(left =-124.732453, bottom =24.445430, right =-66.983690, top =49.39), zoom = 4, maptype = "stamen_terrain_background") #plot map with state borders ggmap(base_out)+ borders("state",colour="black")

问题根源
问题出在坐标系不匹配带来的投影误差:
- Stadia这类在线地图底图用的是Web墨卡托投影(EPSG:3857),这是专门为网页地图优化的投影方式,虽高纬度区域会有拉伸,但适合在线展示。
borders("state")默认加载的是WGS84经纬度坐标系(EPSG:4326)的边界数据,数据直接以经纬度存储。
放大地图(聚焦小范围区域)时,两种坐标系转换的细微误差会被显著放大,表现为边界与底图错位;缩小到全美范围时,误差被分摊到整个地图上,视觉上就难以察觉了。
解决方案
将州边界数据转换为与Stadia底图一致的Web墨卡托坐标系即可解决偏差问题,使用sf包处理空间数据转换:
修正后的代码
library(ggmap) library(sf) # 注册Stadia API密钥 register_stadiamaps(key = "your key") # 获取放大的Web墨卡托底图 base <- get_stadiamap(bbox = c(left = -120, bottom = 31.25, right = -108.5, top = 42), zoom = 8, maptype = "stamen_terrain_background") # 转换州边界坐标系为Web墨卡托(EPSG:3857) state_borders_sf <- borders("state") %>% st_as_sf() %>% # 将borders对象转为sf空间对象 st_transform(crs = 3857) # 转换坐标系 # 绘制地图,设置inherit.aes = FALSE避免ggmap与ggplot的美学映射冲突 ggmap(base) + geom_sf(data = state_borders_sf, color = "black", inherit.aes = FALSE)
补充说明
inherit.aes = FALSE是必填项,否则ggmap和ggplot的默认美学映射会冲突,导致图层无法正确渲染。- 几乎所有在线地图服务(谷歌地图、Mapbox等)都采用Web墨卡托投影,叠加自定义图层时都需要注意坐标系匹配问题。
内容的提问来源于stack exchange,提问作者Jason Edelkind
相关产品推荐
相关产品推荐

