R/route-transport-api.R

Defines functions route_transportapi_public

Documented in route_transportapi_public

#' Plan a single route with TransportAPI.com
#'
#' Provides an R interface to the TransportAPI.com public transport API.
#' The function returns a SpatialLinesDataFrame object representing the
#' public route.
#' Currently only works for the United Kingdom.
#' See \url{https://developer.transportapi.com/documentation}for more information.
#'
#' @param from Text string or coordinates (a numeric vector of
#'  \code{length = 2} representing latitude and longitude) representing a point
#'  on Earth.
#'
#' @param to Text string or coordinates (a numeric vector of
#'  \code{length = 2} representing latitude and longitude) representing a point
#'  on Earth. This represents the destination of the trip.
#'
#' @param silent Logical (default is FALSE). TRUE hides request sent.
#' @param region String for the active region to use for journey plans.
#' Possible values are 'southeast' (default) or 'tfl'.
#' @param modes Vector of character strings containing modes to use. Default is
#' to use all modes.
#' @param not_modes Vector of character strings containing modes not to use.
#' Not used if \code{modes} is set.
#'
#' @details
#'
#' This function uses the online routing service
#' TransportAPI.com to find public routes
#' between origins and destinations. It does not require
#' any key to access the API.
#'
#' Note that if \code{from} and \code{to} are supplied as
#' character strings (instead of lon/lat pairs), Google's
#' geo-coding services are used via \code{geo_code}.
#'
#' @inheritParams line2route
#' @export
#' @seealso line2route
#' @examples
#'
#' \dontrun{
#' # Plan the 'public' route from Hereford to Leeds
#' rqh <- route_transportapi_public(from = "Hereford", to = "Leeds")
#' plot(rq_hfd)
#' }
#'
# Aim plan public transport routes with transportAPI

route_transportapi_public <- function(from, to, silent = FALSE,
                                      region = 'southeast', modes = NA, not_modes = NA){

  # Convert sp object to lat/lon vector
  if(class(from) == "SpatialPoints" | class(from) == "SpatialPointsDataFrame" )
    from <- coordinates(from)
  if(class(to) == "SpatialPoints" | class(to) == "SpatialPointsDataFrame" )
    to <- coordinates(to)

  # Convert character strings to lon/lat if needs be
  if(is.character(from))
    from <- geo_code(from)
  if(is.character(to))
    to <- geo_code(to)

  orig <- paste0(from, collapse = ",")
  dest <- paste0(to, collapse = ",")

  api_base = "http://fcc.transportapi.com"
  ft_string <- paste0("/from/lonlat:", orig, "/to/lonlat:", dest)

  queryattrs <- list(region = region)
  if (is.na(modes) == FALSE) {
    queryattrs[['modes']] = paste0(modes, collapse = "-")
  } else {
    if (is.na(not_modes) == FALSE) {
      queryattrs[['not_modes']] = paste0(not_modes, collapse = "-")
    }
  }

  httrreq <- httr::GET(
    url = api_base,
    path = paste0("/v3/uk/public/journey",ft_string, ".json"),
    query = queryattrs
  )

  if (silent == FALSE) {
    print(paste0("The request sent to transportapi was: ", httrreq$request$url))
  }

  if (grepl('application/json',httrreq$headers$`content-type`) == FALSE &
      grepl('js',httrreq$headers$`content-type`) == FALSE) {
    stop("Error: Transportapi did not return a valid result")
  }

  txt <- httr::content(httrreq, as = "text", encoding = "UTF-8")

  if (txt == "") {
    stop("Error: Transportapi did not return a valid result")
  }

  obj <- jsonlite::fromJSON(txt)

  coords <- obj$routes$route_parts[[1]]$coordinates
  coords <- do.call(rbind, coords)
  route <- sp::SpatialLines(list(sp::Lines(list(sp::Line(coords)), ID = 1)))
  proj4string(route) <- sp::CRS("+init=epsg:4326")

  # for the future: add summary data on the route
  route
}

Try the stplanr package in your browser

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

stplanr documentation built on June 3, 2018, 1:04 a.m.