我正在查询Google Maps Roads API,每个请求最多只接受100个坐标对。但是,routes
中的一些输入线串包含超过100个段。
我已经编写了一个向API发送请求的示例循环,但它仅限于包含if (nrow(routes$mat) <= 100) {...}
的100个细分的行,其中routes$mat
是坐标对的矩阵。
for (i in 1:length(routes)) {
if (nrow(routes$mat) <= 100) {
mat <- paste(apply(mat, 1, paste, collapse=","), collapse="|")
a <- "https://roads.googleapis.com/v1/snapToRoads?path="
b <- mat
c <- "&interpolate=false&key=YOUR_API_KEY"
request <- paste(a,b,c, sep="")
con <- curl(request)
open(con)
out <- readLines(con)
mydf <- fromJSON(out)
close(con)
output <- cbind(mydf$snappedPoints$location$longitude, mydf$snappedPoints$location$latitude)
}
我的目标是将所有行发送到API - 无论其长度如何,但这意味着将它们逐个发送。
如果>> mat
超过100,那么如何调整此循环以一次仅发送100个,然后将结果连接到单个output
?
例如,如果nrow(mat)
= 250,则会有3个输出,第一个为100,第二个为100,第三个为50。
答案 0 :(得分:1)
我总觉得做这种循环有点乱,但有时需要它。
对于这个答案,我正在使用我的googleway
包来处理API调用。我也在使用它附带的tram_route
数据。有55行,所以我每10次迭代一次,但是使用更大的数据集只需增加by = 10
值。
library(googleway)
set_key("roads_api_key", api = "roads")
n <- nrow(tram_route)
subsets <- c(seq(1, n, by = 10), n)
iters <- length(subsets) - 1
## set up a data.frame to store the results
df_result <- data.frame(latitude = numeric(n),
longitude = numeric(n))
for (i in 1:(length(subsets)-1) ) {
if (i == iters[length(iters)]) {
idx <- subsets[i]:subsets[i+1]
} else {
idx <- subsets[i]:(subsets[i+1] -1)
}
print(idx)
res <- google_snapToRoads(df_path = tram_route[idx, ],
lat = "shape_pt_lat",
lon = "shape_pt_lon")
df_result[idx, ] <- res$snappedPoints$location
}
head(df_result)
# latitude longitude
# 1 -37.81436 144.9386
# 2 -37.81330 144.9415
# 3 -37.81274 144.9429
# 4 -37.81268 144.9430
# 5 -37.81314 144.9439
# 6 -37.81351 144.9443
并证明是否需要证明
set_key("map_api_key")
df_result$colour <- "blue"
google_map() %>%
add_markers(tram_route, lat = "shape_pt_lat", lon = "shape_pt_lon") %>%
add_markers(df_result, colour = "colour")