diff --git a/lib/geocoder.rb b/lib/geocoder.rb
index 196cf75dede7e6339705c5d017ca84e1c8b282db..4019e84523f5f00a5ab6e31aebd233804ba5743d 100644
--- a/lib/geocoder.rb
+++ b/lib/geocoder.rb
@@ -1,8 +1,10 @@
require "geocoder/configuration"
+require "geocoder/query"
require "geocoder/calculations"
require "geocoder/exceptions"
require "geocoder/cache"
require "geocoder/request"
+require "geocoder/lookup"
require "geocoder/models/active_record" if defined?(::ActiveRecord)
require "geocoder/models/mongoid" if defined?(::Mongoid)
require "geocoder/models/mongo_mapper" if defined?(::MongoMapper)
@@ -13,15 +15,16 @@ module Geocoder
##
# Search for information about an address or a set of coordinates.
#
- def search(query)
- blank_query?(query) ? [] : lookup(query).search(query)
+ def search(query, options = {})
+ query = Geocoder::Query.new(query, options) unless query.is_a?(Geocoder::Query)
+ query.blank? ? [] : query.execute
end
##
# Look up the coordinates of the given street or IP address.
#
- def coordinates(address)
- if (results = search(address)).size > 0
+ def coordinates(address, options = {})
+ if (results = search(address, options)).size > 0
results.first.coordinates
end
end
@@ -30,8 +33,8 @@ module Geocoder
# Look up the address of the given coordinates ([lat,lon])
# or IP address (string).
#
- def address(query)
- if (results = search(query)).size > 0
+ def address(query, options = {})
+ if (results = search(query, options)).size > 0
results.first.address
end
end
@@ -45,92 +48,6 @@ module Geocoder
end
@cache
end
-
- ##
- # Array of valid Lookup names.
- #
- def valid_lookups
- street_lookups + ip_lookups
- end
-
- ##
- # Array of valid Lookup names, excluding :test.
- #
- def valid_lookups_except_test
- valid_lookups - [:test]
- end
-
- ##
- # All street address lookups, default first.
- #
- def street_lookups
- [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex, :nominatim, :mapquest, :test]
- end
-
- ##
- # All IP address lookups, default first.
- #
- def ip_lookups
- [:freegeoip]
- end
-
-
- private # -----------------------------------------------------------------
-
- ##
- # Get a Lookup object (which communicates with the remote geocoding API).
- # Takes a search query and returns an IP or street address Lookup
- # depending on the query contents.
- #
- def lookup(query)
- if ip_address?(query)
- get_lookup(Configuration.ip_lookup || ip_lookups.first)
- else
- get_lookup(Configuration.lookup || street_lookups.first)
- end
- end
-
- ##
- # Retrieve a Lookup object from the store.
- #
- def get_lookup(name)
- @lookups = {} unless defined?(@lookups)
- @lookups[name] = spawn_lookup(name) unless @lookups.include?(name)
- @lookups[name]
- end
-
- ##
- # Spawn a Lookup of the given name.
- #
- def spawn_lookup(name)
- if valid_lookups.include?(name)
- name = name.to_s
- require "geocoder/lookups/#{name}"
- klass = name.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
- Geocoder::Lookup.const_get(klass).new
- else
- valids = valid_lookups.map(&:inspect).join(", ")
- raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
- "(#{name.inspect} is not one of: #{valids})."
- end
- end
-
- ##
- # Does the given value look like an IP address?
- #
- # Does not check for actual validity, just the appearance of four
- # dot-delimited numbers.
- #
- def ip_address?(value)
- !!value.to_s.match(/^(::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)
- end
-
- ##
- # Is the given search query blank? (ie, should we not bother searching?)
- #
- def blank_query?(value)
- !!value.to_s.match(/^\s*$/)
- end
end
# load Railtie if Rails exists
diff --git a/lib/geocoder/cli.rb b/lib/geocoder/cli.rb
index 9a7fa13b0d6aad7fb546f09782df6da38f2f81e3..a5648631b10babc22c8583a8f52257cbcc9c8e0e 100644
--- a/lib/geocoder/cli.rb
+++ b/lib/geocoder/cli.rb
@@ -32,8 +32,8 @@ module Geocoder
Geocoder::Configuration.http_proxy = proxy
end
- opts.on("-s <service>", Geocoder.valid_lookups_except_test, "--service <service>",
- "Geocoding service: #{Geocoder.valid_lookups_except_test * ', '}") do |service|
+ opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
+ "Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
Geocoder::Configuration.lookup = service.to_sym
Geocoder::Configuration.ip_lookup = service.to_sym
end
@@ -93,7 +93,7 @@ module Geocoder
end
if (result = Geocoder.search(query).first)
- lookup = Geocoder.send(:get_lookup, :google)
+ lookup = Geocoder::Lookup.get(:google)
lines = [
["Latitude", result.latitude],
["Longitude", result.longitude],
diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..11d0a8a20d5fac110f3516c2791479aced6b176b
--- /dev/null
+++ b/lib/geocoder/lookup.rb
@@ -0,0 +1,62 @@
+module Geocoder
+ module Lookup
+
+ ##
+ # Array of valid Lookup service names.
+ #
+ def self.all_services
+ street_services + ip_services
+ end
+
+ ##
+ # Array of valid Lookup service names, excluding :test.
+ #
+ def self.all_services_except_test
+ all_services - [:test]
+ end
+
+ ##
+ # All street address lookup services, default first.
+ #
+ def self.street_services
+ [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex, :nominatim, :mapquest, :test]
+ end
+
+ ##
+ # All IP address lookup services, default first.
+ #
+ def self.ip_services
+ [:freegeoip]
+ end
+
+ ##
+ # Retrieve a Lookup object from the store.
+ # Use this instead of Geocoder::Lookup::X.new to get an
+ # already-configured Lookup object.
+ #
+ def self.get(name)
+ @services = {} unless defined?(@services)
+ @services[name] = spawn(name) unless @services.include?(name)
+ @services[name]
+ end
+
+
+ private # -----------------------------------------------------------------
+
+ ##
+ # Spawn a Lookup of the given name.
+ #
+ def self.spawn(name)
+ if all_services.include?(name)
+ name = name.to_s
+ require "geocoder/lookups/#{name}"
+ klass = name.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
+ Geocoder::Lookup.const_get(klass).new
+ else
+ valids = all_services.map(&:inspect).join(", ")
+ raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
+ "(#{name.inspect} is not one of: #{valids})."
+ end
+ end
+ end
+end
diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index 3665e954b51dfded0e8576335bf0f4c851a10645..a770f97f11546f5519bab2ca1dc8cc8da97e8e33 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -13,6 +13,7 @@ end
module Geocoder
module Lookup
+
class Base
##
@@ -23,18 +24,9 @@ module Geocoder
# "205.128.54.202") for geocoding, or coordinates (latitude, longitude)
# for reverse geocoding. Returns an array of <tt>Geocoder::Result</tt>s.
#
- def search(query)
-
- # if coordinates given as string, turn into array
- query = query.split(/\s*,\s*/) if coordinates?(query)
-
- if query.is_a?(Array)
- reverse = true
- query = query.join(',')
- else
- reverse = false
- end
- results(query, reverse).map{ |r|
+ def search(query, options = {})
+ query = Geocoder::Query.new(query, options) unless query.is_a?(Geocoder::Query)
+ results(query).map{ |r|
result = result_class.new(r)
result.cache_hit = @cache_hit if cache
result
@@ -77,14 +69,14 @@ module Geocoder
##
# Geocoder::Result object or nil on timeout or other error.
#
- def results(query, reverse = false)
+ def results(query)
fail
end
##
# URL to use for querying the geocoding engine.
#
- def query_url(query, reverse = false)
+ def query_url(query)
fail
end
@@ -111,8 +103,8 @@ module Geocoder
##
# Returns a parsed search result (Ruby hash).
#
- def fetch_data(query, reverse = false)
- parse_raw_data fetch_raw_data(query, reverse)
+ def fetch_data(query)
+ parse_raw_data fetch_raw_data(query)
rescue SocketError => err
raise_error(err) or warn "Geocoding API connection cannot be established."
rescue TimeoutError => err
@@ -144,9 +136,9 @@ module Geocoder
##
# Fetches a raw search result (JSON string).
#
- def fetch_raw_data(query, reverse = false)
+ def fetch_raw_data(query)
timeout(Geocoder::Configuration.timeout) do
- url = query_url(query, reverse)
+ url = query_url(query)
uri = URI.parse(url)
if cache and body = cache[url]
@cache_hit = true
@@ -171,20 +163,6 @@ module Geocoder
Geocoder.cache
end
- ##
- # Is the given string a loopback IP address?
- #
- def loopback_address?(ip)
- !!(ip == "0.0.0.0" or ip.to_s.match(/^127/))
- end
-
- ##
- # Does the given string look like latitude/longitude coordinates?
- #
- def coordinates?(value)
- value.is_a?(String) and !!value.to_s.match(/^-?[0-9\.]+, *-?[0-9\.]+$/)
- end
-
##
# Simulate ActiveSupport's Object#to_query.
# Removes any keys with nil value.
diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb
index 2bec5a4f1ec09a6443692b8a1fc356fe42dbbdfe..a5d254c36fd52c85024656aacb300b0aedc2a038 100644
--- a/lib/geocoder/lookups/bing.rb
+++ b/lib/geocoder/lookups/bing.rb
@@ -10,8 +10,8 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
if doc['statusDescription'] == "OK"
return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : []
@@ -21,12 +21,12 @@ module Geocoder::Lookup
end
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {:key => Geocoder::Configuration.api_key}
- params[:query] = query unless reverse
+ params[:query] = query.sanitized_text unless query.reverse_geocode?
base_url = "http://dev.virtualearth.net/REST/v1/Locations"
- url_tail = reverse ? "/#{query}?" : "?"
+ url_tail = query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?"
base_url + url_tail + hash_to_query(params)
end
end
diff --git a/lib/geocoder/lookups/freegeoip.rb b/lib/geocoder/lookups/freegeoip.rb
index a5526667cd343808446934a627d3d8f6c0dee102..a3f6dc91a6662cf40ccc0a37a2461f822975ab0c 100644
--- a/lib/geocoder/lookups/freegeoip.rb
+++ b/lib/geocoder/lookups/freegeoip.rb
@@ -10,11 +10,11 @@ module Geocoder::Lookup
raw_data.match(/^<html><title>404/) ? nil : super(raw_data)
end
- def results(query, reverse = false)
+ def results(query)
# don't look up a loopback address, just return the stored result
- return [reserved_result(query)] if loopback_address?(query)
+ return [reserved_result(query)] if query.loopback_ip_address?
begin
- return (doc = fetch_data(query, reverse)) ? [doc] : []
+ return (doc = fetch_data(query)) ? [doc] : []
rescue StandardError => err # Freegeoip.net returns HTML on bad request
raise_error(err)
return []
@@ -36,8 +36,8 @@ module Geocoder::Lookup
}
end
- def query_url(query, reverse = false)
- "http://freegeoip.net/json/#{query}"
+ def query_url(query)
+ "http://freegeoip.net/json/#{query.sanitized_text}"
end
end
end
diff --git a/lib/geocoder/lookups/geocoder_ca.rb b/lib/geocoder/lookups/geocoder_ca.rb
index 32ea293ab6af7388b0484fd1676ee3af9f57f6ab..379d0fd40c53a123d74a3b6d08d5f4d6c0a9079a 100644
--- a/lib/geocoder/lookups/geocoder_ca.rb
+++ b/lib/geocoder/lookups/geocoder_ca.rb
@@ -6,8 +6,8 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
if doc['error'].nil?
return [doc]
elsif doc['error']['code'] == "005"
@@ -18,21 +18,21 @@ module Geocoder::Lookup
return []
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
:geoit => "xml",
:jsonp => 1,
:callback => "test",
:auth => Geocoder::Configuration.api_key
}
- if reverse
- lat,lon = query.split(',')
+ if query.reverse_geocode?
+ lat,lon = query.coordinates
params[:latt] = lat
params[:longt] = lon
params[:corner] = 1
params[:reverse] = 1
else
- params[:locate] = query
+ params[:locate] = query.sanitized_text
params[:showpostal] = 1
end
"http://geocoder.ca/?" + hash_to_query(params)
diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb
index 6898c267551bc056834cf7969fda1bb7fa46f4a3..ed7f1cd3aadbbb161c03eca6a0d16242b5d995d4 100644
--- a/lib/geocoder/lookups/google.rb
+++ b/lib/geocoder/lookups/google.rb
@@ -10,8 +10,8 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
case doc['status']; when "OK" # OK status implies >0 results
return doc['results']
when "OVER_QUERY_LIMIT"
@@ -27,9 +27,9 @@ module Geocoder::Lookup
return []
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
- (reverse ? :latlng : :address) => query,
+ (query.reverse_geocode? ? :latlng : :address) => query.sanitized_text,
:sensor => "false",
:language => Geocoder::Configuration.language,
:key => Geocoder::Configuration.api_key
diff --git a/lib/geocoder/lookups/google_premier.rb b/lib/geocoder/lookups/google_premier.rb
index 6befdddf585167868fcdbb58a042f0ea8175ea6d..14cbdac8ee911cf268901d6fa78457d71d85ce25 100644
--- a/lib/geocoder/lookups/google_premier.rb
+++ b/lib/geocoder/lookups/google_premier.rb
@@ -8,9 +8,9 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
- (reverse ? :latlng : :address) => query,
+ (query.reverse_geocode? ? :latlng : :address) => query.sanitized_text,
:sensor => 'false',
:language => Geocoder::Configuration.language,
:client => Geocoder::Configuration.api_key[1],
diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb
index 08cd31d8de0d33d19d985188ddff854311fd17f3..08bdaaebd2e5701c0f0c8aa9da3d34704048934e 100644
--- a/lib/geocoder/lookups/mapquest.rb
+++ b/lib/geocoder/lookups/mapquest.rb
@@ -6,26 +6,26 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
doc.is_a?(Array) ? doc : [doc]
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
:format => "json",
:polygon => "1",
:addressdetails => "1",
:"accept-language" => Geocoder::Configuration.language
}
- if (reverse)
+ if (query.reverse_geocode?)
method = 'reverse'
- parts = query.split(/\s*,\s*/);
- params[:lat] = parts[0]
- params[:lon] = parts[1]
+ lat,lon = query.coordinates
+ params[:lat] = lat
+ params[:lon] = lon
else
method = 'search'
- params[:q] = query
+ params[:q] = query.sanitized_text
end
"http://open.mapquestapi.com/#{method}?" + hash_to_query(params)
end
diff --git a/lib/geocoder/lookups/nominatim.rb b/lib/geocoder/lookups/nominatim.rb
index 12f2c1513879cb87346341c96b2aa92f30cab9bf..4ded59b19614740db2f3507c2ab980416834cf1b 100644
--- a/lib/geocoder/lookups/nominatim.rb
+++ b/lib/geocoder/lookups/nominatim.rb
@@ -10,26 +10,26 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
doc.is_a?(Array) ? doc : [doc]
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
:format => "json",
:polygon => "1",
:addressdetails => "1",
:"accept-language" => Geocoder::Configuration.language
}
- if (reverse)
+ if (query.reverse_geocode?)
method = 'reverse'
- parts = query.split(/\s*,\s*/);
- params[:lat] = parts[0]
- params[:lon] = parts[1]
+ lat,lon = query.coordinates
+ params[:lat] = lat
+ params[:lon] = lon
else
method = 'search'
- params[:q] = query
+ params[:q] = query.sanitized_text
end
"http://nominatim.openstreetmap.org/#{method}?" + hash_to_query(params)
end
diff --git a/lib/geocoder/lookups/test.rb b/lib/geocoder/lookups/test.rb
index e06171c9dbc96a4ce03a54b2832c7262efa95b33..89aa97f4445d7d65c75caea6b0fe6d67c3d75dbe 100644
--- a/lib/geocoder/lookups/test.rb
+++ b/lib/geocoder/lookups/test.rb
@@ -5,12 +5,14 @@ module Geocoder
module Lookup
class Test < Base
- def self.add_stub(query, results)
- stubs[query] = results
+ def self.add_stub(query_text, results)
+ stubs[query_text] = results
end
- def self.read_stub(query)
- stubs.fetch(query) { raise ArgumentError, "unknown stub request #{query}" }
+ def self.read_stub(query_text)
+ stubs.fetch(query_text) {
+ raise ArgumentError, "unknown stub request #{query_text}"
+ }
end
def self.stubs
@@ -23,8 +25,8 @@ module Geocoder
private
- def results(query, reverse = false)
- Geocoder::Lookup::Test.read_stub(query)
+ def results(query)
+ Geocoder::Lookup::Test.read_stub(query.text)
end
end
diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb
index 1ce523ecc304a7973f5062e275cfc78473972a43..e240fb4a9361939143c0c9351c818ef2a594bc98 100644
--- a/lib/geocoder/lookups/yahoo.rb
+++ b/lib/geocoder/lookups/yahoo.rb
@@ -10,8 +10,8 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
if doc = doc['ResultSet'] and doc['Error'] == 0
return doc['Found'] > 0 ? doc['Results'] : []
else
@@ -20,11 +20,11 @@ module Geocoder::Lookup
end
end
- def query_url(query, reverse = false)
+ def query_url(query)
params = {
- :location => query,
+ :location => query.sanitized_text,
:flags => "JXTSR",
- :gflags => "AC#{'R' if reverse}",
+ :gflags => "AC#{'R' if query.reverse_geocode?}",
:locale => "#{Geocoder::Configuration.language}_US",
:appid => Geocoder::Configuration.api_key
}
diff --git a/lib/geocoder/lookups/yandex.rb b/lib/geocoder/lookups/yandex.rb
index 452d27694eea2728450e6cb05877b909ee441f7f..11f092d791b39f9576c0380f86d5e492d838a100 100644
--- a/lib/geocoder/lookups/yandex.rb
+++ b/lib/geocoder/lookups/yandex.rb
@@ -10,8 +10,8 @@ module Geocoder::Lookup
private # ---------------------------------------------------------------
- def results(query, reverse = false)
- return [] unless doc = fetch_data(query, reverse)
+ def results(query)
+ return [] unless doc = fetch_data(query)
if err = doc['error']
warn "Yandex Geocoding API error: #{err['status']} (#{err['message']})."
return []
@@ -25,10 +25,14 @@ module Geocoder::Lookup
end
end
- def query_url(query, reverse = false)
- query = query.split(",").reverse.join(",") if reverse
+ def query_url(query)
+ if query.reverse_geocode?
+ q = query.coordinates.reverse.join(",")
+ else
+ q = query.sanitized_text
+ end
params = {
- :geocode => query,
+ :geocode => q,
:format => "json",
:plng => "#{Geocoder::Configuration.language}", # supports ru, uk, be
:key => Geocoder::Configuration.api_key
diff --git a/lib/geocoder/query.rb b/lib/geocoder/query.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3da86ef17430b0227dcc9a8cf285a97835197551
--- /dev/null
+++ b/lib/geocoder/query.rb
@@ -0,0 +1,88 @@
+module Geocoder
+ class Query
+ attr_accessor :text, :options
+
+ def initialize(text, options = {})
+ self.text = text
+ self.options = options
+ end
+
+ def execute
+ lookup.search(text, options)
+ end
+
+ def to_s
+ text
+ end
+
+ def sanitized_text
+ if coordinates?
+ text.split(/\s*,\s*/).join(',')
+ else
+ text
+ end
+ end
+
+ ##
+ # Get a Lookup object (which communicates with the remote geocoding API)
+ # appropriate to the Query text.
+ #
+ def lookup
+ if ip_address?
+ name = Configuration.ip_lookup || Geocoder::Lookup.ip_services.first
+ else
+ name = Configuration.lookup || Geocoder::Lookup.street_services.first
+ end
+ Lookup.get(name)
+ end
+
+ ##
+ # Is the Query text blank? (ie, should we not bother searching?)
+ #
+ def blank?
+ !!text.to_s.match(/^\s*$/)
+ end
+
+ ##
+ # Does the Query text look like an IP address?
+ #
+ # Does not check for actual validity, just the appearance of four
+ # dot-delimited numbers.
+ #
+ def ip_address?
+ !!text.to_s.match(/^(::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)
+ end
+
+ ##
+ # Is the Query text a loopback IP address?
+ #
+ def loopback_ip_address?
+ !!(text == "0.0.0.0" or text.to_s.match(/^127/))
+ end
+
+ ##
+ # Does the given string look like latitude/longitude coordinates?
+ #
+ def coordinates?
+ text.is_a?(Array) or (
+ text.is_a?(String) and
+ !!text.to_s.match(/^-?[0-9\.]+, *-?[0-9\.]+$/)
+ )
+ end
+
+ ##
+ # Return the latitude/longitude coordinates specified in the query,
+ # or nil if none.
+ #
+ def coordinates
+ sanitized_text.split(',') if coordinates?
+ end
+
+ ##
+ # Should reverse geocoding be performed for this query?
+ #
+ def reverse_geocode?
+ coordinates?
+ end
+ end
+end
diff --git a/lib/geocoder/version.rb b/lib/geocoder/version.rb
index 0eb5a04215f806f4d4b75facf7c6e9b2335e31bb..3416c7e7efeb7a1f91029a9b3913b328fda8d0af 100644
--- a/lib/geocoder/version.rb
+++ b/lib/geocoder/version.rb
@@ -1,3 +1,3 @@
module Geocoder
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
end
diff --git a/test/calculations_test.rb b/test/calculations_test.rb
index 4f9fef0df46df8131fb82d67bd7f9b93e61f68d8..902d8d680f8926bb89115b383b89acf72f07bbe3 100644
--- a/test/calculations_test.rb
+++ b/test/calculations_test.rb
@@ -185,4 +185,11 @@ class CalculationsTest < Test::Unit::TestCase
assert !Geocoder::Calculations.coordinates_present?(Geocoder::Calculations::NAN)
assert !Geocoder::Calculations.coordinates_present?(3.23, nil)
end
+
+ def test_extract_coordinates
+ coords = [-23,47]
+ l = Landmark.new("Madagascar", coords[0], coords[1])
+ assert_equal coords, Geocoder::Calculations.extract_coordinates(l)
+ assert_equal coords, Geocoder::Calculations.extract_coordinates(coords)
+ end
end
diff --git a/test/error_handling_test.rb b/test/error_handling_test.rb
index 9d84bdfdc008fe2d25671d36d052e3dd8fadaa40..369613e69540d3c33a039fd8ccf35800ee2445a3 100644
--- a/test/error_handling_test.rb
+++ b/test/error_handling_test.rb
@@ -10,7 +10,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
def test_does_not_choke_on_timeout
# keep test output clean: suppress timeout warning
orig = $VERBOSE; $VERBOSE = nil
- all_lookups_except_test.each do |l|
+ Geocoder::Lookup.all_services_except_test.each do |l|
Geocoder::Configuration.lookup = l
assert_nothing_raised { Geocoder.search("timeout") }
end
@@ -19,20 +19,20 @@ class ErrorHandlingTest < Test::Unit::TestCase
def test_always_raise_timeout_error
Geocoder::Configuration.always_raise = [TimeoutError]
- all_lookups_except_test.each do |l|
- lookup = Geocoder.send(:get_lookup, l)
+ Geocoder::Lookup.all_services_except_test.each do |l|
+ lookup = Geocoder::Lookup.get(l)
assert_raises TimeoutError do
- lookup.send(:results, "timeout")
+ lookup.send(:results, Geocoder::Query.new("timeout"))
end
end
end
def test_always_raise_socket_error
Geocoder::Configuration.always_raise = [SocketError]
- all_lookups_except_test.each do |l|
- lookup = Geocoder.send(:get_lookup, l)
+ Geocoder::Lookup.all_services_except_test.each do |l|
+ lookup = Geocoder::Lookup.get(l)
assert_raises SocketError do
- lookup.send(:results, "socket_error")
+ lookup.send(:results, Geocoder::Query.new("socket_error"))
end
end
end
diff --git a/test/https_test.rb b/test/https_test.rb
index 58219d33cc8f013746583b0d20a699e93b534ad8..aba96acf7e53aea456c91ba503659a5f23160c2a 100644
--- a/test/https_test.rb
+++ b/test/https_test.rb
@@ -6,11 +6,11 @@ class HttpsTest < Test::Unit::TestCase
def test_uses_https_for_secure_query
Geocoder::Configuration.use_https = true
g = Geocoder::Lookup::Google.new
- assert_match /^https:/, g.send(:query_url, {:a => 1, :b => 2})
+ assert_match /^https:/, g.send(:query_url, Geocoder::Query.new("test"))
end
def test_uses_http_by_default
g = Geocoder::Lookup::Google.new
- assert_match /^http:/, g.send(:query_url, {:a => 1, :b => 2})
+ assert_match /^http:/, g.send(:query_url, Geocoder::Query.new("test"))
end
end
diff --git a/test/input_handling_test.rb b/test/input_handling_test.rb
deleted file mode 100644
index f5da1f13c9df941fdbf08a157464a0dbb0738d7c..0000000000000000000000000000000000000000
--- a/test/input_handling_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# encoding: utf-8
-require 'test_helper'
-
-class InputHandlingTest < Test::Unit::TestCase
-
- def test_ip_address_detection
- assert Geocoder.send(:ip_address?, "232.65.123.94")
- assert Geocoder.send(:ip_address?, "666.65.123.94") # technically invalid
- assert Geocoder.send(:ip_address?, "::ffff:12.34.56.78")
- assert !Geocoder.send(:ip_address?, "232.65.123.94.43")
- assert !Geocoder.send(:ip_address?, "232.65.123")
- assert !Geocoder.send(:ip_address?, "::ffff:123.456.789")
- end
-
- def test_blank_query_detection
- assert Geocoder.send(:blank_query?, nil)
- assert Geocoder.send(:blank_query?, "")
- assert Geocoder.send(:blank_query?, "\t ")
- assert !Geocoder.send(:blank_query?, "a")
- assert !Geocoder.send(:blank_query?, "Москва") # no ASCII characters
- end
-
- def test_coordinates_detection
- lookup = Geocoder::Lookup::Google.new
- assert lookup.send(:coordinates?, "51.178844,5")
- assert lookup.send(:coordinates?, "51.178844, -1.826189")
- assert !lookup.send(:coordinates?, "232.65.123")
- end
-
- def test_does_not_choke_on_nil_address
- all_lookups.each do |l|
- Geocoder::Configuration.lookup = l
- assert_nothing_raised { Venue.new("Venue", nil).geocode }
- end
- end
-
- def test_extract_coordinates
- coords = [-23,47]
- l = Landmark.new("Madagascar", coords[0], coords[1])
- assert_equal coords, Geocoder::Calculations.extract_coordinates(l)
- assert_equal coords, Geocoder::Calculations.extract_coordinates(coords)
- end
-end
diff --git a/test/lookup_test.rb b/test/lookup_test.rb
index 9cce80b7751c06470161fa5062c5399808abf08f..5b4550c6c5045705395fb7bc687a6eda16bb7803 100644
--- a/test/lookup_test.rb
+++ b/test/lookup_test.rb
@@ -4,13 +4,20 @@ require 'test_helper'
class LookupTest < Test::Unit::TestCase
def test_search_returns_empty_array_when_no_results
- all_lookups_except_test.each do |l|
- lookup = Geocoder.send(:get_lookup, l)
- assert_equal [], lookup.send(:results, "no results"),
+ Geocoder::Lookup.all_services_except_test.each do |l|
+ lookup = Geocoder::Lookup.get(l)
+ assert_equal [], lookup.send(:results, Geocoder::Query.new("no results")),
"Lookup #{l} does not return empty array when no results."
end
end
+ def test_does_not_choke_on_nil_address
+ Geocoder::Lookup.all_services.each do |l|
+ Geocoder::Configuration.lookup = l
+ assert_nothing_raised { Venue.new("Venue", nil).geocode }
+ end
+ end
+
def test_hash_to_query
g = Geocoder::Lookup::Google.new
assert_equal "a=1&b=2", g.send(:hash_to_query, {:a => 1, :b => 2})
@@ -19,19 +26,19 @@ class LookupTest < Test::Unit::TestCase
def test_google_api_key
Geocoder::Configuration.api_key = "MY_KEY"
g = Geocoder::Lookup::Google.new
- assert_match "key=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
+ assert_match "key=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
end
def test_yahoo_app_id
Geocoder::Configuration.api_key = "MY_KEY"
g = Geocoder::Lookup::Yahoo.new
- assert_match "appid=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
+ assert_match "appid=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
end
def test_geocoder_ca_showpostal
Geocoder::Configuration.api_key = "MY_KEY"
g = Geocoder::Lookup::GeocoderCa.new
- assert_match "showpostal=1", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
+ assert_match "showpostal=1", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
end
end
diff --git a/test/query_test.rb b/test/query_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..22a90b5c674d181f7815b19e6949c4ea87d66c80
--- /dev/null
+++ b/test/query_test.rb
@@ -0,0 +1,34 @@
+# encoding: utf-8
+require 'test_helper'
+
+class QueryTest < Test::Unit::TestCase
+
+ def test_ip_address_detection
+ assert Geocoder::Query.new("232.65.123.94").ip_address?
+ assert Geocoder::Query.new("666.65.123.94").ip_address? # technically invalid
+ assert Geocoder::Query.new("::ffff:12.34.56.78").ip_address?
+ assert !Geocoder::Query.new("232.65.123.94.43").ip_address?
+ assert !Geocoder::Query.new("232.65.123").ip_address?
+ assert !Geocoder::Query.new("::ffff:123.456.789").ip_address?
+ end
+
+ def test_blank_query_detection
+ assert Geocoder::Query.new(nil).blank?
+ assert Geocoder::Query.new("").blank?
+ assert Geocoder::Query.new("\t ").blank?
+ assert !Geocoder::Query.new("a").blank?
+ assert !Geocoder::Query.new("Москва").blank? # no ASCII characters
+ end
+
+ def test_coordinates_detection
+ assert Geocoder::Query.new("51.178844,5").coordinates?
+ assert Geocoder::Query.new("51.178844, -1.826189").coordinates?
+ assert !Geocoder::Query.new("232.65.123").coordinates?
+ end
+
+ def test_loopback_ip_address
+ assert Geocoder::Query.new("0.0.0.0").loopback_ip_address?
+ assert Geocoder::Query.new("127.0.0.1").loopback_ip_address?
+ assert !Geocoder::Query.new("232.65.123.234").loopback_ip_address?
+ end
+end
diff --git a/test/result_test.rb b/test/result_test.rb
index 85bb0f4f7ee26bf2534a3cc3ce8562c7eecd58b3..ab207c5fb6f0bd4834cf88b3764708d2db91ebee 100644
--- a/test/result_test.rb
+++ b/test/result_test.rb
@@ -4,7 +4,7 @@ require 'test_helper'
class ResultTest < Test::Unit::TestCase
def test_result_has_required_attributes
- all_lookups_except_test.each do |l|
+ Geocoder::Lookup.all_services_except_test.each do |l|
Geocoder::Configuration.lookup = l
result = Geocoder.search([45.423733, -75.676333]).first
assert_result_has_required_attributes(result)
diff --git a/test/services_test.rb b/test/services_test.rb
index 83fe571a0eaaa21a066339da4857ddf9cfedc32b..ef701510675f4df140030812dfe73c3e01b78279 100644
--- a/test/services_test.rb
+++ b/test/services_test.rb
@@ -41,7 +41,7 @@ class ServicesTest < Test::Unit::TestCase
def test_google_premier_query_url
Geocoder::Configuration.api_key = ["deadbeef", "gme-test", "test-dev"]
assert_equal "http://maps.googleapis.com/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&channel=test-dev&client=gme-test&language=en&sensor=false&signature=doJvJqX7YJzgV9rJ0DnVkTGZqTg=",
- Geocoder::Lookup::GooglePremier.new.send(:query_url, "Madison Square Garden, New York, NY", false)
+ Geocoder::Lookup::GooglePremier.new.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY"))
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index a9cf367fe3a1ab9e02faea9617da9d9f2808bf85..aa7d6d7a2b5607fde88ed8359170922fe05d57d0 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -60,10 +60,10 @@ module Geocoder
class Google < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
when "no locality"; :no_locality
when "no city data"; :no_city_data
@@ -78,10 +78,10 @@ module Geocoder
class Yahoo < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
else :madison_square_garden
end
@@ -91,10 +91,10 @@ module Geocoder
class Yandex < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
when "invalid key"; :invalid_key
else :kremlin
@@ -105,13 +105,13 @@ module Geocoder
class GeocoderCa < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- if reverse
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ if query.reverse_geocode?
read_fixture "geocoder_ca_reverse.json"
else
- file = case query
+ file = case query.text
when "no results"; :no_results
else :madison_square_garden
end
@@ -122,10 +122,10 @@ module Geocoder
class Freegeoip < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
else "74_200_247_59"
end
@@ -135,13 +135,13 @@ module Geocoder
class Bing < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- if reverse
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ if query.reverse_geocode?
read_fixture "bing_reverse.json"
else
- file = case query
+ file = case query.text
when "no results"; :no_results
else :madison_square_garden
end
@@ -152,10 +152,10 @@ module Geocoder
class Nominatim < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
else :madison_square_garden
end
@@ -165,10 +165,10 @@ module Geocoder
class Mapquest < Base
private #-----------------------------------------------------------------
- def fetch_raw_data(query, reverse = false)
- raise TimeoutError if query == "timeout"
- raise SocketError if query == "socket_error"
- file = case query
+ def fetch_raw_data(query)
+ raise TimeoutError if query.text == "timeout"
+ raise SocketError if query.text == "socket_error"
+ file = case query.text
when "no results"; :no_results
else :madison_square_garden
end
@@ -277,18 +277,6 @@ class Test::Unit::TestCase
}[abbrev]
end
- def all_lookups
- Geocoder.valid_lookups
- end
-
- def all_lookups_except_test
- Geocoder.valid_lookups_except_test
- end
-
- def street_lookups
- Geocoder.street_lookups
- end
-
def is_nan_coordinates?(coordinates)
return false unless coordinates.respond_to? :size # Should be an array
return false unless coordinates.size == 2 # Should have dimension 2