使用ggplot的geom_sf绘制墨卡托投影世界地图出现异常线条的问题
问题原因及解决方法
原因
- maps包提供的世界地图数据未处理跨180°经线的多边形,像俄罗斯这种横跨东西半球的国家,其多边形顶点是连续绘制的,转换到墨卡托投影(EPSG:3857)时,投影算法会直接连接180°经线两侧的顶点,从而形成贯穿整个绘图区域的异常线条。
- 该数据拓扑结构不完善,缺乏针对跨经线多边形的拆分处理,导致投影转换时出现拓扑错误。
解决方法
方法一:改用更规范的sf内置世界地图数据
sf包自带的world_sf数据集已预先处理好跨经线多边形问题,无需额外操作即可正常投影:
library(sf) library(ggplot2) # 加载并过滤掉南极洲 world_sf <- sf::world_sf %>% filter(name != "Antarctica") # 绘制墨卡托投影地图 ggplot(world_sf) + geom_sf() + coord_sf(crs = st_crs("EPSG:3857"))
方法二:手动处理maps包的跨经线多边形
如果坚持使用maps包的数据,可通过sf::st_wrap_dateline函数拆分跨180°经线的多边形,避免异常连线:
library(maps) library(sf) library(ggplot2) # 加载数据并处理跨日期线的多边形 world1 <- sf::st_as_sf(map('world', plot = FALSE, fill = TRUE)) %>% sf::st_wrap_dateline(options = c("WRAPDATELINE=YES", "DATELINEOFFSET=180")) %>% filter(ID != "Antarctica") # 绘制地图 ggplot(world1) + geom_sf() + coord_sf(crs = st_crs("EPSG:3857"))
st_wrap_dateline会把跨180°经线的多边形在日期线位置拆分成两个独立部分,转换投影时就不会出现跨画布的线条了。
内容的提问来源于stack exchange,提问作者Sebastian Geis
相关产品推荐
相关产品推荐

