mongoid-geospatial 4.0.1 → 5.0.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.
@@ -2,12 +2,12 @@
2
2
  #
3
3
  # Just for fun
4
4
  #
5
- $: << File.expand_path("../../lib", __FILE__)
5
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
6
6
 
7
7
  require 'mongoid/geospatial'
8
8
 
9
9
  Mongoid.configure do |config|
10
- config.connect_to("mongoid_geospatial_bench")
10
+ config.connect_to('mongoid_geospatial_bench')
11
11
  end
12
12
 
13
13
  Mongoid::Geospatial.with_georuby!
@@ -36,27 +36,28 @@ Mongoid.purge!
36
36
 
37
37
  Benchmark.bmbm do |b|
38
38
  [100, 1000, 3000].each do |t|
39
- nogeo, cafes = [], []
39
+ nogeo = []
40
+ cafes = []
40
41
  b.report("#{t} W NoGeo") do
41
42
  t.times { nogeo << NoGeo.create(name: 'Boring').id }
42
43
  end
43
44
  b.report("#{t} W Rider") { t.times { Rider.create(name: 'Munro') } }
44
45
 
45
46
  b.report("#{t} W Cafe ") do
46
- t.times { cafes << Cafe.create(name: 'Bacco', spot: [3,3]).id }
47
+ t.times { cafes << Cafe.create(name: 'Bacco', spot: [3, 3]).id }
47
48
  end
48
49
  # puts "---"
49
- b.report("#{t} R NoGeo") { nogeo.each { |id| NoGeo.find(id) }}
50
+ b.report("#{t} R NoGeo") { nogeo.each { |id| NoGeo.find(id) } }
50
51
  # b.report("#{t} R Rider") { t.times { Rider.create(name: 'Munro') } }
51
- b.report("#{t} R Cafe ") { cafes.each { |id| Cafe.find(id) }}
52
- b.report("#{t} R Cafe Georuby") { cafes.each { |id| Cafe.find(id).spot.to_geo }}
53
- b.report("#{t} R Cafe RGeo") { cafes.each { |id| Cafe.find(id).spot.to_rgeo }}
52
+ b.report("#{t} R Cafe ") { cafes.each { |id| Cafe.find(id) } }
53
+ b.report("#{t} R Cafe Georuby") { cafes.each { |id| Cafe.find(id).spot.to_geo } }
54
+ b.report("#{t} R Cafe RGeo") { cafes.each { |id| Cafe.find(id).spot.to_rgeo } }
54
55
  end
55
- b.report("R Cafe GeoRuby") do
56
+ b.report('R Cafe GeoRuby') do
56
57
  cafe = Cafe.first
57
58
  1_000_000.times { cafe.spot.to_geo }
58
59
  end
59
- b.report("R Cafe RGeo") do
60
+ b.report('R Cafe RGeo') do
60
61
  cafe = Cafe.first
61
62
  1_000_000.times { cafe.spot.to_rgeo }
62
63
  end
@@ -6,23 +6,22 @@ require 'mongoid/geospatial/helpers/sphere'
6
6
  require 'mongoid/geospatial/helpers/delegate'
7
7
 
8
8
  module Mongoid
9
-
10
9
  #
11
10
  # Main Geospatial module
12
11
  #
13
12
  # include Mongoid::Geospatial
14
13
  #
15
14
  module Geospatial
16
- autoload :GeometryField, 'mongoid/geospatial/geometry_field'
15
+ autoload :GeometryField, 'mongoid/geospatial/geometry_field'
17
16
 
18
- autoload :Point, 'mongoid/geospatial/fields/point'
19
- autoload :LineString, 'mongoid/geospatial/fields/line_string'
20
- autoload :Polygon, 'mongoid/geospatial/fields/polygon'
17
+ autoload :Point, 'mongoid/geospatial/fields/point'
18
+ autoload :LineString, 'mongoid/geospatial/fields/line_string'
19
+ autoload :Polygon, 'mongoid/geospatial/fields/polygon'
21
20
 
22
- autoload :Box, 'mongoid/geospatial/fields/box'
23
- autoload :Circle, 'mongoid/geospatial/fields/circle'
21
+ autoload :Box, 'mongoid/geospatial/fields/box'
22
+ autoload :Circle, 'mongoid/geospatial/fields/circle'
24
23
 
25
- autoload :VERSION, 'mongoid/geospatial/version'
24
+ autoload :VERSION, 'mongoid/geospatial/version'
26
25
 
27
26
  extend ActiveSupport::Concern
28
27
 
@@ -70,6 +69,7 @@ module Mongoid
70
69
  require 'mongoid/geospatial/wrappers/georuby'
71
70
  end
72
71
 
72
+ # Methods applied to Document's class
73
73
  module ClassMethods
74
74
  #
75
75
  # Create Spatial index for given field
@@ -78,7 +78,8 @@ module Mongoid
78
78
  # @param [String,Symbol] name
79
79
  # @param [Hash] options options for spatial_index
80
80
  #
81
- # http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-geoNearCommand
81
+ # http://www.mongodb.org/display/DOCS/Geospatial+Indexing
82
+ # #GeospatialIndexing-geoNearCommand
82
83
  #
83
84
  def spatial_index(name, options = {})
84
85
  spatial_fields_indexed << name
@@ -92,7 +93,8 @@ module Mongoid
92
93
  # @param [String,Symbol] name
93
94
  # @param [Hash] options options for spatial_index
94
95
  #
95
- # http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-geoNearCommand
96
+ # http://www.mongodb.org/display/DOCS/Geospatial+Indexing
97
+ # #GeospatialIndexing-geoNearCommand
96
98
  def sphere_index(name, options = {})
97
99
  spatial_fields_indexed << name
98
100
  index({ name => '2dsphere' }, options)
@@ -105,7 +107,8 @@ module Mongoid
105
107
  # @param [String,Symbol] name
106
108
  # @param [Hash] options options for spatial_index
107
109
  #
108
- # http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-geoNearCommand
110
+ # http://www.mongodb.org/display/DOCS/Geospatial+Indexing
111
+ # #GeospatialIndexing-geoNearCommand
109
112
  def spatial_scope(field, _opts = {})
110
113
  singleton_class.class_eval do
111
114
  # define_method(:close) do |args|
@@ -114,12 +117,6 @@ module Mongoid
114
117
  end
115
118
  end
116
119
  end
117
-
118
- private
119
- def geo_field(name, options = {})
120
- field name, { type: Mongoid::Geospatial::Point,
121
- spatial: true }.merge(options)
122
- end
123
120
  end
124
121
  end
125
122
  end
@@ -4,10 +4,12 @@ module Mongoid
4
4
  #
5
5
  class Point
6
6
  include Enumerable
7
- attr_reader :x, :y
7
+ attr_accessor :x, :y, :z
8
8
 
9
9
  def initialize(x, y, z = nil)
10
- @x, @y, @z = x, y, z
10
+ @x = x
11
+ @y = y
12
+ @z = z
11
13
  end
12
14
 
13
15
  # Object -> Database
@@ -29,21 +31,33 @@ module Mongoid
29
31
  yield x
30
32
  yield y
31
33
  end
34
+
32
35
  #
33
36
  # Point representation as a Hash
34
37
  #
35
- # @return (Hash)
38
+ # @return [Hash] with { xl => x, yl => y }
39
+ #
36
40
  def to_hsh(xl = :x, yl = :y)
37
41
  { xl => x, yl => y }
38
42
  end
39
43
  alias_method :to_hash, :to_hsh
40
44
 
45
+ #
41
46
  # Helper for [self, radius]
47
+ #
48
+ # @return [Array] with [self, radius]
49
+ #
42
50
  def radius(r = 1)
43
51
  [mongoize, r]
44
52
  end
45
53
 
46
- # Helper for [self, radius / earth radius]
54
+ #
55
+ # Radius Sphere
56
+ #
57
+ # Validates that #x & #y are `Numeric`
58
+ #
59
+ # @return [Array] with [self, radius / earth radius]
60
+ #
47
61
  def radius_sphere(r = 1, unit = :km)
48
62
  radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
49
63
  end
@@ -51,7 +65,9 @@ module Mongoid
51
65
  #
52
66
  # Am I valid?
53
67
  #
54
- # Validates that x & y are `Numeric`
68
+ # Validates that #x & #y are `Numeric`
69
+ #
70
+ # @return [Boolean] if self #x && #y are valid
55
71
  #
56
72
  def valid?
57
73
  x && y && x.is_a?(Numeric) && y.is_a?(Numeric)
@@ -63,10 +79,23 @@ module Mongoid
63
79
  # "x, y"
64
80
  #
65
81
  # @return [String] Point as comma separated String
82
+ #
66
83
  def to_s
67
84
  "#{x}, #{y}"
68
85
  end
69
86
 
87
+ #
88
+ # Point inverse/reverse
89
+ #
90
+ # MongoDB: "x, y"
91
+ # Reverse: "y, x"
92
+ #
93
+ # @return [Array] Point reversed: "y, x"
94
+ #
95
+ def reverse
96
+ [y, x]
97
+ end
98
+
70
99
  #
71
100
  # Distance calculation methods. Thinking about not using it
72
101
  # One needs to choose and external lib. GeoRuby or RGeo
@@ -100,7 +129,7 @@ module Mongoid
100
129
  # Database -> Object
101
130
  # Get it back
102
131
  def demongoize(obj)
103
- obj && Point.new(*obj)
132
+ obj && new(*obj)
104
133
  end
105
134
 
106
135
  #
@@ -122,7 +151,10 @@ module Mongoid
122
151
  # Converts the object that was supplied to a criteria
123
152
  # into a database friendly form.
124
153
  def evolve(obj)
125
- obj.respond_to?(:x) ? obj.mongoize : obj
154
+ case obj
155
+ when Point then obj.mongoize
156
+ else obj
157
+ end
126
158
  end
127
159
 
128
160
  private
@@ -151,9 +183,9 @@ module Mongoid
151
183
  #
152
184
  # @return (Array)
153
185
  #
154
- def from_array(ary)
155
- return nil if ary.empty?
156
- ary.flatten[0..1].map(&:to_f)
186
+ def from_array(array)
187
+ return nil if array.empty?
188
+ array.flatten[0..1].map(&:to_f)
157
189
  end
158
190
 
159
191
  #
@@ -1,5 +1,6 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
+ #
3
4
  #
4
5
  # Main Geometry Array
5
6
  #
@@ -8,8 +9,12 @@ module Mongoid
8
9
  #
9
10
  class GeometryField < Array
10
11
  #
11
- # Determines the multi point geometry bounding box.
12
+ #
13
+ # Determines the 2 points geometry bounding box.
12
14
  # Useful to find map boundaries, and fit to screen.
15
+ # Returns [bottom left, top right]
16
+ #
17
+ # @return [Array] containing 2 points
13
18
  #
14
19
  def bounding_box
15
20
  max_x, min_x = -Float::MAX, Float::MAX
@@ -24,10 +29,26 @@ module Mongoid
24
29
  end
25
30
  alias_method :bbox, :bounding_box
26
31
 
32
+ #
33
+ # Determines the 5 points geometry bounding box.
34
+ # Useful to use with Mongoid #within_geometry
35
+ #
36
+ # Returns a closed ring:
37
+ # [bottom left, top left, top right, bottom right, bottom left]
38
+ #
39
+ # @return [Array] containing 5 points
40
+ #
41
+ def geom_box
42
+ xl, yl = bounding_box
43
+ [xl, [xl[0], yl[1]], yl, [yl[0], xl[1]], xl]
44
+ end
45
+
27
46
  #
28
47
  # Determines the center point of a multi point geometry.
29
48
  # Geometry may be closed or not.
30
49
  #
50
+ # @return [Array] containing 1 point [x,y]
51
+ #
31
52
  def center_point
32
53
  min, max = *bbox
33
54
  [(min[0] + max[0]) / 2.0, (min[1] + max[1]) / 2.0]
@@ -39,6 +60,7 @@ module Mongoid
39
60
  #
40
61
  # @param [Numeric] r radius
41
62
  # @return [Array] [point, r] point and radius in mongoid format
63
+ #
42
64
  def radius(r = 1)
43
65
  [center, r]
44
66
  end
@@ -49,7 +71,7 @@ module Mongoid
49
71
  # point.radius(x) -> [point, x / earth radius]
50
72
  #
51
73
  # @see Point#radius
52
- # @return (Float)
74
+ # @return [Array]
53
75
  #
54
76
  def radius_sphere(r = 1, unit = :km)
55
77
  radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
@@ -59,6 +81,7 @@ module Mongoid
59
81
  #
60
82
  # Database -> Object
61
83
  #
84
+ # @return [Object]
62
85
  def demongoize(obj)
63
86
  obj && new(obj)
64
87
  end
@@ -18,11 +18,15 @@ Mongoid::Fields.option :delegate do |model, field, options|
18
18
  end
19
19
 
20
20
  define_method "#{x_meth}=" do |arg|
21
- self[field.name][0] = arg
21
+ # HACK: Mongoid has detecting an Array changed
22
+ # self[field.name][0] = arg
23
+ send("#{field.name}=", [arg, self[field.name][1]])
22
24
  end
23
25
 
24
26
  define_method "#{y_meth}=" do |arg|
25
- self[field.name][1] = arg
27
+ # self[field.name][1] = arg
28
+ # self[field.name] = [self[field.name][0], arg]
29
+ send("#{field.name}=", [self[field.name][0], arg])
26
30
  end
27
31
  end
28
32
  end
@@ -1,6 +1,6 @@
1
1
  module Mongoid
2
2
  # Mongoid Geospatial version
3
3
  module Geospatial
4
- VERSION = '4.0.1'
4
+ VERSION = '5.0.0'
5
5
  end
6
6
  end
@@ -1,6 +1,10 @@
1
1
  require 'geo_ruby'
2
2
 
3
3
  module Mongoid
4
+ #
5
+ # Wrappers for GeoRuby
6
+ # https://github.com/nofxx/georuby
7
+ #
4
8
  module Geospatial
5
9
  # Wrapper to GeoRuby's Point
6
10
  Point.class_eval do
@@ -2,6 +2,10 @@ require 'rgeo'
2
2
  require 'mongoid/geospatial/ext/rgeo_spherical_point_impl'
3
3
 
4
4
  module Mongoid
5
+ #
6
+ # Wrappers for RGeo
7
+ # https://github.com/rgeo/rgeo
8
+ #
5
9
  module Geospatial
6
10
  # Wrapper to Rgeo's Point
7
11
  Point.class_eval do
@@ -24,7 +28,6 @@ module Mongoid
24
28
 
25
29
  # Rgeo's GeometryField concept
26
30
  GeometryField.class_eval do
27
-
28
31
  def points
29
32
  map do |pair|
30
33
  RGeo::Geographic.spherical_factory.point(*pair)
@@ -4,8 +4,8 @@ require File.expand_path('../lib/mongoid/geospatial/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ['Ryan Ong', 'Marcos Piccinini']
6
6
  gem.email = ['use@git.hub.com']
7
- gem.description = 'Mongoid Extension that simplifies MongoDB casting and operations on spatial Ruby objects.'
8
7
  gem.summary = 'Mongoid Extension that simplifies MongoDB Geospatial Operations.'
8
+ gem.description = 'Mongoid Extension that simplifies MongoDB casting and operations on spatial Ruby objects.'
9
9
  gem.homepage = 'https://github.com/nofxx/mongoid-geospatial'
10
10
 
11
11
  gem.files = `git ls-files`.split("\n")
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
15
15
  gem.version = Mongoid::Geospatial::VERSION
16
16
  gem.license = 'MIT'
17
17
 
18
- gem.add_dependency('mongoid', ['>= 4.0.0'])
18
+ gem.add_dependency('mongoid', ['>= 5.0.0.beta'])
19
19
  end
@@ -5,7 +5,7 @@ class Bar
5
5
 
6
6
  field :name, type: String
7
7
 
8
- geo_field :location
8
+ field :location, type: Point, spatial: true
9
9
 
10
10
  has_one :rating, as: :ratable
11
11
 
@@ -4,7 +4,7 @@ class Farm
4
4
  include Mongoid::Geospatial
5
5
 
6
6
  field :name, type: String
7
- field :geom, type: Point, spatial: true
7
+ field :geom, type: Point, sphere: true
8
8
  field :area, type: Polygon, spatial: true
9
9
  field :m2, type: Fixnum
10
10
 
@@ -26,7 +26,8 @@ class Person
26
26
  field :employer_id
27
27
  field :security_code
28
28
  field :blood_alcohol_content, type: Float, default: -> { 0.0 }
29
- field :last_drink_taken_at, type: Date, default: -> { 1.day.ago.in_time_zone('Alaska') }
29
+ field :last_drink_taken_at, type: Date,
30
+ default: -> { 1.day.ago.in_time_zone('Alaska') }
30
31
 
31
32
  # Geo
32
33
  field :location, type: Point
@@ -3,14 +3,14 @@ class River
3
3
  include Mongoid::Document
4
4
  include Mongoid::Geospatial
5
5
 
6
- field :name, type: String
7
- field :length, type: Integer
8
- field :discharge, type: Integer
9
- field :course, type: LineString, spatial: true
6
+ field :name, type: String
7
+ field :length, type: Integer
8
+ field :discharge, type: Integer
9
+ field :course, type: LineString, spatial: true
10
10
  # set return_array to true if you do not want a hash returned all the time
11
- field :source, type: Point, spatial: true
12
- field :mouth, type: Point, spatial: { lat: 'latitude', lng: 'longitude' }
13
- field :mouth_array, type: Array, spatial: { return_array: true }
11
+ field :source, type: Point, spatial: true
12
+ field :mouth, type: Point, spatial: { lat: 'latitude', lng: 'longitude' }
13
+ field :mouth_array, type: Array, spatial: { return_array: true }
14
14
 
15
15
  # simplified spatial indexing
16
16
  # you can only index one field in mongodb < 1.9