diff --git a/README.md b/README.md index 96644fb7eefe780613b3de416eceb4582d218391..8ad085ac71dbc20379b4471964c0377dcbf5b86e 100644 --- a/README.md +++ b/README.md @@ -415,6 +415,17 @@ Yahoo BOSS is **not a free service**. As of November 17, 2012 Yahoo no longer of * **Terms of Service**: ? * **Limitations**: ? +#### ESRI (`:esri`) + +* **API key**: none +* **Quota**: Required for some scenarios (see Terms of Service) +* **Region**: world +* **SSL support**: yes +* **Languages**: English +* **Documentation**: http://resources.arcgis.com/en/help/arcgis-online-geocoding-rest-api/ +* **Terms of Service**: http://www.esri.com/software/arcgis/arcgisonline/services/geoservices +* **Limitations**: ? + Caching ------- diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb index 07656203119f820ced05476f97868b400e8483af..054d55cc7f520f530607969e2499224d2bcf4d47 100644 --- a/lib/geocoder/lookup.rb +++ b/lib/geocoder/lookup.rb @@ -21,6 +21,7 @@ module Geocoder # def street_services [ + :esri, :google, :google_premier, :yahoo, diff --git a/lib/geocoder/lookups/esri.rb b/lib/geocoder/lookups/esri.rb new file mode 100644 index 0000000000000000000000000000000000000000..194a504a40fccf44039f6393f3cc5a31e80f7c13 --- /dev/null +++ b/lib/geocoder/lookups/esri.rb @@ -0,0 +1,52 @@ +require 'geocoder/lookups/base' +require "geocoder/results/esri" +require 'rack/utils' + +module Geocoder::Lookup + class Esri < Base + + def name + "Esri" + end + + def query_url(query) + search_keyword = query.reverse_geocode? ? "reverseGeocode" : "find" + + "#{protocol}://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/#{search_keyword}?" + + url_query_string(query) + end + + private # --------------------------------------------------------------- + + def results(query) + return [] unless doc = fetch_data(query) + + if (!query.reverse_geocode?) + return [] if doc['locations'].empty? + end + + if (doc['error'].nil?) + return [ doc ] + else + return [] + end + end + + def query_url_params(query) + if query.reverse_geocode? + { + :location => query.text.reverse.join(','), + :outFields => :*, + :p => :pjson + }.merge(super) + else + { + :f => :pjson, + :outFields => :*, + :text => query.sanitized_text + }.merge(super) + end + end + + end +end \ No newline at end of file diff --git a/lib/geocoder/results/esri.rb b/lib/geocoder/results/esri.rb new file mode 100644 index 0000000000000000000000000000000000000000..5d0b79a5b5c5177dc33bbf4407b2e16eaad868df --- /dev/null +++ b/lib/geocoder/results/esri.rb @@ -0,0 +1,51 @@ +require 'geocoder/results/base' + +module Geocoder::Result + class Esri < Base + + def address + address = reverse_geocode? ? 'Address' : 'Match_addr' + attributes[address] + end + + def city + attributes['City'] + end + + def state_code + attributes['Region'] + end + + alias_method :state, :state_code + + def country + country = reverse_geocode? ? "CountryCode" : "Country" + attributes[country] + end + + alias_method :country_code, :country + + def postal_code + attributes['Postal'] + end + + def coordinates + [geometry["y"], geometry["x"]] + end + + private + + def attributes + reverse_geocode? ? @data['address'] : @data['locations'].first['feature']['attributes'] + end + + def geometry + reverse_geocode? ? @data["location"] : @data['locations'].first['feature']["geometry"] + end + + def reverse_geocode? + @data['locations'].nil? + end + + end +end \ No newline at end of file diff --git a/test/fixtures/esri_madison_square_garden b/test/fixtures/esri_madison_square_garden new file mode 100644 index 0000000000000000000000000000000000000000..df79252f7cbbd72f5bb229ae3c915216edd1fed8 --- /dev/null +++ b/test/fixtures/esri_madison_square_garden @@ -0,0 +1,59 @@ +{ + "spatialReference": { + "wkid": 4326, + "latestWkid": 4326 + }, + "locations": [ + { + "name": "Madison Square Garden", + "extent": { + "xmin": -74.000241000000003, + "ymin": 40.744050000000001, + "xmax": -73.988241000000002, + "ymax": 40.756050000000002 + }, + "feature": { + "geometry": { + "x": -73.994238897999651, + "y": 40.750049813000487 + }, + "attributes": { + "Loc_name": "Gaz.WorldGazetteer.POI2", + "Score": 100, + "Match_addr": "Madison Square Garden", + "Addr_type": "POI", + "Type": "Sports Complex", + "PlaceName": "Madison Square Garden", + "Rank": "18", + "AddBldg": "", + "AddNum": "", + "AddNumFrom": "", + "AddNumTo": "", + "Side": "", + "StPreDir": "", + "StPreType": "", + "StName": "", + "StType": "", + "StDir": "", + "Nbrhd": "", + "City": "New York", + "Subregion": "New York", + "Region": "New York", + "Postal": "10001", + "PostalExt": "", + "Country": "USA", + "LangCode": "", + "Distance": 0, + "X": -73.994240000000005, + "Y": 40.750050000000002, + "DisplayX": -73.994240000000005, + "DisplayY": 40.750050000000002, + "Xmin": -74.000241000000003, + "Xmax": -73.988241000000002, + "Ymin": 40.744050000000001, + "Ymax": 40.756050000000002 + } + } + } + ] +} \ No newline at end of file diff --git a/test/fixtures/esri_no_results b/test/fixtures/esri_no_results new file mode 100644 index 0000000000000000000000000000000000000000..09cc0632d3e479ef5d5f7fb575b2fd250ec0ffe8 --- /dev/null +++ b/test/fixtures/esri_no_results @@ -0,0 +1,8 @@ +{ + "spatialReference": { + "wkid": 4326, + "latestWkid": 4326 + }, + "locations": [ + ] +} \ No newline at end of file diff --git a/test/fixtures/esri_reverse b/test/fixtures/esri_reverse new file mode 100644 index 0000000000000000000000000000000000000000..00df64caaa24f9c03709c42df109dec85da7e6da --- /dev/null +++ b/test/fixtures/esri_reverse @@ -0,0 +1,21 @@ +{ + "address": { + "Address": "4 Avenue Gustave Eiffel", + "Neighborhood": "7e Arrondissement", + "City": "Paris", + "Subregion": "Paris", + "Region": "ÃŽle-de-France", + "Postal": "75007", + "PostalExt": null, + "CountryCode": "FRA", + "Loc_name": "FRA.PointAddress" + }, + "location": { + "x": 2.2956200048981574, + "y": 48.858129997357558, + "spatialReference": { + "wkid": 4326, + "latestWkid": 4326 + } + } +} \ No newline at end of file diff --git a/test/lookup_test.rb b/test/lookup_test.rb index 51c2e0d600ccf58a52ff579a1b4cce277c069b72..185249c657512c62c36ce9267b8b1bca568e98b8 100644 --- a/test/lookup_test.rb +++ b/test/lookup_test.rb @@ -34,6 +34,7 @@ class LookupTest < Test::Unit::TestCase end { + :esri => :l, :bing => :key, :geocoder_ca => :auth, :google => :language, diff --git a/test/services_test.rb b/test/services_test.rb index c2eb493f88cd0c2a7019a8a784a7e59bcc6b4968..e2df65fa91a6440489f0f4b23f08e71a9e0d7443 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -274,4 +274,47 @@ class ServicesTest < Test::Unit::TestCase assert_equal "46 West 31st Street, New York, NY, 10001, US", result.address end + + # --- Esri --- + + def test_esri_query_for_geocode + query = Geocoder::Query.new("Bluffton, SC") + lookup = Geocoder::Lookup.get(:esri) + res = lookup.query_url(query) + assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?f=pjson&outFields=%2A&text=Bluffton%2C+SC", + res + end + + def test_esri_query_for_reverse_geocode + query = Geocoder::Query.new([45.423733, -75.676333]) + lookup = Geocoder::Lookup.get(:esri) + res = lookup.query_url(query) + assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode?location=-75.676333%2C45.423733&outFields=%2A&p=pjson", + res + end + + def test_esri_results_component + Geocoder.configure(:lookup => :esri) + result = Geocoder.search("Madison Square Garden, New York, NY").first + assert_equal "10001", result.postal_code + assert_equal "USA", result.country + assert_equal "Madison Square Garden", result.address + assert_equal "New York", result.city + assert_equal "New York", result.state + assert_equal 40.75004981300049, result.coordinates[0] + assert_equal -73.99423889799965, result.coordinates[1] + end + + def test_esri_results_component_when_reverse_geocoding + Geocoder.configure(:lookup => :esri) + result = Geocoder.search([45.423733, -75.676333]).first + assert_equal "75007", result.postal_code + assert_equal "FRA", result.country + assert_equal "4 Avenue Gustave Eiffel", result.address + assert_equal "Paris", result.city + assert_equal "ÃŽle-de-France", result.state + assert_equal 48.858129997357558, result.coordinates[0] + assert_equal 2.2956200048981574, result.coordinates[1] + end + end diff --git a/test/test_helper.rb b/test/test_helper.rb index b74017d41d0d497d8b61b60ea933e452613cf452..e9bf68884c7b84dd6e1e6575e787d8777a6ca344 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -112,6 +112,13 @@ module Geocoder end end + class Esri + private + def fixture_prefix + "esri" + end + end + class GooglePremier private def fixture_prefix