R: Come geodificare un indirizzo semplice usando Data Science Toolbox

Sono entusiasta della geocodifica di Google e ho deciso di provare un’alternativa. Il Data Science Toolkit ( http://www.datasciencetoolkit.org ) consente di geocodificare un numero illimitato di indirizzi. R ha un eccellente pacchetto che funge da wrapper per le sue funzioni (CRAN: RDSTK). Il pacchetto ha una funzione chiamata street2coordinates() che si interfaccia con l’utilità di geocoding di Data Science Toolkit.

Tuttavia, la funzione street2coordinates() non funziona se si tenta di geocodificare qualcosa di semplice come Città, Paese . Nell’esempio seguente proverò ad usare la funzione per ottenere la latitudine e la longitudine della città di Phoenix:

 > require("RDSTK") > street2coordinates("Phoenix+Arizona+United+States") [1] full.address  (or 0-length row.names) 

L’utilità del toolkit Data Science funziona perfettamente. Questa è la richiesta URL che fornisce la risposta: http://www.datasciencetoolkit.org/maps/api/geocode/json?sensor=false&address=Phoenix+Arizona+United+States

Sono interessato a geocodificare più indirizzi (che completano indirizzi e nomi di città). So che l’URL di Data Science Toolkit funzionerà bene. Come faccio a interfacciarmi con l’URL e ottenere latitudini e longitudini multiple in un frame di dati con gli indirizzi?

Ecco un set di dati di esempio:

 dff <- data.frame(address=c( "Birmingham, Alabama, United States", "Mobile, Alabama, United States", "Phoenix, Arizona, United States", "Tucson, Arizona, United States", "Little Rock, Arkansas, United States", "Berkeley, California, United States", "Duarte, California, United States", "Encinitas, California, United States", "La Jolla, California, United States", "Los Angeles, California, United States", "Orange, California, United States", "Redwood City, California, United States", "Sacramento, California, United States", "San Francisco, California, United States", "Stanford, California, United States", "Hartford, Connecticut, United States", "New Haven, Connecticut, United States" )) 

Come questo?

 library(httr) library(rjson) data <- paste0("[",paste(paste0("\"",dff$address,"\""),collapse=","),"]") url <- "http://www.datasciencetoolkit.org/street2coordinates" response <- POST(url,body=data) json <- fromJSON(content(response,type="text")) geocode <- do.call(rbind,sapply(json, function(x) c(long=x$longitude,lat=x$latitude))) geocode # long lat # San Francisco, California, United States -117.88536 35.18713 # Mobile, Alabama, United States -88.10318 30.70114 # La Jolla, California, United States -117.87645 33.85751 # Duarte, California, United States -118.29866 33.78659 # Little Rock, Arkansas, United States -91.20736 33.60892 # Tucson, Arizona, United States -110.97087 32.21798 # Redwood City, California, United States -117.88536 35.18713 # New Haven, Connecticut, United States -72.92751 41.36571 # Berkeley, California, United States -122.29673 37.86058 # Hartford, Connecticut, United States -72.76356 41.78516 # Sacramento, California, United States -121.55541 38.38046 # Encinitas, California, United States -116.84605 33.01693 # Birmingham, Alabama, United States -86.80190 33.45641 # Stanford, California, United States -122.16750 37.42509 # Orange, California, United States -117.85311 33.78780 # Los Angeles, California, United States -117.88536 35.18713 

Questo sfrutta l'interfaccia POST per l'API street2coordinates ( documentata qui ), che restituisce tutti i risultati in 1 richiesta, anziché utilizzare più richieste GET.

EDIT (risposta al commento dell'OP)

L'assenza di Phoenix sembra essere un bug nell'API streetcoordinates. Se vai alla pagina demo dell'API e provi "Phoenix, Arizona, Stati Uniti", ottieni una risposta nulla. Tuttavia, come mostra il tuo esempio, utilizzando il loro "Geocoder in stile Google" viene fornito un risultato per Phoenix. Quindi ecco una soluzione che utilizza ripetute richieste GET. Si noti che questo funziona molto più lentamente .

 geo.dsk <- function(addr){ # single address geocode with data sciences toolkit require(httr) require(rjson) url <- "http://www.datasciencetoolkit.org/maps/api/geocode/json" response <- GET(url,query=list(sensor="FALSE",address=addr)) json <- fromJSON(content(response,type="text")) loc <- json['results'][[1]][[1]]$geometry$location return(c(address=addr,long=loc$lng, lat= loc$lat)) } result <- do.call(rbind,lapply(as.character(dff$address),geo.dsk)) result <- data.frame(result) result # address long lat # 1 Birmingham, Alabama, United States -86.801904 33.456412 # 2 Mobile, Alabama, United States -88.103184 30.701142 # 3 Phoenix, Arizona, United States -112.0733333 33.4483333 # 4 Tucson, Arizona, United States -110.970869 32.217975 # 5 Little Rock, Arkansas, United States -91.207356 33.608922 # 6 Berkeley, California, United States -122.29673 37.860576 # 7 Duarte, California, United States -118.298662 33.786594 # 8 Encinitas, California, United States -116.846046 33.016928 # 9 La Jolla, California, United States -117.876447 33.857515 # 10 Los Angeles, California, United States -117.885359 35.187133 # 11 Orange, California, United States -117.853112 33.787795 # 12 Redwood City, California, United States -117.885359 35.187133 # 13 Sacramento, California, United States -121.555406 38.380456 # 14 San Francisco, California, United States -117.885359 35.187133 # 15 Stanford, California, United States -122.1675 37.42509 # 16 Hartford, Connecticut, United States -72.763564 41.78516 # 17 New Haven, Connecticut, United States -72.927507 41.365709 

Il pacchetto ggmap include il supporto per il geocoding utilizzando Google o Data Science Toolkit, quest’ultimo con il loro “geocoder in stile Google”. Questo è piuttosto lento per più indirizzi, come indicato nella risposta precedente.

 library(ggmap) result <- geocode(as.character(dff[[1]]), source = "dsk") print(cbind(dff, result)) # address lon lat # 1 Birmingham, Alabama, United States -86.80190 33.45641 # 2 Mobile, Alabama, United States -88.10318 30.70114 # 3 Phoenix, Arizona, United States -112.07404 33.44838 # 4 Tucson, Arizona, United States -110.97087 32.21798 # 5 Little Rock, Arkansas, United States -91.20736 33.60892 # 6 Berkeley, California, United States -122.29673 37.86058 # 7 Duarte, California, United States -118.29866 33.78659 # 8 Encinitas, California, United States -116.84605 33.01693 # 9 La Jolla, California, United States -117.87645 33.85751 # 10 Los Angeles, California, United States -117.88536 35.18713 # 11 Orange, California, United States -117.85311 33.78780 # 12 Redwood City, California, United States -117.88536 35.18713 # 13 Sacramento, California, United States -121.55541 38.38046 # 14 San Francisco, California, United States -117.88536 35.18713 # 15 Stanford, California, United States -122.16750 37.42509 # 16 Hartford, Connecticut, United States -72.76356 41.78516 # 17 New Haven, Connecticut, United States -72.92751 41.36571