我在sfnetworks
. 它来源于流网络的线形文件。对于流网中的每条支流,显然都有起止节点来sfnetworks
决定,但线路上也有连接起止节点的节点。为简单起见,我将采用在这个问题中开发的示例网络。
library(sfnetworks)
library(sf)
library(tidygraph)
library(dplyr)
library(tidyverse)
rm(list = ls())
n01 = st_sfc(st_point(c(0, 0)))
n02 = st_sfc(st_point(c(1, 2)))
n03 = st_sfc(st_point(c(1, 3)))
n04 = st_sfc(st_point(c(1, 4)))
n05 = st_sfc(st_point(c(2, 1)))
n06 = st_sfc(st_point(c(2, 3)))
n07 = st_sfc(st_point(c(2, 4)))
n08 = st_sfc(st_point(c(3, 2)))
n09 = st_sfc(st_point(c(3, 3)))
n10 = st_sfc(st_point(c(3, 4)))
n11 = st_sfc(st_point(c(4, 2)))
n12 = st_sfc(st_point(c(4, 4)))
from = c(1, 2, 2, 3, 3, 5, 5, 8, 8, 9, 9)
to = c(5, 3, 6, 4, 7, 2, 8, 9, 11, 10, 12)
nodes = st_as_sf(c(n01, n02, n03, n04, n05, n06, n07, n08, n09, n10, n11, n12))
edges = data.frame(from = from, to = to)
G_1 = sfnetwork(nodes, edges)%>%
convert(to_spatial_explicit, .clean = TRUE) %>%
activate(edges) %>%
mutate(edgeID = c("a","c","d","e","f","b","g","h","i","j","k")) %>%
mutate(dL = c(1100, 300, 100, 100, 100, 500, 500, 300, 100, 100, 100))
ggplot()+
geom_sf(data = G_1 %>% activate(edges) %>% as_tibble() %>% st_as_sf(), aes(color = factor(edgeID)), size = 1.5)+
geom_sf(data = G_1 %>% activate(nodes) %>% as_tibble() %>% st_as_sf())+
scale_color_brewer(palette = "Paired")+
labs(x = "Longitude", y = "Latitude", color = "EdgeID")+
theme_bw()
当你在溪流上游移动时,我正在求解一个方程,从河流出口开始。我会尽可能多地为您保存有关该方程式的详细信息,但本质上是:
我正在hx
根据节点属性在每个节点 x 处求解。
hx = sqrt(h0^2 + (N*dX/K)*(2*L – dX))
N
,dX
,K
和L
都是在我们开始计算之前已知的固定参数。N
,K
对于所有节点都是固定的,它们永远不会改变。dX
是节点特定属性。h0
并且L
是边缘特定的属性(它们对于边缘上的所有节点都是相同的)h0
由用户在计算开始时定义,但随着您在上游遍历网络时发生变化,当新边收敛时在末端节点发生变化。h0
最初设置为 10,N = 0.5,K = 1500。为了简单起见,我们将说每条边长 100m。
dX
只是反映每个边缘的距离。每条边上的下游节点,dX = 0
。每条边上的上游节点,dX = 100
。L
反映了一个通道上游的总距离edge
,加上那个的总长度edge
。
我想在边缘 a的下游节点开始计算h0 = 10
。
hx
在该起点计算,然后在沿边的每个节点计算(在此示例中仅显示起点和终点节点),直到到达边 g和边 b合并形成边 a的交界处。在边 a 的那个端点:
hx = sqrt(10^2 + (0.5*100/1500)*(2*1100-100)).
hx = 13.03
在边缘 g和边缘 b的这个交界处,我想更新
h0
以反映在边缘 ahx
的终点计算的结果,因此为 13.03。该值将用于边g和边 b。hx
h0
我现在想对每个子网进行这个计算。我将从边缘 b开始的子网开始。
h0
已更改为 13.03,我们计算边 bhx
上的节点,然后到达边 c和边 d的交界处。在边 b的那个端点:
hx = sqrt(13.03^2 + (0.5*100/1500)*(2*500-100))
hx = 14.13
h0
为边 c和边 d更新,以反映hx
边b的端点 (14.13)hx
为边 d上的所有节点计算,并再次在边 c上计算。- 在边 c的端点处,
h0
更新以反映边 e和边 fhx
的交界处
hx = sqrt(14.13^2+(0.5*100/1500)*(2*300 – 100))
hx = 14.79
hx
最终计算边缘 e和边缘 f上的所有节点,使用在边缘 chx
的端点计算的. 这样就完成了该子网的遍历。h0
我们返回边 g来计算
hx
从那里开始的子网。从前面的计算中我们知道,边 a
hx
的端点是 13.03。我们现在想再次反映从边 g开始遍历子网络的这个值。h0
当我们到达边 h和边 i的节点交汇点时,我们再次更新
h0
以反映在边 ghx
的终点处计算的值。
hx = sqrt(13.03^2 +(0.5*100/1500)*(2*500-100))
hx = 14.13
- 这是
h0
用于边 h和边 i的值。我们hx
在边 i上计算,然后在边 h上计算。h0
最后一次更新边缘 j和边缘 k合并以反映在边缘 hhx
的端点处计算的值。
hx = sqrt(14.13^2 + (0.5*100/1500)*(2*500-100))
hx = 14.79
在对边 j和边 k上的所有节点进行最终更新后h0
,hx
计算 , 。
总而言之,h0
当您向上游移动到新边缘时,需要更新以反映hx
直接下游边缘的最大值。必须达到一定的解决顺序,在解决任何边缘(第一条边缘之外)之前,您需要知道该ho
段的 ,这意味着您必须首先解决下面的边缘,以确定hx
要使用的.
我一直在努力想出一个循环/迭代/递归解决方案来解决这个计算,从表面上看,它应该很容易解决。单个引流线程的解决方案很容易手动完成,但是当它扩展到整个网络时,必须解决这些排序问题。当网络中有数千条边时,手动进行这些计算将不是一种选择。
这种类型的计算顺序在许多基本水文分析中非常常见(计算河流顺序、河流大小、计算上游贡献面积等)。
sfnetworks
并且 tidygraph
似乎非常适合进行这种类型的计算,但是在水文网络上的示例应用程序很少(大多数图形分析工具都适用于道路网络,考虑到用户数量的差异,这是完全有意义的)。
我试图让它尽可能地重复,如果需要更多,我会很乐意提供,鉴于问题的概念性更强,这很难做到。