mongoid_geo 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,7 +11,7 @@ module Mongoid #:nodoc:
11
11
  # @param [ Hash ] attributes The fields with lat/long values.
12
12
  #
13
13
  # @return [ Criteria ] A new criteria with the added selector.
14
- def nearSphere(attributes = {})
14
+ def nearSphere(attributes = {})
15
15
  update_selector(attributes, "$nearSphere")
16
16
  end
17
17
  end
@@ -10,9 +10,10 @@ module Mongoid
10
10
  attr_accessor :spherical
11
11
 
12
12
  def spherical_mode mode = true, &block
13
- @spherical = mode
14
- yield if block
15
- @spherical = !mode
13
+ @spherical, old_spherical, result = mode, @spherical, @spherical
14
+ result = yield if block
15
+ @spherical = old_spherical
16
+ result
16
17
  end
17
18
 
18
19
  def lat_index
@@ -71,8 +72,7 @@ module Mongoid
71
72
  def create_query klass, center, options = {}
72
73
  num = options[:num]
73
74
  maxDistance = options[:maxDistance]
74
- query = options[:query]
75
- distanceMultiplier = options[:distanceMultiplier]
75
+ query = options[:query]
76
76
  mode = options[:mode] || :plane
77
77
 
78
78
  nq = BSON::OrderedHash.new.tap do |near_query|
@@ -80,10 +80,11 @@ module Mongoid
80
80
  near_query["near"] = center
81
81
  near_query["num"] = num if num
82
82
  near_query["maxDistance"] = maxDistance if maxDistance
83
+
83
84
  # mongodb < 1.7 returns degrees but with earth flat. in Mongodb 1.7 you can set sphere and let mongodb calculate the distance in Miles or KM
84
85
  # for mongodb < 1.7 we need to run Haversine first before calculating degrees to Km or Miles. See below.
85
- near_query["distanceMultiplier"] = distanceMultiplier if distanceMultiplier && Mongoid::Geo.mongo_db_version >= 1.7
86
- near_query["query"] = query if query
86
+ near_query["distanceMultiplier"] = distance_multiplier(options)
87
+ near_query["query"] = query if query
87
88
 
88
89
  # works in mongodb 1.7 but still in beta and not supported by mongodb
89
90
  near_query["spherical"] = true if mode == :sphere && Mongoid::Geo.mongo_db_version >= 1.7
@@ -91,27 +92,85 @@ module Mongoid
91
92
  nq
92
93
  end
93
94
 
94
- def query_result klass, query, center, location_attribute, options = {}
95
- distanceMultiplier = options[:distanceMultiplier]
96
- lon,lat = center
97
- query_result = klass.collection.db.command(query)['results'].sort_by do |r|
98
- loc = r['obj'][location_attribute.to_s]
99
- r['distance'] = Mongoid::Geo::Haversine.distance(lat, lon, loc[1], loc[0]) if Mongoid::Geo.mongo_db_version < 1.7
95
+ def query_result klass, query, center, location_attribute, options = {}
96
+ query_result = query_results(klass, query).sort_by do |r|
100
97
  # Calculate distance in KM or Miles if mongodb < 1.7
101
- r['distance'] = r['distance'] * distanceMultiplier if distanceMultiplier && Mongoid::Geo.mongo_db_version < 1.7
98
+ r[distance_meth] ||= calc_distance(r, center, location_attribute, options) if Mongoid::Geo.mongo_db_version < 1.7
102
99
  r['klass'] = klass
103
100
  end
101
+ query_result
104
102
  end
105
103
 
106
- def create_result query_result
107
- query_result.map do |qr|
104
+ def create_result qres
105
+ qres.map do |qr|
108
106
  res = Hashie::Mash.new(qr['obj'].to_hash).extend(Mongoid::Geo::Model)
109
107
  res.klass = qr['klass']
110
- res.distance = qr['distance']
108
+ res.distance = qr[distance_meth]
111
109
  res._id = qr['obj']['_id'].to_s
112
110
  res
113
111
  end
114
112
  end
113
+
114
+ private
115
+
116
+ def distance_multiplier options
117
+ distanceMultiplier = options[:distanceMultiplier]
118
+ return distanceMultiplier if distanceMultiplier && Mongoid::Geo.mongo_db_version >= 1.7
119
+
120
+ return radian_multiplier[options[:unit]] if options[:unit] && Mongoid::Geo.mongo_db_version >= 1.7
121
+ unit_multiplier[options[:unit]] if options[:unit]
122
+ end
123
+
124
+ def unit_multiplier
125
+ {
126
+ :feet => 0.305,
127
+ :ft => 0.305,
128
+ :m => 1,
129
+ :meters => 1,
130
+ :meter => 1,
131
+ :km => 6371,
132
+ :kms => 6371,
133
+ :mil => 3959,
134
+ :mile => 3959,
135
+ :miles => 3959
136
+ }
137
+ end
138
+
139
+ def radian_multiplier
140
+ {
141
+ :feet => 364491.8,
142
+ :ft => 364491.8,
143
+ :m => 111170,
144
+ :meter => 111170,
145
+ :meters => 111170,
146
+ :km => 111.17,
147
+ :kms => 111.17,
148
+ :mil => 69.407,
149
+ :mile => 69.407,
150
+ :miles => 69.407
151
+ }
152
+ end
153
+
154
+ def query_results klass, query
155
+ exec_query(klass, query)['results']
156
+ end
157
+
158
+ def exec_query klass, query
159
+ klass.collection.db.command(query)
160
+ end
161
+
162
+ def calc_distance r, center, location_attribute, options
163
+ distanceMultiplier = distance_multiplier(options)
164
+ loc = r['obj'][location_attribute.to_s].extend(Mongoid::Geo::Point).to_points
165
+ center = center.extend(Mongoid::Geo::Point).to_points
166
+ dist = Mongoid::Geo::Haversine.distance(center.first, center.last, loc.first, loc.last)
167
+ dist *= distanceMultiplier if distanceMultiplier
168
+ dist
169
+ end
170
+
171
+ def distance_meth
172
+ Mongoid::Geo.mongo_db_version >= 1.7 ? 'dis' : 'distance'
173
+ end
115
174
  end
116
175
  end
117
176
  end
@@ -13,11 +13,13 @@ module Mongoid #:nodoc:
13
13
  # - {"$within" : {"$center" : [center, radius]}}})
14
14
 
15
15
  def geoNear
16
- Criterion::Complex.new(:operator => 'geoNearSphere', :key => self)
16
+ Criterion::Complex.new(:operator => 'geoNearSphere', :key => self)
17
17
  end
18
18
 
19
19
  def nearSphere
20
- Criterion::Complex.new(:operator => 'nearSphere', :key => self)
20
+ Mongoid::Geo.spherical_mode do
21
+ Criterion::Complex.new(:operator => 'nearSphere', :key => self)
22
+ end
21
23
  end
22
24
 
23
25
  def nearMax *calcs
@@ -38,6 +38,24 @@ module Mongoid::Geo
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ module Mongoid::GeoPoint
43
+ def lat= value
44
+ self[Mongoid::Geo.lat_index] = value
45
+ end
46
+
47
+ def lng= value
48
+ self[Mongoid::Geo.lng_index] = value
49
+ end
50
+
51
+ def lat
52
+ self[Mongoid::Geo.lat_index]
53
+ end
54
+
55
+ def lng
56
+ self[Mongoid::Geo.lng_index]
57
+ end
58
+ end
41
59
 
42
60
  module Mongoid::Geo
43
61
  module PointConversion
@@ -53,4 +71,10 @@ module Mongoid::Geo
53
71
  v.extend(Mongoid::Geo::Point).to_points
54
72
  end
55
73
  end
56
- end
74
+ end
75
+
76
+ class Array
77
+ def to_geopoint
78
+ self.extend(Mongoid::GeoPoint)
79
+ end
80
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_geo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-03 00:00:00.000000000Z
12
+ date: 2011-05-04 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2153178360 !ruby/object:Gem::Requirement
16
+ requirement: &2152917100 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '2.4'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2153178360
24
+ version_requirements: *2152917100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mongoid
27
- requirement: &2153177900 !ruby/object:Gem::Requirement
27
+ requirement: &2152916640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.0.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2153177900
35
+ version_requirements: *2152916640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bson
38
- requirement: &2153177440 !ruby/object:Gem::Requirement
38
+ requirement: &2152916180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.3'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2153177440
46
+ version_requirements: *2152916180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &2153176980 !ruby/object:Gem::Requirement
49
+ requirement: &2152915720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 3.0.4
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2153176980
57
+ version_requirements: *2152915720
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: hashie
60
- requirement: &2153176520 !ruby/object:Gem::Requirement
60
+ requirement: &2152931640 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 0.4.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2153176520
68
+ version_requirements: *2152931640
69
69
  description: Geo spatial extension on Mongoid 2, to add more geo-spatial capabilities
70
70
  email:
71
71
  - kmandrup@gmail.com