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

如何使用sf按物种自动构建并绘制基于观测点的凸包?

用sf包自动化批量构建物种分布凸包

当然可行!而且用sf包完全能实现你想要的自动化批量处理,不用再手动复制代码逐个处理物种了。我来帮你把整个流程改成纯sf的实现方式,逻辑和你设想的几乎一致,而且更简洁统一:

步骤1:加载依赖包并读取数据

首先只加载需要的包,我们全程用sf处理空间操作,配合tidyverse做数据分组:

library(tidyverse)
library(sf)
library(maps)
library(ggplot2)

# 读取你的物种出现数据
fd <- read_csv("occurrence.csv")

步骤2:转换为sf点对象并批量构建凸包+缓冲区

核心是用group_by()按物种分组,然后通过summarize()对每组的点进行空间操作:

# 先把数据转换成sf点对象,指定经纬度字段和坐标系(这里用WGS84,EPSG:4326)
fd_sf <- fd %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326)

# 按物种分组,批量生成凸包和缓冲区
species_hulls <- fd_sf %>%
  group_by(species) %>%
  summarize(
    # 1. 把同物种的所有点合并成一个「多点几何对象」
    geometry = st_union(geometry),
    # 2. 基于多点构建凸包
    geometry = st_convex_hull(geometry),
    # 3. 给凸包添加缓冲区(这里dist单位是度,因为当前是地理坐标系;如果要米为单位,看后面的说明)
    geometry = st_buffer(geometry, dist = 1)
  ) %>%
  ungroup()  # 可选:取消分组,方便后续操作

关键细节解释:

  • st_as_sf(coords = c("lon", "lat")):把普通的经纬度列转换成sf的空间几何字段,这是sf处理空间数据的基础。
  • st_union(geometry):必须先把同物种的所有点合并成一个单一的几何对象,否则st_convex_hull()会给每个点单独生成凸包(毫无意义)。
  • st_buffer():这里的dist=1单位是度(因为我们用的是WGS84地理坐标系)。如果需要更准确的距离(比如10公里),建议先转换到投影坐标系(比如UTM)处理,再转回来:
    # 示例:转换到UTM投影(需根据你的数据范围选择合适的UTM带,比如EPSG:32615对应北半球15带)
    fd_utm <- fd_sf %>% st_transform(crs = 32615)
    
    species_hulls_utm <- fd_utm %>%
      group_by(species) %>%
      summarize(
        geometry = st_union(geometry),
        geometry = st_convex_hull(geometry),
        geometry = st_buffer(geometry, dist = 10000)  # 这里dist单位是米,代表10公里
      ) %>%
      st_transform(crs = 4326)  # 转换回WGS84用于绘图
    

步骤3:可视化物种分布区域

现在直接用sf的geom_sf()绘图,不用再像之前那样转换sp对象,更简洁:

# 读取世界地图数据并转换为sf对象
wrld2 <- st_as_sf(map('world2', plot = FALSE, fill = TRUE))

# 绘图
ggplot() +
  # 绘制世界底图
  geom_sf(data = wrld2, fill = 'gray20', color = "lightgrey", size = 0.07) +
  # 绘制每个物种的凸包缓冲区,按物种区分颜色
  geom_sf(data = species_hulls, aes(color = species), fill = NA, size = 1) +
  # 设置坐标范围,和你原来的一致
  coord_sf(xlim = c(100, 300), ylim = c(-60, 60)) +
  # 自定义物种颜色(可选)
  scale_color_manual(values = c("sp.A" = "red", "sp.B" = "blue")) +
  theme_minimal()

这样不管你有多少个物种,代码都能自动批量处理,完全不用手动复制修改每个物种的代码~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:29:01