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

如何实现同一Shapefile中所有美国州样本多边形的完整连线?

问题描述

我想参照Stack Overflow上的菊花链连接思路,将美国州样本中提取的所有多边形用细线连接起来。目前已实现部分多边形间的连线,但无法让所有多边形最终连通,请问如何让已连接的多边形与未连接的多边形建立连接?

当前代码
library(dplyr)
library(sf)
library(ggplot2)
library(nngeo)

nc <- st_read(system.file("shape/nc.shp", package="sf"))
set.seed(2806)
nc_sample=dplyr::sample_n(nc,10)
ggplot() + geom_sf(data = nc_sample)

co=st_connect(nc_sample[1,], nc_sample %>% slice(st_distance(nc_sample[1,],nc_sample) %>%
                                                   units::drop_units() %>% 
                                                   as.data.frame() %>%
                                                   mutate_if(is.numeric, ~na_if(., 0)) %>%
                                                   rowwise() %>% which.min()))
all_connexion=st_sf(co)

for(i in 2:length(nc_sample$AREA)){
  co=st_connect(nc_sample[i,], nc_sample %>% slice(st_distance(nc_sample[i,],nc_sample) %>%
                                       units::drop_units() %>% 
                                       as.data.frame() %>%
                                       mutate_if(is.numeric, ~na_if(., 0)) %>%
                                        rowwise() %>% which.min()))
  all_connexion = rbind(all_connexion,co)
}

ggplot() + 
  geom_sf(data = all_connexion) +
  geom_sf(data = nc_sample) 
当前连线效果

当前连线效果

解决方案

你的问题根源在于:当前逻辑是让每个多边形单独连接自己的最近邻,这会形成多个独立的小连通块,而非单一整体连通的结构。要实现所有多边形连通的菊花链效果,需要维护一个动态扩展的已连通集合,每次从未连通的多边形中找到距离这个集合最近的个体,再将它与集合内最近的多边形连接,逐步把所有多边形纳入连通体系。

改进后的代码如下:

library(dplyr)
library(sf)
library(ggplot2)
library(nngeo)

# 加载数据并采样
nc <- st_read(system.file("shape/nc.shp", package="sf"))
set.seed(2806)
nc_sample <- dplyr::sample_n(nc, 10)

# 初始化已连通多边形的索引和连线对象
connected_idx <- 1
all_connexion <- st_sf()

# 循环直到所有多边形都被连通
while(length(connected_idx) < nrow(nc_sample)) {
  # 拆分已连通和未连通的多边形子集
  connected_polys <- nc_sample[connected_idx, ]
  unconnected_polys <- nc_sample[-connected_idx, ]
  
  # 计算未连通多边形到已连通集合的距离矩阵
  dist_matrix <- st_distance(unconnected_polys, connected_polys) %>%
    units::drop_units()
  
  # 找到距离已连通集合最近的未连通多边形,以及对应的已连通多边形
  min_dist_per_unconnected <- apply(dist_matrix, 1, min)
  target_unconnected_idx <- which.min(min_dist_per_unconnected)
  target_connected_idx <- which.min(dist_matrix[target_unconnected_idx, ])
  
  # 获取要连接的两个多边形
  poly_to_add <- unconnected_polys[target_unconnected_idx, ]
  poly_in_set <- connected_polys[target_connected_idx, ]
  
  # 创建连线并合并到总连线中
  new_connection <- st_connect(poly_to_add, poly_in_set)
  all_connexion <- rbind(all_connexion, st_sf(new_connection))
  
  # 更新已连通集合的索引
  original_unconnected_pos <- which(!(1:nrow(nc_sample) %in% connected_idx))[target_unconnected_idx]
  connected_idx <- c(connected_idx, original_unconnected_pos)
}

# 绘制最终连通效果
ggplot() + 
  geom_sf(data = all_connexion, color = "red") +
  geom_sf(data = nc_sample)
关键说明
  • 核心逻辑是逐步扩展连通域:每次只纳入距离当前连通集合最近的未连通多边形,确保新加入的多边形必然与已有连通体系相连,最终形成单一连通链。
  • 避免了原代码中“各连各的”导致的孤立块问题,确保所有多边形最终连通。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:37:39