Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggmap route finding - doesn't stay on roads

Tags:

r

ggmap

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(origin, destination, structure = "route") code is missing? Or is there an alternative function that can be used to accomplish this?

Sample code:

install_github("rstudio/leaflet")
library(ggmap)
library(leaflet)
way1txt <- "Tinsletown, Vancouver, BC"
way2txt <- "Science World, Vancouver, BC"
route_df <- route(way1txt, way2txt, structure = "route")

# 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

Screenshot of map:

Screenshot of map with wrong route

like image 804
cnmillar Avatar asked May 15 '15 23:05

cnmillar


People also ask

Why does Google Maps stop showing routes while navigating?

One such time is when it stops showing the route while navigating. 1. Check Mobile Data Google Maps requires a stable and constant internet connection to work properly. Therefore unless you’re not using offline maps, make sure that your phone’s internet is working properly.

How to fix Google Maps Navigation not working?

In the Privacy menu, click on the Location services option. Step 2: Now tap on Maps from the list and turn on the ‘Precise Location’ option if it isn’t already. Again, open the Google Maps app and try navigation to see if the issue is resolved.

How do I change the fastest route on Google Maps?

If you ask for Directions on the Google Maps app you might be presented with more than one route, Google would select the fastest one and there is no way to change that.

Can you drag the map to move the route?

Except for rare or random occasions, dragging will move the entire map, not the route. Our automated system analyzes replies to choose the one that's most likely to answer the question. If it seems to be helpful, we may eventually mark it as a Recommended Answer. Helpful?


2 Answers

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:

enter image description here

For reference, there is another decodeLine function here written by @diegovalle.

like image 134
akhmed Avatar answered Oct 12 '22 11:10

akhmed


You can use my googleway package

  • get the directions
  • decode the polyline (if required)
  • plot the route on a Google Map, either as an encoded polyline, or the decoded points

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")

enter image description here

Note

  • It looks like the origin doesn't exist or has moved since the question was asked
like image 42
SymbolixAU Avatar answered Oct 12 '22 09:10

SymbolixAU