class Geokit::Geocoders::Geocoder
The Geocoder
base class which defines the interface to be used by all other geocoders.
Public Class Methods
Main method which calls the do_geocode template method which subclasses are responsible for implementing. Returns a populated GeoLoc
or an empty one with a failed success code.
# File lib/geokit/geocoders.rb, line 90 def self.geocode(address, *args) logger.debug "#{provider_name} geocoding. address: #{address}, args #{args}" do_geocode(address, *args) || GeoLoc.new rescue TooManyQueriesError, GeocodeError, AccessDeniedError raise rescue => e logger.error "Caught an error during #{provider_name} geocoding call: #{$!}" logger.error e.backtrace.join("\n") GeoLoc.new end
Main method which calls the do_reverse_geocode
template method which subclasses are responsible for implementing. Returns a populated GeoLoc
or an empty one with a failed success code.
# File lib/geokit/geocoders.rb, line 103 def self.reverse_geocode(latlng, *args) logger.debug "#{provider_name} geocoding. latlng: #{latlng}, args #{args}" do_reverse_geocode(latlng, *args) || GeoLoc.new end
Protected Class Methods
# File lib/geokit/geocoders.rb, line 110 def self.logger Geokit::Geocoders.logger end
Private Class Methods
Call the geocoder service using the timeout if configured.
# File lib/geokit/geocoders.rb, line 141 def self.call_geocoder_service(url) Timeout.timeout(Geokit::Geocoders.request_timeout) { return do_get(url) } if Geokit::Geocoders.request_timeout do_get(url) rescue Timeout::Error nil end
# File lib/geokit/geocoders.rb, line 116 def self.config(*attrs) attrs.each do |attr| class_eval <<-METHOD @@#{attr} = nil def self.#{attr}=(value) @@#{attr} = value end def self.#{attr} @@#{attr} end METHOD end end
Wraps the geocoder call around a proxy if necessary.
# File lib/geokit/geocoders.rb, line 164 def self.do_get(url) net_adapter.do_get(url) end
Not all geocoders can do reverse geocoding. So, unless the subclass explicitly overrides this method, a call to reverse_geocode
will return an empty GeoLoc
. If you happen to be using MultiGeocoder
, this will cause it to failover to the next geocoder, which will hopefully be one which supports reverse geocoding.
# File lib/geokit/geocoders.rb, line 151 def self.do_reverse_geocode(_latlng) GeoLoc.new end
# File lib/geokit/geocoders.rb, line 130 def self.inherited(base) base.config :secure end
# File lib/geokit/geocoders.rb, line 168 def self.net_adapter Geokit::Geocoders.net_adapter end
# File lib/geokit/geocoders.rb, line 134 def self.new_loc loc = GeoLoc.new loc.provider = Geokit::Inflector.underscore(provider_name) loc end
# File lib/geokit/geocoders.rb, line 176 def self.parse(format, body, *args) logger.debug "#{provider_name} geocoding. Result: #{CGI.escape(body)}" case format when :json then parse_json(JSON.load(body), *args) when :xml then parse_xml(REXML::Document.new(body), *args) when :yaml then parse_yaml(YAML.load(body), *args) when :csv then parse_csv(body.chomp.split(','), *args) end end
# File lib/geokit/geocoders.rb, line 192 def self.process(format, url, *args) res = call_geocoder_service(url) return GeoLoc.new unless net_adapter.success?(res) parse format, res.body, *args end
# File lib/geokit/geocoders.rb, line 159 def self.protocol use_https? ? 'https' : 'http' end
# File lib/geokit/geocoders.rb, line 172 def self.provider_name name.split('::').last.gsub(/Geocoder$/, '') end
# File lib/geokit/geocoders.rb, line 186 def self.set_mappings(loc, xml, mappings) mappings.each_pair do |field, xml_field| loc.send("#{field}=", xml.elements[xml_field].try(:text)) end end
# File lib/geokit/geocoders.rb, line 155 def self.use_https? secure && Geokit::Geocoders.secure end