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.
- data/Manifest.txt +3 -1
- data/README.markdown +89 -5
- data/Rakefile +12 -10
- data/lib/geokit.rb +3 -3
- data/lib/geokit/geocoders.rb +127 -46
- data/lib/geokit/mappable.rb +57 -8
- data/test/test_base_geocoder.rb +9 -7
- data/test/test_bounds.rb +23 -0
- data/test/test_geoloc.rb +18 -0
- data/test/test_geoplugin_geocoder.rb +59 -0
- data/test/test_google_geocoder.rb +67 -0
- data/test/test_google_reverse_geocoder.rb +49 -0
- data/test/test_inflector.rb +24 -0
- data/test/test_ipgeocoder.rb +88 -0
- data/test/test_latlng.rb +77 -0
- data/test/test_multi_geocoder.rb +58 -9
- data/test/test_multi_ip_geocoder.rb +38 -0
- data/test/test_yahoo_geocoder.rb +18 -0
- metadata +9 -3
data/lib/geokit/mappable.rb
CHANGED
@@ -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 - ['@
|
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}\
|
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
|
data/test/test_base_geocoder.rb
CHANGED
@@ -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
|
-
@
|
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::
|
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>R$</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
|