• Stars
    star
    120
  • Rank 285,963 (Top 6 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 13 years ago
  • Updated over 12 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Geo-spatial extension for Mongoid 2

Mongoid geo

Status update: August, 2011

This project is currently dead, as I can find no time to keep it alive for the time being. The project mostly works, except for
`monogid/contexts/geo_mongo.rb`, which needs some loove ;)

The project mongoid_spacial by @ryanong has taken many of the ideas and core design of mongoid_geo, improved, reworked and optimized it and added many new features such as pagination intgration etc.

Please use the mongoid_spacial gem instead!!

Note: I have created several other “geo” projects in various states, some currently with a “refactor” branch.
Would be nice to finish those and have it all integrated some time :)

Cheers!

Running specs

The goal of this branch is to define a good specs structure and build up a good design of this ‘geo’ add-on this way.

$ bundle
$ bundle exec rspec spec/mongoid/geo/config_spec.rb

Status update: June, 2011

- A Mongoid::Geo::Config object has been added which you use to configure Mongoid::Geo, see mongoid/geo/config_spec.rb
- GeoPoints and GeoVectors can be integrated using the new #enable_extensions! method on Mongoid::Geo::Config, specs in mongoid/geo/extensions demonstrate how to use this
- Creation of Mongo query hashes for Twin- and NestedOperators have been extracted into Query classes (see mongoid/geo/queries folder)
- #geo_near now uses configuration from Mongoid::Geo::Config, such as the #distance_calculator (if Mongo server doesn’t support this) and the #radians_multiplier etc.
- extensions can be enabled using Mongoid::Geo.enabele_extension ; currently supported extensions are :geo_calc, geo_point and geo_vectors (see specs for usage examples)

Example Usage 1.0 (goal)

class Address
  field :location, :type => Array, :geo => true
end

my_home = Address.new :location => {:lat => 10, :lng => 12}.to_lng_lat
my_job = Address.new :location => [10.2, "12.1"].to_lng_lat
my_club = Address.new :location => [10.2, 12.1]
my_club.location_lat == 12.1 # true
my_club.location_lng == 10.2 # true

nearest_locations = Address.geo_near my_club
nearest_locations.first

# find near point, max distance
Address.where :location.near_max => [{:latitude => 10, :longitude => 12 }, 5] # 5 km?
Address.where :location.near_max => [my_club, 5]

Address.where(:location.within_box => [my_job, my_club])
Address.where(:location.within_center(:sphere) => [my_home, 5])

# geo_point integration (using GeoPoint class)

Mongoid::Geo::Config.enable_extension! :geo_point

p1 = "58 38 38N, 003 04 12W".geo_point # DMS format support!
my_home = Address.new :location => p1.to_lng_lat

# a GeoPoint includes some nice geo calculation methods, that are calculated relative to itself !
p1.bearing_to my_club.geo_point # => 60 deg ?
p1.distance_to my_home.geo_point # => 2341 kms ?

# geo_vectors integration

Mongoid::Geo::Config.enable_extension! :geo_vectors

my_home = Address.new :location => p1.to_lng_lat
my_home.add [2, 4].vector # add lng/lat vector
my_home.add [20, 4.km].vector # add vector of 4km at 20 degrees

Example Usage 1.1 (goal)

Would be nice with a simple API that acts as a location repository and can be implemented for any key/value store.
Would also be nice to use unit distances as Numeric macros (currently available in geo_magic gem).

Address.where(:location.within_box => [:my_job, :my_club]) # each point should be looked up in the repo using the symbol as key  
Address.where :location.near_max => [:my_home, 5000.meters] # use geo_magic distance here!

Intro

This is a Geo extension for Mongoid 2.

MongoDB Geospatial Indexing

  • Supports Mongo DB 1.7+ sphere distance calculations
  • Extra geo calculation methods such as #near_sphere etc.
  • Adds concept of a special “geo” field (for setting the location point)
  • Configure and create geo indexes
  • Calculate locations near a given point and return as criteria, sorted by distance

You need help?

Post questions in the mongoid-geo group. Here I (and other uses of mongoid-geo) will
try to help out and answer any questions.

Suggestions, improvements and bugs?

Please raise issues or suggestions for improvements in the “Issues” section on github.
I would recommend that you try to branch the project, try to fix it yourself and make a pull request.

Current integrations

Mongoid geo has now been integrated with Google-Maps-for-Rails, thanks to oli-g, see commit

Mongoid 2 geo features

The following summarized what geo functionality is already provided by Mongoid 2.0 (as far as I could tell, May 9th, 2011)

Find addresses near a point

  Address.near(:latlng => [37.761523, -122.423575, 1])

Find locations within a circle

  base.where(:location.within => { "$center" => [ [ 50, -40 ], 1 ] })

Create geo-spatial index

  class Person
    field :location, :type => Array
    index [[ :location, Mongo::GEO2D ]], :min => -180, :max => 180
  end

  # to ensure indexes are created, either:
  Mongoid.autocreate_indexes = true

  # or in the mongoid.yml
  autocreate_indexes: true

These are the only geo features I could find that are currently built-in for Mongoid 2.

Mongoid Geo implements some nice extra geo features:

Mongoid Geo features

The following briefly demonstrates all the features that mongoid-geo provides:

Geo index

A new geo_index class method

Usage example:

geo_index :location

Note: For embedded documents, you must define the index in the root collection class. (davemitchell)

Calling geo_index also adds a #create_index! method to the class to enable construction of the index (on the instances/data in the DB).

  class Address
    ...
    geo_index :location
  end
  
  Address.create_index!

I also added a nice little Array macro so you can do this:

  [Address, Location].create_geo_indexes!

Geo option for Array GPS location field

Objective: When setting a geo GPS location array, the setter should try to convert the value to an array of floats

The “old” manual way:

  class Person
    field :locations, :type => Array

    def locations= args
      @locations = args.kind_of?(String) ? args.split(",").map(&:to_f) : args
    end
  end

mongoid-geo provides a new :geo option that can be used with any Array field:

Usage example:

  class Person
    field :location, :type => Array, :geo => true

    geo_index :location
  end

   p = Person.new

   # A Geo array can now be set via String or Strings, Hash or Object, here a few examples...
   # Please see geo_fields_spec.rb for more options!

   p.location = "45.1, -3.4"
   p.location = "45.1", "-3.4"
   p.location = {:lat => 45.1, :lng => -3.4}
   p.location = [{:lat => 45.1, :lng => -3.4}]
   p.location = {:latitude => 45.1, :longitude => -3.4}  

   my_location  = Location.new :latitude => 45.1, :longitude => -3.4
   p.location   = my_location

   # for each of the above, the following holds
   assert([45.1, -3.4], p.location)

   # also by default adds #lat and #lng convenience methods (thanks to TeuF)
   assert(45.1 , p.lat)
   assert(-3.4 , p.lng)

Customizing lat/lng attribute names:

    # the #lat and #lng convenience methods can also be customized with the :lat and :lng options
   field :location, :type => Array, :geo => true, :lat => :latitude, :lng => :longitude

   assert(45.1 , p.latitude)
   assert(-3.4 , p.longitude)

   # or set the array attributes using symmetric setter convenience methods!
   p.latitude   = 44
   assert(44 , p.latitude)

Reversing lat/lng for spherical calculations

  # You can also reverse the lat/lng positioning of the array storage - this is fx useful for spherical calculations
  
  Mongoid::Geo.spherical_mode do
    # Mongoid::Geo.lat_index.should == 1
    # Mongoid::Geo.lng_index.should == 0
    address.location = "23.5, -47"
    address.location.should == [23.5, -47].reverse
  end  

  # or alternatively 
  Mongoid::Geo.spherical = true
  
  address.location = "23.5, -47"
  address.location.should == [23.5, -47].reverse  

geo_near

class Address
  include Mongoid::Document
  extend Mongoid::Geo::Near

  field :location, :type => Array, :geo => true
  ...
end

# Find all addresses sorted nearest to a specific address loation
nearest_addresses = Address.geo_near(another_address, :location)

class Position
  include Mongoid::Document

  field :pos, :type => Array, :geo => true
  ...
end

Find all positions sorted nearest to the address loation

nearest_positions = Position.geo_near(another_address.location, :pos)

Perform distance locations in Speherical mode inside Mongo DB (default is :plane)

nearest_positions = Position.geo_near(another_address.location, :pos, :mode => :sphere)

Other options supported are: :num, :maxDistance, :distanceMultiplier, :query

GeoNear returns each distance calculated in degrees. Use the :distanceMultiplier or :unit option to return in the unit of your choice (see unit.rb).

Set :distanceMultiplier = 6371 to get distance in KMs
Set @:distanceMultiplier = @3963.19 to get distance in Miles

You can also use the :unit option instead like this (supports :feet, :meters, :kms, :miles):

results = Address.geo_near @center.location, :location, :unit => :feet, :dist_order => :desc

The geo_near query result is returned as a Mongoid::Criteria

results.desc(:distance).map(&:distance)

Note that the :fromLocation field, stores the location the distance was last calculated as a Hash of the GPS location point it was calculated from:

[23.5, -47].hash

This hash can be retrieved (and used for comparison?) using the fromHash field

from = results.first.fromHash

You can also at any time get the GPS location point which the distance of any result instance was calculated from, using the @fromPoint field

from = results.first.fromPoint

You can now explicitly set/configure the Mongo DB version used. This will affect whether built-in Mongo DB distance calculation will be used or using standalone Ruby Haversine algorithm. By default the Mongo DB version is set to 1.8 (as of May 9, 2011) . See geo_near specs for more details/info on this.

Mongoid::Geo.mongo_db_version = 1.7

Mongoid Geo extra inclusions

Find addresses near a point using spherical distance calculation

  Address.near_sphere(:location => [ 72, -44 ])

Mongoid Geo extra inflections

near_sphere

  base.where(:location.near_sphere => [ 72, -44 ])
  # => :location => { "$nearSphere" : [ 72, -44 ] }

near_max

Find points near a given point within a maximum distance

  base.where(:location.near_max => [[ 72, -44 ], 5])
  # => { $near: [50, 40] , $maxDistance: 3 }

  base.where(:location.near_max(:sphere) => [[ 72, -44 ], 5])
  # => { $nearSphere: [50, 40] , $maxDistanceSphere: 3 }

  base.where(:location.near_max(:sphere, :flat) => [[ 72, -44 ], 5])
  # => { $nearSphere: [50, 40] , $maxDistance: 3 }

You can also use a Hash to define the near_max

  places.where(:location.near_max => {:point => [ 72, -44 ], :distance => 5})

Or use an Object (which must have the methods #point and #distance that return the point and max distance from that point)

  near_max_ = (Struct.new :point, :distance).new
  near_max.point = [50, 40]
  near_max.distance = [30,55]

  places.where(:location.near_max => near_max)

Note: For the points, you can also use a hash or an object with the methods/keys, either :lat, :lng or :latitude, :longitude

Example:

  center = (Struct.new :lat, :lng).new
  center.lat = 72
  center.lng = -44
  places.where(:location.within_center => [center, radius])

  # OR

  places.where(:location.within_center => [{:lat => 72, :lng => -44}, radius])

within_box

  box = [[50, 40], [30,55]]
  base.where(:location.within_box => box)
  # => locations: {"$within" : {"$box" : [[50, 40], [30,55]]}

  base.where(:location.within_box(:sphere) => box)
  # => locations: {"$within" : {"$boxSphere" : [[50, 40], [30,55]]}

You can also use a Hash to define the box

  places.where(:location.within_box => {:lower_left => [50, 40], :upper_right => [30,55]})

  # or mix and match

  places.where(:location.within_box => {:lower_left => {:lat => 50, :lng => 40}, :upper_right => [30,55] } )

Or use an object (which must have the methods #lower_left and #upper_right that return the points of the bounding box)

  box = (Struct.new :lower_left, :upper_right).new
  box.lower_left =  [50, 40]
  box.upper_right = [30, 55]

  places.where(:location.within_box => box)

within_center

  center = [50, 40]
  radius = 4

  places.where(:location.within_center => [center, radius])
  # => places: {"$within" : {"$center" : [[50, 40], 4]}

  places.where(:location.within_center(:sphere) => [center, radius])
  # => places: {"$within" : {"$centerSphere" : [[50, 40], 4]}

You can also use a hash to define the circle, with :center and :radius keys

  places.where(:location.within_center => {:center => [50, 40], :radius => 4})

Or use an object (which must have the methods #center and #radius that return the center and radius of the circle))

  circle = (Struct.new :center, :radius).new
  circle.center = [50, 40]
  circle.radius = 4

  places.where(:location.within_center => circle)

Note on the specs

The specs still use the old “Javascript” like method convention, such as #nearSphere
Don’t let that fool you ;)

Contribute

Please feel free to contribute to the project!

I aim to deliver a complete geo package for use with Mongoid_. This gem should work nicely with geo_calc and geo_vectorsvectors that I’m also working on.

Your assistance on any of these projects will be greatly appreciated :)

More Repositories

1

cantango

CanCan extension with role oriented permission management, rules caching and much more
Ruby
407
star
2

cream

Integrates Devise, Roles and CanCan with Permits for a Rails 3 app
Ruby
295
star
3

schema-to-yup

Schema to Yup validation
JavaScript
277
star
4

masonry-rails

JQuery Masonry plugin ready for use with Rails asset pipeline
HTML
235
star
5

datascript-tutorial

Datascript and Datomic tutorial book
206
star
6

haversine

Calculates the haversine distance between two locations using longitude and latitude
Ruby
89
star
7

vue2-dragula-demo

Vue2 demo app for vue-dragula plugin
JavaScript
78
star
8

gmaps-autocomplete-rails

Google Maps v3 search with jQuery UI Autocomplete, ready for use with Rails asset pipeline
Ruby
73
star
9

geo_magic

Location from IP, geocoding, distance calculation, and geo/map utilities
Ruby
69
star
10

acts_as_list_mongoid

Make your Mongoid model acts as a list
Ruby
64
star
11

roles_generic

Generic role model strategies sharing same API easy to insert in any model
Ruby
59
star
12

rails-gallery

Popular javascript photo gallery and carousel components ready for use with Rails 3 and above :)
Ruby
53
star
13

geo-distance

Calculates the geo distance between two locations using longitude and latitude, using Haversine, Speherical or Vincenty formula
Ruby
52
star
14

ui_datepicker-rails3

jQuery UI datepicker integration for Formtastic, Simple Form and Active Admin
Ruby
50
star
15

world-flags

Use world flag sprites in your Rails 3 app
HTML
48
star
16

mm-devise

Mongo Mapper integration for Devise framework
Ruby
47
star
17

amazing-aurelia-book

Book on how to write advanced, high powered apps with the Aurelia framework.
41
star
18

troles

Roles for Rails 3
Ruby
41
star
19

json-schema-to-es-mapping

Convert JSON Schema to Elastic Search mapping schema
JavaScript
38
star
20

generator-aurelia-ts

Turbo Start generator for Aurelia apps
JavaScript
31
star
21

roles_mongoid

Roles for mongoid using the Roles generic API from roles_generic
Ruby
29
star
22

emberjs-plugin

EmberJS plugin for Intellij IDEA and Webstorm IDE
Java
28
star
23

sugar-high

More Ruby sugar - inspired by the 'zuker' project
Ruby
26
star
24

ember-konacha-rails

Generate Konacha spec infrastructure for your Ember-Rails apps
Ruby
24
star
25

papertrail_mongoid

Papertrail for mongoid
Ruby
23
star
26

cancan-permits

Role specific Permits for use with CanCan permission system
Ruby
21
star
27

auth-assistant

Assistance for configuring and use of devise and cancan in combination
Ruby
20
star
28

vue-framer

Bridging the final gap of the design to app workflow, making a Framer app work with Vue
JavaScript
20
star
29

roles_active_record

Roles for Active Record implementing the Roles generic API
Ruby
18
star
30

slush-reframe

Reframe generator for base application and main artifacts such as domain models
JavaScript
17
star
31

jquery-ui-bootstrap-rails

jQuery UI Bootstrap for Rails asset pipeline
Ruby
17
star
32

bootstrap-addons-rails

Twitter Bootstrap addons: Color- and Datepicker, Image gallery, ready for use with Rails asset pipeline
Ruby
17
star
33

mongoid_embedded_helper

Facilitates performing queries on collections in embedded Mongoid documents
Ruby
16
star
34

mongo_rails3_gen

Mongo DB rails 3 generators to setup use of Mongo DB and create Mongo DB compatible models in Rails 3
Ruby
16
star
35

aurelia-rethink-bindtable

Aurelia bind table integration for RethinkDB via Socket.io
JavaScript
16
star
36

rails3-templates

Rails 3 templates for rapid creation of Rails 3 applications
Ruby
15
star
37

cantango-permits

Permits and Permit engine for CanTango
Ruby
15
star
38

bs-xstate

Bucklescript bindings for XState state machine
OCaml
15
star
39

world-flag-packs

World Flag image packs for use on the web or with the world-flags rails gem
15
star
40

json-schema-to-graphql-types-decorated

Convert JSON schema to GraphQL types (string) including GraphQL transforms/directives
JavaScript
14
star
41

very_nifty_generators

Rails 3 very nifty generators using very DRY conventions
Ruby
14
star
42

geo_calc

Geo calculations in ruby and javascript
Ruby
14
star
43

ember-pusher

A nice little Ember - Pusher integration library
Ruby
14
star
44

vue2-apollo-scaphold

Vue2 Apollo Scaphold.io starter app
Vue
13
star
45

gun-edge

API helpers for Gun.js
JavaScript
13
star
46

pie-rails

Progressive Internet Explorer (PIE) ready for use with Rails asset pipeline
Ruby
13
star
47

react-16.nim

React 16.x bindings for Nim 1.0 with example app (WIP)
Nim
13
star
48

timespan

Use TimeSpans in ruby
Ruby
13
star
49

cartling

Shopping Cart system for Node.js using Keystone and MongoDB by default
JavaScript
12
star
50

ember-beercan

Authorization a-la cancan style for Ember with some Authentication magic added for good measure ;)
Ruby
12
star
51

convert-json-schema-to-mongoose

Convert JSON schema to mongoose 5 schema
JavaScript
12
star
52

prawn_html

A prawn library to assist in converting html to pdf using prawn for pdf rendering
Ruby
11
star
53

cream-app-active_record

Cream demo app for Rails 3 with ActiveRecord
Ruby
11
star
54

react-mxgraph-typescript-starter

React 16 mxgraph-js and typescript starter template based on create-react-app
TypeScript
11
star
55

cypher-query

Javascript Cypher query engine for graphs such as graphology and gun
TypeScript
11
star
56

cantango-demo

Cantango Rails 3 demo app with devise integration
Ruby
11
star
57

Prawn-assist

Helper functions to parse HTML and create output to assist rendering PDF using prawn (or some other renderer)
Ruby
11
star
58

semantic-sass-bootstrap

Semantic SASS wrapper for Twitter Bootstrap
Ruby
11
star
59

chain-gun

Gun.js chain API extensions
JavaScript
10
star
60

mongoid_adjust

Adds simple adjust! method to Mongoid - in the near future it should use the built-in Mongo DB functionality
Ruby
10
star
61

FirebaseUI

FirebaseUI wrapped for use with React Native (iOS only)
Objective-C
9
star
62

acts_as_tree_rails3

The old acts_as_tree updated and converted into a gem for rails 3
Ruby
9
star
63

mongoid-serializer

Add some sane controller serialization support for your Mongoid 3+ models
Ruby
9
star
64

permit-authorize

Authorization library for Javascript and NodeJS using permits and user abilities
LiveScript
9
star
65

cancan-rest-links

Rest link helpers for CanCan
Ruby
9
star
66

ember-config

Yeoman generator for ember-cli to facilitate configuring an Ember app with various asset compilers, components, layout frameworks etc.
JavaScript
9
star
67

money-mongoid

Standalone Mongoid support and integration for the Money gem
Ruby
9
star
68

ruby_traverser_dsl

A ruby code traverser DSL for finding and traversing ruby code as an object model using a nice DSL - uses ripper2ruby
Ruby
9
star
69

rspec-action_view

RSpec addon to simplify creating specs for Rails 3 ActionView extensions
Ruby
8
star
70

cream-app-mongoid

Cream 7.7 demonstration app
Ruby
8
star
71

awd-rails-4th-depot-app

Agile web development with Rails 4th edition - Depot application
Ruby
8
star
72

authorize-mw

Authorization middleware for Node.js and Javascript platform in general (with a little twist)
LiveScript
8
star
73

cancan-permits-demo

Demo of how to use cancan-permits in a Rails 3 app
Ruby
8
star
74

ember-easyform-cli

Experimental fork of ember-easyForm to wrap it as an Ember CLI addon for easy installation
JavaScript
8
star
75

typescript-ast-processor

Process a TypeScript AST using visitors, collectors and instrumentation
TypeScript
7
star
76

red-elements

Node-red UI components as native custom elements
TypeScript
7
star
77

sweetloader

Sweetens up your autoloading of classes and modules
Ruby
7
star
78

ember-factories

Simple Factory library for use with Ember.js
Ruby
7
star
79

geokit-rails3-mongoid

Geokit for Rails 3 using Mongoid
Ruby
7
star
80

facebook-social_plugins

Facebook HTML5 style social plugins for Rails 3
Ruby
7
star
81

ember-cli-emberscript

Adds precompilation of EmberScript files and all the basic generation types to the ember generate command.
JavaScript
7
star
82

rubyproject

A Thor based generator for generating a skeleton Ruby project with Rspec and Cucumber on by default
Ruby
7
star
83

json-schema-model-builder

Infrastructure components to easily process JSON schema and build models from it
JavaScript
7
star
84

semantic-ui-page-layouts

Semantic UI page layouts for common scenarios
HTML
6
star
85

log4r-color

log4r now with color outputs to terminal/console
Ruby
6
star
86

credit_card_icons

Credit card icons for Rails 3 as an engine, using CSS sprites with icons in various sizes and shapes
Ruby
6
star
87

easy_as_pie

Rails asset wrapper for jQuery easy-pie-chart
Ruby
6
star
88

rspec-book-movie-app

The RSpec book movie app implemented for Rails 3 and Rspec 2 with Capybara
Ruby
6
star
89

water-gun

Gun.js API extensions for working with Observables/Streams and CSP channels
JavaScript
6
star
90

rspec-book-views-example

RSpec book views example for RSpec 2.beta11 with Rails 3.b3 and Capybara
Ruby
6
star
91

netzke_widget_generators

Rails 3 generators to quickly generate skeletons for custom Netzke widgets
Ruby
6
star
92

future-gun

Gun.js extensions for Promise and async/await based flow control
JavaScript
6
star
93

concerned

Concerns for Rails
Ruby
5
star
94

cantango-core

The core functionality of CanTango
Ruby
5
star
95

ember-bootstrap-rails

Add ember-bootstrap to your Rails 3.1+ Assets pipeline
JavaScript
5
star
96

koa-marko-example

Convenient Koa.js server setup for rendering pages of a multi page application
JavaScript
5
star
97

ember-big_project

Create a sensible and extensible Ember project structure for big projects ;)
Ruby
5
star
98

aurelia-definitely-typed

Aurelia definition files for registration with TypeScript Definitely Typed registry for use with tsd package manager
TypeScript
5
star
99

geo_point

A GeoPoint encapsulates latitude, longitude and various geo calculations relative to itself
Ruby
5
star
100

qiankun-demo

Qiankun demo app - single-spa Micro Front End (MFE) application
JavaScript
5
star