Get address from Geocode latitude and longitude

Learn get address from geocode latitude and longitude with practical examples, diagrams, and best practices. Covers ruby-on-rails, ruby, geocoding development techniques with visual explanations.

Reverse Geocoding in Ruby on Rails: From Lat/Lon to Address

Hero image for Get address from Geocode latitude and longitude

Learn how to convert geographic coordinates (latitude and longitude) into human-readable street addresses using the Geocoder gem in your Ruby on Rails application.

Geocoding is the process of converting addresses (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (like 37.423021, -122.083739). Reverse geocoding is the opposite: converting geographic coordinates into a human-readable address. This functionality is crucial for many applications, from displaying user locations on a map to providing location-based services. In Ruby on Rails, the geocoder gem simplifies this process significantly, abstracting away the complexities of interacting with various geocoding APIs.

Setting Up the Geocoder Gem

Before you can perform reverse geocoding, you need to add the geocoder gem to your Rails project and configure it. This gem provides a unified interface for various geocoding services, including Google Geocoding API, OpenStreetMap, and others. For this article, we'll focus on using Google Geocoding API, which often requires an API key for production use and higher request limits.

gem 'geocoder'

Add the geocoder gem to your Gemfile

After adding the gem, run bundle install to install it. Next, you'll want to configure geocoder. The gem can be configured globally in an initializer file. This is where you'd specify your geocoding service and any necessary API keys.

# config/initializers/geocoder.rb
Geocoder.configure(
  # Geocoding service (e.g., :google, :nominatim, :mapbox)
  :lookup    => :google,

  # API key for geocoding service
  :api_key   => ENV['GOOGLE_GEOCODING_API_KEY'],

  # Geocoding service request timeout (in seconds)
  :timeout   => 3,

  # Use HTTPS for geocoding service requests
  :use_https => true,

  # Set default language for results (e.g., :en, :es, :fr)
  :language  => :en,

  # Cache geocoded results (optional, but recommended for performance)
  # :cache => Redis.new
)

Example Geocoder configuration in an initializer

Performing Reverse Geocoding

Once configured, performing reverse geocoding is straightforward. The geocoder gem provides a Geocoder.search method that can accept either an address string (for forward geocoding) or an array of [latitude, longitude] (for reverse geocoding). It returns an array of Geocoder::Result objects, which contain detailed information about the location.

flowchart TD
    A[Start] --> B{Input: Latitude, Longitude}
    B --> C[Call Geocoder.search([lat, lon])]
    C --> D{Geocoding Service API}
    D --> E[Receive Geocoding Results]
    E --> F{Extract Address Components}
    F --> G[Display/Use Address]
    G --> H[End]

Reverse Geocoding Process Flow

# Example: Reverse geocoding coordinates for the Eiffel Tower
latitude = 48.8584
longitude = 2.2945

results = Geocoder.search([latitude, longitude])

if results.any?
  first_result = results.first
  puts "Full Address: #{first_result.address}"
  puts "City: #{first_result.city}"
  puts "State: #{first_result.state}"
  puts "Country: #{first_result.country}"
  puts "Postal Code: #{first_result.postal_code}"
else
  puts "No address found for these coordinates."
end

Ruby code to perform reverse geocoding

The Geocoder::Result object provides various helper methods to access specific parts of the address, such as city, state, country, postal_code, and more. The address method typically returns the full formatted address string.

Integrating with Rails Models

The geocoder gem can also be integrated directly into your Rails models. This is particularly useful if you have models that store location data (e.g., User, Event, Location). You can configure a model to automatically geocode or reverse geocode based on its attributes.

# app/models/location.rb
class Location < ApplicationRecord
  geocoded_by :address
  reverse_geocoded_by :latitude, :longitude do |obj,results|
    if geo = results.first
      obj.address      = geo.address
      obj.city         = geo.city
      obj.state        = geo.state
      obj.country      = geo.country
      obj.postal_code  = geo.postal_code
    end
  end
  after_validation :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }
  after_validation :reverse_geocode, if: ->(obj){ obj.latitude.present? and obj.longitude.present? and (obj.latitude_changed? || obj.longitude_changed?) }
end

Integrating reverse geocoding into a Rails model

In this example, the Location model will automatically attempt to reverse geocode its latitude and longitude attributes into an address, city, state, country, and postal_code whenever those coordinate attributes change. Similarly, it will forward geocode an address into latitude and longitude.