CASE
Я хотел бы понять, как использовать stplanr
для моих собственных данных узлов и ребер. Узлы имеют определенные c координаты, но ребра между этими узлами не являются линейным расстоянием. Ребра содержат информацию о том, какие узлы они соединяют, каково расстояние и дополнительный весовой коэффициент, который описывает, насколько обременительным является использование этого пути. Поэтому самый короткий путь не всегда самый быстрый.
Решенные проблемы
Сейчас я выяснил, как:
- преобразовать мои данные ребер в
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!
Задачи
Как правильно определить узлы?
Во время моего dataprep я не смог поддерживать идентификаторы узлов. Я могу назначить их, как показано ниже, но это очень важно для ошибок. Кроме того, сам маршрут, похоже, не сохраняется правильно при использовании идентификаторов (красная линия не достигает нужного узла).
# 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
Как получить фактический маршрут?
I может вычислить кратчайший путь через sum_network_routes()
, получить сводную информацию и может построить путь. Тем не менее, как я могу получить фактический маршрут пройденных вершин / узлов? Я не мог извлечь его из самого объекта. Кроме того, ни одна из функций route_*()
или line2route()
не работала.
Любая помощь приветствуется :)