rjaswal-geokit 1.5.0.2 → 1.5.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/README.markdown +5 -3
- data/lib/geokit/mappable.rb +57 -59
- data/test/test_geoloc.rb +1 -1
- data/test/test_geoplugin_geocoder.rb +2 -2
- data/test/test_google_geocoder.rb +1 -1
- data/test/test_google_geocoder3.rb +536 -0
- data/test/test_ipgeocoder.rb +32 -10
- data/test/test_yahoo_geocoder.rb +34 -16
- metadata +17 -5
data/README.markdown
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The Geokit gem provides:
|
|
4
4
|
|
|
5
5
|
* Distance calculations between two points on the earth. Calculate the distance in miles, kilometers, or nautical miles, with all the trigonometry abstracted away by GeoKit.
|
|
6
|
-
* Geocoding from multiple providers. It supports Google, Yahoo, Geocoder.us, and Geocoder.ca geocoders, and others. It provides a uniform response structure from all of them.
|
|
6
|
+
* Geocoding from multiple providers. It supports Google (API v2), Google (API v3), Bing, Yahoo, Geocoder.us, and Geocoder.ca geocoders, and others. It provides a uniform response structure from all of them.
|
|
7
7
|
It also provides a fail-over mechanism, in case your input fails to geocode in one service.
|
|
8
8
|
* Rectangular bounds calculations: is a point within a given rectangular bounds?
|
|
9
9
|
* Heading and midpoint calculations
|
|
@@ -16,7 +16,9 @@ Combine this gem with the [geokit-rails plugin](http://github.com/andre/geokit-r
|
|
|
16
16
|
|
|
17
17
|
## INSTALL
|
|
18
18
|
|
|
19
|
-
sudo gem install geokit
|
|
19
|
+
sudo gem install rjaswal-geokit
|
|
20
|
+
or for latest use
|
|
21
|
+
./script/plugin install git://github.com/rjaswal/geokit-gem.git
|
|
20
22
|
|
|
21
23
|
## QUICK START
|
|
22
24
|
|
|
@@ -54,7 +56,7 @@ If you're using this gem by itself, here are the configuration options:
|
|
|
54
56
|
# This is the timeout value in seconds to be used for calls to the geocoder web
|
|
55
57
|
# services. For no timeout at all, comment out the setting. The timeout unit
|
|
56
58
|
# is in seconds.
|
|
57
|
-
Geokit::Geocoders::
|
|
59
|
+
Geokit::Geocoders::request_timeout = 3
|
|
58
60
|
|
|
59
61
|
# These settings are used if web service calls must be routed through a proxy.
|
|
60
62
|
# These setting can be nil if not needed, otherwise, addr and port must be
|
data/lib/geokit/mappable.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
#require 'forwardable'
|
|
2
|
-
|
|
3
1
|
module Geokit
|
|
4
2
|
# Contains class and instance methods providing distance calcuation services. This
|
|
5
3
|
# module is meant to be mixed into classes containing lat and lng attributes where
|
|
@@ -22,12 +20,12 @@ module Geokit
|
|
|
22
20
|
KMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * KMS_PER_MILE
|
|
23
21
|
NMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * NMS_PER_MILE
|
|
24
22
|
LATITUDE_DEGREES = EARTH_RADIUS_IN_MILES / MILES_PER_LATITUDE_DEGREE
|
|
25
|
-
|
|
23
|
+
|
|
26
24
|
# Mix below class methods into the includer.
|
|
27
25
|
def self.included(receiver) # :nodoc:
|
|
28
26
|
receiver.extend ClassMethods
|
|
29
27
|
end
|
|
30
|
-
|
|
28
|
+
|
|
31
29
|
module ClassMethods #:nodoc:
|
|
32
30
|
# Returns the distance between two points. The from and to parameters are
|
|
33
31
|
# required to have lat and lng attributes. Valid options are:
|
|
@@ -43,15 +41,15 @@ module Geokit
|
|
|
43
41
|
when :sphere
|
|
44
42
|
begin
|
|
45
43
|
units_sphere_multiplier(units) *
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
Math.acos( Math.sin(deg2rad(from.lat)) * Math.sin(deg2rad(to.lat)) +
|
|
45
|
+
Math.cos(deg2rad(from.lat)) * Math.cos(deg2rad(to.lat)) *
|
|
46
|
+
Math.cos(deg2rad(to.lng) - deg2rad(from.lng)))
|
|
49
47
|
rescue Errno::EDOM
|
|
50
48
|
0.0
|
|
51
49
|
end
|
|
52
50
|
when :flat
|
|
53
51
|
Math.sqrt((units_per_latitude_degree(units)*(from.lat-to.lat))**2 +
|
|
54
|
-
|
|
52
|
+
(units_per_longitude_degree(from.lat, units)*(from.lng-to.lng))**2)
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
|
|
@@ -69,23 +67,23 @@ module Geokit
|
|
|
69
67
|
x=Math.cos(from_lat)*Math.sin(to_lat)-Math.sin(from_lat)*Math.cos(to_lat)*Math.cos(d_lng)
|
|
70
68
|
heading=to_heading(Math.atan2(y,x))
|
|
71
69
|
end
|
|
72
|
-
|
|
70
|
+
|
|
73
71
|
# Given a start point, distance, and heading (in degrees), provides
|
|
74
72
|
# an endpoint. Returns a LatLng instance. Typically, the instance method
|
|
75
73
|
# will be used instead of this method.
|
|
76
74
|
def endpoint(start,heading, distance, options={})
|
|
77
75
|
units = options[:units] || Geokit::default_units
|
|
78
76
|
radius = case units
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
when :kms; EARTH_RADIUS_IN_KMS
|
|
78
|
+
when :nms; EARTH_RADIUS_IN_NMS
|
|
79
|
+
else EARTH_RADIUS_IN_MILES
|
|
80
|
+
end
|
|
83
81
|
start=Geokit::LatLng.normalize(start)
|
|
84
82
|
lat=deg2rad(start.lat)
|
|
85
83
|
lng=deg2rad(start.lng)
|
|
86
84
|
heading=deg2rad(heading)
|
|
87
85
|
distance=distance.to_f
|
|
88
|
-
|
|
86
|
+
|
|
89
87
|
end_lat=Math.asin(Math.sin(lat)*Math.cos(distance/radius) +
|
|
90
88
|
Math.cos(lat)*Math.sin(distance/radius)*Math.cos(heading))
|
|
91
89
|
|
|
@@ -103,29 +101,29 @@ module Geokit
|
|
|
103
101
|
from=Geokit::LatLng.normalize(from)
|
|
104
102
|
|
|
105
103
|
units = options[:units] || Geokit::default_units
|
|
106
|
-
|
|
104
|
+
|
|
107
105
|
heading=from.heading_to(to)
|
|
108
106
|
distance=from.distance_to(to,options)
|
|
109
107
|
midpoint=from.endpoint(heading,distance/2,options)
|
|
110
108
|
end
|
|
111
|
-
|
|
109
|
+
|
|
112
110
|
# Geocodes a location using the multi geocoder.
|
|
113
111
|
def geocode(location, options = {})
|
|
114
112
|
res = Geocoders::MultiGeocoder.geocode(location, options)
|
|
115
113
|
return res if res.success?
|
|
116
114
|
raise Geokit::Geocoders::GeocodeError
|
|
117
115
|
end
|
|
118
|
-
|
|
116
|
+
|
|
119
117
|
protected
|
|
120
|
-
|
|
118
|
+
|
|
121
119
|
def deg2rad(degrees)
|
|
122
120
|
degrees.to_f / 180.0 * Math::PI
|
|
123
121
|
end
|
|
124
|
-
|
|
122
|
+
|
|
125
123
|
def rad2deg(rad)
|
|
126
124
|
rad.to_f * 180.0 / Math::PI
|
|
127
125
|
end
|
|
128
|
-
|
|
126
|
+
|
|
129
127
|
def to_heading(rad)
|
|
130
128
|
(rad2deg(rad)+360)%360
|
|
131
129
|
end
|
|
@@ -133,36 +131,36 @@ module Geokit
|
|
|
133
131
|
# Returns the multiplier used to obtain the correct distance units.
|
|
134
132
|
def units_sphere_multiplier(units)
|
|
135
133
|
case units
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
when :kms; EARTH_RADIUS_IN_KMS
|
|
135
|
+
when :nms; EARTH_RADIUS_IN_NMS
|
|
136
|
+
else EARTH_RADIUS_IN_MILES
|
|
139
137
|
end
|
|
140
138
|
end
|
|
141
139
|
|
|
142
140
|
# Returns the number of units per latitude degree.
|
|
143
141
|
def units_per_latitude_degree(units)
|
|
144
142
|
case units
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
when :kms; KMS_PER_LATITUDE_DEGREE
|
|
144
|
+
when :nms; NMS_PER_LATITUDE_DEGREE
|
|
145
|
+
else MILES_PER_LATITUDE_DEGREE
|
|
148
146
|
end
|
|
149
147
|
end
|
|
150
|
-
|
|
148
|
+
|
|
151
149
|
# Returns the number units per longitude degree.
|
|
152
150
|
def units_per_longitude_degree(lat, units)
|
|
153
151
|
miles_per_longitude_degree = (LATITUDE_DEGREES * Math.cos(lat * PI_DIV_RAD)).abs
|
|
154
152
|
case units
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
when :kms; miles_per_longitude_degree * KMS_PER_MILE
|
|
154
|
+
when :nms; miles_per_longitude_degree * NMS_PER_MILE
|
|
155
|
+
else miles_per_longitude_degree
|
|
158
156
|
end
|
|
159
157
|
end
|
|
160
158
|
end
|
|
161
|
-
|
|
159
|
+
|
|
162
160
|
# -----------------------------------------------------------------------------------------------
|
|
163
161
|
# Instance methods below here
|
|
164
162
|
# -----------------------------------------------------------------------------------------------
|
|
165
|
-
|
|
163
|
+
|
|
166
164
|
# Extracts a LatLng instance. Use with models that are acts_as_mappable
|
|
167
165
|
def to_lat_lng
|
|
168
166
|
return self if instance_of?(Geokit::LatLng) || instance_of?(Geokit::GeoLoc)
|
|
@@ -190,7 +188,7 @@ module Geokit
|
|
|
190
188
|
def heading_from(other)
|
|
191
189
|
self.class.heading_between(other,self)
|
|
192
190
|
end
|
|
193
|
-
|
|
191
|
+
|
|
194
192
|
# Returns the endpoint, given a heading (in degrees) and distance.
|
|
195
193
|
# Valid option:
|
|
196
194
|
# :units - valid values are :miles, :kms, or :nms (:miles is the default)
|
|
@@ -204,7 +202,7 @@ module Geokit
|
|
|
204
202
|
def midpoint_to(other, options={})
|
|
205
203
|
self.class.midpoint_between(self,other,options)
|
|
206
204
|
end
|
|
207
|
-
|
|
205
|
+
|
|
208
206
|
end
|
|
209
207
|
|
|
210
208
|
class LatLng
|
|
@@ -235,12 +233,12 @@ module Geokit
|
|
|
235
233
|
def ll
|
|
236
234
|
"#{lat},#{lng}"
|
|
237
235
|
end
|
|
238
|
-
|
|
236
|
+
|
|
239
237
|
#returns a string with comma-separated lat,lng values
|
|
240
238
|
def to_s
|
|
241
239
|
ll
|
|
242
240
|
end
|
|
243
|
-
|
|
241
|
+
|
|
244
242
|
#returns a two-element array
|
|
245
243
|
def to_a
|
|
246
244
|
[lat,lng]
|
|
@@ -250,15 +248,15 @@ module Geokit
|
|
|
250
248
|
def ==(other)
|
|
251
249
|
other.is_a?(LatLng) ? self.lat == other.lat && self.lng == other.lng : false
|
|
252
250
|
end
|
|
253
|
-
|
|
251
|
+
|
|
254
252
|
def hash
|
|
255
253
|
lat.hash + lng.hash
|
|
256
254
|
end
|
|
257
|
-
|
|
255
|
+
|
|
258
256
|
def eql?(other)
|
|
259
257
|
self == other
|
|
260
258
|
end
|
|
261
|
-
|
|
259
|
+
|
|
262
260
|
# A *class* method to take anything which can be inferred as a point and generate
|
|
263
261
|
# a LatLng from it. You should use this anything you're not sure what the input is,
|
|
264
262
|
# and want to deal with it as a LatLng if at all possible. Can take:
|
|
@@ -271,7 +269,7 @@ module Geokit
|
|
|
271
269
|
def self.normalize(thing,other=nil)
|
|
272
270
|
# if an 'other' thing is supplied, normalize the input by creating an array of two elements
|
|
273
271
|
thing=[thing,other] if other
|
|
274
|
-
|
|
272
|
+
|
|
275
273
|
if thing.is_a?(String)
|
|
276
274
|
thing.strip!
|
|
277
275
|
if match=thing.match(/(\-?\d+\.?\d*)[, ] ?(\-?\d+\.?\d*)$/)
|
|
@@ -288,10 +286,10 @@ module Geokit
|
|
|
288
286
|
elsif thing.class.respond_to?(:acts_as_mappable) && thing.class.respond_to?(:distance_column_name)
|
|
289
287
|
return thing.to_lat_lng
|
|
290
288
|
end
|
|
291
|
-
|
|
289
|
+
|
|
292
290
|
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
291
|
end
|
|
294
|
-
|
|
292
|
+
|
|
295
293
|
# Reverse geocodes a LatLng object using the MultiGeocoder (default), or optionally
|
|
296
294
|
# using a geocoder of your choosing. Returns a new Geokit::GeoLoc object
|
|
297
295
|
#
|
|
@@ -313,7 +311,7 @@ module Geokit
|
|
|
313
311
|
else
|
|
314
312
|
raise ArgumentError.new("#{options[:using]} is not a valid geocoder.")
|
|
315
313
|
end
|
|
316
|
-
|
|
314
|
+
|
|
317
315
|
provider.send(:reverse_geocode, self)
|
|
318
316
|
end
|
|
319
317
|
end
|
|
@@ -355,7 +353,7 @@ module Geokit
|
|
|
355
353
|
# Constructor expects a hash of symbols to correspond with attributes.
|
|
356
354
|
def initialize(h={})
|
|
357
355
|
@all = [self]
|
|
358
|
-
|
|
356
|
+
|
|
359
357
|
@street_address=h[:street_address]
|
|
360
358
|
@street_number=nil
|
|
361
359
|
@street_name=nil
|
|
@@ -374,7 +372,7 @@ module Geokit
|
|
|
374
372
|
def is_us?
|
|
375
373
|
country_code == 'US'
|
|
376
374
|
end
|
|
377
|
-
|
|
375
|
+
|
|
378
376
|
def success?
|
|
379
377
|
success == true
|
|
380
378
|
end
|
|
@@ -419,7 +417,7 @@ module Geokit
|
|
|
419
417
|
@street_address = address
|
|
420
418
|
end
|
|
421
419
|
end
|
|
422
|
-
|
|
420
|
+
|
|
423
421
|
# Returns a comma-delimited string consisting of the street address, city, state,
|
|
424
422
|
# zip, and country code. Only includes those attributes that are non-blank.
|
|
425
423
|
def to_geocodeable_s
|
|
@@ -427,7 +425,7 @@ module Geokit
|
|
|
427
425
|
a.delete_if { |e| !e || e == '' }
|
|
428
426
|
a.join(', ')
|
|
429
427
|
end
|
|
430
|
-
|
|
428
|
+
|
|
431
429
|
def to_yaml_properties
|
|
432
430
|
(instance_variables - ['@all']).sort
|
|
433
431
|
end
|
|
@@ -437,33 +435,33 @@ module Geokit
|
|
|
437
435
|
"Provider: #{provider}\nStreet: #{street_address}\nCity: #{city}\nState: #{state}\nZip: #{zip}\nLatitude: #{lat}\nLongitude: #{lng}\nCountry: #{country_code}\nSuccess: #{success}"
|
|
438
436
|
end
|
|
439
437
|
end
|
|
440
|
-
|
|
438
|
+
|
|
441
439
|
# Bounds represents a rectangular bounds, defined by the SW and NE corners
|
|
442
440
|
class Bounds
|
|
443
441
|
# sw and ne are LatLng objects
|
|
444
442
|
attr_accessor :sw, :ne
|
|
445
|
-
|
|
443
|
+
|
|
446
444
|
# provide sw and ne to instantiate a new Bounds instance
|
|
447
445
|
def initialize(sw,ne)
|
|
448
446
|
raise ArgumentError if !(sw.is_a?(Geokit::LatLng) && ne.is_a?(Geokit::LatLng))
|
|
449
447
|
@sw,@ne=sw,ne
|
|
450
448
|
end
|
|
451
|
-
|
|
449
|
+
|
|
452
450
|
#returns the a single point which is the center of the rectangular bounds
|
|
453
451
|
def center
|
|
454
452
|
@sw.midpoint_to(@ne)
|
|
455
453
|
end
|
|
456
|
-
|
|
454
|
+
|
|
457
455
|
# a simple string representation:sw,ne
|
|
458
456
|
def to_s
|
|
459
457
|
"#{@sw.to_s},#{@ne.to_s}"
|
|
460
458
|
end
|
|
461
|
-
|
|
459
|
+
|
|
462
460
|
# a two-element array of two-element arrays: sw,ne
|
|
463
461
|
def to_a
|
|
464
462
|
[@sw.to_a, @ne.to_a]
|
|
465
463
|
end
|
|
466
|
-
|
|
464
|
+
|
|
467
465
|
# Returns true if the bounds contain the passed point.
|
|
468
466
|
# allows for bounds which cross the meridian
|
|
469
467
|
def contains?(point)
|
|
@@ -476,7 +474,7 @@ module Geokit
|
|
|
476
474
|
end
|
|
477
475
|
res
|
|
478
476
|
end
|
|
479
|
-
|
|
477
|
+
|
|
480
478
|
# returns true if the bounds crosses the international dateline
|
|
481
479
|
def crosses_meridian?
|
|
482
480
|
@sw.lng > @ne.lng
|
|
@@ -487,7 +485,7 @@ module Geokit
|
|
|
487
485
|
def ==(other)
|
|
488
486
|
other.is_a?(Bounds) ? self.sw == other.sw && self.ne == other.ne : false
|
|
489
487
|
end
|
|
490
|
-
|
|
488
|
+
|
|
491
489
|
# Equivalent to Google Maps API's .toSpan() method on GLatLng's.
|
|
492
490
|
#
|
|
493
491
|
# Returns a LatLng object, whose coordinates represent the size of a rectangle
|
|
@@ -497,9 +495,9 @@ module Geokit
|
|
|
497
495
|
lng_span = (crosses_meridian? ? 360 + @ne.lng - @sw.lng : @ne.lng - @sw.lng).abs
|
|
498
496
|
Geokit::LatLng.new(lat_span, lng_span)
|
|
499
497
|
end
|
|
500
|
-
|
|
498
|
+
|
|
501
499
|
class <<self
|
|
502
|
-
|
|
500
|
+
|
|
503
501
|
# returns an instance of bounds which completely encompases the given circle
|
|
504
502
|
def from_point_and_radius(point,radius,options={})
|
|
505
503
|
point=LatLng.normalize(point)
|
|
@@ -511,7 +509,7 @@ module Geokit
|
|
|
511
509
|
ne=Geokit::LatLng.new(p0.lat,p90.lng)
|
|
512
510
|
Geokit::Bounds.new(sw,ne)
|
|
513
511
|
end
|
|
514
|
-
|
|
512
|
+
|
|
515
513
|
# Takes two main combinations of arguments to create a bounds:
|
|
516
514
|
# point,point (this is the only one which takes two arguments
|
|
517
515
|
# [point,point]
|
|
@@ -521,7 +519,7 @@ module Geokit
|
|
|
521
519
|
def normalize (thing,other=nil)
|
|
522
520
|
# maybe this will be simple -- an actual bounds object is passed, and we can all go home
|
|
523
521
|
return thing if thing.is_a? Bounds
|
|
524
|
-
|
|
522
|
+
|
|
525
523
|
# no? OK, if there's no "other," the thing better be a two-element array
|
|
526
524
|
thing,other=thing if !other && thing.is_a?(Array) && thing.size==2
|
|
527
525
|
|
data/test/test_geoloc.rb
CHANGED
|
@@ -65,7 +65,7 @@ class GeoLocTest < Test::Unit::TestCase #:nodoc: all
|
|
|
65
65
|
@loc.zip = '94105'
|
|
66
66
|
@loc.country_code = 'US'
|
|
67
67
|
assert_equal(
|
|
68
|
-
"--- !ruby/object:Geokit::GeoLoc \ncity: San Francisco\ncountry_code: US\nfull_address: \nlat: \nlng: \nprecision: unknown\nprovince: \nstate: CA\nstreet_address: \nsuccess: false\nzip: \"94105\"\n",
|
|
68
|
+
"--- !ruby/object:Geokit::GeoLoc \ncity: San Francisco\ncountry_code: US\nfull_address: \nlat: \nlng: \nprecision: unknown\nprovince: \nstate: CA\nstreet_address: \nstreet_name: \nstreet_number: \nsuccess: false\nzip: \"94105\"\n",
|
|
69
69
|
@loc.to_yaml)
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -33,8 +33,8 @@ class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
33
33
|
GeoKit::Geocoders::GeoPluginGeocoder.expects(:call_geocoder_service).with(url).returns(success)
|
|
34
34
|
location = GeoKit::Geocoders::GeoPluginGeocoder.geocode('200.150.38.66')
|
|
35
35
|
assert_not_nil location
|
|
36
|
-
assert_equal
|
|
37
|
-
assert_equal
|
|
36
|
+
assert_equal(-19.916700, location.lat)
|
|
37
|
+
assert_equal(-43.933300, location.lng)
|
|
38
38
|
assert_equal "Belo Horizonte", location.city
|
|
39
39
|
assert_equal "Minas Gerais", location.state
|
|
40
40
|
assert_equal "BR", location.country_code
|
|
@@ -186,7 +186,7 @@ class GoogleGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
186
186
|
|
|
187
187
|
assert_equal "Plaza de la Puerta del Sol, 28013, Madrid, Spain", res.full_address
|
|
188
188
|
assert_equal "28013", res.zip
|
|
189
|
-
assert_equal "Plaza
|
|
189
|
+
assert_equal "Plaza de la Puerta del Sol", res.street_address
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
def test_country_code_biasing
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_base_geocoder')
|
|
2
|
+
|
|
3
|
+
Geokit::Geocoders::google = 'Google'
|
|
4
|
+
|
|
5
|
+
class GoogleGeocoder3Test < BaseGeocoderTest #:nodoc: all
|
|
6
|
+
|
|
7
|
+
GOOGLE3_FULL=%q/
|
|
8
|
+
{
|
|
9
|
+
"status": "OK",
|
|
10
|
+
"results": [ {
|
|
11
|
+
"types": [ "street_address" ],
|
|
12
|
+
"formatted_address": "100 Spear St, San Francisco, CA 94105, USA",
|
|
13
|
+
"address_components": [ {
|
|
14
|
+
"long_name": "100",
|
|
15
|
+
"short_name": "100",
|
|
16
|
+
"types": [ "street_number" ]
|
|
17
|
+
}, {
|
|
18
|
+
"long_name": "Spear St",
|
|
19
|
+
"short_name": "Spear St",
|
|
20
|
+
"types": [ "route" ]
|
|
21
|
+
}, {
|
|
22
|
+
"long_name": "San Francisco",
|
|
23
|
+
"short_name": "San Francisco",
|
|
24
|
+
"types": [ "locality", "political" ]
|
|
25
|
+
}, {
|
|
26
|
+
"long_name": "San Francisco",
|
|
27
|
+
"short_name": "San Francisco",
|
|
28
|
+
"types": [ "administrative_area_level_3", "political" ]
|
|
29
|
+
}, {
|
|
30
|
+
"long_name": "San Francisco",
|
|
31
|
+
"short_name": "San Francisco",
|
|
32
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
33
|
+
}, {
|
|
34
|
+
"long_name": "California",
|
|
35
|
+
"short_name": "CA",
|
|
36
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
37
|
+
}, {
|
|
38
|
+
"long_name": "United States",
|
|
39
|
+
"short_name": "US",
|
|
40
|
+
"types": [ "country", "political" ]
|
|
41
|
+
}, {
|
|
42
|
+
"long_name": "94105",
|
|
43
|
+
"short_name": "94105",
|
|
44
|
+
"types": [ "postal_code" ]
|
|
45
|
+
} ],
|
|
46
|
+
"geometry": {
|
|
47
|
+
"location": {
|
|
48
|
+
"lat": 37.7921509,
|
|
49
|
+
"lng": -122.3940000
|
|
50
|
+
},
|
|
51
|
+
"location_type": "ROOFTOP",
|
|
52
|
+
"viewport": {
|
|
53
|
+
"southwest": {
|
|
54
|
+
"lat": 37.7890033,
|
|
55
|
+
"lng": -122.3971476
|
|
56
|
+
},
|
|
57
|
+
"northeast": {
|
|
58
|
+
"lat": 37.7952985,
|
|
59
|
+
"lng": -122.3908524
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} ]
|
|
64
|
+
}
|
|
65
|
+
/.strip
|
|
66
|
+
|
|
67
|
+
GOOGLE3_CITY=%q/
|
|
68
|
+
{
|
|
69
|
+
"status": "OK",
|
|
70
|
+
"results": [ {
|
|
71
|
+
"types": [ "locality", "political" ],
|
|
72
|
+
"formatted_address": "San Francisco, CA, USA",
|
|
73
|
+
"address_components": [ {
|
|
74
|
+
"long_name": "San Francisco",
|
|
75
|
+
"short_name": "San Francisco",
|
|
76
|
+
"types": [ "locality", "political" ]
|
|
77
|
+
}, {
|
|
78
|
+
"long_name": "San Francisco",
|
|
79
|
+
"short_name": "San Francisco",
|
|
80
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
81
|
+
}, {
|
|
82
|
+
"long_name": "California",
|
|
83
|
+
"short_name": "CA",
|
|
84
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
85
|
+
}, {
|
|
86
|
+
"long_name": "United States",
|
|
87
|
+
"short_name": "US",
|
|
88
|
+
"types": [ "country", "political" ]
|
|
89
|
+
} ],
|
|
90
|
+
"geometry": {
|
|
91
|
+
"location": {
|
|
92
|
+
"lat": 37.7749295,
|
|
93
|
+
"lng": -122.4194155
|
|
94
|
+
},
|
|
95
|
+
"location_type": "APPROXIMATE",
|
|
96
|
+
"viewport": {
|
|
97
|
+
"southwest": {
|
|
98
|
+
"lat": 37.7043396,
|
|
99
|
+
"lng": -122.5474749
|
|
100
|
+
},
|
|
101
|
+
"northeast": {
|
|
102
|
+
"lat": 37.8454521,
|
|
103
|
+
"lng": -122.2913561
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"bounds": {
|
|
107
|
+
"southwest": {
|
|
108
|
+
"lat": 37.7034000,
|
|
109
|
+
"lng": -122.5270000
|
|
110
|
+
},
|
|
111
|
+
"northeast": {
|
|
112
|
+
"lat": 37.8120000,
|
|
113
|
+
"lng": -122.3482000
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} ]
|
|
118
|
+
}
|
|
119
|
+
/.strip
|
|
120
|
+
GOOGLE3_MULTI=%q/
|
|
121
|
+
{
|
|
122
|
+
"status": "OK",
|
|
123
|
+
"results": [ {
|
|
124
|
+
"types": [ "street_address" ],
|
|
125
|
+
"formatted_address": "Via Sandro Pertini, 8, 20010 Mesero MI, Italy",
|
|
126
|
+
"address_components": [ {
|
|
127
|
+
"long_name": "8",
|
|
128
|
+
"short_name": "8",
|
|
129
|
+
"types": [ "street_number" ]
|
|
130
|
+
}, {
|
|
131
|
+
"long_name": "Via Sandro Pertini",
|
|
132
|
+
"short_name": "Via Sandro Pertini",
|
|
133
|
+
"types": [ "route" ]
|
|
134
|
+
}, {
|
|
135
|
+
"long_name": "Mesero",
|
|
136
|
+
"short_name": "Mesero",
|
|
137
|
+
"types": [ "locality", "political" ]
|
|
138
|
+
}, {
|
|
139
|
+
"long_name": "Milan",
|
|
140
|
+
"short_name": "MI",
|
|
141
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
142
|
+
}, {
|
|
143
|
+
"long_name": "Lombardy",
|
|
144
|
+
"short_name": "Lombardy",
|
|
145
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
146
|
+
}, {
|
|
147
|
+
"long_name": "Italy",
|
|
148
|
+
"short_name": "IT",
|
|
149
|
+
"types": [ "country", "political" ]
|
|
150
|
+
}, {
|
|
151
|
+
"long_name": "20010",
|
|
152
|
+
"short_name": "20010",
|
|
153
|
+
"types": [ "postal_code" ]
|
|
154
|
+
} ],
|
|
155
|
+
"geometry": {
|
|
156
|
+
"location": {
|
|
157
|
+
"lat": 45.4966218,
|
|
158
|
+
"lng": 8.8526940
|
|
159
|
+
},
|
|
160
|
+
"location_type": "RANGE_INTERPOLATED",
|
|
161
|
+
"viewport": {
|
|
162
|
+
"southwest": {
|
|
163
|
+
"lat": 45.4934754,
|
|
164
|
+
"lng": 8.8495559
|
|
165
|
+
},
|
|
166
|
+
"northeast": {
|
|
167
|
+
"lat": 45.4997707,
|
|
168
|
+
"lng": 8.8558512
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"bounds": {
|
|
172
|
+
"southwest": {
|
|
173
|
+
"lat": 45.4966218,
|
|
174
|
+
"lng": 8.8526940
|
|
175
|
+
},
|
|
176
|
+
"northeast": {
|
|
177
|
+
"lat": 45.4966243,
|
|
178
|
+
"lng": 8.8527131
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"partial_match": true
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"types": [ "route" ],
|
|
186
|
+
"formatted_address": "Via Sandro Pertini, 20010 Ossona MI, Italy",
|
|
187
|
+
"address_components": [ {
|
|
188
|
+
"long_name": "Via Sandro Pertini",
|
|
189
|
+
"short_name": "Via Sandro Pertini",
|
|
190
|
+
"types": [ "route" ]
|
|
191
|
+
}, {
|
|
192
|
+
"long_name": "Ossona",
|
|
193
|
+
"short_name": "Ossona",
|
|
194
|
+
"types": [ "locality", "political" ]
|
|
195
|
+
}, {
|
|
196
|
+
"long_name": "Milan",
|
|
197
|
+
"short_name": "MI",
|
|
198
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
199
|
+
}, {
|
|
200
|
+
"long_name": "Lombardy",
|
|
201
|
+
"short_name": "Lombardy",
|
|
202
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
203
|
+
}, {
|
|
204
|
+
"long_name": "Italy",
|
|
205
|
+
"short_name": "IT",
|
|
206
|
+
"types": [ "country", "political" ]
|
|
207
|
+
}, {
|
|
208
|
+
"long_name": "20010",
|
|
209
|
+
"short_name": "20010",
|
|
210
|
+
"types": [ "postal_code" ]
|
|
211
|
+
} ],
|
|
212
|
+
"geometry": {
|
|
213
|
+
"location": {
|
|
214
|
+
"lat": 45.5074444,
|
|
215
|
+
"lng": 8.9023200
|
|
216
|
+
},
|
|
217
|
+
"location_type": "GEOMETRIC_CENTER",
|
|
218
|
+
"viewport": {
|
|
219
|
+
"southwest": {
|
|
220
|
+
"lat": 45.5043320,
|
|
221
|
+
"lng": 8.8990670
|
|
222
|
+
},
|
|
223
|
+
"northeast": {
|
|
224
|
+
"lat": 45.5106273,
|
|
225
|
+
"lng": 8.9053622
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"bounds": {
|
|
229
|
+
"southwest": {
|
|
230
|
+
"lat": 45.5064427,
|
|
231
|
+
"lng": 8.9020024
|
|
232
|
+
},
|
|
233
|
+
"northeast": {
|
|
234
|
+
"lat": 45.5085166,
|
|
235
|
+
"lng": 8.9024268
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
/.strip
|
|
243
|
+
GOOGLE3_REVERSE_MADRID=%q/
|
|
244
|
+
{
|
|
245
|
+
"status": "OK",
|
|
246
|
+
"results": [ {
|
|
247
|
+
"types": [ ],
|
|
248
|
+
"formatted_address": "Calle de las Carretas, 28013 Madrid, Spain",
|
|
249
|
+
"address_components": [ {
|
|
250
|
+
"long_name": "Calle de las Carretas",
|
|
251
|
+
"short_name": "Calle de las Carretas",
|
|
252
|
+
"types": [ "route" ]
|
|
253
|
+
}, {
|
|
254
|
+
"long_name": "Madrid",
|
|
255
|
+
"short_name": "Madrid",
|
|
256
|
+
"types": [ "locality", "political" ]
|
|
257
|
+
}, {
|
|
258
|
+
"long_name": "Madrid",
|
|
259
|
+
"short_name": "M",
|
|
260
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
261
|
+
}, {
|
|
262
|
+
"long_name": "Madrid",
|
|
263
|
+
"short_name": "Madrid",
|
|
264
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
265
|
+
}, {
|
|
266
|
+
"long_name": "Spain",
|
|
267
|
+
"short_name": "ES",
|
|
268
|
+
"types": [ "country", "political" ]
|
|
269
|
+
}, {
|
|
270
|
+
"long_name": "28013",
|
|
271
|
+
"short_name": "28013",
|
|
272
|
+
"types": [ "postal_code" ]
|
|
273
|
+
} ],
|
|
274
|
+
"geometry": {
|
|
275
|
+
"location": {
|
|
276
|
+
"lat": 40.4166824,
|
|
277
|
+
"lng": -3.7033411
|
|
278
|
+
},
|
|
279
|
+
"location_type": "APPROXIMATE",
|
|
280
|
+
"viewport": {
|
|
281
|
+
"southwest": {
|
|
282
|
+
"lat": 40.4135351,
|
|
283
|
+
"lng": -3.7064880
|
|
284
|
+
},
|
|
285
|
+
"northeast": {
|
|
286
|
+
"lat": 40.4198303,
|
|
287
|
+
"lng": -3.7001927
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
"bounds": {
|
|
291
|
+
"southwest": {
|
|
292
|
+
"lat": 40.4166419,
|
|
293
|
+
"lng": -3.7033685
|
|
294
|
+
},
|
|
295
|
+
"northeast": {
|
|
296
|
+
"lat": 40.4167235,
|
|
297
|
+
"lng": -3.7033122
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
} ]
|
|
302
|
+
}
|
|
303
|
+
/
|
|
304
|
+
GOOGLE3_COUNTRY_CODE_BIASED_RESULT=%q/
|
|
305
|
+
{
|
|
306
|
+
"status": "OK",
|
|
307
|
+
"results": [ {
|
|
308
|
+
"types": [ "administrative_area_level_2", "political" ],
|
|
309
|
+
"formatted_address": "Syracuse, Italy",
|
|
310
|
+
"address_components": [ {
|
|
311
|
+
"long_name": "Syracuse",
|
|
312
|
+
"short_name": "SR",
|
|
313
|
+
"types": [ "administrative_area_level_2", "political" ]
|
|
314
|
+
}, {
|
|
315
|
+
"long_name": "Sicily",
|
|
316
|
+
"short_name": "Sicily",
|
|
317
|
+
"types": [ "administrative_area_level_1", "political" ]
|
|
318
|
+
}, {
|
|
319
|
+
"long_name": "Italy",
|
|
320
|
+
"short_name": "IT",
|
|
321
|
+
"types": [ "country", "political" ]
|
|
322
|
+
} ],
|
|
323
|
+
"geometry": {
|
|
324
|
+
"location": {
|
|
325
|
+
"lat": 37.0630218,
|
|
326
|
+
"lng": 14.9856176
|
|
327
|
+
},
|
|
328
|
+
"location_type": "APPROXIMATE",
|
|
329
|
+
"viewport": {
|
|
330
|
+
"southwest": {
|
|
331
|
+
"lat": 36.7775664,
|
|
332
|
+
"lng": 14.4733800
|
|
333
|
+
},
|
|
334
|
+
"northeast": {
|
|
335
|
+
"lat": 37.3474070,
|
|
336
|
+
"lng": 15.4978552
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
"bounds": {
|
|
340
|
+
"southwest": {
|
|
341
|
+
"lat": 36.6441736,
|
|
342
|
+
"lng": 14.7724913
|
|
343
|
+
},
|
|
344
|
+
"northeast": {
|
|
345
|
+
"lat": 37.4125978,
|
|
346
|
+
"lng": 15.3367367
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
} ]
|
|
351
|
+
}
|
|
352
|
+
/
|
|
353
|
+
GOOGLE3_TOO_MANY=%q/
|
|
354
|
+
{
|
|
355
|
+
"status": "OVER_QUERY_LIMIT"
|
|
356
|
+
}
|
|
357
|
+
/
|
|
358
|
+
def setup
|
|
359
|
+
super
|
|
360
|
+
@google_full_hash = {:street_address=>"100 Spear St", :city=>"San Francisco", :state=>"CA", :zip=>"94105", :country_code=>"US"}
|
|
361
|
+
@google_city_hash = {:city=>"San Francisco", :state=>"CA"}
|
|
362
|
+
|
|
363
|
+
@google_full_loc = Geokit::GeoLoc.new(@google_full_hash)
|
|
364
|
+
@google_city_loc = Geokit::GeoLoc.new(@google_city_hash)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def test_google3_full_address
|
|
368
|
+
response = MockSuccess.new
|
|
369
|
+
response.expects(:body).returns(GOOGLE3_FULL)
|
|
370
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@address)}"
|
|
371
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
372
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@address)
|
|
373
|
+
assert_equal "CA", res.state
|
|
374
|
+
assert_equal "San Francisco", res.city
|
|
375
|
+
assert_equal "37.7921509,-122.394", res.ll # slightly dif from yahoo
|
|
376
|
+
assert res.is_us?
|
|
377
|
+
assert_equal "100 Spear St, San Francisco, CA 94105, USA", res.full_address #slightly different from yahoo
|
|
378
|
+
assert_equal "google3", res.provider
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def test_google3_full_address_with_geo_loc
|
|
382
|
+
response = MockSuccess.new
|
|
383
|
+
response.expects(:body).returns(GOOGLE3_FULL)
|
|
384
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@full_address_short_zip)}"
|
|
385
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
386
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@google_full_loc)
|
|
387
|
+
assert_equal "CA", res.state
|
|
388
|
+
assert_equal "San Francisco", res.city
|
|
389
|
+
assert_equal "37.7921509,-122.394", res.ll # slightly dif from yahoo
|
|
390
|
+
assert res.is_us?
|
|
391
|
+
assert_equal "100 Spear St, San Francisco, CA 94105, USA", res.full_address #slightly different from yahoo
|
|
392
|
+
assert_equal "google3", res.provider
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def test_google3_full_address_accuracy
|
|
396
|
+
response = MockSuccess.new
|
|
397
|
+
response.expects(:body).returns(GOOGLE3_FULL)
|
|
398
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@full_address_short_zip)}"
|
|
399
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
400
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@google_full_loc)
|
|
401
|
+
assert_equal 9, res.accuracy
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def test_google3_city
|
|
405
|
+
response = MockSuccess.new
|
|
406
|
+
response.expects(:body).returns(GOOGLE3_CITY)
|
|
407
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@address)}"
|
|
408
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
409
|
+
res=Geokit::Geocoders::GoogleGeocoder3.do_geocode(@address)
|
|
410
|
+
assert_nil res.street_address
|
|
411
|
+
assert_equal "CA", res.state
|
|
412
|
+
assert_equal "San Francisco", res.city
|
|
413
|
+
assert_equal "37.7749295,-122.4194155", res.ll
|
|
414
|
+
assert res.is_us?
|
|
415
|
+
assert_equal "San Francisco, CA, USA", res.full_address
|
|
416
|
+
assert_equal "google3", res.provider
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def test_google3_city_accuracy
|
|
420
|
+
response = MockSuccess.new
|
|
421
|
+
response.expects(:body).returns(GOOGLE3_CITY)
|
|
422
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@address)}"
|
|
423
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
424
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@address)
|
|
425
|
+
assert_equal 4, res.accuracy
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def test_google3_city_with_geo_loc
|
|
429
|
+
response = MockSuccess.new
|
|
430
|
+
response.expects(:body).returns(GOOGLE3_CITY)
|
|
431
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@address)}"
|
|
432
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
433
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@google_city_loc)
|
|
434
|
+
assert_equal "CA", res.state
|
|
435
|
+
assert_equal "San Francisco", res.city
|
|
436
|
+
assert_equal "37.7749295,-122.4194155", res.ll
|
|
437
|
+
assert res.is_us?
|
|
438
|
+
assert_equal "San Francisco, CA, USA", res.full_address
|
|
439
|
+
assert_nil res.street_address
|
|
440
|
+
assert_equal "google3", res.provider
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def test_google3_suggested_bounds
|
|
444
|
+
response = MockSuccess.new
|
|
445
|
+
response.expects(:body).returns(GOOGLE3_FULL)
|
|
446
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@full_address_short_zip)}"
|
|
447
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
448
|
+
res = Geokit::Geocoders::GoogleGeocoder3.geocode(@google_full_loc)
|
|
449
|
+
|
|
450
|
+
assert_instance_of Geokit::Bounds, res.suggested_bounds
|
|
451
|
+
assert_equal Geokit::Bounds.new(Geokit::LatLng.new(37.7890033, -122.3971476), Geokit::LatLng.new(37.7952985, -122.3908524)), res.suggested_bounds
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def test_service_unavailable
|
|
455
|
+
response = MockFailure.new
|
|
456
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector::url_escape(@address)}"
|
|
457
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
458
|
+
assert !Geokit::Geocoders::GoogleGeocoder3.geocode(@google_city_loc).success
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def test_multiple_results
|
|
462
|
+
#Geokit::Geocoders::GoogleGeocoder3.do_geocode('via Sandro Pertini 8, Ossona, MI')
|
|
463
|
+
response = MockSuccess.new
|
|
464
|
+
response.expects(:body).returns(GOOGLE3_MULTI)
|
|
465
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector.url_escape('via Sandro Pertini 8, Ossona, MI')}"
|
|
466
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
467
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode('via Sandro Pertini 8, Ossona, MI')
|
|
468
|
+
assert_equal "Lombardy", res.state
|
|
469
|
+
assert_equal "Mesero", res.city
|
|
470
|
+
assert_equal "45.4966218,8.852694", res.ll
|
|
471
|
+
assert !res.is_us?
|
|
472
|
+
assert_equal "Via Sandro Pertini, 8, 20010 Mesero MI, Italy", res.full_address
|
|
473
|
+
assert_equal "8 Via Sandro Pertini", res.street_address
|
|
474
|
+
assert_equal "google3", res.provider
|
|
475
|
+
|
|
476
|
+
assert_equal 2, res.all.size
|
|
477
|
+
res = res.all[1]
|
|
478
|
+
assert_equal "Lombardy", res.state
|
|
479
|
+
assert_equal "Ossona", res.city
|
|
480
|
+
assert_equal "45.5074444,8.90232", res.ll
|
|
481
|
+
assert !res.is_us?
|
|
482
|
+
assert_equal "Via Sandro Pertini, 20010 Ossona MI, Italy", res.full_address
|
|
483
|
+
assert_equal "Via Sandro Pertini", res.street_address
|
|
484
|
+
assert_equal "google3", res.provider
|
|
485
|
+
end
|
|
486
|
+
#
|
|
487
|
+
def test_reverse_geocode
|
|
488
|
+
#Geokit::Geocoders::GoogleGeocoder3.do_reverse_geocode("40.4167413, -3.7032498")
|
|
489
|
+
madrid = Geokit::GeoLoc.new
|
|
490
|
+
madrid.lat, madrid.lng = "40.4167413", "-3.7032498"
|
|
491
|
+
response = MockSuccess.new
|
|
492
|
+
response.expects(:body).returns(GOOGLE3_REVERSE_MADRID)
|
|
493
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&latlng=#{Geokit::Inflector::url_escape(madrid.ll)}"
|
|
494
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).
|
|
495
|
+
returns(response)
|
|
496
|
+
res=Geokit::Geocoders::GoogleGeocoder3.do_reverse_geocode(madrid.ll)
|
|
497
|
+
|
|
498
|
+
assert_equal madrid.lat.to_s.slice(1..5), res.lat.to_s.slice(1..5)
|
|
499
|
+
assert_equal madrid.lng.to_s.slice(1..5), res.lng.to_s.slice(1..5)
|
|
500
|
+
assert_equal "ES", res.country_code
|
|
501
|
+
assert_equal "google3", res.provider
|
|
502
|
+
|
|
503
|
+
assert_equal "Madrid", res.city
|
|
504
|
+
assert_equal "Madrid", res.state
|
|
505
|
+
|
|
506
|
+
assert_equal "Spain", res.country
|
|
507
|
+
assert_equal "street", res.precision
|
|
508
|
+
assert_equal true, res.success
|
|
509
|
+
|
|
510
|
+
assert_equal "Calle de las Carretas, 28013 Madrid, Spain", res.full_address
|
|
511
|
+
assert_equal "28013", res.zip
|
|
512
|
+
assert_equal "Calle de las Carretas", res.street_address
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def test_country_code_biasing
|
|
516
|
+
response = MockSuccess.new
|
|
517
|
+
response.expects(:body).returns(GOOGLE3_COUNTRY_CODE_BIASED_RESULT)
|
|
518
|
+
|
|
519
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=Syracuse®ion=it"
|
|
520
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
521
|
+
biased_result = Geokit::Geocoders::GoogleGeocoder3.geocode('Syracuse', :bias => 'it')
|
|
522
|
+
|
|
523
|
+
assert_equal 'IT', biased_result.country_code
|
|
524
|
+
assert_equal 'Sicily', biased_result.state
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def test_too_many_queries
|
|
528
|
+
response = MockSuccess.new
|
|
529
|
+
response.expects(:body).returns(GOOGLE3_TOO_MANY)
|
|
530
|
+
url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{Geokit::Inflector.url_escape(@address)}"
|
|
531
|
+
Geokit::Geocoders::GoogleGeocoder3.expects(:call_geocoder_service).with(url).returns(response)
|
|
532
|
+
assert_raise Geokit::TooManyQueriesError do
|
|
533
|
+
res=Geokit::Geocoders::GoogleGeocoder3.geocode(@address)
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
end
|
data/test/test_ipgeocoder.rb
CHANGED
|
@@ -4,8 +4,8 @@ require File.join(File.dirname(__FILE__), 'test_base_geocoder')
|
|
|
4
4
|
class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
5
5
|
|
|
6
6
|
IP_FAILURE=<<-EOF
|
|
7
|
-
Country:
|
|
8
|
-
City: (
|
|
7
|
+
Country: SWITZERLAND (CH)
|
|
8
|
+
City: (Unknown City)
|
|
9
9
|
Latitude:
|
|
10
10
|
Longitude:
|
|
11
11
|
EOF
|
|
@@ -24,10 +24,22 @@ class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
24
24
|
Longitude: 12.9167
|
|
25
25
|
EOF
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
PRIVATE_IPS_TO_TEST = [
|
|
28
|
+
'10.10.10.10',
|
|
29
|
+
'172.16.1.3',
|
|
30
|
+
'172.22.3.42',
|
|
31
|
+
'172.30.254.164',
|
|
32
|
+
'192.168.1.1',
|
|
33
|
+
'0.0.0.0',
|
|
34
|
+
'127.0.0.1',
|
|
35
|
+
'240.3.4.5',
|
|
36
|
+
'225.1.6.55'
|
|
37
|
+
].freeze
|
|
38
|
+
|
|
39
|
+
def setup
|
|
40
|
+
super
|
|
41
|
+
@success.provider = "hostip"
|
|
42
|
+
end
|
|
31
43
|
|
|
32
44
|
def test_successful_lookup
|
|
33
45
|
success = MockSuccess.new
|
|
@@ -64,14 +76,24 @@ class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
64
76
|
def test_failed_lookup
|
|
65
77
|
failure = MockSuccess.new
|
|
66
78
|
failure.expects(:body).returns(IP_FAILURE)
|
|
67
|
-
url = 'http://api.hostip.info/get_html.php?ip=
|
|
79
|
+
url = 'http://api.hostip.info/get_html.php?ip=128.178.0.0&position=true'
|
|
68
80
|
GeoKit::Geocoders::IpGeocoder.expects(:call_geocoder_service).with(url).returns(failure)
|
|
69
|
-
location = GeoKit::Geocoders::IpGeocoder.geocode("
|
|
81
|
+
location = GeoKit::Geocoders::IpGeocoder.geocode("128.178.0.0")
|
|
70
82
|
assert_not_nil location
|
|
71
83
|
assert !location.success?
|
|
72
84
|
end
|
|
73
85
|
|
|
86
|
+
def test_private_ips
|
|
87
|
+
GeoKit::Geocoders::IpGeocoder.expects(:call_geocoder_service).never
|
|
88
|
+
PRIVATE_IPS_TO_TEST.each do |ip|
|
|
89
|
+
location = GeoKit::Geocoders::IpGeocoder.geocode(ip)
|
|
90
|
+
assert_not_nil location
|
|
91
|
+
assert !location.success?
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
74
95
|
def test_invalid_ip
|
|
96
|
+
GeoKit::Geocoders::IpGeocoder.expects(:call_geocoder_service).never
|
|
75
97
|
location = GeoKit::Geocoders::IpGeocoder.geocode("blah")
|
|
76
98
|
assert_not_nil location
|
|
77
99
|
assert !location.success?
|
|
@@ -79,9 +101,9 @@ class IpGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
79
101
|
|
|
80
102
|
def test_service_unavailable
|
|
81
103
|
failure = MockFailure.new
|
|
82
|
-
url = 'http://api.hostip.info/get_html.php?ip=
|
|
104
|
+
url = 'http://api.hostip.info/get_html.php?ip=12.215.42.19&position=true'
|
|
83
105
|
GeoKit::Geocoders::IpGeocoder.expects(:call_geocoder_service).with(url).returns(failure)
|
|
84
|
-
location = GeoKit::Geocoders::IpGeocoder.geocode("
|
|
106
|
+
location = GeoKit::Geocoders::IpGeocoder.geocode("12.215.42.19")
|
|
85
107
|
assert_not_nil location
|
|
86
108
|
assert !location.success?
|
|
87
109
|
end
|
data/test/test_yahoo_geocoder.rb
CHANGED
|
@@ -4,15 +4,15 @@ Geokit::Geocoders::yahoo = 'Yahoo'
|
|
|
4
4
|
|
|
5
5
|
class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
6
6
|
YAHOO_FULL=<<-EOF.strip
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
8
|
+
<ResultSet version="1.0"><Error>0</Error><ErrorMessage>No error</ErrorMessage><Locale>us_US</Locale><Quality>87</Quality><Found>1</Found><Result><quality>87</quality><latitude>37.792418</latitude><longitude>-122.393913</longitude><offsetlat>37.792332</offsetlat><offsetlon>-122.394027</offsetlon><radius>500</radius><name></name><line1>100 Spear St</line1><line2>San Francisco, CA 94105-1578</line2><line3></line3><line4>United States</line4><house>100</house><street>Spear St</street><xstreet></xstreet><unittype></unittype><unit></unit><postal>94105-1578</postal><neighborhood></neighborhood><city>San Francisco</city><county>San Francisco County</county><state>California</state><country>United States</country><countrycode>US</countrycode><statecode>CA</statecode><countycode></countycode><uzip>94105</uzip><hash>0FA06819B5F53E75</hash><woeid>12797156</woeid><woetype>11</woetype></Result></ResultSet>
|
|
9
|
+
<!-- gws17.maps.sp1.yahoo.com uncompressed/chunked Fri Feb 11 13:41:03 PST 2011 -->
|
|
10
10
|
EOF
|
|
11
11
|
|
|
12
12
|
YAHOO_CITY=<<-EOF.strip
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
14
|
+
<ResultSet version="1.0"><Error>0</Error><ErrorMessage>No error</ErrorMessage><Locale>us_US</Locale><Quality>40</Quality><Found>1</Found><Result><quality>40</quality><latitude>37.777125</latitude><longitude>-122.419644</longitude><offsetlat>37.777125</offsetlat><offsetlon>-122.419644</offsetlon><radius>10700</radius><name></name><line1></line1><line2>San Francisco, CA</line2><line3></line3><line4>United States</line4><house></house><street></street><xstreet></xstreet><unittype></unittype><unit></unit><postal></postal><neighborhood></neighborhood><city>San Francisco</city><county>San Francisco County</county><state>California</state><country>United States</country><countrycode>US</countrycode><statecode>CA</statecode><countycode></countycode><uzip>94102</uzip><hash></hash><woeid>2487956</woeid><woetype>7</woetype></Result></ResultSet>
|
|
15
|
+
<!-- gws31.maps.sp1.yahoo.com uncompressed/chunked Fri Feb 11 13:38:19 PST 2011 -->
|
|
16
16
|
EOF
|
|
17
17
|
|
|
18
18
|
def setup
|
|
@@ -27,7 +27,7 @@ class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
27
27
|
def test_yahoo_full_address
|
|
28
28
|
response = MockSuccess.new
|
|
29
29
|
response.expects(:body).returns(YAHOO_FULL)
|
|
30
|
-
url = "http://
|
|
30
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
31
31
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
32
32
|
do_full_address_assertions(Geokit::Geocoders::YahooGeocoder.geocode(@address))
|
|
33
33
|
end
|
|
@@ -35,16 +35,25 @@ class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
35
35
|
def test_yahoo_full_address_accuracy
|
|
36
36
|
response = MockSuccess.new
|
|
37
37
|
response.expects(:body).returns(YAHOO_FULL)
|
|
38
|
-
url = "http://
|
|
38
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
39
39
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
40
40
|
res = Geokit::Geocoders::YahooGeocoder.geocode(@address)
|
|
41
41
|
assert_equal 8, res.accuracy
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def test_yahoo_full_address_precision
|
|
45
|
+
response = MockSuccess.new
|
|
46
|
+
response.expects(:body).returns(YAHOO_FULL)
|
|
47
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
48
|
+
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
49
|
+
res = Geokit::Geocoders::YahooGeocoder.geocode(@address)
|
|
50
|
+
assert_equal 'address', res.precision
|
|
51
|
+
end
|
|
52
|
+
|
|
44
53
|
def test_yahoo_full_address_with_geo_loc
|
|
45
54
|
response = MockSuccess.new
|
|
46
55
|
response.expects(:body).returns(YAHOO_FULL)
|
|
47
|
-
url = "http://
|
|
56
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@full_address)}"
|
|
48
57
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
49
58
|
do_full_address_assertions(Geokit::Geocoders::YahooGeocoder.geocode(@yahoo_full_loc))
|
|
50
59
|
end
|
|
@@ -52,7 +61,7 @@ class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
52
61
|
def test_yahoo_city
|
|
53
62
|
response = MockSuccess.new
|
|
54
63
|
response.expects(:body).returns(YAHOO_CITY)
|
|
55
|
-
url = "http://
|
|
64
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
56
65
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
57
66
|
do_city_assertions(Geokit::Geocoders::YahooGeocoder.geocode(@address))
|
|
58
67
|
end
|
|
@@ -60,23 +69,32 @@ class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
60
69
|
def test_yahoo_city_accuracy
|
|
61
70
|
response = MockSuccess.new
|
|
62
71
|
response.expects(:body).returns(YAHOO_CITY)
|
|
63
|
-
url = "http://
|
|
72
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
64
73
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
65
74
|
res = Geokit::Geocoders::YahooGeocoder.geocode(@address)
|
|
66
75
|
assert_equal 4, res.accuracy
|
|
67
76
|
end
|
|
68
77
|
|
|
78
|
+
def test_yahoo_city_precision
|
|
79
|
+
response = MockSuccess.new
|
|
80
|
+
response.expects(:body).returns(YAHOO_CITY)
|
|
81
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
82
|
+
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
83
|
+
res = Geokit::Geocoders::YahooGeocoder.geocode(@address)
|
|
84
|
+
assert_equal 'city', res.precision
|
|
85
|
+
end
|
|
86
|
+
|
|
69
87
|
def test_yahoo_city_with_geo_loc
|
|
70
88
|
response = MockSuccess.new
|
|
71
89
|
response.expects(:body).returns(YAHOO_CITY)
|
|
72
|
-
url = "http://
|
|
90
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
73
91
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
74
92
|
do_city_assertions(Geokit::Geocoders::YahooGeocoder.geocode(@yahoo_city_loc))
|
|
75
93
|
end
|
|
76
94
|
|
|
77
95
|
def test_service_unavailable
|
|
78
96
|
response = MockFailure.new
|
|
79
|
-
url = "http://
|
|
97
|
+
url = "http://where.yahooapis.com/geocode?appid=Yahoo&count=100&location=#{Geokit::Inflector.url_escape(@address)}"
|
|
80
98
|
Geokit::Geocoders::YahooGeocoder.expects(:call_geocoder_service).with(url).returns(response)
|
|
81
99
|
assert !Geokit::Geocoders::YahooGeocoder.geocode(@yahoo_city_loc).success
|
|
82
100
|
end
|
|
@@ -87,16 +105,16 @@ class YahooGeocoderTest < BaseGeocoderTest #:nodoc: all
|
|
|
87
105
|
def do_full_address_assertions(res)
|
|
88
106
|
assert_equal "CA", res.state
|
|
89
107
|
assert_equal "San Francisco", res.city
|
|
90
|
-
assert_equal "37.
|
|
108
|
+
assert_equal "37.792418,-122.393913", res.ll
|
|
91
109
|
assert res.is_us?
|
|
92
|
-
assert_equal "100 Spear St, San Francisco, CA
|
|
110
|
+
assert_equal "100 Spear St, San Francisco, CA 94105-1578", res.full_address
|
|
93
111
|
assert_equal "yahoo", res.provider
|
|
94
112
|
end
|
|
95
113
|
|
|
96
114
|
def do_city_assertions(res)
|
|
97
115
|
assert_equal "CA", res.state
|
|
98
116
|
assert_equal "San Francisco", res.city
|
|
99
|
-
assert_equal "37.
|
|
117
|
+
assert_equal "37.777125,-122.419644", res.ll
|
|
100
118
|
assert res.is_us?
|
|
101
119
|
assert_equal "San Francisco, CA, US", res.full_address
|
|
102
120
|
assert_nil res.street_address
|
metadata
CHANGED
|
@@ -5,9 +5,8 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
segments:
|
|
6
6
|
- 1
|
|
7
7
|
- 5
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
version: 1.5.0.2
|
|
8
|
+
- 1
|
|
9
|
+
version: 1.5.1
|
|
11
10
|
platform: ruby
|
|
12
11
|
authors:
|
|
13
12
|
- Andre Lewis and Bill Eisenhauer
|
|
@@ -17,8 +16,19 @@ cert_chain: []
|
|
|
17
16
|
|
|
18
17
|
date: 2009-08-02 00:00:00 -07:00
|
|
19
18
|
default_executable:
|
|
20
|
-
dependencies:
|
|
21
|
-
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: json_pure
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
segments:
|
|
28
|
+
- 0
|
|
29
|
+
version: "0"
|
|
30
|
+
type: :runtime
|
|
31
|
+
version_requirements: *id001
|
|
22
32
|
description: Geokit Gem
|
|
23
33
|
email:
|
|
24
34
|
- andre@earthcode.com / bill_eisenhauer@yahoo.com
|
|
@@ -40,6 +50,7 @@ files:
|
|
|
40
50
|
- test/test_bounds.rb
|
|
41
51
|
- test/test_ca_geocoder.rb
|
|
42
52
|
- test/test_geoloc.rb
|
|
53
|
+
- test/test_google_geocoder3.rb
|
|
43
54
|
- test/test_google_geocoder.rb
|
|
44
55
|
- test/test_latlng.rb
|
|
45
56
|
- test/test_multi_geocoder.rb
|
|
@@ -82,6 +93,7 @@ test_files:
|
|
|
82
93
|
- test/test_ca_geocoder.rb
|
|
83
94
|
- test/test_geoloc.rb
|
|
84
95
|
- test/test_geoplugin_geocoder.rb
|
|
96
|
+
- test/test_google_geocoder3.rb
|
|
85
97
|
- test/test_google_geocoder.rb
|
|
86
98
|
- test/test_google_reverse_geocoder.rb
|
|
87
99
|
- test/test_inflector.rb
|