mongoid_geo 0.4.3 → 0.5.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/README.textile +32 -10
- data/lib/mongoid/geo/fields.rb +6 -1
- data/lib/mongoid/geo/geo_near.rb +20 -50
- data/lib/mongoid/geo/unit.rb +83 -0
- data/lib/mongoid/geo.rb +1 -0
- metadata +14 -13
data/README.textile
CHANGED
@@ -123,9 +123,9 @@ With the new @:geo@ option supplied by _mongoid-geo_ :
|
|
123
123
|
Mongoid::Geo.spherical = true
|
124
124
|
</pre>
|
125
125
|
|
126
|
-
h2. News update (
|
126
|
+
h2. News update (May 9, 2011)
|
127
127
|
|
128
|
-
|
128
|
+
The geoNear queries can now convert the result into a Mongoid::Criteria, where distance from a given location is sorted in either descending or ascending (default) order
|
129
129
|
|
130
130
|
<pre>
|
131
131
|
class Address
|
@@ -145,18 +145,40 @@ class Position
|
|
145
145
|
field :pos, :type => Array, :geo => true
|
146
146
|
...
|
147
147
|
end
|
148
|
+
</pre>
|
149
|
+
|
150
|
+
Find all positions sorted nearest to the address loation
|
151
|
+
@nearest_positions = Position.geoNear(another_address.location, :pos)@
|
152
|
+
|
153
|
+
Perform distance locations in Speherical mode inside Mongo DB (default is :plane)
|
154
|
+
@nearest_positions = Position.geoNear(another_address.location, :pos, :mode => :sphere)@
|
155
|
+
|
156
|
+
Other options supported are: @:num, :maxDistance, :distanceMultiplier, :query@
|
157
|
+
|
158
|
+
GeoNear distance returns distance in degrees. Use distanceMultiplier to return in Miles or KM.
|
159
|
+
|
160
|
+
Set :distanceMultiplier to 6371 to get distance in KM
|
161
|
+
Set :distanceMultiplier to 3963.19 to get distance in Miles
|
162
|
+
|
163
|
+
You can also use the :unit option instead like this (supports :feet, :meters, :kms, :miles)
|
164
|
+
|
165
|
+
results = Address.geoNear @center.location, :location, :unit => :km
|
166
|
+
|
167
|
+
The query result is returned as an Array of Hashies
|
168
|
+
|
169
|
+
The result can be then converted to a Mongoid::Criteria if needed
|
170
|
+
|
171
|
+
pp results.as_criteria.to_a.map(&:distance)
|
172
|
+
pp results.as_criteria(:desc).to_a.map(&:distance)
|
173
|
+
|
174
|
+
Or converted to an array of Model instances
|
148
175
|
|
149
|
-
|
150
|
-
nearest_positions = Position.geoNear(another_address.location, :pos)
|
176
|
+
pp results.to_models.map(&:distance)
|
151
177
|
|
152
|
-
|
153
|
-
nearest_positions = Position.geoNear(another_address.location, :pos, :mode => :sphere)
|
178
|
+
Note that the :fromLocation field, stores the location the distance was last calculated as a hash of the Point it was calculated from
|
154
179
|
|
155
|
-
|
180
|
+
@[23.5, -47].hash@
|
156
181
|
|
157
|
-
# GeoNear distance returns distance in degrees. Use distanceMultiplier to return in Miles or KM.
|
158
|
-
# set distanceMultiplier to 6371 to get distance in KM
|
159
|
-
# set distanceMultiplier to 3963.19 to get distance in Miles
|
160
182
|
</pre>
|
161
183
|
|
162
184
|
If you need to operate on the Mongoid models referenced by the query result, simply call #to_models on it
|
data/lib/mongoid/geo/fields.rb
CHANGED
@@ -26,6 +26,11 @@ module Mongoid #:nodoc
|
|
26
26
|
end
|
27
27
|
|
28
28
|
define_method("#{meth}=") do |value|
|
29
|
+
if options[:geo]
|
30
|
+
self.class.send :field, :distance, :type => Float
|
31
|
+
self.class.send :field, :fromLocation, :type => String
|
32
|
+
end
|
33
|
+
|
29
34
|
if options[:type] == Array && options[:geo]
|
30
35
|
value = case value
|
31
36
|
when String
|
@@ -37,7 +42,7 @@ module Mongoid #:nodoc
|
|
37
42
|
end
|
38
43
|
value = value[0..1] if !value.nil?
|
39
44
|
end
|
40
|
-
value.reverse! if Mongoid::Geo.spherical && value
|
45
|
+
value.reverse! if Mongoid::Geo.spherical && value && !value.kind_of?(BSON::ObjectId)
|
41
46
|
write_attribute(name, value)
|
42
47
|
end
|
43
48
|
|
data/lib/mongoid/geo/geo_near.rb
CHANGED
@@ -25,39 +25,38 @@ module Mongoid
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
module Distance
|
29
|
-
attr_reader :distance
|
30
|
-
|
31
|
-
def set_distance dist
|
32
|
-
@distance = dist
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
28
|
module Model
|
37
29
|
def to_model
|
38
30
|
m = klass.where(:_id => _id).first.extend(Mongoid::Geo::Distance)
|
39
|
-
m.
|
31
|
+
m.distance = distance
|
40
32
|
m
|
41
33
|
end
|
42
34
|
end
|
43
35
|
|
44
36
|
module Models
|
45
|
-
def to_models
|
37
|
+
def to_models mode = nil
|
46
38
|
distance_hash = Hash[ self.map {|item| [item._id, item.distance] } ]
|
39
|
+
from_hash = Hash[ self.map { |item| [item._id, item.fromLocation] } ]
|
47
40
|
|
48
41
|
ret = to_criteria.to_a.map do |m|
|
49
|
-
m.
|
50
|
-
m.
|
42
|
+
m.distance = distance_hash[m._id.to_s]
|
43
|
+
m.fromLocation = from_hash[m._id.to_s]
|
44
|
+
m.save if mode == :save
|
51
45
|
m
|
52
46
|
end
|
53
|
-
|
54
47
|
ret.sort {|a,b| a.distance <=> b.distance}
|
55
48
|
end
|
49
|
+
|
50
|
+
def as_criteria direction = :asc
|
51
|
+
to_models(:save)
|
52
|
+
ids = first.klass.where().map(&:_id)
|
53
|
+
Mongoid::Criteria.new(first.klass).where(:_id.in => ids, :fromLocation => first.fromLocation).send(direction, :distance)
|
54
|
+
end
|
56
55
|
|
57
56
|
def to_criteria
|
58
|
-
ids = map(&:_id)
|
59
|
-
first.klass.where(:_id.in => ids)
|
60
|
-
end
|
57
|
+
ids = map(&:_id)
|
58
|
+
Mongoid::Criteria.new(first.klass).where(:_id.in => ids).desc(:distance)
|
59
|
+
end
|
61
60
|
end
|
62
61
|
|
63
62
|
module Near
|
@@ -97,6 +96,7 @@ module Mongoid
|
|
97
96
|
# Calculate distance in KM or Miles if mongodb < 1.7
|
98
97
|
r[distance_meth] ||= calc_distance(r, center, location_attribute, options) if Mongoid::Geo.mongo_db_version < 1.7
|
99
98
|
r['klass'] = klass
|
99
|
+
r['from'] = center.hash
|
100
100
|
end
|
101
101
|
query_result
|
102
102
|
end
|
@@ -105,10 +105,11 @@ module Mongoid
|
|
105
105
|
qres.map do |qr|
|
106
106
|
res = Hashie::Mash.new(qr['obj'].to_hash).extend(Mongoid::Geo::Model)
|
107
107
|
res.klass = qr['klass']
|
108
|
+
res.fromLocation = qr['from']
|
108
109
|
res.distance = qr[distance_meth]
|
109
110
|
res._id = qr['obj']['_id'].to_s
|
110
111
|
res
|
111
|
-
end
|
112
|
+
end
|
112
113
|
end
|
113
114
|
|
114
115
|
private
|
@@ -116,39 +117,8 @@ module Mongoid
|
|
116
117
|
def distance_multiplier options
|
117
118
|
distanceMultiplier = options[:distanceMultiplier]
|
118
119
|
return distanceMultiplier if distanceMultiplier && Mongoid::Geo.mongo_db_version >= 1.7
|
119
|
-
|
120
|
-
|
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
|
-
}
|
120
|
+
return Mongoid::Geo::Unit.distMultiplier(options[:unit]) if options[:unit]
|
121
|
+
1
|
152
122
|
end
|
153
123
|
|
154
124
|
def query_results klass, query
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Geo
|
3
|
+
class Unit
|
4
|
+
class << self
|
5
|
+
def key unit = :km
|
6
|
+
unit = unit.to_sym
|
7
|
+
methods.grep(/_unit/).each do |meth|
|
8
|
+
return meth.to_s.chomp('_unit').to_sym if send(meth).include? unit
|
9
|
+
end
|
10
|
+
raise ArgumentError, "Unknown unit key: #{unit}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def distMultiplier unit = :km
|
14
|
+
unit_key = key(unit)
|
15
|
+
return radian_multiplier[unit_key] if unit_key && Mongoid::Geo.mongo_db_version >= 1.7
|
16
|
+
unit_multiplier[unit_key] if unit_key
|
17
|
+
end
|
18
|
+
|
19
|
+
def precision
|
20
|
+
{
|
21
|
+
:feet => 0,
|
22
|
+
:meters => 2,
|
23
|
+
:kms => 4,
|
24
|
+
:miles => 4,
|
25
|
+
:radians => 4
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# from mongoid-geo, as suggested by niedhui :)
|
30
|
+
def radian_multiplier
|
31
|
+
{
|
32
|
+
:feet => 364491.8,
|
33
|
+
:meters => 111170,
|
34
|
+
:kms => 111.17,
|
35
|
+
:miles => 69.407,
|
36
|
+
:radians => 1
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def unit_multiplier
|
41
|
+
{
|
42
|
+
:feet => 0.305,
|
43
|
+
:meters => 1,
|
44
|
+
:kms => 6371,
|
45
|
+
:miles => 3959
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def meters_map
|
50
|
+
{
|
51
|
+
:feet => 3.2808,
|
52
|
+
:meters => 1,
|
53
|
+
:kms => 0.001,
|
54
|
+
:miles => 0.00062137,
|
55
|
+
:radians => 111170
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def feet_unit
|
62
|
+
[:ft, :feet, :foot]
|
63
|
+
end
|
64
|
+
|
65
|
+
def meters_unit
|
66
|
+
[:m, :meter, :meters]
|
67
|
+
end
|
68
|
+
|
69
|
+
def kms_unit
|
70
|
+
[:km, :kms, :kilometer, :kilometers]
|
71
|
+
end
|
72
|
+
|
73
|
+
def miles_unit
|
74
|
+
[:mil, :mile, :miles]
|
75
|
+
end
|
76
|
+
|
77
|
+
def radians_unit
|
78
|
+
[:rad, :radians]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/mongoid/geo.rb
CHANGED
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
|
+
version: 0.5.0
|
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-
|
12
|
+
date: 2011-05-09 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152937900 !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: *
|
24
|
+
version_requirements: *2152937900
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mongoid
|
27
|
-
requirement: &
|
27
|
+
requirement: &2152965320 !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: *
|
35
|
+
version_requirements: *2152965320
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bson
|
38
|
-
requirement: &
|
38
|
+
requirement: &2152964860 !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: *
|
46
|
+
version_requirements: *2152964860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: activesupport
|
49
|
-
requirement: &
|
49
|
+
requirement: &2152964400 !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: *
|
57
|
+
version_requirements: *2152964400
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: hashie
|
60
|
-
requirement: &
|
60
|
+
requirement: &2152963940 !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: *
|
68
|
+
version_requirements: *2152963940
|
69
69
|
description: Geo spatial extension on Mongoid 2, to add more geo-spatial capabilities
|
70
70
|
email:
|
71
71
|
- kmandrup@gmail.com
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/mongoid/geo/index.rb
|
86
86
|
- lib/mongoid/geo/inflections.rb
|
87
87
|
- lib/mongoid/geo/point.rb
|
88
|
+
- lib/mongoid/geo/unit.rb
|
88
89
|
- lib/mongoid/geo.rb
|
89
90
|
- lib/mongoid_geo.rb
|
90
91
|
- MIT-LICENSE
|
@@ -110,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
111
|
version: 1.3.6
|
111
112
|
requirements: []
|
112
113
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.8.0
|
114
115
|
signing_key:
|
115
116
|
specification_version: 3
|
116
117
|
summary: Adds extra convenience methods for geo-spatial operations etc.
|