lib/geokit/geocoders.rb in andre-geokit-1.4.0 vs lib/geokit/geocoders.rb in andre-geokit-1.4.1

- old
+ new

@@ -3,10 +3,13 @@ require 'yaml' require 'timeout' require 'logger' module Geokit + + class TooManyQueriesError < StandardError; end + module Inflector extend self def titleize(word) @@ -65,11 +68,11 @@ module Geocoders @@proxy_addr = nil @@proxy_port = nil @@proxy_user = nil @@proxy_pass = nil - @@timeout = nil + @@request_timeout = nil @@yahoo = 'REPLACE_WITH_YOUR_YAHOO_KEY' @@google = 'REPLACE_WITH_YOUR_GOOGLE_KEY' @@geocoder_us = false @@geocoder_ca = false @@geonames = false @@ -79,11 +82,11 @@ @@logger.level=Logger::INFO @@domain = nil def self.__define_accessors class_variables.each do |v| - sym = v.delete("@").to_sym + sym = v.to_s.delete("@").to_sym unless self.respond_to? sym module_eval <<-EOS, __FILE__, __LINE__ def self.#{sym} value = if defined?(#{sym.to_s.upcase}) #{sym.to_s.upcase} @@ -131,11 +134,11 @@ return res.success? ? res : GeoLoc.new end # Call the geocoder service using the timeout if configured. def self.call_geocoder_service(url) - timeout(Geokit::Geocoders::timeout) { return self.do_get(url) } if Geokit::Geocoders::timeout + Timeout::timeout(Geokit::Geocoders::request_timeout) { return self.do_get(url) } if Geokit::Geocoders::request_timeout return self.do_get(url) rescue TimeoutError return nil end @@ -160,12 +163,11 @@ req = Net::HTTP::Get.new(url) req.basic_auth(uri.user, uri.password) if uri.userinfo res = Net::HTTP::Proxy(GeoKit::Geocoders::proxy_addr, GeoKit::Geocoders::proxy_port, GeoKit::Geocoders::proxy_user, - GeoKit::Geocoders::proxy_pass).start(uri.host, uri.port) { |http| http.request(req) } - + GeoKit::Geocoders::proxy_pass).start(uri.host, uri.port) { |http| http.get(uri.path + "?" + uri.query) } return res end # Adds subclass' geocode method making it conveniently available through # the base class. @@ -461,18 +463,23 @@ # geolocs onto "geoloc.all" geoloc.all.push(extracted_geoloc) end end return geoloc - else + elsif doc.elements['//kml/Response/Status/code'].text == '620' + raise Geokit::TooManyQueriesError + else logger.info "Google was unable to geocode address: "+address return GeoLoc.new end - rescue - logger.error "Caught an error during Google geocoding call: "+$! - return GeoLoc.new + rescue Geokit::TooManyQueriesError + # re-raise because of other rescue + raise Geokit::TooManyQueriesError, "Google returned a 620 status, too many queries. The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly." + rescue + logger.error "Caught an error during Google geocoding call: "+$! + return GeoLoc.new end # extracts a single geoloc from a //placemark element in the google results xml def self.extract_placemark(doc) res = GeoLoc.new @@ -485,13 +492,16 @@ res.provider='google' #extended -- false if not not available res.city = doc.elements['.//LocalityName'].text if doc.elements['.//LocalityName'] res.state = doc.elements['.//AdministrativeAreaName'].text if doc.elements['.//AdministrativeAreaName'] + res.province = doc.elements['.//SubAdministrativeAreaName'].text if doc.elements['.//SubAdministrativeAreaName'] res.full_address = doc.elements['.//address'].text if doc.elements['.//address'] # google provides it res.zip = doc.elements['.//PostalCodeNumber'].text if doc.elements['.//PostalCodeNumber'] res.street_address = doc.elements['.//ThoroughfareName'].text if doc.elements['.//ThoroughfareName'] + res.country = doc.elements['.//CountryName'].text if doc.elements['.//CountryName'] + res.district = doc.elements['.//DependentLocalityName'].text if doc.elements['.//DependentLocalityName'] # Translate accuracy into Yahoo-style token address, street, zip, zip+4, city, state, country # For Google, 1=low accuracy, 8=high accuracy address_details=doc.elements['.//*[local-name() = "AddressDetails"]'] res.accuracy = address_details ? address_details.attributes['Accuracy'].to_i : 0 res.precision=%w{unknown country state state city zip zip+4 street address building}[res.accuracy] @@ -502,11 +512,11 @@ [suggested_bounds.attributes['south'], suggested_bounds.attributes['west']], [suggested_bounds.attributes['north'], suggested_bounds.attributes['east']]) end res.success=true - - return res + + return res end end # -------------------------------------------------------------------------------------------