mongoid_geospatial 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
- VERSION = "2.0.0"
3
+ VERSION = "2.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,28 @@
1
+ require 'georuby'
2
+ # require 'mongoid_geospatial/extensions/georuby'
3
+
4
+ module Mongoid
5
+ module Geospatial
6
+
7
+ class Point
8
+ def to_geo
9
+ GeoRuby::SimpleFeatures::Point.from_x_y(x, y)
10
+ end
11
+ end
12
+
13
+
14
+ class LineString < Array
15
+ def to_geo
16
+ GeoRuby::SimpleFeatures::LineString.from_array(self)
17
+ end
18
+
19
+ end
20
+
21
+ class Polygon < GeometryField
22
+ def to_geo
23
+ GeoRuby::SimpleFeatures::Polygon.from_array(self)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require 'rgeo'
2
+ require 'mongoid_geospatial/extensions/rgeo_spherical_point_impl'
3
+
4
+ module Mongoid
5
+ module Geospatial
6
+
7
+ class Point
8
+ def to_geo
9
+ RGeo::Geographic.spherical_factory.point x, y
10
+ end
11
+ end
12
+
13
+
14
+ class LineString < GeometryField
15
+ def to_geo
16
+ RGeo::Geographic.spherical_factory.line_string self
17
+ end
18
+
19
+ end
20
+
21
+ class Polygon < GeometryField
22
+ def to_geo
23
+ points = self.map do |pair|
24
+ RGeo::Geographic.spherical_factory.point *pair
25
+ end
26
+ ring = RGeo::Geographic.spherical_factory.linear_ring points
27
+ RGeo::Geographic.spherical_factory.polygon ring
28
+ end
29
+
30
+ end
31
+ end
32
+ end
data/spec/models/farm.rb CHANGED
@@ -2,8 +2,11 @@ class Farm
2
2
  include Mongoid::Document
3
3
  include Mongoid::Geospatial
4
4
 
5
- field :name, type: String
6
- field :area, type: Polygon, spatial: true
5
+ field :name, type: String
6
+ field :geom, type: Point, spatial: true
7
+ field :area, type: Polygon, spatial: true
8
+ field :m2, type: Fixnum
7
9
 
10
+ spatial_index :geom
8
11
  spatial_index :area
9
12
  end
@@ -3,6 +3,7 @@ class Person
3
3
  include Mongoid::MultiParameterAttributes
4
4
  include Mongoid::Timestamps
5
5
  include Mongoid::Versioning
6
+ include Mongoid::Geospatial
6
7
 
7
8
  attr_accessor :mode
8
9
 
@@ -27,6 +28,9 @@ class Person
27
28
  field :reading, :type => Object
28
29
  field :bson_id, :type => bson_object_id_class
29
30
 
31
+ # Geo
32
+ field :location, :type => Point
33
+
30
34
  index age: 1
31
35
  index addresses: 1
32
36
  index dob: 1
@@ -49,21 +53,7 @@ class Person
49
53
  end
50
54
  end
51
55
 
52
- # embeds_many :services
53
-
54
-
55
- # has_many \
56
- # :posts,
57
- # :dependent => :delete,
58
- # :order => :rating.desc do
59
- # def extension
60
- # "Testing"
61
- # end
62
- # end
63
-
64
56
  accepts_nested_attributes_for :addresses
65
- accepts_nested_attributes_for :name, :update_only => true
66
-
67
57
 
68
58
  scope :minor, where(:age.lt => 18)
69
59
  scope :without_ssn, without(:ssn)
data/spec/models/phone.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  class Phone
2
2
  include Mongoid::Document
3
3
  field :number
4
- if Mongoid::VERSION < '3'
5
- key :number
6
- end
4
+
7
5
  embeds_one :country_code
8
6
  embedded_in :person
9
7
  end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe "Core Extensions" do
4
+
5
+ describe Array do
6
+
7
+ it "should have a #to_xy method" do
8
+ [1,2,3].to_xy.should eql([1.0, 2.0])
9
+ end
10
+
11
+ end
12
+
13
+ describe Hash do
14
+
15
+ it "should have a #to_xy method" do
16
+ { x: 1.1, y: 2.1 }.to_xy.should eql([1.1, 2.1])
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields do
4
+
5
+ context "spatial" do
6
+ end
7
+
8
+ context "geom" do
9
+ end
10
+
11
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Geospatial::LineString do
4
+
5
+ describe "(de)mongoize" do
6
+
7
+ it "should support a field mapped as linestring" do
8
+ river = River.new(source: [[5,5],[6,5],[6,6],[5,6]])
9
+ river.source.should be_a Mongoid::Geospatial::LineString
10
+ river.source.should eq([[5,5],[6,5],[6,6],[5,6]])
11
+ end
12
+
13
+ it "should support a field mapped as linestring" do
14
+ River.create!(source: [[5,5],[6,5],[6,6],[5,6]])
15
+ River.first.source.should eq([[5,5],[6,5],[6,6],[5,6]])
16
+ end
17
+
18
+ it "should have a bounding box" do
19
+ geom = Mongoid::Geospatial::LineString.new [[1,5],[6,5],[6,6],[5,6]]
20
+ geom.bbox.should eq([[1,5], [6,6]])
21
+ end
22
+
23
+ it "should have a center point" do
24
+ geom = Mongoid::Geospatial::LineString.new [[1,1],[1,1],[9,9],[9,9]]
25
+ geom.center.should eq([5.5,5.5])
26
+ end
27
+
28
+ it "should have a radius helper" do
29
+ geom = Mongoid::Geospatial::LineString.new [[1,1],[1,1],[9,9],[9,9]]
30
+ geom.radius(10).should eq([[5.5,5.5], 10])
31
+ end
32
+
33
+ it "should have a radius sphere" do
34
+ geom = Mongoid::Geospatial::LineString.new [[1,1],[1,1],[9,9],[9,9]]
35
+ geom.radius_sphere(10)[1].should be_within(0.001).of(0.001569)
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -2,30 +2,156 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Geospatial::Point do
4
4
 
5
- describe "in use" do
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
+ end
15
+
16
+ describe ":near :near_sphere" do
17
+
18
+ let!(:berlin) do
19
+ Bar.create(:name => :berlin, :location => [ 52.30, 13.25 ])
20
+ end
21
+
22
+ let!(:prague) do
23
+ Bar.create(:name => :prague, :location => [ 50.5, 14.26 ])
24
+ end
25
+
26
+ let!(:paris) do
27
+ Bar.create(:name => :paris, :location => [ 48.48, 2.20 ])
28
+ end
29
+
30
+ let!(:jim) do
31
+ Person.new(:location => [ 41.23, 2.9 ])
32
+ end
33
+
34
+ it "returns the documents sorted closest to furthest" do
35
+ Bar.where(:location.near => jim.location).should == [ paris, prague, berlin ]
36
+ end
37
+
38
+ it "returns the documents sorted closest to furthest sphere" do
39
+ person = Person.new(:location => [ 41.23, 2.9 ])
40
+ Bar.where(:location.near_sphere => jim.location).should == [ paris, prague, berlin ]
41
+ end
42
+
43
+ it "returns the documents sorted closest to furthest with max" do
44
+ Bar.near(location: jim.location).max_distance(location: 10).to_a.should == [ paris ] #, prague, berlin ]
45
+ end
46
+
47
+ end
48
+
49
+ describe ":within_circle :within_spherical_circle" do
50
+ let!(:mile1) do
51
+ Bar.create(:name => 'mile1', :location => [-73.997345, 40.759382])
52
+ end
53
+
54
+ let!(:mile3) do
55
+ Bar.create(:name => 'mile3', :location => [-73.927088, 40.752151])
56
+ end
57
+
58
+ let!(:mile7) do
59
+ Bar.create(:name => 'mile7', :location => [-74.0954913, 40.7161472])
60
+ end
61
+
62
+ let!(:mile9) do
63
+ Bar.create(:name => 'mile9', :location => [-74.0604951, 40.9178011])
64
+ end
65
+
66
+ let!(:elvis) do
67
+ Person.new(:location => [-73.98, 40.75])
68
+ end
69
+
70
+ it "returns the documents within a center_circle" do
71
+ Bar.where(:location.within_circle => [elvis.location, 250.0/Mongoid::Geospatial::EARTH_RADIUS_KM]).to_a.should == [ mile1 ]
72
+ end
73
+
74
+ it "returns the documents within a center_circle" do
75
+ Bar.where(:location.within_circle => [elvis.location, 500.0/Mongoid::Geospatial::EARTH_RADIUS_KM]).to_a.should include(mile3)
76
+ end
77
+
78
+ it "returns the documents within a center_sphere" do
79
+ Bar.where(:location.within_spherical_circle => [elvis.location, 0.0005]).to_a.should == [ mile1 ]
80
+ end
81
+
82
+ it "returns the documents within a center_sphere" do
83
+ Bar.where(:location.within_spherical_circle => [elvis.location, 0.5]).to_a.should include(mile9)
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ describe "(de)mongoize" do
6
90
 
7
91
  it "should mongoize array" do
8
92
  bar = Bar.new(location: [10, -9])
9
- bar.location.class.should eql(RGeo::Geographic::SphericalPointImpl)
93
+ bar.location.class.should eql(Mongoid::Geospatial::Point)
10
94
  bar.location.x.should be_within(0.1).of(10)
11
95
  bar.location.y.should be_within(0.1).of(-9)
12
96
  end
13
97
 
14
98
  it "should mongoize hash" do
15
- bar = Bar.new(location: {x: 10, y: -9})
16
- bar.location.class.should eql(RGeo::Geographic::SphericalPointImpl)
17
- bar.location.x.should be_within(0.1).of(10)
18
- bar.location.y.should be_within(0.1).of(-9)
99
+ geom = Bar.new(location: {x: 10, y: -9}).location
100
+ geom.class.should eql(Mongoid::Geospatial::Point)
101
+ geom.x.should be_within(0.1).of(10)
102
+ geom.y.should be_within(0.1).of(-9)
19
103
  end
20
104
 
21
- describe "instantiated" do
22
105
 
23
- let(:bar) { Bar.create!(name: 'Vitinho', location: [10,10]) }
106
+ describe "methods" do
107
+
108
+ it "should have a .to_a" do
109
+ bar = Bar.create!(location: [3,2])
110
+ bar.location.to_a[0..1].should == [3.0, 2.0]
111
+ end
24
112
 
25
- it "should demongoize to rgeo" do
26
- bar.location.class.should eql(RGeo::Geographic::SphericalPointImpl)
113
+ it "should have an array [] accessor" do
114
+ bar = Bar.create!(location: [3,2])
115
+ bar.location[0].should == 3.0
27
116
  end
28
117
 
118
+ it "should have an ActiveModel symbol accessor" do
119
+ bar = Bar.create!(location: [3,2])
120
+ bar[:location].should == [3,2]
121
+ end
122
+
123
+ it "should calculate distance between points" do
124
+ pending
125
+ bar = Bar.create!(location: [5,5])
126
+ bar2 = Bar.create!(location: [15,15])
127
+ bar.location.distance(bar2.location).should be_within(1).of(1561283.8)
128
+ end
129
+
130
+ it "should calculate 3d distances by default" do
131
+ pending
132
+ bar = Bar.create! location: [-73.77694444, 40.63861111 ]
133
+ bar2 = Bar.create! location: [-118.40, 33.94] #,:unit=>:mi, :spherical => true)
134
+ bar.location.distance(bar2.location).to_i.should be_within(1).of(2469)
135
+ end
136
+
137
+ end
138
+
139
+ # should raise
140
+ # geom.to_geo
141
+
142
+ describe "with rgeo" do
143
+
144
+ describe "instantiated" do
145
+
146
+ let(:bar) { Bar.create!(name: 'Vitinho', location: [10,10]) }
147
+
148
+ it "should demongoize to rgeo" do
149
+ bar.location.class.should eql(Mongoid::Geospatial::Point)
150
+ end
151
+
152
+ end
153
+
154
+
29
155
  end
30
156
 
31
157
  end
@@ -2,5 +2,80 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Geospatial::Polygon do
4
4
 
5
+ describe "(de)mongoize" do
6
+
7
+ it "should support a field mapped as polygon" do
8
+ farm = Farm.new(area: [[5,5],[6,5],[6,6],[5,6]])
9
+ farm.area.should eq([[5,5],[6,5],[6,6],[5,6]])
10
+ farm.area.should be_a Mongoid::Geospatial::Polygon
11
+ end
12
+
13
+ it "should store as array on mongo" do
14
+ Farm.create(area: [[5,5],[6,5],[6,6],[5,6]])
15
+ Farm.first.area.should eq([[5,5],[6,5],[6,6],[5,6]])
16
+ end
17
+
18
+ it "should have a bounding box" do
19
+ geom = Mongoid::Geospatial::Polygon.new [[1,5],[6,5],[6,6],[5,6]]
20
+ geom.bbox.should eq([[1,5], [6,6]])
21
+ end
22
+
23
+ it "should have a center point" do
24
+ geom = Mongoid::Geospatial::Polygon.new [[1,1],[1,1],[9,9],[9,9]]
25
+ geom.center.should eq([5.5,5.5])
26
+ end
27
+
28
+ it "should have a radius helper" do
29
+ geom = Mongoid::Geospatial::Polygon.new [[1,1],[1,1],[9,9],[9,9]]
30
+ geom.radius(10).should eq([[5.5,5.5], 10])
31
+ end
32
+
33
+ it "should have a radius sphere" do
34
+ geom = Mongoid::Geospatial::Polygon.new [[1,1],[1,1],[9,9],[9,9]]
35
+ geom.radius_sphere(10)[1].should be_within(0.001).of(0.001569)
36
+ end
37
+
38
+
39
+ describe "with rgeo" do
40
+ # farm.area.should be_a RGeo::Geographic::SphericalPolygonImpl
41
+ end
42
+
43
+ end
44
+
45
+ describe "query" do
46
+
47
+ context ":box, :polygon" do
48
+
49
+ before do
50
+ Farm.create_indexes
51
+ end
52
+
53
+ let!(:ranch) do
54
+ Farm.create(:name => 'Ranch', area: [[1, 1],[3, 3]], :geom => [2, 2])
55
+ end
56
+
57
+ let!(:farm) do
58
+ Farm.create(name: 'Farm', area: [[47, 1],[49, 1.5],[49, 3],[46, 5]], geom: [47.5, 2.26])
59
+ end
60
+
61
+ it "returns the documents within a box" do
62
+ Farm.where(:geom.within_box => ranch.area ).to_a.should == [ ranch ]
63
+ end
64
+
65
+ it "returns the documents within a polygon" do
66
+ Farm.where(:geom.within_polygon => farm.area).to_a.should == [ farm ]
67
+ end
68
+
69
+ it "returns the documents within a center" do
70
+ Farm.where(:geom.within_circle => [ranch.geom, 0.4]).first.should eq(ranch)
71
+ end
72
+
73
+ it "returns the documents within a center_sphere" do
74
+ Farm.where(:geom.within_spherical_circle => [ranch.geom, 0.1]).first.should eq(ranch)
75
+ end
76
+
77
+ end
78
+
79
+ end
5
80
 
6
81
  end