From e2dca64dd355aaeb80de3600d9de525c9f134ee8 Mon Sep 17 00:00:00 2001 From: dblock <dblock@dblock.org> Date: Tue, 21 Jan 2014 13:59:01 -0500 Subject: [PATCH] Added support for Geocod.io. --- CHANGELOG.md | 1 + README.md | 15 ++++- lib/geocoder/lookup.rb | 1 + lib/geocoder/lookups/geocodio.rb | 34 ++++++++++ lib/geocoder/results/geocodio.rb | 66 ++++++++++++++++++++ test/fixtures/geocodio_1101_pennsylvania_ave | 1 + test/fixtures/geocodio_no_results | 1 + test/services_test.rb | 23 +++++++ test/test_helper.rb | 6 ++ 9 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 lib/geocoder/lookups/geocodio.rb create mode 100644 lib/geocoder/results/geocodio.rb create mode 100644 test/fixtures/geocodio_1101_pennsylvania_ave create mode 100644 test/fixtures/geocodio_no_results diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8f6ee7..d58330bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Major changes to Geocoder for each release. Please see the Git log for complete * Add :baidu_ip lookup (thanks github.com/yonggu). * Add :min_radius option to `near` scope (thanks github.com/phallstrom). * Fix: Yandex city attribute caused exception with certain responses (thanks github.com/dblock). +* Add support for Geocod.io API (thanks github.com/dblock). 1.1.9 (2013 Dec 11) ------------------- diff --git a/README.md b/README.md index 3521b240..1bca09f3 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,7 @@ When querying for objects (if you're using ActiveRecord) you can also look withi This can also dramatically improve query performance, especially when used in conjunction with indexes on the latitude/longitude columns. Note, however, that returned results do not include `distance` and `bearing` attributes. Note that `#near` performs both bounding box and radius queries for speed. -You can also specify a minimum radius (if you're using ActiveRecord and not Sqlite) to constrain the +You can also specify a minimum radius (if you're using ActiveRecord and not Sqlite) to constrain the lower bound (ie. think of a donut, or ring) by using the `:min_radius` option: box = Geocoder::Calculations.bounding_box(center_point, distance, :min_radius => 10.5) @@ -522,6 +522,17 @@ Data Science Toolkit provides an API whose reponse format is like Google's but w * **Terms of Service**: http://cloudmade.com/api-terms-of-service * **Limitations**: ? +#### Geocodio (`:geocodio`) + +* **API key**: required +* **Quota**: 2,500 free requests/day then purchase $.001 for each +* **Region**: US +* **SSL support**: no +* **Languages**: en +* **Documentation**: http://geocod.io/docs +* **Terms of Service**: http://geocod.io/terms-of-use +* **Limitations**: ? + ### IP Address Services #### FreeGeoIP (`:freegeoip`) @@ -558,7 +569,7 @@ Data Science Toolkit provides an API whose reponse format is like Google's but w * **Terms of Service**: ? * **Limitations**: ? * **Notes**: You must add the **geoip** gem to your Gemfile or have it installed in your system. You also have to specify the path of the MaxMind database in your configuration. For example: - + `Geocoder.configure(:ip_lookup => :maxmind_local, :maxmind_local => {:database => File.join('folder', 'GeoLiteCity.dat')})` #### Baidu IP (`:baidu_ip`) diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb index 104de94c..fbfec2f8 100644 --- a/lib/geocoder/lookup.rb +++ b/lib/geocoder/lookup.rb @@ -35,6 +35,7 @@ module Geocoder :ovi, :baidu, :cloudmade, + :geocodio, :test ] end diff --git a/lib/geocoder/lookups/geocodio.rb b/lib/geocoder/lookups/geocodio.rb new file mode 100644 index 00000000..d3fc8f97 --- /dev/null +++ b/lib/geocoder/lookups/geocodio.rb @@ -0,0 +1,34 @@ +require 'geocoder/lookups/base' +require "geocoder/results/geocodio" + +module Geocoder::Lookup + class Geocodio < Base + + def name + "Geocodio" + end + + def query_url(query) + "#{protocol}://api.geocod.io/v1/geocode?#{url_query_string(query)}" + end + + def results(query) + return [] unless doc = fetch_data(query) + if doc['error'].nil? + return doc["results"] + else + warn "Geocodio service error: #{doc['error']}." + end + [] + end + + private # --------------------------------------------------------------- + + def query_url_params(query) + { + :api_key => configuration.api_key, + :q => query.sanitized_text + }.merge(super) + end + end +end diff --git a/lib/geocoder/results/geocodio.rb b/lib/geocoder/results/geocodio.rb new file mode 100644 index 00000000..e80c750f --- /dev/null +++ b/lib/geocoder/results/geocodio.rb @@ -0,0 +1,66 @@ +require 'geocoder/results/base' + +module Geocoder::Result + class Geocodio < Base + def number + address_components["number"] + end + + def street + address_components["street"] + end + + def suffix + address_components["suffix"] + end + + def state + address_components["state"] + end + alias_method :state_code, :state + + def zip + address_components["zip"] + end + alias_method :postal_code, :zip + + def country + "United States" # Geocodio only supports the US + end + + def country_code + "US" # Geocodio only supports the US + end + + def city + address_components["city"] + end + + def postdirectional + address_components["postdirectional"] + end + + def location + @data['location'] + end + + def coordinates + ['lat', 'lng'].map{ |i| location[i] } if location + end + + def accuracy + @data['accuracy'].to_f if @data.key?('accuracy') + end + + def formatted_address(format = :full) + @data['formatted_address'] + end + alias_method :address, :formatted_address + + private + + def address_components + @data['address_components'] || {} + end + end +end diff --git a/test/fixtures/geocodio_1101_pennsylvania_ave b/test/fixtures/geocodio_1101_pennsylvania_ave new file mode 100644 index 00000000..c89bf170 --- /dev/null +++ b/test/fixtures/geocodio_1101_pennsylvania_ave @@ -0,0 +1 @@ +{"input":{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC"},"results":[{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":38.895019,"lng":-77.028095},"accuracy":1},{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":38.895016122449,"lng":-77.028084377551},"accuracy":0.8}]} \ No newline at end of file diff --git a/test/fixtures/geocodio_no_results b/test/fixtures/geocodio_no_results new file mode 100644 index 00000000..45b14b1a --- /dev/null +++ b/test/fixtures/geocodio_no_results @@ -0,0 +1 @@ +{"input":{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC"},"results":[]} diff --git a/test/services_test.rb b/test/services_test.rb index ad7f361b..f7c7ca61 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -397,4 +397,27 @@ class ServicesTest < Test::Unit::TestCase assert_equal 2.2956200048981574, result.coordinates[1] end + # --- Geocodio --- + + def test_geocodio_result_components + Geocoder.configure(:lookup => :geocodio) + set_api_key!(:geocodio) + result = Geocoder.search("1101 Pennsylvania Ave NW, Washington DC").first + assert_equal 1.0, result.accuracy + assert_equal "1101", result.number + assert_equal "Ave", result.suffix + assert_equal "DC", result.state + assert_equal "20004", result.zip + assert_equal "NW", result.postdirectional + assert_equal "Washington", result.city + assert_equal "1101 Pennsylvania Ave NW, Washington DC, 20004", result.formatted_address + assert_equal({ "lat" => 38.895019, "lng" => -77.028095 }, result.location) + end + + def test_geocodio_no_results + Geocoder.configure(:lookup => :geocodio) + set_api_key!(:geocodio) + results = Geocoder.search("no results") + assert_equal 0, results.length + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0035c55a..20d3a13d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -174,6 +174,12 @@ module Geocoder end end + class Geocodio + private + def default_fixture_filename + "geocodio_1101_pennsylvania_ave" + end + end end end -- GitLab