R/google_directions.R

Defines functions locationStopMessage validateLocation.default validateLocation.data.frame validateLocation.numeric validateLocation.character validateLocation.list validateLocation google_directions

Documented in google_directions

#' Google Directions
#'
#' The Google Maps Directions API is a service that calculates directions between
#' locations. You can search for directions for several modes of transportation,
#' including transit, driving, walking, or cycling.
#'
#' @param origin Origin location as either a one or two column data.frame, a
#' list of unnamed elements, each element is either a numeric vector of lat/lon
#' coordinates, an address string or a place_id, or a vector of a pair of lat / lon coordinates
#' @param destination destination location as either a one or two column data.frame, a
#' list of unnamed elements, each element is either a numeric vector of lat/lon
#' coordinates, an address string or place_id, or a vector of a pair of lat / lon coordinates
#' @param mode \code{string} One of 'driving', 'walking', 'bicycling' or 'transit'.
#' @param departure_time The desired time of departure.
#' Use either a \code{POSIXct} time since 1st January 1970, or the string 'now'.
#' If no value is specified it defaults to \code{Sys.time()}.
#' @param arrival_time Specifies the desired time of arrival for transit requests.
#' Use either a \code{POSIXct} time since 1st January 1970.
#' Note you can only specify one of \code{arrival_time} or \code{departure_time}, not both.
#' If both are supplied, \code{departure_time} will be used.
#' @param waypoints list of waypoints, expressed as either \code{vectors} of
#' lat/lon coordinates, or a \code{string} address to be geocoded, or an encoded
#' polyline enclosed by \code{enc:} and \code{:}. Only available for driving,
#' walking or bicycling modes. List elements must be named either 'stop' or 'via',
#' where 'stop' is used to indicate a stopover for a waypoint, and 'via' will
#' not stop at the waypoint.
#' See \url{https://developers.google.com/maps/documentation/directions/overview#Waypoints} for details
#' @param optimise_waypoints \code{boolean} allow the Directions service to optimize the
#' provided route by rearranging the waypoints in a more efficient order.
#' (This optimization is an application of the Travelling Salesman Problem.)
#' Travel time is the primary factor which is optimized, but other factors such
#' as distance, number of turns and many more may be taken into account when
#' deciding which route is the most efficient. All waypoints must be stopovers
#' for the Directions service to optimize their route.
#' @param alternatives \code{logical} If set to true, specifies that the Directions
#' service may provide more than one route alternative in the response
#' @param avoid \code{character} vector stating which features should be avoided.
#' One of 'tolls', 'highways', 'ferries' or 'indoor'
#' @param units \code{string} metric or imperial. Note: Only affects the text displayed
#' within the distance field. The values are always in metric
#' @param traffic_model \code{string} - one of 'best_guess', 'pessimistic' or 'optimistic'.
#' Only valid with a departure time
#' @param transit_mode \code{vector} of strings, either 'bus', 'subway', 'train', 'tram' or 'rail'.
#' Only vaid where \code{mode = 'transit'}. Note that 'rail' is equivalent
#' to \code{transit_mode=c("train", "tram", "subway")}
#' @param transit_routing_preference \code{vector} of strings - one of 'less_walking' and
#' 'fewer_transfers'. specifies preferences for transit routes. Only valid for
#' transit directions.
#' @param language \code{string} - specifies the language in which to return the results.
#' See the list of supported languages: \url{https://developers.google.com/maps/faq#languagesupport}.
#' If no langauge is supplied, the service will attempt to use the language of the domain from which the request was sent
#' @param region \code{string} - specifies the region code, specified as a ccTLD
#' ("top-level domain"). See region basing for details
#' \url{https://developers.google.com/maps/documentation/directions/overview#RegionBiasing}
#' @param key \code{string} - a valid Google Developers Directions API key
#' @param simplify \code{logical} - TRUE indicates the returned JSON will be coerced into a list.
#' FALSE indicates the returend JSON will be returned as a string
#' @param curl_proxy a curl proxy object
#' @return Either list or JSON string of the route between origin and destination
#'
#' @inheritSection google_geocode API use and limits
#'
#' @examples
#' \dontrun{
#'
#' set_key("YOUR_GOOGLE_API_KEY")
#'
#' ## using lat/long coordinates
#' google_directions(origin = c(-37.8179746, 144.9668636),
#'           destination = c(-37.81659, 144.9841),
#'           mode = "walking")
#'
#'
#' ## using address string
#' google_directions(origin = "Flinders Street Station, Melbourne",
#'          destination = "MCG, Melbourne",
#'          mode = "walking")
#'
#'
#' google_directions(origin = "Melbourne Airport, Australia",
#'          destination = "Portsea, Melbourne, Australia",
#'          departure_time =  Sys.time() + (24 * 60 * 60),
#'          waypoints = list(stop = c(-37.81659, 144.9841),
#'                            via = "Ringwood, Victoria"),
#'          mode = "driving",
#'          alternatives = FALSE,
#'          avoid = c("TOLLS", "highways"),
#'          units = "imperial",
#'          simplify = TRUE)
#'
#' ## using 'now' as departure time
#' google_directions(origin = "Flinders Street Station, Melbourne",
#'          destination = "MCG, Melbourne",
#'          departure_time = 'now')
#'
#' ## waypoints expressed as an encoded polyline
#' polyWaypoints <- encode_pl(tram_stops[1:2, c("stop_lat")], tram_stops[1:2, c("stop_lon")])
#' polyWaypoints <- list(via = paste0("enc:", polyWaypoints, ":"))
#'
#' google_directions(origin = "Melbourne Zoo, Melbourne",
#'          destination = "Studley Park, Melbourne",
#'          waypoints = polyWaypoints)
#'
#'
#' ## using bus and less walking
#' res <- google_directions(origin = "Melbourne Airport, Australia",
#'          destination = "Portsea, Melbourne, Australia",
#'          departure_time =  Sys.time() + (24 * 60 * 60),
#'          mode = "transit",
#'          transit_mode = "bus",
#'          transit_routing_preference = "less_walking",
#'          simplify = FALSE)
#'
#' ## using arrival time
#' res <- google_directions(origin = "Melbourne Airport, Australia",
#'          destination = "Portsea, Melbourne, Australia",
#'          arrival_time =  Sys.time() + (24 * 60 * 60),
#'          mode = "transit",
#'          transit_mode = "bus",
#'          transit_routing_preference = "less_walking",
#'          simplify = FALSE)
#'
#' ## return results in French
#' res <- google_directions(origin = "Melbourne Airport, Australia",
#'          destination = "Portsea, Melbourne, Australia",
#'          arrival_time =  Sys.time() + (24 * 60 * 60),
#'          mode = "transit",
#'          transit_mode = "bus",
#'          transit_routing_preference = "less_walking",
#'          language = "fr",
#'          simplify = FALSE)
#'
#' }
#' @export
google_directions <- function(origin,
                              destination,
                              mode = c('driving','walking','bicycling','transit'),
                              departure_time = NULL,
                              arrival_time = NULL,
                              waypoints = NULL,
                              optimise_waypoints = FALSE,
                              alternatives = FALSE,
                              avoid = NULL,
                              units = c("metric", "imperial"),
                              traffic_model = NULL,
                              transit_mode = NULL,
                              transit_routing_preference = NULL,
                              language = NULL,
                              region = NULL,
                              key = get_api_key("directions"),
                              simplify = TRUE,
                              curl_proxy = NULL){

  origin <- validateLocation(origin)
  destination <- validateLocation(destination)

  directions_data(base_url = "https://maps.googleapis.com/maps/api/directions/json?",
                information_type = "directions",
                origin,
                destination,
                mode,
                departure_time,
                arrival_time,
                waypoints,
                optimise_waypoints,
                alternatives,
                avoid,
                units,
                traffic_model,
                transit_mode,
                transit_routing_preference,
                language,
                region,
                key,
                simplify,
                curl_proxy)

}


validateLocation <- function(location) UseMethod("validateLocation")

#' @export
validateLocation.list <- function(location){
  if(length(location) > 1)
    stop(locationStopMessage())

  location[[1]]
}


#' @export
validateLocation.character <- function(location) {
  if(length(location) > 1)
    stop(locationStopMessage())
  location
}

#' @export
validateLocation.numeric <- function(location) {
  ## a vector has to be put into a list
  if(length(location) > 2) stop(locationStopMessage())
  location
}

#' @export
validateLocation.data.frame <- function(location){

  ## A dataframe can be used, and can be one column or two
  ##
  if(ncol(location) > 2) stop("A data.frame can have a maximum of two columns")
  if(nrow(location) > 1) stop(locationStopMessage())

  ## two-columns indicate lat/lons
  if(ncol(location) == 2){
    # location <- lapply(1:nrow(location), function(x) as.numeric(location[x, ]))
    return(as.numeric(location))
  }else{
#    location <- lapply(1:nrow(location), function(x) as.character(location[x,]))
    return(as.character(location))
  }
}

#' @export
validateLocation.default <- function(location) location

locationStopMessage <- function() "Only a single location is allowed inside google_directions for origin or destination"

Try the googleway package in your browser

Any scripts or data that you put into this service are public.

googleway documentation built on Aug. 22, 2023, 9:13 a.m.