library(tidyverse)
library(ggmap)
library(gmapsdistance)
library(knitr)

Introduction

There are so many incredible ways to leverage the open source tools we have at our fingertips in the R universe. In my opinion, one of the best applications is finding opportunities to build efficiency or gain insights from free-open source data sets. We do this a lot in our Program Evaluation program because data scientists in the public and non-profit sectors are often left without sufficient resources or time to tackle data-driven questions at scale in an enterprise solution.

Google is a great partner to the open source community and often provides limited access to their data to small-time developers like us for free.

Because we spent so much time in this course analyzing and talking about spatial data, I think leveraging the Google Maps API to show you some new and exciting ways to look at geographical data is an excellent way to wrap up the semester.

Getting started with the Maps API

The ggmap package provides users with a quick and easy way to leverage a Google Maps API key to access a plethora of data directly from Maps. There are a few steps that you’ll need to do outside of the RStudio IDE before you are able to start working with the data.

Get Your API Key

  1. Go to https://developers.google.com/maps

  2. Select “Get Started”

  3. Ensure you are logged into your personal Google account

  4. Select “Keys and Credentials”

  5. Follow the steps to create a personal project

  6. Copy the generated API key

Set up your script

The syntax below provides an example of the code you need to set up your API key. The actual code with my personal API key for this project has been suppressed.

Make sure the ggmap and gmapsdistance packages have been loaded.

register_google("Paste API Key Here") #for the ggmap package

set.api.key("Paste API Key Here") #for the gmapsdistance package

Start Making Calls

Once you have your API key loaded, you can start making calls to the API!

Let’s start by simply getting a map of Tempe, AZ.

Tempe_Map <- get_map("Tempe", source="google", api_key = apiKey, zoom=12)

ggmap(Tempe_Map)

Now let’s adjust the zoom parameter of the function to get a closer look at the city:

Tempe_Map_Zoom <- get_map("Tempe", source="google", api_key = apiKey, zoom=15)

ggmap(Tempe_Map_Zoom)

Notice how the API is user-friendly enough to accept text inputs and translate them to geographic outputs. There may be instances in which you are using another package or have a different application that requires getting actual longitude and latitude coordinates.

The ggmap package can help you with that too.

geocode("Arizona State University Tempe")
## # A tibble: 1 × 2
##     lon   lat
##   <dbl> <dbl>
## 1 -112.  33.4

Great! Now we know how to get maps directly from Google Maps via their API. The get_map function in the ggmap package has a variety of parameters that you can tweak to get exactly the map you would like, but due to the limitations of free API calls in Maps Developer I won’t demonstrate them here.

For more information when you start working on this on your own, check out the ggmap package or more specifically the get_map function documentation online.

Overlaying data points on a map

The maps API will also allow us to overlay data on the map.

Let’s create a table of major landmarks in Tempe place them as an overlay on the map:

  1. Create the data frame with latitudes and longitudes using an API call
locations <- geocode(c("Hayden Library Tempe", "Tempe Public Library", "Tempe Arizona MVD", "Kiwanis Park", "A Mountain Tempe"))


#manually add in location labels and landmark types 

locations <- locations %>%
  mutate(Labels = c("Hayden Library Tempe", "Tempe Public Library", "Tempe Arizona MVD", "Kiwanis Park", "A Mountain Tempe"),
         Type = c("Library", "Library", "Government Building", "Public Space", "Public Space"))

#save the resulting table as a data frame for compatibility

locationsDF <- as.data.frame(locations)
  1. Use our original map of Tempe and leverage grammar of graphics (ggplot2) conventions to layer in the points of interest onto the map. This time, we will specify the type of map we want to make the visualization more legible. We will make each space type it’s own color so they are easily distinguishable.
Tempe_Map_Landmarks <- ggmap(Tempe_Map)

Tempe_Map_Landmarks + 
  geom_point(data=locationsDF, aes(color = Type), size=3) +
  geom_text(data=locationsDF, aes(label=Labels), size=2.5)

Note that this map is a little busy, so we can also adjust the style of the map to satellite, which should do a better job highlighting where each landmark is:

Tempe_Map_Sat <- get_map("Tempe", source="google", api_key = apiKey, zoom=12, maptype = "satellite")


Tempe_Map_Landmarks_Sat <- ggmap(Tempe_Map_Sat)

Tempe_Map_Landmarks_Sat + 
  geom_point(data=locationsDF, aes(color = Type), size=3) +
  geom_text(data=locationsDF, aes(label=Labels), size=2.5, color="white")

Calcuating Driving Distances and Times

A last application that I find exciting and scalable is getting driving distances and times between two points using gmapsdistance. This might be especially useful in some logistics applications where planning for driving distance and time is critical to business operations.

For this example, we will calculate the driving distances and times between ASU campuses.

First, we create two vectors with origins and destinations.

origins <- c("Arizona State University Tempe", "Arizona State University West", "Arizona State University Polytechnic", "Arizona State University Yuma", "Arizona State University Lake Havasu")

destinations <- c("Arizona State University Tempe", "Arizona State University West", "Arizona State University Polytechnic", "Arizona State University Yuma", "Arizona State University Lake Havasu")

Next, we call gmapsdistance and specify origin, destination, and the mode of transportation.

distances <- gmapsdistance(origin = origins,
                        destination = destinations,
                        mode = "driving")

A list object is generated with statuses, driving times, and driving distances. Below you can see the results from the Time and Distance tables, which are originally output in meters and seconds for units. For legibility, I converted these to minutes and miles.

kable(distances$Time/60, format="html", caption = "Driving Times Between ASU Campuses (Minutes)") %>% kableExtra::column_spec(1, bold = TRUE) 
Driving Times Between ASU Campuses (Minutes)
Arizona State University Tempe Arizona State University West Arizona State University Polytechnic Arizona State University Yuma Arizona State University Lake Havasu
Arizona State University Tempe 0.00000 29.70000 29.11667 175.9167 198.4500
Arizona State University West 29.01667 0.00000 51.13333 174.7333 197.2500
Arizona State University Polytechnic 29.68333 51.28333 0.00000 182.6000 220.2333
Arizona State University Yuma 176.98333 175.51667 183.83333 0.0000 161.4833
Arizona State University Lake Havasu 199.08333 197.61667 219.80000 162.2500 0.0000
kable(distances$Distance/1609.34, format="html", caption = "Driving Distances Between ASU Campuses (Miles)") %>% kableExtra::column_spec(1, bold = TRUE) 
Driving Distances Between ASU Campuses (Miles)
Arizona State University Tempe Arizona State University West Arizona State University Polytechnic Arizona State University Yuma Arizona State University Lake Havasu
Arizona State University Tempe 0.00000 24.47028 25.72980 193.9460 202.6154
Arizona State University West 24.94812 0.00000 48.69636 188.0622 196.7322
Arizona State University Polytechnic 27.41994 49.86578 0.00000 191.8985 226.2623
Arizona State University Yuma 193.46751 187.55888 192.67153 0.0000 155.5402
Arizona State University Lake Havasu 202.80550 196.89686 226.23995 155.5638 0.0000


This application is just a small sample of the power and scalability of the Google Maps API. Even with a free account, it gives users the opportunity to access lots of spacial and geographic information with ease and turn it into actionable insights.

Imagine now applying this at scale paired with consumer data to determine the most optimal placement of a new business or the best routes for truck drivers delivering goods. The possibilities are endless, though at scale a paid account with Google is going to be required.

Conclusion

There are obviously endless applications that we can leverage with such a powerful and user-friendly API. Imagine, with unlimited API calls, how seamless it would be to build a data set with longitude and latitude coordinates of thousands of locations of interest, and pairing that with data for visualization and deeper analysis including census data, consumer data, or logistics data. Just remember, for our purposes with a free account API calls are strictly limited by the system.

This code through is not designed to cover any of this in depth, but my hope is that it will give you a basic set of tools to leverage the free, limited, yet quite powerful Google Maps API. Paired with your R coding skills, it gives you another tool in your belt to obtain, manipulate, and analyze spatial data.

References

D. Kahle and H. Wickham. ggmap: Spatial Visualization with ggplot2. The R Journal, 5(1), 144-161. URL http://journal.r-project.org/archive/2013-1/kahle-wickham.pdf