diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index a770f97f11546f5519bab2ca1dc8cc8da97e8e33..7c80494a07050aaa74061c2681ff778d52a64328 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -73,6 +73,16 @@ module Geocoder fail end + def query_url_params(query) + query.options[:params] || {} + end + + def url_query_string(query) + hash_to_query( + query_url_params(query).reject{ |key,value| value.nil? } + ) + end + ## # URL to use for querying the geocoding engine. # diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb index a5d254c36fd52c85024656aacb300b0aedc2a038..1edb567a8532a4b3ddc8c10b0640e0c1ee2861c9 100644 --- a/lib/geocoder/lookups/bing.rb +++ b/lib/geocoder/lookups/bing.rb @@ -21,13 +21,17 @@ module Geocoder::Lookup end end - def query_url(query) - params = {:key => Geocoder::Configuration.api_key} - params[:query] = query.sanitized_text unless query.reverse_geocode? + def query_url_params(query) + super.merge( + :key => Geocoder::Configuration.api_key, + :query => query.reverse_geocode? ? nil : query.sanitized_text + ) + end - base_url = "http://dev.virtualearth.net/REST/v1/Locations" - url_tail = query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?" - base_url + url_tail + hash_to_query(params) + def query_url(query) + "http://dev.virtualearth.net/REST/v1/Locations" + + (query.reverse_geocode? ? "/#{query.sanitized_text}?" : "?") + + url_query_string(query) end end end diff --git a/lib/geocoder/lookups/geocoder_ca.rb b/lib/geocoder/lookups/geocoder_ca.rb index 379d0fd40c53a123d74a3b6d08d5f4d6c0a9079a..97ac2721c756fe0e158f7ac51b3106f7bb9af1bb 100644 --- a/lib/geocoder/lookups/geocoder_ca.rb +++ b/lib/geocoder/lookups/geocoder_ca.rb @@ -18,13 +18,13 @@ module Geocoder::Lookup return [] end - def query_url(query) - params = { + def query_url_params(query) + params = super.merge( :geoit => "xml", :jsonp => 1, :callback => "test", :auth => Geocoder::Configuration.api_key - } + ) if query.reverse_geocode? lat,lon = query.coordinates params[:latt] = lat @@ -35,7 +35,11 @@ module Geocoder::Lookup params[:locate] = query.sanitized_text params[:showpostal] = 1 end - "http://geocoder.ca/?" + hash_to_query(params) + params + end + + def query_url(query) + "http://geocoder.ca/?" + url_query_string(query) end def parse_raw_data(raw_data) diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb index 967294f53c3abfe4728b6710e9121e861069a50f..13bb676351260674d6a7dbc47f469586fac895f3 100644 --- a/lib/geocoder/lookups/google.rb +++ b/lib/geocoder/lookups/google.rb @@ -27,7 +27,7 @@ module Geocoder::Lookup return [] end - def query_url_base_params(query) + def query_url_google_params(query) params = { (query.reverse_geocode? ? :latlng : :address) => query.sanitized_text, :sensor => "false", @@ -39,11 +39,14 @@ module Geocoder::Lookup params end - def query_url(query) - params = query_url_base_params(query).merge( + def query_url_params(query) + super.merge(query_url_google_params(query)).merge( :key => Geocoder::Configuration.api_key - ).reject{ |key, value| value.nil? } - "#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(params) + ) + end + + def query_url(query) + "#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + url_query_string(query) end end end diff --git a/lib/geocoder/lookups/google_premier.rb b/lib/geocoder/lookups/google_premier.rb index 2f1d974c76ccceceac9fdc6f7df6f80dd0193c56..b725b9fb4543aacd07206a7746a92d54f1bcdbf3 100644 --- a/lib/geocoder/lookups/google_premier.rb +++ b/lib/geocoder/lookups/google_premier.rb @@ -8,12 +8,16 @@ module Geocoder::Lookup private # --------------------------------------------------------------- - def query_url(query) - params = query_url_base_params(query).merge( + def query_url_params(query) + super.merge(query_url_google_params(query)).merge( + :key => nil, # don't use param inherited from Google lookup :client => Geocoder::Configuration.api_key[1], :channel => Geocoder::Configuration.api_key[2] - ).reject{ |key, value| value.nil? } - path = "/maps/api/geocode/json?#{hash_to_query(params)}" + ) + end + + def query_url(query) + path = "/maps/api/geocode/json?" + url_query_string(query) "#{protocol}://maps.googleapis.com#{path}&signature=#{sign(path)}" end diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb index 0b02807cd2c13cc45168259a77e32fac2c8819fe..404bda22eef80bfc0e79593a39df3345f6ef5717 100644 --- a/lib/geocoder/lookups/mapquest.rb +++ b/lib/geocoder/lookups/mapquest.rb @@ -8,9 +8,8 @@ module Geocoder::Lookup private # --------------------------------------------------------------- def query_url(query) - params = query_url_params(query) method = query.reverse_geocode? ? "reverse" : "search" - "http://open.mapquestapi.com/#{method}?" + hash_to_query(params) + "http://open.mapquestapi.com/#{method}?" + url_query_string(query) end end end diff --git a/lib/geocoder/lookups/nominatim.rb b/lib/geocoder/lookups/nominatim.rb index 3a0773690c662ff9755f3309bd5778a48f35b74e..d79f7312650c2d6d3d7df63285c0b6cea5b4bb19 100644 --- a/lib/geocoder/lookups/nominatim.rb +++ b/lib/geocoder/lookups/nominatim.rb @@ -16,12 +16,12 @@ module Geocoder::Lookup end def query_url_params(query) - params = { + params = super.merge( :format => "json", :polygon => "1", :addressdetails => "1", :"accept-language" => Geocoder::Configuration.language - } + ) if query.reverse_geocode? lat,lon = query.coordinates params[:lat] = lat @@ -33,9 +33,8 @@ module Geocoder::Lookup end def query_url(query) - params = query_url_params(query) method = query.reverse_geocode? ? "reverse" : "search" - "http://nominatim.openstreetmap.org/#{method}?" + hash_to_query(params) + "http://nominatim.openstreetmap.org/#{method}?" + url_query_string(query) end end end diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb index e240fb4a9361939143c0c9351c818ef2a594bc98..9282f2e970deedc170889f1d5d2043673cf38251 100644 --- a/lib/geocoder/lookups/yahoo.rb +++ b/lib/geocoder/lookups/yahoo.rb @@ -20,15 +20,18 @@ module Geocoder::Lookup end end - def query_url(query) - params = { + def query_url_params(query) + super.merge( :location => query.sanitized_text, :flags => "JXTSR", :gflags => "AC#{'R' if query.reverse_geocode?}", :locale => "#{Geocoder::Configuration.language}_US", :appid => Geocoder::Configuration.api_key - } - "http://where.yahooapis.com/geocode?" + hash_to_query(params) + ) + end + + def query_url(query) + "http://where.yahooapis.com/geocode?" + url_query_string(query) end end end diff --git a/lib/geocoder/lookups/yandex.rb b/lib/geocoder/lookups/yandex.rb index 11f092d791b39f9576c0380f86d5e492d838a100..9b4f63d6e8104fe422f7d48474e51fba30973bf6 100644 --- a/lib/geocoder/lookups/yandex.rb +++ b/lib/geocoder/lookups/yandex.rb @@ -25,19 +25,22 @@ module Geocoder::Lookup end end - def query_url(query) + def query_url_params(query) if query.reverse_geocode? q = query.coordinates.reverse.join(",") else q = query.sanitized_text end - params = { + super.merge( :geocode => q, :format => "json", :plng => "#{Geocoder::Configuration.language}", # supports ru, uk, be :key => Geocoder::Configuration.api_key - } - "http://geocode-maps.yandex.ru/1.x/?" + hash_to_query(params) + ) + end + + def query_url(query) + "http://geocode-maps.yandex.ru/1.x/?" + url_query_string(query) end end end diff --git a/test/services_test.rb b/test/services_test.rb index 2864588dd465dbb903d4af3eed40211dd0fb89e7..07cb694c728458b88f1ac04ab7654aa11bcf05ac 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -4,6 +4,18 @@ require 'test_helper' class ServicesTest < Test::Unit::TestCase + def test_query_url_contains_values_in_params_hash + Geocoder::Lookup.all_services_except_test.each do |l| + next if l == :google_premier # TODO: need to set keys to test + next if l == :freegeoip # does not use query string + url = Geocoder::Lookup.get(l).send(:query_url, Geocoder::Query.new( + "test", :params => {:one_in_the_hand => "two in the bush"} + )) + assert_match /one_in_the_hand=two\+in\+the\+bush/, url, + "Lookup #{l} does not appear to support arbitrary params in URL" + end + end + # --- Google --- def test_google_result_components