Applying Revgeocode to a List of Longitude-Latitude Coordinates

Applying revgeocode to a list of longitude-latitude coordinates

There are lots of things wrong here.

First, you have latitude and longitude reversed. All the locations in your dataset, as specified, are in Antarctica.

Second, revgeocode(...) expects a numeric vector of length 2 containing the longitude and latitude in that order. You are passing a data.frame object (this is the reason for the error), and as per (1) it's in the wrong order.

Third, revgeocode(...) uses the google maps api, which limits you to 2500 queries a day. So if you really do have a large dataset, good luck with that.

This code works with your sample:

data <- read.csv(text="ID,      Longitude,      Latitude
311175, 41.298437, -72.929179
292058, 41.936943, -87.669838
12979, 37.580956, -77.471439")

library(ggmap)
result <- do.call(rbind,
lapply(1:nrow(data),
function(i)revgeocode(as.numeric(data[i,3:2]))))
data <- cbind(data,result)
data
# ID Longitude Latitude result
# 1 311175 41.29844 -72.92918 16 Church Street South, New Haven, CT 06519, USA
# 2 292058 41.93694 -87.66984 1632 West Nelson Street, Chicago, IL 60657, USA
# 3 12979 37.58096 -77.47144 2077-2199 Seddon Way, Richmond, VA 23230, USA

This extracts the zipcodes:

library(stringr)
data$zipcode <- substr(str_extract(data$result," [0-9]{5}, .+"),2,6)
data[,-4]
# ID Longitude Latitude zipcode
# 1 311175 41.29844 -72.92918 06519
# 2 292058 41.93694 -87.66984 60657
# 3 12979 37.58096 -77.47144 23230

Using revgeocode function in a FOR loop. Help required

No need to use a for-loop here. I recommand you to use lapply to avoid side effect, and pre-allocate problems:

    locaddr <- lapply(seq(nrow(location)), function(i){ 
revgeocode(location[i,],
output = c("address"),
messaging = FALSE,
sensor = FALSE,
override_limit = FALSE)
})

Problems with reverse geocoding loops with latitude longitude co-ordinates using googleway: r gives the same results for different co-ordinates

It looks like the calls to google_geocode can return more than one address for each lat/longitude pair thus you could be overwriting your data in the output data frame.

Also, I am not sure your if statement is evaluating properly.

Here is my attempt on your problem:

library(googleway)

origAddress<-read.table(header = TRUE, text = "lat lng
1.436316 103.8299
1.375093 103.8516
1.369347 103.8398
1.367353 103.8426")

#add the output column
origAddress$venadd<-NA

for(i in 1:nrow(origAddress))
{
# Print("Working...")
result <- google_reverse_geocode(location = c(origAddress$lat[i],origAddress$lng[i]),
key=key,
location_type = "rooftop")

#add a slight pause so not to overload the call requests
Sys.sleep(1)
if(result$status =="OK" ){
#multiple address can be returned with in gecode request picks the first one
origAddress$venadd[i] <- result$results$formatted_address[1]
#use this to collect all addresses:
#paste(result$results$formatted_address, collapse = " ")
}
}

Since the call to google_reverse_geocode returns the address, I just pull the first address from the result saving a call to the internet (performance improvement). Also since the call returns a status, I check for an OK and if exist save the first address.

Hope this helps.

How to reverse geocode latitude and longitude from location stored in CloudKit? - Swift 3

Apple provides a method built into Core Location's CLGeocoder class. Here are the docs. If successful the completion handler will give you access to an array of CLPlacemark, so you can grab one of those and access whichever human-readable elements you need. The names of the variables are pretty generic to cover locations all over the world, so you'll have to dig in a bit to find exactly what you need. Check the docs on CLPlacemark for exact details on the variables available to you. In your particular case you'll need locality and administrativeArea for city and state, respectively.

Usage would be something like this:

let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
guard let placemarks = placemarks, let placemark = placemarks.first else { return }
if let city = placemark.locality, let state = placemark.administrativeArea {
//Set your labels or whatever
}
}

Use revgeocode on two columns in data.table

ggmap::revgeocode requires location in longitude/latitude format to be a numeric array of length 2. suggestion is to use mapply to concatenate the longitude and latitude into an array of length 2.

dt <- fread("
Pickup_longitude,Pickup_latitude
-73.945,40.799
-73.930,40.864
-73.944,40.696
-74.001,40.688
-73.926,40.755
-73.936,40.812
")

dt[, Address:=mapply(function(long, lat) ggmap::revgeocode(c(long, lat)),
Pickup_longitude, Pickup_latitude)]

Reverse geocoding speed

You could find a 'spatial' data source of the boroughs, then perform geometric operations to find points in polygons using the sf library


Setting up the data

Find a spatial data source. Here is one of the neighbourhoods in geojson format

library(sf)

sf <- sf::st_read("https://raw.githubusercontent.com/blackmad/neighborhoods/master/new-york-city-boroughs.geojson")

Convert your coordinates into a sf object. I've swapped your lat & lon column order.

latitude <- c(40.84935,40.76306,40.81423,40.63464,40.71054)
longitude <- c(-73.87119,-73.90235,-73.93443,-73.88090,-73.83765)
x = data.frame(longitude, latitude)

sf_x <- sf::st_as_sf(x, coords = c("longitude", "latitude"))

To perform spatial operations, the coordinate reference system needs to match between the two geometries

## set the cooridnate reference systesm to be the same
st_crs(sf_x) <- st_crs(sf)

use st_within to find the polygons (neighbourhoods) each point is in

Point-in-polygon calculation

res <- st_within(sf_x, sf)  ## return the indexes of sf that sf_x are within

This gives you a sparse matrix of the indexes of the polygons that each point is in

## view the results
sapply(res, function(x) as.character(sf$name[x]))
# [1] "Bronx" "Queens" "Manhattan" "Brooklyn" "Queens"

Visual

Confirm with a plot

library(googleway)

x$neighbourhood <- sapply(res, function(x) as.character(sf$name[x]))

mapKey <- "map_api_key"

google_map(key = mapKey) %>%
add_markers(data = x, info_window = "neighbourhood")

Sample Image


Further Reading

  • Simple features vignette

Can I get place details against a coordinate for free?? Geocoding/Reverse Geocoding Api is not free?

I finally got this, this API is free and unlimited on client side application based on the user current location getting from (GeoLocation.getCurrentPosition Method).

https://www.bigdatacloud.com/geocoding-apis/free-reverse-geocode-to-city-api

Read their terms and conditions must.

How can I extract the zip code from the ggmap output?

I don't have an API key, but try something like the following:

my_func <- function(longlat, output){
list(list(list(c(vector("list", 7), list(12345L)))))
}

test %>%
rowwise() %>%
mutate(zip = list(my_func(c(pickup_longitude, pickup_latitude), output = "all"))) %>%
mutate(zip = zip[[1]][[1]],
zip = zip[[8]])

Replace my_func with revgeocode . You'll have to figure out exactly how to pick out the zip code from the output. But you can try something like the above.



Related Topics



Leave a reply



Submit