geocoder 1.1.2 → 1.1.3

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.

data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ gemfile:
6
+ - Gemfile
7
+ - gemfiles/Gemfile.mongoid-2.4.x
8
+ env: SSL_CERT_DIR=/etc/ssl/certs
9
+ matrix:
10
+ exclude:
11
+ - rvm: 1.8.7
12
+ gemfile: Gemfile
13
+ env: SSL_CERT_DIR=/etc/ssl/certs
14
+ - rvm: 1.9.2
15
+ gemfile: Gemfile
16
+ env: SSL_CERT_DIR=/etc/ssl/certs
17
+ - rvm: 1.9.3
18
+ gemfile: gemfiles/Gemfile.mongoid-2.4.x
19
+ env: SSL_CERT_DIR=/etc/ssl/certs
data/CHANGELOG.rdoc CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Per-release changes to Geocoder.
4
4
 
5
+ == 1.1.3 (2012 Aug 26)
6
+
7
+ * Add support for Mapquest geocoding service (thanks github.com/razorinc).
8
+ * Add :test lookup for easy testing of apps using Geocoder (thanks github.com/mguterl).
9
+ * Add #precision method to Yandex results (thanks github.com/gemaker).
10
+ * Add support for raising :all exceptions (thanks github.com/andyvb).
11
+ * Add exceptions for certain Google geocoder responses (thanks github.com/andyvb).
12
+ * Add Travis-CI integration (thanks github.com/petergoldstein).
13
+ * Fix: unit config was not working with SQLite (thanks github.com/balvig).
14
+ * Fix: get tests to pass under Jruby (thanks github.com/petergoldstein).
15
+ * Fix: bug in distance_from_sql method (error occurred when coordinates not found).
16
+ * Fix: incompatibility with Mongoid 3.0.x (thanks github.com/petergoldstein).
17
+
5
18
  == 1.1.2 (2012 May 24)
6
19
 
7
20
  * Add ability to specify default units and distance calculation method (thanks github.com/abravalheri).
data/README.rdoc CHANGED
@@ -201,6 +201,20 @@ For reverse geocoding you can also specify an alternate name attribute where the
201
201
  reverse_geocoded_by :coordinates, :address => :loc # MongoDB
202
202
 
203
203
 
204
+ == Advanced Querying
205
+
206
+ When querying for objects (if you're using ActiveRecord) you can also look within a square rather than a radius (circle) by using the <tt>within_bounding_box</tt> scope:
207
+
208
+ distance = 20
209
+ center_point = [40.71, 100.23]
210
+ box = Geocoder::Calculations.bounding_box(center_point, distance)
211
+ Venue.within_bounding_box(box, distance)
212
+
213
+ This can also dramatically improve query performance, especially when used in conjunction with indexes on the latitude/longitude columns. Note, however, that returned results do not include +distance+ and +bearing+ attributes. If you want to improve performance AND have access to distance and bearing info, use both scopes:
214
+
215
+ Venue.near(center_point, distance).within_bounding_box(box, distance)
216
+
217
+
204
218
  == Advanced Geocoding
205
219
 
206
220
  So far we have looked at shortcuts for assigning geocoding results to object attributes. However, if you need to do something fancy you can skip the auto-assignment by providing a block (takes the object to be geocoded and an array of <tt>Geocoder::Result</tt> objects) in which you handle the parsed geocoding result any way you like, for example:
@@ -264,7 +278,7 @@ The following is a comparison of the supported geocoding APIs. The "Limitations"
264
278
 
265
279
  ==== Google (<tt>:google</tt>)
266
280
 
267
- API key:: optional (required for Premier)
281
+ API key:: required for Premier (do NOT use a key for the free version)
268
282
  Key signup:: http://code.google.com/apis/maps/signup.html
269
283
  Quota:: 2,500 requests/day, 100,000 with Google Maps API Premier
270
284
  Region:: world
@@ -312,9 +326,8 @@ Limitations:: Please limit request rate to 1 per second and include your contact
312
326
 
313
327
  ==== Yandex (<tt>:yandex</tt>)
314
328
 
315
- API key:: required
316
- Key signup:: http://api.yandex.ru/maps/intro/concepts/intro.xml#apikey
317
- Quota:: ?
329
+ API key:: none
330
+ Quota:: 25000 requests / day
318
331
  Region:: Russia
319
332
  SSL support:: no
320
333
  Languages:: Russian, Belarusian, and Ukrainian
@@ -333,13 +346,24 @@ Documentation:: ?
333
346
  Terms of Service:: http://geocoder.ca/?terms=1
334
347
  Limitations:: "Under no circumstances can our data be re-distributed or re-sold by anyone to other parties without our written permission."
335
348
 
336
- ==== FreeGeoIP
349
+ ==== Mapquest (<tt>:mapquest</tt>)
337
350
 
338
351
  API key:: none
339
352
  Quota:: ?
340
353
  Region:: world
341
354
  SSL support:: no
342
355
  Languages:: English
356
+ Documentation:: http://www.mapquestapi.com/geocoding/
357
+ Terms of Service:: http://info.mapquest.com/terms-of-use/
358
+ Limitations:: ?
359
+
360
+ ==== FreeGeoIP
361
+
362
+ API key:: none
363
+ Quota:: 1000 requests per hour. After reaching the hourly quota, all of your requests will result in HTTP 403 (Forbidden) until it clears up on the next roll over.
364
+ Region:: world
365
+ SSL support:: no
366
+ Languages:: English
343
367
  Documentation:: http://github.com/fiorix/freegeoip/blob/master/README.rst
344
368
  Terms of Service:: ?
345
369
  Limitations:: ?
@@ -416,6 +440,29 @@ You can use Geocoder outside of Rails by calling the <tt>Geocoder.search</tt> me
416
440
  This returns an array of <tt>Geocoder::Result</tt> objects with all information provided by the geocoding service. Please see above and in the code for details.
417
441
 
418
442
 
443
+ == Testing Apps that Use Geocoder
444
+
445
+ When writing tests for an app that uses Geocoder it may be useful to avoid network calls and have Geocoder return consistent, configurable results. To do this, configure and use the <tt>:test</tt> lookup. For example:
446
+
447
+ Geocoder::Configuration.lookup = :test
448
+
449
+ Geocoder::Lookup::Test.add_stub(
450
+ "New York, NY", [
451
+ {
452
+ 'latitude' => 40.7143528,
453
+ 'longitude' => -74.0059731,
454
+ 'address' => 'New York, NY, USA',
455
+ 'state' => 'New York',
456
+ 'state_code' => 'NY',
457
+ 'country' => 'United States',
458
+ 'country_code' => 'US'
459
+ }
460
+ ]
461
+ )
462
+
463
+ Now, any time Geocoder looks up "New York, NY" its results array will contain one result with the above attributes.
464
+
465
+
419
466
  == Command Line Interface
420
467
 
421
468
  When you install the Geocoder gem it adds a +geocode+ command to your shell. You can search for a street address, IP address, postal code, coordinates, etc just like you can with the Geocoder.search method for example:
@@ -441,7 +488,7 @@ Mongo document classes (Mongoid and MongoMapper) have a built-in +near+ scope, b
441
488
 
442
489
  === Latitude/Longitude Order
443
490
 
444
- Coordinates are generally printed and spoken as latitude, then logitude ([lat,lon]). Geocoder respects this convention and always expects method arguments to be given in [lat,lon] order. However, MongoDB requires that coordinates be stored in [lon,lat] order as per the GeoJSON spec (http://geojson.org/geojson-spec.html#positions), so internally they are stored "backwards." However, this does not affect order of arguments to methods when using Mongoid or MongoMapper.
491
+ Coordinates are generally printed and spoken as latitude, then longitude ([lat,lon]). Geocoder respects this convention and always expects method arguments to be given in [lat,lon] order. However, MongoDB requires that coordinates be stored in [lon,lat] order as per the GeoJSON spec (http://geojson.org/geojson-spec.html#positions), so internally they are stored "backwards." However, this does not affect order of arguments to methods when using Mongoid or MongoMapper.
445
492
 
446
493
  To access an object's coordinates in the conventional order, use the <tt>to_coordinates</tt> instance method provided by Geocoder. For example:
447
494
 
@@ -485,6 +532,12 @@ By default Geocoder will rescue any exceptions raised by calls to the geocoding
485
532
 
486
533
  Geocoder::Configuration.always_raise = [SocketError, TimeoutError]
487
534
 
535
+ You can also do this to raise all exceptions:
536
+
537
+ Geocoder::Configuration.always_raise = :all
538
+
539
+ See <tt>lib/geocoder/exceptions.rb</tt> for a list of raise-able exceptions.
540
+
488
541
 
489
542
  == Known Issue
490
543
 
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec :path => '..'
4
+
5
+ group :development, :test do
6
+ gem 'rake'
7
+ gem 'mongoid', '2.4.11'
8
+ gem 'bson_ext', :platforms => :ruby
9
+
10
+ gem 'rails'
11
+
12
+ platforms :jruby do
13
+ gem 'jruby-openssl'
14
+ end
15
+ end
@@ -1,4 +1,4 @@
1
- Geocoder.configure do
1
+ Geocoder.configure do |config|
2
2
  ## Configurable parameters: if you wish to change some configurable
3
3
  ## behaviour in Geocoder, feel free to uncomment the following lines
4
4
  ## and provide custom parameters.
@@ -19,7 +19,7 @@ Geocoder.configure do
19
19
  # config.always_raise = []
20
20
 
21
21
  ## Calculation options
22
- # config.units = :mi # :km for kilometers or :mi for miles
23
- # config.method = :linear # :spherical or :linear
22
+ # config.units = :mi # :km for kilometers or :mi for miles
23
+ # config.distances = :linear # :spherical or :linear
24
24
  end
25
25
 
data/lib/geocoder.rb CHANGED
@@ -57,7 +57,7 @@ module Geocoder
57
57
  # All street address lookups, default first.
58
58
  #
59
59
  def street_lookups
60
- [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex, :nominatim]
60
+ [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex, :nominatim, :mapquest, :test]
61
61
  end
62
62
 
63
63
  ##
@@ -24,6 +24,18 @@ module Geocoder
24
24
  # Not a number constant
25
25
  NAN = defined?(::Float::NAN) ? ::Float::NAN : 0 / 0.0
26
26
 
27
+ ##
28
+ # Returns true if all given arguments are valid latitude/longitude values.
29
+ #
30
+ def coordinates_present?(*args)
31
+ args.each do |a|
32
+ # note that Float::NAN != Float::NAN
33
+ # still, this could probably be improved:
34
+ return false if (!a.is_a?(Numeric) or a.to_s == "NaN")
35
+ end
36
+ true
37
+ end
38
+
27
39
  ##
28
40
  # Distance spanned by one degree of latitude in the given units.
29
41
  #
@@ -99,5 +99,6 @@ module Geocoder
99
99
  instance.set_defaults
100
100
  end
101
101
  end
102
+
102
103
  end
103
104
  end
@@ -8,4 +8,11 @@ module Geocoder
8
8
 
9
9
  class OverQueryLimitError < Error
10
10
  end
11
+
12
+ class RequestDenied < Error
13
+ end
14
+
15
+ class InvalidRequest < Error
16
+ end
17
+
11
18
  end
@@ -1,4 +1,5 @@
1
1
  require 'net/http'
2
+ require 'net/https'
2
3
  require 'uri'
3
4
 
4
5
  unless defined?(ActiveSupport::JSON)
@@ -99,7 +100,8 @@ module Geocoder
99
100
  # Return false if exception not raised.
100
101
  #
101
102
  def raise_error(error, message = nil)
102
- if Geocoder::Configuration.always_raise.include?( error.is_a?(Class) ? error : error.class )
103
+ exceptions = Geocoder::Configuration.always_raise
104
+ if exceptions == :all or exceptions.include?( error.is_a?(Class) ? error : error.class )
103
105
  raise error, message
104
106
  else
105
107
  false
@@ -18,9 +18,11 @@ module Geocoder::Lookup
18
18
  raise_error(Geocoder::OverQueryLimitError) ||
19
19
  warn("Google Geocoding API error: over query limit.")
20
20
  when "REQUEST_DENIED"
21
- warn "Google Geocoding API error: request denied."
21
+ raise_error(Geocoder::RequestDenied) ||
22
+ warn("Google Geocoding API error: request denied.")
22
23
  when "INVALID_REQUEST"
23
- warn "Google Geocoding API error: invalid request."
24
+ raise_error(Geocoder::InvalidRequest) ||
25
+ warn("Google Geocoding API error: invalid request.")
24
26
  end
25
27
  return []
26
28
  end
@@ -0,0 +1,33 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/mapquest"
3
+
4
+ module Geocoder::Lookup
5
+ class Mapquest < Base
6
+
7
+ private # ---------------------------------------------------------------
8
+
9
+ def results(query, reverse = false)
10
+ return [] unless doc = fetch_data(query, reverse)
11
+ doc.is_a?(Array) ? doc : [doc]
12
+ end
13
+
14
+ def query_url(query, reverse = false)
15
+ params = {
16
+ :format => "json",
17
+ :polygon => "1",
18
+ :addressdetails => "1",
19
+ :"accept-language" => Geocoder::Configuration.language
20
+ }
21
+ if (reverse)
22
+ method = 'reverse'
23
+ parts = query.split(/\s*,\s*/);
24
+ params[:lat] = parts[0]
25
+ params[:lon] = parts[1]
26
+ else
27
+ method = 'search'
28
+ params[:q] = query
29
+ end
30
+ "http://open.mapquestapi.com/#{method}?" + hash_to_query(params)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/test'
3
+
4
+ module Geocoder
5
+ module Lookup
6
+ class Test < Base
7
+
8
+ def self.add_stub(query, results)
9
+ stubs[query] = results
10
+ end
11
+
12
+ def self.read_stub(query)
13
+ stubs.fetch(query) { raise ArgumentError, "unknown stub request #{query}" }
14
+ end
15
+
16
+ def self.stubs
17
+ @stubs ||= {}
18
+ end
19
+
20
+ def self.reset
21
+ @stubs = {}
22
+ end
23
+
24
+ private
25
+
26
+ def results(query, reverse = false)
27
+ Geocoder::Lookup::Test.read_stub(query)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,4 @@
1
+ require 'mongoid/version'
1
2
  require 'geocoder/models/base'
2
3
  require 'geocoder/models/mongo_base'
3
4
 
@@ -17,8 +18,14 @@ module Geocoder
17
18
  def geocoder_init(options)
18
19
  super(options)
19
20
  if options[:skip_index] == false
20
- index [[ geocoder_options[:coordinates], Mongo::GEO2D ]],
21
- :min => -180, :max => 180 # create 2d index
21
+ # create 2d index
22
+ if (::Mongoid::VERSION >= "3")
23
+ index({ geocoder_options[:coordinates].to_sym => '2d' },
24
+ {:min => -180, :max => 180})
25
+ else
26
+ index [[ geocoder_options[:coordinates], '2d' ]],
27
+ :min => -180, :max => 180
28
+ end
22
29
  end
23
30
  end
24
31
  end
@@ -0,0 +1,66 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Mapquest < Base
5
+
6
+ def house_number
7
+ @data['address']['house_number']
8
+ end
9
+
10
+ def address
11
+ @data['display_name']
12
+ end
13
+
14
+ def street
15
+ @data['address']['road']
16
+ end
17
+
18
+ def city
19
+ @data['address']['city']
20
+ end
21
+
22
+ def village
23
+ @data['address']['villiage']
24
+ end
25
+
26
+ def town
27
+ @data['address']['town']
28
+ end
29
+
30
+ def state
31
+ @data['address']['state']
32
+ end
33
+
34
+ alias_method :state_code, :state
35
+
36
+ def postal_code
37
+ @data['address']['postcode']
38
+ end
39
+
40
+ def county
41
+ @data['address']['county']
42
+ end
43
+
44
+ def country
45
+ @data['address']['country']
46
+ end
47
+
48
+ def country_code
49
+ @data['address']['country_code']
50
+ end
51
+
52
+ def coordinates
53
+ [@data['lat'].to_f, @data['lon'].to_f]
54
+ end
55
+
56
+ def self.response_attributes
57
+ %w[place_id boundingbox license polygonpoints display_name class type stadium suburb]
58
+ end
59
+
60
+ response_attributes.each do |a|
61
+ define_method a do
62
+ @data[a]
63
+ end
64
+ end
65
+ end
66
+ end
@@ -3,6 +3,12 @@ require 'geocoder/results/base'
3
3
  module Geocoder::Result
4
4
  class Nominatim < Base
5
5
 
6
+ def poi
7
+ %w[stadium bus_stop tram_stop].each do |key|
8
+ @data['address'][key] if @data['address'].key?(key)
9
+ end
10
+ end
11
+
6
12
  def house_number
7
13
  @data['address']['house_number']
8
14
  end
@@ -12,11 +18,17 @@ module Geocoder::Result
12
18
  end
13
19
 
14
20
  def street
15
- @data['address']['road']
21
+ %w[road pedestrian highway].each do |key|
22
+ return @data['address'][key] if @data['address'].key?(key)
23
+ end
24
+ return nil
16
25
  end
17
26
 
18
27
  def city
19
- @data['address']['city']
28
+ %w[city town village hamlet].each do |key|
29
+ return @data['address'][key] if @data['address'].key?(key)
30
+ end
31
+ return nil
20
32
  end
21
33
 
22
34
  def village
@@ -49,13 +61,17 @@ module Geocoder::Result
49
61
  @data['address']['country_code']
50
62
  end
51
63
 
64
+ def suburb
65
+ @data['address']['suburb']
66
+ end
67
+
52
68
  def coordinates
53
69
  [@data['lat'].to_f, @data['lon'].to_f]
54
70
  end
55
71
 
56
72
  def self.response_attributes
57
- %w[place_id, osm_type, osm_id, boundingbox, license,
58
- polygonpoints, display_name, class, type, stadium, suburb]
73
+ %w[place_id osm_type osm_id boundingbox license
74
+ polygonpoints display_name class type stadium]
59
75
  end
60
76
 
61
77
  response_attributes.each do |a|
@@ -0,0 +1,15 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder
4
+ module Result
5
+ class Test < Base
6
+
7
+ %w[latitude longitude city state state_code province
8
+ province_code postal_code country country_code address].each do |attr|
9
+ define_method(attr) do
10
+ @data[attr.to_s] || @data[attr.to_sym]
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -57,6 +57,10 @@ module Geocoder::Result
57
57
  address_details['Locality']['Premise']['PremiseName']
58
58
  end
59
59
 
60
+ def precision
61
+ @data['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision']
62
+ end
63
+
60
64
  private # ----------------------------------------------------------------
61
65
 
62
66
  def address_details
@@ -33,7 +33,7 @@ module Geocoder::Store
33
33
  #
34
34
  scope :near, lambda{ |location, *args|
35
35
  latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
36
- if latitude and longitude and ![latitude, longitude].include?(Geocoder::Calculations::NAN)
36
+ if Geocoder::Calculations.coordinates_present?(latitude, longitude)
37
37
  near_scope_options(latitude, longitude, *args)
38
38
  else
39
39
  where(false_condition) # no results if no lat/lon given
@@ -68,7 +68,9 @@ module Geocoder::Store
68
68
 
69
69
  def distance_from_sql(location, *args)
70
70
  latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
71
- distance_from_sql_options(latitude, longitude, *args) if latitude and longitude
71
+ if Geocoder::Calculations.coordinates_present?(latitude, longitude)
72
+ distance_from_sql_options(latitude, longitude, *args)
73
+ end
72
74
  end
73
75
 
74
76
  private # ----------------------------------------------------------------
@@ -202,21 +204,21 @@ module Geocoder::Store
202
204
  end
203
205
  if options[:bearing]
204
206
  bearing = "CASE " +
205
- "WHEN (#{lat_attr} >= #{latitude} AND #{lon_attr} >= #{longitude}) THEN 45.0 " +
206
- "WHEN (#{lat_attr} < #{latitude} AND #{lon_attr} >= #{longitude}) THEN 135.0 " +
207
- "WHEN (#{lat_attr} < #{latitude} AND #{lon_attr} < #{longitude}) THEN 225.0 " +
208
- "WHEN (#{lat_attr} >= #{latitude} AND #{lon_attr} < #{longitude}) THEN 315.0 " +
207
+ "WHEN (#{full_column_name(lat_attr)} >= #{latitude} AND #{full_column_name(lon_attr)} >= #{longitude}) THEN 45.0 " +
208
+ "WHEN (#{full_column_name(lat_attr)} < #{latitude} AND #{full_column_name(lon_attr)} >= #{longitude}) THEN 135.0 " +
209
+ "WHEN (#{full_column_name(lat_attr)} < #{latitude} AND #{full_column_name(lon_attr)} < #{longitude}) THEN 225.0 " +
210
+ "WHEN (#{full_column_name(lat_attr)} >= #{latitude} AND #{full_column_name(lon_attr)} < #{longitude}) THEN 315.0 " +
209
211
  "END"
210
212
  else
211
213
  bearing = false
212
214
  end
213
215
 
214
- distance = approx_distance_from_sql(latitude, longitude, options)
215
216
  options[:units] ||= (geocoder_options[:units] || Geocoder::Configuration.units)
217
+ distance = approx_distance_from_sql(latitude, longitude, options)
216
218
 
217
219
  b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
218
220
  conditions = [
219
- "#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
221
+ "#{full_column_name(lat_attr)} BETWEEN ? AND ? AND #{full_column_name(lon_attr)} BETWEEN ? AND ?"] +
220
222
  [b[0], b[2], b[1], b[3]
221
223
  ]
222
224
  default_near_scope_options(latitude, longitude, radius, options).merge(
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -152,24 +152,24 @@ class CalculationsTest < Test::Unit::TestCase
152
152
 
153
153
  def test_extract_coordinates
154
154
  result = Geocoder::Calculations.extract_coordinates([ nil, nil ])
155
- assert_equal [ Geocoder::Calculations::NAN ] * 2, result
155
+ assert is_nan_coordinates?(result)
156
156
 
157
157
  result = Geocoder::Calculations.extract_coordinates([ 1.0 / 3, 2.0 / 3 ])
158
158
  assert_in_delta 1.0 / 3, result.first, 1E-5
159
159
  assert_in_delta 2.0 / 3, result.last, 1E-5
160
160
 
161
161
  result = Geocoder::Calculations.extract_coordinates(nil)
162
- assert_equal [ Geocoder::Calculations::NAN ] * 2, result
162
+ assert is_nan_coordinates?(result)
163
163
 
164
164
  result = Geocoder::Calculations.extract_coordinates('')
165
- assert_equal [ Geocoder::Calculations::NAN ] * 2, result
165
+ assert is_nan_coordinates?(result)
166
166
 
167
167
  result = Geocoder::Calculations.extract_coordinates([ 'nix' ])
168
- assert_equal [ Geocoder::Calculations::NAN ] * 2, result
168
+ assert is_nan_coordinates?(result)
169
169
 
170
170
  o = Object.new
171
171
  result = Geocoder::Calculations.extract_coordinates(o)
172
- assert_equal [ Geocoder::Calculations::NAN ] * 2, result
172
+ assert is_nan_coordinates?(result)
173
173
 
174
174
  def o.to_coordinates
175
175
  [ 1.0 / 3, 2.0 / 3 ]
@@ -178,5 +178,11 @@ class CalculationsTest < Test::Unit::TestCase
178
178
  assert_in_delta 1.0 / 3, result.first, 1E-5
179
179
  assert_in_delta 2.0 / 3, result.last, 1E-5
180
180
  end
181
- end
182
181
 
182
+ def test_coordinates_present
183
+ assert Geocoder::Calculations.coordinates_present?(3.23)
184
+ assert !Geocoder::Calculations.coordinates_present?(nil)
185
+ assert !Geocoder::Calculations.coordinates_present?(Geocoder::Calculations::NAN)
186
+ assert !Geocoder::Calculations.coordinates_present?(3.23, nil)
187
+ end
188
+ end
@@ -10,7 +10,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
10
10
  def test_does_not_choke_on_timeout
11
11
  # keep test output clean: suppress timeout warning
12
12
  orig = $VERBOSE; $VERBOSE = nil
13
- all_lookups.each do |l|
13
+ all_lookups_except_test.each do |l|
14
14
  Geocoder::Configuration.lookup = l
15
15
  assert_nothing_raised { Geocoder.search("timeout") }
16
16
  end
@@ -19,7 +19,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
19
19
 
20
20
  def test_always_raise_timeout_error
21
21
  Geocoder::Configuration.always_raise = [TimeoutError]
22
- all_lookups.each do |l|
22
+ all_lookups_except_test.each do |l|
23
23
  lookup = Geocoder.send(:get_lookup, l)
24
24
  assert_raises TimeoutError do
25
25
  lookup.send(:results, "timeout")
@@ -29,7 +29,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
29
29
 
30
30
  def test_always_raise_socket_error
31
31
  Geocoder::Configuration.always_raise = [SocketError]
32
- all_lookups.each do |l|
32
+ all_lookups_except_test.each do |l|
33
33
  lookup = Geocoder.send(:get_lookup, l)
34
34
  assert_raises SocketError do
35
35
  lookup.send(:results, "socket_error")
@@ -0,0 +1,27 @@
1
+ [
2
+ {
3
+ "place_id":"2177656031",
4
+ "licence":"Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0.",
5
+ "osm_type":"way",
6
+ "osm_id":"138141251",
7
+ "boundingbox":["40.7498588562012","40.751163482666","-73.9944381713867","-73.9925842285156"],
8
+ "polygonpoints":[["-73.9944367","40.7505417"],["-73.9940278","40.7511034"],["-73.9939442","40.7510658"],["-73.9938776","40.7510941"],["-73.9937734","40.7511298"],["-73.9936562","40.7511561"],["-73.993619","40.7511624"],["-73.9935537","40.7510862"],["-73.9935336","40.7510885"],["-73.9934248","40.7510898"],["-73.9933248","40.7510806"],["-73.9932268","40.7510614"],["-73.9931334","40.7510327"],["-73.9930378","40.7509909"],["-73.9929554","40.7509421"],["-73.9928865","40.7508886"],["-73.992821","40.7508216"],["-73.9927742","40.7507572"],["-73.9926591","40.7507581"],["-73.9926036","40.750603"],["-73.992704","40.7505536"],["-73.9927029","40.7505065"],["-73.9925855","40.7505009"],["-73.9925989","40.7503952"],["-73.9926442","40.7504003"],["-73.9926722","40.7503155"],["-73.9927117","40.7502402"],["-73.9927617","40.7501715"],["-73.992824","40.7501067"],["-73.9928991","40.7500484"],["-73.992869","40.7500159"],["-73.9929742","40.749956"],["-73.9930375","40.7500318"],["-73.9931229","40.7499938"],["-73.9931273","40.7499005"],["-73.9933201","40.7498624"],["-73.9933853","40.7499355"],["-73.993402","40.7499336"],["-73.9935038","40.749932"],["-73.9936041","40.7499407"],["-73.9936962","40.7499579"],["-73.9937875","40.7499846"],["-73.9938783","40.7500221"],["-73.9939639","40.7500701"],["-73.9940328","40.7501206"],["-73.9940991","40.7501842"],["-73.9941506","40.7502504"],["-73.9941562","40.7502603"],["-73.9942791","40.7502628"],["-73.9942969","40.7503035"],["-73.9943271","40.7503844"],["-73.9943435","40.7504689"],["-73.9943454","40.7505049"],["-73.9944367","40.7505417"]],
9
+ "lat":"40.7505206016777",
10
+ "lon":"-73.993490694181",
11
+ "display_name":"Madison Square Garden, 46, West 31st Street, Chelsea, New York City, New York, United States of America",
12
+ "class":"leisure",
13
+ "type":"stadium",
14
+ "address":{
15
+ "stadium":"Madison Square Garden",
16
+ "house_number":"46",
17
+ "road":"West 31st Street",
18
+ "suburb":"Chelsea",
19
+ "city":"New York City",
20
+ "county":"New York",
21
+ "state":"New York",
22
+ "postcode":"10119",
23
+ "country":"United States of America",
24
+ "country_code":"us"
25
+ }
26
+ }
27
+ ]
@@ -0,0 +1 @@
1
+ []
data/test/lookup_test.rb CHANGED
@@ -4,7 +4,7 @@ require 'test_helper'
4
4
  class LookupTest < Test::Unit::TestCase
5
5
 
6
6
  def test_search_returns_empty_array_when_no_results
7
- all_lookups.each do |l|
7
+ all_lookups_except_test.each do |l|
8
8
  lookup = Geocoder.send(:get_lookup, l)
9
9
  assert_equal [], lookup.send(:results, "no results"),
10
10
  "Lookup #{l} does not return empty array when no results."
data/test/mongoid_test.rb CHANGED
@@ -17,7 +17,8 @@ class MongoidTest < Test::Unit::TestCase
17
17
  def test_custom_coordinate_field_near_scope
18
18
  location = [40.750354, -73.993371]
19
19
  p = Place.near(location)
20
- assert_equal p.selector[:location]['$nearSphere'], location.reverse
20
+ key = Mongoid::VERSION >= "3" ? "location" : :location
21
+ assert_equal p.selector[key]['$nearSphere'], location.reverse
21
22
  end
22
23
 
23
24
  def test_model_configuration
@@ -7,8 +7,12 @@ require 'geocoder/models/mongoid'
7
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
9
 
10
- Mongoid.configure do |config|
11
- config.logger = Logger.new($stderr, :debug)
10
+ if (::Mongoid::VERSION >= "3")
11
+ Mongoid.logger = Logger.new($stderr, :debug)
12
+ else
13
+ Mongoid.configure do |config|
14
+ config.logger = Logger.new($stderr, :debug)
15
+ end
12
16
  end
13
17
 
14
18
  ##
data/test/result_test.rb CHANGED
@@ -4,7 +4,7 @@ require 'test_helper'
4
4
  class ResultTest < Test::Unit::TestCase
5
5
 
6
6
  def test_result_has_required_attributes
7
- all_lookups.each do |l|
7
+ all_lookups_except_test.each do |l|
8
8
  Geocoder::Configuration.lookup = l
9
9
  result = Geocoder.search([45.423733, -75.676333]).first
10
10
  assert_result_has_required_attributes(result)
data/test/test_helper.rb CHANGED
@@ -163,6 +163,19 @@ module Geocoder
163
163
  end
164
164
  end
165
165
 
166
+ class Mapquest < Base
167
+ private #-----------------------------------------------------------------
168
+ def fetch_raw_data(query, reverse = false)
169
+ raise TimeoutError if query == "timeout"
170
+ raise SocketError if query == "socket_error"
171
+ file = case query
172
+ when "no results"; :no_results
173
+ else :madison_square_garden
174
+ end
175
+ read_fixture "mapquest_#{file}.json"
176
+ end
177
+ end
178
+
166
179
  end
167
180
  end
168
181
 
@@ -268,8 +281,18 @@ class Test::Unit::TestCase
268
281
  Geocoder.valid_lookups
269
282
  end
270
283
 
284
+ def all_lookups_except_test
285
+ Geocoder.valid_lookups - [:test]
286
+ end
287
+
271
288
  def street_lookups
272
289
  all_lookups - [:freegeoip]
273
290
  end
291
+
292
+ def is_nan_coordinates?(coordinates)
293
+ return false unless coordinates.respond_to? :size # Should be an array
294
+ return false unless coordinates.size == 2 # Should have dimension 2
295
+ coordinates[0].nan? && coordinates[1].nan? # Both coordinates should be NaN
296
+ end
274
297
  end
275
298
 
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+ require 'geocoder/lookups/test'
3
+
4
+ class TestModeTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @_original_lookup = Geocoder::Configuration.lookup
8
+ Geocoder::Configuration.lookup = :test
9
+ end
10
+
11
+ def teardown
12
+ Geocoder::Lookup::Test.reset
13
+ Geocoder::Configuration.lookup = @_original_lookup
14
+ end
15
+
16
+ def test_search_with_known_stub
17
+ coordinates = [40.7143528, -74.0059731]
18
+ attributes = {
19
+ 'coordinates' => coordinates,
20
+ 'latitude' => coordinates[0],
21
+ 'longitude' => coordinates[1],
22
+ 'address' => 'New York, NY, USA',
23
+ 'state' => 'New York',
24
+ 'state_code' => 'NY',
25
+ 'country' => 'United States',
26
+ 'country_code' => 'US',
27
+ }
28
+
29
+ Geocoder::Lookup::Test.add_stub("New York, NY", [attributes])
30
+
31
+ results = Geocoder.search("New York, NY")
32
+ assert_equal 1, results.size
33
+
34
+ result = results.first
35
+ assert_equal coordinates, result.coordinates
36
+ assert_equal attributes['latitude'], result.latitude
37
+ assert_equal attributes['longitude'], result.longitude
38
+ assert_equal attributes['address'], result.address
39
+ assert_equal attributes['state'], result.state
40
+ assert_equal attributes['state_code'], result.state_code
41
+ assert_equal attributes['country'], result.country
42
+ assert_equal attributes['country_code'], result.country_code
43
+ end
44
+
45
+ def test_search_with_unknown_stub
46
+ assert_raise ArgumentError do
47
+ Geocoder.search("New York, NY")
48
+ end
49
+ end
50
+
51
+ end
metadata CHANGED
@@ -1,34 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.3
4
5
  prerelease:
5
- version: 1.1.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Alex Reisner
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2012-05-24 00:00:00 Z
12
+ date: 2012-08-26 00:00:00.000000000 Z
14
13
  dependencies: []
15
-
16
- description: Provides object geocoding (by street or IP address), reverse geocoding (coordinates to street address), distance queries for ActiveRecord and Mongoid, result caching, and more. Designed for Rails but works with Sinatra and other Rack frameworks too.
17
- email:
14
+ description: Provides object geocoding (by street or IP address), reverse geocoding
15
+ (coordinates to street address), distance queries for ActiveRecord and Mongoid,
16
+ result caching, and more. Designed for Rails but works with Sinatra and other Rack
17
+ frameworks too.
18
+ email:
18
19
  - alex@alexreisner.com
19
- executables:
20
+ executables:
20
21
  - geocode
21
22
  extensions: []
22
-
23
23
  extra_rdoc_files: []
24
-
25
- files:
24
+ files:
26
25
  - .gitignore
26
+ - .travis.yml
27
27
  - CHANGELOG.rdoc
28
28
  - LICENSE
29
29
  - README.rdoc
30
30
  - Rakefile
31
31
  - bin/geocode
32
+ - gemfiles/Gemfile.mongoid-2.4.x
32
33
  - lib/generators/geocoder/config/config_generator.rb
33
34
  - lib/generators/geocoder/config/templates/initializer.rb
34
35
  - lib/geocoder.rb
@@ -43,7 +44,9 @@ files:
43
44
  - lib/geocoder/lookups/geocoder_ca.rb
44
45
  - lib/geocoder/lookups/google.rb
45
46
  - lib/geocoder/lookups/google_premier.rb
47
+ - lib/geocoder/lookups/mapquest.rb
46
48
  - lib/geocoder/lookups/nominatim.rb
49
+ - lib/geocoder/lookups/test.rb
47
50
  - lib/geocoder/lookups/yahoo.rb
48
51
  - lib/geocoder/lookups/yandex.rb
49
52
  - lib/geocoder/models/active_record.rb
@@ -59,7 +62,9 @@ files:
59
62
  - lib/geocoder/results/geocoder_ca.rb
60
63
  - lib/geocoder/results/google.rb
61
64
  - lib/geocoder/results/google_premier.rb
65
+ - lib/geocoder/results/mapquest.rb
62
66
  - lib/geocoder/results/nominatim.rb
67
+ - lib/geocoder/results/test.rb
63
68
  - lib/geocoder/results/yahoo.rb
64
69
  - lib/geocoder/results/yandex.rb
65
70
  - lib/geocoder/stores/active_record.rb
@@ -86,6 +91,8 @@ files:
86
91
  - test/fixtures/google_no_city_data.json
87
92
  - test/fixtures/google_no_locality.json
88
93
  - test/fixtures/google_no_results.json
94
+ - test/fixtures/mapquest_madison_square_garden.json
95
+ - test/fixtures/mapquest_no_results.json
89
96
  - test/fixtures/nominatim_madison_square_garden.json
90
97
  - test/fixtures/nominatim_no_results.json
91
98
  - test/fixtures/yahoo_garbage.json
@@ -106,32 +113,35 @@ files:
106
113
  - test/result_test.rb
107
114
  - test/services_test.rb
108
115
  - test/test_helper.rb
116
+ - test/test_mode_test.rb
109
117
  homepage: http://www.rubygeocoder.com
110
118
  licenses: []
111
-
112
119
  post_install_message:
113
120
  rdoc_options: []
114
-
115
- require_paths:
121
+ require_paths:
116
122
  - lib
117
- required_ruby_version: !ruby/object:Gem::Requirement
123
+ required_ruby_version: !ruby/object:Gem::Requirement
118
124
  none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: "0"
123
- required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ segments:
130
+ - 0
131
+ hash: 585705263
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
133
  none: false
125
- requirements:
126
- - - ">="
127
- - !ruby/object:Gem::Version
128
- version: "0"
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ segments:
139
+ - 0
140
+ hash: 585705263
129
141
  requirements: []
130
-
131
142
  rubyforge_project:
132
143
  rubygems_version: 1.8.24
133
144
  signing_key:
134
145
  specification_version: 3
135
146
  summary: Complete geocoding solution for Ruby.
136
147
  test_files: []
137
-