From da70955e164071010047ea025ebcf0bdb7257157 Mon Sep 17 00:00:00 2001 From: Jed Schneider <jed.schneider@modeset.com> Date: Fri, 12 Oct 2012 17:01:21 -0400 Subject: [PATCH] Bringing in Mapquest API changes previously the mapquest service was relying on an outdated url that was just defering to the Nominatum service. This commit brings in supported Mapquest API support for v1 of their API. It supports the open (free) tier of the API along with the licensed version of the service. --- lib/geocoder/lookups/mapquest.rb | 35 ++++++++- lib/geocoder/results/mapquest.rb | 48 +++++++++++- .../mapquest_madison_square_garden.json | 75 ++++++++++++------- test/fixtures/mapquest_no_results.json | 8 +- test/services_test.rb | 39 +++++++++- test/test_helper.rb | 2 +- 6 files changed, 170 insertions(+), 37 deletions(-) diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb index 404bda22..e9df075a 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 f977a6b5..6c45305a 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 1c8d3b31..86c135ba 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 fe51488c..0cfc3e76 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 0f44de51..ba7cd96a 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 b246afdd..e390f0db 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" -- GitLab