Class: RailsGoogleMap::Geocoder

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_google_map/geocoder.rb,
sig/rails_google_map.rbs

Overview

Converts a free-text address into lat/lng coordinates using the Google Geocoding API. Useful if you want to build a custom map (with markers, info windows, etc.) using the Maps JavaScript API instead of the simple embed iframe. Unlike the view helpers, this always needs an API key.

Defined Under Namespace

Classes: GeocodeError

Constant Summary collapse

GEOCODE_URL =

Returns:

  • (String)
"https://maps.googleapis.com/maps/api/geocode/json"

Class Method Summary collapse

Class Method Details

.coordinates_for(address, api_key: nil) ⇒ { lat: Float, lng: Float }

Returns { lat: Float, lng: Float } for address. Raises ConfigurationError without an API key, GeocodeError on failure.

Parameters:

  • address (Object)
  • api_key: (String, nil) (defaults to: nil)

Returns:

  • ({ lat: Float, lng: Float })

Raises:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rails_google_map/geocoder.rb', line 19

def self.coordinates_for(address, api_key: nil)
  key = api_key || RailsGoogleMap.configuration.api_key
  if key.nil? || key.to_s.strip.empty?
    raise ConfigurationError,
          "RailsGoogleMap.configuration.api_key is not set; geocoding requires an API key."
  end

  raise GeocodeError, "Cannot geocode a blank address." if address.to_s.strip.empty?

  uri = URI(GEOCODE_URL)
  uri.query = URI.encode_www_form(address: address.to_s, key: key)

  response = Net::HTTP.get_response(uri)
  unless response.is_a?(Net::HTTPSuccess)
    raise GeocodeError, "HTTP error while geocoding: #{response.code}"
  end

  data = JSON.parse(response.body)
  unless data["status"] == "OK"
    raise GeocodeError, "Geocoding failed for #{address.inspect}: #{data['status']}"
  end

  location = data.dig("results", 0, "geometry", "location")
  raise GeocodeError, "Geocoding returned no coordinates for #{address.inspect}." if location.nil?

  { lat: location["lat"], lng: location["lng"] }
end