Giter VIP home page Giter VIP logo

openrouteservice-r's Introduction

R-CMD-check Coverage Status lifecycle

openrouteservice R client

openrouteservice R package provides easy access to the openrouteservice (ORS) API from R. It allows you to painlessly consume the following services:

Disclaimer

By using this package, you agree to the ORS terms and conditions.

Installation

The package is not yet available from CRAN, but you can install the development version directly from GitHub.

# install.packages("remotes")
remotes::install_github("GIScience/openrouteservice-r")

Get started

See the package vignette for an overview of the offered functionality.

Local ORS instance

The default is to fire any requests against the free public services at <api.openrouteservice.org>. In order to query a different openrouteservice instance, say a local one, set

options(openrouteservice.url = "http://localhost:8080/ors")

If necessary, endpoint configuration can be further customized through openrouteservice.paths which specifies a named list of paths. The defaults are equivalent of having

options(openrouteservice.paths = list(directions = "v2/directions",
                                      isochrones = "v2/isochrones",
                                      matrix = "v2/matrix",
                                      geocode = "geocode",
                                      pois = "pois",
                                      elevation = "elevation",
                                      optimization = "optimization"))

Package News

version 0.4.0

NEW FEATURES

  • Enable optimization endpoint.

version 0.3.3

BUG FIXES

  • Fixed resolving of URL paths to endpoints.

version 0.3.2

NEW FEATURES

  • More descriptive messages for API response errors.

openrouteservice-r's People

Contributors

aoles avatar heidiseibold avatar patperu avatar thegreatrefrigerator avatar tyrasd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openrouteservice-r's Issues

Update to ORS v5

Probably not much to do, as you're hardly asking for optional parameters as far as I could see. But at least update the profiles, e.g. cycling-safe doesn't exist anymore.

Assign units to `ors_matrix()` results

Use units for the resulting matrix to facilitate conversion.

library(openrouteservice)
library(units)
#> udunits system database from /Library/Frameworks/R.framework/Versions/3.5/Resources/library/units/share/udunits

coordinates = data.frame(
  lng = c(9.970093, 9.207916, 37.573242, 115.663757),
  lat = c(48.477473, 49.153868, 55.801281, 38.106467)
)

res <- ors_matrix(coordinates, sources = c(0, 2), destinations = c(1, 3))
m <- res$durations

m <- set_units(m, "secs")
m
#> Units: [s]
#>          [,1]     [,2]
#> [1,]  6299.06 400713.4
#> [2,] 89063.38 314298.8

units(m) <- "min"
m
#> Units: [min]
#>           [,1]     [,2]
#> [1,]  104.9843 6678.557
#> [2,] 1484.3897 5238.312

Created on 2019-05-10 by the reprex package (v0.2.1)

Sanitize the interface to `ors_pois()`

Modify the function interface for the sake of usability rather than strictly reflect the API. For example, abandon request argument in favor of binary summary argument, and return the category list if none arguments were provided, i.e.:

  • ors_pois("pois", ...) -> ors_pois(..., summary = FALSE) (the default)
  • ors_pois("stats", ...) -> ors_pois(..., summary = TRUE)
  • ors_pois("list") -> ors_pois()

Additionally, ease-up things by expanding the nested geometry object into separate function arguments.

Think of a more convenient representation of the category list, or a helper function to facilitate specifying filters = list(category_ids = category)) by keywords rather than ids like in the following example.

ors_pois_ids <- function (category, group) {
  pois_list = ors_pois("list")
  
  group_ids = sapply(pois_list, `[[`, 'id')
  
  category_ids = lapply(pois_list, function(x) {
    unlist(unname(x$children))
  })
  category_ids <- do.call(c, unname(category_ids))
  if (missing(category) && missing(group))
    return(list(groups = group_ids, categories = category_ids))

  res <- list()

  if (!missing(category))
    res$category_ids <- I(unname(category_ids[category]))

  if (!missing(group))
    res$category_group_ids <- I(unname(group_ids[group]))

  res
}

ors_pois(geometry = list(geojson = list(type = "Point",
                                        coordinates = c(8.8034, 53.0756)),
                         buffer = 100),
         limit = 200,
         sortby = "distance",
         filters = ors_pois_ids(c("waste_basket", "ship")))

Switch secret storage from keyring to .Renviron

Abandon the notorious keyring package which is causing trouble under certain architectures and deployment environments such as shinyapps.io.

The idea is to store the key as plain environment variable, preferable in .Renviron. In order to ease-up the set-up procedure and to retain previous functionality introduce an intelligent way of updating .Renviron through a call to ors_api_key(<YOUR_API_KEY>). See ?Startup for R startup details.

To remain CRAN compliant, ask for user permission before updating .Renviron (see e.g. rsam).

Calling a locally hosted instance of ors fails

I'm unable to call a locally hosted instance of openrouteservice (created following the instructions here) from openrouteservice-r

I'm setting the endpoint using options("openrouteservice.url"="http://localhost:8080/ors/"). Setting the openrouteservice.verbose option shows that the /ors/ is being stripped from the URLs, so all calls fail.

This is because the call to modify_url() in api_call.R replaces the path element of the URL, and so loses the /ors/. I've fixed this locally by pasting any existing path element of ors_url() to path. I'm unsure whether this is the best approach to fixing it - I'm happy to submit a PR if you think that's an OK way of fixing it.

Improvements to reverse geocoding

Have a separate function for the reverse geocode service such as ors_geocode_reverse and support output of the address in a single string, similarly to revgeo.

Allow raw JSON string as output format fo `api_call`s

Following the suggestion by @SymbolixAU have an option to output unprocessed JSON/GeoJSON string as returned by content(res, "text"). The output format could be set globally through options("openrouteservice.output_format")

ors_endpoint <- function (query_params, ..., output.format = NULL) {
  ...
  api_call("endpoint",  method, query, output.format = output.format)
}

and have in api_call

if ( is.null(output.format) )
  output.format <- getOption("openrouteservice.output_format", "list")

Rate limiting

Subsequent queries might exhaust the rate limit of 40 requests/min, as in the following example. Consider implementing a limiting mechanism.

replicate(100, ors_geocode("Heidelberg"))
## Error: openrouteservice API request failed
##   [429] Rate limit exceeded 

ors_isochrones to sf

Hey I am using your package for my shiny-app and i use this conversion function to convert the ors objects to sf, maybe this is useful and could be implemented in the package (i could also contribute this for the other geom types):

require(sf)

iso2sf = function(obj){
  k = 1
  poly_list = list()
  for (i in obj$features){
    tmp = i
    tmp2 = data.frame(lon = 0, lat = 0)
    n = 1
    for(j in tmp$geometry$coordinates[[1]]){
      tmp2 = rbind(tmp2, c(lon = j[1], lat = j[2]))
      n = n + 1
    }
    interval[k] = tmp$properties$value
    poly_list[[k]] = sf::st_sfc(st_polygon(list(as.matrix(tmp2)[-1,])),  
                             crs = 4326)
    k = k + 1
  }
  
  polys = do.call(c,rev(poly_list))
  p = sf::st_sf(interval = rev(interval) ,geometry =  polys)
  return(p)
}

# test calls
#
# iso <- ors_isochrones(geo_code("Jena"),range =1000 ,interval = 200,range_type = "distance")
# iso2sf(iso)

Unable to complete install

Hello,
I tried to install the package but I get a leaflet error.

platform       i386-w64-mingw32            
arch           i386                        
os             mingw32                     
system         i386, mingw32               
status                                     
major          3                           
minor          5.0                         
year           2018                        
month          04                          
day            23                          
svn rev        74626                       
language       R                           
version.string R version 3.5.0 (2018-04-23)
nickname       Joy in Playing 

Here is the error that I get during the install

Warning: unable to move temporary installation ‘C:\Program Files\R\R-3.5.0\library\file2df872755172\leaflet’ to ‘C:\Program Files\R\R-3.5.0\library\leaflet’

The downloaded binary packages are in
	C:\Users\valexandre\AppData\Local\Temp\RtmpiU3Ope\downloaded_packages
"C:/PROGRA~1/R/R-35~1.0/bin/i386/R" --no-site-file --no-environ  \
  --no-save --no-restore --quiet CMD INSTALL  \
  "C:/Users/valexandre/AppData/Local/Temp/RtmpiU3Ope/devtools2df8aa24fde/GIScience-openrouteservice-r-87a03dd"  \
  --library="C:/Program Files/R/R-3.5.0/library" --install-tests 

ERROR: dependency 'leaflet' is not available for package 'openrouteservice'
* removing 'C:/Program Files/R/R-3.5.0/library/openrouteservice'
In R CMD INSTALL
Installation failed: Command failed (1)

Have you already been reported this error ?
Thanks.

Specify countries by names

Allow providing countries to advanced routing options by names rather than obscure ORS country codes. Maybe countrycode package with ORS country codes added as data source could be levereged for this.

Unit-aware arguments to `ors_isochrones()`

Leverage the units package for assigning units to variables provided to arguments such as ranges or intervals to e.g. ors_isochrones() and for doing the conversion from hours/minutes to the internal representation in seconds. Based on unit type (time vs. distance) appropriate range_type could be chosen, see also measurements.

library(units)
#> udunits system database from /Library/Frameworks/R.framework/Versions/3.5/Resources/library/units/share/udunits

x <- set_units(20, "min")
x
#> 20 [min]

units(x) <- "secs"
x
#> 1200 [s]

library(measurements)
conv_unit_options$duration
#>  [1] "nsec" "usec" "msec" "sec"  "min"  "hr"   "day"  "wk"   "mon"  "yr"  
#> [11] "dec"  "cen"  "mil"  "Ma"

Created on 2019-05-09 by the reprex package (v0.2.1)

Account for different error response formats

API error responses might have different formats, such as:

{
  "error": "Key not authorised"
}
{
  "error": {
    "code": 2001,
    "message": "Parameter 'profile' is missing."
  },
  "info": {
    "engine": {
      "version": "4.5.0",
      "build_date": "2018-03-26T13:41:46Z"
    },
    "timestamp": 1528811534758
  }
}
{
    "code": 4000,
    "message": "Invalid JSON object in request"
}

Add test for this!

submit location via dataframe

I would like to suggest an improvement. How about allowing user to submit a dataframe/matrix rather than a list (as done in the osmdata package for instance)? It would improve usability tremendously...

Thanks,

Alan

Test for broken URLs

Consider automated checking for broken URLs in package documentation such as

  • man pages
  • vignettes
  • README

This functionality could be actually provided in a separate R 📦 and exposed through a function expect_no_broken_links to be used with testthat.

Matrix: Use POST, not GET

GET has limited amount of characters, which is can limit the usability esp for matrix API. Also, did you constrain coordinate input to 6 decimals? Couldn't really decipher that, but didn't look like it. If not, please do that, too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.