I am trying to map a route using the route() function in ggmap. My problem is that the route doesn\'t stay on the roads. Is there something that my route_df <- route(or
You can use my googleway
package
library(googleway)
apiKey <- 'your_api_key'
mapKey <- 'your_maps_api_key'
res <- google_directions(origin = "Tinsletown, Vancouver, BC",
destination = "Science World, Vancouver, BC",
key = apiKey)
The polyline is in res$routes$overview_polyline$points
You can decode the polyline if you want
pl <- res$routes$overview_polyline$points
decode_pl(pl)
# lat lon
# 1 49.28025 -123.1076
# 2 49.27969 -123.1076
# 3 49.27823 -123.1076
# 4 49.27711 -123.1077
# 5 49.27707 -123.1043
But you don't have to, you can plot the line directly
df <- data.frame(polyline = pl)
google_map(key = mapKey, search_box = T) %>%
add_polylines(data = df, polyline = "polyline")
Note
It looks like you are not actually getting the required polylines from route()
since the default output=
parameter is set to simple
. You probably need to change it to all
as below and start decoding the polylines.
Below is one solution that is based on the decodeLine()
function taken from here. Their solution is to define a custom function that decodes polylines and then plot everything it decoded.
library(ggmap)
library(leaflet)
way1txt <- "Tinsletown, Vancouver, BC"
way2txt <- "Science World, Vancouver, BC"
route_all <- route(way1txt, way2txt, structure = "route",
output = "all")
# Custom decode function
# Taken from http://s4rdd.blogspot.com/2012/12/google-maps-api-decoding-polylines-for.html
decodeLine <- function(encoded){
require(bitops)
vlen <- nchar(encoded)
vindex <- 0
varray <- NULL
vlat <- 0
vlng <- 0
while(vindex < vlen){
vb <- NULL
vshift <- 0
vresult <- 0
repeat{
if(vindex + 1 <= vlen){
vindex <- vindex + 1
vb <- as.integer(charToRaw(substr(encoded, vindex, vindex))) - 63
}
vresult <- bitOr(vresult, bitShiftL(bitAnd(vb, 31), vshift))
vshift <- vshift + 5
if(vb < 32) break
}
dlat <- ifelse(
bitAnd(vresult, 1)
, -(bitShiftR(vresult, 1)+1)
, bitShiftR(vresult, 1)
)
vlat <- vlat + dlat
vshift <- 0
vresult <- 0
repeat{
if(vindex + 1 <= vlen) {
vindex <- vindex+1
vb <- as.integer(charToRaw(substr(encoded, vindex, vindex))) - 63
}
vresult <- bitOr(vresult, bitShiftL(bitAnd(vb, 31), vshift))
vshift <- vshift + 5
if(vb < 32) break
}
dlng <- ifelse(
bitAnd(vresult, 1)
, -(bitShiftR(vresult, 1)+1)
, bitShiftR(vresult, 1)
)
vlng <- vlng + dlng
varray <- rbind(varray, c(vlat * 1e-5, vlng * 1e-5))
}
coords <- data.frame(varray)
names(coords) <- c("lat", "lon")
coords
}
route_df <- decodeLine( route_all$routes[[1]]$overview_polyline$points )
# Map using Leaflet R
m = leaflet() %>% addTiles()
m = m %>% addPolylines(route_df$lon, route_df$lat, fill = FALSE)
m = m %>% addPopups(route_df$lon[1], route_df$lat[1], 'Origin')
m = m %>% addPopups(route_df$lon[length(route_df$lon)],
route_df$lat[length(route_df$lon)], 'Destination')
m
And I get this:
For reference, there is another decodeLine
function here written by @diegovalle.