Site icon R-bloggers

Making an R Package to use the HERE geocode API

[This article was first published on Stats and things, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

HERE is a product by Nokia, formerly called Nokia maps and before that, Ovi maps. It's the result of the acquisition of NAVTEQ in 2007 combined with Plazes and Metacarta, among others. It has a geocoding API, mapping tiles, routing services, and other things. I'm focused on the geocoding service. Under the “Base” license, you can run 10,000 geocoding requests per day. According to wikipedia, that is the most among the free geocoding services. On top of that, HERE does bulk encoding where you submit a file of things to geocode and it returns a link to download a file of results. This sure beats making thousands of requests one at a time.

I figured coding up a quick function to use this service would be the perfect reason to build my first R package. So, after getting my HERE API keys, I fired up devtools and got started with the R package.

First, I had to install the latest version of devtools and roxygen2

install.packages("devtools", repos="http://cran.rstudio.com/")
install.packages("roxygen2", repos="http://cran.rstudio.com/")
library(devtools)
library(roxygen2)

Next, I chose a directory, and ran the create() function from devtools. This creates a package skeleton that contains the basic structure needed for an R package.

devtools::create("geocodeHERE")

Several files and directories are created after running create(). I moved over to the 'R' directory and created a file called “geocodeHERE_simple.R”. I put my function to use the HERE geocoding API in there. This function was designed to be minimalist and similar to the ggmap geocode() function.

#' Attempt to geocode a string
#'
#' Enter a string and have latitude and longitude returned using the HERE API
#' @param search A string to search
#' @param App_id App_id to use the production HERE API. Get one here... http://developer.here.com/get-started. If left blank, will default to demo key with an unknown usage limit.
#' @param App_code App_code to use the production HERE API. Get one here... http://developer.here.com/get-started. If left blank, will default to demo key with an unknown usage limit.
#' @keywords geocode
#' @export
#' @examples
#' dontrun{
#' geocodeHERE_simple("chicago")
#' geocodeHERE_simple("wrigley field chicago IL")
#' geocodeHERE_simple("233 S Wacker Dr, Chicago, IL 60606")
#' }
#' geocodeHERE_simple
geocodeHERE_simple <- function(search, App_id="", App_code=""){
  if(!is.character(search)){stop("'search' must be a character string")}
  if(!is.character(App_id)){stop("'App_id' must be a character string")}
  if(!is.character(App_code)){stop("'App_code' must be a character string")}

  if(App_id=="" & App_code==""){
    App_id <- "DemoAppId01082013GAL"
    App_code <- "AJKnXv84fjrb0KIHawS0Tg"
    base_url <- "http://geocoder.cit.api.here.com/6.2/geocode."
  }else{
    base_url <- "http://geocoder.api.here.com/6.2/geocode."
  }

  search <- RCurl::curlEscape(search)

  final_url <- paste0(base_url, format, "?app_id=", ids$App_id, "&app_code=",
                      ids$App_code, "&searchtext=", search)

  response <- RCurl::getURL(final_url)
  response_parsed <- RJSONIO::fromJSON(response)
  if(length(response_parsed$Response$View) > 0){
    ret <- response_parsed$Response$View[[1]]$Result[[1]]$Location$DisplayPosition
  }else{
    ret <- NA
  }
  return(ret)
}

Note the text on the top of the code. That is added in order to automatically create help documentation for the function.

Now, if you look closely, I am using two other packages in that function… RCurl and RJSONIO. Also, notice that I'm not making any library() calls. This must be done in the DESCRIPTION file that is automatically generated by create(). In addition to calling out what packages to import, you input the package name, author, description, etc.

Package: geocodeHERE
Title: Wrapper for the HERE geocoding API
Version: 0.1
Authors@R: "Cory Nissen <corynissen@gmail.com> [aut, cre]"
Description: Wrapper for the HERE geocoding API
Depends:
    R (>= 3.1.1)
License: MIT
LazyData: true
Imports:
    RJSONIO,
    RCurl

Then, I set my working directory to the package root and ran the document() function from devtools that automatically creates package documentation.

setwd("geocodeHERE")
document()

From this point, you can upload your package to github and use install_github(), or use the install() function to install your package locally.

setwd("..")
install()

As far as the HERE geocoding API goes, I find it pretty decent at doing “fuzzy matching”. That is, given a place name instead of an address, it does a good job of correctly returning the coordinates. The downside is that you must register for an API key, where Google does not require registration to use it's geocoding service. But, you only get 2500 requests per day via Google, HERE offers 10,000 per day.

Any how, a big shout out to Hilary Parker for her blog post on creating an R package using devtools, Hadley Wickham for the devtools package (among others), and RStudio for the fantastic and free (and open source) IDE for R.

The geocodeHERE package is available on github. I'll be adding bulk geocoding functionality as time permits. You can install the package with the following code:

devtools::install_github("corynissen/geocodeHERE")

To leave a comment for the author, please follow the link and comment on their blog: Stats and things.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.