Wie wird der Google Distance Matrix API-Schlüssel in R-Code integriert?
Ich habe mich bei Google registriert, um mehr Anfragen zu Fahrzeitentfernungen zu erhalten. Google nimmt diese "Erlaubnis" jedoch nicht automatisch entgegen, um mehr als 2500 Abfragen pro Tag auszuführen. Zusätzlichmapdist()
hat kein Argument, um einen API-Schlüssel zu integrieren.
Ich habe es geschafft, einen API-Schlüssel über die Google-Konsole abzurufen.
Ich habe versucht, den Rohcode zu ändern, indem ich den Schlüssel hinzufügte und die Zeilen 56, 90 und 91 wie folgt änderte:
mapdist <- function(from, to, mode = c("driving","walking","bicycling"),
output = c("simple","all"), messaging = FALSE, sensor = FALSE,
language = "en-EN", override_limit = FALSE, key = "XXXX")
{
message("by using this function you are agreeing to the terms at :")
message("http://code.google.com/apis/maps/documentation/distancematrix/\n")
# check parameters
if(is.numeric(from) && length(from) == 2) from <- revgeocode(from)
stopifnot(is.character(from))
if(is.numeric(to) && length(to) == 2) to <- revgeocode(to)
stopifnot(is.character(to))
from_to_df <- data.frame(from = from, to = to, stringsAsFactors = FALSE)
origins <- from_to_df$from
destinations <- from_to_df$to # this ensures # from = # to
mode <- match.arg(mode)
output <- match.arg(output)
stopifnot(is.logical(messaging))
stopifnot(is.logical(sensor))
getdists <- function(df){
# format url
origin <- df$from[1]
origin <- gsub(",", "", origin)
origin <- gsub(" ", "+", origin)
origin <- paste("origins=", origin, sep = "")
destinations <- df$to
destinations <- gsub(",", "", destinations)
destinations <- gsub(" ", "+", destinations)
destinations <- paste("destinations=", paste(destinations, collapse = "|"), sep = "")
mode4url <- paste("mode=", mode, sep = "")
lang4url <- paste("language=", language, sep = "")
sensor4url <- paste("sensor=", tolower(as.character(sensor)), sep = "")
keyUrl <- paste("key=", key, sep = "")
posturl <- paste(origin, destinations, mode4url, sensor4url, keyUrl, sep = "&")
url_string <- paste("http://maps.googleapis.com/maps/api/distancematrix/json?",
posturl, sep = "")
url_string <- URLencode(url_string)
# check if query is too long
if(nchar(url_string) >= 2048){
n <- nrow(df)
half_df <- floor(n/2)
return(
rbind(
getdists(df[half_df,]),
getdists(df[(half_df+1):n,])
)
)
}
# check/update google query limit
check_dist_query_limit(url_string, elems = nrow(df),
override = override_limit, messaging = messaging)
# distance lookup
if(messaging) message("trying url ", url_string)
connect <- url(url_string)
tree <- fromJSON(paste(readLines(connect), collapse = ""))
close(connect)
# message user
message(paste0("Information from URL : ", url_string))
# label destinations - first check if all were found
if(length(df$to) != length(tree$destination_addresses)){
message("matching was not perfect, returning what was found.")
names( tree$rows[[c(1,1)]] ) <- tree$destination_addresses
output <<- "all"
# stringdist::amatch(df$to, tree$destination_addresses, maxDist = 10)
} else {
names( tree$rows[[c(1,1)]] ) <- df$to
}
# return
tree$rows[[c(1,1)]]
}
out <- dlply(from_to_df, "from", getdists)
# return all
if(output == "all") return(out)
# format output
out <-
ldply(out, function(oneFromList){
ldply(oneFromList, function(oneToList){
data.frame(
m = oneToList$distance$value,
km = oneToList$distance$value/1000,
miles = 0.0006214 * oneToList$distance$value,
seconds = oneToList$duration$value,
minutes = oneToList$duration$value / 60,
hours = oneToList$duration$value / 3600
)
})
})
names(out) <- c("from", "to", names(out)[3:ncol(out)])
# "simple" return
suppressMessages(join(from_to_df, out))
}
check_dist_query_limit <- function(url_string, elems, override, messaging){
.GoogleDistQueryCount <- NULL; rm(.GoogleDistQueryCount); # R CMD check trick
if(exists(".GoogleDistQueryCount", .GlobalEnv)){
.GoogleDistQueryCount <<-
subset(.GoogleDistQueryCount, time >= Sys.time() - 24*60*60)
# 2500 per 24 hours
if(sum(.GoogleDistQueryCount$elements) + elems > 2500){
message("query max exceeded, see ?mapdist. current total = ",
sum(.GoogleDistQueryCount$elements))
if(!override) stop("google query limit exceeded.", call. = FALSE)
}
# 100 per 10 seconds
if(with(.GoogleDistQueryCount,
sum(elements[time >= Sys.time() - 10]) + elems > 100
)){
if(messaging) message("waiting 10 seconds for another 100 queries...", appendLF=F)
Sys.sleep(10) # can do better
if(messaging) message(" done")
}
# append to .GoogleDistQueryCount
.GoogleDistQueryCount <<- rbind(.GoogleDistQueryCount,
data.frame(time = Sys.time(), url = url_string,
elements = elems, stringsAsFactors = FALSE)
)
} else {
.GoogleDistQueryCount <<-
data.frame(time = Sys.time(), url = url_string,
elements = elems, stringsAsFactors = FALSE)
}
}
#' Check Google Maps Distance Matrix API query limit
#'
#' Check Google Maps Distance Matrix API query limit
#'
#' @return a data frame
#' @author David Kahle \email{david.kahle@@gmail.com}
#' @seealso \url{http://code.google.com/apis/maps/documentation/distancematrix/}
#' @export
#' @examples
#' distQueryCheck()
distQueryCheck <- function(){
.GoogleDistQueryCount <- NULL; rm(.GoogleDistQueryCount); # R CMD check trick
if(exists(".GoogleDistQueryCount", .GlobalEnv)){
remaining <- 2500-sum(
subset(.GoogleDistQueryCount, time >= Sys.time() - 24*60*60)$elements
)
message(remaining, " distance queries remaining.")
} else {
remaining <- 2500
message(remaining, " distance queries remaining.")
}
invisible(remaining)
}
Aber ich habe beim Ausführen von mapdist () die folgende Fehlermeldung erhalten:
by using this function you are agreeing to the terms at :
http://code.google.com/apis/maps/documentation/distancematrix/
Information from URL : http://maps.googleapis.com/maps/api/distancematrix/json?origins=NG17+7LG&destinations=CV2+2DX&mode=driving&sensor=false&key=AIzaSyBQN9Dvgfw3bXpWj_-ddluungZcDv8Y4rg
matching was not perfect, returning what was found.
Error in `*tmp*`[[c(1, 1)]] : no such index at level 1
Called from: .fun(piece, ...)
Browse[1]> results <- dput(result)
list()
Browse[1]> res_df <- do.call(rbind, results)
Ich habe das Gefühl, dass ich diesen Schlüssel in meinen Code auf R integrieren muss, damit Google meine "Erlaubnis" abholt. Mir wurde von einem Freund gesagt, dass ich es durch @ tun könnthttr
aber ich weiß nicht viel darüber. Ich weiß wirklich nicht viel über das Programmieren und würde mich über jede Hilfe freuen!