Can't extract geo keys' even though the GeoJSON is valid - mongodb

I have a collection in MongoDB with a 2dsphere index. The object I want to save looks like this:
{
"type" : "Polygon",
"coordinates" : [
[
[
5.052617929724351,
52.64653192570052
],
[
5.051738165167465,
52.64765805672784
],
[
5.054162882116928,
52.64831549553909
],
[
5.054592035559312,
52.64780777138566
],
[
5.055364511755601,
52.64790541110375
],
[
5.056094072607651,
52.64688343792051
],
[
5.054237983969346,
52.64661654927096
],
[
5.052617929724351,
52.64653192570052
]
]
]
}
According to http://geojsonlint.com/ this is perfectly valid GeoJSON. However MongoDB says it can't extract the geo keys because the GeoJSON might be malformed.
Can anyone help me out and spot the mistake?
This is the MongoDB error I get:
insertDocument :: caused by :: 16755 Can't extract geo keys from object, malformed geometry?

The problem is that you are not providing the name of the top level object that the GeoJSON would be assigned to.
You must have created the "2dsphere" index on the "coordinates" field. Instead you want to create it on the field that this entire GeoJSON value will be assigned to.
db.geo.createIndex({"location":"2dsphere"})
db.geo.insert({"location" : {
"type" : "Polygon",
"coordinates" : [
[ <list of your-coord-pairs> ]
]
}})
WriteResult({ "nInserted" : 1 })

Related

Creating a Geospatial Index on MongoDB

I am using the Geospatial Feature of MongoDB and my typical document looks like:
{
"_id" : ObjectId("574ebe5f9985eb31a9bdbe39"),
"geoareaName" : "GEOAREA2",
"loc" : {
"type" : "Polygon",
"coordinates" : [
[
[
13.870663396091308,
3.481292724609375
],
[
13.875996314658366,
3.482236862182617
],
[
13.872746581997381,
3.484210968017578
],
[
13.871829982503106,
3.484961986541748
],
[
13.870663396091308,
3.481292724609375
]
]
]
},
"color" : "#ff0000",
"_version" : 4,
"active" : false
}
and then there are some point locations which I query using the $geoIntersects keyword and it works like a charm. However, to optimally use the geospatial feature of mongo I want to put indexes around the location.
Can someone please suggest what should be the correct approach for that.
Create a 2dsphere index on loc.
db.collection.createIndex( { loc : "2dsphere" } )
It's pretty basic but it works great!

How do I query a GeometryCollection in Mongodb?

I am trying to run a mongoldb query on a GEOjson collection of points and polygons but I'm struggling. I am new to GEOjson and Mongodb and haven't been able to find any examples on how to do this via google search and S.O. search so I'm hoping someone can shed some light on my issue.
I have created a 2DSphere index on geometry.coordinates - not sure if that's correct or not.
My overall objective is to return all points within the current map view and add both the point and the polygon associated to the map. I am using Leaflet.js and understand how to add to the map, but I can't figure out the query on Mongodb to get the results.
Just looking to find out if my GEOjson is correct and maybe an example on how I would perform the search on my GeometryCollection and get the point using $geowithin and then get the associated polygon.
Here's an example of my GEOjson-
{
"_id" : ObjectId("5709722f4044ccc4b8291651"),
"type" : "Feature",
"geometry" : {
"type" : "GeometryCollection",
"geometries" : [
{
"type" : "Point",
"coordinates" : [
-105.960805584616,
39.4671896545181
]
},
{
"type" : "Polygon",
"coordinates" : [
[
[
-105.96110187372227,
39.463449804295806
],
[
-105.96602244670311,
39.462956063632134
],
[
-105.96577627486317,
39.46671592928652
],
[
-105.96553007974012,
39.470475771657675
],
[
-105.96047434857059,
39.47089761421853
],
[
-105.95541854755197,
39.471319247231634
],
[
-105.95579990086372,
39.46763141937862
],
[
-105.95618125417559,
39.463943568242485
],
[
-105.96110187372227,
39.463449804295806
]
]
]
}
]
},
"properties" : {
"processed" : "Yes"
}
}

Mongo malformed geo-query with MultiPolygon

I'm using $geoWithin on a large list of geographic regions, defined in geoJSON. Some of these regions are Polygons, and some are MultiPolygons.
MultiPolygons fail, with a non-descript Malformed geo query error. After experimenting with the repl, I found I can't get mongo to take any MultiPolygon.
This is a minimal example:
{
"type" : "MultiPolygon",
"coordinates" : [
[
[
[ 9.560016, 42.152492 ],
[ 8.746009, 42.628122 ],
[ 9.390001, 43.009985 ],
[ 9.560016, 42.152492 ]
]
]
]
}
GEOJSONLint says it's fine, and shows me a triangle in the map, but mongo won't take it.
How is it malformed?

Why am I getting values outside polygon with geoIntersect

I am using mongodb with polygons stored with geometry in this format
"geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 2.0315, 85.8546219515 ], [ 2.0315, 86.1673780485 ], [ 1.7185, 86.1673780485 ], [ 1.7185, 85.8546219515 ], [ 2.0315, 85.8546219515 ] ] ] }
I am trying to use geoIntersect and query a rectangle polygon using something like this:
find({geometry:{$geoIntersects:{$geometry:{"type": "Polygon", "coordinates":[ [[12,20], [13,20], [13,18], [12,18], [12,20]]]}}}})
When I do small queries like that, the results are fine, but when I expand to really large boxes:
find({geometry:{$geoIntersects:{$geometry:{"type": "Polygon", "coordinates":[ [[-166.2890625,46.55886030311719], [-166.2890625,47.39834920035926], [12.12890625,47.39834920035926], [12.12890625,46.55886030311719], [-166.2890625,46.55886030311719]]]}}}})
then I start getting really odd results like
"geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 2.9684999999999997, 85.54162195149999 ], [ 2.9684999999999997, 85.8543780485 ], [ 2.6555, 85.8543780485 ], [ 2.6555, 85.54162195149999 ], [ 2.9684999999999997, 85.54162195149999 ] ] ] }
I am only returned a few polygons (4 total) from the db that are actually inside my input polygon:
"geometry":{"type":"Polygon","coordinates":[[[12.343499999999999,47.1416219515],[12.343499999999999,47.454378048500004],[12.0305,47.454378048500004],[12.0305,47.1416219515],[12.343499999999999,47.1416219515]]]}}
"geometry":{"type":"Polygon","coordinates":[[[12.343499999999999,46.829621951499995],[12.343499999999999,47.1423780485],[12.0305,47.1423780485],[12.0305,46.829621951499995],[12.343499999999999,46.829621951499995]]]}}
"geometry":{"type":"Polygon","coordinates":[[[-166.0935,46.5166219515],[-166.0935,46.829378048500004],[-166.4065,46.829378048500004],[-166.4065,46.5166219515],[-166.0935,46.5166219515]]]}}
"geometry":{"type":"Polygon","coordinates":[[[-166.0935,46.829621951499995],[-166.0935,47.1423780485],[-166.4065,47.1423780485],[-166.4065,46.829621951499995],[-166.0935,46.829621951499995]]]}}
I shouldn't have any latitudes in the 80's with my input. I don't know where these are coming from. They make up the majority of what is returned. (847/851 results)
I don't think the polygon fits in one hemisphere. From the $geoIntersects docs,
Any geometry specified with GeoJSON to $geoIntersects queries, must fit within a single hemisphere.

MongoDB can't parse query (2dsphere): $geoWithin:

I have the following objects in my Collection that look like the following:
{
"_id" : ObjectId("527d33a8623f6efd1c997440"),
"location" : {
"geometry" : {
"type" : "Point",
"coordinates" : [
-78.4067,
37.26725
]
},
"type" : "Feature",
"properties" : {
"name" : "Something here"
}
},
"name" : "Name of Object"
}
I have the following index:
{
"location.geometry" : "2dsphere"
}
I can do the following:
db.myCollection.find({'location.geometry':{'$near':{'$geometry':{'type':"Point", 'coordinates': [-78.406700,37.267250]}, '$maxDistance' : 1000 }}})
However, I can Not do the following:
db.myCollection.find( { 'location.geometry': { '$geoWithin':
{ '$geometry' :
{ 'type' : "Polygon",
'coordinates' : [ [ -118.108006, 34.046072], [ -117.978230, 34.041521] , [ -117.987328,33.913645 ]] } }
} } )
As it returns with the error:
error: {
"$err" : "can't parse query (2dsphere): { $geoWithin: { $geometry: { type: \"Polygon\", coordinates: [ [ -118.108006, 34.046072 ], [ -117.97823, 34.041521 ], [ -117.987328, 33.913645 ] ] } } }",
"code" : 16535
}
Am I using geoWithin wrong? Can it not be used on this index?
The polygon that you are providing for $geowithin query is incorrect. A polygon needs to have the same start and end point as per GeoJSON definition.
The correct query is:
db.myCollection.find( { 'location.geometry':
{ '$geoWithin':
{ '$geometry' :
{ 'type' : "Polygon",
'coordinates' : [
[ -118.108006, 34.046072],
[ -117.978230, 34.041521],
[ -117.987328,33.913645 ],
[ -118.108006, 34.046072]
]
}
}
}
}
);
Notice the updated coordinates array.
Clearly, what is mentioned here in MongoDB docs about implicit connection of Polygons is NOT incorrect. It says that when you define the polygon using $polygon in MongoDB, only then is the connection implicit. It says nothing about being smart and making an implicit connection in the GeoJSON polygon provided to the query.
In fact, if for some GeoJSON variable you are saying that its type is polygon and you are not connecting its start with the end, then you have not created a correct GeoJSON polygon in the first place.
There is an error in the MongoDB documentation on $geoWithin queries. While the documentation states that:
The last point specified is always implicitly connected to the first.
You can specify as many points, and therefore sides, as you like.
This is incorrect. The polygon needs to be closed. There is an open ticket about this in MongoDB Jira:
https://jira.mongodb.org/browse/DOCS-2029
So your first and last points need to be equal - you cannot depend on MongoDB to implicitly draw the last line of the polygon.