Как назначить идентификаторы узлов и получить кратчайшие маршруты в stplanr?

КЕЙС

Я хотел бы понять, как пользоваться stplanrна моих собственных данных узлов и ребер. Узлы имеют определенные координаты, но края между этими узлами не являются линейным расстоянием. Ребра содержат информацию о том, какие узлы они соединяют, каково расстояние, а также дополнительный весовой коэффициент, который описывает, насколько обременительно использовать этот путь. Поэтому кратчайший путь не всегда самый быстрый.

Решенные проблемы

Прямо сейчас я понял, как:

  • преобразовать мои данные ребер в stplanr пространственные объекты,
  • применять stplanr функция для них
  • учитывать разные веса

Dataprep

# attach packages --------------------------------------------------------------
library(sp)
library(sf)
library(igraph)
library(stplanr)
library(data.table)

# make up some dummy data that has the same structure as my original data ------
routes <- data.frame(X_from = c(1, 3, 3, 2, 1),
                     Y_from = c(3, 3, 2, 1, 3),
                     X_to = c(3, 3, 2, 1, 3),
                     Y_to = c(3, 2, 1, 3, 2),
                     id_from = c(101, 102, 103, 104, 101),
                     id_to = c(102, 103, 104, 101, 103),
                     id_edge = 1:5,
                     distance = c(2.1, 1, 1.5, 2.5, 10))

# convert it to the desired SpatialLinesNetwork format -------------------------
slines <- apply(routes, 1, function(x){
  l1 <- cbind(c(x["X_from"], x["X_to"]),
              c(x["Y_from"], x["Y_to"]))
  Sl1 <- Line(l1)
  S1 <- Lines(list(Sl1), ID = format(x["id_edge"], scientific = FALSE))
})
sl <- SpatialLines(slines)
df <- data.table(len = routes[["distance"]])
rownames(df) <- as.character(routes$id_edge)
sldf <- SpatialLinesDataFrame(sl, df)
sln <- SpatialLinesNetwork(sldf)
plot(sln) # success!

Проблемы

Как правильно определить узлы?

During my dataprep, I was not able to maintain the node IDs. I can assign them as demonstrated in the following, yet this is very prune to errors. Furthermore, the route itself seems not to be stored correctly when using the IDs (the red line does not reach the correct node).

# overwrite node/vertex IDs ----------------------------------------------------
V(sln@g)$name <- as.character(101:104)

# length of edges are automatically calculated
sln@sl$length
# [1] 2.000000 1.000000 1.414214 2.236068 2.236068

# add an additional weight information to each edge
(sln@sl$weight <- routes$distance)
# [1]  2.1  1.0  1.5  2.5 10.0

# shortest path ----------------------------------------------------------------
weightfield(sln) # current wightfield
# [1] "length"
(shortest <- sum_network_routes(sln = sln, 
                                start = "101", end = "103", 
                                sumvars = c("length", "weight"))
)
# sum_length,         sum_weight
# 2.2360678,          10

# fastest path -----------------------------------------------------------------
weightfield(sln) <- "weight" # change weightfield
(most_efficient <- sum_network_routes(sln = sln, 
                                      start = "101", end = "103",
                                      sumvars = c("length", "weight"))
) 
# sum_length,         sum_weight
# 3,                  3.1

# plot the results -------------------------------------------------------------
plot(sln)
plot(shortest, add = TRUE, col = "blue")
plot(most_efficient, add = TRUE, col = "red") # only one line of the whole path

How to derive the actual route?

I can calculate the shortest path via sum_network_routes(), get summary information and can plot the path. Yet, how do I retrieve the actual route of the vertices/nodes passed? I could'nt retrieve it from the object itself. Additionally, neither of the route_*() or line2route() functions worked.

Any help is appreciated:)

0 ответов

Другие вопросы по тегам