使用ggplot2与RMapShaper实现地图平滑边框时ms_simplify致图形错乱
问题核心诱因
- 警告本身的来源:
rmapshaper::ms_simplify()内部处理几何时会临时把输入的空间对象转成sp类做拓扑计算,这个转换过程会把原本带注释的WKT格式CRS对象转成传统proj4字符串,触发sp::proj4string的版本兼容警告,核心坐标参考参数并不会真的丢失。 - 边界完全错乱的本质原因:
- 对象栈混用:如果读入shapefile时用旧版
rgdal::readOGR()生成sp类对象传入函数,简化后的几何顶点顺序、多边形环方向会被打乱,后续用fortify()转成ggplot多边形数据时,无法正确按行政区边界分组,所有顶点会被跨行政区直接连线,出现完全缠结的错乱效果。 - 简化参数不匹配:函数默认的简化容差、顶点保留比例是针对投影坐标系(单位为米)设计的,如果输入的是经纬度地理坐标系(单位为度),默认容差会把跨行政区的顶点过度抽稀,甚至合并不同行政区的边界点,导致几何变形。
- CRS元数据校验缺失:函数简化后返回的对象如果没有手动同步CRS,后续空间操作时会因为CRS识别偏差,把坐标值映射到错误的位置。
- 对象栈混用:如果读入shapefile时用旧版
可落地的解决方案
按照从读入到画图的全流程调整,不需要更换其他简化函数:
- 统一用sf生态栈读入空间数据,从源头规避sp类对象的兼容问题
# 替换旧版readOGR读入逻辑 esp_map <- sf::st_read("西班牙自治区shapefile的本地存储路径") - 显式适配地理坐标系的参数调用
ms_simplify(),避免过度简化esp_map_simp <- rmapshaper::ms_simplify( esp_map, keep = 0.1, # 保留10%的顶点足够满足可视化精度 keep_by = "total", # 按整体总顶点数计算保留比例,避免小面积飞地被过度简化 snap = TRUE, # 自动吸附相邻边界的顶点,消除缝隙 wrap = FALSE, # 关闭跨日期线坐标折叠,西班牙不跨日期线,开启会导致坐标计算错误 sys = TRUE ) - 简化完成后手动校验并同步CRS,消除警告带来的潜在偏差
# 将原对象的CRS完整赋值给简化后的对象,覆盖转换过程丢失的注释元数据 sf::st_crs(esp_map_simp) <- sf::st_crs(esp_map) - 用
geom_sf()替换传统geom_polygon()的画图逻辑,避免顶点分组错乱
不需要手动用fortify()拆分多边形顶点,sf原生绘图函数会自动处理每个行政区的边界环、内洞、分组逻辑,从根源避免跨边界连线的错乱效果:ggplot() + geom_sf( data = esp_map_simp, fill = "#e8f4f8", color = "white", linewidth = 0.25 ) + theme_void()
注:出现的CRS警告本身不会影响实际可视化效果,只要完成上述CRS同步步骤,警告不会再复现,地图边界也不会出现错乱。
内容的提问来源于stack exchange,提问作者cholo.trem
相关产品推荐
相关产品推荐

