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.
我试着用给定的lat/lon来计算两点之间的行驶距离。我可以手动将它们放入谷歌地图中,并得到行驶距离,但我想以编程的方式完成所有这些。
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.
我想JavaScript是要去的语言。但是,我不知道JavaScript,我对使用R很熟悉,我更喜欢用R来做,因为我用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?
我在路上寻找的是距离而不是拥挤的距离。经过几个小时的尝试,我用R(这个和这个)写了下面的函数。你有没有更好的方法来求这个函数内的距离或者更简单的方法?
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
结果= 17224.41
5 个解决方案
#1
7
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
#2
3
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
我需要计算一串地址的行驶距离,因此我为它写了一个简短的函数,并把它放在一个同样小的包中。您可以在我的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.
它应该返回14.8公里。
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.
Barryhunter已经暗示了谷歌的使用限制,它将此API的使用与在谷歌映射上显示结果联系起来。
Hope that still helps some people who stumble across this post (like me)...
希望这仍能帮助那些偶然发现这篇文章的人(比如我)……
#3
3
I authored the gmapsdistance
package to do just that. It is available on CRAN. You can use the function in the following way:
我编写了gmapsdistance包来做到这一点。在CRAN上可以买到。你可以用以下方法使用这个函数:
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
#4
1
I've written the googleway
package to do this using Google Maps API
我用谷歌Maps API编写了Google way包来实现这一点
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
特别地,google_directions()函数将为您提供驾驶距离、方向、路线、腿、步骤等,而google_distance()函数将为您提供所有起点/目的地的距离矩阵
You need a Google API key to use their API
您需要一个谷歌API密钥来使用它们的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
给定google_directions()函数返回一条折线(当你搜索路线时,你在谷歌地图上得到的那条线),我们可以在谷歌地图上画出来。
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
#5
0
At time of writing, Renjin (a Java-based R interpreter) does not have a lot of packages to help solve this problem. Here is an implementation that does not depend on extra packages.
在编写本文时,Renjin(一个基于java的R解释器)没有很多包来帮助解决这个问题。这是一个不依赖于额外包的实现。
# Computes the distance between two locations in meters. This uses an online
# map API and therefore an Internet connection is required for an accurate
# result. If no connection is found, this will use the Haversine formula
# to provide a rough estimate for the distance.
#
# @param src The source latitude and longitude.
# @param dst The destination latitude and longitude.
# @param mode Driving, cycling, walking, etc.
distance <- function( lat1, lon1, lat2, lon2, mode = 'driving' ) {
lat1 = as.numeric( lat1 )
lon1 = as.numeric( lon1 )
lat2 = as.numeric( lat2 )
lon2 = as.numeric( lon2 )
# Create the URL to use to get the distance data.
url = paste0(
'https://maps.googleapis.com/maps/api/distancematrix/xml?',
'origins=', lat1,
',', lon1,
'&destinations=', lat2,
',', lon2,
'&mode=', mode,
'&sensor=false'
)
tryCatch({
# Download the XML document with distance information.
xml = readLines( url )
# The <value> element immediately follows the distance element.
value = xml[ grep( "<distance>", xml ) + 1 ]
# Obtain the distance in meters.
meters = sub( ".*>(.*?)<.*", "\\1", value )
# Return the distance.
as.numeric( meters )
},
warning = function( w ) {
haversine( lat1, lon1, lat2, lon2 )
},
error = function( e ) {
haversine( lat1, lon1, lat2, lon2 )
})
}
# Computes distance using Haversine formula.
#
# Returns the result in meters.
haversine <- function( lat1, lon1, lat2, lon2, radius = 6371 ) {
# Convert decimal degrees to radians
lon1 = lon1 * pi / 180
lon2 = lon2 * pi / 180
lat1 = lat1 * pi / 180
lat2 = lat2 * pi / 180
# Haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
return( radius * c * 1000 )
}
Output:
输出:
distance( '44.5646', '-123.2620', '41.2861', '-124.0902' )
[1] 495892
distance( 44.5646, -123.2620, 41.2861, -124.0902, mode='walking' )
[1] 487715
Conversion from meters to feet is an exercise for the reader.
从米到脚的转换对于读者来说是一个练习。
#1
7
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
#2
3
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
我需要计算一串地址的行驶距离,因此我为它写了一个简短的函数,并把它放在一个同样小的包中。您可以在我的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.
它应该返回14.8公里。
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.
Barryhunter已经暗示了谷歌的使用限制,它将此API的使用与在谷歌映射上显示结果联系起来。
Hope that still helps some people who stumble across this post (like me)...
希望这仍能帮助那些偶然发现这篇文章的人(比如我)……
#3
3
I authored the gmapsdistance
package to do just that. It is available on CRAN. You can use the function in the following way:
我编写了gmapsdistance包来做到这一点。在CRAN上可以买到。你可以用以下方法使用这个函数:
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
#4
1
I've written the googleway
package to do this using Google Maps API
我用谷歌Maps API编写了Google way包来实现这一点
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
特别地,google_directions()函数将为您提供驾驶距离、方向、路线、腿、步骤等,而google_distance()函数将为您提供所有起点/目的地的距离矩阵
You need a Google API key to use their API
您需要一个谷歌API密钥来使用它们的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
给定google_directions()函数返回一条折线(当你搜索路线时,你在谷歌地图上得到的那条线),我们可以在谷歌地图上画出来。
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
#5
0
At time of writing, Renjin (a Java-based R interpreter) does not have a lot of packages to help solve this problem. Here is an implementation that does not depend on extra packages.
在编写本文时,Renjin(一个基于java的R解释器)没有很多包来帮助解决这个问题。这是一个不依赖于额外包的实现。
# Computes the distance between two locations in meters. This uses an online
# map API and therefore an Internet connection is required for an accurate
# result. If no connection is found, this will use the Haversine formula
# to provide a rough estimate for the distance.
#
# @param src The source latitude and longitude.
# @param dst The destination latitude and longitude.
# @param mode Driving, cycling, walking, etc.
distance <- function( lat1, lon1, lat2, lon2, mode = 'driving' ) {
lat1 = as.numeric( lat1 )
lon1 = as.numeric( lon1 )
lat2 = as.numeric( lat2 )
lon2 = as.numeric( lon2 )
# Create the URL to use to get the distance data.
url = paste0(
'https://maps.googleapis.com/maps/api/distancematrix/xml?',
'origins=', lat1,
',', lon1,
'&destinations=', lat2,
',', lon2,
'&mode=', mode,
'&sensor=false'
)
tryCatch({
# Download the XML document with distance information.
xml = readLines( url )
# The <value> element immediately follows the distance element.
value = xml[ grep( "<distance>", xml ) + 1 ]
# Obtain the distance in meters.
meters = sub( ".*>(.*?)<.*", "\\1", value )
# Return the distance.
as.numeric( meters )
},
warning = function( w ) {
haversine( lat1, lon1, lat2, lon2 )
},
error = function( e ) {
haversine( lat1, lon1, lat2, lon2 )
})
}
# Computes distance using Haversine formula.
#
# Returns the result in meters.
haversine <- function( lat1, lon1, lat2, lon2, radius = 6371 ) {
# Convert decimal degrees to radians
lon1 = lon1 * pi / 180
lon2 = lon2 * pi / 180
lat1 = lat1 * pi / 180
lat2 = lat2 * pi / 180
# Haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
return( radius * c * 1000 )
}
Output:
输出:
distance( '44.5646', '-123.2620', '41.2861', '-124.0902' )
[1] 495892
distance( 44.5646, -123.2620, 41.2861, -124.0902, mode='walking' )
[1] 487715
Conversion from meters to feet is an exercise for the reader.
从米到脚的转换对于读者来说是一个练习。