Query to match a polygon containing a point

The docs in my mongodb collection look like this:

{
"_id" : ObjectId("5562d6831683523f449e7d85")
"geometry" : {
"type" : "Polygon",
"coordinates" : 
    [[
    [-122.4,37.81],
    [-132.9, 39.9],
    [-122.28, 37.80],
    [-124.18, 39.81]
    ]]
}}

      

I have a point (a long pair of lengths) which I will call x

and y

. I need to see if the document coordinates create a polygon in such a way that those coordinates are inside that polygon.

So, of course, I need to compute the string describing each edge of the polygon, etc., and then see if the coordinates of the point are in it. However, for now, let's say we want to query documents with x

and y

within the maximum and minimum long long values ​​for the entire array.

This is how I tried to execute the request:

db.<collection-name>.find(
    {'geometry.coordinates':
        {$elemMatch:
            {
                [{$gt:-122.1}, {$lt:-122.0 }], [{$gt: 37.89 },{$lt: 37.91}]
            }
        }
    }
)

      

but the result: Unexpected token [

. I tried to follow the example here .

How can I query for an array like this where there are conditions for each element of the array in the document? thank.

+3


source to share


1 answer


What you are trying to do by matching the elements of the array is actually "Find a polygon containing a point", so I changed the title of the question.

You are better off using MongoDB's geoSpatail features for this rather than trying to work out the boundaries yourself. With valid GeoJSON data, the request is quite simple using an operator . $geoIntersects

To demonstrate, I'll first set up a collection with some Polygon data:

db.areas.insert([
    {
        "name": "San Jose",
        "geometry": {
            "type": "Polygon",
            "coordinates": [[
                [ -122.20916748046876, 37.13404537126446  ],
                [ -122.20916748046876, 37.496652341233364 ],
                [ -121.65710449218749, 37.496652341233364 ],
                [ -121.65710449218749, 37.13404537126446  ],
                [ -122.20916748046876, 37.13404537126446  ]
             ]]
         }
    },
    {
        "name": "San Franciso",
        "geometry": {
            "type": "Polygon",
            "coordinates": [[
                [ -122.73651123046874, 37.58811876638322 ],
                [ -122.73651123046874, 37.89219554724437 ],
                [ -122.28332519531249, 37.89219554724437 ],
                [ -122.28332519531249, 37.58811876638322 ],
                [ -122.73651123046874, 37.58811876638322 ]
            ]]
        }
    }
])

      

Then (although not required for $geoIntersects

) when working with geoSpatial data, it is best to define an "index". What makes sense for real GeoJSON locations is "2dsphere" . The index is created in a field that contains the "root" of the GeoJSON data, which in this case is called "geometry":

db.areas.createIndex({ "geometry": "2dsphere" })

      



Then you just need to submit a request .find()

. I'm using coordinates for "San Francisco City" here:

db.areas.find({
    "geometry": {
        "$geoIntersects": {
             "$geometry": {
                "type": "Point",
                "coordinates": [ 
                    -122.45361328124999, 
                    37.76420119453823
                ]
             }
         }
    }
})

      

Which, of course, returns the "Polyon" defining the "San Francisco" area, since this point is inside this object.

    {
        "name": "San Franciso",
        "geometry": {
            "type": "Polygon",
            "coordinates": [[
                [ -122.73651123046874, 37.58811876638322 ],
                [ -122.73651123046874, 37.89219554724437 ],
                [ -122.28332519531249, 37.89219554724437 ],
                [ -122.28332519531249, 37.58811876638322 ],
                [ -122.73651123046874, 37.58811876638322 ]
            ]]
        }
    }

      

This is all it takes to determine if your "point" is inside the "Polygon" that you saved in your collection.

Also take a look at tools like geojsonlint.com and geojson.io (examples, not confirmations) to validate and visualize your data, which from your example does not provide a well-formed Polygon.

+3


source







All Articles