mongoid_spacial 0.2.5 → 0.2.6
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/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"
|