rails-geocoder 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,19 +12,31 @@ module Geocoder::Result
12
12
  end
13
13
 
14
14
  def city
15
- address_components_of_type(:locality).first['long_name']
15
+ fields = [:locality, :sublocality, :administrative_area_level_3,
16
+ :administrative_area_level_2, :administrative_area_level_1]
17
+ fields.each do |f|
18
+ if entity = address_components_of_type(f).first
19
+ return entity['long_name']
20
+ end
21
+ end
16
22
  end
17
23
 
18
24
  def country
19
- address_components_of_type(:country).first['long_name']
25
+ if country = address_components_of_type(:country).first
26
+ country['long_name']
27
+ end
20
28
  end
21
29
 
22
30
  def country_code
23
- address_components_of_type(:country).first['short_name']
31
+ if country = address_components_of_type(:country).first
32
+ country['short_name']
33
+ end
24
34
  end
25
35
 
26
36
  def postal_code
27
- address_components_of_type(:postal_code).first['long_name']
37
+ if postal = address_components_of_type(:postal_code).first
38
+ postal['long_name']
39
+ end
28
40
  end
29
41
 
30
42
  def types
@@ -0,0 +1 @@
1
+ test({"longt":"-73.992006","latt":"40.749101"});
@@ -0,0 +1 @@
1
+ test({"longt":"-0.000000","error":{"description":"Postal Code is not in the proper Format.","code":"005"},"latt":"176946676.000000"});
@@ -0,0 +1,34 @@
1
+ test({
2
+ "latt":"45.423733",
3
+ "longt":"-75.676333",
4
+ "inlatt":"45.424035",
5
+ "inlongt":"-75.675941",
6
+ "betweenRoad1":"Chapel",
7
+ "betweenRoad2":"Russell",
8
+ "distance":"0.034",
9
+ "stnumber":"289",
10
+ "staddress":"Somerset ST E",
11
+ "city":"Ottawa",
12
+ "prov":"ON",
13
+ "postal":"K1N6W1",
14
+ "NearRoad":"Somerset ST E",
15
+ "NearRoadDistance":"0.013",
16
+ "intersection":{
17
+ "lattx":"45.423733",
18
+ "longtx":"-75.676333",
19
+ "distance":"0.045",
20
+ "street1":"Somerset St E",
21
+ "street2":"Russell Ave",
22
+ "city":"OTTAWA",
23
+ "prov":"ON"
24
+ },
25
+ "major_intersection":{
26
+ "lattx":"45.4241623853",
27
+ "longtx":"-75.6753026518",
28
+ "distance":"0.052",
29
+ "street1":"Chapel St",
30
+ "street2":"Somerset St E",
31
+ "city":"OTTAWA",
32
+ "prov":"ON"
33
+ }
34
+ });
@@ -0,0 +1,51 @@
1
+ {
2
+ "status": "OK",
3
+ "results": [ {
4
+ "types": [ "route" ],
5
+ "formatted_address": "Al Ahram, Haram, Giza, Egypt",
6
+ "address_components": [ {
7
+ "long_name": "Al Ahram",
8
+ "short_name": "Al Ahram",
9
+ "types": [ "route" ]
10
+ }, {
11
+ "long_name": "Haram",
12
+ "short_name": "Haram",
13
+ "types": [ "administrative_area_level_2", "political" ]
14
+ }, {
15
+ "long_name": "Al Jizah",
16
+ "short_name": "Al Jizah",
17
+ "types": [ "administrative_area_level_1", "political" ]
18
+ }, {
19
+ "long_name": "Egypt",
20
+ "short_name": "EG",
21
+ "types": [ "country", "political" ]
22
+ } ],
23
+ "geometry": {
24
+ "location": {
25
+ "lat": 29.9803527,
26
+ "lng": 31.1330307
27
+ },
28
+ "location_type": "APPROXIMATE",
29
+ "viewport": {
30
+ "southwest": {
31
+ "lat": 29.9768276,
32
+ "lng": 31.1302189
33
+ },
34
+ "northeast": {
35
+ "lat": 29.9831228,
36
+ "lng": 31.1365141
37
+ }
38
+ },
39
+ "bounds": {
40
+ "southwest": {
41
+ "lat": 29.9775337,
42
+ "lng": 31.1327483
43
+ },
44
+ "northeast": {
45
+ "lat": 29.9824167,
46
+ "lng": 31.1339847
47
+ }
48
+ }
49
+ }
50
+ } ]
51
+ }
@@ -1,9 +1,10 @@
1
+ # encoding: utf-8
1
2
  require 'test_helper'
2
3
 
3
4
  class GeocoderTest < Test::Unit::TestCase
4
5
 
5
6
  def setup
6
- Geocoder::Configuration.lookup = :google
7
+ Geocoder::Configuration.set_defaults
7
8
  end
8
9
 
9
10
 
@@ -19,22 +20,15 @@ class GeocoderTest < Test::Unit::TestCase
19
20
 
20
21
  # --- sanity checks ---
21
22
 
22
- def test_distance_between
23
- assert_equal 69, Geocoder::Calculations.distance_between(0,0, 0,1).round
24
- end
25
-
26
- def test_geographic_center
27
- assert_equal [0.0, 0.5],
28
- Geocoder::Calculations.geographic_center([[0,0], [0,1]])
29
- assert_equal [0.0, 1.0],
30
- Geocoder::Calculations.geographic_center([[0,0], [0,1], [0,2]])
23
+ def test_uses_https_for_secure_query
24
+ Geocoder::Configuration.use_https = true
25
+ g = Geocoder::Lookup::Google.new
26
+ assert_match /^https:/, g.send(:query_url, {:a => 1, :b => 2})
31
27
  end
32
28
 
33
- def test_does_not_choke_on_nil_address
34
- v = Venue.new("Venue", nil)
35
- assert_nothing_raised do
36
- v.geocode
37
- end
29
+ def test_uses_http_by_default
30
+ g = Geocoder::Lookup::Google.new
31
+ assert_match /^http:/, g.send(:query_url, {:a => 1, :b => 2})
38
32
  end
39
33
 
40
34
  def test_distance_to_returns_float
@@ -49,6 +43,14 @@ class GeocoderTest < Test::Unit::TestCase
49
43
  assert_equal v.distance_from(30, -94), v.distance_to(30, -94)
50
44
  end
51
45
 
46
+ def test_coordinates_method
47
+ assert Geocoder.coordinates("Madison Square Garden, New York, NY").is_a?(Array)
48
+ end
49
+
50
+ def test_address_method
51
+ assert Geocoder.address(40.750354, -73.993371).is_a?(String)
52
+ end
53
+
52
54
 
53
55
  # --- general ---
54
56
 
@@ -70,7 +72,7 @@ class GeocoderTest < Test::Unit::TestCase
70
72
  e = Event.new(*venue_params(:msg))
71
73
  coords = [40.750354, -73.993371]
72
74
  e.geocode
73
- assert_equal coords.map{ |c| c.to_s }.join(','), e.coordinates
75
+ assert_equal coords.map{ |c| c.to_s }.join(','), e.coords_string
74
76
  end
75
77
 
76
78
  def test_geocode_with_block_doesnt_auto_assign_coordinates
@@ -118,22 +120,176 @@ class GeocoderTest < Test::Unit::TestCase
118
120
  assert_equal address, v.address
119
121
  end
120
122
 
123
+ def test_search_returns_empty_array_when_no_results
124
+ street_lookups.each do |l|
125
+ Geocoder::Configuration.lookup = l
126
+ assert_equal [], Geocoder.search("no results"),
127
+ "Lookup #{l} does not return empty array when no results."
128
+ end
129
+ end
130
+
131
+ def test_result_has_required_attributes
132
+ all_lookups.each do |l|
133
+ Geocoder::Configuration.lookup = l
134
+ result = Geocoder.search(45.423733, -75.676333).first
135
+ assert_result_has_required_attributes(result)
136
+ end
137
+ end
138
+
139
+
140
+ # --- calcluations ---
141
+
142
+ def test_longitude_degree_distance_at_equator
143
+ assert_equal 69, Geocoder::Calculations.longitude_degree_distance(0).round
144
+ end
145
+
146
+ def test_longitude_degree_distance_at_new_york
147
+ assert_equal 53, Geocoder::Calculations.longitude_degree_distance(40).round
148
+ end
149
+
150
+ def test_longitude_degree_distance_at_north_pole
151
+ assert_equal 0, Geocoder::Calculations.longitude_degree_distance(89.98).round
152
+ end
153
+
154
+ def test_distance_between_in_miles
155
+ assert_equal 69, Geocoder::Calculations.distance_between(0,0, 0,1).round
156
+ la_to_ny = Geocoder::Calculations.distance_between(34.05,-118.25, 40.72,-74).round
157
+ assert (la_to_ny - 2444).abs < 10
158
+ end
159
+
160
+ def test_distance_between_in_kilometers
161
+ assert_equal 111, Geocoder::Calculations.distance_between(0,0, 0,1, :units => :km).round
162
+ la_to_ny = Geocoder::Calculations.distance_between(34.05,-118.25, 40.72,-74, :units => :km).round
163
+ assert (la_to_ny - 3942).abs < 10
164
+ end
165
+
166
+ def test_geographic_center_with_arrays
167
+ assert_equal [0.0, 0.5],
168
+ Geocoder::Calculations.geographic_center([[0,0], [0,1]])
169
+ assert_equal [0.0, 1.0],
170
+ Geocoder::Calculations.geographic_center([[0,0], [0,1], [0,2]])
171
+ end
172
+
173
+ def test_geographic_center_with_mixed_arguments
174
+ p1 = [0, 0]
175
+ p2 = Landmark.new("Some Cold Place", 0, 1)
176
+ assert_equal [0.0, 0.5], Geocoder::Calculations.geographic_center([p1, p2])
177
+ end
178
+
179
+ def test_bounding_box_calculation_in_miles
180
+ center = [51, 7] # Cologne, DE
181
+ radius = 10 # miles
182
+ dlon = radius / Geocoder::Calculations.latitude_degree_distance
183
+ dlat = radius / Geocoder::Calculations.longitude_degree_distance(center[0])
184
+ corners = [50.86, 6.77, 51.14, 7.23]
185
+ assert_equal corners.map{ |i| (i * 100).round },
186
+ Geocoder::Calculations.bounding_box(center[0], center[1], radius).map{ |i| (i * 100).round }
187
+ end
188
+
189
+ def test_bounding_box_calculation_in_kilometers
190
+ center = [51, 7] # Cologne, DE
191
+ radius = 111 # kilometers (= 1 degree latitude)
192
+ dlon = radius / Geocoder::Calculations.latitude_degree_distance(:km)
193
+ dlat = radius / Geocoder::Calculations.longitude_degree_distance(center[0], :km)
194
+ corners = [50, 5.41, 52, 8.59]
195
+ assert_equal corners.map{ |i| (i * 100).round },
196
+ Geocoder::Calculations.bounding_box(center[0], center[1], radius, :units => :km).map{ |i| (i * 100).round }
197
+ end
198
+
199
+
200
+ # --- bearing ---
201
+
202
+ def test_compass_points
203
+ assert_equal "N", Geocoder::Calculations.compass_point(0)
204
+ assert_equal "N", Geocoder::Calculations.compass_point(1.0)
205
+ assert_equal "N", Geocoder::Calculations.compass_point(360)
206
+ assert_equal "N", Geocoder::Calculations.compass_point(361)
207
+ assert_equal "N", Geocoder::Calculations.compass_point(-22)
208
+ assert_equal "NW", Geocoder::Calculations.compass_point(-23)
209
+ assert_equal "S", Geocoder::Calculations.compass_point(180)
210
+ assert_equal "S", Geocoder::Calculations.compass_point(181)
211
+ end
212
+
213
+ def test_bearing_between
214
+ bearings = {
215
+ :n => 0,
216
+ :e => 90,
217
+ :s => 180,
218
+ :w => 270
219
+ }
220
+ points = {
221
+ :n => [41, -75],
222
+ :e => [40, -74],
223
+ :s => [39, -75],
224
+ :w => [40, -76]
225
+ }
226
+ directions = [:n, :e, :s, :w]
227
+ methods = [:linear, :spherical]
228
+
229
+ methods.each do |m|
230
+ directions.each_with_index do |d,i|
231
+ opp = directions[(i + 2) % 4] # opposite direction
232
+ p1 = points[d]
233
+ p2 = points[opp]
234
+
235
+ args = p1 + p2 + [:method => m]
236
+ b = Geocoder::Calculations.bearing_between(*args)
237
+ assert (b - bearings[opp]).abs < 1,
238
+ "Bearing (#{m}) should be close to #{bearings[opp]} but was #{b}."
239
+ end
240
+ end
241
+ end
242
+
243
+
244
+ # --- input handling ---
245
+
246
+ def test_ip_address_detection
247
+ assert Geocoder.send(:ip_address?, "232.65.123.94")
248
+ assert Geocoder.send(:ip_address?, "666.65.123.94") # technically invalid
249
+ assert !Geocoder.send(:ip_address?, "232.65.123.94.43")
250
+ assert !Geocoder.send(:ip_address?, "232.65.123")
251
+ end
252
+
253
+ def test_blank_query_detection
254
+ assert Geocoder.send(:blank_query?, nil)
255
+ assert Geocoder.send(:blank_query?, "")
256
+ assert Geocoder.send(:blank_query?, "\t ")
257
+ assert !Geocoder.send(:blank_query?, "a")
258
+ assert !Geocoder.send(:blank_query?, "Москва") # no ASCII characters
259
+ end
260
+
261
+ def test_does_not_choke_on_nil_address
262
+ all_lookups.each do |l|
263
+ Geocoder::Configuration.lookup = l
264
+ assert_nothing_raised { Venue.new("Venue", nil).geocode }
265
+ end
266
+ end
267
+
268
+
269
+ # --- error handling ---
270
+
271
+ def test_does_not_choke_on_timeout
272
+ # keep test output clean: suppress timeout warning
273
+ orig = $VERBOSE; $VERBOSE = nil
274
+ all_lookups.each do |l|
275
+ Geocoder::Configuration.lookup = l
276
+ assert_nothing_raised { Geocoder.search("timeout") }
277
+ end
278
+ $VERBOSE = orig
279
+ end
280
+
121
281
 
122
282
  # --- Google ---
123
283
 
124
- def test_result_address_components_of_type
125
- result = Geocoder.search("Madison Square Garden, New York, NY")
284
+ def test_google_result_components
285
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
126
286
  assert_equal "Manhattan",
127
287
  result.address_components_of_type(:sublocality).first['long_name']
128
288
  end
129
289
 
130
- def test_google_result_has_required_attributes
131
- result = Geocoder.search("Madison Square Garden, New York, NY")
132
- assert_result_has_required_attributes(result)
133
- end
134
-
135
- def test_google_returns_nil_when_no_results
136
- assert_nil Geocoder.search("no results")
290
+ def test_google_returns_city_when_no_locality_in_result
291
+ result = Geocoder.search("no locality").first
292
+ assert_equal "Haram", result.city
137
293
  end
138
294
 
139
295
 
@@ -141,79 +297,79 @@ class GeocoderTest < Test::Unit::TestCase
141
297
 
142
298
  def test_yahoo_result_components
143
299
  Geocoder::Configuration.lookup = :yahoo
144
- result = Geocoder.search("Madison Square Garden, New York, NY")
145
- assert_equal "10001", result.postal
300
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
301
+ assert_equal "10001", result.postal_code
146
302
  end
147
303
 
148
304
  def test_yahoo_address_formatting
149
305
  Geocoder::Configuration.lookup = :yahoo
150
- result = Geocoder.search("Madison Square Garden, New York, NY")
306
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
151
307
  assert_equal "Madison Square Garden, New York, NY 10001, United States",
152
308
  result.address
153
309
  end
154
310
 
155
- def test_yahoo_result_has_required_attributes
156
- Geocoder::Configuration.lookup = :yahoo
157
- result = Geocoder.search("Madison Square Garden, New York, NY")
158
- assert_result_has_required_attributes(result)
159
- end
160
311
 
161
- def test_yahoo_returns_nil_when_no_results
162
- Geocoder::Configuration.lookup = :yahoo
163
- assert_nil Geocoder.search("no results")
312
+ # --- Geocoder.ca ---
313
+
314
+ def test_geocoder_ca_result_components
315
+ Geocoder::Configuration.lookup = :geocoder_ca
316
+ result = Geocoder.search(45.423733, -75.676333).first
317
+ assert_equal "CA", result.country_code
318
+ assert_equal "289 Somerset ST E, Ottawa, ON K1N6W1, Canada", result.address
164
319
  end
165
320
 
166
321
 
167
322
  # --- FreeGeoIp ---
168
323
 
169
324
  def test_freegeoip_result_on_ip_address_search
170
- result = Geocoder.search("74.200.247.59")
325
+ result = Geocoder.search("74.200.247.59").first
171
326
  assert result.is_a?(Geocoder::Result::Freegeoip)
172
327
  end
173
328
 
174
329
  def test_freegeoip_result_components
175
- result = Geocoder.search("74.200.247.59")
330
+ result = Geocoder.search("74.200.247.59").first
176
331
  assert_equal "Plano, TX 75093, United States", result.address
177
332
  end
178
333
 
179
- def test_freegeoip_result_has_required_attributes
180
- result = Geocoder.search("74.200.247.59")
181
- assert_result_has_required_attributes(result)
182
- end
183
-
184
334
 
185
335
  # --- search queries ---
186
336
 
187
- def test_ip_address_detection
188
- assert Geocoder.send(:ip_address?, "232.65.123.94")
189
- assert Geocoder.send(:ip_address?, "666.65.123.94") # technically invalid
190
- assert !Geocoder.send(:ip_address?, "232.65.123.94.43")
191
- assert !Geocoder.send(:ip_address?, "232.65.123")
337
+ def test_hash_to_query
338
+ g = Geocoder::Lookup::Google.new
339
+ assert_equal "a=1&b=2", g.send(:hash_to_query, {:a => 1, :b => 2})
192
340
  end
193
341
 
194
- def test_blank_query_detection
195
- assert Geocoder.send(:blank_query?, nil)
196
- assert Geocoder.send(:blank_query?, "")
197
- assert Geocoder.send(:blank_query?, ", , (-)")
198
- assert !Geocoder.send(:blank_query?, "a")
342
+ def test_google_api_key
343
+ Geocoder::Configuration.api_key = "MY_KEY"
344
+ g = Geocoder::Lookup::Google.new
345
+ assert_match "key=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
199
346
  end
200
347
 
201
- def test_hash_to_query
202
- g = Geocoder::Lookup::Google.new
203
- assert_equal "a=1&b=2", g.send(:hash_to_query, {:a => 1, :b => 2})
348
+ def test_yahoo_app_id
349
+ Geocoder::Configuration.api_key = "MY_KEY"
350
+ g = Geocoder::Lookup::Yahoo.new
351
+ assert_match "appid=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
352
+ end
353
+
354
+ def test_detection_of_coordinates_in_search_string
355
+ Geocoder::Configuration.lookup = :geocoder_ca
356
+ result = Geocoder.search("51.178844, -1.826189").first
357
+ assert_not_nil result.city
358
+ # city only present if reverse geocoding search performed
204
359
  end
205
360
 
206
361
 
207
362
  private # ------------------------------------------------------------------
208
363
 
209
364
  def assert_result_has_required_attributes(result)
210
- assert result.coordinates.is_a?(Array)
211
- assert result.latitude.is_a?(Float)
212
- assert result.longitude.is_a?(Float)
213
- assert result.city.is_a?(String)
214
- assert result.postal_code.is_a?(String)
215
- assert result.country.is_a?(String)
216
- assert result.country_code.is_a?(String)
217
- assert_not_nil result.address
365
+ m = "Lookup #{Geocoder::Configuration.lookup} does not support %s attribute."
366
+ assert result.coordinates.is_a?(Array), m % "coordinates"
367
+ assert result.latitude.is_a?(Float), m % "latitude"
368
+ assert result.longitude.is_a?(Float), m % "longitude"
369
+ assert result.city.is_a?(String), m % "city"
370
+ assert result.postal_code.is_a?(String), m % "postal_code"
371
+ assert result.country.is_a?(String), m % "country"
372
+ assert result.country_code.is_a?(String), m % "country_code"
373
+ assert_not_nil result.address, m % "address"
218
374
  end
219
375
  end