I'm trying to generate a list of nodes on the shortest path between two nodes using st_network_paths()
. However, I only get a single value for the node index in node_path
.
It works with toy data but not real world data. What needs to happen to make the real world, stream network, play ball?
Line data available here
library(sfnetworks)
library(sf)
library(tidygraph)
library(tidyverse)
ln <- st_read("river.gpkg")
net = as_sfnetwork(ln)
paths <- st_network_paths(net,
from = 2,
to = 50)
# plot one path to check
node_path <- paths %>%
slice(1) %>%
pull(node_paths) %>%
unlist()
node_path
plot(net, col = "grey")
plot(slice(activate(net, "nodes"), 2),
col = "blue", add = TRUE)
plot(slice(activate(net, "nodes"), 50),
col = "red", add = TRUE)
plot(slice(activate(net, "nodes"), node_path),
col = "green", add = TRUE) # just recreates the node_path
The problem is that you are trying to compute a path between two different branches in a directed network:
# packages
library(sf)
library(tidygraph)
library(sfnetworks)
# data
ln <- st_read("C:/Users/andre/Desktop/river.gpkg", quiet = TRUE)
net = as_sfnetwork(ln)
# plot
par(mar = rep(0, 4))
plot(net)
plot(net %N>% slice(2, 50), add = TRUE, cex = 2, col = c("red", "blue"))
Created on 2021-12-15 by the reprex package (v2.0.1)
If the desired paths can also be calculated travelling "backwards", you can set the argument directed
in as_sfnetwork
to FALSE
(i.e. net = as_sfnetwork(ln, directed = FALSE)
and run the same code as before. You can recognise this type of problems since st_network_paths()
returns a warning message like
> paths <- st_network_paths(
+ net,
+ from = 2,
+ to = 50
+ )
Warning message:
In shortest_paths(x, from, to, weights = weights, output = "both", :
At structural_properties.c:4745 :Couldn't reach some vertices