[SERVER-12479] $geoWithin picks points outside of polygon Created: 25/Jan/14  Updated: 10/Dec/14  Resolved: 26/Jan/14

Status: Closed
Project: Core Server
Component/s: Geo
Affects Version/s: 2.4.9
Fix Version/s: None

Type: Bug Priority: Critical - P2
Reporter: Konstantin Ignatyev Assignee: Unassigned
Resolution: Done Votes: 0
Labels: geo, geoWithin
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

OSX 64


Attachments: PNG File flat-map.png     PNG File great-arc.png    
Issue Links:
Related
related to SERVER-15609 GeoWithin query returns wrong result Closed
Operating System: ALL
Participants:

 Description   

Given 3 points:

{ "_id" : "1", "name" : "b",  "loc" : { "coordinates" : [ -121, 47.134296 ], "type" : "Point" }, "description" : ""}
{ "_id" : "2", "name" : "a",  "loc" : { "coordinates" : [ -120, 47.234296 ], "type" : "Point" }, "description" : ""}
{ "_id" : "3", "name" : "c",  "loc" : { "coordinates" : [ -125, 49.134296 ], "type" : "Point" }, "description" : ""}

The following query returns 2 results - first 2 objects (with id-s 1 and 2 ) even though their latitude lays outside of given polygon.

db.SimpleVisits.find( { "loc" : { "$geoWithin" : { "$geometry" : 
                                    { "type" : "Polygon" , 
                                    "coordinates" : [ [ [ -100.0 , 46.5] , [ -130.0 , 46.5] , [ -130.0 , 40.01] , [ -100.0 , 40.01] , [ -100.0 , 46.5]]]}}}})  



 Comments   
Comment by Konstantin Ignatyev [ 27/Jan/14 ]

Got you, kind of makes sense. Maybe it need to be emphasized in documentation, I was expecting $geoWithin to be aligned with lat and lng. Given the way it works in Mongo it makes it problematic to align results with google map: lets say I display a google map that gives it bounds as in my example, then I try using the bounds to find what I need to show on the map, and find the 2 points, but they will NOT be visible on the map.

Is there a way to avoid such discrepancy?

Comment by Daniel Pasette (Inactive) [ 27/Jan/14 ]

Here is some more background on the math involved:
http://www.movable-type.co.uk/scripts/latlong.html

If you plug the values for the top arc of your bounding polygon into the first example on that page, it will render the upper bound and you can zoom in to see that the points are actually contained by the polygon you queried with.

first point: 46 30N and -100W
second point: 46 30N and -130W

Comment by Konstantin Ignatyev [ 27/Jan/14 ]

Hey, arc on sphere is at latitude 46.5, so it can NOT include points at latitude 47.13. Latitude is an angle, so angle 46.6 is smaller than 47.13.
What do you mean it works as designed?

Comment by Daniel Pasette (Inactive) [ 26/Jan/14 ]

When querying over a large area on a sphere, the borders of the polygon are not straight lines, but great arcs. The two points returned actually are included in the region you're querying.

It can be helpful to see how your query looks on a flat map vs. a sphere. I've attached screenshots, but the links also go to the source of the graphics.

This shows how the area you're querying for looks rendered on the sphere:
http://www.gcmap.com/mapui?P=100W46.5N+-+130W46.5N+-+130W40N+-+100W40.01N+-+100W46.5N

This is how your sample points and bounding polygon render on a flat map:
Plug this GeoJSON collection into GeoJSONLint (a nice tool to render your GeoJSON found here: http://geojsonlint.com/):

{"type": "GeometryCollection",
    "geometries": [
 
{ "coordinates" : [ -121, 47.134296 ], "type" : "Point" }, 
{ "coordinates" : [ -120, 47.234296 ], "type" : "Point" }, 
{ "coordinates" : [ -125, 49.134296 ], "type" : "Point" },
       { "type" : "Polygon" , "coordinates" : [ [ [ -100.0 , 46.5] , [ -130.0 , 46.5] , [ -130.0 , 40.01] , [ -100.0 , 40.01] , [ -100.0 , 46.5]]]}
    ]
}   

Generated at Thu Feb 08 03:28:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.