Jorge Pozas
Jorge Pozas

Reputation: 43

How to get all circles that a Point is contained in?

Is there a way to find out what polygons (specifically circles) a specific Point lies in?

In this case I would have stored a documents containing circles, like below, I would pass in a latitude and longitude for a point, and would like to get back all documents where the point is within the given circle.

{
  "_id" : ObjectId("53e3e85ce4b0c2e8227a1dad"),
  "name" : "Menlo College",
  "location" : [-122.1928, 37.45632],
  "radius" : NumberLong(215),
},
{
  "_id" : ObjectId("53e43d19e4b0aeabcb3d3f9d"),
  "name" : "West Valley College",
  "location" : [-122.01021194458008, 37.263226547586207],
  "radius" : NumberLong(604),
}

If this is not possible, then is it at least possible with other GeoJSON shapes? Everything I've found so far indicates that the inverse is possible (find all points which like inside a circle), but nothing for this scenario.

Thanks

Upvotes: 4

Views: 1768

Answers (1)

displayName
displayName

Reputation: 14399

It is possible using MongoDB's $geoIntersects Geospatial query operator.

So, if you have a collection of GeoJson polygons and you want to find out all the polygons that intersect with your given point, then you need to run the following:

db.places.find( { <locationFieldOfYourDocuments> :
                  { $geoIntersects :
                    { $geometry :
                      { type : "Point" ,
                        coordinates: [long, lat]
                } } } } )

In the command above, loc is that attribute of each document that contains the coordinates for GeoJson polygon. Also, make sure that you have 2dsphere index over <locationFieldOfYourDocuments>.

Now, to get your original problem solved I will use a little bit of javascript. There may be better solutions but not in my knowledge.

Let's say all your circles are stored in Circles collection. I would query that collection and fetch each circle one by one and then perform an intersect with another collection that would contain a single point which would be the one you wanted to query if it intersects with the circles or not. So let the point be stored in SinglePoint collection.

The script would look like...

db.Intersections.remove({}); // emptying the output collection
var circleCursor = db.Circles.find();
while (circleCursor.hasNext()) {
    var circle = circleCursor.next();
    var coord = circle.location;
    var radiusInRadians = circle.radius * conversionFactorForRadius;
    var intersect = db.SinglePoint.find({loc :
                                         { $geoWithin :
                                           {$centerSphere : [coord], radiusInRadians}
                                         }});
    if (intersect.hasNext()) {db.Intersections.add(circle)} // this will add all intersecting circles to Intersections collection
}

All you have to do is save this script in a file (myScript.js) and make a call:

mongo DBName pathTomyScript.js

This will store all the circles that intersect with your input point in the Intersects collection. All the above collections should be in DBName database.

Upvotes: 2

Related Questions