Skip to content

Instantly share code, notes, and snippets.

@tbuckl
Forked from josecarlosgonz/GoogleMapsAndR.md
Last active August 29, 2015 14:17
Show Gist options
  • Save tbuckl/6a40ae347a94f9559f65 to your computer and use it in GitHub Desktop.
Save tbuckl/6a40ae347a94f9559f65 to your computer and use it in GitHub Desktop.

Travel Time and Distance with Google Maps API (and a CSV)

You're probably better off just using this: the python library used there seems to handle errors better https://gist.github.com/buckleytom/0ecfbbb546913c7d9814

However, if you really want to:

This script uses RCurl and RJSONIO to download data from Google's API to get the travel time and distance between latitudes and longitudes by mode, based on some data in a csv

library(RCurl)
library(RJSONIO)
library(plyr)
library(hash)

Build a URL to access the API:

url <- function(orig_y,orig_x,dest_y,dest_x, mode, return.call = "json", alternatives="false") {
  root <- "http://maps.googleapis.com/maps/api/directions/"
  origin <- paste(orig_y,orig_x,sep=",")
  destination <- paste(dest_y,dest_x,sep=",")
  mode <- mode_map[[mode]]
  u <- paste(root, return.call, "?origin=", origin, "&destination=", destination, "&mode=", mode, sep = "")
  return(URLencode(u))
}

Function to parse the results:

findroute <- function(orig_y,orig_x,dest_y,dest_x,mode,verbose=FALSE) {
  u <- url(orig_y,orig_x,dest_y,dest_x,mode)
  doc <- getURL(u)
  #save raw results to file (optional)
  #  write(doc, file = "routedata",
  #    append = TRUE)
  x <- fromJSON(doc,simplify = FALSE)
  if(x$status=="OK") {
    duration <- x$routes[[1]]$legs[[1]]$duration$value
    distance <- x$routes[[1]]$legs[[1]]$distance$value
    Sys.sleep(5)
    #units are meters and seconds
    return(c(duration,distance))
  } else {
    return(c(NA,NA,NA, NA))
  }
}

Load data from a spreadsheet and map user transit defined values to google maps allowed types (configure as needed)

tripdata <- read.csv("~/tripdata.csv")
v1 <- as.character(unique(tripdata["mode"])[[1]])
v2 <- c("driving","driving","driving","walking","biking","driving","driving")
mode_map <- hash(keys=v1, values=v2)

function to get results based on the spreadsheet capped at the api limit (configurable)

gettimedistance <- function(tripdata,apilimit=2500) {
  selectd <- tripdata[1:apilimit,]
  timedist <- apply(selectd, 1,
    function(y)
    tryCatch(splat(findroute)(
    y[c('orig_y','orig_x','dest_y','dest_x','mode')]),error=function(e) c(NA,NA))) #orig_y = origin latitude in our spreadsheet
  return(cbind(selectd,t(timedist)))
}

Return results, with original columns, as data frame, with 2 new columns

result <- gettimedistance(tripdata,1)

Name the new columns

names(result)[12] <- "distance(m)"
names(result)[13] <- "time(s)"

Write the data frame to a csv

write.csv(result, file = "tripdata_google.csv")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment