over_query_limit - Geocodificación en R con Google Maps
massive geocoding (6)
¿Has pensado en utilizar la llamada json en su lugar? En cuanto a su código, podría lograr lo mismo al hacer esto (deberá instalar los paquetes RCurl y RJSONIO de omegahat.com).
Copie y pegue esto en R:
library(RCurl)
library(RJSONIO)
construct.geocode.url <- function(address, return.call = "json", sensor = "false") {
root <- "http://maps.google.com/maps/api/geocode/"
u <- paste(root, return.call, "?address=", address, "&sensor=", sensor, sep = "")
return(URLencode(u))
}
gGeoCode <- function(address,verbose=FALSE) {
if(verbose) cat(address,"/n")
u <- construct.geocode.url(address)
doc <- getURL(u)
x <- fromJSON(doc,simplify = FALSE)
if(x$status=="OK") {
lat <- x$results[[1]]$geometry$location$lat
lng <- x$results[[1]]$geometry$location$lng
return(c(lat, lng))
} else {
return(c(NA,NA))
}
}
Así es como usa las funciones anteriores:
x <- gGeoCode("Philadelphia, PA")
Este es el resultado que obtienes. Creo que en el código original, lat y lng están mezclados? Pero espero que esto es lo que quieres:
> x
[1] 39.95233 -75.16379
Espero que ayude a un pequeño compañero,
Tony Breyal
He intentado ejecutar el código para geocodificar ubicaciones en R a través de Google Maps y el paquete XML
de esta publicación de blog: http://www.r-chart.com/2010/07/maps-geocoding-and-r-user-conference.html
Estas son sus funciones:
getDocNodeVal=function(doc, path){
sapply(getNodeSet(doc, path), function(el) xmlValue(el))
}
gGeoCode=function(str){
library(XML)
u=paste(''http://maps.google.com/maps/api/geocode/xml?sensor=false&address='',str)
doc = xmlTreeParse(u, useInternal=TRUE)
str=gsub('' '',''%20'',str)
lng=getDocNodeVal(doc, "/GeocodeResponse/result/geometry/location/lat")
lat=getDocNodeVal(doc, "/GeocodeResponse/result/geometry/location/lng")
c(lat,lng)
}
Cuando ejecuto gGeoCode()
, gGeoCode()
el siguiente error:
> gGeoCode("Philadelphia, PA")
failed to load external entity "http%3A//maps.google.com/maps/api/geocode/xml%3Fsensor=false&address=%20Philadelphia,%20PA"
Error: 1: failed to load external entity "http%3A//maps.google.com/maps/api/geocode/xml%3Fsensor=false&address=%20Philadelphia,%20PA"
Si solo pego en un navegador la URL de la API con Philadelphia, PA
adjuntada al final, al igual que la cadena pasada a xmlParseTree
, obtengo un resultado que se ve como xml legítimo cuando lo descargo.
¿Es esto un problema con el código o he fallado al configurar algo u otro?
Esta es otra opción para geocodificar; puede ser más fácil de analizar:
Este código funciona usando solo la biblioteca XML
library(XML)
url = ''http://maps.googleapis.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true''
doc = xmlTreeParse(url, useInternal=TRUE)
lat = as.numeric(xmlValue(getNodeSet(doc, ''//location/lat'')[[1]]))
lng = as.numeric(xmlValue(getNodeSet(doc, ''//location/lng'')[[1]]))
Esto también se puede hacer con mi paquete googleway y una clave válida de Google Maps API
library(googleway)
key <- "your_api_key"
df <- google_geocode("Philadelphia, PA",
key = key)
df$results$geometry$location
# lat lng
# 1 39.95258 -75.16522
Y a geocodificación inversa
df <- google_reverse_geocode(location = c(39.95258, -75.16522),
key = key)
df$results$formatted_address
# [1] "1414 PA-611, Philadelphia, PA 19102, USA" "15th St Station - MFL, Philadelphia, PA 19102, USA"
# [3] "Center City West, Philadelphia, PA, USA" "Center City, Philadelphia, PA, USA"
# [5] "Philadelphia, PA, USA" "Philadelphia, PA 19107, USA"
# [7] "Philadelphia County, PA, USA" "Philadelphia-Camden-Wilmington, PA-NJ-DE-MD, USA"
# [9] "Philadelphia Metropolitan Area, USA" "Pennsylvania, USA"
# [11] "United States"
He modificado la solución de Tony Breyal para que la función gGeoCode
también tome un vector de direcciones como entrada. Con esta versión, no solo puede hacer gGeoCode("Philadelphia, PA")
sino también gGeoCode(c("Philadelphia, PA","New York, NY"))
con este valor de retorno.
address lat lng
1 "Philadelphia, PA" "39.952335" "-75.163789"
2 "New York, NY" "40.7143528" "-74.0059731"
Tenga en cuenta que la API de Google Maps tiene un límite diario de 2.500 para que su vector no sea demasiado largo. Aquí está la función actualizada:
library(RCurl)
library(RJSONIO)
construct.geocode.url <- function(address, return.call = "json", sensor = "false") {
root <- "http://maps.google.com/maps/api/geocode/"
u <- paste(root, return.call, "?address=", address, "&sensor=", sensor, sep = "")
return(URLencode(u))
}
gGeoCode <- function(address,verbose=FALSE) {
require("plyr")
if(verbose) cat(address,"/n")
u <- aaply(address,1,construct.geocode.url)
doc <- aaply(u,1,getURL)
json <- alply(doc,1,fromJSON,simplify = FALSE)
coord = laply(json,function(x) {
if(x$status=="OK") {
lat <- x$results[[1]]$geometry$location$lat
lng <- x$results[[1]]$geometry$location$lng
return(c(lat, lng))
} else {
return(c(NA,NA))
}
})
if(length(address)>1) colnames(coord)=c("lat","lng")
else names(coord)=c("lat","lng")
return(data.frame(address,coord))
}
EDITAR: Corrección pequeña en el código para que lat y lng se devuelvan como valores numéricos.
Necesitaba obtener todas las direcciones devueltas del geocode
no solo la primera, así que escribí una pequeña función para hacerlo. Se puede usar para geocodificar e invertir geocodificación
geocode <- function(address,reverse=FALSE) {
require("RJSONIO")
baseURL <- "http://maps.google.com/maps/api/geocode/json?sensor=false&"
# This is not necessary,
# because the parameter "address" accepts both formatted address and latlng
conURL <- ifelse(reverse,paste0(baseURL,''latlng='',URLencode(address)),
paste0(baseURL,''address='',URLencode(address)))
con <- url(conURL)
data.json <- fromJSON(paste(readLines(con), collapse=""))
close(con)
status <- data.json["status"]
if(toupper(status) == "OK"){
t(sapply(data.json$results,function(x) {
list(address=x$formatted_address,lat=x$geometry$location[1],
lng=x$geometry$location[2])}))
} else {
warning(status)
NULL
}
}
Ejemplo de geocodificación:
geocode ("Dupont Cir NW, Washington, DC 20036, EE. UU.")
address lat lng
[1,] "Dupont Circle Northwest, Washington, DC 20036, USA" 38.90914 -77.04366
[2,] "Dupont Circle, 1 Dupont Circle Northwest, Washington, DC 20036, USA" 38.90921 -77.04438
[3,] "Washington, DC 20036, USA" 38.90808 -77.04061
[4,] "Dupont Circle, Washington, DC 20036, USA" 38.90958 -77.04344
Ejemplo de geocodificación inversa:
tenga en cuenta que la dirección puede ser una dirección formateada o latlng, el parámetro reverse
no se utiliza, pero se incluye para su uso futuro con otros servicios de geocodificación
código geográfico ("38.910262, -77.043565")
address lat lng
[1,] "40-58 Dupont Circle Northwest, Washington, DC 20036, USA" 38.91027 -77.04357
[2,] "Washington, DC 20036, USA" 38.90808 -77.04061
[3,] "Dupont Circle, Washington, DC, USA" 38.90969 -77.04334
[4,] "Northwest Washington, Washington, DC, USA" 38.94068 -77.06796
[5,] "District of Columbia, USA" 38.90598 -77.03342
[6,] "Washington, DC, USA" 38.90723 -77.03646
[7,] "United States" 37.09024 -95.71289