Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB $geoIntersects not finding one fully-contained line in polygon, but finding another

I have a MongoDB database that has a collection called fooCollection. This collection has documents in it containing geospatial data in the way of a bounding polygon. I am using the C# MongoDB driver in my app. I noticed that it was not finding documents with certain spatial queries although it works with most of them. I emptied the collection except for one offending document and I tried to find it by executing queries directly.

My document looks like this:

{
"_id" : UUID("12345678-62d9-4024-86dc-123456789012"),
"polygon" : {
    "type" : "Polygon",
    "coordinates" : [ [ 
            [ 18.414846, -33.9699577 ], 
            [ 18.414846, -26.0991189 ], 
            [ 31.0330578, -26.0991189 ], 
            [ 31.0330578, -33.9699577 ], 
            [ 18.414846, -33.9699577 ]
    ] ]
},
"foo": "bar"
}

I also have this index on that collection:

[
    1,
    {
       "polygon" : "2dsphere"
    },
    "polygon_2dsphere",
    "data.fooCollection",
    3
]

The following query correctly returns this document:

db.getCollection('fooCollection').find( { 
    "polygon": { 
        $geoIntersects: { 
            $geometry: { 
                type: "LineString", 
                coordinates: [[24.7698287, -28.7353533],[28.0423, -26.19793]]
}}}})

However, this query does not:

db.getCollection('fooCollection').find( { 
    "polygon": { 
        $geoIntersects: { 
            $geometry: { 
                type: "LineString", 
                coordinates: [[27.7706902, -26.1091189],[28.0423, -26.19793]]
}}}})

If you plot those three geometries, I can't really see why one would work but not the other.

  • Both lines lie entirely within the polygon
  • The working line is much longer
  • The working line has a bearing of between 0° and 90°, the other between 90° and 180°.

Is anyone able to explain this behaviour?

EDIT: I have also tested the points individually instead of using the LineStrings. The only one that is a hit is [24.7698287, -28.7353533]. I do need the LineStrings - the query should be a hit even if only the edge intersects the polygon and no points lie within

You can see the geojson here or you can plot the three geometries yourself by pasting the following line into http://geojson.io/:

{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[18.414846,-33.9699577],[18.414846,-26.0991189],[31.0330578,-26.0991189],[31.0330578,-33.9699577],[18.414846,-33.9699577]]]},{"type":"LineString","coordinates":[[27.7706902,-26.1091189],[28.0423,-26.19793]]},{"type":"LineString","coordinates":[[24.7698287,-28.7353533],[28.0423,-26.19793]]}]}
like image 557
08Dc91wk Avatar asked Jan 17 '17 12:01

08Dc91wk


1 Answers

Is anyone able to explain this behaviour?

This is because Earth is not flat, but quite spherical (curved) . Earth’s surface cannot be represented on a plane without distortion. So this means that every map projection will distort the Earth in some way. See also Map Projections

MongoDB 2dsphere index, supports queries that calculate geometries on an earth-like sphere.

When you map the coordinate on http://geojson.io, it doesn't take account of the spherical nature of Earth. The shorter LineString is shown to be within the "square" Polygon.

geojson.io

If you map the GeoJSON geometrics on https://geodndmap.mongodb.com that takes account of the fact that there's a spherical distortion, you'll see below:

geodndmap.mongodb.com

The shorter LineString is actually outside of "square" Polygon. This is what MongoDB 2dsphere index/query is performed upon.

The impact of the distortion effect grows with the longer/bigger area projections.

Example:

{"type":"GeometryCollection","geometries":[
{"type":"Polygon","coordinates":[[[18.414846,-33.9699577],[18.414846,-26.0991189],[31.0330578,-26.0991189],[31.0330578,-33.9699577],[18.414846,-33.9699577]]]},
{"type":"LineString","coordinates":[[24.7698287,-28.7353533],[88.0423,-26.19793]]}]}

geojson.io

geodndmap.mongodb.com

PS: To use geodndmap.mongodb.com, drag and drop GeoJSON onto the map, either as a file or as text from an editing program.

like image 145
Wan Bachtiar Avatar answered Oct 22 '22 11:10

Wan Bachtiar