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

如何实现两个sfc_LINESTRING网格对象的最近邻连接以构建sfnetworks网络

连接两个独立sf网格并构建统一网络的解决方案

问题背景

我有两个相邻区域,各自拥有一个sfc_LINESTRING类型的连通网格——一个区域较大、网格较粗,另一个区域较小、网格较细。想要实现连接操作,让大网格中的至少一个点与小网格中的至少一个点相连,最终目标是用sfnetworks构建包含两个采样区域所有节点的网络。尝试用st_join和merge未能成功,相关代码如下:

library(sf)
library(nngeo)

nc = st_read(system.file("shape/nc.shp", package="sf"))
nc_utm = st_transform(nc, crs="+proj=utm +zone=18 +datum=NAD83 +unit=m") # 使用UTM坐标系

# 裁剪出两个小区域用于采样网格
area_1 <- st_crop(nc_utm, xmin = 0, xmax = 20000, 
                  ymin = 3950000, ymax = 4000000)
area_2 <- st_crop(nc_utm, xmin = 20100, xmax = 25000, 
                  ymin = 3960000, ymax = 3980000)

# 采样网格并内部连接
grid_1 <- sf::st_sample(
  area_1, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  nngeo::st_connect(.,.,k = 9)

grid_2 <- sf::st_sample(
  area_2, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  nngeo::st_connect(.,.,k = 9)

# 可视化
ggplot() + 
  geom_sf(data = nc_utm) +
  geom_sf(data = area_1, fill = 'blue', alpha = 0.3) + 
  geom_sf(data = area_2, fill = "red", alpha = 0.3) + 
  geom_sf(data = grid_1, colour = "blue") + 
  geom_sf(data = grid_2, colour = "red") +
  coord_sf(datum = "+proj=utm +zone=18 +datum=NAD83 +unit=m",
           xlim = c(-10000, 30000), ylim = c(3940000, 4001000))

解决方案

st_join和merge仅适用于属性表关联,无法生成空间连接线。正确思路是:提取两个网格的原始节点,找到节点间的最近对,生成连接线,再合并所有线要素构建统一网络。

1. 保存网格的原始节点

修改采样代码,单独保存节点要素(后续用于找连接点):

library(dplyr)

# 采样area_1并保存节点
nodes_1 <- sf::st_sample(area_1, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  mutate(node_id = paste0("g1_", row_number())) # 给节点加唯一ID

grid_1 <- nngeo::st_connect(nodes_1, nodes_1, k = 9)

# 采样area_2并保存节点
nodes_2 <- sf::st_sample(area_2, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  mutate(node_id = paste0("g2_", row_number()))

grid_2 <- nngeo::st_connect(nodes_2, nodes_2, k = 9)

2. 找到两个网格的最近节点对

通过空间计算找出距离最近的节点对,作为连接点:

# 计算nodes_1中每个节点对应的nodes_2最近节点索引
nearest_idx <- st_nearest_feature(nodes_1, nodes_2)
# 计算每对节点的距离
nodes_1$nearest_dist <- st_distance(nodes_1, nodes_2[nearest_idx, ], by_element = TRUE)
# 筛选出距离最小的节点对
min_dist_row <- which.min(nodes_1$nearest_dist)
connect_node_1 <- nodes_1[min_dist_row, ]
connect_node_2 <- nodes_2[nearest_idx[min_dist_row], ]

3. 生成两个网格的连接线

基于选中的节点对生成空间连接线:

# 生成连接线要素
connect_line <- st_union(connect_node_1, connect_node_2) %>% 
  st_cast("LINESTRING") %>%
  st_as_sf() %>%
  mutate(from = connect_node_1$node_id, to = connect_node_2$node_id) # 记录连接关系

4. 合并网格并构建sfnetwork

将原始网格线和连接线合并,转换为sfnetwork对象:

library(sfnetworks)

# 合并所有线要素
all_lines <- bind_rows(grid_1, grid_2, connect_line)

# 构建无向sfnetwork
combined_network <- as_sfnetwork(all_lines, directed = FALSE)

5. 可视化验证

添加连接线的可视化代码,确认连接效果:

ggplot() + 
  geom_sf(data = nc_utm) +
  geom_sf(data = area_1, fill = 'blue', alpha = 0.3) + 
  geom_sf(data = area_2, fill = "red", alpha = 0.3) + 
  geom_sf(data = grid_1, colour = "blue") + 
  geom_sf(data = grid_2, colour = "red") +
  geom_sf(data = connect_line, colour = "green", size = 1.2) # 高亮连接线

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:12:49