using mongo, I would like to compare a user's geo coordinates to a collection of documents each representing a defined geographical boundary. This is what i have thought to do, but cant get working. Other suggestions to get the same result are also welcome.
A document from the collection looks like this (those are manhattan coordinates, if you draw a line in sequence from one coordinate to the next, it wraps manhattan)
{
"__v" : 1,
"_id" : ObjectId("53220803a74a16da9c729202"),
"name" : "Manhattan",
"boundary" : {
"type" : "Polygon",
"coordinates" : [
[
[
-74.01237999999999,
40.69967
],
[
-73.97895,
40.71076
],
[
-73.97169,
40.73049
],
[
-73.92828,
40.79605
],
[
-73.95547999999999,
40.82635
],
[
-74.00901,
40.75431
],
[
-74.01961,
40.7059
]
]
]
}
}
i then use the following query to make my check
db.collection.find( { boundary :
{ $geoIntersects :
{ $geometry :
{ type : "Point" ,
coordinates : [ [user_long, user_lat] ]
} } } } ).exec(function(err, city){
console.log(err, "error");
res.send({agent_count : city});
});
Related
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!
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"
}
}
I have the following document in the entities collection at Mongo (a 2dsphere index for location.coords is in place):
> db.entities.find({},{location: 1}).pretty()
{
"_id" : {
"id" : "en3",
"type" : "t",
"servicePath" : "/"
},
"location" : {
"attrName" : "position",
"coords" : {
"type" : "MultiPoint",
"coordinates" : [
[
-3.691944,
40.418889
],
[
4.691944,
45.418889
]
]
}
}
}
As far as I have checked, $geoWithin only matches when the geometry includes all the points of the MultiPoint, e.g:
> db.entities.find({"location.coords": { $geoWithin: { $centerSphere: [ [ -3.691944, 40.418889 ], 0.002118976612776644 ] } } })
// Small circle centered at first point, but without covering the second point: it doesn't matchh
> db.entities.find({"location.coords": { $geoWithin: { $centerSphere: [ [ -3.691944, 40.418889 ], 2 ] } } })
// Big circle centered at first point covering also the second point: it matches
However, I would like to have a query to match if at least one point of the MultiPoint matches. I have read about the $geoIntersects operator. I have tried just replace $geoWithin by $geoIntersect in my query, but it doesn't work:
> db.entities.find({"location.coords": { $geoIntersects: { $centerSphere: [ [ -3.691944, 40.418889 ], 0.002118976612776644 ] } } })
error: {
"$err" : "Can't canonicalize query: BadValue bad geo query",
"code" : 17287
}
Reading the $geoIntersects operator, it seems that it can be only used with polygons or multi-polygons, but it doesn't mention circles. I wonder if I'm missing something, because this "asymmetry" between $geoWithin and $geoIntersects seems to be a bit weird...
Thus, is there any way of doing a geo-query using a circle as area to match at least one of the points of MultiPoint object?
I think I have found the answer at the end. It can be done with the $near operator, in the following way:
db.entities.find({"location.coords": { $near: { $geometry: { type: "Point", "coordinates": [ -3.691944, 40.418889 ] }, $maxDistance: 0.5 } }})
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 })
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.