$centerSphere is not returning any geojson polygons (mongoDB) - mongodb

I am having a lot of trouble with the following Mongo query
location: { $geoWithin: { $centerSphere: [[lon,lat],radians] } }
It only returns geoJSON Points and ignores all my geoJSON Polygons for some reason. The documentation states:
You can use the $centerSphere operator on both GeoJSON objects and legacy coordinate pairs.
I am using Mongoose to run the queries and my geoJSON is coverted from WellKnown Text by the NPM module wellknown. This is how my geoJSON looks after the wellknown module has converted them:
"location": {
"coordinates": [
22.1,
33.3
],
"type": "Point"
}
and
"location": {
"coordinates": [
[
[
43,
30
],
[
40,
28
],
[
49,
27
],
[
43,
30
]
],
[
[
44,
28
],
[
44.7,
28.8
],
[
46,
28
],
[
44,
28
]
]
],
"type": "Polygon"
}
My Mongoose schema is defined as:
location: {
type: schema.Types.Mixed,
index: '2dsphere',
required: false
}
I should add that the withinPolygon methods work as expected and I get both the Points and Polygons returned. The following works completely fine:
location: { $geoWithin: { $geometry: geoJSON } }
Thank you for any help. I have read the documentation and can't see anywhere where it mentions that the $centerSphere only returns geoJSON Points.

With the recent release of MongoDB version 3.6.0-rc0, you can now query GeoJSON LineStrings and Polygons with $geoWithin geospatial operator $centerSphere.
See also SERVER-27968 more information about the update.

Related

MongoDB can't parse query (2dsphere): Java API

I have the following object in my Collection:
{
"_id":"test123",
"footprint":{
"type":"Polygon",
"coordinates":[
[
[10, 30], [20, 45], [38, 38], [43, 38], [45, 30], [10, 30]
]
]
}
}
with index of type "2dsphere" on "footprint" attribute.
Now, I would like to implements the geospatial query "overlaps", as implemented by ST_Overlaps in PostGIS: https://postgis.net/docs/ST_Overlaps.html.
Due to the fact that MongoDB doesn't support "overlap" natively (only within, intersect and near) and according to the above definition, I whould return all overlapping documents not totally within the search area.
Using mongo-java-drivers 3.12.8, I developed the following Bson filter:
Polygon polygon = new Polygon(
new PolygonCoordinates(
Arrays.asList(
new Position(41.62109375000001d, 38.087716380862716d),
new Position(41.870727539062514d, 37.998201197578084d),
new Position(41.72393798828124d, 38.01268326428104d),
new Position(41.62109375000001d, 38.087716380862716d)
)
)
);
Bson spatialFilter = Filters.and(
Filters.geoIntersects("footprint", polygon),
Filters.not(Filters.geoWithin("footprint", polygon))
);
But when I execute the following:
db.collection.find(spatialFilter);
I get the following error:
Query failed with error code 2 and error message 'can't parse extra field: $geoWithin: { $geometry: { type: "Polygon", coordinates: [ [ [ 41.62109375000001, 38.08771638086272 ], [ 41.87072753906251, 37.99820119757808 ], [ 41.72393798828124, 38.01268326428104 ], [ 41.62109375000001, 38.08771638086272 ] ] ] } }' on server localhost:27017
As explained here MongoDB can't parse query (2dsphere): two conditions, it seems that the "$and" wrapper filter is not correctly generated.
Am I wrong? Is there any workaround?
Thanks
Maybe, it was a bug in 3.12.8 version.
It seems fixed in 4.2.3 version

How to dynamically filter datasets based on their location

I'm trying to achieve the following behaviour with a mongodb query:
I have documents which have a field location and a 2dshere geospatial index on that field
The documents also have a field maxdistance
The location of the user is available in the variable user.gps as a GeoJSON point
The query currently looks like this:
query["location"] = {
$nearSphere: {
$geometry: user.gps,
$maxDistance: filterDistance
}
};
This query successfully selects all the datasets in a given filterDistance relative to the user.
What i'd like to have now is "If document.maxdistance field > 0 and the distance to the user is greater than document.maxdistance" do not select the dataset.
So i have documents that should not be found if the user lives in a distance greater than a given distance saved inside the document.
I don't know hot to express this in a mongodb query and i couldn't find any example of such a query.
$near/$nearSphere don't support per-document distance. Only per query. The main reason is sorting by distance. If you need only filtering you can use $geoIntersects/$geoWithin, but you will need to change documents to contain a polygon of the covered area, like a circle Pi*2*distance around it's location.
Example:
Assuming you have a document:
{
loc: { type: "Point", coordinates: [ 10, 20 ] },
distance: 10
}
So that it is returned when user's coordinate is within the radius, e.g. [12, 25], and is not returned when user's coordinate is outside, e.g. [12,30].
For that documents should be updated to convert loc/distance pair to a polygon. For the sake of simplicity I'll use octagon, but you may want to increase number of vertices for more accurate results:
{
loc: { type: "Point", coordinates: [ 10, 20 ] },
distance: 10,
area: {
type : "Polygon",
coordinates : [[
[ 17, 27 ],
[ 10, 30 ],
[ 3, 27 ],
[ 0, 20 ],
[ 3, 13 ],
[ 10, 10 ],
[ 17, 13 ],
[ 20, 20 ],
[ 17, 27 ]
]]
}
}
Then you can use $geoIntersects to find documents which area includes user's coordinates:
db.collection.find({
area: {
$geoIntersects: {
$geometry: { type: "Point" , coordinates: [ 12, 25] }
}
}
})

MongoDB Geospacial Query on MultiPolygon

I've been reading through mongo's docs on geospacial querying, and have things working well for singl Polygon types but am having trouble with MultiPolygon. What I want to do is essentially this:
Given a MultiPolygon outlining areas of exclusion:
{
"type" : "MultiPolygon",
"coordinates" : [
[
[
[
-117.873730659485,
33.6152089844919
],
[
-117.873065471649,
33.615048159758
],
[
-117.873044013977,
33.614690770386
],
[
-117.873666286469,
33.6146729008785
],
[
-117.873730659485,
33.6152089844919
]
]
]
]
}
I simply want to be able to pass in a Point to see if it is excluded. I've tried $geoIntersects just to see if it even can determine if a Point is included or not, but that doesn't work. In the end, I want to check that a point is not included within the exclusion list, but the query is simpler without the additional $not operator... Here's what I've been trying:
var geoPoint = {type: 'Point', coordinates: [-117.8731230, 33.6150696]};
db.myCollection.aggregate([
{$match: {'exclusionsPolygons': {$geoIntersects: {$geometry: geoPoint}}}}
]);
Note that if I do the same exact thing with a GeoJSON type of Polygon then it works just fine:
Given this single polygon:
{
"type" : "Polygon",
"coordinates" : [
[
[
-117.8711744,
33.6129677
],
[
-117.8751744,
33.6129677
],
[
-117.874444839148,
33.6162171973226
],
[
-117.87287399259,
33.6172714730352
],
[
-117.871410434393,
33.6165209730032
],
[
-117.8711744,
33.6129677
]
]
]
}
This query works just find and returns the item(s) whose singular polygon contains the point:
var geoPoint = {type: 'Point', coordinates: [-117.8731230, 33.6150696]};
db.myCollection.aggregate([
{$match: {'singularPolygon': {$geoIntersects: {$geometry: geoPoint}}}}
]);
After some tinkering, it turns out the result set was right and I was wrong...
I was using the areas of interest on the map to get addresses to try to query against. One such place was, I thought, in an exclusion polygon:
However, once I made the polygon larger the result set started coming back as I expected it to... So, I reset the polygon and double-checked the map content, finding that if I zoom in further the area of interest was actually excluded from the polygon as there are multiple areas of interest contained:
Whoops - my bad :)

Limitations on mongodb Polygon

I'm trying to insert a Polygon on a mongodb document
polygons: {
type: "Polygon",
coordinates: [
[
[ -104.6093679, 50.449794 ],
[ -104.6093679, 50.449794 ],
[ -104.6093863, 50.449794 ],
[ -104.6093863, 50.449794 ],
[ -104.6093679, 50.449794 ]
]
]
}
But mongodb throws this exception: "Can't extract geo keys from object, malformed geometry?" I also checked the correctness of index and verified that with the same structure but different data, insert works well. My question is: are there some limitations on Polygon area that mongodb can manage?

Does MongoDB support GIS geofencing with $geoWithin?

I would like to have a MongoDB collection and each document contains a geospatial polygon defined by latitude/longitude points (in GeoJSON). Then, I would like to take any given longitude/latitude point and check if it resides within any of the MongoDB polygons defined in the documents. Hypothetically, this is what the documents would look like.
{
"type" : "congressional",
"points" : [
{ "coords" : [
-141.0205,
70.0187 ]
},
...
{ "coords" : [
-141.0205,
70.0187 ]
}
]
}
Or maybe like so:
{ loc :
{ type : "Polygon" ,
coordinates : [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ]
} }
And then I would query it, hypothetically, like so (most likely with Mongo's $geoWithin):
db.places.find( { loc : { $geoWithin : { $geometry : "EACH DOCUMENT IN COLLECTION"} } } )
Is geofencing, or something similar, possible to do with the current MongoDB feature-set? If so, how would it be done?
I believe you would have to first find every document from the collection., and then make a "$geoWithin" query for every document, passing in the Polygon to test against for each case.
Depending on the number of documents in your collection, that may or may not provide sufficient performance.
MongoDB has full support for geofencing or finding documents whose geometry intersects with a given geometry (point, polygon). The query below is an example. geometry of Collection is the field containing the geometry.
Document Example:
{ "geometry": {
"type": "Polygon",
"coordinates": [
[
[
-74.001487,
40.692346
],
[
-74.001755,
40.692057
],
[
-74.000977,
40.691951
],
[
-74.000827,
40.692297
],
[
-74.001487,
40.692346
]
]
]
}
}
JS Query:
//find quests bots that matches the users location
await Collection.find({ geometry:
{ $geoIntersects:
{
{
type: "Point",
coordinates: [
-73.99460599999999,
40.7347229
]
}
}
}
});