简体   繁体   中英

how to use geointersects to check if a point is within a Polygon in mongodb

I'm trying to learn how to use geospatial query in MongoDB, but it seems that i can't really get it right! So i have my tiles collection in mongo, for the sake of the argument suppose i have only one document in it, most precisely, this one:

{
    "_id" : "-180-9018090",
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [
                    -180,
                    -90
                ],
                [
                    180,
                    -90
                ],
                [
                    180,
                    90
                ],
                [
                    -180,
                    90
                ],
                [
                    -180,
                    -90
                ]
            ]
        ]
    },
    "type" : "Feature",
    "properties" : {
        "zoom-level" : 0,
        "center" : [
            0,
            0
        ]
    }
}

which represents basically the entire world. Now i want to see if a certain point, let's say (0,0) is inside of this area. my understanding is that i should use a geointersects to achieve this task, so the query should look like this(?):

db.tiles.find({
  geometry: {
     $geoIntersects: {
        $geometry: {
           type: "Point" ,
           coordinates: [ 0,0]
        }
     }
  }
});

but of course the resultset is empty as my mind of ideas on why this is happening. Could you help me understanding what i'm doing wrong ?

EDIT:

upon further attempts, the query seems correct, so there must be something on how $geointersects works that i'm missing out. My finding so far trough an example:

let's suppose to have a 5 docs in our db:

          *-----*
          | 4|3 | => whole world tile: from [-90,-180] to [90,180]
          | 1|2 |
          *-----* 

let's take this tile and divide it in 4:

*---*  *---*  *---*  *---*
| 1 |  | 2 |  | 3 |  | 4 | => 1) [-90,-180]-> [0,0]   (lower left)
*---*  *---*  *---*  *---*    2) [0,-90]   -> [180,0] (lower right)
                              3) [0,0]     -> [180,90](upper right)
                              4) [-180,0]  -> [0,90]  (upper left)

so, as the poor schema is struggling to show, we have 5 docs, each one representing a polygon of 4 vertices (wich in geoJson become 5 since you have to append the initial point at the end).

Now, using the same query will actually produce this result:

> db.tiles.find({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ 0,0 ] } } } }).sort({"zoom": 1})
    { "_id" : "0.0-90.0180.00.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 0, -90 ], [ 180, -90 ], [ 180, 0 ], [ 0, 0 ], [ 0, -90 ] ] ] }, "zoom" : 1 }
    { "_id" : "-180.00.00.090.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ -180, 0 ], [ 0, 0 ], [ 0, 90 ], [ -180, 90 ], [ -180, 0 ] ] ] }, "zoom" : 1 }
    { "_id" : "0.00.0180.090.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 180, 0 ], [ 180, 90 ], [ 0, 90 ], [ 0, 0 ] ] ] }, "zoom" : 1 }

which are the tiles 2,3,4. In other words this two documents where left behind:

    {
        "_id" : "-180-9018090",   ---> world wide tile
        "geometry" : {
            "type" : "Polygon",
            "coordinates" : [
                [
                    [
                        -180,
                        -90
                    ],
                    [
                        180,
                        -90
                    ],
                    [
                        180,
                        90
                    ],
                    [
                        -180,
                        90
                    ],
                    [
                        -180,
                        -90
                    ]
                ]
            ]
        },
        "zoom" : 0
    }
{
    "_id" : "-180.0-90.00.00.0",  ----> tile number 1 of the example
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [
                    -180,
                    -90
                ],
                [
                    0,
                    -90
                ],
                [
                    0,
                    0
                ],
                [
                    -180,
                    0
                ],
                [
                    -180,
                    -90
                ]
            ]
        ]
    },
    "zoom" : 1
}

Now, my first guess would be that the worldwide document isn't selected because it's too big, and maybe the other one for conventional reasons ? Can someone validate or disprove this? Thank you

EDIT:

This could be an explanation of why the bigger one is not selected, i'll test it out.

EDIT:

Looks like it's not. The CRS only works if you are trying to intersect two polygons, so the input query cannot be a point, as this page indicates.

This is not a solution, just a notification that indeed mongodb allows CRS only if you query a Polygon. ( see this ). But even if you query a Polygon, I cannot see how it would have helped: you want to specify that the Polygon that is in the DB is "big", bigger than semi-sphere (a polygon that spans more than half of the Earth's surface). So it make sense to me to enable CRS upon insertion.

I have raised an issue in mongodb Jira .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM