From 29f2ca868a945caaf451b918ea004cb7b212ca2e Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Fri, 18 Mar 2011 18:14:50 -0400 Subject: [PATCH] Use more sophisticated city detection with Google. Google results don't return a 'city', so we have to look at several fields in descending order of preference. --- lib/geocoder/results/google.rb | 20 ++++++++--- test/fixtures/google_no_locality.json | 51 +++++++++++++++++++++++++++ test/geocoder_test.rb | 5 +++ test/test_helper.rb | 6 +++- 4 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/google_no_locality.json diff --git a/lib/geocoder/results/google.rb b/lib/geocoder/results/google.rb index 5e7f44ae..5455004d 100644 --- a/lib/geocoder/results/google.rb +++ b/lib/geocoder/results/google.rb @@ -12,19 +12,31 @@ module Geocoder::Result end def city - address_components_of_type(:locality).first['long_name'] + fields = [:locality, :sublocality, :administrative_area_level_3, + :administrative_area_level_2, :administrative_area_level_1] + fields.each do |f| + if entity = address_components_of_type(f).first + return entity['long_name'] + end + end end def country - address_components_of_type(:country).first['long_name'] + if country = address_components_of_type(:country).first + country['long_name'] + end end def country_code - address_components_of_type(:country).first['short_name'] + if country = address_components_of_type(:country).first + country['short_name'] + end end def postal_code - address_components_of_type(:postal_code).first['long_name'] + if postal = address_components_of_type(:postal_code).first + postal['long_name'] + end end def types diff --git a/test/fixtures/google_no_locality.json b/test/fixtures/google_no_locality.json new file mode 100644 index 00000000..d012817c --- /dev/null +++ b/test/fixtures/google_no_locality.json @@ -0,0 +1,51 @@ +{ + "status": "OK", + "results": [ { + "types": [ "route" ], + "formatted_address": "Al Ahram, Haram, Giza, Egypt", + "address_components": [ { + "long_name": "Al Ahram", + "short_name": "Al Ahram", + "types": [ "route" ] + }, { + "long_name": "Haram", + "short_name": "Haram", + "types": [ "administrative_area_level_2", "political" ] + }, { + "long_name": "Al Jizah", + "short_name": "Al Jizah", + "types": [ "administrative_area_level_1", "political" ] + }, { + "long_name": "Egypt", + "short_name": "EG", + "types": [ "country", "political" ] + } ], + "geometry": { + "location": { + "lat": 29.9803527, + "lng": 31.1330307 + }, + "location_type": "APPROXIMATE", + "viewport": { + "southwest": { + "lat": 29.9768276, + "lng": 31.1302189 + }, + "northeast": { + "lat": 29.9831228, + "lng": 31.1365141 + } + }, + "bounds": { + "southwest": { + "lat": 29.9775337, + "lng": 31.1327483 + }, + "northeast": { + "lat": 29.9824167, + "lng": 31.1339847 + } + } + } + } ] +} diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb index 3dda9307..68b8f844 100644 --- a/test/geocoder_test.rb +++ b/test/geocoder_test.rb @@ -170,6 +170,11 @@ class GeocoderTest < Test::Unit::TestCase result.address_components_of_type(:sublocality).first['long_name'] end + def test_google_returns_city_when_no_locality_in_result + result = Geocoder.search("no locality") + assert_equal "Haram", result.city + end + # --- Yahoo --- diff --git a/test/test_helper.rb b/test/test_helper.rb index 18c7aa74..3cf70f3b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -62,7 +62,11 @@ module Geocoder private #----------------------------------------------------------------- def fetch_raw_data(query, reverse = false) raise TimeoutError if query == "timeout" - file = query == "no results" ? :no_results : :madison_square_garden + file = case query + when "no results"; :no_results + when "no locality"; :no_locality + else :madison_square_garden + end read_fixture "google_#{file}.json" end end -- GitLab