Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb $geoIntersect issue

I have a collection with a property 'place' as below.

"place" : {
    "name" : "Central Region",
    "country" : "Country_A",
    "coor_type" : "Polygon",
    "coordinates" : [ 
        [ 
            [ 
                103.749959507073, 
                1.2123138339349
            ], 
            [ 
                103.918426999964, 
                1.2123138339349
            ], 
            [ 
                103.918426999964, 
                1.36874499902569
            ], 
            [ 
                103.749959507073, 
                1.36874499902569
            ]
        ]
    ]
}

I'm trying to use $geoInterset operator to get back a list of documents where place.coordinates intersect with a rectangle defined by two points.

[ [103.591247, 1.222136], [104.040313, 1.477497] ] 

where the first point is bottom left corner and the other top right corner of the rectangle.

I wrote a query:

db.Document.find(
    {'place.coordinates':
        {$geoIntersects: 
            {$geometry:
                {type:'Polygon'
                , coordinates:[[103.591247,1.222136],[104.040313,1.477497]]
                }
            }
        }
    }
);

However, mongodb keep complaining

error: {
    "$err" : "Malformed geo query: { $geoIntersects: { $geometry: 
    { type:\"Polygon\", 
        coordinates:[[103.591247,1.222136],[104.040313,1.477497]]
    }}}",
"code" : 16677}

I have tried different types like 'Box' and 'LineString'. Box will give similar error. LineString doesn't complain but won't return any results either.

What am I doing wrong here? Any advice?

like image 927
Lee Avatar asked Nov 19 '25 13:11

Lee


1 Answers

The main problem is that the place document and query isn't a proper Polygon GeoJSON document.

Here's how to fix it.

1)

The first and last coordinates for a LinearRing needs to be the same.

Polygons consist of an array of GeoJSON LinearRing coordinate arrays. These LinearRings are closed LineStrings. Closed LineStrings have at least four coordinate pairs and specify the same position as the first and last coordinates. -- MongoDb doc - Polygon

2)

Rename coor_type to type to conform to the GeoJSON standard.

{ <location field>: { type: "<GeoJSON type>" , coordinates: <coordinates> } }

In order to index GeoJSON data, you must store the data in a location field that you name. The location field contains a subdocument with a type field specifying the GeoJSON object type and a coordinates field specifying the object’s coordinates. Always store coordinates in longitude, latitude order. Mongodb docs - geojson polygon

Sample GeoJSON polygon doc insertion:

var obj = {
    "place": {
        "name": "Central Region",
        "country": "Country_A",
        "type": "Polygon",
        "coordinates": [
            [
                [
                    103.749959507073,
                    1.2123138339349
                ],
                [
                    103.918426999964,
                    1.2123138339349
                ],
                [
                    103.918426999964,
                    1.36874499902569
                ],
                [
                    103.749959507073,
                    1.36874499902569
                ],
                [
                    103.749959507073,
                    1.2123138339349
                ]
            ]
        ]
    }
};

db.geo.drop();
db.geo.insert( obj );

//Use the 2dsphere index to validate your GeoJSON format
// and speed up queries
db.geo.ensureIndex({ "place"  : "2dsphere" })

3)

Make sure your query has a proper Polygon value and that searching on the field that contains the type and coordinates field. You were searching on the field place.coordinates, when it should have been place.

Sample $geoIntersects Query

db.geo.find({
    place: {
        $geoIntersects: {
            $geometry: {
                type: "Polygon",
                coordinates: [
                    [
                        [
                            103.749959507073,
                            1.2123138339349
                        ],
                        [
                            103.918426999964,
                            1.2123138339349
                        ],
                        [
                            103.918426999964,
                            1.36874499902569
                        ],
                        [
                            103.749959507073,
                            1.36874499902569
                        ],
                        [
                            103.749959507073,
                            1.2123138339349
                        ]
                    ]
                ]
            }
        }
    }
})
like image 147
Larry Battle Avatar answered Nov 22 '25 03:11

Larry Battle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!