mongoid_geospatial 2.5.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -31,16 +31,16 @@ You can also use an external Geometric/Spatial alongside.
31
31
  # Include the module
32
32
  include Mongoid::Geospatial
33
33
 
34
- # Just like mongoid,
34
+ # Just like mongoid,
35
35
  field :name, type: String
36
- # define your field, but choose a geometry type:
37
- field :location, type: Point, :spatial => true
36
+ # define your field, but choose a geometry type:
37
+ field :location, type: Point
38
38
  field :route, type: Linestring
39
39
  field :area, type: Polygon
40
-
41
- # If your are going to query on your points, don't forget to index:
42
- spatial_index :location
43
-
40
+
41
+ # If your are going to query on your points, don't forget to index:
42
+ spatial_index :location
43
+ # You can index points with :spatial => true option too, see below.
44
44
  end
45
45
 
46
46
 
@@ -57,15 +57,14 @@ Currently, MongoDB supports query operations on 2D points only, so that's
57
57
  what this lib does. All geometries apart from points are just arrays
58
58
  in the database. Here's is how you can input a point as:
59
59
 
60
- * an unordered hash with the lat long string keys defined when setting the field (only applies for setting the field)
61
60
  * longitude latitude array in that order - [long,lat] ([x, y])
62
61
  * an unordered hash with latitude key(:lat, :latitude) and a longitude key(:lon, :long, :lng, :longitude)
63
62
  * an ordered hash with longitude as the first item and latitude as the second item
64
63
  This hash does not have include the latitude and longitude keys
65
64
  \*only works in ruby 1.9 and up because hashes below ruby 1.9 because they are not ordered
66
- * anything with the method to_lng_lat that converts it to a [long,lat]
65
+ * anything with the a method #to_xy or #to_lng_lat that converts itself to [long, lat] array
67
66
 
68
- We store data in the DB as a [lng,lat] array then reformat when it is returned to you
67
+ We store data in the DB as a [x, y] array then reformat when it is returned to you
69
68
 
70
69
 
71
70
  hudson = River.create(
@@ -81,15 +80,17 @@ We store data in the DB as a [lng,lat] array then reformat when it is returned t
81
80
  Now to access this spatial information we can do this
82
81
 
83
82
  hudson.mouth # => [-74.026667, 40.703056]
84
-
83
+
85
84
  If you need a hash
86
85
 
87
86
  hudson.mouth.to_hsh # => { x: -74.026667, y: 40.703056 }
88
-
87
+
89
88
  If you are using GeoRuby or RGeo
90
89
 
91
90
  hudson.mouth.to_geo # => NiceGeolib::Point
92
91
 
92
+ Conventions: This lib uses #x and #y everywhere. 1. It's shorter than lat or lng or another variation that also confuses. 2. A point is a 2D mathematical notation, longitude/latitude is when you use that notation to map an sphere. In other words, all longitudes are 'xs' where not all 'xs' are longitudes. In the eyes of a moralist it's not even a valid position point, it does not have #z or #m.
93
+
93
94
  Distance and other geometrical calculations are delegated to the external
94
95
  library you choosed. More info about using RGeo or GeoRuby below.
95
96
  Some built in helpers for mongoid queries:
@@ -106,9 +107,9 @@ Some built in helpers for mongoid queries:
106
107
 
107
108
  And for polygons and lines:
108
109
 
109
- house.area.bbox # Returns polygon bounding_box (envelope)
110
- house.area.center # Returns calculate middle point
111
-
110
+ house.area.bbox # Returns polygon bounding_box (envelope)
111
+ house.area.center # Returns calculate middle point
112
+
112
113
 
113
114
  Query
114
115
  --------
@@ -125,7 +126,7 @@ You can use Geometry instance directly on any query:
125
126
  * near
126
127
  * Bar.near(location: person.house)
127
128
  * Bar.where(:location.near => person.house)
128
-
129
+
129
130
 
130
131
  * near_sphere
131
132
  * Bar.near_sphere(location: person.house)
@@ -134,15 +135,15 @@ You can use Geometry instance directly on any query:
134
135
 
135
136
  * within_box
136
137
  * Bar.within_box(location: hood.area)
137
-
138
+
138
139
 
139
140
  * within_circle
140
141
  * Bar.within_circle(location: hood.area)
141
-
142
+
142
143
 
143
144
  * within_circle_sphere
144
145
  * Bar.within_circle_sphere(location: hood.area)
145
-
146
+
146
147
 
147
148
  * within_polygon
148
149
  * Bar.within_polygon(location: city.area)
@@ -213,7 +214,7 @@ With RGeo
213
214
  With GeoRuby
214
215
 
215
216
  Mongoid::Geospatial.use_georuby
216
-
217
+
217
218
 
218
219
  Defaults (change if you know what you're doing)
219
220
 
@@ -233,25 +234,43 @@ You can create Point, Line, Circle, Box and Polygon on your models:
233
234
  include Mongoid::Document
234
235
  include Mongoid::Geospatial
235
236
 
236
- field :location, type: Point
237
+ field :location, type: Point, :spatial => true, :delegate => true
238
+
239
+ field :route, type: Line
240
+ field :area, type: Polygon
241
+
242
+ field :square, type: Box
243
+ field :around, type: Circle
237
244
 
238
- field :route, type: Line
239
- field :area, type: Polygon
240
-
241
- field :square, type: Box
242
- field :around, type: Circle
243
-
244
245
  # spatial indexing
245
246
  spatial_index :mouth
246
247
 
247
248
  # default mongodb options
248
249
  spatial_index :mouth, {bit: 24, min: -180, max: 180}
249
-
250
- # query by location
251
- spatial_scope :location
250
+
251
+ # query by location
252
+ spatial_scope :location
252
253
  end
253
254
 
254
255
 
256
+ Helpers
257
+ -------
258
+
259
+ You can use `:spatial => true` to add an '2d' index automatically,
260
+ No need for `spatial_index :location`:
261
+
262
+
263
+ field :location, type: Point, :spatial => true
264
+
265
+
266
+ You can delegate some point methods to the instance itself:
267
+
268
+
269
+ field :location, type: Point, :delegate => true
270
+
271
+
272
+ Now instead of `instance.location.x` you may call `instance.x`.
273
+
255
274
 
256
275
  Nearby
257
276
  ------
@@ -259,11 +278,11 @@ Nearby
259
278
  You can add a `spatial_scope` on your models. So you can query:
260
279
 
261
280
  Bar.nearby(my.location)
262
-
281
+
263
282
  instead of
264
283
 
265
284
  Bar.near(location: my.location)
266
-
285
+
267
286
  Good when you're drunk. Just add to your model:
268
287
 
269
288
  spatial_scope :<field>
@@ -0,0 +1,24 @@
1
+ Mongoid::Fields.option :delegate do |model, field, options|
2
+ options = {} unless options.kind_of?(Hash)
3
+ x_meth = options[:x] || :x
4
+ y_meth = options[:y] || :y
5
+
6
+ model.instance_eval do
7
+ define_method x_meth do self[field.name][0]; end
8
+ define_method y_meth do self[field.name][1]; end
9
+
10
+ define_method "#{x_meth}=" do |arg|
11
+ self[field.name][0] = arg
12
+ end
13
+
14
+ define_method "#{y_meth}=" do |arg|
15
+ self[field.name][1] = arg
16
+ end
17
+
18
+ # model.class_eval do
19
+ # define_method "close_to" do |*args|
20
+ # queriable.where(field.name.near_sphere => *args)
21
+ # end
22
+ # end
23
+ end
24
+ end
@@ -1,5 +1,3 @@
1
- #require 'ostruct'
2
-
3
1
  Mongoid::Fields.option :spatial do |model,field,options|
4
2
  options = {} unless options.kind_of?(Hash)
5
3
  # x_meth = options[:x] || :x
@@ -13,9 +11,14 @@ Mongoid::Fields.option :spatial do |model,field,options|
13
11
 
14
12
  model.class_eval do
15
13
  (self.spatial_fields ||= []) << field.name.to_sym
16
- # define_method "distance_from_#{field.name}" do |*args|
17
- # self.distance_from(field.name, *args)
18
- # end
14
+ (self.spatial_fields_indexed ||= []) << field.name.to_sym
15
+
16
+ # Create 2D index
17
+ spatial_index field.name
18
+
19
+ # define_method "near_#{field.name}" do |*args|
20
+ # queryable.where(field.near_sphere => args)
21
+ # end
19
22
  end
20
23
 
21
24
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
- VERSION = "2.5.1"
3
+ VERSION = "2.7.0"
4
4
  end
5
5
  end
@@ -1,17 +1,33 @@
1
- require 'georuby'
1
+ require 'geo_ruby'
2
2
  # require 'mongoid_geospatial/extensions/georuby'
3
3
 
4
4
  module Mongoid
5
5
  module Geospatial
6
6
 
7
7
  class Point
8
+ delegate :distance, :to => :to_geo
9
+
8
10
  def to_geo
9
- GeoRuby::SimpleFeatures::Point.from_x_y(x, y)
11
+ GeoRuby::SimpleFeatures::Point.xy(x, y)
12
+ end
13
+
14
+ def distance other
15
+ to_geo.spherical_distance(other.to_geo)
16
+ end
17
+
18
+ def self.mongoize(obj)
19
+ case obj
20
+ when GeoRuby::SimpleFeatures::Point then [obj.x, obj.y]
21
+ when Point then obj.mongoize
22
+ when Array then obj.to_xy
23
+ when Hash then obj.to_xy
24
+ else obj
25
+ end
10
26
  end
11
27
  end
12
28
 
13
29
 
14
- class Line < Array
30
+ class Line < GeometryField
15
31
  def to_geo
16
32
  GeoRuby::SimpleFeatures::LineString.from_array(self)
17
33
  end
@@ -5,12 +5,15 @@ module Mongoid
5
5
  module Geospatial
6
6
 
7
7
  class Point
8
- delegate :distance, :to => :to_geo
9
8
 
10
9
  def to_geo
11
10
  RGeo::Geographic.spherical_factory.point x, y
12
11
  end
13
12
 
13
+ def distance other
14
+ to_geo.distance other.to_geo
15
+ end
16
+
14
17
  def self.mongoize(obj)
15
18
  case obj
16
19
  when RGeo::Geographic::SphericalPointImpl then [obj.x, obj.y]
@@ -4,7 +4,8 @@ require 'active_support/concern'
4
4
  require 'mongoid_geospatial/geospatial'
5
5
  require 'mongoid_geospatial/extensions/core_ext'
6
6
  require 'mongoid_geospatial/extensions/rgeo_spherical_point_impl'
7
- require 'mongoid_geospatial/field_option'
7
+ require 'mongoid_geospatial/helpers/spatial'
8
+ require 'mongoid_geospatial/helpers/delegate'
8
9
 
9
10
  require 'mongoid_geospatial/fields/geometry_field'
10
11
 
data/spec/models/bar.rb CHANGED
@@ -7,7 +7,6 @@ class Bar
7
7
 
8
8
  has_one :rating, :as => :ratable
9
9
 
10
- spatial_index :location
11
10
  spatial_scope :location
12
11
 
13
12
  end
@@ -0,0 +1,11 @@
1
+ class Bus
2
+ include Mongoid::Document
3
+ include Mongoid::Geospatial
4
+
5
+ field :plates, :type => String
6
+ field :location, :type => Point, :delegate => true
7
+
8
+ spatial_index :location
9
+ spatial_scope :location
10
+
11
+ end
@@ -0,0 +1,13 @@
1
+ class Place
2
+ include Mongoid::Document
3
+ include Mongoid::Geospatial
4
+
5
+ field :name, :type => String
6
+ field :location, :type => Point, :spatial => true
7
+
8
+ has_one :rating, :as => :ratable
9
+
10
+ spatial_index :location
11
+ spatial_scope :location
12
+
13
+ end
@@ -1,21 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Fields do
4
-
5
- context "spatial" do
6
- before do
7
- Bar.create_indexes
8
- end
9
-
10
- it "should set some class methods" do
11
- far = Bar.create!(name: "Far", location: [7,7])
12
- near = Bar.create!(name: "Near", location: [2,2])
13
- Bar.nearby([1,1]).should eq([near, far])
14
- end
15
-
16
- end
17
-
18
- context "geom" do
19
- end
20
-
21
- end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields do
4
+
5
+ context "delegate" do
6
+ before do
7
+ Bus.create_indexes
8
+ end
9
+
10
+ context 'x, y helpers' do
11
+
12
+ let(:bus) { Bus.create!(name: "Far", location: [7,8]) }
13
+
14
+ it "should set instance method x" do
15
+ bus.x.should eq(7)
16
+ end
17
+
18
+ it "should set instance method y" do
19
+ bus.y.should eq(8)
20
+ end
21
+
22
+ it "should set instance method x=" do
23
+ bus.x = 9
24
+ bus.x.should eq(9)
25
+ end
26
+
27
+ it "should set instance method y=" do
28
+ bus.y = 9
29
+ bus.y.should eq(9)
30
+ end
31
+
32
+ end
33
+
34
+ it "should set instance method x and y" do
35
+ bus = Bus.create!(name: "B", location: [7,7])
36
+ bus.x = 9; bus.y = 9
37
+ bus.location.to_a.should eq([9,9])
38
+ end
39
+
40
+ end
41
+
42
+ context "geom" do
43
+ end
44
+
45
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields do
4
+
5
+ context "spatial" do
6
+ before do
7
+ Bar.create_indexes
8
+ end
9
+
10
+ it "should created indexes" do
11
+ Bar.index_options.keys.should include({'location' => '2d'})
12
+ end
13
+
14
+ it "should set spatial fields" do
15
+ Bar.spatial_fields.should eql([:location])
16
+ end
17
+
18
+ it "should set some class methods" do
19
+ far = Bar.create!(name: "Far", location: [7,7])
20
+ near = Bar.create!(name: "Near", location: [2,2])
21
+ Bar.nearby([1,1]).should eq([near, far])
22
+ end
23
+
24
+ # it "should set some class methods" do
25
+ # far = Bar.create!(name: "Far", location: [7,7])
26
+ # near = Bar.create!(name: "Near", location: [2,2])
27
+ # Bar.near_location([1,1]).should eq([near, far])
28
+ # end
29
+
30
+ end
31
+
32
+ context "geom" do
33
+ end
34
+
35
+ end
@@ -0,0 +1,62 @@
1
+ require "spec_helper"
2
+
3
+
4
+ describe Mongoid::Geospatial::Point do
5
+
6
+ before(:all) do
7
+ Mongoid::Geospatial.send(:remove_const, 'Point')
8
+ load "#{File.dirname(__FILE__)}/../../../lib/mongoid_geospatial/fields/point.rb"
9
+ Object.send(:remove_const, 'Place')
10
+ load "#{File.dirname(__FILE__)}/../../models/place.rb"
11
+ end
12
+
13
+ it "should not inferfer with mongoid" do
14
+ Place.create!(name: "Moe's")
15
+ Place.count.should eql(1)
16
+ end
17
+
18
+ it "should not respond to distance before loading external gem" do
19
+ bar = Place.create!(location: [5,5])
20
+ bar.location.should_not respond_to(:distance)
21
+ end
22
+
23
+
24
+ describe "queryable" do
25
+
26
+ before do
27
+ Mongoid::Geospatial.use_georuby
28
+ Place.create_indexes
29
+ end
30
+
31
+ describe "(de)mongoize" do
32
+
33
+ it "should mongoize array" do
34
+ geom = Place.new(location: [10, -9]).location
35
+ geom.class.should eql(Mongoid::Geospatial::Point)
36
+ geom.to_geo.class.should eql(GeoRuby::SimpleFeatures::Point)
37
+ geom.x.should be_within(0.1).of(10)
38
+ geom.to_geo.y.should be_within(0.1).of(-9)
39
+ end
40
+
41
+ it "should mongoize hash" do
42
+ geom = Place.new(location: {x: 10, y: -9}).location
43
+ geom.class.should eql(Mongoid::Geospatial::Point)
44
+ geom.to_geo.class.should eql(GeoRuby::SimpleFeatures::Point)
45
+ end
46
+
47
+ it "should accept a GeoRuby point" do
48
+ point = GeoRuby::SimpleFeatures::Point.from_x_y 1, 2
49
+ bar = Place.create!(location: point)
50
+ bar.location.x.should be_within(0.1).of(1)
51
+ bar.location.y.should be_within(0.1).of(2)
52
+ end
53
+
54
+ it "should calculate 3d distances by default" do
55
+ bar = Place.create! location: [-73.77694444, 40.63861111 ]
56
+ bar2 = Place.create! location: [-118.40, 33.94] #,:unit=>:mi, :spherical => true)
57
+ bar.location.distance(bar2.location).to_i.should be_within(1).of(3973808)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -2,6 +2,13 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Geospatial::Point do
4
4
 
5
+ before(:all) do
6
+ Mongoid::Geospatial.send(:remove_const, 'Point')
7
+ load "#{File.dirname(__FILE__)}/../../../lib/mongoid_geospatial/fields/point.rb"
8
+ Object.send(:remove_const, 'Bar')
9
+ load "#{File.dirname(__FILE__)}/../../models/bar.rb"
10
+ end
11
+
5
12
  it "should not inferfer with mongoid" do
6
13
  Bar.create!(name: "Moe's")
7
14
  Bar.count.should eql(1)
@@ -16,8 +23,8 @@ describe Mongoid::Geospatial::Point do
16
23
  describe "queryable" do
17
24
 
18
25
  before do
19
- Bar.create_indexes
20
26
  Mongoid::Geospatial.use_rgeo
27
+ Bar.create_indexes
21
28
  end
22
29
 
23
30
  describe "(de)mongoize" do
@@ -46,7 +53,7 @@ describe Mongoid::Geospatial::Point do
46
53
  it "should calculate 3d distances by default" do
47
54
  bar = Bar.create! location: [-73.77694444, 40.63861111 ]
48
55
  bar2 = Bar.create! location: [-118.40, 33.94] #,:unit=>:mi, :spherical => true)
49
- bar.location.distance(bar2.location.to_geo).to_i.should be_within(1).of(3978262)
56
+ bar.location.distance(bar2.location).to_i.should be_within(1).of(3978262)
50
57
  end
51
58
 
52
59
  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.5.1
4
+ version: 2.7.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-17 00:00:00.000000000 Z
13
+ date: 2012-09-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: mongoid
@@ -143,7 +143,6 @@ files:
143
143
  - lib/mongoid_geospatial.rb
144
144
  - lib/mongoid_geospatial/extensions/core_ext.rb
145
145
  - lib/mongoid_geospatial/extensions/rgeo_spherical_point_impl.rb
146
- - lib/mongoid_geospatial/field_option.rb
147
146
  - lib/mongoid_geospatial/fields/box.rb
148
147
  - lib/mongoid_geospatial/fields/circle.rb
149
148
  - lib/mongoid_geospatial/fields/geometry_field.rb
@@ -151,6 +150,8 @@ files:
151
150
  - lib/mongoid_geospatial/fields/point.rb
152
151
  - lib/mongoid_geospatial/fields/polygon.rb
153
152
  - lib/mongoid_geospatial/geospatial.rb
153
+ - lib/mongoid_geospatial/helpers/delegate.rb
154
+ - lib/mongoid_geospatial/helpers/spatial.rb
154
155
  - lib/mongoid_geospatial/version.rb
155
156
  - lib/mongoid_geospatial/wrappers/georuby.rb
156
157
  - lib/mongoid_geospatial/wrappers/rgeo.rb
@@ -158,10 +159,12 @@ files:
158
159
  - spec/models/address.rb
159
160
  - spec/models/alarm.rb
160
161
  - spec/models/bar.rb
162
+ - spec/models/bus.rb
161
163
  - spec/models/event.rb
162
164
  - spec/models/farm.rb
163
165
  - spec/models/person.rb
164
166
  - spec/models/phone.rb
167
+ - spec/models/place.rb
165
168
  - spec/models/river.rb
166
169
  - spec/mongoid_geospatial/extensions/core_ext_spec.rb
167
170
  - spec/mongoid_geospatial/field_option_spec.rb
@@ -171,6 +174,9 @@ files:
171
174
  - spec/mongoid_geospatial/fields/point_spec.rb
172
175
  - spec/mongoid_geospatial/fields/polygon_spec.rb
173
176
  - spec/mongoid_geospatial/geospatial_spec.rb
177
+ - spec/mongoid_geospatial/helpers/delegate_spec.rb
178
+ - spec/mongoid_geospatial/helpers/spatial_spec.rb
179
+ - spec/mongoid_geospatial/wrappers/georuby_spec.rb
174
180
  - spec/mongoid_geospatial/wrappers/rgeo_spec.rb
175
181
  - spec/spec_helper.rb
176
182
  - spec/support/authentication.rb
@@ -205,10 +211,12 @@ test_files:
205
211
  - spec/models/address.rb
206
212
  - spec/models/alarm.rb
207
213
  - spec/models/bar.rb
214
+ - spec/models/bus.rb
208
215
  - spec/models/event.rb
209
216
  - spec/models/farm.rb
210
217
  - spec/models/person.rb
211
218
  - spec/models/phone.rb
219
+ - spec/models/place.rb
212
220
  - spec/models/river.rb
213
221
  - spec/mongoid_geospatial/extensions/core_ext_spec.rb
214
222
  - spec/mongoid_geospatial/field_option_spec.rb
@@ -218,6 +226,9 @@ test_files:
218
226
  - spec/mongoid_geospatial/fields/point_spec.rb
219
227
  - spec/mongoid_geospatial/fields/polygon_spec.rb
220
228
  - spec/mongoid_geospatial/geospatial_spec.rb
229
+ - spec/mongoid_geospatial/helpers/delegate_spec.rb
230
+ - spec/mongoid_geospatial/helpers/spatial_spec.rb
231
+ - spec/mongoid_geospatial/wrappers/georuby_spec.rb
221
232
  - spec/mongoid_geospatial/wrappers/rgeo_spec.rb
222
233
  - spec/spec_helper.rb
223
234
  - spec/support/authentication.rb