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.
- data/Gemfile +2 -1
- data/README.md +84 -60
- data/lib/mongoid_geospatial.rb +3 -7
- data/lib/mongoid_geospatial/{geospatial → extensions}/core_ext.rb +0 -0
- data/lib/mongoid_geospatial/field_option.rb +3 -4
- data/lib/mongoid_geospatial/fields/geometry_field.rb +34 -0
- data/lib/mongoid_geospatial/fields/line_string.rb +5 -7
- data/lib/mongoid_geospatial/fields/point.rb +18 -33
- data/lib/mongoid_geospatial/fields/polygon.rb +6 -14
- data/lib/mongoid_geospatial/geospatial.rb +20 -25
- data/lib/mongoid_geospatial/version.rb +1 -1
- data/lib/mongoid_geospatial/wrappers/georuby.rb +28 -0
- data/lib/mongoid_geospatial/wrappers/rgeo.rb +32 -0
- data/spec/models/farm.rb +5 -2
- data/spec/models/person.rb +4 -14
- data/spec/models/phone.rb +1 -3
- data/spec/mongoid_geospatial/extensions/core_ext_spec.rb +20 -0
- data/spec/mongoid_geospatial/field_option_spec.rb +11 -0
- data/spec/mongoid_geospatial/fields/line_string_spec.rb +40 -0
- data/spec/mongoid_geospatial/fields/point_spec.rb +136 -10
- data/spec/mongoid_geospatial/fields/polygon_spec.rb +75 -0
- data/spec/mongoid_geospatial/geospatial_spec.rb +88 -3
- data/spec/mongoid_geospatial/wrappers/rgeo_spec.rb +43 -0
- data/spec/spec_helper.rb +5 -21
- metadata +14 -26
- data/lib/mongoid_geospatial/contextual/mongo.rb +0 -118
- data/lib/mongoid_geospatial/criteria.rb +0 -10
- data/lib/mongoid_geospatial/criterion/complex.rb +0 -26
- data/lib/mongoid_geospatial/criterion/inclusion.rb +0 -14
- data/lib/mongoid_geospatial/criterion/near_spatial.rb +0 -52
- data/lib/mongoid_geospatial/criterion/within_spatial.rb +0 -62
- data/lib/mongoid_geospatial/extensions/symbol.rb +0 -46
- data/lib/mongoid_geospatial/finders.rb +0 -5
- data/lib/mongoid_geospatial/geospatial/geo_near_results.rb +0 -140
- data/spec/mongoid_geospatial/contextual/mongo_spec.rb +0 -135
- data/spec/mongoid_geospatial/criterion/complex_spec.rb +0 -15
- data/spec/mongoid_geospatial/criterion/inclusion_spec.rb +0 -375
- data/spec/mongoid_geospatial/criterion/near_spatial_spec.rb +0 -39
- data/spec/mongoid_geospatial/criterion/within_spatial_spec.rb +0 -54
- data/spec/mongoid_geospatial/geospatial/geo_near_results_spec.rb +0 -78
- data/spec/mongoid_geospatial/mongoid_geospatial_spec.rb +0 -83
@@ -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,
|
6
|
-
field :
|
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
|
data/spec/models/person.rb
CHANGED
@@ -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
@@ -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,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
|
-
|
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(
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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
|
26
|
-
bar.location
|
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
|