Class: Graticule::Geocoder::Multi
- Inherits:
-
Object
- Object
- Graticule::Geocoder::Multi
- Defined in:
- lib/graticule/geocoder/multi.rb
Defined Under Namespace
Classes: ParallelLookup, SerialLookup
Instance Method Summary collapse
-
#initialize(*geocoders, &acceptable) ⇒ Multi
constructor
The Multi geocoder allows you to use multiple geocoders in succession.
- #locate(address) ⇒ Object
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
Use the :timeout option to specify the number of seconds to allow for each geocoder before raising a Timout::Error (defaults to 10 seconds).
Graticule.service(:multi).new(geocoders, :timeout => 3)
32 33 34 35 36 |
# File 'lib/graticule/geocoder/multi.rb', line 32 def initialize(*geocoders, &acceptable) @options = {:timeout => 10, :async => false}.merge(geocoders.) @acceptable = acceptable || Proc.new { true } @geocoders = geocoders end |
Instance Method Details
#locate(address) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/graticule/geocoder/multi.rb', line 38 def locate(address) @lookup = @options[:async] ? ParallelLookup.new : SerialLookup.new last_error = nil @geocoders.each do |geocoder| @lookup.perform do begin result = nil Timeout.timeout(@options[:timeout]) do result = geocoder.locate address end result if @acceptable.call(result) rescue => e last_error = e nil end end end @lookup.result || raise(last_error || AddressError.new("Couldn't find '#{address}' with any of the services")) end |