mongoid_geospatial 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f481eb153c311039d3c9ab431dd181481b51a97b
4
- data.tar.gz: 3d1fa8021e6b79c79e85463a468ea865e53cdd99
3
+ metadata.gz: 21d6d74c13e2891b09aa7aeffa7b6fa6399d9d48
4
+ data.tar.gz: ac5e8cd42381ebce08dc3db81f43abcecea37db0
5
5
  SHA512:
6
- metadata.gz: bc40ac5a0f57a48a1d83c4c940b86ca381252aafa17b2eb90a1943fc27303007230e66a3ff1b98420735dadfc5b58f0d1e2478c58c1e58c7d73b66e3f5a8e433
7
- data.tar.gz: d5264c6beec42461c03d803892b2b46270e17e9bdbdd6f9f160cdcabc9cd2230d162bfbf39f59889b4b809e6d52da67247ad7346a1ee12e3ceac874d62cd6dab
6
+ metadata.gz: 9eb99f91d65bd9ff57b4047deeedcd0853b86412fa98906703f1a3e90e7752f9642a2a490de19ef312931647bbc37abe76c40cd6c9cf5d45eb908daa3179d36d
7
+ data.tar.gz: b78d364526ccd9a4da0ec39863c70b5ee1129c9813e2e7c75fab5c23ce6afb5a92744d374b9ca388cb44d28b4912acf0e5574debb351743d1a56e3d3aa365cb3
@@ -2,8 +2,6 @@ require 'mongoid'
2
2
  require 'active_support/core_ext/string/inflections'
3
3
  require 'active_support/concern'
4
4
  require 'mongoid_geospatial/geospatial'
5
- require 'mongoid_geospatial/extensions/rgeo_spherical_point_impl'
6
- require 'mongoid_geospatial/helpers/core'
7
5
  require 'mongoid_geospatial/helpers/spatial'
8
6
  require 'mongoid_geospatial/helpers/sphere'
9
7
  require 'mongoid_geospatial/helpers/delegate'
@@ -3,7 +3,7 @@ module RGeo
3
3
  # RGeo Point
4
4
  class SphericalPointImpl
5
5
 
6
- def mongoize
6
+ def to_xy
7
7
  [x, y]
8
8
  end
9
9
 
@@ -1,7 +1,6 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
3
  class Box < GeometryField
4
-
5
4
  end
6
5
  end
7
6
  end
@@ -1,12 +1,14 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
+ # Circle
4
+ #
3
5
  class Circle < GeometryField
4
6
  attr_accessor :center, :radius
5
7
 
6
8
  def point
7
9
  Point.new(self[0])
8
10
  end
9
- alias :point :center
11
+ alias_method :point, :center
10
12
 
11
13
  def radius
12
14
  self[1]
@@ -1,5 +1,7 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
+ # Main Geometry Array
4
+ # Holds Lines/Polygons....
3
5
  class GeometryField < Array
4
6
 
5
7
  def bounding_box
@@ -13,32 +15,30 @@ module Mongoid
13
15
  end
14
16
  [[min_x, min_y], [max_x, max_y]]
15
17
  end
16
- alias :bbox :bounding_box
18
+ alias_method :bbox, :bounding_box
17
19
 
18
20
  def center_point
19
21
  min, max = *bbox
20
22
  [(min[0] + max[0]) / 2.0, (min[1] + max[1]) / 2.0]
21
23
  end
22
- alias :center :center_point
24
+ alias_method :center, :center_point
23
25
 
24
- def radius r = 1
26
+ def radius(r = 1)
25
27
  [center, r]
26
28
  end
27
29
 
28
- def radius_sphere r = 1, unit = :km
29
- radius r.to_f/Mongoid::Geospatial.earth_radius[unit]
30
+ def radius_sphere(r = 1, unit = :km)
31
+ radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
30
32
  end
31
33
 
32
-
33
34
  class << self
34
35
 
35
36
  # Database -> Object
36
37
  def demongoize(o)
37
- self.new(o)
38
+ new(o)
38
39
  end
39
40
 
40
41
  end
41
-
42
42
  end
43
43
  end
44
44
  end
@@ -1,21 +1,24 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
+ # Point
4
+ #
3
5
  class Point
4
6
  include Enumerable
5
7
  attr_reader :x, :y
6
8
 
7
9
  def initialize(x = nil, y = nil)
8
- return unless x
9
- ll = y ? [x, y] : x.split(/,|\s/).reject(&:empty?)
10
- @x, @y = ll.map(&:to_f)
10
+ return unless x && y
11
+ @x, @y = x, y
11
12
  end
12
13
 
13
14
  # Object -> Database
15
+ # Let's store NilClass if we are invalid.
14
16
  def mongoize
17
+ return nil unless x && y
15
18
  [x, y]
16
19
  end
17
- alias :to_a :mongoize
18
- alias :to_xy :mongoize
20
+ alias_method :to_a, :mongoize
21
+ alias_method :to_xy, :mongoize
19
22
 
20
23
  def [](args)
21
24
  mongoize[args]
@@ -30,44 +33,88 @@ module Mongoid
30
33
  "#{x}, #{y}"
31
34
  end
32
35
 
33
- def to_hsh xl = :x, yl = :y
34
- {xl => x, yl => y}
36
+ def to_hsh(xl = :x, yl = :y)
37
+ { xl => x, yl => y }
35
38
  end
36
- alias :to_hash :to_hsh
39
+ alias_method :to_hash, :to_hsh
37
40
 
38
- def radius r = 1
41
+ def radius(r = 1)
39
42
  [mongoize, r]
40
43
  end
41
44
 
42
- def radius_sphere r = 1, unit = :km
43
- radius r.to_f/Mongoid::Geospatial.earth_radius[unit]
45
+ def radius_sphere(r = 1, unit = :km)
46
+ radius r.to_f / Mongoid::Geospatial.earth_radius[unit]
47
+ end
48
+
49
+ def valid?
50
+ x && y && x.is_a?(Numeric) && y.is_a?(Numeric)
44
51
  end
45
52
 
46
53
  #
47
54
  # Distance calculation methods. Thinking about not using it
48
55
  # One needs to choose and external lib. GeoRuby or RGeo
49
56
  #
50
- # #Return the distance between the 2D points (ie taking care only of the x and y coordinates), assuming
51
- # #the points are in projected coordinates. Euclidian distance in whatever unit the x and y ordinates are.
57
+ # Return the distance between the 2D points (ie taking care
58
+ # only of the x and y coordinates), assuming the points are
59
+ # in projected coordinates. Euclidian distance in whatever
60
+ # unit the x and y ordinates are.
52
61
  # def euclidian_distance(point)
53
62
  # Math.sqrt((point.x - x)**2 + (point.y - y)**2)
54
63
  # end
55
64
 
56
65
  # # Spherical distance in meters, using 'Haversine' formula.
57
66
  # # with a radius of 6471000m
58
- # # Assumes x is the lon and y the lat, in degrees (Changed in version 1.1).
59
- # # The user has to make sure using this distance makes sense (ie she should be in latlon coordinates)
67
+ # # Assumes x is the lon and y the lat, in degrees (Changed
68
+ # in version 1.1).
69
+ # # The user has to make sure using this distance makes sense
70
+ # (ie she should be in latlon coordinates)
60
71
  # def spherical_distance(point,r=6370997.0)
61
72
  # dlat = (point.lat - lat) * DEG2RAD / 2
62
73
  # dlon = (point.lon - lon) * DEG2RAD / 2
63
74
 
64
- # a = Math.sin(dlat)**2 + Math.cos(lat * DEG2RAD) * Math.cos(point.lat * DEG2RAD) * Math.sin(dlon)**2
75
+ # a = Math.sin(dlat)**2 + Math.cos(lat * DEG2RAD) *
76
+ # Math.cos(point.lat * DEG2RAD) * Math.sin(dlon)**2
65
77
  # c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
66
78
  # r * c
67
79
  # end
68
80
 
69
81
  class << self
70
82
 
83
+ # Makes life easier:
84
+ # "" -> nil
85
+ def from_string(str)
86
+ return nil if str.empty?
87
+ str.split(/,|\s/).reject(&:empty?).map(&:to_f)
88
+ end
89
+
90
+ # Also makes life easier:
91
+ # [] -> nil
92
+ def from_array(ary)
93
+ return nil if ary.empty?
94
+ ary[0..1].map(&:to_f)
95
+ end
96
+
97
+ # Throw error on wrong hash, just for a change.
98
+ def from_hash(hsh)
99
+ fail "Hash must have at least 2 items" if hsh.size < 2
100
+ [from_hash_x(hsh), from_hash_y(hsh)]
101
+ end
102
+
103
+ def from_hash_y(hsh)
104
+ v = (Mongoid::Geospatial.lat_symbols & hsh.keys).first
105
+ return hsh[v].to_f if !v.nil? && hsh[v]
106
+ fail "Hash must contain #{Mongoid::Geospatial.lat_symbols.inspect} if Ruby version is less than 1.9" if RUBY_VERSION.to_f < 1.9
107
+ fail "Hash cannot contain #{Mongoid::Geospatial.lng_symbols.inspect} as the second item if there is no #{Mongoid::Geospatial.lat_symbols.inspect}" if Mongoid::Geospatial.lng_symbols.index(hsh.keys[1])
108
+ hsh.values[1].to_f
109
+ end
110
+
111
+ def from_hash_x(hsh)
112
+ v = (Mongoid::Geospatial.lng_symbols & hsh.keys).first
113
+ return hsh[v].to_f if !v.nil? && hsh[v]
114
+ fail "Hash cannot contain #{Mongoid::Geospatial.lat_symbols.inspect} as the first item if there is no #{Mongoid::Geospatial.lng_symbols.inspect}" if Mongoid::Geospatial.lat_symbols.index(keys[0])
115
+ values[0].to_f
116
+ end
117
+
71
118
  # Database -> Object
72
119
  def demongoize(object)
73
120
  Point.new(*object) if object
@@ -75,10 +122,14 @@ module Mongoid
75
122
 
76
123
  def mongoize(object)
77
124
  case object
78
- when Point then object.mongoize
79
- when Array then Geospatial.from_array(object)
80
- when Hash then Geospatial.from_hash(object)
81
- else object.mongoize
125
+ when Point then object.mongoize
126
+ when String then from_string(object)
127
+ when Array then from_array(object)
128
+ when Hash then from_hash(object)
129
+ when NilClass then nil
130
+ else
131
+ return object.to_xy if object.respond_to?(:to_xy)
132
+ fail 'Invalid Point'
82
133
  end
83
134
  end
84
135
 
@@ -87,8 +138,9 @@ module Mongoid
87
138
  def evolve(object)
88
139
  object.respond_to?(:x) ? object.mongoize : object
89
140
  end
90
- end
91
141
 
92
- end
93
- end
94
- end
142
+ end # << self
143
+
144
+ end # Point
145
+ end # Geospatial
146
+ end # Mongoid
@@ -1,7 +1,6 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
3
  class Polygon < GeometryField
4
-
5
4
  end
6
5
  end
7
6
  end
@@ -12,7 +12,7 @@ module Mongoid
12
12
  :km => EARTH_RADIUS_KM,
13
13
  :m => EARTH_RADIUS_KM * 1000,
14
14
  :mi => EARTH_RADIUS_KM * 0.621371192, # taken directly from mongodb
15
- :ft => EARTH_RADIUS_KM * 5280*0.621371192,
15
+ :ft => EARTH_RADIUS_KM * 5280 * 0.621371192,
16
16
  :sm => EARTH_RADIUS_KM * 0.53995680345572 # sea mile
17
17
  }
18
18
 
@@ -41,6 +41,7 @@ module Mongoid
41
41
  end
42
42
 
43
43
  module ClassMethods #:nodoc:
44
+
44
45
  def geo_field name, options = {}
45
46
  field name, {type: Mongoid::Geospatial::Point, spatial: true}.merge(options)
46
47
  end
@@ -51,15 +52,15 @@ module Mongoid
51
52
  # http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-geoNearCommand
52
53
  def spatial_index name, options = {}
53
54
  self.spatial_fields_indexed << name
54
- index({name => '2d'}, options)
55
+ index({ name => '2d' }, options)
55
56
  end
56
57
 
57
- def sphere_index name, options = {}
58
+ def sphere_index(name, options = {})
58
59
  self.spatial_fields_indexed << name
59
- index({name => '2dsphere'}, options)
60
+ index({ name => '2dsphere' }, options)
60
61
  end
61
62
 
62
- def spatial_scope field, opts = {}
63
+ def spatial_scope(field, opts = {})
63
64
  self.singleton_class.class_eval do
64
65
  # define_method(:close) do |args|
65
66
  define_method(:nearby) do |args|
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module Geospatial
3
- VERSION = "3.0.0"
3
+ VERSION = "3.1.0"
4
4
  end
5
5
  end
@@ -1,5 +1,4 @@
1
1
  require 'geo_ruby'
2
- require 'mongoid_geospatial/extensions/georuby_point'
3
2
 
4
3
  module Mongoid
5
4
  module Geospatial
@@ -8,10 +7,11 @@ module Mongoid
8
7
  delegate :distance, :to => :to_geo
9
8
 
10
9
  def to_geo
10
+ return unless valid?
11
11
  GeoRuby::SimpleFeatures::Point.xy(x, y)
12
12
  end
13
13
 
14
- def geo_distance other
14
+ def geo_distance(other)
15
15
  to_geo.spherical_distance(other.to_geo)
16
16
  end
17
17
 
@@ -1,5 +1,5 @@
1
1
  require 'rgeo'
2
- require 'mongoid_geospatial/extensions/rgeo_spherical_point_impl'
2
+ require 'mongoid_geospatial/ext/rgeo_spherical_point_impl'
3
3
 
4
4
  module Mongoid
5
5
  module Geospatial
@@ -21,19 +21,19 @@ describe Mongoid::Geospatial::Point do
21
21
 
22
22
  it "should set point with comma separated text" do
23
23
  bar = Bar.create!(name: "Moe's", location: Mongoid::Geospatial::Point.new)
24
- bar.location = Mongoid::Geospatial::Point.new("2.99,3.99")
24
+ bar.location = "2.99,3.99"
25
25
  bar.location.mongoize.should eq([2.99, 3.99])
26
26
  end
27
27
 
28
28
  it "should set point with space separated text" do
29
29
  bar = Bar.create!(name: "Moe's", location: Mongoid::Geospatial::Point.new)
30
- bar.location = Mongoid::Geospatial::Point.new("2.99 3.99")
30
+ bar.location = "2.99 3.99"
31
31
  bar.location.mongoize.should eq([2.99, 3.99])
32
32
  end
33
33
 
34
34
  it "should set point with space comma separated text" do
35
35
  bar = Bar.create!(name: "Moe's", location: Mongoid::Geospatial::Point.new)
36
- bar.location = Mongoid::Geospatial::Point.new("2.99 , 3.99")
36
+ bar.location = "2.99 , 3.99"
37
37
  bar.location.mongoize.should eq([2.99, 3.99])
38
38
  end
39
39
 
@@ -42,7 +42,23 @@ describe Mongoid::Geospatial::Point do
42
42
  bar.location = nil
43
43
  bar.location.should be_nil
44
44
  bar.save.should be_true
45
- Bar.first.location.should be_nil
45
+ Bar.where(location: nil).first.should eq(bar)
46
+ end
47
+
48
+ it "should set point empty string to nil" do
49
+ bar = Bar.create!(name: "Moe's", location: [1, 1])
50
+ bar.location = ""
51
+ bar.location.should be_nil
52
+ bar.save.should be_true
53
+ Bar.where(location: nil).first.should eq(bar)
54
+ end
55
+
56
+ it "should set point empty array to nil" do
57
+ bar = Bar.create!(name: "Moe's", location: [1, 1])
58
+ bar.location = []
59
+ bar.location.should be_nil
60
+ bar.save.should be_true
61
+ Bar.where(location: nil).first.should eq(bar)
46
62
  end
47
63
 
48
64
  describe "methods" do
@@ -20,7 +20,6 @@ describe Mongoid::Geospatial::Point do
20
20
  bar.location.should_not respond_to(:distance)
21
21
  end
22
22
 
23
-
24
23
  describe "queryable" do
25
24
 
26
25
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_geospatial
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ong
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-06 00:00:00.000000000 Z
12
+ date: 2013-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongoid
@@ -70,8 +70,7 @@ files:
70
70
  - README.md
71
71
  - Rakefile
72
72
  - lib/mongoid_geospatial.rb
73
- - lib/mongoid_geospatial/extensions/georuby_point.rb
74
- - lib/mongoid_geospatial/extensions/rgeo_spherical_point_impl.rb
73
+ - lib/mongoid_geospatial/ext/rgeo_spherical_point_impl.rb
75
74
  - lib/mongoid_geospatial/fields/box.rb
76
75
  - lib/mongoid_geospatial/fields/circle.rb
77
76
  - lib/mongoid_geospatial/fields/geometry_field.rb
@@ -79,7 +78,6 @@ files:
79
78
  - lib/mongoid_geospatial/fields/point.rb
80
79
  - lib/mongoid_geospatial/fields/polygon.rb
81
80
  - lib/mongoid_geospatial/geospatial.rb
82
- - lib/mongoid_geospatial/helpers/core.rb
83
81
  - lib/mongoid_geospatial/helpers/delegate.rb
84
82
  - lib/mongoid_geospatial/helpers/spatial.rb
85
83
  - lib/mongoid_geospatial/helpers/sphere.rb
@@ -1,12 +0,0 @@
1
- module GeoRuby
2
- module SimpleFeatures
3
- # GeoRuby Point
4
- class Point
5
-
6
- def mongoize
7
- [x, y]
8
- end
9
-
10
- end
11
- end
12
- end
@@ -1,28 +0,0 @@
1
- module Mongoid
2
- module Geospatial
3
-
4
- def self.from_array(ary)
5
- ary[0..1].map(&:to_f)
6
- end
7
-
8
- def self.from_hash(hsh)
9
- raise "Hash must have at least 2 items" if hsh.size < 2
10
- [from_hash_x(hsh), from_hash_y(hsh)]
11
- end
12
-
13
- def self.from_hash_y(hsh)
14
- v = (Mongoid::Geospatial.lat_symbols & hsh.keys).first
15
- return hsh[v].to_f if !v.nil? && hsh[v]
16
- fail "Hash must contain #{Mongoid::Geospatial.lat_symbols.inspect} if ruby version is less than 1.9" if RUBY_VERSION.to_f < 1.9
17
- fail "Hash cannot contain #{Mongoid::Geospatial.lng_symbols.inspect} as the second item if there is no #{Mongoid::Geospatial.lat_symbols.inspect}" if Mongoid::Geospatial.lng_symbols.index(hsh.keys[1])
18
- hsh.values[1].to_f
19
- end
20
-
21
- def self.from_hash_x(hsh)
22
- v = (Mongoid::Geospatial.lng_symbols & hsh.keys).first
23
- return hsh[v].to_f if !v.nil? && hsh[v]
24
- fail "Hash cannot contain #{Mongoid::Geospatial.lat_symbols.inspect} as the first item if there is no #{Mongoid::Geospatial.lng_symbols.inspect}" if Mongoid::Geospatial.lat_symbols.index(keys[0])
25
- values[0].to_f
26
- end
27
- end
28
- end