mongoid_geospatial 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +2 -1
  2. data/README.md +84 -60
  3. data/lib/mongoid_geospatial.rb +3 -7
  4. data/lib/mongoid_geospatial/{geospatial → extensions}/core_ext.rb +0 -0
  5. data/lib/mongoid_geospatial/field_option.rb +3 -4
  6. data/lib/mongoid_geospatial/fields/geometry_field.rb +34 -0
  7. data/lib/mongoid_geospatial/fields/line_string.rb +5 -7
  8. data/lib/mongoid_geospatial/fields/point.rb +18 -33
  9. data/lib/mongoid_geospatial/fields/polygon.rb +6 -14
  10. data/lib/mongoid_geospatial/geospatial.rb +20 -25
  11. data/lib/mongoid_geospatial/version.rb +1 -1
  12. data/lib/mongoid_geospatial/wrappers/georuby.rb +28 -0
  13. data/lib/mongoid_geospatial/wrappers/rgeo.rb +32 -0
  14. data/spec/models/farm.rb +5 -2
  15. data/spec/models/person.rb +4 -14
  16. data/spec/models/phone.rb +1 -3
  17. data/spec/mongoid_geospatial/extensions/core_ext_spec.rb +20 -0
  18. data/spec/mongoid_geospatial/field_option_spec.rb +11 -0
  19. data/spec/mongoid_geospatial/fields/line_string_spec.rb +40 -0
  20. data/spec/mongoid_geospatial/fields/point_spec.rb +136 -10
  21. data/spec/mongoid_geospatial/fields/polygon_spec.rb +75 -0
  22. data/spec/mongoid_geospatial/geospatial_spec.rb +88 -3
  23. data/spec/mongoid_geospatial/wrappers/rgeo_spec.rb +43 -0
  24. data/spec/spec_helper.rb +5 -21
  25. metadata +14 -26
  26. data/lib/mongoid_geospatial/contextual/mongo.rb +0 -118
  27. data/lib/mongoid_geospatial/criteria.rb +0 -10
  28. data/lib/mongoid_geospatial/criterion/complex.rb +0 -26
  29. data/lib/mongoid_geospatial/criterion/inclusion.rb +0 -14
  30. data/lib/mongoid_geospatial/criterion/near_spatial.rb +0 -52
  31. data/lib/mongoid_geospatial/criterion/within_spatial.rb +0 -62
  32. data/lib/mongoid_geospatial/extensions/symbol.rb +0 -46
  33. data/lib/mongoid_geospatial/finders.rb +0 -5
  34. data/lib/mongoid_geospatial/geospatial/geo_near_results.rb +0 -140
  35. data/spec/mongoid_geospatial/contextual/mongo_spec.rb +0 -135
  36. data/spec/mongoid_geospatial/criterion/complex_spec.rb +0 -15
  37. data/spec/mongoid_geospatial/criterion/inclusion_spec.rb +0 -375
  38. data/spec/mongoid_geospatial/criterion/near_spatial_spec.rb +0 -39
  39. data/spec/mongoid_geospatial/criterion/within_spatial_spec.rb +0 -54
  40. data/spec/mongoid_geospatial/geospatial/geo_near_results_spec.rb +0 -78
  41. data/spec/mongoid_geospatial/mongoid_geospatial_spec.rb +0 -83
@@ -16,12 +16,97 @@ describe Mongoid::Geospatial do
16
16
 
17
17
  end
18
18
 
19
+ #
20
+ # TODO: Model helpers
21
+ # describe "#geo_near" do
19
22
 
20
- context "Included" do
23
+ # before do
24
+ # Bar.create_indexes
25
+ # end
21
26
 
22
- # HO
23
- end
27
+ # let!(:jfk) do
28
+ # Bar.create(:name => 'jfk', :location => [-73.77694444, 40.63861111 ])
29
+ # end
30
+
31
+ # let!(:lax) do
32
+ # Bar.create(:name => 'lax', :location => [-118.40, 33.94])
33
+ # end
34
+
35
+ # it "should work with specifying specific center and different location attribute on collction" do
36
+ # pending
37
+ # Bar.geo_near(lax.location, :spherical => true).should == [lax, jfk]
38
+ # end
39
+
40
+ # context ':maxDistance' do
41
+ # it "should get 1 item" do
42
+ # Bar.geo_near(lax.location, :spherical => true, :max_distance => 2465/Mongoid::Geospatial.earth_radius[:mi]).size.should == 1
43
+ # end
44
+
45
+ # end
46
+
47
+ # context ':distance_multiplier' do
48
+ # it "should multiply returned distance with multiplier" do
49
+ # Bar.geo_near(lax.location, :spherical => true, :distance_multiplier=> Mongoid::Geospatial.earth_radius[:mi]).second.geo[:distance].to_i.should be_within(1).of(2469)
50
+ # end
51
+ # end
52
+
53
+ # context ':unit' do
54
+ # it "should multiply returned distance with multiplier" do
55
+ # Bar.geo_near(lax.location, :spherical => true, :unit => :mi).second.geo[:distance].to_i.should be_within(1).of(2469)
56
+ # end
57
+
58
+ # it "should convert max_distance to radians with unit" do
59
+ # Bar.geo_near(lax.location, :spherical => true, :max_distance => 2465, :unit => :mi).size.should == 1
60
+ # end
61
+
62
+ # end
63
+
64
+ # context ':query' do
65
+ # it "should filter using extra query option" do
66
+ # # two record in the collection, only one's name is Munich
67
+ # Bar.geo_near(jfk.location, :query => {:name => jfk.name}).should == [jfk]
68
+ # end
69
+ # end
70
+
71
+ # end
72
+
73
+ # context 'criteria chaining' do
74
+ # it "should filter by where" do
75
+ # Bar.where(:name => jfk.name).geo_near(jfk.location).should == [jfk]
76
+ # Bar.any_of({:name => jfk.name},{:name => lax.name}).geo_near(jfk.location).should == [jfk,lax]
77
+ # end
78
+
79
+ # it 'should skip 1' do
80
+ # Bar.skip(1).geo_near(jfk.location).size.should == 1
81
+ # end
82
+
83
+ # it 'should limit 1' do
84
+ # Bar.limit(1).geo_near(jfk.location).size.should == 1
85
+ # end
86
+ # end
87
+ # end
88
+
89
+ # context ':paginate' do
90
+ # before do
91
+ # Bar.create_indexes
92
+ # 50.times do
93
+ # Bar.create({:location => [rand(360)-180,rand(360)-180]})
94
+ # end
95
+ # end
96
+
97
+ # [nil,1,2].each do |page|
98
+ # it "page=#{page} should have 25" do
99
+ # Bar.geo_near([1,1], :page => page).size.should == 25
100
+ # end
101
+ # end
24
102
 
103
+ # it "page=3 should have 0" do
104
+ # Bar.geo_near([1,1], :page => 20).size.should == 0
105
+ # end
25
106
 
107
+ # it "per_page=5" do
108
+ # Bar.geo_near([1,1], :page => 1, :per_page => 5).size.should == 5
109
+ # end
110
+ # end
26
111
 
27
112
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Geospatial::Point do
4
+
5
+ it "should not inferfer with mongoid" do
6
+ Bar.create!(name: "Moe's")
7
+ Bar.count.should eql(1)
8
+ end
9
+
10
+ describe "queryable" do
11
+
12
+ before do
13
+ Bar.create_indexes
14
+ Mongoid::Geospatial.use_rgeo
15
+ end
16
+
17
+ describe "(de)mongoize" do
18
+
19
+ it "should mongoize array" do
20
+ geom = Bar.new(location: [10, -9]).location
21
+ geom.class.should eql(Mongoid::Geospatial::Point)
22
+ geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
23
+ geom.x.should be_within(0.1).of(10)
24
+ geom.to_geo.y.should be_within(0.1).of(-9)
25
+ end
26
+
27
+ it "should mongoize hash" do
28
+ geom = Bar.new(location: {x: 10, y: -9}).location
29
+ geom.class.should eql(Mongoid::Geospatial::Point)
30
+ geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
31
+ end
32
+
33
+ it "should accept an RGeo object" do
34
+ pending
35
+ point = RGeo::Geographic.spherical_factory.point 1, 2
36
+ bar = Bar.create!(location: point)
37
+ bar.location.x.should be_within(0.1).of(1)
38
+ bar.location.y.should be_within(0.1).of(2)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,7 +8,7 @@ $LOAD_PATH.unshift(MODELS)
8
8
  $LOAD_PATH.unshift(SUPPORT)
9
9
 
10
10
  require "mongoid"
11
- require "mocha"
11
+ # require "mocha"
12
12
  require "rspec"
13
13
  require "mongoid_geospatial"
14
14
 
@@ -27,12 +27,10 @@ if RUBY_VERSION >= '1.9.2'
27
27
  YAML::ENGINE.yamler = 'syck'
28
28
  end
29
29
 
30
- puts "version: #{Mongoid::VERSION}"
31
-
32
- require 'mongoid_setup'
30
+ puts "Running with Mongoid v#{Mongoid::VERSION}"
33
31
 
34
32
  Mongoid.configure do |config|
35
- Mongoid::VersionSetup.configure config
33
+ config.connect_to('mongoid_geo_test')
36
34
  end
37
35
 
38
36
  # Autoload every model for the test suite that sits in spec/app/models.
@@ -44,27 +42,13 @@ end
44
42
  Dir[ File.join(SUPPORT, "*.rb") ].each { |file| require File.basename(file) }
45
43
 
46
44
  def bson_object_id_class
47
- Mongoid::VERSION > '3' ? Moped::BSON:: ObjectId : BSON::ObjectId
45
+ Moped::BSON::ObjectId
48
46
  end
49
47
 
50
48
  RSpec.configure do |config|
51
- config.mock_with(:mocha)
49
+ # config.mock_with(:mocha)
52
50
 
53
51
  config.before(:each) do
54
52
  Mongoid.purge!
55
- # Mongoid.database.collections.each do |collection|
56
- # unless collection.name =~ /^system\./
57
- # collection.remove
58
- # end
59
- # end
60
53
  end
61
-
62
- # We filter out the specs that require authentication if the database has not
63
- # had the mongoid user set up properly.
64
- # user_configured = Support::Authentication.configured?
65
- # warn(Support::Authentication.message) unless user_configured
66
-
67
- # config.filter_run_excluding(:config => lambda { |value|
68
- # return true if value == :user && !user_configured
69
- # })
70
54
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_geospatial
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-11 00:00:00.000000000 Z
13
+ date: 2012-09-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rgeo
@@ -157,23 +157,17 @@ files:
157
157
  - README.md
158
158
  - Rakefile
159
159
  - lib/mongoid_geospatial.rb
160
- - lib/mongoid_geospatial/contextual/mongo.rb
161
- - lib/mongoid_geospatial/criteria.rb
162
- - lib/mongoid_geospatial/criterion/complex.rb
163
- - lib/mongoid_geospatial/criterion/inclusion.rb
164
- - lib/mongoid_geospatial/criterion/near_spatial.rb
165
- - lib/mongoid_geospatial/criterion/within_spatial.rb
160
+ - lib/mongoid_geospatial/extensions/core_ext.rb
166
161
  - lib/mongoid_geospatial/extensions/rgeo_spherical_point_impl.rb
167
- - lib/mongoid_geospatial/extensions/symbol.rb
168
162
  - lib/mongoid_geospatial/field_option.rb
163
+ - lib/mongoid_geospatial/fields/geometry_field.rb
169
164
  - lib/mongoid_geospatial/fields/line_string.rb
170
165
  - lib/mongoid_geospatial/fields/point.rb
171
166
  - lib/mongoid_geospatial/fields/polygon.rb
172
- - lib/mongoid_geospatial/finders.rb
173
167
  - lib/mongoid_geospatial/geospatial.rb
174
- - lib/mongoid_geospatial/geospatial/core_ext.rb
175
- - lib/mongoid_geospatial/geospatial/geo_near_results.rb
176
168
  - lib/mongoid_geospatial/version.rb
169
+ - lib/mongoid_geospatial/wrappers/georuby.rb
170
+ - lib/mongoid_geospatial/wrappers/rgeo.rb
177
171
  - mongoid_geospatial.gemspec
178
172
  - spec/models/address.rb
179
173
  - spec/models/bar.rb
@@ -182,16 +176,13 @@ files:
182
176
  - spec/models/person.rb
183
177
  - spec/models/phone.rb
184
178
  - spec/models/river.rb
185
- - spec/mongoid_geospatial/contextual/mongo_spec.rb
186
- - spec/mongoid_geospatial/criterion/complex_spec.rb
187
- - spec/mongoid_geospatial/criterion/inclusion_spec.rb
188
- - spec/mongoid_geospatial/criterion/near_spatial_spec.rb
189
- - spec/mongoid_geospatial/criterion/within_spatial_spec.rb
179
+ - spec/mongoid_geospatial/extensions/core_ext_spec.rb
180
+ - spec/mongoid_geospatial/field_option_spec.rb
181
+ - spec/mongoid_geospatial/fields/line_string_spec.rb
190
182
  - spec/mongoid_geospatial/fields/point_spec.rb
191
183
  - spec/mongoid_geospatial/fields/polygon_spec.rb
192
- - spec/mongoid_geospatial/geospatial/geo_near_results_spec.rb
193
184
  - spec/mongoid_geospatial/geospatial_spec.rb
194
- - spec/mongoid_geospatial/mongoid_geospatial_spec.rb
185
+ - spec/mongoid_geospatial/wrappers/rgeo_spec.rb
195
186
  - spec/spec_helper.rb
196
187
  - spec/support/authentication.rb
197
188
  - spec/support/mongod.conf
@@ -229,16 +220,13 @@ test_files:
229
220
  - spec/models/person.rb
230
221
  - spec/models/phone.rb
231
222
  - spec/models/river.rb
232
- - spec/mongoid_geospatial/contextual/mongo_spec.rb
233
- - spec/mongoid_geospatial/criterion/complex_spec.rb
234
- - spec/mongoid_geospatial/criterion/inclusion_spec.rb
235
- - spec/mongoid_geospatial/criterion/near_spatial_spec.rb
236
- - spec/mongoid_geospatial/criterion/within_spatial_spec.rb
223
+ - spec/mongoid_geospatial/extensions/core_ext_spec.rb
224
+ - spec/mongoid_geospatial/field_option_spec.rb
225
+ - spec/mongoid_geospatial/fields/line_string_spec.rb
237
226
  - spec/mongoid_geospatial/fields/point_spec.rb
238
227
  - spec/mongoid_geospatial/fields/polygon_spec.rb
239
- - spec/mongoid_geospatial/geospatial/geo_near_results_spec.rb
240
228
  - spec/mongoid_geospatial/geospatial_spec.rb
241
- - spec/mongoid_geospatial/mongoid_geospatial_spec.rb
229
+ - spec/mongoid_geospatial/wrappers/rgeo_spec.rb
242
230
  - spec/spec_helper.rb
243
231
  - spec/support/authentication.rb
244
232
  - spec/support/mongod.conf
@@ -1,118 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Contextual #:nodoc:
4
- class Mongo #:nodoc:
5
-
6
- # Fetches rows from the data base sorted by distance.
7
- # In MongoDB versions 1.7 and above it returns a distance.
8
- # Uses all criteria chains except without, only, asc, desc, order_by
9
- #
10
- # @example Minimal Query
11
- #
12
- # Address.geo_near([70,40])
13
- #
14
- # @example Chained Query
15
- #
16
- # Address.where(:state => 'ny').geo_near([70,40])
17
- #
18
- # @example Calc Distances Query
19
- #
20
- # Address.geo_near([70,40], :max_distance => 5, :unit => 5)
21
- #
22
- # @param [ Array, Hash, #to_xy ] center The center of where to calculate distance from
23
- # @param [ Hash ] opts the options to query with
24
- # @options opts [Integer] :num The number of rows to fetch
25
- # @options opts [Hash] :query The query to filter the rows by, accepts
26
- # @options opts [Numeric] :distance_multiplier this is multiplied against the calculated distance
27
- # @options opts [Numeric] :max_distance The max distance of a row that should be returned in :unit(s)
28
- # @options opts [Numeric, :km, :k, :mi, :ft] :unit automatically sets :distance_multiplier and converts :max_distance
29
- # @options opts [true,false] :spherical Will determine the distance either by spherical calculation or flat calculation
30
- # @options opts [TrueClass,Array<Symbol>] :calculate Which extra fields to calculate distance for in ruby, if set to TrueClass it will calculate all spatial fields
31
- #
32
- # @return [ Array ] Sorted Rows
33
- def geo_near(center, opts = {})
34
- opts = self.criteria.options.merge(opts)
35
- # convert point
36
- center = center.to_xy if center.respond_to?(:to_xy)
37
- center = [center.x, center.y] if center.respond_to?(:x)
38
-
39
- # set default opts
40
- opts[:skip] ||= 0
41
-
42
- if unit = Mongoid::Geospatial.earth_radius[opts[:unit]]
43
- opts[:unit] = (opts[:spherical]) ? unit : unit * Mongoid::Geospatial::RAD_PER_DEG
44
- end
45
-
46
- if unit = Mongoid::Geospatial.earth_radius[opts[:distance_multiplier]]
47
- opts[:distance_multiplier] = (opts[:spherical]) ? unit : unit * Mongoid::Geospatial::RAD_PER_DEG
48
- end
49
-
50
- opts[:distance_multiplier] = opts[:unit] if opts[:unit].kind_of?(Numeric)
51
-
52
- # setup paging.
53
- if opts.has_key?(:page)
54
- opts[:page] ||= 1
55
- opts[:paginator] ||= Mongoid::Geospatial.paginator()
56
-
57
- if opts[:per_page].blank?
58
- opts[:per_page] = case opts[:paginator]
59
- when :will_paginate
60
- @document.per_page
61
- when :kaminari
62
- Kaminari.config.default_per_page
63
- else
64
- Mongoid::Geospatial.default_per_page
65
- end
66
- opts[:per_page] = opts[:per_page].to_i
67
- end
68
-
69
- end
70
- opts[:query] = create_geo_near_query(center,opts)
71
- results = klass.mongo_session.command(opts[:query])
72
-
73
- Mongoid::Geospatial::GeoNearResults.new(klass,results,opts)
74
- end
75
-
76
- private
77
-
78
- def create_geo_near_query(center,opts)
79
- # minimum query
80
- query = {}
81
- query[:geoNear] = klass.collection_name
82
- query[:near] = center
83
-
84
- # create limit and use skip
85
- if opts[:num]
86
- query['num'] = opts[:skip].to_i + opts[:num].to_i
87
- elsif opts[:limit]
88
- query['num'] = opts[:skip].to_i + opts[:limit].to_i
89
- elsif opts[:page]
90
- query['num'] = opts[:skip].to_i + (opts[:page].to_i * opts[:per_page].to_i)
91
- end
92
-
93
- # allow the use of complex werieis
94
- if opts[:query]
95
- query['query'] = self.criteria.where(opts[:query]).selector
96
- elsif self.criteria.selector != {}
97
- query['query'] = self.criteria.selector
98
- end
99
-
100
- if opts[:max_distance]
101
- query['maxDistance'] = opts[:max_distance].to_f
102
- query['maxDistance'] = query['maxDistance']/opts[:unit].to_f if opts[:unit]
103
- end
104
-
105
- if opts[:unique_docs]
106
- query['uniqueDocs'] = true
107
- end
108
-
109
- query['spherical'] = true if opts[:spherical]
110
-
111
- # mongodb < 1.7 returns degrees but with earth flat. in Mongodb 1.7 you can set sphere and let mongodb calculate the distance in Miles or KM
112
- # for mongodb < 1.7 we need to run Haversine first before calculating degrees to Km or Miles. See below.
113
- query['distanceMultiplier'] = opts[:distance_multiplier].to_f if opts[:distance_multiplier]
114
- query
115
- end
116
- end
117
- end
118
- end
@@ -1,10 +0,0 @@
1
- require 'mongoid_geospatial/criterion/complex'
2
- require 'mongoid_geospatial/criterion/near_spatial'
3
- require 'mongoid_geospatial/criterion/within_spatial'
4
-
5
-
6
- module Mongoid #:nodoc:
7
- class Criteria
8
- delegate :geo_near, :to => :context
9
- end
10
- end
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
- # Complex criterion are used when performing operations on symbols to get
5
- # get a shorthand syntax for where clauses.
6
- #
7
- # Example:
8
- #
9
- # <tt>{ :field => { "$lt" => "value" } }</tt>
10
- # becomes:
11
- # <tt> { :field.lt => "value }</tt>
12
- class Complex
13
-
14
- attr_accessor :key, :operator
15
-
16
- def initialize(opts = {})
17
- @key, @operator = opts[:key], opts[:operator]
18
- end
19
-
20
-
21
- def to_mongo_query v
22
- {"$#{operator}" => v}
23
- end
24
- end
25
- end
26
- end
@@ -1,14 +0,0 @@
1
- # encoding: utf-8
2
- # module Mongoid #:nodoc:
3
- # module Criterion #:nodoc:
4
- # module Inclusion
5
- # def near(attributes = {})
6
- # update_selector(attributes, "$near")
7
- # end
8
-
9
- # def near_sphere(attributes = {})
10
- # update_selector(attributes, "$near")
11
- # end
12
- # end
13
- # end
14
- # end