February 18, 2020

R for Driving Directions?

Driving Directions from R

There is no reason that maps with driving directions cannot be produced in R. Given the directions api from Google, it should be doable. As it happens, I was surprised how easy it was. Let me try to map a simple A to B location. First, to the locations; I will specify two. It is possible to geolocate addresses for this also, I happened to have the GPS coordinates in hand.

InNOut <- data.frame(lat = 45.01182, lng=-123.01566, popup = "In-N-Out, Keizer")
WU <- data.frame(lat = 44.9366627941527, lng = -123.030147262156, popup = "Willamette University")

With these coordinates in mind, I need to acquire the directions, and routes based on those directions. The mapsapi package interacts with the various google maps APIs. I have yet to figure out how to effectively hide the key in these API calls so I am copying the code chunk but will work with the data that I obtained from the following code. The first step is to request directions. mp_directions requires an origin and a destination in one of a few forms. You can feed a character string [vector of length 1], a numeric vector of length 2 [lon, lat], a matrix with one row and two columns, same as above, or an sf/sfc point layer with only one feature. While I have not specified them, we can also require waypoints, choose a mode other than the default (driving), and get multiple alternatives or only a single set of directions. Here, I will ask for alternatives.

library(mapsapi)
doc <- mp_directions(
  origin = c(WU$lng,WU$lat),
  destination = c(InNOut$lng,InNOut$lat),
  alternatives = TRUE, key=key, quiet=TRUE)
route <- mp_get_routes(doc)

What does the output of this look like?

load("data/doc.RData")
doc
## $node
## <pointer: (nil)>
## 
## $doc
## <pointer: (nil)>
## 
## attr(,"class")
## [1] "xml_document" "xml_node"

mp_directions returns xml from the Directions API consisting of a status report, the routes, and the beginning and endpoints.

route
##     alternative_id leg_id                      summary distance_m distance_text
## 1-1              1      1   Broadway St and River Rd N       9830        6.1 mi
## 2-1              2      1                   River Rd N      10730        6.7 mi
## 3-1              3      1 Cherry Ave NE and River Rd N       9630        6.0 mi
##     duration_s duration_text duration_in_traffic_s duration_in_traffic_text
## 1-1       1164       19 mins                    NA                       NA
## 2-1       1165       19 mins                    NA                       NA
## 3-1       1167       19 mins                    NA                       NA
##     departure_time arrival_time
## 1-1           <NA>         <NA>
## 2-1           <NA>         <NA>
## 3-1           <NA>         <NA>
##                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 geometry
## 1-1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 -123.02928, -123.02960, -123.02943, -123.02893, -123.02837, -123.02809, -123.02808, -123.02771, -123.02755, -123.02721, -123.02586, -123.02554, -123.02505, -123.02480, -123.02475, -123.02475, -123.02483, -123.02495, -123.02511, -123.02529, -123.02561, -123.02626, -123.02619, -123.02568, -123.02492, -123.02402, -123.02320, -123.02347, -123.02372, -123.02491, -123.03019, -123.03145, -123.03058, -123.02994, -123.02930, -123.02888, -123.02864, -123.02860, -123.02863, -123.02864, -123.02862, -123.02860, -123.02859, -123.02858, -123.02858, -123.02851, -123.02851, -123.02847, -123.02843, -123.02844, -123.02846, -123.02844, -123.02849, -123.02854, -123.02853, -123.02850, -123.02850, -123.02851, -123.02847, -123.02842, -123.02838, -123.02800, -123.02789, -123.02751, -123.02715, -123.02689, -123.02669, -123.02660, -123.02658, -123.02658, -123.02658, -123.02660, -123.02660, -123.02661, -123.02661, -123.02662, -123.02664, -123.02664, -123.02663, -123.02665, -123.02661, -123.02656, -123.02648, -123.02636, -123.02626, -123.02593, -123.02470, -123.02373, -123.02321, -123.02266, -123.02221, -123.02170, -123.02140, -123.02107, -123.02073, -123.02039, -123.02017, -123.01996, -123.01977, -123.01866, -123.01799, -123.01742, -123.01632, -123.01589, -123.01566, 44.93631, 44.93574, 44.93566, 44.93553, 44.93538, 44.93531, 44.93531, 44.93603, 44.93636, 44.93702, 44.93973, 44.94037, 44.94135, 44.94193, 44.94210, 44.94225, 44.94246, 44.94259, 44.94271, 44.94280, 44.94289, 44.94305, 44.94321, 44.94419, 44.94566, 44.94742, 44.94908, 44.94909, 44.94913, 44.94944, 44.95077, 44.95108, 44.95277, 44.95405, 44.95535, 44.95619, 44.95679, 44.95706, 44.95756, 44.95910, 44.96066, 44.96227, 44.96426, 44.96570, 44.96632, 44.96641, 44.96665, 44.96702, 44.96770, 44.96818, 44.96869, 44.96929, 44.97027, 44.97034, 44.97124, 44.97163, 44.97252, 44.97285, 44.97317, 44.97335, 44.97348, 44.97398, 44.97415, 44.97483, 44.97578, 44.97652, 44.97714, 44.97767, 44.97820, 44.97920, 44.98062, 44.98199, 44.98412, 44.98598, 44.98742, 44.99146, 44.99623, 44.99987, 45.00054, 45.00172, 45.00254, 45.00291, 45.00320, 45.00346, 45.00366, 45.00408, 45.00540, 45.00643, 45.00703, 45.00776, 45.00843, 45.00931, 45.00992, 45.01070, 45.01055, 45.01043, 45.01039, 45.01040, 45.01043, 45.01083, 45.01092, 45.01104, 45.01128, 45.01138, 45.01138
## 2-1 -123.02928, -123.02960, -123.02943, -123.02893, -123.02837, -123.02809, -123.02808, -123.02818, -123.02832, -123.02836, -123.02838, -123.02852, -123.02888, -123.02904, -123.03033, -123.03130, -123.03349, -123.03434, -123.03457, -123.03485, -123.03501, -123.03525, -123.03534, -123.03539, -123.03540, -123.03537, -123.03524, -123.03521, -123.03520, -123.03524, -123.03536, -123.03544, -123.03555, -123.03572, -123.03608, -123.04041, -123.04167, -123.04193, -123.04206, -123.04217, -123.04228, -123.04232, -123.04231, -123.04211, -123.04157, -123.04097, -123.04038, -123.03993, -123.03941, -123.03931, -123.03921, -123.03905, -123.03895, -123.03872, -123.03854, -123.03821, -123.03769, -123.03747, -123.03724, -123.03707, -123.03699, -123.03656, -123.03560, -123.03546, -123.03530, -123.03510, -123.03472, -123.03440, -123.03425, -123.03348, -123.03263, -123.03175, -123.03148, -123.03146, -123.03144, -123.03144, -123.03143, -123.03144, -123.03145, -123.03150, -123.03151, -123.03162, -123.03173, -123.03179, -123.03179, -123.03183, -123.03183, -123.03182, -123.03183, -123.03186, -123.03193, -123.03197, -123.03198, -123.03197, -123.03193, -123.03189, -123.03194, -123.03174, -123.03133, -123.03049, -123.03024, -123.02984, -123.02900, -123.02888, -123.02870, -123.02851, -123.02847, -123.02842, -123.02838, -123.02800, -123.02789, -123.02751, -123.02715, -123.02689, -123.02669, -123.02660, -123.02658, -123.02658, -123.02658, -123.02660, -123.02660, -123.02661, -123.02662, -123.02664, -123.02664, -123.02664, -123.02663, -123.02665, -123.02661, -123.02656, -123.02648, -123.02636, -123.02626, -123.02593, -123.02470, -123.02373, -123.02321, -123.02266, -123.02221, -123.02170, -123.02140, -123.02107, -123.02073, -123.02039, -123.02017, -123.01996, -123.01977, -123.01866, -123.01799, -123.01742, -123.01632, -123.01589, -123.01566, 44.93631, 44.93574, 44.93566, 44.93553, 44.93538, 44.93531, 44.93531, 44.93506, 44.93466, 44.93465, 44.93463, 44.93434, 44.93350, 44.93313, 44.93345, 44.93370, 44.93427, 44.93448, 44.93455, 44.93469, 44.93480, 44.93505, 44.93526, 44.93550, 44.93572, 44.93592, 44.93656, 44.93686, 44.93699, 44.93723, 44.93756, 44.93773, 44.93784, 44.93797, 44.93816, 44.93926, 44.93960, 44.93968, 44.93976, 44.93985, 44.94003, 44.94021, 44.94034, 44.94080, 44.94179, 44.94303, 44.94422, 44.94516, 44.94621, 44.94637, 44.94648, 44.94661, 44.94669, 44.94677, 44.94681, 44.94682, 44.94681, 44.94686, 44.94695, 44.94710, 44.94720, 44.94807, 44.95002, 44.95020, 44.95034, 44.95046, 44.95064, 44.95080, 44.95102, 44.95256, 44.95427, 44.95599, 44.95649, 44.95656, 44.95750, 44.95965, 44.96190, 44.96362, 44.96422, 44.96487, 44.96499, 44.96543, 44.96571, 44.96596, 44.96620, 44.96628, 44.96642, 44.96699, 44.96751, 44.96819, 44.96864, 44.96880, 44.96894, 44.96909, 44.96922, 44.96935, 44.96939, 44.96962, 44.97017, 44.97116, 44.97143, 44.97189, 44.97281, 44.97286, 44.97286, 44.97285, 44.97317, 44.97335, 44.97348, 44.97398, 44.97415, 44.97483, 44.97578, 44.97652, 44.97714, 44.97767, 44.97820, 44.97920, 44.98062, 44.98199, 44.98412, 44.98742, 44.99146, 44.99469, 44.99817, 44.99987, 45.00054, 45.00172, 45.00254, 45.00291, 45.00320, 45.00346, 45.00366, 45.00408, 45.00540, 45.00643, 45.00703, 45.00776, 45.00843, 45.00931, 45.00992, 45.01070, 45.01055, 45.01043, 45.01039, 45.01040, 45.01043, 45.01083, 45.01092, 45.01104, 45.01128, 45.01138, 45.01138
## 3-1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   -123.02928, -123.02960, -123.02943, -123.02893, -123.02837, -123.02809, -123.02808, -123.02771, -123.02755, -123.02721, -123.02586, -123.02554, -123.02505, -123.02480, -123.02475, -123.02475, -123.02483, -123.02495, -123.02511, -123.02529, -123.02561, -123.02626, -123.02619, -123.02568, -123.02492, -123.02402, -123.02320, -123.02236, -123.02204, -123.02182, -123.02120, -123.02075, -123.02069, -123.02068, -123.02075, -123.02088, -123.02088, -123.02086, -123.02076, -123.02062, -123.02041, -123.02029, -123.02028, -123.02022, -123.02008, -123.02004, -123.02074, -123.02105, -123.02113, -123.02130, -123.02131, -123.02128, -123.01939, -123.01941, -123.01938, -123.01937, -123.01941, -123.01950, -123.01965, -123.01994, -123.02001, -123.02036, -123.02042, -123.02039, -123.02054, -123.02061, -123.02086, -123.02102, -123.02121, -123.02144, -123.02159, -123.02210, -123.02268, -123.02381, -123.02425, -123.02505, -123.02567, -123.02602, -123.02623, -123.02628, -123.02662, -123.02662, -123.02662, -123.02663, -123.02664, -123.02664, -123.02664, -123.02664, -123.02665, -123.02663, -123.02661, -123.02656, -123.02648, -123.02636, -123.02626, -123.02615, -123.02593, -123.02527, -123.02470, -123.02373, -123.02321, -123.02292, -123.02238, -123.02202, -123.02170, -123.02140, -123.02107, -123.02073, -123.02039, -123.02017, -123.01996, -123.01977, -123.01866, -123.01799, -123.01742, -123.01632, -123.01589, -123.01566, 44.93631, 44.93574, 44.93566, 44.93553, 44.93538, 44.93531, 44.93531, 44.93603, 44.93636, 44.93702, 44.93973, 44.94037, 44.94135, 44.94193, 44.94210, 44.94225, 44.94246, 44.94259, 44.94271, 44.94280, 44.94289, 44.94305, 44.94321, 44.94419, 44.94566, 44.94742, 44.94908, 44.95074, 44.95144, 44.95203, 44.95331, 44.95415, 44.95443, 44.95461, 44.95491, 44.95529, 44.95544, 44.95562, 44.95583, 44.95601, 44.95618, 44.95630, 44.95634, 44.95640, 44.95650, 44.95660, 44.95710, 44.95721, 44.95854, 44.95909, 44.96010, 44.96224, 44.96224, 44.96324, 44.96425, 44.96564, 44.96652, 44.96699, 44.96770, 44.96907, 44.96953, 44.97074, 44.97095, 44.97100, 44.97157, 44.97167, 44.97248, 44.97297, 44.97364, 44.97426, 44.97476, 44.97647, 44.97823, 44.98139, 44.98258, 44.98494, 44.98676, 44.98785, 44.98847, 44.98876, 44.98877, 44.98918, 44.99026, 44.99205, 44.99517, 44.99646, 45.00004, 45.00111, 45.00172, 45.00222, 45.00254, 45.00291, 45.00320, 45.00346, 45.00366, 45.00380, 45.00408, 45.00480, 45.00540, 45.00643, 45.00703, 45.00740, 45.00816, 45.00874, 45.00931, 45.00992, 45.01070, 45.01055, 45.01043, 45.01039, 45.01040, 45.01043, 45.01083, 45.01092, 45.01104, 45.01128, 45.01138, 45.01138

mp_get_route extracts the routes from the directions that we previously obtained as an sf. The routes themselves are LINESTRING geometries. The last setup step involves figuring out how to center the map. This is not completely general as the zoom needs adjustment depending upon the distance between the beginning and endpoints. My solution is to simply average the latitude and longitude.

Mean.Lat <- mean(c(WU$lat,InNOut$lat))
Mean.Lon <- mean(c(WU$lng,InNOut$lng))

Now I have a center to view the map. Let’s build a map using Leaflet. First, call the library. Second, initiate a new Leaflet. Add tiles to it. Define the view using my average coordinates. Add a marker for Willamette and for In-N-Out with popup text. Finally, add the routes.

library(leaflet)
m <- leaflet() %>% 
  addTiles() %>% 
  setView(lat=Mean.Lat,lng=Mean.Lon, zoom = 12) %>% 
  addMarkers(lat=WU$lat, lng=WU$lng, popup = WU$popup) %>% 
  addMarkers(lat=InNOut$lat, lng=InNOut$lng, popup = InNOut$popup) %>%  
  addPolylines(data = route)

What does it look like?

m