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

如何通过sf包将ggplot2绘制的地图导出为GeoPDF?

解决ggplot2地图导出GeoPDF的问题

错误原因分析

你碰到的 Error in UseMethod("st_as_sf") : method not applicable for 'st_as_sf' applied to a class object "c('gg', 'ggplot')" 错误,核心原因很简单:
sf::st_write() 是专门用来写入sf空间数据对象的工具,它完全无法识别ggplot生成的可视化对象(gg/ggplot类)。直接把ggplot图传给它,自然会出现类型不匹配的报错。

下面给你两种可行的解决方案,既能保留ggplot的定制化样式,又能生成带地理参考的PDF。

方案一:先导出普通PDF,再用GDAL添加地理参考

这是最灵活的方法——既可以用ggplot随心所欲定制地图样式,又能给成品PDF补上地理参考。需要用到gdalUtils包(前提是你的系统已经安装了GDAL工具,Windows可以通过OSGeo4W安装,macOS用Homebrew,Linux用包管理器比如apt-get install gdal-bin)。

完整代码示例

# 加载所需包
library(ggplot2)
library(ggspatial)
library(sf)
library(gdalUtils)

# 读取并处理数据
all.stands.predict <- read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/prediction__bug_2021-03-18.csv")
all.stands.predict <- all.stands.predict[all.stands.predict[,3]=="VILA PALMA",]
sites <- st_as_sf(all.stands.predict, coords = c("x", "y"), crs = 4326, agr = "constant")

# 绘制你需要的ggplot地图
gg <- ggplot() +
  geom_sf(data=sites, color="red") +
  annotation_north_arrow(location = "bl", which_north = "true", pad_x = unit(0.3, "in"), pad_y = unit(0.5, "in"), style = north_arrow_fancy_orienteering) +
  annotation_scale(location = "bl", width_hint = 0.55) +
  xlab("Longitude") + ylab("Latitude") +
  theme_bw()

# 1. 先导出无地理参考的普通PDF
ggsave("mymap_plain.pdf", plot = gg, device = "pdf")

# 2. 获取数据的地理范围(用于给PDF添加参考)
bbox <- st_bbox(sites)
# 转换成GDAL需要的格式:xmin ymin xmax ymax
bbox_str <- paste(bbox$xmin, bbox$ymin, bbox$xmax, bbox$ymax)

# 3. 用gdal_translate给PDF添加地理参考,生成GeoPDF
gdal_translate(
  src_dataset = "mymap_plain.pdf",
  dst_dataset = "mymap_georef.pdf",
  of = "PDF",
  a_srs = "EPSG:4326",  # 匹配你的数据坐标系
  a_ullr = bbox_str    # 传入地理范围
)

方案二:用sf原生绘图生成GeoPDF(简化版)

如果你的地图不需要太复杂的ggplot定制(比如只需要基础的空间点展示),可以直接用sf::st_plot()绘图,再按同样的流程添加地理参考,步骤会更简洁:

代码示例

library(sf)
library(gdalUtils)

# 读取并处理数据(同方案一)
all.stands.predict <- read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/prediction__bug_2021-03-18.csv")
all.stands.predict <- all.stands.predict[all.stands.predict[,3]=="VILA PALMA",]
sites <- st_as_sf(all.stands.predict, coords = c("x", "y"), crs = 4326, agr = "constant")

# 用st_plot绘制并导出普通PDF
st_plot(sites, col = "red")
ggsave("mymap_sf_plain.pdf")

# 重复方案一的步骤添加地理参考
bbox <- st_bbox(sites)
bbox_str <- paste(bbox$xmin, bbox$ymin, bbox$xmax, bbox$ymax)
gdal_translate(
  src_dataset = "mymap_sf_plain.pdf",
  dst_dataset = "mymap_sf_georef.pdf",
  of = "PDF",
  a_srs = "EPSG:4326",
  a_ullr = bbox_str
)

注意事项

  • 如果你的ggplot地图手动设置了xlim/ylim缩放范围,一定要把bbox换成你实际显示的范围,而不是原始数据的边界,否则地理参考会错位。
  • 确认GDAL工具安装成功:可以在终端输入gdalinfo --version检查,R里的gdalUtils包需要依赖系统级的GDAL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:39:12