mongoid-geospatial 5.1.0 → 7.1.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -65
  3. data/lib/mongoid/geospatial/config/point.rb +5 -2
  4. data/lib/mongoid/geospatial/config.rb +2 -0
  5. data/lib/mongoid/geospatial/ext/rgeo_spherical_point_impl.rb +2 -0
  6. data/lib/mongoid/geospatial/fields/box.rb +2 -0
  7. data/lib/mongoid/geospatial/fields/circle.rb +2 -2
  8. data/lib/mongoid/geospatial/fields/line_string.rb +2 -0
  9. data/lib/mongoid/geospatial/fields/point.rb +28 -13
  10. data/lib/mongoid/geospatial/fields/polygon.rb +2 -0
  11. data/lib/mongoid/geospatial/geometry_field.rb +4 -2
  12. data/lib/mongoid/geospatial/helpers/delegate.rb +2 -0
  13. data/lib/mongoid/geospatial/helpers/spatial.rb +2 -0
  14. data/lib/mongoid/geospatial/helpers/sphere.rb +3 -1
  15. data/lib/mongoid/geospatial/version.rb +3 -1
  16. data/lib/mongoid/geospatial/wrappers/georuby.rb +2 -0
  17. data/lib/mongoid/geospatial/wrappers/rgeo.rb +2 -0
  18. data/lib/mongoid/geospatial.rb +234 -27
  19. metadata +7 -80
  20. data/.coveralls.yml +0 -1
  21. data/.gitignore +0 -49
  22. data/.hound.yml +0 -2
  23. data/.rspec +0 -3
  24. data/.rubocop.yml +0 -6
  25. data/.rubocop_todo.yml +0 -93
  26. data/.travis.yml +0 -33
  27. data/CHANGELOG.md +0 -19
  28. data/CONTRIBUTING.md +0 -118
  29. data/Dangerfile +0 -1
  30. data/Gemfile +0 -37
  31. data/Guardfile +0 -16
  32. data/RELEASING.md +0 -62
  33. data/Rakefile +0 -20
  34. data/bench/bench +0 -64
  35. data/mongoid-geospatial.gemspec +0 -18
  36. data/spec/models/address.rb +0 -69
  37. data/spec/models/alarm.rb +0 -12
  38. data/spec/models/bar.rb +0 -13
  39. data/spec/models/bus.rb +0 -12
  40. data/spec/models/event.rb +0 -18
  41. data/spec/models/farm.rb +0 -13
  42. data/spec/models/person.rb +0 -96
  43. data/spec/models/phone.rb +0 -8
  44. data/spec/models/place.rb +0 -13
  45. data/spec/models/river.rb +0 -22
  46. data/spec/mongoid/geospatial/config_spec.rb +0 -22
  47. data/spec/mongoid/geospatial/fields/box_spec.rb +0 -8
  48. data/spec/mongoid/geospatial/fields/circle_spec.rb +0 -8
  49. data/spec/mongoid/geospatial/fields/line_string_spec.rb +0 -79
  50. data/spec/mongoid/geospatial/fields/point_spec.rb +0 -269
  51. data/spec/mongoid/geospatial/fields/polygon_spec.rb +0 -87
  52. data/spec/mongoid/geospatial/geospatial_spec.rb +0 -150
  53. data/spec/mongoid/geospatial/helpers/core_spec.rb +0 -35
  54. data/spec/mongoid/geospatial/helpers/delegate_spec.rb +0 -67
  55. data/spec/mongoid/geospatial/helpers/spatial_spec.rb +0 -39
  56. data/spec/mongoid/geospatial/helpers/sphere_spec.rb +0 -29
  57. data/spec/mongoid/geospatial/wrappers/georuby_spec.rb +0 -63
  58. data/spec/mongoid/geospatial/wrappers/rgeo_spec.rb +0 -115
  59. data/spec/spec_helper.rb +0 -47
  60. data/spec/support/authentication.rb +0 -28
  61. data/spec/support/mongod.conf +0 -3
  62. data/spec/support/mongoid.yml +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c947554ea1c07198ca1c8b7c649ed93464fd1a08c6c71a2b2752e826344f049
4
- data.tar.gz: 49d2636d235a0b91671564db6807241a4600d40070089e3d2729dd598151b2d2
3
+ metadata.gz: 88d807a8e7011846e353f18fc6812fb55e578f371464c202fa726976c7fec6e6
4
+ data.tar.gz: 32f5124231bfe558a9a591520c90dda408f76995faa2030e67c39bee1e9f7b23
5
5
  SHA512:
6
- metadata.gz: 8da975f59a71106fc991043f1438f5c7c910e1e7c2cc78f7e112062bee9fc34a966ecf80a39ec423230805aa6756f0c01e5882085fb5e701618b0ec7d4d6b6f5
7
- data.tar.gz: 8c8c89eec0397d1a0e3bcae04ca972ef5b3aa82094d76b4b060c53c2bb6dbc4eb058bc80cfb0d9c5b5fbb7b217aaed973212b98193247c3cfe079fb5de67a489
6
+ metadata.gz: f8beb1650724d7b54d7a2a35d2376597144d9290360f2571da28681ef11d3e3e0792bf562f0c904f762b0abaf09d43b9f8c8f1747cb4d7753a5f187a6c6d04c5
7
+ data.tar.gz: b457c28c88ab87968e76eeb00afca6e376e37cf2432df230fc88260ab44b9984c9cd11708deba53eb19fa4a19d27175d63042c5b142762707fe3bd1019107652
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Mongoid Geospatial
2
- ==================
1
+ # Mongoid Geospatial
3
2
 
4
3
  A Mongoid Extension that simplifies the use of MongoDB spatial features.
5
4
 
@@ -8,8 +7,7 @@ A Mongoid Extension that simplifies the use of MongoDB spatial features.
8
7
  [![Coverage Status](https://coveralls.io/repos/github/mongoid/mongoid-geospatial/badge.svg?branch=master)](https://coveralls.io/github/mongoid/mongoid-geospatial?branch=master)
9
8
  [![Build Status](https://travis-ci.org/mongoid/mongoid-geospatial.svg?branch=master)](https://travis-ci.org/mongoid/mongoid-geospatial)
10
9
 
11
- Quick Start
12
- -----------
10
+ ## Quick Start
13
11
 
14
12
  This gem focuses on (making helpers for) MongoDB's spatial features using Mongoid 5, 6 and 7.
15
13
 
@@ -60,17 +58,16 @@ Or programatically:
60
58
  Place.create_indexes
61
59
  ```
62
60
 
63
- Points
64
- ------
61
+ ## Points
65
62
 
66
63
  This gem defines a specific `Point` class under the Mongoid::Geospatial namespace. Make sure to use `type: ::Mongoid::Geospatial::Point` to avoid name errors or collisions with other `Point` classes you might already have defined `NameError`s.
67
64
 
68
65
  Currently, MongoDB supports query operations on 2D points only, so that's what this lib does. All geometries apart from points are just arrays in the database. Here's is how you can input a point as:
69
66
 
70
- * longitude latitude array in that order - [long,lat] ([x, y])
71
- * an unordered hash with latitude key(:lat, :latitude) and a longitude key(:lon, :long, :lng, :longitude)
72
- * an ordered hash with longitude as the first item and latitude as the second item; this hash does not have include the latitude and longitude keys
73
- * anything with the a method #to_xy or #to_lng_lat that converts itself to [long, lat] array
67
+ - longitude latitude array in that order - [long,lat] ([x, y])
68
+ - an unordered hash with latitude key(:lat, :latitude) and a longitude key(:lon, :long, :lng, :longitude)
69
+ - an ordered hash with longitude as the first item and latitude as the second item; this hash does not have include the latitude and longitude keys
70
+ - anything with the a method #to_xy or #to_lng_lat that converts itself to [long, lat] array
74
71
 
75
72
  _Note: the convention of having longitude as the first coordinate may vary for other libraries. For instance, Google Maps often refer to "LatLng". Make sure you keep those differences in mind. See below for how to configure this library for LatLng._
76
73
 
@@ -131,8 +128,7 @@ house.area.bbox # Returns polygon bounding_box (envelope)
131
128
  house.area.center # Returns calculate middle point
132
129
  ```
133
130
 
134
- Model Setup
135
- -----------
131
+ ## Model Setup
136
132
 
137
133
  You can create Point, Line, Circle, Box and Polygon on your models:
138
134
 
@@ -157,8 +153,7 @@ class CrazyGeom
157
153
  end
158
154
  ```
159
155
 
160
- Helpers
161
- -------
156
+ ## Helpers
162
157
 
163
158
  You can use `spatial: true` to add a '2d' index automatically,
164
159
  No need for `spatial_index :location`:
@@ -181,29 +176,7 @@ field :location, type: Point, delegate: true
181
176
 
182
177
  Now instead of `instance.location.x` you may call `instance.x`.
183
178
 
184
- Nearby
185
- ------
186
-
187
- You can add a `spatial_scope` on your models. So you can query:
188
-
189
- ```ruby
190
- Bar.nearby(my.location)
191
- ```
192
-
193
- instead of
194
-
195
- ```ruby
196
- Bar.near(location: my.location)
197
- ```
198
-
199
- Good when you're drunk. Just add to your model:
200
-
201
- ```ruby
202
- spatial_scope :<field>
203
- ```
204
-
205
- Geometry
206
- --------
179
+ ## Geometry
207
180
 
208
181
  You can also store Circle, Box, Line (LineString) and Polygons.
209
182
  Some helper methods are available to them:
@@ -224,34 +197,84 @@ polygon.radius(5) # [[1.0, 1.0], 5]
224
197
  polygon.radius_sphere(5) # [[1.0, 1.0], 0.00048..]
225
198
  ```
226
199
 
227
- Query
228
- -----
229
-
230
- Before you proceed, make sure you have read this:
231
-
232
- http://mongoid.github.io/old/en/origin/docs/selection.html#standard
233
-
234
- All MongoDB queries are handled by Mongoid/Origin.
235
-
236
- http://www.rubydoc.info/github/mongoid/origin/Origin/Selectable
200
+ ## Query
237
201
 
238
202
  You can use Geometry instance directly on any query:
239
203
 
240
- * near
204
+ ### near
241
205
 
242
206
  ```ruby
243
207
  Bar.near(location: person.house)
244
208
  Bar.where(:location.near => person.house)
245
209
  ```
246
210
 
247
- * near_sphere
211
+ ### near_sphere
248
212
 
249
213
  ```ruby
250
214
  Bar.near_sphere(location: person.house)
251
215
  Bar.where(:location.near_sphere => person.house)
252
216
  ```
253
217
 
254
- * within_polygon
218
+ ### nearby
219
+
220
+ You can add a `spatial_scope` on your models. So you can query:
221
+
222
+ ```ruby
223
+ Bar.nearby(my.location)
224
+ ```
225
+
226
+ instead of
227
+
228
+ ```ruby
229
+ Bar.near(location: my.location)
230
+ ```
231
+
232
+ Good when you're drunk. Just add to your model:
233
+
234
+ ```ruby
235
+ spatial_scope :<field>
236
+ ```
237
+
238
+ ### geo_near
239
+
240
+ The `geo_near` class method provides a more powerful way to query for documents based on proximity,
241
+ using MongoDB's `$geoNear` aggregation pipeline stage. This method allows for more complex
242
+ options and returns the distance to each matched document.
243
+
244
+ ```ruby
245
+ # Find places near [10, 20], using spherical calculations, up to 5km away,
246
+ # and get the distance.
247
+ # The :distanceField option specifies the name of the field that will contain the distance.
248
+ # The :limit option is applied as a separate $limit stage in the aggregation.
249
+ Place.geo_near(:location, [10, 20],
250
+ spherical: true,
251
+ maxDistance: 5000, # 5 kilometers in meters for spherical queries
252
+ distanceField: 'dist.calculated', # Default is 'distance'
253
+ query: { category: 'restaurant' }, # Optional: filter documents before geoNear
254
+ limit: 10)
255
+
256
+ # Iterate over results
257
+ Place.geo_near(:location, [10, 20], spherical: true).each do |place|
258
+ # 'place.distance' will be available if distanceField was 'distance' (the default)
259
+ # or 'place.dist_calculated' if distanceField was 'dist.calculated'
260
+ puts "#{place.name} is #{place.distance || place.dist_calculated} meters away."
261
+ end
262
+ ```
263
+
264
+ Key features and options for `geo_near`:
265
+
266
+ - `:spherical` (Boolean): If `true`, calculates distances using spherical geometry. Defaults to `false`.
267
+ - `:distanceField` (String): Name of the output field for the calculated distance. Defaults to `'distance'`.
268
+ - `:maxDistance` (Numeric): Maximum distance from the center point. (Meters for spherical, units of coordinates for planar).
269
+ - `:minDistance` (Numeric): Minimum distance from the center point.
270
+ - `:query` (Hash): A query to filter documents _before_ the `$geoNear` stage.
271
+ - `:limit` (Integer): Maximum number of documents to return (applied as a separate `$limit` stage).
272
+ - `:distanceMultiplier` (Numeric): A factor to multiply all distances.
273
+ - `:includeLocs` (String): Name of an output field that will contain the exact location on the document used for the distance calculation. Useful for multi-location fields or complex GeoJSON geometries.
274
+
275
+ The `geo_near` method returns an array of instantiated Mongoid documents, with the `distanceField` and `includeLocs` field (if specified) available as dynamic attributes on each model instance.
276
+
277
+ - within_polygon
255
278
 
256
279
  ```ruby
257
280
  Bar.within_polygon(location: [[[x,y],...[x,y]]])
@@ -259,13 +282,11 @@ Bar.within_polygon(location: [[[x,y],...[x,y]]])
259
282
  Bar.within_polygon(location: street.bbox)
260
283
  ```
261
284
 
262
- * intersects_line
263
- * intersects_point
264
- * intersects_polygon
265
-
285
+ - intersects_line
286
+ - intersects_point
287
+ - intersects_polygon
266
288
 
267
- External Libraries
268
- ------------------
289
+ ## External Libraries
269
290
 
270
291
  We currently support GeoRuby and RGeo.
271
292
  If you require one of those, a #to_geo and #to_rgeo, respectivelly,
@@ -338,8 +359,7 @@ end
338
359
 
339
360
  You will need to manually migrate any existing `Point` data if you change configuration in an existing system.
340
361
 
341
- This Fork
342
- ---------
362
+ ## This Fork
343
363
 
344
364
  This fork is not backwards compatible with 'mongoid_spacial'.
345
365
  This fork delegates calculations to external libs.
@@ -370,8 +390,7 @@ field :source, type: Point, spatial: true # or sphere: true
370
390
 
371
391
  Beware the 't' and 'c' issue. It's spaTial.
372
392
 
373
- Troubleshooting
374
- ---------------
393
+ ## Troubleshooting
375
394
 
376
395
  **Mongo::OperationFailure: can't find special index: 2d**
377
396
 
@@ -387,15 +406,12 @@ Programatically
387
406
  Model.create_indexes
388
407
  ```
389
408
 
390
- Contributing
391
- ------------
409
+ ## Contributing
392
410
 
393
411
  See [CONTRIBUTING](CONTRIBUTING.md).
394
412
 
395
- License
396
- -------
413
+ ## License
397
414
 
398
415
  Copyright (c) 2009-2017 Mongoid Geospatial Authors
399
416
 
400
417
  MIT License, see [MIT-LICENSE](MIT-LICENSE).
401
-
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  module Config
4
6
  module Point
5
7
  extend self
6
8
 
7
- attr_accessor :x
8
- attr_accessor :y
9
+ attr_accessor :x, :y
9
10
 
10
11
  def reset!
12
+ # Now self.x and self.y refer to the public module accessors
11
13
  self.x = Mongoid::Geospatial.lng_symbols
12
14
  self.y = Mongoid::Geospatial.lat_symbols
13
15
  end
14
16
 
17
+ # Initialize the configuration
15
18
  reset!
16
19
  end
17
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  module Config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RGeo
2
4
  module Geographic
3
5
  # RGeo Point
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  class Box < GeometryField
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  # Circle
4
6
  #
5
7
  class Circle < GeometryField
6
- attr_accessor :center, :radius
7
-
8
8
  def center
9
9
  Point.new(*self[0])
10
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  class LineString < GeometryField
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  # Point
@@ -6,10 +8,10 @@ module Mongoid
6
8
  include Enumerable
7
9
  attr_accessor :x, :y, :z
8
10
 
9
- def initialize(x, y, z = nil)
10
- @x = x
11
- @y = y
12
- @z = z
11
+ def initialize(lon, lat, alt = nil)
12
+ @x = lon
13
+ @y = lat
14
+ @z = alt
13
15
  end
14
16
 
15
17
  # Object -> Database
@@ -35,11 +37,12 @@ module Mongoid
35
37
 
36
38
  #
37
39
  # Point representation as a Hash
40
+ # Optional param: custom keys.
38
41
  #
39
- # @return [Hash] with { xl => x, yl => y }
42
+ # @return [Hash] with { lng_key => x, lat_key => y }
40
43
  #
41
- def to_hsh(xl = :x, yl = :y)
42
- { xl => x, yl => y }
44
+ def to_hsh(xkey = :x, ykey = :y)
45
+ { xkey => x, ykey => y }
43
46
  end
44
47
  alias to_hash to_hsh
45
48
 
@@ -48,7 +51,7 @@ module Mongoid
48
51
  #
49
52
  # @return [Array] with [self, radius]
50
53
  #
51
- def radius(r = 1)
54
+ def radius(r = 1) # rubocop:disable Naming/MethodParameterName
52
55
  [mongoize, r]
53
56
  end
54
57
 
@@ -59,7 +62,7 @@ module Mongoid
59
62
  #
60
63
  # @return [Array] with [self, radius / earth radius]
61
64
  #
62
- def radius_sphere(r = 1, unit = :km)
65
+ def radius_sphere(r = 1, unit = :km) # rubocop:disable Naming/MethodParameterName
63
66
  radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
64
67
  end
65
68
 
@@ -85,6 +88,18 @@ module Mongoid
85
88
  "#{x}, #{y}"
86
89
  end
87
90
 
91
+ #
92
+ # Point definition as GeoJSON
93
+ #
94
+ # "x, y"
95
+ #
96
+ # @return [String] Point as comma separated String
97
+ #
98
+ def to_geo_json
99
+ # Return a GeoJSON point hash that MongoDB can use
100
+ { type: 'Point', coordinates: [x, y] }
101
+ end
102
+
88
103
  #
89
104
  # Point inverse/reverse
90
105
  #
@@ -225,7 +240,7 @@ module Mongoid
225
240
 
226
241
  raise "Hash must contain #{Mongoid::Geospatial::Config::Point.x.inspect}"
227
242
  end
228
- end # << self
229
- end # Point
230
- end # Geospatial
231
- end # Mongoid
243
+ end
244
+ end
245
+ end
246
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  class Polygon < GeometryField
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  module Geospatial
3
5
  #
@@ -63,7 +65,7 @@ module Mongoid
63
65
  # @param [Numeric] r radius
64
66
  # @return [Array] [point, r] point and radius in mongoid format
65
67
  #
66
- def radius(r = 1)
68
+ def radius(r = 1) # rubocop:disable Naming/MethodParameterName
67
69
  [center, r]
68
70
  end
69
71
 
@@ -75,7 +77,7 @@ module Mongoid
75
77
  # @see Point#radius
76
78
  # @return [Array]
77
79
  #
78
- def radius_sphere(r = 1, unit = :km)
80
+ def radius_sphere(r = 1, unit = :km) # rubocop:disable Naming/MethodParameterName
79
81
  radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
80
82
  end
81
83
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Mongoid fields extension
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Mongoid fields extension
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Mongoid fields extension
3
5
  #
@@ -11,6 +13,6 @@ Mongoid::Fields.option :sphere do |model, field, _options|
11
13
  spatial_fields_indexed << field.name.to_sym
12
14
 
13
15
  # Create 2Dsphere index
14
- sphere_index field.name
16
+ spherical_index field.name
15
17
  end
16
18
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mongoid
2
4
  # Mongoid Geospatial version
3
5
  module Geospatial
4
- VERSION = '5.1.0'.freeze
6
+ VERSION = '7.1.0'
5
7
  end
6
8
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'geo_ruby'
2
4
 
3
5
  module Mongoid
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rgeo'
2
4
  require 'mongoid/geospatial/ext/rgeo_spherical_point_impl'
3
5