使用 R 包 sfnetworks 对给定节点上游的河流网络进行子集化

mbc*_*ima 6 r network-analysis r-sf sfnetwork

我正在尝试使用该sfnetworks 来查询河流网络。具体来说,我想相对于任何给定站点对河流网络的上游部分进行子集化。

我有一个小型河流网络数据集(可在此处获取),我可以将其转换为sfnetwork,该数据集由包定义为具有空间明确边缘的有根树。生成的网络是有向非循环图(参见ggraph下图)。

library(sf)
library(sfnetworks)
library(ggraph)
library(cowplot)

ss <- st_read(file.path("stream_network_subsetS_KNIG.gpkg")) # subset small network (Lull Creek)

#' create sfnetwork object from river network
#' https://github.com/luukvdmeer/sfnetworks/discussions/143
n.ss <- as_sfnetwork(st_cast(ss, "LINESTRING"))

n.ss

plot(n.ss)

#' visualize directness of network
ggraph(n.ss, layout = "tree") +
  geom_node_point(size = 1) +
  geom_edge_link(arrow = arrow(length = unit(2, 'mm'), ends = "first"),
                 end_cap = circle(2, 'mm'),
                 start_cap = circle(2, 'mm')) +
  theme_graph()
Run Code Online (Sandbox Code Playgroud)

sfnetwork对象的直接性 我想做的是子集/过滤我指定的任何给定节点上游的网络。由于sfnetworks用于igraph底层网络数据结构,我尝试使用igraph::shortest_paths获取上游节点:

#' this node is on the lower main stem of the network
node <- 50

#' query the nodes/vertices with a path to the node (warning issued)
x <- unique(unlist(igraph::shortest_paths(n.ss, from = node, to = igraph::V(n.ss), mode = "in")[[1]]))

#' select upstream nodes from spatial network
up.ss <- rep(FALSE, nrow(st_as_sf(n.ss, "nodes")))
up.ss[x] <- TRUE

n.ss.up <- n.ss |>
  activate("nodes") |>
  filter(up.ss)

#' plot upstream nodes
plot_grid(autoplot(n.ss), autoplot(n.ss.up))
Run Code Online (Sandbox Code Playgroud)

左:整个河网,右:尝试提取节点 50 上游的节点 奇怪的是,shortest_paths只返回沿河网主干的节点。我知道sfnetworks::st_network_paths,但我不确定它是否适合我想做的事情。我的问题是,我将如何sfnetworks选择我指定的节点上游的河网(即顶点/节点和边)?

我还知道sfnetworks有一个路由教程(路由教程),但它明确强调街道网络路由。

使用dput示例数据会产生难以处理的输出,因此我已将数据集上传到此处的Google Drive (如果有人可以指出共享约 50MB 文件的更好解决方案,我将继续使用它以实现可重复性) )。谢谢你!

小智 2

接近了!您的代码正在寻找可以到达下游而不是上游的所有河流段。这可能只是河流数据集中的链接编码方式的产物。

更改您的代码行:

  • from x <- unique(unlist(igraph::shortest_paths(n.ss, from = node, to = igraph::V(n.ss), mode = " in ")[ 1 ]))
  • x <- unique(unlist(igraph::shortest_paths(n.ss, from = node, to = igraph::V(n.ss), mode = " out ")[ 1 ]))

我希望您会看到突出显示的上游链接,如下所示: 显示整个流域以及下游和上游节点的图像(分别为进出)