You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用osmdata与ggplot2实现海洋/陆地填充?osm_line2poly报错求解

如何用{osmdata}和{ggplot2}实现海洋/陆地区域填充?

问题背景

需求是通过{osmdata}和{ggplot2}绘制包含海洋、陆地区域填充的地图,但实际操作中遇到阻碍:

  • OpenStreetMap将海岸线存储为线条对象,{osmplotr}文档提及的osm_line2poly()转换函数调用时报错:
    osmplotr::osm_line2poly(coast$osm_lines, bb)
    #> Error in FUN(X[[i]], ...): unbenutztes Argument (V = c(3, 1, 6, 7, 2, NA, 5))
    
  • {tigris}包仅能提供美国区域的多边形数据,无法满足通用区域需求。

尝试的代码示例:

library(osmdata)
library(osmplotr)
library(sf)
library(tidyverse)

# define example bbox
bb <- tribble(
  ~xy,  ~min,  ~max,
  "x", 12.00, 12.18,
  "y", 54.08, 54.20
) %>% column_to_rownames("xy") %>% as.matrix()

# get "water"
water <- opq(bb) %>%
  add_osm_feature(key = "natural", value = "water") %>%
  osmdata_sf()

# get "coastline"
coast <- opq(bb) %>%
  add_osm_feature(key = "natural", value = "coastline") %>%
  osmdata_sf()

# ggplot
ggplot() +
  geom_sf(
    data = water$osm_multipolygons,
    fill = "navy",
    color = NA
  ) + 
  geom_sf(
    data = coast$osm_lines,
    fill = "navy",
    color = "blue"
  )

解决方案

方案1:基于{sf}空间运算的通用方法

无需依赖{osmplotr},直接通过{sf}的差集运算生成海洋区域,步骤如下:

  1. 获取陆地多边形数据
    OSM中natural=land标签对应陆地区域,直接获取:
land <- opq(bb) %>%
  add_osm_feature(key = "natural", value = "land") %>%
  osmdata_sf()
  1. 创建边界框多边形
    将自定义的bbox转换为空间多边形,作为整个地图的范围基底:
bb_poly <- st_as_sfc(st_bbox(bb))
  1. 计算海洋区域
    通过边界框减去所有陆地的合并多边形,得到海洋区域:
ocean <- st_difference(bb_poly, st_union(land$osm_multipolygons))
  1. 绘制填充地图
    按照海洋→陆地→内陆水的层级顺序绘制,确保视觉正确:
ggplot() +
  # 填充海洋
  geom_sf(data = ocean, fill = "navy", color = NA) +
  # 填充陆地
  geom_sf(data = land$osm_multipolygons, fill = "forestgreen", color = NA) +
  # 填充内陆水域(湖泊、河流等)
  geom_sf(data = water$osm_multipolygons, fill = "navy", color = NA) +
  # 可选:添加海岸线边框
  geom_sf(data = coast$osm_lines, color = "blue", size = 0.2) +
  theme_minimal()

方案2:修复{osmplotr}转换错误

若坚持使用{osmplotr},可尝试以下操作:

  • 更新{osmplotr}至最新版本,旧版本可能存在参数兼容问题
  • 先将分散的海岸线线条合并为单一多线对象,再调用转换函数:
# 合并海岸线线条为多线对象
coast_combined <- coast$osm_lines %>%
  st_combine() %>%
  st_cast("MULTILINESTRING")

# 转换为多边形
coast_poly <- osmplotr::osm_line2poly(coast_combined, bb)

内容的提问来源于stack exchange,提问作者Paul Schmidt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:25:27