Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I perform a $geoIntersects query with Mongoid?

I'm using Sinatra and mongoid driver, now I'm trying to perform this query in mongoid, actually I have a geospatial (Polygon) field called 'geometry':

db.states.find({
    geometry: {
        $geoIntersects: {
            $geometry: {
                type: "Point",
                coordinates: [-99.176524, 18.929204]
            }
        }
    }
})

Actually this query works in mongodb shell.

However, I want to find states that intersects with given point (Point-in-polygon) with mongoid or maybe other ruby driver.

Any help would be greatly appreciated.

Thanks.

like image 299
chroman Avatar asked Mar 21 '13 21:03

chroman


People also ask

How do you create a geospatial index on it?

Geospatial Indexes and Sharded Collections However, you can create a geospatial index on a sharded collection by using a different field as the shard key. The following geospatial operations are supported on sharded collections: $geoNear aggregation stage. $near and $nearSphere query operators (starting in MongoDB 4.0)

Does MongoDB support geospatial index?

A 2dsphere index supports queries that calculate geometries on an earth-like sphere. 2dsphere index supports all MongoDB geospatial queries: queries for inclusion, intersection and proximity.

Is MongoDB a spatial database?

MongoDB, which is a NoSQL Database, allows storing of Geospatial Data in the form of multiple GeoJSON types. Geospatial Feature of MongoDB makes it easy to store Geographical data into a database. So, basically, you can store the geospatial type data in the MongoDB in the form of GeoJSON objects.

How does MongoDB store location?

MongoDB provides the functionality to store locations under the object type geoJSON and their coordinates against the coordinate field in [longitude, latitude] form where longitude must lie between [-180, 180] and latitude must lie between [-90,90], both inclusive.


1 Answers

I was recently searching for this, and after a while I found the following. Maybe someone else will have use for this..

$geoIntersects is now implemented in mongoid 4.0.0.beta1, but not well documented.. I found this in the origin changelog: https://github.com/mongoid/origin/blob/master/CHANGELOG.md#new-features-1

query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
query.geo_spacial(:location.intersects_point => [[ 1, 10 ]])
query.geo_spacial(:location.intersects_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])

and a commit: https://github.com/mongoid/origin/commit/30938fad644f17fe38f62cf90571b78783b900d8

 # Add a $geoIntersects selection. Symbol operators must be used as shown in
 # the examples to expand the criteria.
 #
 # @note The only valid geometry shapes for a $geoIntersects are: :line,
 #   :point, and :polygon.
 # ...
 # @example Add a geo intersect criterion for a point.
 #   query.geo_intersects(:location.point => [[ 1, 10 ]])

In my project i have mongoid (4.0.0.beta1) and origin (2.1.0) I have a model Polygon

class Polygon
  include Mongoid::Document
  # some fields 

  embeds_many :loc

  # coordinates is an array of two points: [10, 12]
  def find_polygons_with_point(coordinates)
    # This is where the magic happens!
    Polygon.all.geo_spacial(:loc.intersects_point => coordinates)
  end

end

And a model Loc

class Loc
  field :type, type: String #Need to be set to 'Polygon' when creating a new location.
  field :coordinates, type: Array
  # For some reason the array has to be in the format
  # [ [ [1,1], [2,3], [5,3], [1,1] ] ]
  # And the first coordinate needs to be the same as the last
  # to close the polygon

  embedded_in :polygon

  index({ coordinates: "2d" }, { min: -200, max: 200 }) #may not need min/max
end

This code returns all polygons that has this point inside.

There might be more elegant ways of doing this. If so I would like to hear it :)

like image 95
Hilde Avatar answered Oct 15 '22 05:10

Hilde