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 CHANGED
@@ -1 +1 @@
1
- 0.2.5
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,unit = nil, formula = nil)
23
- formula ||= @@distance_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
- unit = earth_radius[unit] if unit.kind_of?(Symbol) && earth_radius[unit]
29
- rads = Formulas.send(formula, p1, p2)
30
- (unit.kind_of?(Numeric)) ? unit*rads : rads
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 :distance_formula
43
- @@distance_formula = :n_vector
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, unit = nil, formula = nil)
24
+ def distance_from(key,p2, opts = {})
25
25
  p1 = self.send(key)
26
- Mongoid::Spacial.distance(p1, p2, unit, formula = nil)
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
- def self.n_vector(point1,point2)
6
- p1 = point1.map{|deg| deg * RAD_PER_DEG}
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
- sin_x1 = Math.sin(p1[0])
10
- cos_x1 = Math.cos(p1[0])
12
+ sin_y1 = Math.sin(p1[1])
13
+ cos_y1 = Math.cos(p1[1])
11
14
 
12
- sin_y1 = Math.sin(p1[1])
13
- cos_y1 = Math.cos(p1[1])
15
+ sin_x2 = Math.sin(p2[0])
16
+ cos_x2 = Math.cos(p2[0])
14
17
 
15
- sin_x2 = Math.sin(p2[0])
16
- cos_x2 = Math.cos(p2[0])
18
+ sin_y2 = Math.sin(p2[1])
19
+ cos_y2 = Math.cos(p2[1])
17
20
 
18
- sin_y2 = Math.sin(p2[1])
19
- cos_y2 = Math.cos(p2[1])
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
- cross_prod = (cos_y1*cos_x1 * cos_y2*cos_x2) +
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
- return cross_prod > 0 ? 0 : Math::PI if (cross_prod >= 1 || cross_prod <= -1)
27
+ d = Math.acos(cross_prod)
28
+ d.instance_variable_set("@radian", true)
29
+ d
30
+ end
26
31
 
27
- Math.acos(cross_prod)
28
- end
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
- def self.haversine(point1,point2)
31
- p1 = point1.map{|deg| deg * RAD_PER_DEG}
32
- p2 = point2.map{|deg| deg * RAD_PER_DEG}
36
+ dlon = p2[0] - p1[0]
37
+ dlat = p2[1] - p1[1]
33
38
 
34
- dlon = p2[0] - p1[0]
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
- a = (Math.sin(dlat/2))**2 + Math.cos(p1[1]) * Math.cos(p2[1]) * (Math.sin(dlon/2))**2
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
- 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
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
@@ -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.5"
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
+
@@ -0,0 +1,6 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Spacial do
4
+ describe '#distance' do
5
+ end
6
+ end
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
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: 4489034122612301384
267
+ hash: 1525314815871723941
266
268
  segments:
267
269
  - 0
268
270
  version: "0"