diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb index 404bda22eef80bfc0e79593a39df3345f6ef5717..e9df075a149f23c9669bba7946eb6b2f2b730343 100644 --- a/lib/geocoder/lookups/mapquest.rb +++ b/lib/geocoder/lookups/mapquest.rb @@ -1,15 +1,42 @@ +require 'uri' require 'geocoder/lookups/base' -require "geocoder/lookups/nominatim" require "geocoder/results/mapquest" module Geocoder::Lookup - class Mapquest < Nominatim + class Mapquest < Base private # --------------------------------------------------------------- def query_url(query) - method = query.reverse_geocode? ? "reverse" : "search" - "http://open.mapquestapi.com/#{method}?" + url_query_string(query) + key = Geocoder::Configuration.api_key + domain = key ? "www" : "open" + url = "http://#{domain}.mapquestapi.com/geocoding/v1/#{search_type(query)}?" + url + url_query_string(query) + end + + def search_type(query) + query.reverse_geocode? ? "reverse" : "address" + end + + def query_url_params(query) + key = Geocoder::Configuration.api_key + params = { :location => query.sanitized_text } + if key + params[:key] = URI.unescape(key) + end + super.merge(params) + end + + def results(query) + return [] unless doc = fetch_data(query) + doc["results"][0]['locations'] + end + + def hash_to_query(hash) + require 'uri' unless defined?(URI) && defined?(URI.escape) + hash.collect{ |p| + p[1].nil? ? nil : p.map{ |i| URI.escape i.to_s } * '=' + }.compact.sort * '&' end end end diff --git a/lib/geocoder/results/mapquest.rb b/lib/geocoder/results/mapquest.rb index f977a6b5f5afb5e26aa8303e29723140daaae04b..6c45305a562601d14ff71ae71fab0cb4a1ccbbe3 100644 --- a/lib/geocoder/results/mapquest.rb +++ b/lib/geocoder/results/mapquest.rb @@ -1,7 +1,51 @@ require 'geocoder/results/base' -require 'geocoder/results/nominatim' module Geocoder::Result - class Mapquest < Nominatim + class Mapquest < Base + def latitude + @data["latLng"]["lat"] + end + + def longitude + @data["latLng"]["lng"] + end + + def coordinates + [latitude, longitude] + end + + def city + @data['adminArea5'] + end + + def street + @data['street'] + end + + def state + @data['adminArea3'] + end + + alias_method :state_code, :state + + #FIXME: these might not be right, unclear with MQ documentation + alias_method :provinice, :state + alias_method :province_code, :state + + def postal_code + @data['postalCode'].to_s + end + + def country + @data['adminArea1'] + end + + def country_code + country + end + + def address + "#{street}, #{city}, #{state}, #{postal_code}, #{country}" + end end end diff --git a/test/fixtures/mapquest_madison_square_garden.json b/test/fixtures/mapquest_madison_square_garden.json index 1c8d3b31746fefaf645edadcf8cc805780e8607e..86c135bac459db715783f28a07b793cc8820ff19 100644 --- a/test/fixtures/mapquest_madison_square_garden.json +++ b/test/fixtures/mapquest_madison_square_garden.json @@ -1,27 +1,52 @@ -[ - { - "place_id":"2177656031", - "licence":"Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0.", - "osm_type":"way", - "osm_id":"138141251", - "boundingbox":["40.7498588562012","40.751163482666","-73.9944381713867","-73.9925842285156"], - "polygonpoints":[["-73.9944367","40.7505417"],["-73.9940278","40.7511034"],["-73.9939442","40.7510658"],["-73.9938776","40.7510941"],["-73.9937734","40.7511298"],["-73.9936562","40.7511561"],["-73.993619","40.7511624"],["-73.9935537","40.7510862"],["-73.9935336","40.7510885"],["-73.9934248","40.7510898"],["-73.9933248","40.7510806"],["-73.9932268","40.7510614"],["-73.9931334","40.7510327"],["-73.9930378","40.7509909"],["-73.9929554","40.7509421"],["-73.9928865","40.7508886"],["-73.992821","40.7508216"],["-73.9927742","40.7507572"],["-73.9926591","40.7507581"],["-73.9926036","40.750603"],["-73.992704","40.7505536"],["-73.9927029","40.7505065"],["-73.9925855","40.7505009"],["-73.9925989","40.7503952"],["-73.9926442","40.7504003"],["-73.9926722","40.7503155"],["-73.9927117","40.7502402"],["-73.9927617","40.7501715"],["-73.992824","40.7501067"],["-73.9928991","40.7500484"],["-73.992869","40.7500159"],["-73.9929742","40.749956"],["-73.9930375","40.7500318"],["-73.9931229","40.7499938"],["-73.9931273","40.7499005"],["-73.9933201","40.7498624"],["-73.9933853","40.7499355"],["-73.993402","40.7499336"],["-73.9935038","40.749932"],["-73.9936041","40.7499407"],["-73.9936962","40.7499579"],["-73.9937875","40.7499846"],["-73.9938783","40.7500221"],["-73.9939639","40.7500701"],["-73.9940328","40.7501206"],["-73.9940991","40.7501842"],["-73.9941506","40.7502504"],["-73.9941562","40.7502603"],["-73.9942791","40.7502628"],["-73.9942969","40.7503035"],["-73.9943271","40.7503844"],["-73.9943435","40.7504689"],["-73.9943454","40.7505049"],["-73.9944367","40.7505417"]], - "lat":"40.7505206016777", - "lon":"-73.993490694181", - "display_name":"Madison Square Garden, 46, West 31st Street, Chelsea, New York City, New York, United States of America", - "class":"leisure", - "type":"stadium", - "address":{ - "stadium":"Madison Square Garden", - "house_number":"46", - "road":"West 31st Street", - "suburb":"Chelsea", - "city":"New York City", - "county":"New York", - "state":"New York", - "postcode":"10119", - "country":"United States of America", - "country_code":"us" +{ + "results": [ + { + "locations": [ + { + "latLng": { + "lng": -73.994637, + "lat": 40.720409 + }, + "adminArea4": "New York County", + "adminArea5Type": "City", + "adminArea4Type": "County", + "adminArea5": "New York", + "street": "46 West 31st Street", + "adminArea1": "US", + "adminArea3": "NY", + "type": "s", + "displayLatLng": { + "lng": -73.994637, + "lat": 40.720409 + }, + "linkId": 0, + "postalCode": "10001", + "sideOfStreet": "N", + "dragPoint": false, + "adminArea1Type": "Country", + "geocodeQuality": "CITY", + "geocodeQualityCode": "A5XAX", + "mapUrl": "http://www.mapquestapi.com/staticmap/v3/getmap?type=map&size=225,160&pois=purple-1,40.720409,-73.994637,0,0|¢er=40.720409,-73.994637&zoom=9&key=Gmjtd|luua2hu2nd,7x=o5-lz8lg&rand=604519389", + "adminArea3Type": "State" + } + ], + "providedLocation": { + "location": "Madison Square Garden, New York, NY" + } } + ], + "options": { + "ignoreLatLngInput": false, + "maxResults": -1, + "thumbMaps": true + }, + "info": { + "copyright": { + "text": "© 2012 MapQuest, Inc.", + "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif", + "imageAltText": "© 2012 MapQuest, Inc." + }, + "statuscode": 0, + "messages": [] } -] +} diff --git a/test/fixtures/mapquest_no_results.json b/test/fixtures/mapquest_no_results.json index fe51488c7066f6687ef680d6bfaa4f7768ef205c..0cfc3e76e385c41ecb2f9cfcea589e3f44ba38ab 100644 --- a/test/fixtures/mapquest_no_results.json +++ b/test/fixtures/mapquest_no_results.json @@ -1 +1,7 @@ -[] +{ + "results": [ + { + "locations": [] + } + ] +} diff --git a/test/services_test.rb b/test/services_test.rb index 0f44de51d66626d080a3c6869663fef7b65b5eb5..ba7cd96a578b524360cb25e003a6786e4f4d3cc3 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -8,11 +8,17 @@ class ServicesTest < Test::Unit::TestCase 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 + # mapquest seems to like URI instead of CGI escaping + regex = if l == :mapquest + /one_in_the_hand=two%20in%20the%20bush/ + else + /one_in_the_hand=two\+in\+the\+bush/ + end 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" + assert_match(regex, url, + "Lookup #{l} does not appear to support arbitrary params in URL") end end @@ -46,7 +52,7 @@ class ServicesTest < Test::Unit::TestCase "Some Intersection", :bounds => [[40.0, -120.0], [39.0, -121.0]] )) - assert_match /bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url + assert_match(/bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url) end # --- Google Premier --- @@ -154,7 +160,7 @@ class ServicesTest < Test::Unit::TestCase # --- Nominatim --- - def test_nominatim_result_components + def test_nominatim_result_components Geocoder::Configuration.lookup = :nominatim result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "10001", result.postal_code @@ -166,4 +172,29 @@ class ServicesTest < Test::Unit::TestCase assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America", result.address end + # --- MapQuest --- + + def test_api_route + Geocoder::Configuration.lookup = :mapquest + Geocoder::Configuration.api_key = "abc123" + + lookup = Geocoder::Lookup::Mapquest.new + query = Geocoder::Query.new("Bluffton, SC") + res = lookup.send(:query_url, query) + assert_equal "http://www.mapquestapi.com/geocoding/v1/address?key=abc123&location=Bluffton,%20SC", + res + end + + def test_mapquest_result_components + Geocoder::Configuration.lookup = :mapquest + result = Geocoder.search("Madison Square Garden, New York, NY").first + assert_equal "10001", result.postal_code + end + + def test_mapquest_address_formatting + Geocoder::Configuration.lookup = :mapquest + result = Geocoder.search("Madison Square Garden, New York, NY").first + assert_equal "46 West 31st Street, New York, NY, 10001, US", + result.address + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index b246afdd3c9b45ea17335a6f7b92f42af5564fe7..e390f0dbae5af55a5ca3419af546204cf7ebed94 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -176,7 +176,7 @@ module Geocoder end end - class Mapquest < Nominatim + class Mapquest < Base private #----------------------------------------------------------------- def fetch_raw_data(query) raise TimeoutError if query.text == "timeout"