Fast Reverse Geocoding Using R and a Local PostGIS Database

Most states like New York have Street Address Management system where you can download every address in the state as a Shapefile then upload it to a locally running PostGIS database.

library(tidyverse)
library(RPostgreSQL)
library(sf)

con <- DBI::dbConnect(RPostgres::Postgres(), dbname='gis', host='localhost', 
                      port=5432, user='postgres', password='xxxxx')

# function that uses PostGIS query to return the closest
# point in the SAM database
reverseGeocode <- function(geom) {
  # convert sf geom object to text
  geom <- st_as_text(geom)
  
  # query
  sql <- str_c("
SELECT 
  *,
  \"Shape\" <-> 'SRID=26918;", geom, "'::geometry AS dist
FROM
  nys_sam_points
ORDER BY
  dist
LIMIT 1;")
  
  query <- dbGetQuery(con, sql)
  
  str_c(query$addresslabel, 
        ', ',
        query$citytownname,
        ', NY ',
        query$zipcode
        ) %>% return
}

# obtain centroids for each county
ny.county.centroids <- tigris::county_subdivisions('ny') %>% 
  st_centroid()

# get addresses of properties by reverse gecoding
ny.county.centroids %>%
  st_transform(26918) %>%   # use same projection 
                            # as your postgis database
  mutate(
    # obtain address using purr and map_chr using the 
    # reverseGeocode Function defined above
    Address = map_chr(geometry, reverseGeocode)
  )

Leave a Reply

Your email address will not be published. Required fields are marked *