mongoid_geo 0.1.8 → 0.2.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 CHANGED
@@ -111,9 +111,32 @@ With the new @:geo@ option supplied by _mongoid-geo_ :
111
111
  # PURE MAGIC!!!
112
112
  </pre>
113
113
 
114
- h2. News update
114
+ h2. News update (March 2)
115
115
 
116
- Added support for setting location attribute using object with either #location or #position attribute that has lat/lng attributes within (see fields spec).
116
+ * Added support for geoNear queries!!!
117
+
118
+ <pre>
119
+ class Address
120
+ include Mongoid::Document
121
+ extend Mongoid::Geo::Near
122
+
123
+ field :location, :type => Array, :geo => true
124
+ ...
125
+ end
126
+
127
+ # Find all addresses sorted nearest to a specific address loation
128
+ nearest_addresses = Address.geoNear(another_address, :location)
129
+
130
+ class Position
131
+ include Mongoid::Document
132
+
133
+ field :pos, :type => Array, :geo => true
134
+ ...
135
+ end
136
+
137
+ # Find all positions sorted nearest to the address loation
138
+ nearest_positions = Position.geoNear(another_address.location, :pos)
139
+ </pre>
117
140
 
118
141
  h2. Mongoid Geo extra inclusions
119
142
 
@@ -7,6 +7,9 @@ module Mongoid #:nodoc
7
7
  define_method(meth) { read_attribute(name) }
8
8
 
9
9
  if options[:type] == Array && options[:geo]
10
+ puts "geo:"
11
+ # instance_eval { self.send :extend, Mongoid::Geo::Near }
12
+
10
13
  lat_meth = options[:lat] || "lat"
11
14
  lng_meth = options[:lng] || "lng"
12
15
 
@@ -0,0 +1,46 @@
1
+ require 'net/http'
2
+ require 'active_support'
3
+ require 'haversine'
4
+ require 'rack'
5
+ require 'hashie'
6
+ require 'mongoid/geo/haversine'
7
+
8
+ module Mongoid
9
+ module Geo
10
+ module Near
11
+ def geoNear(center, location_attribute)
12
+ center = center.respond_to?(:collection) ? center.send(location_attribute) : center
13
+ query = create_query(self, center)
14
+ create_result(query_result(self, query, center, location_attribute))
15
+ end
16
+
17
+ protected
18
+
19
+ def create_query clazz, center, mode = :plane
20
+ BSON::OrderedHash.new.tap do |query|
21
+ query["geoNear"] = clazz.to_s.tableize
22
+ query["near"] = center
23
+ # works in mongodb 1.7 but still in beta and not supported by mongodb
24
+ query["spherical"] = true if mode == :sphere
25
+ end
26
+ end
27
+
28
+ def query_result clazz, query, center, location_attribute
29
+ lon,lat = center
30
+ query_result = clazz.collection.db.command(query)['results'].sort_by do |r|
31
+ loc = r['obj'][location_attribute.to_s]
32
+ r['distance'] = Mongoid::Geo::Haversine.distance(lat, lon, loc[1], loc[0])
33
+ end
34
+ end
35
+
36
+ def create_result query_result
37
+ query_result.inject([]) do |result, qr|
38
+ res = Hashie::Mash.new(qr['obj'].to_hash)
39
+ res.dis = qr['distance']
40
+ res._id = qr['obj']['_id'].to_s
41
+ result.push(res)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ module Mongoid
2
+ module Geo
3
+ class Haversine
4
+ #EARTH_RADIUS = 3963.19 # miles
5
+ EARTH_RADIUS = 6371 # kilometers
6
+ RADIAN_PER_DEGREE = Math::PI / 180.0
7
+
8
+ def self.distance(lat1, lng1, lat2, lng2)
9
+ lat1_radians = lat1 * RADIAN_PER_DEGREE
10
+ lat2_radians = lat2 * RADIAN_PER_DEGREE
11
+
12
+ distance_lat = (lat2-lat1) * RADIAN_PER_DEGREE
13
+ distance_lng = (lng2-lng1) * RADIAN_PER_DEGREE
14
+
15
+ a = Math.sin(distance_lat/2)**2 + Math.cos(lat1_radians) * Math.cos(lat2_radians) * Math.sin(distance_lng/2) ** 2
16
+ c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
17
+ EARTH_RADIUS * c
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,6 +12,10 @@ module Mongoid #:nodoc:
12
12
  # withinCenter
13
13
  # - {"$within" : {"$center" : [center, radius]}}})
14
14
 
15
+ def geoNear
16
+ Criterion::Complex.new(:operator => 'geoNearSphere', :key => self)
17
+ end
18
+
15
19
  def nearSphere
16
20
  Criterion::Complex.new(:operator => 'nearSphere', :key => self)
17
21
  end
data/lib/mongoid/geo.rb CHANGED
@@ -6,4 +6,5 @@ end
6
6
  require 'mongoid/geo/point'
7
7
  require 'mongoid/geo/criteria'
8
8
  require 'mongoid/geo/index'
9
- require 'mongoid/geo/point'
9
+ require 'mongoid/geo/point'
10
+ require 'mongoid/geo/geo_near'
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.1.8
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,23 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-02-23 00:00:00.000000000 +01:00
12
+ date: 2011-03-02 00:00:00.000000000 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &2156123600 !ruby/object:Gem::Requirement
17
+ requirement: &2154720940 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
- version: '0'
22
+ version: '2.4'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *2156123600
25
+ version_requirements: *2154720940
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: mongoid
28
- requirement: &2156123060 !ruby/object:Gem::Requirement
28
+ requirement: &2154720340 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 2.0.0.rc.6
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2156123060
36
+ version_requirements: *2154720340
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: bson_ext
39
- requirement: &2154833320 !ruby/object:Gem::Requirement
39
+ requirement: &2154719720 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,7 +44,40 @@ dependencies:
44
44
  version: 1.1.6
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2154833320
47
+ version_requirements: *2154719720
48
+ - !ruby/object:Gem::Dependency
49
+ name: active_support
50
+ requirement: &2154719140 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: 3.0.4
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2154719140
59
+ - !ruby/object:Gem::Dependency
60
+ name: rack
61
+ requirement: &2154718560 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *2154718560
70
+ - !ruby/object:Gem::Dependency
71
+ name: hashie
72
+ requirement: &2154717980 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *2154717980
48
81
  description: Geo spatial extension on Mongoid 2, to add more geo-spatial capabilities
49
82
  email:
50
83
  - kmandrup@gmail.com
@@ -59,6 +92,8 @@ files:
59
92
  - lib/mongoid/geo/criterion/outer_operator.rb
60
93
  - lib/mongoid/geo/criterion/twin_operators.rb
61
94
  - lib/mongoid/geo/fields.rb
95
+ - lib/mongoid/geo/geo_near.rb
96
+ - lib/mongoid/geo/haversine.rb
62
97
  - lib/mongoid/geo/index.rb
63
98
  - lib/mongoid/geo/inflections.rb
64
99
  - lib/mongoid/geo/point.rb
@@ -88,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
123
  version: 1.3.6
89
124
  requirements: []
90
125
  rubyforge_project:
91
- rubygems_version: 1.5.2
126
+ rubygems_version: 1.5.3
92
127
  signing_key:
93
128
  specification_version: 3
94
129
  summary: Adds extra convenience methods for geo-spatial operations etc.