mongoid_geo 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.