如何在R中正确将多边形地图叠加在栅格地图之上?
解决ggmap与SF图层叠加不匹配问题
问题核心原因
你遇到的图层偏移和警告提示,本质是坐标系不统一:
- 从
USAboundaries获取的州边界数据采用WGS84地理坐标系(EPSG:4326,经纬度格式) ggmap从Stamen获取的栅格地图默认使用Web墨卡托投影(EPSG:3857,米制平面坐标系)
直接叠加不同坐标系的图层会导致位置偏移,同时触发"Coordinate system already present"的警告。
解决方案:统一坐标系
将SF数据转换为与底图一致的EPSG:3857坐标系,即可彻底解决匹配问题。以下是修改后的完整代码:
library(USAboundaries) library(ggmap) library(ggplot2) library(sf) # 获取州边界并裁剪指定范围 us.state.longlat <- us_states() us.state.longlat.cropped.large <- sf::st_crop(us.state.longlat, c(xmin=-100, xmax=-80, ymin=30, ymax=50)) # 将SF数据转换为Web墨卡托投影(与底图坐标系一致) us.state.3857 <- st_transform(us.state.longlat.cropped.large, crs = 3857) # 获取栅格底图 bbox <- setNames(st_bbox(us.state.longlat.cropped.large), c("left", "bottom", "right", "top")) base_map <- get_map(bbox, source = "stamen", zoom = 5) # 叠加图层:此时坐标系完全匹配,无偏移 ggmap(base_map) + geom_sf(data = us.state.3857, inherit.aes = FALSE, color = "red", fill = "transparent")
小范围裁剪场景的适配
针对小范围裁剪的代码,只需添加相同的投影转换步骤即可:
us.state.longlat.cropped.small <- sf::st_crop(us.state.longlat, c(xmin=-92, xmax=-85, ymin=32, ymax=36)) # 转换为Web墨卡托投影 us.state.small.3857 <- st_transform(us.state.longlat.cropped.small, crs = 3857) bbox <- setNames(st_bbox(us.state.longlat.cropped.small), c("left", "bottom", "right", "top")) base_map_small <- get_map(bbox, source = "stamen", zoom = 7) ggmap(base_map_small) + geom_sf(data = us.state.small.3857, inherit.aes = FALSE, color = "red", fill = "transparent")
简化方案(适配新版ggmap)
如果使用较新版本的ggmap,可以直接用get_stamenmap配合ggmap_sf函数,该方式原生支持SF对象,无需手动转换投影:
base_map_sf <- get_stamenmap(bbox, zoom = 5, maptype = "terrain") ggmap_sf(base_map_sf) + geom_sf(data = us.state.longlat.cropped.large, color = "red", fill = "transparent")
内容的提问来源于stack exchange,提问作者Giuseppe Petri
相关产品推荐
相关产品推荐

