Class: Graticule::Geocoder::Multi

Inherits:
Object
  • Object
show all
Defined in:
lib/graticule/geocoder/multi.rb

Instance Method Summary collapse

Constructor Details

#initialize(*geocoders, &acceptable) ⇒ Multi

The Multi geocoder allows you to use multiple geocoders in succession.

geocoder = Graticule.service(:multi).new(
  Graticule.service(:google).new("api_key"),
  Graticule.service(:yahoo).new("api_key"),
)
geocoder.locate '49423' # <= tries geocoders in succession

The Multi geocoder will try the geocoders in order if a Graticule::AddressError is raised. You can customize this behavior by passing in a block to the Multi geocoder. For example, to try the geocoders until one returns a result with a high enough precision:

geocoder = Graticule.service(:multi).new(geocoders) do |result|
  [:address, :street].include?(result.precision)
end

Geocoders will be tried in order until the block returned true for one of the results



24
25
26
27
# File 'lib/graticule/geocoder/multi.rb', line 24

def initialize(*geocoders, &acceptable)
  @acceptable = acceptable || lambda { true }
  @geocoders = geocoders.flatten
end

Instance Method Details

#locate(address) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/graticule/geocoder/multi.rb', line 29

def locate(address)
  last_error = nil
  @geocoders.each do |geocoder|
    begin
      result = geocoder.locate address
      return result if @acceptable.call(result)
    rescue Error => e
      last_error = e
    rescue Errno::ECONNREFUSED
      logger.error("Connection refused to #{service}")
    end
  end
  raise last_error || AddressError.new("Couldn't find '#{address}' with any of the services")
end