Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting driving distance between two points (lat, lon) using R and Google Map API

I am trying to get the driving distance between two points with lat/lon given. I can manually put them into google map and get the driving distance but I want to do all this programatically.

I guess JavaScript is the language to go. But, I do not know JavaScript and I am fairly familiar using R. I would prefer to do it in R since I am doing all the data analysis in R.

I am looking for distance along the road not crow-fly distance. After few hours of trying, I wrote the following function in R (This and this one helped). Do you have any better way to get the distance either within this function or anything very very simpler?

library(XML)
latlon2ft <- function(origin,destination)
{

xml.url <- paste0('http://maps.googleapis.com/maps/api/distancematrix/xml?origins=',origin,'&destinations=',destination,'&mode=driving&sensor=false')

xmlfile <- xmlTreeParse(xml.url)
xmltop = xmlRoot(xmlfile)
distance <- xmltop[['row']][[1]][5][1][['distance']][['value']][[1]]
distance <- as.numeric(unclass(distance)[['value']])
ft <- distance*3.28084 # FROM METER TO FEET
return(ft)
}

latlon2ft(origin='37.193489,-121.07395',destination='37.151616,-121.046586')

RESULT = 17224.41

like image 915
Stat-R Avatar asked May 31 '13 17:05

Stat-R


People also ask

Can Google Maps API calculate distance between two points?

What can you do with the Distance Matrix API? The API returns information based on the recommended route between start and end points. You can request distance data for different travel modes, request distance data in different units such kilometers or miles, and estimate travel time in traffic.

How do you find the distance between two latitude longitude points in Google Sheets?

To give you a quick example, if you have the starting address in column A and the destination address in column B, a formula like =GOOGLEMAPS_DISTANCE(A1, B1, "driving") will quickly calculate the distance between the two points.

How do you find the distance between two latitude points?

If you treat the Earth as a sphere with a circumference of 25,000 miles, then one degree of latitude is 25,000/360 = 69.44 miles. A minute is thus 69.44/60 = 1.157 miles, and a second is 1.15/60 = 0.0193 miles, or about 101 feet.


4 Answers

I authored the gmapsdistance package to do just that. It is available on CRAN. You can use the function in the following way:

results = gmapsdistance(origin = "38.1621328+24.0029257",
                        destination = "37.9908372+23.7383394",
                        mode = "walking") results
# $Time
# [1] 30025
# 
# $Distance
# [1] 39507
# 
# $Status
# [1] "OK"

You can also include vectors of origins and destinations, and get the resulting distance matrix. It supports also directions, and has a bunch of options:

results = gmapsdistance(origin = c("Washington+DC", "New+York+NY", "Seattle+WA", "Miami+FL"), 
                        destination = c("Los+Angeles+CA", "Austin+TX", "Chicago+IL", "Philadelphia+PA"), 
                        mode = "bicycling", 
                        departure = 1514742000)
results
# $Time
#              or Time.Los+Angeles+CA Time.Austin+TX Time.Chicago+IL Time.Philadelphia+PA
# 1 Washington+DC              856621         535146          247765                54430
# 2   New+York+NY              917486         596011          308630                32215
# 3    Seattle+WA              374692         678959          674989               956702
# 4      Miami+FL              829039         416667          452035               411283
# 
# $Distance
#              or Distance.Los+Angeles+CA Distance.Austin+TX Distance.Chicago+IL Distance.Philadelphia+PA
# 1 Washington+DC                 4567470            2838519             1303067                   266508
# 2   New+York+NY                 4855086            3126136             1590684                   160917
# 3    Seattle+WA                 1982354            3562970             3588297                  5051951
# 4      Miami+FL                 4559205            2279966             2381610                  2169382
# 
# $Status
#              or status.Los+Angeles+CA status.Austin+TX status.Chicago+IL status.Philadelphia+PA
# 1 Washington+DC                    OK               OK                OK                     OK
# 2   New+York+NY                    OK               OK                OK                     OK
# 3    Seattle+WA                    OK               OK                OK                     OK
# 4      Miami+FL                    OK               OK                OK                     OK
like image 67
rodazuero Avatar answered Oct 07 '22 19:10

rodazuero


You need RCurl or an equivalent here.

library(XML)
library(bitops)
library(RCurl)
latlon2ft <- function(origin,destination){
  xml.url <- paste0('http://maps.googleapis.com/maps/api/distancematrix/xml?origins=',origin,'&destinations=',destination,'&mode=driving&sensor=false')
  xmlfile <- xmlParse(getURL(xml.url))
  dist <- xmlValue(xmlChildren(xpathApply(xmlfile,"//distance")[[1]])$value)
  distance <- as.numeric(sub(" km","",dist))
  ft <- distance*3.28084 # FROM METER TO FEET
  return(ft)
}

latlon2ft(origin='37.193489,-121.07395',destination='37.151616,-121.046586')

Result:

[1] 17224.41
like image 30
Thomas Avatar answered Oct 07 '22 21:10

Thomas


I needed to calculate driving distances for a bunch of addresses, so I wrote a short function for it and put it in a likewise small packet. You can find it in my GitHub repo: https://github.com/JanMultmeier/GeoData/blob/master/GeoDataPackage/R/GetDist.R

This should get it to run:

require(devtools)
install_github("JanMultmeier/GeoData/GeoDataPackage")
library(GeoData)
getDist(from="1 Infinity Loop, Cupertino, CA 95014", to="1600 Amphitheatre Pkwy, Mountain View, CA 94043",modus="driving",get="distance")

It should return 14.8 km.

Barryhunter has already hinted at the usage restriction by Google, which ties the use of this API to displaying the results on a Google map.

Hope that still helps some people who stumble across this post (like me)...

like image 38
Jan Multmeier Avatar answered Oct 07 '22 21:10

Jan Multmeier


I've written the googleway package to do this using Google Maps API

In particular, the google_directions() function will give you driving distances, directions, routes, legs, steps etc. And the google_distance() function will give you a distance matrix for all the origins/destinations

You need a Google API key to use their API

library(googleway)

## your valid API key
key <- "your_api_key_here"

directions <- google_directions(origin = c(37.193489,-121.07395),
                                destination = c(37.151616,-121.046586),
                                key = key, 
                                simplify = T)

directions$routes$legs
# [[1]]
# distance.text distance.value duration.text duration.value duration_in_traffic.text duration_in_traffic.value                 end_address
# 1        5.2 km           5250        3 mins            161                   3 mins                       156 I-5, Gustine, CA 95322, USA
# end_location.lat end_location.lng               start_address start_location.lat start_location.lng
# 1         37.15162        -121.0466 I-5, Gustine, CA 95322, USA           37.19349           -121.074
# steps
# 1 5.2 km, 5250, 3 mins, 161, 37.1516163, -121.0465852, Head <b>southeast</b> on <b>I-5 S</b>, ij_bFfg~aVpBgA`DkB~FeDbIwEpEgCtaAsj@nAs@lDqBxIaF~FgDlHcEjC{AdFuCrBkAhC{A|A{@|A}@bAk@rBkArBkA|A{@`DiB|A}@vDwBdAm@dAm@rBkA|A{@zA{@~J{FpC_B~A}@tBkAjHeEvGuDlMmHtBkAVO, 37.1934864, -121.0739565, DRIVING
#   traffic_speed_entry via_waypoint
#   1                NULL         NULL



google_distance(origins = list(c(37.193489,-121.07395)),
                destinations = list(c(37.151616,-121.046586)),
                key = key, 
                simplify = T,
                units = "imperial")

# $destination_addresses
# [1] "I-5, Gustine, CA 95322, USA"
# 
# $origin_addresses
# [1] "I-5, Gustine, CA 95322, USA"
# 
# $rows
# elements
# 1 3.3 mi, 5250, 3 mins, 161, 3 mins, 157, OK
# 
# $status
# [1] "OK"

Given the google_directions() function returns a polyline (the line you get on Google Maps when you search for a route), we can plot it on a Google Map

key <- 'your_map_api_key'

df_route <- decode_pl(directions$routes$overview_polyline$points)

google_map(data = df_route, key = key, height = 800, search_box = T) %>%
    add_markers()
## or you can use `add_polyline()` to view the entire line

enter image description here

like image 27
SymbolixAU Avatar answered Oct 07 '22 20:10

SymbolixAU