1getGeoCode <- structure(function#geocoding utility
2### Geocode your data using, R, JSON and OSM or Google Maps' Geocoding APIs
3(
4  gcStr, ##<< adddress to geocode
5  API = c("osm", "google")[1], ##<< which API to use. see https://nominatim.org/release-docs/develop/api/Search/ and http://allthingsr.blogspot.de/2012/01/geocode-your-data-using-r-json-and.html
6  JSON = FALSE, ##<< use the JSON protocol. If FALSE, we do not have to load additional libraries
7  verbose=0 ##<< level of verbosity
8){
9  #library("RJSONIO") #Load Library
10  gcStr <- enc2utf8(gsub(' ','%20',gcStr)) #Encode URL Parameters
11  if (API == "google"){
12    #baseURL= paste0('http://maps.google.com/maps/api/geocode/",ifelse(JSON, "json","xml"),"?sensor=false&address=')
13
14    if (JSON){
15      #Open Connection
16      # connectStr <- paste('http://maps.google.com/maps/api/geocode/json?sensor=false&address=',gcStr, sep="")
17      # if (verbose) cat("fetching ", connectStr, "\n")
18      # con <- url(connectStr)
19      # data.json <- fromJSON(paste(readLines(con), collapse=""))
20      # close(con)
21      # #Flatten the received JSON
22      # data.json <- unlist(data.json)
23      # lat <- data.json["results.geometry.location.lat"]
24      # lng <- data.json["results.geometry.location.lng"]
25
26      connectStr <- paste('http://maps.google.com/maps/api/geocode/json?sensor=false&address=',gcStr, sep="")
27      if (verbose) cat("fetching ", connectStr, "\n")
28      con <- url(connectStr)
29      data.json <- readLines(con)
30      close(con)
31
32      iLoc = grep("\"location\"", data.json,fixed=TRUE)
33      iLat = grep("\"lat\"", data.json,fixed=TRUE); iLat = min(iLat[iLat>iLoc])
34      lat = as.numeric(gsub(",", "",gsub("\"lat\" : ", "", data.json[iLat])))
35      iLng = grep("\"lng\"", data.json,fixed=TRUE); iLng = min(iLng[iLng>iLoc])
36      lng = as.numeric(gsub(",", "",gsub("\"lng\" :", "", data.json[iLng])))
37
38    } else {
39      #Open Connection
40      connectStr <- paste('http://maps.google.com/maps/api/geocode/xml?sensor=false&address=',gcStr, sep="")
41      if (verbose) cat("fetching ", connectStr, "\n")
42      con <- url(connectStr)
43      data.xml <- readLines(con)
44      close(con)
45      #browser()
46      iLoc = grep("<location>", data.xml,fixed=TRUE)
47      iLat = grep("<lat>", data.xml,fixed=TRUE); iLat = min(iLat[iLat>iLoc])
48      lat = as.numeric(gsub("</lat>", "",gsub("<lat>", "", data.xml[iLat])))
49      iLng = grep("<lng>", data.xml,fixed=TRUE); iLng = min(iLng[iLng>iLoc])
50      lng = as.numeric(gsub("</lng>", "",gsub("<lng>", "", data.xml[iLng])))
51    }
52  } else if (API == "osm") {
53    #baseURL= paste0("https://nominatim.openstreetmap.org/search?format=",ifelse(JSON, "json","xml"),"&polygon=0&addressdetails=0&q=")
54    # https://nominatim.openstreetmap.org/search?format=xml&polygon=0&addressdetails=0&q=135+pilkington+avenue,+birmingham&
55    #https://nominatim.openstreetmap.org/search?q=17+Strada+Pictor+Alexandru+Romano%2C+Bukarest&format=xml
56    if (JSON) {
57
58    } else {
59      connectStr <- paste0("https://nominatim.openstreetmap.org/search?q=",gcStr,"&format=xml&limit=1")
60      if (verbose) cat("fetching ", connectStr, "\n")
61      con <- url(connectStr)
62      data.xml <- readLines(con, warn=FALSE)
63      close(con)
64      #browser()
65      tmp=unlist(strsplit( data.xml," "))
66      iLat = grep("lat=", tmp,fixed=TRUE)
67      lat = as.numeric(gsub("lat='|'", "",tmp[iLat]))
68      iLng = grep("lon=", tmp,fixed=TRUE)
69      lng = as.numeric(gsub("lon='|'", "",tmp[iLng]))
70    }
71
72  }
73  gcodes <- as.numeric(c(lat, lng))
74  names(gcodes) <- c("lat", "lon")
75  return (gcodes)
76### returns lat/lon for address
77}, ex = function(){
78  if (0){
79    getGeoCode("1600 Amphitheatre Parkway, Mountain View, CA")
80    getGeoCode("Brooklyn")
81    #You can run this on the entire column of a data frame or a data table:
82    DF = cbind.data.frame(address=c("Berlin,Germany", "Princeton,NJ",
83              "cadillac+mountain+acadia+national+park"), lat = NA, lon = NA)
84    DF <- with(DF, data.frame(address, t(sapply(DF$address, getGeoCode))))
85  }
86})
87
88
89