Class: Mongoid::Geospatial::Point

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/mongoid/geospatial/fields/point.rb

Overview

Point

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lon, lat, alt = nil) ⇒ Point

Returns a new instance of Point.



18
19
20
21
22
# File 'lib/mongoid/geospatial/fields/point.rb', line 18

def initialize(lon, lat, alt = nil)
  @x = lon
  @y = lat
  @z = alt
end

Instance Attribute Details

#x ⇒ Object Also known as: lng, lon

Returns the value of attribute x.



10
11
12
# File 'lib/mongoid/geospatial/fields/point.rb', line 10

def x
  @x
end

#y ⇒ Object Also known as: lat

Returns the value of attribute y.



10
11
12
# File 'lib/mongoid/geospatial/fields/point.rb', line 10

def y
  @y
end

#z ⇒ Object

Returns the value of attribute z.



10
11
12
# File 'lib/mongoid/geospatial/fields/point.rb', line 10

def z
  @z
end

Class Method Details

.demongoize(obj) ⇒ Object

Database -> Object Get it back



170
171
172
# File 'lib/mongoid/geospatial/fields/point.rb', line 170

def demongoize(obj)
  obj && new(*obj)
end

.evolve(obj) ⇒ Object

Converts the object that was supplied to a criteria into a database friendly form.



193
194
195
196
197
198
# File 'lib/mongoid/geospatial/fields/point.rb', line 193

def evolve(obj)
  case obj
  when Point then obj.mongoize
  else obj
  end
end

.mongoize(obj) ⇒ Object

Object -> Database Send it to MongoDB



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mongoid/geospatial/fields/point.rb', line 177

def mongoize(obj)
  case obj
  when Point  then obj.mongoize
  when String then from_string(obj)
  when Array  then from_array(obj)
  when Hash   then from_hash(obj)
  when NilClass then nil
  else
    return obj.to_xy if obj.respond_to?(:to_xy)

    raise 'Invalid Point'
  end
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Two points are the same spot when they hold the same pair. Without this, == was object identity (Enumerable does not bring one), so a point loaded twice never equalled itself: place.geom == city.geom was false for the very same [x, y]. Only a Point equals a Point — to_a is the door to compare with an Array. z is not stored (see #mongoize), so it does not take part.



43
44
45
# File 'lib/mongoid/geospatial/fields/point.rb', line 43

def ==(other)
  other.is_a?(Point) && mongoize == other.mongoize
end

#[](args) ⇒ Object

Raises:

  • (ArgumentError)


50
51
52
53
54
# File 'lib/mongoid/geospatial/fields/point.rb', line 50

def [](args)
  raise ArgumentError, "Invalid point: #{inspect}" unless (pair = mongoize)

  pair[args]
end

#distance(other, unit = :km) ⇒ Object

Crow-flies distance. Haversine, Mongo's earth radius (6371 km). RGeo/GeoRuby still win for projections; this is ETA and "how far".

Raises:

  • (ArgumentError)


153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/mongoid/geospatial/fields/point.rb', line 153

def distance(other, unit = :km) # rubocop:disable Metrics/AbcSize
  xy = other.is_a?(Point) ? [other.x, other.y] : self.class.mongoize(other)
  raise ArgumentError, "Invalid point: #{other.inspect}" unless xy&.size == 2

  dlat = (xy[1] - y) * RAD_PER_DEG
  dlon = (xy[0] - x) * RAD_PER_DEG
  a = (Math.sin(dlat / 2)**2) +
      (Math.cos(y * RAD_PER_DEG) * Math.cos(xy[1] * RAD_PER_DEG) *
       (Math.sin(dlon / 2)**2))
  c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
  Mongoid::Geospatial.earth_radius[unit] * c
end

#each {|x| ... } ⇒ Object

Yields:

  • (x)


56
57
58
59
# File 'lib/mongoid/geospatial/fields/point.rb', line 56

def each
  yield x
  yield y
end

#hash ⇒ Object



48
# File 'lib/mongoid/geospatial/fields/point.rb', line 48

def hash = [Point, mongoize].hash

#mongoize ⇒ Array

Object -> Database Let's store NilClass if we are invalid.

Returns:

  • (Array)


28
29
30
31
32
# File 'lib/mongoid/geospatial/fields/point.rb', line 28

def mongoize
  return nil unless x && y

  [x, y]
end

#radius(r = 1) ⇒ Array

Helper for [self, radius]

Returns:

  • (Array) —

    with [self, radius]



66
67
68
69
70
# File 'lib/mongoid/geospatial/fields/point.rb', line 66

def radius(r = 1) # rubocop:disable Naming/MethodParameterName
  return nil unless (pair = mongoize)

  [pair, r]
end

#radius_sphere(r = 1, unit = :km) ⇒ Array

Radius Sphere

Validates that #x & #y are Numeric

Returns:

  • (Array) —

    with [self, radius / earth radius]



79
80
81
# File 'lib/mongoid/geospatial/fields/point.rb', line 79

def radius_sphere(r = 1, unit = :km) # rubocop:disable Naming/MethodParameterName
  radius r.to_f / Mongoid::Geospatial.earth_radius.fetch(unit)
end

#reverse ⇒ Array

Point inverse/reverse

MongoDB: "x, y" Reverse: "y, x"

Returns:

  • (Array) —

    Point reversed: "y, x"



145
146
147
# File 'lib/mongoid/geospatial/fields/point.rb', line 145

def reverse
  [y, x]
end

#to_a ⇒ Array

Object -> Database Let's store NilClass if we are invalid.

Returns:

  • (Array)


33
34
35
36
37
# File 'lib/mongoid/geospatial/fields/point.rb', line 33

def mongoize
  return nil unless x && y

  [x, y]
end

#to_geo_json ⇒ String

Point definition as GeoJSON

"x, y"

Returns:

  • (String) —

    Point as comma separated String



132
133
134
135
# File 'lib/mongoid/geospatial/fields/point.rb', line 132

def to_geo_json
  # Return a GeoJSON point hash that MongoDB can use
  { type: 'Point', coordinates: [x, y] }
end

#to_hsh(xkey = :x, ykey = :y) ⇒ Hash Also known as: to_hash

Point representation as a Hash Optional param: custom keys.

Returns:

  • (Hash) —

    with { lng_key => x, lat_key => y }



111
112
113
# File 'lib/mongoid/geospatial/fields/point.rb', line 111

def to_hsh(xkey = :x, ykey = :y)
  { xkey => x, ykey => y }
end

#to_lat_lon ⇒ Hash

Point representation more commonly used Latitude, Longitude

Returns:

  • (Hash) —

    with { latitude: y, longitude: x }



121
122
123
# File 'lib/mongoid/geospatial/fields/point.rb', line 121

def to_lat_lon
  { latitude: y, longitude: x }
end

#to_lng_lat ⇒ Array

Object -> Database Let's store NilClass if we are invalid.

Returns:

  • (Array)


35
36
37
38
39
# File 'lib/mongoid/geospatial/fields/point.rb', line 35

def mongoize
  return nil unless x && y

  [x, y]
end

#to_s ⇒ String

Point definition as string

"x, y"

Returns:

  • (String) —

    Point as comma separated String



101
102
103
# File 'lib/mongoid/geospatial/fields/point.rb', line 101

def to_s
  "#{x}, #{y}"
end

#to_xy ⇒ Array

Object -> Database Let's store NilClass if we are invalid.

Returns:

  • (Array)


34
35
36
37
38
# File 'lib/mongoid/geospatial/fields/point.rb', line 34

def mongoize
  return nil unless x && y

  [x, y]
end

#valid? ⇒ Boolean

Am I valid?

Validates that #x & #y are Numeric

Returns:

  • (Boolean) —

    if self #x && #y are valid



90
91
92
# File 'lib/mongoid/geospatial/fields/point.rb', line 90

def valid?
  x && y && x.is_a?(Numeric) && y.is_a?(Numeric)
end