mongoid_spacial 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/mongoid_spacial/spacial.rb +16 -11
- data/lib/mongoid_spacial/spacial/document.rb +2 -2
- data/lib/mongoid_spacial/spacial/formulas.rb +33 -24
- data/lib/mongoid_spacial/spacial/geo_near_results.rb +2 -2
- data/mongoid_spacial.gemspec +4 -2
- data/spec/functional/mongoid/spacial_spec.rb +18 -0
- data/spec/unit/mongoid/spacial_spec.rb +6 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.6
|
@@ -19,15 +19,19 @@ module Mongoid
|
|
19
19
|
LNG_SYMBOLS = [:x, :lon, :long, :lng, :longitude]
|
20
20
|
LAT_SYMBOLS = [:y, :lat, :latitude]
|
21
21
|
|
22
|
-
def self.distance(p1,p2,
|
23
|
-
formula ||= @@
|
24
|
-
|
22
|
+
def self.distance(p1,p2,opts = {})
|
23
|
+
opts[:formula] ||= (opts[:spherical]) ? @@spherical_distance_formula : :pythagorean_theorem
|
25
24
|
p1 = p1.to_lng_lat if p1.respond_to?(:to_lng_lat)
|
26
25
|
p2 = p2.to_lng_lat if p2.respond_to?(:to_lng_lat)
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
rads = Formulas.send(opts[:formula], p1, p2)
|
28
|
+
|
29
|
+
if unit = earth_radius[opts[:unit]]
|
30
|
+
opts[:unit] = (rads.instance_variable_get("@radian")) ? unit : unit * RAD_PER_DEG
|
31
|
+
end
|
32
|
+
|
33
|
+
rads *= opts[:unit].to_f if opts[:unit]
|
34
|
+
rads
|
31
35
|
end
|
32
36
|
|
33
37
|
mattr_accessor :lng_symbols
|
@@ -39,13 +43,14 @@ module Mongoid
|
|
39
43
|
mattr_accessor :earth_radius
|
40
44
|
@@earth_radius = EARTH_RADIUS.dup
|
41
45
|
|
42
|
-
mattr_accessor :
|
43
|
-
@@
|
44
|
-
|
45
|
-
mattr_accessor :paginator
|
46
|
-
@@paginator = :array
|
46
|
+
mattr_accessor :paginator
|
47
|
+
@@paginator = :array
|
47
48
|
|
48
49
|
mattr_accessor :default_per_page
|
49
50
|
@@default_per_page = 25
|
51
|
+
|
52
|
+
mattr_accessor :spherical_distance_formula
|
53
|
+
@@spherical_distance_formula = :n_vector
|
54
|
+
|
50
55
|
end
|
51
56
|
end
|
@@ -21,9 +21,9 @@ module Mongoid
|
|
21
21
|
end
|
22
22
|
|
23
23
|
module InstanceMethods #:nodoc:
|
24
|
-
def distance_from(key,p2,
|
24
|
+
def distance_from(key,p2, opts = {})
|
25
25
|
p1 = self.send(key)
|
26
|
-
Mongoid::Spacial.distance(p1, p2,
|
26
|
+
Mongoid::Spacial.distance(p1, p2, opts)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -1,42 +1,51 @@
|
|
1
1
|
module Mongoid
|
2
2
|
module Spacial
|
3
3
|
module Formulas
|
4
|
+
class << self
|
5
|
+
def n_vector(point1,point2)
|
6
|
+
p1 = point1.map{|deg| deg * RAD_PER_DEG}
|
7
|
+
p2 = point2.map{|deg| deg * RAD_PER_DEG}
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
p2 = point2.map{|deg| deg * RAD_PER_DEG}
|
9
|
+
sin_x1 = Math.sin(p1[0])
|
10
|
+
cos_x1 = Math.cos(p1[0])
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
sin_y1 = Math.sin(p1[1])
|
13
|
+
cos_y1 = Math.cos(p1[1])
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
sin_x2 = Math.sin(p2[0])
|
16
|
+
cos_x2 = Math.cos(p2[0])
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
sin_y2 = Math.sin(p2[1])
|
19
|
+
cos_y2 = Math.cos(p2[1])
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
cross_prod = (cos_y1*cos_x1 * cos_y2*cos_x2) +
|
22
|
+
(cos_y1*sin_x1 * cos_y2*sin_x2) +
|
23
|
+
(sin_y1 * sin_y2)
|
20
24
|
|
21
|
-
|
22
|
-
(cos_y1*sin_x1 * cos_y2*sin_x2) +
|
23
|
-
(sin_y1 * sin_y2)
|
25
|
+
return cross_prod > 0 ? 0 : Math::PI if (cross_prod >= 1 || cross_prod <= -1)
|
24
26
|
|
25
|
-
|
27
|
+
d = Math.acos(cross_prod)
|
28
|
+
d.instance_variable_set("@radian", true)
|
29
|
+
d
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
32
|
+
def haversine(point1,point2)
|
33
|
+
p1 = point1.map{|deg| deg * RAD_PER_DEG}
|
34
|
+
p2 = point2.map{|deg| deg * RAD_PER_DEG}
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
p2 = point2.map{|deg| deg * RAD_PER_DEG}
|
36
|
+
dlon = p2[0] - p1[0]
|
37
|
+
dlat = p2[1] - p1[1]
|
33
38
|
|
34
|
-
|
35
|
-
dlat = p2[1] - p1[1]
|
39
|
+
a = (Math.sin(dlat/2))**2 + Math.cos(p1[1]) * Math.cos(p2[1]) * (Math.sin(dlon/2))**2
|
36
40
|
|
37
|
-
|
41
|
+
d = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
|
42
|
+
d.instance_variable_set("@radian", true)
|
43
|
+
d
|
44
|
+
end
|
38
45
|
|
39
|
-
|
46
|
+
def pythagorean_theorem(p1, p2)
|
47
|
+
Math.sqrt(((p2[0] - p1[0]) ** 2) + ((p2[1] - p1[1]) ** 2))
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
end
|
@@ -34,7 +34,7 @@ module Mongoid
|
|
34
34
|
end
|
35
35
|
@opts[:calculate].each do |key|
|
36
36
|
key = (key.to_s+'_distance').to_sym
|
37
|
-
res.geo[key] = res.distance_from(key,center, @opts[:distance_multiplier])
|
37
|
+
res.geo[key] = res.distance_from(key,center,{:unit =>@opts[:unit] || @opts[:distance_multiplier], :spherical => @opts[:spherical]} )
|
38
38
|
res.geo[:distance] = res.geo[key] if primary && key == primary
|
39
39
|
end
|
40
40
|
end
|
@@ -51,7 +51,7 @@ module Mongoid
|
|
51
51
|
|
52
52
|
def page(page, options = {})
|
53
53
|
new_collection = self.dup
|
54
|
-
|
54
|
+
|
55
55
|
options = self.opts.merge(options)
|
56
56
|
|
57
57
|
options[:page] = page || 1
|
data/mongoid_spacial.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid_spacial}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Ryan Ong}]
|
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
|
|
47
47
|
"spec/functional/mongoid/contexts/mongo_spec.rb",
|
48
48
|
"spec/functional/mongoid/criterion/inclusion_spec.rb",
|
49
49
|
"spec/functional/mongoid/spacial/geo_near_results_spec.rb",
|
50
|
+
"spec/functional/mongoid/spacial_spec.rb",
|
50
51
|
"spec/models/account.rb",
|
51
52
|
"spec/models/acolyte.rb",
|
52
53
|
"spec/models/address.rb",
|
@@ -122,7 +123,8 @@ Gem::Specification.new do |s|
|
|
122
123
|
"spec/unit/mongoid/criterion/inclusion_spec.rb",
|
123
124
|
"spec/unit/mongoid/criterion/near_spacial_spec.rb",
|
124
125
|
"spec/unit/mongoid/criterion/within_spacial_spec.rb",
|
125
|
-
"spec/unit/mongoid/spacial/formulas_spec.rb"
|
126
|
+
"spec/unit/mongoid/spacial/formulas_spec.rb",
|
127
|
+
"spec/unit/mongoid/spacial_spec.rb"
|
126
128
|
]
|
127
129
|
s.homepage = %q{http://github.com/ryanong/mongoid_spacial}
|
128
130
|
s.licenses = [%q{MIT}]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Spacial do
|
4
|
+
describe '#distance' do
|
5
|
+
it "should calculate 2d by default" do
|
6
|
+
Mongoid::Spacial.distance([0,0],[3,4]).should == 5
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should calculate 2d distances using degrees" do
|
10
|
+
Mongoid::Spacial.distance([0,0],[3,4], :unit=>:mi).should == 5*Mongoid::Spacial::EARTH_RADIUS[:mi]*Mongoid::Spacial::RAD_PER_DEG
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should calculate 3d distances by default" do
|
14
|
+
Mongoid::Spacial.distance([-73.77694444, 40.63861111 ],[-118.40, 33.94],:unit=>:mi, :spherical => true).to_i.should be_within(1).of(2469)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: mongoid_spacial
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ryan Ong
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- spec/functional/mongoid/contexts/mongo_spec.rb
|
174
174
|
- spec/functional/mongoid/criterion/inclusion_spec.rb
|
175
175
|
- spec/functional/mongoid/spacial/geo_near_results_spec.rb
|
176
|
+
- spec/functional/mongoid/spacial_spec.rb
|
176
177
|
- spec/models/account.rb
|
177
178
|
- spec/models/acolyte.rb
|
178
179
|
- spec/models/address.rb
|
@@ -249,6 +250,7 @@ files:
|
|
249
250
|
- spec/unit/mongoid/criterion/near_spacial_spec.rb
|
250
251
|
- spec/unit/mongoid/criterion/within_spacial_spec.rb
|
251
252
|
- spec/unit/mongoid/spacial/formulas_spec.rb
|
253
|
+
- spec/unit/mongoid/spacial_spec.rb
|
252
254
|
homepage: http://github.com/ryanong/mongoid_spacial
|
253
255
|
licenses:
|
254
256
|
- MIT
|
@@ -262,7 +264,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
262
264
|
requirements:
|
263
265
|
- - ">="
|
264
266
|
- !ruby/object:Gem::Version
|
265
|
-
hash:
|
267
|
+
hash: 1525314815871723941
|
266
268
|
segments:
|
267
269
|
- 0
|
268
270
|
version: "0"
|