I have a lattitude and longitude for two points in a dataframe. I am using the code below in R for obtaining the driving distance.
我在dataframe中有两个点的准确和经度。我使用下面R中的代码来获取行驶距离。
library(XML)
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)
}
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")
distance <- list()
for(i in 1:nrow(test)){
dat <- latlon2ft(test[i,'origin1'],test[i,'destination1'])
distance[[i]] <- dat
}
all_distance <- do.call("rbind", distance)
But i am getting the following error.
但是我得到了下面的错误。
Error in xpathApply(xmlfile, "//distance")[[1]] : subscript out of bounds
3 xmlChildren(xpathApply(xmlfile, "//distance")[[1]])
2 xmlValue(xmlChildren(xpathApply(xmlfile, "//distance")[[1]])$value)
1 latlon2ft(test[i, "origin1"], test[i, "destination1"])
This is a sample of my data:
这是我的数据样本:
store_lat | store_lng | lat | lng
19.21368 | 72.99034 | 19.1901094 | 72.9758546
19.10749 | 72.86444 | 19.1052534 | 72.8609213
19.01480 | 72.84545 | 18.9942502 | 72.8365256
19.01480 | 72.84545 | 19.1453449 | 72.8367015
Where in my code am i wrong? As far as i can see i am not able to pass the values correctly into the function while running the loop. But i am not able to find a work around. Thanks in advance for any help.
在我的代码中我哪里错了?就我所知,我不能在运行循环时将值正确地传递到函数中。但是我找不到工作。谢谢你的帮助。
3 个解决方案
#1
2
The subscript out of bounds error is occurring because you are not using the correct API format for the URL. It produces an xmlfile
response from the Google server of:
由于您没有为URL使用正确的API格式,因此出现了超出界限的下标错误。它从谷歌服务器生成一个xmlfile响应:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address/>
<destination_address/>
<row>
<element>
<status>NOT_FOUND</status>
</element>
</row>
</DistanceMatrixResponse>
Which has no valid distance
in it.
没有有效距离。
The mistake is the single quotes around the origins
and destinations
in the URL. When you join them together with the code
错误在于URL中围绕源和目的地的单引号。当您将它们与代码连接在一起时
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")
You add '
single quotes around the values, which is incorrect. If you drop the single quotes:
你在值周围加上“单引号”,这是不正确的。如果你省略了单引号:
test$origin1 = paste0(test$store_lat,",",test$store_lng)
test$destination1 = paste0(test$lat,",",test$lng)
Your code then produces a correct URL of http://maps.googleapis.com/maps/api/distancematrix/xml?origins=19.21368,72.99034&destinations=19.1901094,72.9758546&mode=driving&sensor=false"
without the single quotes. The resulting XML returned by the Google server is then:
然后您的代码生成一个正确的URL http://maps.googleapis.com/maps/api/distancematrix/xml?origin =19.21368,72.99034&destination =19.1901094,72.9758546&mode=driving&sensor=false,没有单引号。谷歌服务器返回的结果XML如下:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address>External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India</origin_address>
<destination_address>A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India</destination_address>
<row>
<element>
<status>OK</status>
<duration>
<value>981</value>
<text>16 mins</text>
</duration>
<distance>
<value>4908</value>
<text>4.9 km</text>
</distance>
</element>
</row>
</DistanceMatrixResponse>
Which now has a valid distance value.
它现在有一个有效的距离值。
You can find more details on the specifics of the Google Maps Distance API here
您可以在这里找到关于谷歌映射距离API的详细信息
#2
1
I've written the googleway
package that can do a lot of the hard work for you.
我已经写了googleway包它可以为你做很多艰苦的工作。
If you have a valid Google API key you can use the function google_distance()
to get a distance matrix between numerous locations.
如果您有一个有效的谷歌API密钥,您可以使用google_distance()函数来获得多个位置之间的距离矩阵。
library(googleway)
key <- "your_api_key"
## distances for individual locations
google_distance(origins = list(c(df[1, "store_lat"], df[1,"store_lng"])),
destinations = list(c(df[1, "lat"], df[1, "lng"])),
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
#
# $rows
# elements
# 1 4.9 km, 4874, 17 mins, 995, 15 mins, 904, OK
#
# $status
# [1] "OK"
## distance matrix for multiple locations
origins <- split(df[, c("store_lat","store_lng")], f = row.names(df))
origins <- lapply(origins, as.numeric)
destinations <- split(df[, c("lat","lng")], f = row.names(df))
destinations <- lapply(destinations, as.numeric)
google_distance(origins = origins,
destinations = destinations,
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
# [2] "A-102, Sahar Rd, Bramhan Wadi, Andheri East, Mumbai, Maharashtra 400047, India"
# [3] "Lalbaug Flyover, Ghodapdeo, Ganesh Gully, Parel, Mumbai, Maharashtra 400012, India"
# [4] "24-A/101, Behram Baug, Jogeshwari West, Mumbai, Maharashtra 400047, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
# [2] "Cardinal Gracias Rd, Kanti Nagar, J B Nagar, Andheri East, Mumbai, Maharashtra 400059, India"
# [3] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
# [4] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
#
# $rows
# elements
# 1 4.9 km, 26.1 km, 33.2 km, 28.2 km, 4874, 26130, 33150, 28194, 17 mins, 49 mins, 45 mins, 56 mins, 995, 2931, 2697, 3384, 16 mins, 44 mins, 41 mins, 48 mins, 943, 2638, 2471, 2906, OK, OK, OK, OK
# 2 20.3 km, 0.9 km, 16.0 km, 9.1 km, 20303, 872, 16045, 9140, 44 mins, 4 mins, 34 mins, 25 mins, 2655, 257, 2055, 1512, 39 mins, 4 mins, 32 mins, 21 mins, 2364, 214, 1938, 1231, OK, OK, OK, OK
# 3 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
# 4 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
#
# $status
# [1] "OK"
#3
0
test$origin1 = paste0(test$store_lat, ",", test$store_lng)
test$destination1 = paste0(test$lat, ",", test$lng)
distance <- list()
for(i in 1:nrow(test)) {
dat <- latlon2ft(test[i, 'origin1'], test[i, 'destination1'])
distance[[i]] <- dat
}
without "'"
没有“”
#1
2
The subscript out of bounds error is occurring because you are not using the correct API format for the URL. It produces an xmlfile
response from the Google server of:
由于您没有为URL使用正确的API格式,因此出现了超出界限的下标错误。它从谷歌服务器生成一个xmlfile响应:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address/>
<destination_address/>
<row>
<element>
<status>NOT_FOUND</status>
</element>
</row>
</DistanceMatrixResponse>
Which has no valid distance
in it.
没有有效距离。
The mistake is the single quotes around the origins
and destinations
in the URL. When you join them together with the code
错误在于URL中围绕源和目的地的单引号。当您将它们与代码连接在一起时
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")
You add '
single quotes around the values, which is incorrect. If you drop the single quotes:
你在值周围加上“单引号”,这是不正确的。如果你省略了单引号:
test$origin1 = paste0(test$store_lat,",",test$store_lng)
test$destination1 = paste0(test$lat,",",test$lng)
Your code then produces a correct URL of http://maps.googleapis.com/maps/api/distancematrix/xml?origins=19.21368,72.99034&destinations=19.1901094,72.9758546&mode=driving&sensor=false"
without the single quotes. The resulting XML returned by the Google server is then:
然后您的代码生成一个正确的URL http://maps.googleapis.com/maps/api/distancematrix/xml?origin =19.21368,72.99034&destination =19.1901094,72.9758546&mode=driving&sensor=false,没有单引号。谷歌服务器返回的结果XML如下:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address>External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India</origin_address>
<destination_address>A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India</destination_address>
<row>
<element>
<status>OK</status>
<duration>
<value>981</value>
<text>16 mins</text>
</duration>
<distance>
<value>4908</value>
<text>4.9 km</text>
</distance>
</element>
</row>
</DistanceMatrixResponse>
Which now has a valid distance value.
它现在有一个有效的距离值。
You can find more details on the specifics of the Google Maps Distance API here
您可以在这里找到关于谷歌映射距离API的详细信息
#2
1
I've written the googleway
package that can do a lot of the hard work for you.
我已经写了googleway包它可以为你做很多艰苦的工作。
If you have a valid Google API key you can use the function google_distance()
to get a distance matrix between numerous locations.
如果您有一个有效的谷歌API密钥,您可以使用google_distance()函数来获得多个位置之间的距离矩阵。
library(googleway)
key <- "your_api_key"
## distances for individual locations
google_distance(origins = list(c(df[1, "store_lat"], df[1,"store_lng"])),
destinations = list(c(df[1, "lat"], df[1, "lng"])),
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
#
# $rows
# elements
# 1 4.9 km, 4874, 17 mins, 995, 15 mins, 904, OK
#
# $status
# [1] "OK"
## distance matrix for multiple locations
origins <- split(df[, c("store_lat","store_lng")], f = row.names(df))
origins <- lapply(origins, as.numeric)
destinations <- split(df[, c("lat","lng")], f = row.names(df))
destinations <- lapply(destinations, as.numeric)
google_distance(origins = origins,
destinations = destinations,
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
# [2] "A-102, Sahar Rd, Bramhan Wadi, Andheri East, Mumbai, Maharashtra 400047, India"
# [3] "Lalbaug Flyover, Ghodapdeo, Ganesh Gully, Parel, Mumbai, Maharashtra 400012, India"
# [4] "24-A/101, Behram Baug, Jogeshwari West, Mumbai, Maharashtra 400047, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
# [2] "Cardinal Gracias Rd, Kanti Nagar, J B Nagar, Andheri East, Mumbai, Maharashtra 400059, India"
# [3] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
# [4] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
#
# $rows
# elements
# 1 4.9 km, 26.1 km, 33.2 km, 28.2 km, 4874, 26130, 33150, 28194, 17 mins, 49 mins, 45 mins, 56 mins, 995, 2931, 2697, 3384, 16 mins, 44 mins, 41 mins, 48 mins, 943, 2638, 2471, 2906, OK, OK, OK, OK
# 2 20.3 km, 0.9 km, 16.0 km, 9.1 km, 20303, 872, 16045, 9140, 44 mins, 4 mins, 34 mins, 25 mins, 2655, 257, 2055, 1512, 39 mins, 4 mins, 32 mins, 21 mins, 2364, 214, 1938, 1231, OK, OK, OK, OK
# 3 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
# 4 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
#
# $status
# [1] "OK"
#3
0
test$origin1 = paste0(test$store_lat, ",", test$store_lng)
test$destination1 = paste0(test$lat, ",", test$lng)
distance <- list()
for(i in 1:nrow(test)) {
dat <- latlon2ft(test[i, 'origin1'], test[i, 'destination1'])
distance[[i]] <- dat
}
without "'"
没有“”