ggmap route finding - doesn't stay on roads

帅比萌擦擦* 提交于 2019-12-03 10:20:07

问题


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:


回答1:


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.




回答2:


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

Note

  • It looks like the origin doesn't exist or has moved since the question was asked


来源:https://stackoverflow.com/questions/30270011/ggmap-route-finding-doesnt-stay-on-roads

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!