Изменение веса края пути в графике на основе открытой карты улиц на основе списка GPS-координат
Я хочу изменить вес частей маршрута на основе координат GPS. Для этого я хотел бы получить gps-координаты края рассчитанного маршрута, затем сравнить их со списком координат, которые у меня есть, и если координаты в моем списке совпадают с координатами конца маршрута, я хотел бы изменить вес этого края. В настоящее время у меня есть код, который рассчитывает маршрут и меняет вес всего маршрута. Я получаю координаты маршрута, но не могу понять, какие шаги необходимы, чтобы вернуться к графику... мой мозг просто отключается:)
library(osmar)
library(igraph)
### Get data ----
src <- osmsource_api(url = "https://api.openstreetmap.org/api/0.6/")
muc_bbox <- center_bbox(11.575278, 48.137222, 1000, 1000)
muc <- get_osm(muc_bbox, src)
### Reduce to highways: ----
hways <- subset(muc, way_ids = find(muc, way(tags(k == "highway"))))
hways <- find(hways, way(tags(k == "name")))
hways <- find_down(muc, way(hways))
hways <- subset(muc, ids = hways)
#### Plot data ----
## Plot complete data and highways on top:
plot(muc)
plot_ways(muc, col = "lightgrey")
plot_ways(hways, col = "coral", add = TRUE)
### Define route start and end nodes: ----
id<-find(muc, node(tags(v %agrep% "Sendlinger Tor")))[1]
hway_start_node <-find_nearest_node(muc, id, way(tags(k == "highway")))
hway_start <- subset(muc, node(hway_start_node))
id <- find(muc, node(attrs(lon > 11.58 & lat > 48.15)))[1]
hway_end_node <- find_nearest_node(muc, id, way(tags(k == "highway")))
hway_end <- subset(muc, node(hway_end_node))
## Add the route start and and nodes to the plot:
plot_nodes(hway_start, add = TRUE, col = "red", pch = 19, cex = 2)
plot_nodes(hway_end, add = TRUE, col = "red", pch = 19, cex = 2)
### Create street graph ----
gr <- as.undirected(as_igraph(hways))
### Compute shortest route: ----
# Calculate route
route <- function(start_node,end_node) {
get.shortest.paths(gr,
from = as.character(start_node),
to = as.character(end_node),
mode = "all")[[1]][[1]]}
# Plot route
plot.route <- function(r,color) {
r.nodes.names <- as.numeric(V(gr)[r]$name)
r.ways <- subset(hways, ids = osmar::find_up(hways, node(r.nodes.names)))
plot_ways(r.ways, add = TRUE, col = color, lwd = 2)
}
r <- route(hway_start_node,hway_end_node)
color <- colorRampPalette(c("springgreen","royalblue"))(nways)[numway]
plot.route(r,color)
route_nodes <- as.numeric(V(gr)[r]$name)
#We construct a newosmarobject containing only elements
#related to the nodes defining the route:
route_ids <- find_up(hways, node(route_nodes))
route_muc <- subset(hways, ids = route_ids)
#Route details.
#In order to present route details like street names,
#distances, and directions we have to work directly on the internals of the osmar objects.
#We start by extracting the route’s node IDs (which are in the correct order)
#and the way IDs (whichwe have to order)
#where the nodes are members:
node_ids <- route_muc$nodes$attrs$id
way_ids <- local({
w <- match(node_ids, route_muc$ways$refs$ref)
route_muc$ways$refs$id[w]
})
#Then we extract the names of the ways in the correct order:>
way_names <- local({
n <- subset(route_muc$ways$tags, k == "name")
n[match(way_ids, n$id), "v"]
})
#The next step is to extract the nodes’ coordinates,>
node_coords <- route_muc$nodes$attrs[, c("lon", "lat")]
#and to compute the distances (meters) and the bearings (degrees)
#between successive nodes (using thepackagegeosphere):
node_dirs <- local({
n <- nrow(node_coords)
from <- 1:(n - 1)
to <- 2:n
cbind(dist = c(0, distHaversine(node_coords[from,], node_coords[to,])),
bear = c(0, bearing(node_coords[from,], node_coords[to,])))
})
#Finally, we pack together all the information,
#and additionally compute the cumulative distance
route_details <- data.frame(way_names, node_dirs)
route_details$cdist <- cumsum(route_details$dist)
route_details$coord <- node_coords
route_details$id <- node_ids
print(route_details)
#here we select randomly parts from the route
gps_points<-route_details[sample(1:nrow(route_details), 10,replace=FALSE),]
здесь я хотел бы изменить вес частей графика на основе выбранных координат GPS. Я добираюсь до точки получения координат GPS, но я просто мысленно кладу трубку, чтобы вернуться к графику и изменить там веса.
# Currently i can only Modify current route weight
E(gr)[r]$weight <- E(gr)[r]$weight * 2
Спасибо за помощь! С наилучшими пожеланиями.
1 ответ
Следующий скрипт находит идентификаторы ребер, смежных со списком координат (wished.coord
), чтобы вы могли изменить веса:
library(osmar)
library(igraph)
library(tidyr)
library(dplyr)
### Get data ----
src <- osmsource_api(url = "https://api.openstreetmap.org/api/0.6/")
muc_bbox <- center_bbox(11.575278, 48.137222, 1000, 1000)
muc <- get_osm(muc_bbox, src)
### Reduce to highways: ----
hways <- subset(muc, way_ids = find(muc, way(tags(k == "highway"))))
hways <- find(hways, way(tags(k == "name")))
hways <- find_down(muc, way(hways))
hways <- subset(muc, ids = hways)
#### Plot data ----
## Plot complete data and highways on top:
plot(muc)
plot_ways(muc, col = "lightgrey")
plot_ways(hways, col = "coral", add = TRUE)
### Define route start and end nodes: ----
id<-find(muc, node(tags(v %agrep% "Sendlinger Tor")))[1]
hway_start_node <-find_nearest_node(muc, id, way(tags(k == "highway")))
hway_start <- subset(muc, node(hway_start_node))
id <- find(muc, node(attrs(lon > 11.58 & lat > 48.15)))[1]
hway_end_node <- find_nearest_node(muc, id, way(tags(k == "highway")))
hway_end <- subset(muc, node(hway_end_node))
## Add the route start and and nodes to the plot:
plot_nodes(hway_start, add = TRUE, col = "red", pch = 19, cex = 2)
plot_nodes(hway_end, add = TRUE, col = "red", pch = 19, cex = 2)
### Create street graph ----
gr <- as.undirected(as_igraph(hways))
### Compute shortest route: ----
# Calculate route
route <- function(start_node,end_node) {
get.shortest.paths(gr,
from = as.character(start_node),
to = as.character(end_node),
mode = "all")[[1]][[1]]}
# Plot route
plot.route <- function(r,color) {
r.nodes.names <- as.numeric(V(gr)[r]$name)
r.ways <- subset(hways, ids = osmar::find_up(hways, node(r.nodes.names)))
plot_ways(r.ways, add = TRUE, col = color, lwd = 2)
}
nways <- 1
numway <- 1
r <- route(hway_start_node,hway_end_node)
# Plot route
color <- colorRampPalette(c("springgreen","royalblue"))(nways)[numway]
plot.route(r,color)
## Route details ----
# Construct a new osmar object containing only elements
# related to the nodes defining the route:
route_nodes <- as.numeric(V(gr)[r]$name)
route_ids <- find_up(hways, node(route_nodes))
osmar.route <- subset(hways, ids = route_ids)
osmar.nodes.ids <- osmar.route$nodes$attrs$id
# Extract the nodes’ coordinates,
osmar.nodes.coords <- osmar.route$nodes$attrs[, c("lon", "lat")]
osmar.nodes <- cbind(data.frame(ids = osmar.nodes.ids),
data.frame(ids_igraph = as.numeric(V(gr)[r]) ),
osmar.nodes.coords)
## Find edges ids containing points of interest ----
wished.coords <- data.frame(wlon = c(11.57631),
wlat = c(48.14016))
# Calculate all distances
distances <- crossing(osmar.nodes,wished.coords) %>%
mutate(dist = geosphere::distHaversine(cbind(lon,lat),cbind(wlon,wlat)))
# Select nodes below maximum distance :
mindist <- 50 #m
wished.nodes <- distances %>% filter(dist < mindist)
# Select edges incident to these nodes :
selected.edges <- unlist(incident_edges(gr,V(gr)[wished.nodes$ids_igraph]))
# Weight of selected edges
E(gr)[selected.edges]$weight