2

我在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,KL都是在我们开始计算之前已知的固定参数。

  • 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

  1. hx在该起点计算,然后在沿边的每个节点计算(在此示例中仅显示起点和终点节点),直到到达边 g边 b合并形成边 a的交界处。

  2. 在边 a 的那个端点:

hx = sqrt(10^2 + (0.5*100/1500)*(2*1100-100)).
hx = 13.03
  1. 边缘 g边缘 b的这个交界处,我想更新h0以反映在边缘 ahx的终点计算的结果,因此为 13.03。该值将用于边g边 bhxh0

  2. 我现在想对每个子网进行这个计算。我将从边缘 b开始的子网开始。h0已更改为 13.03,我们计算边 bhx上的节点,然后到达边 c边 d的交界处。

  3. 在边 b的那个端点:

hx = sqrt(13.03^2 + (0.5*100/1500)*(2*500-100))
hx = 14.13
  1. h0边 c边 d更新,以反映hxb的端点 (14.13)
  2. hx为边 d上的所有节点计算,并再次在边 c上计算。
  3. 边 c的端点处,h0更新以反映边 e边 fhx的交界处
hx = sqrt(14.13^2+(0.5*100/1500)*(2*300 – 100))
hx = 14.79
  1. hx最终计算边缘 e边缘 f上的所有节点,使用在边缘 chx的端点计算的. 这样就完成了该子网的遍历。h0

  2. 我们返回边 g来计算hx从那里开始的子网。

  3. 从前面的计算中我们知道,边 ahx的端点是 13.03。我们现在想再次反映从边 g开始遍历子网络的这个值。h0

  4. 当我们到达边 h边 i的节点交汇点时,我们再次更新h0以反映在边 ghx的终点处计算的值。

hx = sqrt(13.03^2 +(0.5*100/1500)*(2*500-100))
hx = 14.13
  1. 这是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上的所有节点进行最终更新后h0hx计算 , 。

总而言之,h0当您向上游移动到新边缘时,需要更新以反映hx直接下游边缘的最大值。必须达到一定的解决顺序,在解决任何边缘(第一条边缘之外)之前,您需要知道该ho段的 ,这意味着您必须首先解决下面的边缘,以确定hx要使用的.

我一直在努力想出一个循环/迭代/递归解决方案来解决这个计算,从表面上看,它应该很容易解决。单个引流线程的解决方案很容易手动完成,但是当它扩展到整个网络时,必须解决这些排序问题。当网络中有数千条边时,手动进行这些计算将不是一种选择。

这种类型的计算顺序在许多基本水文分析中非常常见(计算河流顺序、河流大小、计算上游贡献面积等)。 sfnetworks并且 tidygraph似乎非常适合进行这种类型的计算,但是在水文网络上的示例应用程序很少(大多数图形分析工具都适用于道路网络,考虑到用户数量的差异,这是完全有意义的)。

我试图让它尽可能地重复,如果需要更多,我会很乐意提供,鉴于问题的概念性更强,这很难做到。

4

0 回答 0