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 87 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 100 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 107 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 138 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 TimeoutError nil end
# File lib/geokit/geocoders.rb, line 113 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 161 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 148 def self.do_reverse_geocode(latlng) GeoLoc.new end
# File lib/geokit/geocoders.rb, line 127 def self.inherited(base) base.config :secure end
# File lib/geokit/geocoders.rb, line 165 def self.net_adapter Geokit::Geocoders.net_adapter end
# File lib/geokit/geocoders.rb, line 131 def self.new_loc loc = GeoLoc.new loc.provider = Geokit::Inflector.underscore(provider_name) loc end
# File lib/geokit/geocoders.rb, line 173 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 189 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 156 def self.protocol use_https? ? "https" : "http" end
# File lib/geokit/geocoders.rb, line 169 def self.provider_name name.split("::").last.gsub(/Geocoder$/, "") end
# File lib/geokit/geocoders.rb, line 183 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 195 def self.transcode_to_utf8(body) require "iconv" unless String.method_defined?(:encode) if String.method_defined?(:encode) body.encode!("UTF-8", "UTF-8", invalid: :replace) else ic = Iconv.new("UTF-8", "UTF-8//IGNORE") ic.iconv(body) end end
# File lib/geokit/geocoders.rb, line 152 def self.use_https? secure && Geokit::Geocoders.secure end