darrell-geokit 1.2.4.1 → 1.4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -110,9 +110,9 @@ module Geokit
110
110
  end
111
111
 
112
112
  # Geocodes a location using the multi geocoder.
113
- def geocode(location)
114
- res = Geocoders::MultiGeocoder.geocode(location)
115
- return res if res.success
113
+ def geocode(location, options = {})
114
+ res = Geocoders::MultiGeocoder.geocode(location, options)
115
+ return res if res.success?
116
116
  raise Geokit::Geocoders::GeocodeError
117
117
  end
118
118
 
@@ -251,6 +251,14 @@ module Geokit
251
251
  other.is_a?(LatLng) ? self.lat == other.lat && self.lng == other.lng : false
252
252
  end
253
253
 
254
+ def hash
255
+ lat.hash + lng.hash
256
+ end
257
+
258
+ def eql?(other)
259
+ self == other
260
+ end
261
+
254
262
  # A *class* method to take anything which can be inferred as a point and generate
255
263
  # a LatLng from it. You should use this anything you're not sure what the input is,
256
264
  # and want to deal with it as a LatLng if at all possible. Can take:
@@ -270,7 +278,7 @@ module Geokit
270
278
  return Geokit::LatLng.new(match[1],match[2])
271
279
  else
272
280
  res = Geokit::Geocoders::MultiGeocoder.geocode(thing)
273
- return res if res.success
281
+ return res if res.success?
274
282
  raise Geokit::Geocoders::GeocodeError
275
283
  end
276
284
  elsif thing.is_a?(Array) && thing.size==2
@@ -284,6 +292,30 @@ module Geokit
284
292
  raise ArgumentError.new("#{thing} (#{thing.class}) cannot be normalized to a LatLng. We tried interpreting it as an array, string, Mappable, etc., but no dice.")
285
293
  end
286
294
 
295
+ # Reverse geocodes a LatLng object using the MultiGeocoder (default), or optionally
296
+ # using a geocoder of your choosing. Returns a new Geokit::GeoLoc object
297
+ #
298
+ # ==== Options
299
+ # * :using - Specifies the geocoder to use for reverse geocoding. Defaults to
300
+ # MultiGeocoder. Can be either the geocoder class (or any class that
301
+ # implements do_reverse_geocode for that matter), or the name of
302
+ # the class without the "Geocoder" part (e.g. :google)
303
+ #
304
+ # ==== Examples
305
+ # LatLng.new(51.4578329, 7.0166848).reverse_geocode # => #<Geokit::GeoLoc:0x12dac20 @state...>
306
+ # LatLng.new(51.4578329, 7.0166848).reverse_geocode(:using => :google) # => #<Geokit::GeoLoc:0x12dac20 @state...>
307
+ # LatLng.new(51.4578329, 7.0166848).reverse_geocode(:using => Geokit::Geocoders::GoogleGeocoder) # => #<Geokit::GeoLoc:0x12dac20 @state...>
308
+ def reverse_geocode(options = { :using => Geokit::Geocoders::MultiGeocoder })
309
+ if options[:using].is_a?(String) or options[:using].is_a?(Symbol)
310
+ provider = Geokit::Geocoders.const_get("#{Geokit::Inflector::camelize(options[:using].to_s)}Geocoder")
311
+ elsif options[:using].respond_to?(:do_reverse_geocode)
312
+ provider = options[:using]
313
+ else
314
+ raise ArgumentError.new("#{options[:using]} is not a valid geocoder.")
315
+ end
316
+
317
+ provider.send(:reverse_geocode, self)
318
+ end
287
319
  end
288
320
 
289
321
  # This class encapsulates the result of a geocoding call.
@@ -314,9 +346,12 @@ module Geokit
314
346
  # Attributes set upon return from geocoding. Success will be true for successful
315
347
  # geocode lookups. The provider will be set to the name of the providing geocoder.
316
348
  # Finally, precision is an indicator of the accuracy of the geocoding.
317
- attr_accessor :success, :provider, :precision
349
+ attr_accessor :success, :provider, :precision, :suggested_bounds
318
350
  # Street number and street name are extracted from the street address attribute.
319
351
  attr_reader :street_number, :street_name
352
+ # accuracy is set for Yahoo and Google geocoders, it is a numeric value of the
353
+ # precision. see http://code.google.com/apis/maps/documentation/geocoding/#GeocodingAccuracy
354
+ attr_accessor :accuracy
320
355
 
321
356
  # Constructor expects a hash of symbols to correspond with attributes.
322
357
  def initialize(h={})
@@ -337,6 +372,10 @@ module Geokit
337
372
  def is_us?
338
373
  country_code == 'US'
339
374
  end
375
+
376
+ def success?
377
+ success == true
378
+ end
340
379
 
341
380
  # full_address is provided by google but not by yahoo. It is intended that the google
342
381
  # geocoding method will provide the full address, whereas for yahoo it will be derived
@@ -374,7 +413,7 @@ module Geokit
374
413
  #@street_address = Geokit::Inflector::titleize(address) if address
375
414
  @street_address = address if address
376
415
  end
377
-
416
+
378
417
  # Returns a comma-delimited string consisting of the street address, city, state,
379
418
  # zip, and country code. Only includes those attributes that are non-blank.
380
419
  def to_geocodeable_s
@@ -384,12 +423,12 @@ module Geokit
384
423
  end
385
424
 
386
425
  def to_yaml_properties
387
- (instance_variables - ['@results']).sort
426
+ (instance_variables - ['@all']).sort
388
427
  end
389
428
 
390
429
  # Returns a string representation of the instance.
391
430
  def to_s
392
- "Provider: #{provider}\n Street: #{street_address}\nCity: #{city}\nState: #{state}\nZip: #{zip}\nLatitude: #{lat}\nLongitude: #{lng}\nCountry: #{country_code}\nSuccess: #{success}"
431
+ "Provider: #{provider}\nStreet: #{street_address}\nCity: #{city}\nState: #{state}\nZip: #{zip}\nLatitude: #{lat}\nLongitude: #{lng}\nCountry: #{country_code}\nSuccess: #{success}"
393
432
  end
394
433
  end
395
434
 
@@ -443,6 +482,16 @@ module Geokit
443
482
  other.is_a?(Bounds) ? self.sw == other.sw && self.ne == other.ne : false
444
483
  end
445
484
 
485
+ # Equivalent to Google Maps API's .toSpan() method on GLatLng's.
486
+ #
487
+ # Returns a LatLng object, whose coordinates represent the size of a rectangle
488
+ # defined by these bounds.
489
+ def to_span
490
+ lat_span = (@ne.lat - @sw.lat).abs
491
+ lng_span = (crosses_meridian? ? 360 + @ne.lng - @sw.lng : @ne.lng - @sw.lng).abs
492
+ Geokit::LatLng.new(lat_span, lng_span)
493
+ end
494
+
446
495
  class <<self
447
496
 
448
497
  # returns an instance of bounds which completely encompases the given circle
@@ -17,25 +17,27 @@ end
17
17
  # Base class for testing geocoders.
18
18
  class BaseGeocoderTest < Test::Unit::TestCase #:nodoc: all
19
19
 
20
+ class Geokit::Geocoders::TestGeocoder < Geokit::Geocoders::Geocoder
21
+ def self.do_get(url)
22
+ sleep(2)
23
+ end
24
+ end
25
+
20
26
  # Defines common test fixtures.
21
27
  def setup
22
28
  @address = 'San Francisco, CA'
23
29
  @full_address = '100 Spear St, San Francisco, CA, 94105-1522, US'
24
30
  @full_address_short_zip = '100 Spear St, San Francisco, CA, 94105, US'
25
31
 
26
- @success = Geokit::GeoLoc.new({:city=>"SAN FRANCISCO", :state=>"CA", :country_code=>"US", :lat=>37.7742, :lng=>-122.417068})
32
+ @latlng = Geokit::LatLng.new(37.7742, -122.417068)
33
+ @success = Geokit::GeoLoc.new({:city=>"SAN FRANCISCO", :state=>"CA", :country_code=>"US", :lat=>@latlng.lat, :lng=>@latlng.lng})
27
34
  @success.success = true
28
35
  end
29
36
 
30
37
  def test_timeout_call_web_service
31
- Geokit::Geocoders::Geocoder.class_eval do
32
- def self.do_get(url)
33
- sleep(2)
34
- end
35
- end
36
38
  url = "http://www.anything.com"
37
39
  Geokit::Geocoders::timeout = 1
38
- assert_nil Geokit::Geocoders::Geocoder.call_geocoder_service(url)
40
+ assert_nil Geokit::Geocoders::TestGeocoder.call_geocoder_service(url)
39
41
  end
40
42
 
41
43
  def test_successful_call_web_service
data/test/test_bounds.rb CHANGED
@@ -71,4 +71,27 @@ class BoundsTest < Test::Unit::TestCase #:nodoc: all
71
71
  assert !bounds.contains?(outside)
72
72
  end
73
73
 
74
+ def test_bounds_to_span
75
+ sw = Geokit::LatLng.new(32, -96)
76
+ ne = Geokit::LatLng.new(40, -70)
77
+ bounds = Geokit::Bounds.new(sw, ne)
78
+
79
+ assert_equal Geokit::LatLng.new(8, 26), bounds.to_span
80
+ end
81
+
82
+ def test_bounds_to_span_with_bounds_crossing_prime_meridian
83
+ sw = Geokit::LatLng.new(20, -70)
84
+ ne = Geokit::LatLng.new(40, 100)
85
+ bounds = Geokit::Bounds.new(sw, ne)
86
+
87
+ assert_equal Geokit::LatLng.new(20, 170), bounds.to_span
88
+ end
89
+
90
+ def test_bounds_to_span_with_bounds_crossing_dateline
91
+ sw = Geokit::LatLng.new(20, 100)
92
+ ne = Geokit::LatLng.new(40, -70)
93
+ bounds = Geokit::Bounds.new(sw, ne)
94
+
95
+ assert_equal Geokit::LatLng.new(20, 190), bounds.to_span
96
+ end
74
97
  end
data/test/test_geoloc.rb CHANGED
@@ -13,6 +13,14 @@ class GeoLocTest < Test::Unit::TestCase #:nodoc: all
13
13
  assert @loc.is_us?
14
14
  end
15
15
 
16
+ def test_success
17
+ assert !@loc.success?
18
+ @loc.success = false
19
+ assert !@loc.success?
20
+ @loc.success = true
21
+ assert @loc.success?
22
+ end
23
+
16
24
  def test_street_number
17
25
  @loc.street_address = '123 Spear St.'
18
26
  assert_equal '123', @loc.street_number
@@ -51,4 +59,14 @@ class GeoLocTest < Test::Unit::TestCase #:nodoc: all
51
59
  assert_equal [@loc], @loc.all
52
60
  end
53
61
 
62
+ def test_to_yaml
63
+ @loc.city = 'San Francisco'
64
+ @loc.state = 'CA'
65
+ @loc.zip = '94105'
66
+ @loc.country_code = 'US'
67
+ assert_equal(
68
+ "--- !ruby/object:Geokit::GeoLoc \ncity: San Francisco\ncountry_code: US\nfull_address: \nlat: \nlng: \nprecision: unknown\nstate: CA\nstreet_address: \nsuccess: false\nzip: \"94105\"\n",
69
+ @loc.to_yaml)
70
+ end
71
+
54
72
  end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), 'test_base_geocoder')
3
+
4
+ class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
5
+
6
+ IP_SUCCESS=<<-EOF
7
+ <?xml version="1.0" encoding="UTF-8"?>
8
+ <geoPlugin>
9
+ <geoplugin_city>Belo Horizonte</geoplugin_city>
10
+ <geoplugin_region>Minas Gerais</geoplugin_region>
11
+ <geoplugin_areaCode>0</geoplugin_areaCode>
12
+ <geoplugin_dmaCode>0</geoplugin_dmaCode>
13
+ <geoplugin_countryCode>BR</geoplugin_countryCode>
14
+ <geoplugin_countryName>Brazil</geoplugin_countryName>
15
+ <geoplugin_continentCode>SA</geoplugin_continentCode>
16
+ <geoplugin_latitude>-19.916700</geoplugin_latitude>
17
+ <geoplugin_longitude>-43.933300</geoplugin_longitude>
18
+ <geoplugin_currencyCode>BRL</geoplugin_currencyCode>
19
+ <geoplugin_currencySymbol>&#82;&#36;</geoplugin_currencySymbol>
20
+ <geoplugin_currencyConverter>2.2575001717</geoplugin_currencyConverter>
21
+ </geoPlugin>
22
+ EOF
23
+
24
+ def setup
25
+ super
26
+ @success.provider = "geoPlugin"
27
+ end
28
+
29
+ def test_successful_lookup
30
+ success = MockSuccess.new
31
+ success.expects(:body).returns(IP_SUCCESS)
32
+ url = 'http://www.geoplugin.net/xml.gp?ip=200.150.38.66'
33
+ GeoKit::Geocoders::GeoPluginGeocoder.expects(:call_geocoder_service).with(url).returns(success)
34
+ location = GeoKit::Geocoders::GeoPluginGeocoder.geocode('200.150.38.66')
35
+ assert_not_nil location
36
+ assert_equal -19.916700, location.lat
37
+ assert_equal -43.933300, location.lng
38
+ assert_equal "Belo Horizonte", location.city
39
+ assert_equal "Minas Gerais", location.state
40
+ assert_equal "BR", location.country_code
41
+ assert_equal "geoPlugin", location.provider
42
+ assert location.success?
43
+ end
44
+
45
+ def test_invalid_ip
46
+ location = GeoKit::Geocoders::GeoPluginGeocoder.geocode("pixrum")
47
+ assert_not_nil location
48
+ assert !location.success?
49
+ end
50
+
51
+ def test_service_unavailable
52
+ failure = MockFailure.new
53
+ url = 'http://www.geoplugin.net/xml.gp?ip=10.10.10.10'
54
+ GeoKit::Geocoders::GeoPluginGeocoder.expects(:call_geocoder_service).with(url).returns(failure)
55
+ location = GeoKit::Geocoders::GeoPluginGeocoder.geocode("10.10.10.10")
56
+ assert_not_nil location
57
+ assert !location.success?
58
+ end
59
+ end
@@ -7,6 +7,10 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
7
7
  GOOGLE_FULL=<<-EOF.strip
8
8
  <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>100 spear st, san francisco, ca</name><Status><code>200</code><request>geocode</request></Status><Placemark><address>100 Spear St, San Francisco, CA 94105, USA</address><AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>San Francisco</SubAdministrativeAreaName><Locality><LocalityName>San Francisco</LocalityName><Thoroughfare><ThoroughfareName>100 Spear St</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>94105</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><Point><coordinates>-122.393985,37.792501,0</coordinates></Point></Placemark></Response></kml>
9
9
  EOF
10
+
11
+ GOOGLE_RESULT_WITH_SUGGESTED_BOUNDS=<<-EOF.strip
12
+ <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>100 spear st, san francisco, ca</name><Status><code>200</code><request>geocode</request></Status><Placemark><address>100 Spear St, San Francisco, CA 94105, USA</address><AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>San Francisco</SubAdministrativeAreaName><Locality><LocalityName>San Francisco</LocalityName><Thoroughfare><ThoroughfareName>100 Spear St</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>94105</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="37.7956328" south="37.7893376" east="-122.3908573" west="-122.3971525" /></ExtendedData><Point><coordinates>-122.393985,37.792501,0</coordinates></Point></Placemark></Response></kml>
13
+ EOF
10
14
 
11
15
  GOOGLE_CITY=<<-EOF.strip
12
16
  <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>San Francisco</name><Status><code>200</code><request>geocode</request></Status><Placemark><address>San Francisco, CA, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><Locality><LocalityName>San Francisco</LocalityName></Locality></AdministrativeArea></Country></AddressDetails><Point><coordinates>-122.418333,37.775000,0</coordinates></Point></Placemark></Response></kml>
@@ -14,6 +18,14 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
14
18
 
15
19
  GOOGLE_MULTI="<?xml version='1.0' encoding='UTF-8'?>\n<kml xmlns='http://earth.google.com/kml/2.0'><Response>\n <name>via Sandro Pertini 8, Ossona, MI</name>\n <Status>\n <code>200</code>\n <request>geocode</request>\n </Status>\n <Placemark id='p1'>\n <address>Via Sandro Pertini, 8, 20010 Mesero MI, Italy</address>\n <AddressDetails Accuracy='8' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>IT</CountryNameCode><CountryName>Italy</CountryName><AdministrativeArea><AdministrativeAreaName>Lombardy</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Milan</SubAdministrativeAreaName><Locality><LocalityName>Mesero</LocalityName><Thoroughfare><ThoroughfareName>8 Via Sandro Pertini</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>20010</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails>\n <Point><coordinates>8.8527131,45.4966243,0</coordinates></Point>\n </Placemark>\n <Placemark id='p2'>\n <address>Via Sandro Pertini, 20010 Ossona MI, Italy</address>\n <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>IT</CountryNameCode><CountryName>Italy</CountryName><AdministrativeArea><AdministrativeAreaName>Lombardy</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Milan</SubAdministrativeAreaName><Locality><LocalityName>Ossona</LocalityName><Thoroughfare><ThoroughfareName>Via Sandro Pertini</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>20010</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails>\n <Point><coordinates>8.9023200,45.5074444,0</coordinates></Point>\n </Placemark>\n</Response></kml>\n"
16
20
 
21
+ GOOGLE_COUNTRY_CODE_BIASED_RESULT = <<-EOF.strip
22
+ <?xml version="1.0" encoding="UTF-8" ?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>Syracuse</name><Status><code>200</code><request>geocode</request></Status><Placemark id="p1"><address>Syracuse, Italy</address><AddressDetails Accuracy="3" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>IT</CountryNameCode><CountryName>Italy</CountryName><AdministrativeArea><AdministrativeAreaName>Sicily</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Syracuse</SubAdministrativeAreaName></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="37.4125978" south="36.6441736" east="15.3367367" west="14.7724913" /></ExtendedData><Point><coordinates>14.9856176,37.0630218,0</coordinates></Point></Placemark></Response></kml>
23
+ EOF
24
+
25
+ GOOGLE_BOUNDS_BIASED_RESULT = <<-EOF.strip
26
+ <?xml version="1.0" encoding="UTF-8" ?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>Winnetka</name><Status><code>200</code><request>geocode</request></Status><Placemark id="p1"><address>Winnetka, California, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>CA</AdministrativeAreaName><AddressLine>Winnetka</AddressLine></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="34.2353090" south="34.1791050" east="-118.5534191" west="-118.5883200" /></ExtendedData><Point><coordinates>-118.5710220,34.2131710,0</coordinates></Point></Placemark></Response></kml>
27
+ EOF
28
+
17
29
  def setup
18
30
  super
19
31
  @google_full_hash = {:street_address=>"100 Spear St", :city=>"San Francisco", :state=>"CA", :zip=>"94105", :country_code=>"US"}
@@ -50,6 +62,15 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
50
62
  assert_equal "100 Spear St, San Francisco, CA 94105, USA", res.full_address #slightly different from yahoo
51
63
  assert_equal "google", res.provider
52
64
  end
65
+
66
+ def test_google_full_address_accuracy
67
+ response = MockSuccess.new
68
+ response.expects(:body).returns(GOOGLE_FULL)
69
+ url = "http://maps.google.com/maps/geo?q=#{Geokit::Inflector.url_escape(@full_address_short_zip)}&output=xml&key=Google&oe=utf-8"
70
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
71
+ res=Geokit::Geocoders::GoogleGeocoder.geocode(@google_full_loc)
72
+ assert_equal 8, res.accuracy
73
+ end
53
74
 
54
75
  def test_google_city
55
76
  response = MockSuccess.new
@@ -66,6 +87,15 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
66
87
  assert_equal "google", res.provider
67
88
  end
68
89
 
90
+ def test_google_city_accuracy
91
+ response = MockSuccess.new
92
+ response.expects(:body).returns(GOOGLE_CITY)
93
+ url = "http://maps.google.com/maps/geo?q=#{Geokit::Inflector.url_escape(@address)}&output=xml&key=Google&oe=utf-8"
94
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
95
+ res=Geokit::Geocoders::GoogleGeocoder.geocode(@address)
96
+ assert_equal 4, res.accuracy
97
+ end
98
+
69
99
  def test_google_city_with_geo_loc
70
100
  response = MockSuccess.new
71
101
  response.expects(:body).returns(GOOGLE_CITY)
@@ -81,6 +111,17 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
81
111
  assert_equal "google", res.provider
82
112
  end
83
113
 
114
+ def test_google_suggested_bounds
115
+ response = MockSuccess.new
116
+ response.expects(:body).returns(GOOGLE_RESULT_WITH_SUGGESTED_BOUNDS)
117
+ url = "http://maps.google.com/maps/geo?q=#{Geokit::Inflector.url_escape(@full_address_short_zip)}&output=xml&key=Google&oe=utf-8"
118
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
119
+ res = Geokit::Geocoders::GoogleGeocoder.geocode(@google_full_loc)
120
+
121
+ assert_instance_of Geokit::Bounds, res.suggested_bounds
122
+ assert_equal Geokit::Bounds.new(Geokit::LatLng.new(37.7893376, -122.3971525), Geokit::LatLng.new(37.7956328, -122.3908573)), res.suggested_bounds
123
+ end
124
+
84
125
  def test_service_unavailable
85
126
  response = MockFailure.new
86
127
  url = "http://maps.google.com/maps/geo?q=#{Geokit::Inflector.url_escape(@address)}&output=xml&key=Google&oe=utf-8"
@@ -113,4 +154,30 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
113
154
  assert_equal "Via Sandro Pertini", res.street_address
114
155
  assert_equal "google", res.provider
115
156
  end
157
+
158
+ def test_country_code_biasing
159
+ response = MockSuccess.new
160
+ response.expects(:body).returns(GOOGLE_COUNTRY_CODE_BIASED_RESULT)
161
+
162
+ url = "http://maps.google.com/maps/geo?q=Syracuse&output=xml&gl=it&key=Google&oe=utf-8"
163
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
164
+ biased_result = Geokit::Geocoders::GoogleGeocoder.geocode('Syracuse', :bias => 'it')
165
+
166
+ assert_equal 'IT', biased_result.country_code
167
+ assert_equal 'Sicily', biased_result.state
168
+ end
169
+
170
+ def test_bounds_biasing
171
+ response = MockSuccess.new
172
+ response.expects(:body).returns(GOOGLE_BOUNDS_BIASED_RESULT)
173
+
174
+ url = "http://maps.google.com/maps/geo?q=Winnetka&output=xml&ll=34.197693208849,-118.547160027785&spn=0.247047999999999,0.294914000000006&key=Google&oe=utf-8"
175
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
176
+
177
+ bounds = Geokit::Bounds.normalize([34.074081, -118.694401], [34.321129, -118.399487])
178
+ biased_result = Geokit::Geocoders::GoogleGeocoder.geocode('Winnetka', :bias => bounds)
179
+
180
+ assert_equal 'US', biased_result.country_code
181
+ assert_equal 'CA', biased_result.state
182
+ end
116
183
  end
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(__FILE__), 'test_base_geocoder')
2
+
3
+ Geokit::Geocoders::google = 'Google'
4
+
5
+ class GoogleReverseGeocoderTest < BaseGeocoderTest #:nodoc: all
6
+
7
+ GOOGLE_REVERSE_FULL=<<-EOF.strip
8
+ <?xml version="1.0" encoding="UTF-8" ?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>51.457833,7.016685</name><Status><code>200</code><request>geocode</request></Status><Placemark id="p1"><address>Porscheplatz 1, 45127 Essen, Deutschland</address><AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Essen</SubAdministrativeAreaName><Locality><LocalityName>Essen</LocalityName><DependentLocality><DependentLocalityName>Stadtkern</DependentLocalityName><Thoroughfare><ThoroughfareName>Porscheplatz 1</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>45127</PostalCodeNumber></PostalCode></DependentLocality></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="51.4609805" south="51.4546853" east="7.0198324" west="7.0135372" /></ExtendedData><Point><coordinates>7.0166848,51.4578329,0</coordinates></Point></Placemark><Placemark id="p2"><address>Stadtkern, Essen, Deutschland</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Essen</SubAdministrativeAreaName><Locality><LocalityName>Essen</LocalityName><DependentLocality><DependentLocalityName>Stadtkern</DependentLocalityName></DependentLocality></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="51.4630710" south="51.4506320" east="7.0193200" west="7.0026170" /></ExtendedData><Point><coordinates>7.0124328,51.4568201,0</coordinates></Point></Placemark><Placemark id="p3"><address>45127 Essen, Deutschland</address><AddressDetails Accuracy="5" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Essen</SubAdministrativeAreaName><Locality><LocalityName>Essen</LocalityName><PostalCode><PostalCodeNumber>45127</PostalCodeNumber></PostalCode></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="51.4637808" south="51.4503125" east="7.0231080" west="6.9965454" /></ExtendedData><Point><coordinates>7.0104543,51.4556194,0</coordinates></Point></Placemark><Placemark id="p4"><address>Essen, Deutschland</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Essen</SubAdministrativeAreaName><Locality><LocalityName>Essen</LocalityName></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="51.5342070" south="51.3475730" east="7.1376530" west="6.8943470" /></ExtendedData><Point><coordinates>7.0147614,51.4580686,0</coordinates></Point></Placemark><Placemark id="p5"><address>Essen, Deutschland</address><AddressDetails Accuracy="3" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Essen</SubAdministrativeAreaName></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="51.5342070" south="51.3475730" east="7.1376530" west="6.8943470" /></ExtendedData><Point><coordinates>7.0461136,51.4508381,0</coordinates></Point></Placemark><Placemark id="p6"><address>Nordrhein-Westfalen, Deutschland</address><AddressDetails Accuracy="2" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName><AdministrativeArea><AdministrativeAreaName>Nordrhein-Westfalen</AdministrativeAreaName></AdministrativeArea></Country></AddressDetails><ExtendedData><LatLonBox north="52.5314170" south="50.3225720" east="9.4615950" west="5.8663566" /></ExtendedData><Point><coordinates>7.6615938,51.4332367,0</coordinates></Point></Placemark><Placemark id="p7"><address>Deutschland</address><AddressDetails Accuracy="1" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>DE</CountryNameCode><CountryName>Deutschland</CountryName></Country></AddressDetails><ExtendedData><LatLonBox north="55.0568230" south="47.2701270" east="15.0418536" west="5.8663566" /></ExtendedData><Point><coordinates>10.4515260,51.1656910,0</coordinates></Point></Placemark></Response></kml>
9
+ EOF
10
+
11
+
12
+ def test_google_full_address
13
+ response = MockSuccess.new
14
+ response.expects(:body).returns(GOOGLE_REVERSE_FULL)
15
+
16
+
17
+ # http://maps.google.com/maps/geo?output=xml&oe=utf-8&ll=51.4578329,7.0166848&key=asdad
18
+
19
+ # #<Geokit::GeoLoc:0x10ec7ec
20
+ # @city="Essen",
21
+ # @country_code="DE",
22
+ # @full_address="Porscheplatz 1, 45127 Essen, Germany",
23
+ # @lat=51.4578329,
24
+ # @lng=7.0166848,
25
+ # @precision="address",
26
+ # @provider="google",
27
+ # @state="Nordrhein-Westfalen",
28
+ # @street_address="Porscheplatz 1",
29
+ # @success=true,
30
+ # @zip="45127">
31
+ #
32
+
33
+
34
+ @latlng = "51.4578329,7.0166848"
35
+
36
+ url = "http://maps.google.com/maps/geo?ll=#{Geokit::Inflector.url_escape(@latlng)}&output=xml&key=Google&oe=utf-8"
37
+ Geokit::Geocoders::GoogleGeocoder.expects(:call_geocoder_service).with(url).returns(response)
38
+ res=Geokit::Geocoders::GoogleGeocoder.reverse_geocode(@latlng)
39
+ assert_equal "Nordrhein-Westfalen", res.state
40
+ assert_equal "Essen", res.city
41
+ assert_equal "45127", res.zip
42
+ assert_equal "51.4578329,7.0166848", res.ll # slightly dif from yahoo
43
+ assert res.is_us? == false
44
+ assert_equal "Porscheplatz 1, 45127 Essen, Deutschland", res.full_address #slightly different from yahoo
45
+ assert_equal "google", res.provider
46
+ end
47
+
48
+
49
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'lib/geokit'
5
+
6
+ class InflectorTest < Test::Unit::TestCase #:nodoc: all
7
+
8
+ def test_titleize
9
+ assert_equal 'Sugar Grove', Geokit::Inflector.titleize('Sugar Grove')
10
+ assert_equal 'Sugar Grove', Geokit::Inflector.titleize('Sugar grove')
11
+ assert_equal 'Sugar Grove', Geokit::Inflector.titleize('sugar Grove')
12
+ assert_equal 'Sugar Grove', Geokit::Inflector.titleize('sugar grove')
13
+ end
14
+
15
+ def test_titleize_with_unicode
16
+ assert_equal 'Borås', Geokit::Inflector.titleize('Borås')
17
+ assert_equal 'Borås', Geokit::Inflector.titleize('borås')
18
+ assert_equal 'Borås (Abc)', Geokit::Inflector.titleize('Borås (Abc)')
19
+ assert_equal 'Borås (Abc)', Geokit::Inflector.titleize('Borås (abc)')
20
+ assert_equal 'Borås (Abc)', Geokit::Inflector.titleize('borås (Abc)')
21
+ assert_equal 'Borås (Abc)', Geokit::Inflector.titleize('borås (abc)')
22
+ end
23
+
24
+ end