class Geokit::Geocoders::MultiGeocoder
Provides methods to geocode with a variety of geocoding service providers, plus failover among providers in the order you configure. When 2nd parameter is set 'true', perform ip location lookup with 'address' as the ip address.
Goal:
-
homogenize the results of multiple geocoders
Limitations:
-
currently only provides the first result. Sometimes geocoders will return multiple results.
-
currently discards the “accuracy” component of the geocoding calls
Private Class Methods
This method will call one or more geocoders in the order specified in the configuration until one of the geocoders work.
The failover approach is crucial for production-grade apps, but is rarely used. 98% of your geocoding calls will be successful with the first call
# File lib/geokit/multi_geocoder.rb, line 28 def self.do_geocode(address, *args) provider_order = provider_order_for(address, args) provider_order.each do |provider| klass = geocoder(provider) begin res = klass.send :geocode, address, *args return res if res.success? rescue => e logger.error("An error has occurred during geocoding: #{e}\n" \ "Address: #{address}. Provider: #{provider}") end end # If we get here, we failed completely. GeoLoc.new end
This method will call one or more geocoders in the order specified in the configuration until one of the geocoders work, only this time it's going to try to reverse geocode a geographical point.
# File lib/geokit/multi_geocoder.rb, line 48 def self.do_reverse_geocode(latlng, *args) provider_order = provider_order_for(latlng, args) provider_order.each do |provider| klass = geocoder(provider) begin res = klass.send :reverse_geocode, latlng return res if res.success? rescue => e logger.error("An error has occurred during geocoding: #{e}\n" \ "Latlng: #{latlng}. Provider: #{provider}") end end # If we get here, we failed completely. GeoLoc.new end
# File lib/geokit/multi_geocoder.rb, line 65 def self.geocoder(provider) class_name = "#{Geokit::Inflector.camelize(provider.to_s)}Geocoder" Geokit::Geocoders.const_get class_name end
# File lib/geokit/multi_geocoder.rb, line 70 def self.provider_order_for(address, args) if args.last.is_a?(Hash) && args.last.key?(:provider_order) args.last.delete(:provider_order) else if address.is_a?(String) && /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.match(address) Geokit::Geocoders.ip_provider_order else Geokit::Geocoders.provider_order end end end