从Lat Lng到Loop的行驶距离

时间:2016-04-07 16:50:09

标签: xml r google-maps-api-3

我在数据帧中有两个点的经度和经度。我在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)

但是我收到了以下错误。

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"])

这是我的数据样本:

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

我的代码中哪里错了?据我所知,我无法在运行循环时将值正确传递给函数。但我无法找到解决方法。提前感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

出现了下标超出范围错误,因为您没有为URL使用正确的API格式。它会从Google服务器生成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>

其中没有有效的distance

错误是网址中originsdestinations周围的单引号。当您将它们与代码

连接在一起时
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")

您在值周围添加'个单引号,这是不正确的。如果你删掉单引号:

test$origin1 = paste0(test$store_lat,",",test$store_lng)
test$destination1 = paste0(test$lat,",",test$lng)

然后,您的代码会生成http://maps.googleapis.com/maps/api/distancematrix/xml?origins=19.21368,72.99034&destinations=19.1901094,72.9758546&mode=driving&sensor=false"的正确网址,而不会使用单引号。然后,Google服务器返回的结果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>

现在有一个有效的距离值。

您可以找到有关Google Maps Distance API here

详细信息的更多详细信息

答案 1 :(得分:1)

我写了googleway包,可以为你做很多艰苦的工作。

如果您拥有有效的Google 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"

答案 2 :(得分: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
}

没有“'”