geocoder 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

@@ -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