Module: Mongoid::Geospatial

Extended by:
ActiveSupport::Concern
Defined in:
lib/mongoid/geospatial.rb,
lib/mongoid/geospatial/config.rb,
lib/mongoid/geospatial/version.rb,
lib/mongoid/geospatial/fields/box.rb,
lib/mongoid/geospatial/config/point.rb,
lib/mongoid/geospatial/fields/point.rb,
lib/mongoid/geospatial/helpers/geom.rb,
lib/mongoid/geospatial/fields/circle.rb,
lib/mongoid/geospatial/wrappers/rgeo.rb,
lib/mongoid/geospatial/fields/polygon.rb,
lib/mongoid/geospatial/geometry_field.rb,
lib/mongoid/geospatial/wrappers/georuby.rb,
lib/mongoid/geospatial/fields/line_string.rb

Overview

Wrappers for GeoRuby https://github.com/nofxx/georuby

Defined Under Namespace

Modules: ClassMethods, Config, Geom Classes: Box, Circle, GeometryField, LineString, Point, Polygon

Constant Summary collapse

LNG_SYMBOLS =

Symbols accepted as 'longitude', 'x'...

[:x, :lon, :long, :lng, :longitude,
'x', 'lon', 'long', 'lng', 'longitude'].freeze
LAT_SYMBOLS =

Symbols accepted as 'latitude', 'y'...

[:y, :lat, :latitude, 'y', 'lat', 'latitude'].freeze
EARTH_RADIUS_KM =

For distance spherical calculations

6371
RAD_PER_DEG =

taken directly from mongodb

Math::PI / 180
EARTH_RADIUS =

Earth radius in multiple units

{
  m: EARTH_RADIUS_KM * 1000,
  km: EARTH_RADIUS_KM,
  mi: EARTH_RADIUS_KM * 0.621371192,
  ft: EARTH_RADIUS_KM * 5280 * 0.621371192,
  sm: EARTH_RADIUS_KM * 0.53995680345572 # sea mile
}.freeze
VERSION =
'7.3.1'
@@lng_symbols =
LNG_SYMBOLS.dup
@@lat_symbols =
LAT_SYMBOLS.dup
@@earth_radius =
EARTH_RADIUS.dup

Class Method Summary collapse

Class Method Details

.configObject



26
27
28
# File 'lib/mongoid/geospatial/config.rb', line 26

def config
  Config
end

.configureObject



22
23
24
# File 'lib/mongoid/geospatial/config.rb', line 22

def configure
  block_given? ? yield(Config) : Config
end

.km!(km) ⇒ Object

A cap Mongo can measure: a positive number of kilometres.

Raises:

  • (ArgumentError)


90
91
92
93
94
# File 'lib/mongoid/geospatial.rb', line 90

def self.km!(km) # rubocop:disable Naming/MethodParameterName
  raise ArgumentError, "Invalid km: #{km.inspect}" unless km.is_a?(Numeric) && km.positive?

  km
end

.mongoize_point!(geom) ⇒ Object

A [lng, lat] pair, or nothing. Point.mongoize is lenient — it reads "nowhere" as [0.0] — and a half pair is a query Mongo cannot answer.



78
79
80
81
82
83
84
85
# File 'lib/mongoid/geospatial.rb', line 78

def self.mongoize_point!(geom)
  coords = Point.mongoize(geom)
  unless coords.is_a?(Array) && coords.size == 2 && coords.all?(Numeric)
    raise ArgumentError, "Invalid coordinates: #{geom.inspect}"
  end

  coords
end

.near_query(geom, km) ⇒ Object

$nearSphere value with a km cap, GeoJSON. Metres on the wire. This is the 2dsphere shape — see #near_selector for the other one.



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

def self.near_query(geom, km) # rubocop:disable Naming/MethodParameterName
  { '$geometry' => { 'type' => 'Point', 'coordinates' => mongoize_point!(geom) },
    '$maxDistance' => km!(km) * 1_000 }
end

.near_selector(field, geom, km, sphere: true) ⇒ Object

The whole { field => ... } selector for "within +km+", for either index.

$nearSphere speaks two dialects and the index picks which:

2dsphere   { loc: { $nearSphere: { $geometry: {...}, $maxDistance: <m> } } }
2d         { loc: { $nearSphere: [x, y],             $maxDistance: <rad> } }

Hand the wrong one over and the server answers NoQueryExecutionPlans, not a wrong count — so ask the field which it is before building.



116
117
118
119
120
121
# File 'lib/mongoid/geospatial.rb', line 116

def self.near_selector(field, geom, km, sphere: true) # rubocop:disable Naming/MethodParameterName
  return { field => { '$nearSphere' => near_query(geom, km) } } if sphere

  { field => { '$nearSphere' => mongoize_point!(geom),
               '$maxDistance' => km!(km) / EARTH_RADIUS_KM.to_f } }
end

.with_georuby!Object



70
71
72
# File 'lib/mongoid/geospatial.rb', line 70

def self.with_georuby!
  require 'mongoid/geospatial/wrappers/georuby'
end

.with_rgeo!Object



66
67
68
# File 'lib/mongoid/geospatial.rb', line 66

def self.with_rgeo!
  require 'mongoid/geospatial/wrappers/rgeo'
end