Pr0d1r2-geokit 1.3.2.10 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +0 -1
- data/README.markdown +38 -2
- data/generators/geokit_cached/geokit_cached_generator.rb +1 -1
- data/lib/geokit.rb +2 -2
- data/lib/geokit/cached/geocodable.rb +3 -3
- data/lib/geokit/cached/model.rb +4 -13
- data/lib/geokit/geocoders.rb +75 -15
- data/lib/geokit/mappable.rb +39 -5
- data/test/test_base_geocoder.rb +2 -1
- data/test/test_bounds.rb +23 -0
- data/test/test_google_geocoder.rb +49 -0
- data/test/test_inflector.rb +2 -0
- data/test/test_latlng.rb +61 -0
- data/test/test_multi_geocoder.rb +49 -10
- data/test/test_multi_ip_geocoder.rb +5 -5
- metadata +4 -6
data/Manifest.txt
CHANGED
data/README.markdown
CHANGED
@@ -124,12 +124,48 @@ creates a template with these settings and places it in `config/initializers/geo
|
|
124
124
|
* Geonames - a free geocoder
|
125
125
|
|
126
126
|
### address geocoders that also provide reverse geocoding
|
127
|
-
* Google Geocoder - requires an API key. Also supports multiple results.
|
127
|
+
* Google Geocoder - requires an API key. Also supports multiple results and bounding box/country code biasing.
|
128
128
|
|
129
129
|
### IP address geocoders
|
130
130
|
* IP Geocoder - geocodes an IP address using hostip.info's web service.
|
131
131
|
* Geoplugin.net -- another IP address geocoder
|
132
132
|
|
133
|
+
### Google Geocoder Tricks
|
134
|
+
|
135
|
+
The Google Geocoder sports a number of useful tricks that elevate it a little bit above the rest of the currently supported geocoders. For starters, it returns a `suggested_bounds` property for all your geocoded results, so you can more easily decide where and how to center a map on the places you geocode. Here's a quick example:
|
136
|
+
|
137
|
+
irb> res = Geokit::Geocoders::GoogleGeocoder.geocode('140 Market St, San Francisco, CA')
|
138
|
+
irb> pp res.suggested_bounds
|
139
|
+
#<Geokit::Bounds:0x53b36c
|
140
|
+
@ne=#<Geokit::LatLng:0x53b204 @lat=37.7968528, @lng=-122.3926933>,
|
141
|
+
@sw=#<Geokit::LatLng:0x53b2b8 @lat=37.7905576, @lng=-122.3989885>>
|
142
|
+
|
143
|
+
In addition, you can use viewport or country code biasing to make sure the geocoders prefers results within a specific area. Say we wanted to geocode the city of Syracuse in Italy. A normal geocoding query would look like this:
|
144
|
+
|
145
|
+
irb> res = Geokit::Geocoder::GoogleGeocoder.geocode('Syracuse')
|
146
|
+
irb> res.full_address
|
147
|
+
=> "Syracuse, NY, USA"
|
148
|
+
|
149
|
+
Not exactly what we were looking for. We know that Syracuse is in Italy, so we can tell the Google Geocoder to prefer results from Italy first, and then wander the Syracuses of the world. To do that, we have to pass Italy's ccTLD (country code top-level domain) to the `:bias` option of the `geocode` method. You can find a comprehensive list of all ccTLDs here: http://en.wikipedia.org/wiki/CcTLD.
|
150
|
+
|
151
|
+
irb> res = Geokit::Geocoder::GoogleGeocoder.geocode('Syracuse', :bias => 'it')
|
152
|
+
irb> res.full_address
|
153
|
+
=> "Syracuse, Italy"
|
154
|
+
|
155
|
+
Alternatively, we can speficy the geocoding bias as a bounding box object. Say we wanted to geocode the Winnetka district in Los Angeles.
|
156
|
+
|
157
|
+
irb> res = Geokit::Geocoder::GoogleGeocoder.geocode('Winnetka')
|
158
|
+
irb> res.full_address
|
159
|
+
=> "Winnetka, IL, USA"
|
160
|
+
|
161
|
+
Not it. What we can do is tell the geocoder to return results only from in and around LA.
|
162
|
+
|
163
|
+
irb> la_bounds = Geokit::Geocoder::GoogleGeocoder.geocode('Los Angeles').suggested_bounds
|
164
|
+
irb> res = Geokit::Geocoder::GoogleGeocoder.geocode('Winnetka', :bias => la_bounds)
|
165
|
+
irb> res.full_address
|
166
|
+
=> "Winnetka, California, USA"
|
167
|
+
|
168
|
+
|
133
169
|
### The Multigeocoder
|
134
170
|
Multi Geocoder - provides failover for the physical location geocoders, and also IP address geocoders. Its configured by setting Geokit::Geocoders::provider_order, and Geokit::Geocoders::ip_provider_order. You should call the Multi-Geocoder with its :geocode method, supplying one address parameter which is either a real street address, or an ip address. For example:
|
135
171
|
|
@@ -195,7 +231,7 @@ You must then also require such extenal file back in your main geokit configurat
|
|
195
231
|
# and use :external to specify this geocoder in your list of geocoders.
|
196
232
|
class ExternalGeocoder < Geocoder
|
197
233
|
private
|
198
|
-
def self.do_geocode(address)
|
234
|
+
def self.do_geocode(address, options = {})
|
199
235
|
# Main geocoding method
|
200
236
|
end
|
201
237
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class GeokitCachedGenerator < RspecModelGenerator
|
2
2
|
|
3
3
|
def initialize(runtime_args, runtime_options = {})
|
4
|
-
runtime_args = ['CachedLocation', 'address:string', 'provider:string', 'lng:float', 'lat:float'
|
4
|
+
runtime_args = ['CachedLocation', 'address:string', 'provider:string', 'lng:float', 'lat:float']
|
5
5
|
super
|
6
6
|
end
|
7
7
|
|
data/lib/geokit.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Geokit
|
2
|
-
VERSION = '1.
|
2
|
+
VERSION = '1.4.1'
|
3
3
|
# These defaults are used in Geokit::Mappable.distance_to and in acts_as_mappable
|
4
4
|
@@default_units = :miles
|
5
5
|
@@default_formula = :sphere
|
@@ -22,7 +22,7 @@ module Geokit
|
|
22
22
|
end
|
23
23
|
|
24
24
|
path = File.expand_path(File.dirname(__FILE__))
|
25
|
-
|
25
|
+
$:.unshift path unless $:.include?(path)
|
26
26
|
require 'geokit/geocoders'
|
27
27
|
require 'geokit/mappable'
|
28
28
|
require 'geokit/cached'
|
@@ -22,7 +22,7 @@ module Geokit
|
|
22
22
|
|
23
23
|
def geocode_address_cached
|
24
24
|
@geo = multi_geocoder.geocode(complete_address)
|
25
|
-
self.lat, self.lng, self.provider
|
25
|
+
self.lat, self.lng, self.provider = @geo.lat, @geo.lng, @geo.provider if @geo.success
|
26
26
|
end
|
27
27
|
|
28
28
|
def cache_locations?
|
@@ -34,9 +34,9 @@ module Geokit
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def cache_location!
|
37
|
-
cached_location.cache!(:lat => lat, :lng => lng, :provider => provider
|
37
|
+
cached_location.cache!(:lat => lat, :lng => lng, :provider => provider) if cache_locations?
|
38
38
|
end
|
39
39
|
|
40
40
|
end
|
41
41
|
end
|
42
|
-
end
|
42
|
+
end
|
data/lib/geokit/cached/model.rb
CHANGED
@@ -14,13 +14,12 @@ module Geokit
|
|
14
14
|
|
15
15
|
def cache!(attributes)
|
16
16
|
self.attributes = attributes
|
17
|
-
self.city = convert_to_utf8(self.city)
|
18
17
|
save if new_record? || changed?
|
19
18
|
end
|
20
19
|
|
21
20
|
def update!
|
22
21
|
if !by_google? && geo.success
|
23
|
-
self.lat, self.lng, self.provider
|
22
|
+
self.lat, self.lng, self.provider = geo.lat, geo.lng, geo.provider
|
24
23
|
save if changed?
|
25
24
|
end
|
26
25
|
end
|
@@ -36,7 +35,7 @@ module Geokit
|
|
36
35
|
|
37
36
|
def fake_geoloc
|
38
37
|
geoloc = Geokit::GeoLoc.new
|
39
|
-
geoloc.lat, geoloc.lng, geoloc.provider, geoloc.
|
38
|
+
geoloc.lat, geoloc.lng, geoloc.provider, geoloc.success = lat, lng, provider, success?
|
40
39
|
geoloc
|
41
40
|
end
|
42
41
|
|
@@ -45,7 +44,7 @@ module Geokit
|
|
45
44
|
end
|
46
45
|
|
47
46
|
def geoloc
|
48
|
-
fake_geoloc
|
47
|
+
successful_geoloc || fake_geoloc
|
49
48
|
end
|
50
49
|
|
51
50
|
def by_google?
|
@@ -57,7 +56,7 @@ module Geokit
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def changed?
|
60
|
-
lat_changed? || lng_changed? || changed_to_google?
|
59
|
+
lat_changed? || lng_changed? || changed_to_google?
|
61
60
|
end
|
62
61
|
|
63
62
|
def geocoding_occured?
|
@@ -68,14 +67,6 @@ module Geokit
|
|
68
67
|
!!(lat and lng)
|
69
68
|
end
|
70
69
|
|
71
|
-
def convert_to_utf8(str)
|
72
|
-
begin
|
73
|
-
Iconv.new('UTF-8', 'UTF-8').iconv(str)
|
74
|
-
rescue Iconv::Failure => iconv_exception
|
75
|
-
Iconv.new('UTF-8', 'ISO-8859-1').iconv(str)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
70
|
end
|
80
71
|
end
|
81
72
|
end
|
data/lib/geokit/geocoders.rb
CHANGED
@@ -83,7 +83,7 @@ module Geokit
|
|
83
83
|
|
84
84
|
def self.__define_accessors
|
85
85
|
class_variables.each do |v|
|
86
|
-
sym = v.delete("@").to_sym
|
86
|
+
sym = v.to_s.delete("@").to_sym
|
87
87
|
unless self.respond_to? sym
|
88
88
|
module_eval <<-EOS, __FILE__, __LINE__
|
89
89
|
def self.#{sym}
|
@@ -121,8 +121,8 @@ module Geokit
|
|
121
121
|
# Main method which calls the do_geocode template method which subclasses
|
122
122
|
# are responsible for implementing. Returns a populated GeoLoc or an
|
123
123
|
# empty one with a failed success code.
|
124
|
-
def self.geocode(address)
|
125
|
-
res = do_geocode(address)
|
124
|
+
def self.geocode(address, options = {})
|
125
|
+
res = do_geocode(address, options)
|
126
126
|
return res.nil? ? GeoLoc.new : res
|
127
127
|
end
|
128
128
|
# Main method which calls the do_reverse_geocode template method which subclasses
|
@@ -174,8 +174,8 @@ module Geokit
|
|
174
174
|
def self.inherited(clazz)
|
175
175
|
class_name = clazz.name.split('::').last
|
176
176
|
src = <<-END_SRC
|
177
|
-
def self.#{Geokit::Inflector.underscore(class_name)}(address)
|
178
|
-
#{class_name}.geocode(address)
|
177
|
+
def self.#{Geokit::Inflector.underscore(class_name)}(address, options = {})
|
178
|
+
#{class_name}.geocode(address, options)
|
179
179
|
end
|
180
180
|
END_SRC
|
181
181
|
class_eval(src)
|
@@ -201,7 +201,7 @@ module Geokit
|
|
201
201
|
private
|
202
202
|
|
203
203
|
# Template method which does the geocode lookup.
|
204
|
-
def self.do_geocode(address)
|
204
|
+
def self.do_geocode(address, options = {})
|
205
205
|
raise ArgumentError('Geocoder.ca requires a GeoLoc argument') unless address.is_a?(GeoLoc)
|
206
206
|
url = construct_request(address)
|
207
207
|
res = self.call_geocoder_service(url)
|
@@ -243,7 +243,7 @@ module Geokit
|
|
243
243
|
class UsGeocoder < Geocoder
|
244
244
|
|
245
245
|
private
|
246
|
-
def self.do_geocode(address)
|
246
|
+
def self.do_geocode(address, options = {})
|
247
247
|
address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
|
248
248
|
|
249
249
|
query = (address_str =~ /^\d{5}(?:-\d{4})?$/ ? "zip" : "address") + "=#{Geokit::Inflector::url_escape(address_str)}"
|
@@ -291,7 +291,7 @@ module Geokit
|
|
291
291
|
private
|
292
292
|
|
293
293
|
# Template method which does the geocode lookup.
|
294
|
-
def self.do_geocode(address)
|
294
|
+
def self.do_geocode(address, options = {})
|
295
295
|
address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
|
296
296
|
url="http://api.local.yahoo.com/MapsService/V1/geocode?appid=#{Geokit::Geocoders::yahoo}&location=#{Geokit::Inflector::url_escape(address_str)}"
|
297
297
|
res = self.call_geocoder_service(url)
|
@@ -337,7 +337,7 @@ module Geokit
|
|
337
337
|
private
|
338
338
|
|
339
339
|
# Template method which does the geocode lookup.
|
340
|
-
def self.do_geocode(address)
|
340
|
+
def self.do_geocode(address, options = {})
|
341
341
|
address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
|
342
342
|
# geonames need a space seperated search string
|
343
343
|
address_str.gsub!(/,/, " ")
|
@@ -402,15 +402,50 @@ module Geokit
|
|
402
402
|
end
|
403
403
|
|
404
404
|
# Template method which does the geocode lookup.
|
405
|
-
|
405
|
+
#
|
406
|
+
# Supports viewport/country code biasing
|
407
|
+
#
|
408
|
+
# ==== OPTIONS
|
409
|
+
# * :bias - This option makes the Google Geocoder return results biased to a particular
|
410
|
+
# country or viewport. Country code biasing is achieved by passing the ccTLD
|
411
|
+
# ('uk' for .co.uk, for example) as a :bias value. For a list of ccTLD's,
|
412
|
+
# look here: http://en.wikipedia.org/wiki/CcTLD. By default, the geocoder
|
413
|
+
# will be biased to results within the US (ccTLD .com).
|
414
|
+
#
|
415
|
+
# If you'd like the Google Geocoder to prefer results within a given viewport,
|
416
|
+
# you can pass a Geokit::Bounds object as the :bias value.
|
417
|
+
#
|
418
|
+
# ==== EXAMPLES
|
419
|
+
# # By default, the geocoder will return Syracuse, NY
|
420
|
+
# Geokit::Geocoders::GoogleGeocoder.geocode('Syracuse').country_code # => 'US'
|
421
|
+
# # With country code biasing, it returns Syracuse in Sicily, Italy
|
422
|
+
# Geokit::Geocoders::GoogleGeocoder.geocode('Syracuse', :bias => :it).country_code # => 'IT'
|
423
|
+
#
|
424
|
+
# # By default, the geocoder will return Winnetka, IL
|
425
|
+
# Geokit::Geocoders::GoogleGeocoder.geocode('Winnetka').state # => 'IL'
|
426
|
+
# # When biased to an bounding box around California, it will now return the Winnetka neighbourhood, CA
|
427
|
+
# bounds = Geokit::Bounds.normalize([34.074081, -118.694401], [34.321129, -118.399487])
|
428
|
+
# Geokit::Geocoders::GoogleGeocoder.geocode('Winnetka', :bias => bounds).state # => 'CA'
|
429
|
+
def self.do_geocode(address, options = {})
|
430
|
+
bias_str = options[:bias] ? construct_bias_string_from_options(options[:bias]) : ''
|
406
431
|
address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
|
407
|
-
res = self.call_geocoder_service("http://maps.google.com/maps/geo?q=#{Geokit::Inflector::url_escape(address_str)}&output=xml&key=#{Geokit::Geocoders::google}&oe=utf-8")
|
432
|
+
res = self.call_geocoder_service("http://maps.google.com/maps/geo?q=#{Geokit::Inflector::url_escape(address_str)}&output=xml#{bias_str}&key=#{Geokit::Geocoders::google}&oe=utf-8")
|
408
433
|
return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
|
409
434
|
xml = res.body
|
410
435
|
logger.debug "Google geocoding. Address: #{address}. Result: #{xml}"
|
411
436
|
return self.xml2GeoLoc(xml, address)
|
412
437
|
end
|
413
438
|
|
439
|
+
def self.construct_bias_string_from_options(bias)
|
440
|
+
if bias.is_a?(String) or bias.is_a?(Symbol)
|
441
|
+
# country code biasing
|
442
|
+
"&gl=#{bias.to_s.downcase}"
|
443
|
+
elsif bias.is_a?(Bounds)
|
444
|
+
# viewport biasing
|
445
|
+
"&ll=#{bias.center.ll}&spn=#{bias.to_span.ll}"
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
414
449
|
def self.xml2GeoLoc(xml, address="")
|
415
450
|
doc=REXML::Document.new(xml)
|
416
451
|
|
@@ -462,6 +497,14 @@ module Geokit
|
|
462
497
|
address_details=doc.elements['.//*[local-name() = "AddressDetails"]']
|
463
498
|
res.accuracy = address_details ? address_details.attributes['Accuracy'].to_i : 0
|
464
499
|
res.precision=%w{unknown country state state city zip zip+4 street address building}[res.accuracy]
|
500
|
+
|
501
|
+
# google returns a set of suggested boundaries for the geocoded result
|
502
|
+
if suggested_bounds = doc.elements['//LatLonBox']
|
503
|
+
res.suggested_bounds = Bounds.normalize(
|
504
|
+
[suggested_bounds.attributes['south'], suggested_bounds.attributes['west']],
|
505
|
+
[suggested_bounds.attributes['north'], suggested_bounds.attributes['east']])
|
506
|
+
end
|
507
|
+
|
465
508
|
res.success=true
|
466
509
|
|
467
510
|
return res
|
@@ -477,7 +520,7 @@ module Geokit
|
|
477
520
|
class GeoPluginGeocoder < Geocoder
|
478
521
|
private
|
479
522
|
|
480
|
-
def self.do_geocode(ip)
|
523
|
+
def self.do_geocode(ip, options = {})
|
481
524
|
return GeoLoc.new unless /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/.match(ip)
|
482
525
|
response = self.call_geocoder_service("http://www.geoplugin.net/xml.gp?ip=#{ip}")
|
483
526
|
return response.is_a?(Net::HTTPSuccess) ? parse_xml(response.body) : GeoLoc.new
|
@@ -510,7 +553,7 @@ module Geokit
|
|
510
553
|
# Given an IP address, returns a GeoLoc instance which contains latitude,
|
511
554
|
# longitude, city, and country code. Sets the success attribute to false if the ip
|
512
555
|
# parameter does not match an ip address.
|
513
|
-
def self.do_geocode(ip)
|
556
|
+
def self.do_geocode(ip, options = {})
|
514
557
|
return GeoLoc.new if '0.0.0.0' == ip
|
515
558
|
return GeoLoc.new unless /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/.match(ip)
|
516
559
|
url = "http://api.hostip.info/get_html.php?ip=#{ip}&position=true"
|
@@ -565,14 +608,14 @@ module Geokit
|
|
565
608
|
#
|
566
609
|
# The failover approach is crucial for production-grade apps, but is rarely used.
|
567
610
|
# 98% of your geocoding calls will be successful with the first call
|
568
|
-
def self.do_geocode(address)
|
611
|
+
def self.do_geocode(address, options = {})
|
569
612
|
geocode_ip = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.match(address)
|
570
613
|
provider_order = geocode_ip ? Geokit::Geocoders::ip_provider_order : Geokit::Geocoders::provider_order
|
571
614
|
|
572
615
|
provider_order.each do |provider|
|
573
616
|
begin
|
574
617
|
klass = Geokit::Geocoders.const_get "#{Geokit::Inflector::camelize(provider.to_s)}Geocoder"
|
575
|
-
res = klass.send :geocode, address
|
618
|
+
res = klass.send :geocode, address, options
|
576
619
|
return res if res.success?
|
577
620
|
rescue
|
578
621
|
logger.error("Something has gone very wrong during geocoding, OR you have configured an invalid class name in Geokit::Geocoders::provider_order. Address: #{address}. Provider: #{provider}")
|
@@ -581,6 +624,23 @@ module Geokit
|
|
581
624
|
# If we get here, we failed completely.
|
582
625
|
GeoLoc.new
|
583
626
|
end
|
627
|
+
|
628
|
+
# This method will call one or more geocoders in the order specified in the
|
629
|
+
# configuration until one of the geocoders work, only this time it's going
|
630
|
+
# to try to reverse geocode a geographical point.
|
631
|
+
def self.do_reverse_geocode(latlng)
|
632
|
+
Geokit::Geocoders::provider_order.each do |provider|
|
633
|
+
begin
|
634
|
+
klass = Geokit::Geocoders.const_get "#{Geokit::Inflector::camelize(provider.to_s)}Geocoder"
|
635
|
+
res = klass.send :reverse_geocode, latlng
|
636
|
+
return res if res.success?
|
637
|
+
rescue
|
638
|
+
logger.error("Something has gone very wrong during reverse geocoding, OR you have configured an invalid class name in Geokit::Geocoders::provider_order. LatLng: #{latlng}. Provider: #{provider}")
|
639
|
+
end
|
640
|
+
end
|
641
|
+
# If we get here, we failed completely.
|
642
|
+
GeoLoc.new
|
643
|
+
end
|
584
644
|
end
|
585
645
|
end
|
586
646
|
end
|
data/lib/geokit/mappable.rb
CHANGED
@@ -110,8 +110,8 @@ 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)
|
113
|
+
def geocode(location, options = {})
|
114
|
+
res = Geocoders::MultiGeocoder.geocode(location, options)
|
115
115
|
return res if res.success?
|
116
116
|
raise Geokit::Geocoders::GeocodeError
|
117
117
|
end
|
@@ -292,6 +292,30 @@ module Geokit
|
|
292
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.")
|
293
293
|
end
|
294
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
|
295
319
|
end
|
296
320
|
|
297
321
|
# This class encapsulates the result of a geocoding call.
|
@@ -322,7 +346,7 @@ module Geokit
|
|
322
346
|
# Attributes set upon return from geocoding. Success will be true for successful
|
323
347
|
# geocode lookups. The provider will be set to the name of the providing geocoder.
|
324
348
|
# Finally, precision is an indicator of the accuracy of the geocoding.
|
325
|
-
attr_accessor :success, :provider, :precision
|
349
|
+
attr_accessor :success, :provider, :precision, :suggested_bounds
|
326
350
|
# Street number and street name are extracted from the street address attribute.
|
327
351
|
attr_reader :street_number, :street_name
|
328
352
|
# accuracy is set for Yahoo and Google geocoders, it is a numeric value of the
|
@@ -387,8 +411,8 @@ module Geokit
|
|
387
411
|
# Sets the street address after capitalizing each word within the street address.
|
388
412
|
def street_address=(address)
|
389
413
|
@street_address = Geokit::Inflector::titleize(address) if address
|
390
|
-
end
|
391
|
-
|
414
|
+
end
|
415
|
+
|
392
416
|
# Returns a comma-delimited string consisting of the street address, city, state,
|
393
417
|
# zip, and country code. Only includes those attributes that are non-blank.
|
394
418
|
def to_geocodeable_s
|
@@ -457,6 +481,16 @@ module Geokit
|
|
457
481
|
other.is_a?(Bounds) ? self.sw == other.sw && self.ne == other.ne : false
|
458
482
|
end
|
459
483
|
|
484
|
+
# Equivalent to Google Maps API's .toSpan() method on GLatLng's.
|
485
|
+
#
|
486
|
+
# Returns a LatLng object, whose coordinates represent the size of a rectangle
|
487
|
+
# defined by these bounds.
|
488
|
+
def to_span
|
489
|
+
lat_span = (@ne.lat - @sw.lat).abs
|
490
|
+
lng_span = (crosses_meridian? ? 360 + @ne.lng - @sw.lng : @ne.lng - @sw.lng).abs
|
491
|
+
Geokit::LatLng.new(lat_span, lng_span)
|
492
|
+
end
|
493
|
+
|
460
494
|
class <<self
|
461
495
|
|
462
496
|
# returns an instance of bounds which completely encompases the given circle
|
data/test/test_base_geocoder.rb
CHANGED
@@ -29,7 +29,8 @@ class BaseGeocoderTest < Test::Unit::TestCase #:nodoc: all
|
|
29
29
|
@full_address = '100 Spear St, San Francisco, CA, 94105-1522, US'
|
30
30
|
@full_address_short_zip = '100 Spear St, San Francisco, CA, 94105, US'
|
31
31
|
|
32
|
-
@
|
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})
|
33
34
|
@success.success = true
|
34
35
|
end
|
35
36
|
|
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
|
@@ -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"}
|
@@ -99,6 +111,17 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
99
111
|
assert_equal "google", res.provider
|
100
112
|
end
|
101
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
|
+
|
102
125
|
def test_service_unavailable
|
103
126
|
response = MockFailure.new
|
104
127
|
url = "http://maps.google.com/maps/geo?q=#{Geokit::Inflector.url_escape(@address)}&output=xml&key=Google&oe=utf-8"
|
@@ -131,4 +154,30 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
131
154
|
assert_equal "Via Sandro Pertini", res.street_address
|
132
155
|
assert_equal "google", res.provider
|
133
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
|
134
183
|
end
|
data/test/test_inflector.rb
CHANGED
data/test/test_latlng.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'lib/geokit'
|
3
|
+
require 'mocha'
|
3
4
|
|
4
5
|
class LatLngTest < Test::Unit::TestCase #:nodoc: all
|
5
6
|
|
@@ -9,6 +10,25 @@ class LatLngTest < Test::Unit::TestCase #:nodoc: all
|
|
9
10
|
@point = Geokit::LatLng.new(@loc_a.lat, @loc_a.lng)
|
10
11
|
end
|
11
12
|
|
13
|
+
def valid_reverse_geocoding_result
|
14
|
+
location = Geokit::GeoLoc.new({
|
15
|
+
:city => "Essen",
|
16
|
+
:country_code => "DE",
|
17
|
+
:lat => 51.4578329,
|
18
|
+
:lng => 7.0166848,
|
19
|
+
:provider => "google",
|
20
|
+
:state => "Nordrhein-Westfalen",
|
21
|
+
:street_address => "Porscheplatz 1",
|
22
|
+
:zip => "45127"
|
23
|
+
})
|
24
|
+
|
25
|
+
location.full_address = "Porscheplatz 1, 45127 Essen, Deutschland"
|
26
|
+
location.precision = 'address'
|
27
|
+
location.provider = 'google'
|
28
|
+
location.success = true
|
29
|
+
location
|
30
|
+
end
|
31
|
+
|
12
32
|
def test_distance_between_same_using_defaults
|
13
33
|
assert_equal 0, Geokit::LatLng.distance_between(@loc_a, @loc_a)
|
14
34
|
assert_equal 0, @loc_a.distance_to(@loc_a)
|
@@ -145,4 +165,45 @@ class LatLngTest < Test::Unit::TestCase #:nodoc: all
|
|
145
165
|
assert first.eql?(second)
|
146
166
|
assert second.eql?(first)
|
147
167
|
end
|
168
|
+
|
169
|
+
def test_reverse_geocode
|
170
|
+
point = Geokit::LatLng.new(51.4578329, 7.0166848)
|
171
|
+
Geokit::Geocoders::MultiGeocoder.expects(:reverse_geocode).with(point).returns(valid_reverse_geocoding_result)
|
172
|
+
res = point.reverse_geocode
|
173
|
+
|
174
|
+
assert_equal "Nordrhein-Westfalen", res.state
|
175
|
+
assert_equal "Essen", res.city
|
176
|
+
assert_equal "45127", res.zip
|
177
|
+
assert_equal "51.4578329,7.0166848", res.ll # slightly dif from yahoo
|
178
|
+
assert res.is_us? == false
|
179
|
+
assert_equal "Porscheplatz 1, 45127 Essen, Deutschland", res.full_address #slightly different from yahoo
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_reverse_geocoding_using_specific_geocoder
|
183
|
+
point = Geokit::LatLng.new(51.4578329, 7.0166848)
|
184
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(point).returns(valid_reverse_geocoding_result)
|
185
|
+
res = point.reverse_geocode(:using => Geokit::Geocoders::GoogleGeocoder)
|
186
|
+
|
187
|
+
assert_equal "Nordrhein-Westfalen", res.state
|
188
|
+
assert_equal "Essen", res.city
|
189
|
+
assert_equal "45127", res.zip
|
190
|
+
assert_equal "51.4578329,7.0166848", res.ll # slightly dif from yahoo
|
191
|
+
assert res.is_us? == false
|
192
|
+
assert_equal "Porscheplatz 1, 45127 Essen, Deutschland", res.full_address #slightly different from yahoo
|
193
|
+
assert_equal "google", res.provider
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_reverse_geocoding_using_specific_geocoder_short_syntax
|
197
|
+
point = Geokit::LatLng.new(51.4578329, 7.0166848)
|
198
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(point).returns(valid_reverse_geocoding_result)
|
199
|
+
res = point.reverse_geocode(:using => :google)
|
200
|
+
|
201
|
+
assert_equal "Nordrhein-Westfalen", res.state
|
202
|
+
assert_equal "Essen", res.city
|
203
|
+
assert_equal "45127", res.zip
|
204
|
+
assert_equal "51.4578329,7.0166848", res.ll # slightly dif from yahoo
|
205
|
+
assert res.is_us? == false
|
206
|
+
assert_equal "Porscheplatz 1, 45127 Essen, Deutschland", res.full_address #slightly different from yahoo
|
207
|
+
assert_equal "google", res.provider
|
208
|
+
end
|
148
209
|
end
|
data/test/test_multi_geocoder.rb
CHANGED
@@ -10,27 +10,27 @@ class MultiGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_successful_first
|
13
|
-
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address).returns(@success)
|
13
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address, {}).returns(@success)
|
14
14
|
assert_equal @success, Geokit::Geocoders::MultiGeocoder.geocode(@address)
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_failover
|
18
|
-
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address).returns(@failure)
|
19
|
-
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address).returns(@success)
|
18
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
19
|
+
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address, {}).returns(@success)
|
20
20
|
assert_equal @success, Geokit::Geocoders::MultiGeocoder.geocode(@address)
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_double_failover
|
24
|
-
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address).returns(@failure)
|
25
|
-
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address).returns(@failure)
|
26
|
-
Geokit::Geocoders::UsGeocoder.expects(:geocode).with(@address).returns(@success)
|
24
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
25
|
+
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
26
|
+
Geokit::Geocoders::UsGeocoder.expects(:geocode).with(@address, {}).returns(@success)
|
27
27
|
assert_equal @success, Geokit::Geocoders::MultiGeocoder.geocode(@address)
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_failure
|
31
|
-
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address).returns(@failure)
|
32
|
-
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address).returns(@failure)
|
33
|
-
Geokit::Geocoders::UsGeocoder.expects(:geocode).with(@address).returns(@failure)
|
31
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
32
|
+
Geokit::Geocoders::YahooGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
33
|
+
Geokit::Geocoders::UsGeocoder.expects(:geocode).with(@address, {}).returns(@failure)
|
34
34
|
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.geocode(@address)
|
35
35
|
end
|
36
36
|
|
@@ -45,10 +45,49 @@ class MultiGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
45
45
|
t1, t2 = Geokit::Geocoders.provider_order, Geokit::Geocoders.ip_provider_order # will need to reset after
|
46
46
|
Geokit::Geocoders.provider_order = [:google]
|
47
47
|
Geokit::Geocoders.ip_provider_order = [:geo_plugin]
|
48
|
-
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with("").returns(@failure)
|
48
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:geocode).with("", {}).returns(@failure)
|
49
49
|
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).never
|
50
50
|
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.geocode("")
|
51
51
|
Geokit::Geocoders.provider_order, Geokit::Geocoders.ip_provider_order = t1, t2 # reset to orig values
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_reverse_geocode_successful_first
|
55
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(@latlng).returns(@success)
|
56
|
+
assert_equal @success, Geokit::Geocoders::MultiGeocoder.reverse_geocode(@latlng)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_reverse_geocode_failover
|
60
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
61
|
+
Geokit::Geocoders::YahooGeocoder.expects(:reverse_geocode).with(@latlng).returns(@success)
|
62
|
+
assert_equal @success, Geokit::Geocoders::MultiGeocoder.reverse_geocode(@latlng)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_reverse_geocode_double_failover
|
66
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
67
|
+
Geokit::Geocoders::YahooGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
68
|
+
Geokit::Geocoders::UsGeocoder.expects(:reverse_geocode).with(@latlng).returns(@success)
|
69
|
+
assert_equal @success, Geokit::Geocoders::MultiGeocoder.reverse_geocode(@latlng)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_reverse_geocode_failure
|
73
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
74
|
+
Geokit::Geocoders::YahooGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
75
|
+
Geokit::Geocoders::UsGeocoder.expects(:reverse_geocode).with(@latlng).returns(@failure)
|
76
|
+
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.reverse_geocode(@latlng)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_reverse_geocode_with_invalid_provider
|
80
|
+
temp = Geokit::Geocoders::provider_order
|
81
|
+
Geokit::Geocoders.provider_order = [:bogus]
|
82
|
+
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.reverse_geocode(@latlng)
|
83
|
+
Geokit::Geocoders.provider_order = temp
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_reverse_geocode_with_blank_latlng
|
87
|
+
t1 = Geokit::Geocoders.provider_order # will need to reset after
|
88
|
+
Geokit::Geocoders.provider_order = [:google]
|
89
|
+
Geokit::Geocoders::GoogleGeocoder.expects(:reverse_geocode).with("").returns(@failure)
|
90
|
+
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.reverse_geocode("")
|
91
|
+
Geokit::Geocoders.provider_order = t1 # reset to orig values
|
92
|
+
end
|
54
93
|
end
|
@@ -12,19 +12,19 @@ class MultiIpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_successful_first
|
15
|
-
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address).returns(@success)
|
15
|
+
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address, {}).returns(@success)
|
16
16
|
assert_equal @success, Geokit::Geocoders::MultiGeocoder.geocode(@ip_address)
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_failover
|
20
|
-
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address).returns(@failure)
|
21
|
-
Geokit::Geocoders::IpGeocoder.expects(:geocode).with(@ip_address).returns(@success)
|
20
|
+
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address, {}).returns(@failure)
|
21
|
+
Geokit::Geocoders::IpGeocoder.expects(:geocode).with(@ip_address, {}).returns(@success)
|
22
22
|
assert_equal @success, Geokit::Geocoders::MultiGeocoder.geocode(@ip_address)
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_failure
|
26
|
-
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address).returns(@failure)
|
27
|
-
Geokit::Geocoders::IpGeocoder.expects(:geocode).with(@ip_address).returns(@failure)
|
26
|
+
Geokit::Geocoders::GeoPluginGeocoder.expects(:geocode).with(@ip_address, {}).returns(@failure)
|
27
|
+
Geokit::Geocoders::IpGeocoder.expects(:geocode).with(@ip_address, {}).returns(@failure)
|
28
28
|
assert_equal @failure, Geokit::Geocoders::MultiGeocoder.geocode(@ip_address)
|
29
29
|
end
|
30
30
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Pr0d1r2-geokit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andre Lewis and Bill Eisenhauer and Pr0d1r2 (Marcin Nowicki)
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-17 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Geokit Gem
|
16
|
+
description: Geokit Gem
|
17
17
|
email:
|
18
18
|
- andre@earthcode.com / bill_eisenhauer@yahoo.com / pr0d1r2@gmail.com
|
19
19
|
executables: []
|
@@ -48,8 +48,6 @@ files:
|
|
48
48
|
- lib/geokit/geocoders/cached_multi_geocoder.rb
|
49
49
|
has_rdoc: true
|
50
50
|
homepage: http://geokit.rubyforge.org
|
51
|
-
licenses: []
|
52
|
-
|
53
51
|
post_install_message:
|
54
52
|
rdoc_options:
|
55
53
|
- --main
|
@@ -71,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
69
|
requirements: []
|
72
70
|
|
73
71
|
rubyforge_project: geokit
|
74
|
-
rubygems_version: 1.
|
72
|
+
rubygems_version: 1.2.0
|
75
73
|
signing_key:
|
76
74
|
specification_version: 2
|
77
75
|
summary: none
|