Mongo geoWithin error: Polygon coordinates must be an array - mongodb

I have a data set with geo points.
{ _id ...other fields... location: { type: "Point", coordinates: [0,0]}}
What I have been attempting to do is filter out and delete any documents that have points that are in water bodies. I downloaded and converted a shape file of the earth's water bodies and stored that in a separate collection in the same database.
I have been trying to use Mongo's geoWithin function, but am not able to get it to work for me when I specify the water body's polygon document. If I hard code a polygon it works, but I don't really want to type in all the earth's water polygons into my code...
This doesn't work:
var geo = {type: "Point", coordinates: [0,0]}
db.waterBodies.find({
geo: {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: "$geometry.coordinates"
}
}
}
}).count()
or this
var geo = {type: "Point", coordinates: [0,0]}
var poly = [[[0,0],[0,3],[3,0],[0,0]]]
db.data.find({
geo: {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: "$poly"
}
}
}
}).count()
It generates this error:
E QUERY [js] uncaught exception: Error: count failed: { "ok" : 0, "errmsg" : "Polygon coordinates must be an array", "code" : 2,
"codeName" : "BadValue" } :
_getErrorWithCode#src/mongo/shell/utils.js:25:13 DBQuery.prototype.count#src/mongo/shell/query.js:376:11 #(shell):1:1
This works and doesn't throw an error but requires hard coded values:
var geo = {type: "Point", coordinates: [0,0]}
db.data.find({
geo: {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: [[[0,0],[0,3],[3,0],[0,0]]]
}
}
}
}).count()
and this
db.data.find({
'location.coordinates': {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: [[[0,0],[0,3],[3,0],[0,0]]]
}
}
}
}).count()
I of coarse don't want the count but used that for testing purposes.
The simple answer for me would look something like this:
const polygons = await getPolygons(); //get all the polygons from the water body's collection
const filter = {
'location.coordinates': { //the points I want to filter
$geoWithin: { //could also be geoIntersects
$geometry: {
type: 'MultiPolygon',
coordinates: polygons.geometry.coordinates //the water body polygons
}
}
}
};
try {
await db.collection(collection).deleteMany(filter);
} catch (e) {
if (e instanceof MongoError) {
Logger.info('Error deleting log');
throw e;
}
}
I would want to use multipolygon since there are many water bodies.
So far I have read everything I can find on google but nothing has worked for me. All the examples I have found hard code an array for the coordinates, but I don't want to do this.
Please help and let me know if there is a way to do this or to remove all points that are not found on land.
Thanks in advance.

Does this work for you?
db.data.insert({
geo: {
type: "Point",
coordinates: [0,0]
}
})
db.polygons.insert({
geo: {
type: "Polygon",
coordinates: [[[0,0],[0,3],[3,0],[0,0]]]
}
})
var polygon = db.polygons.findOne()
db.data.find({
geo: {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: polygon.geo.coordinates
}
}
}
}).count()

Related

With Mongo's geoSpatial queries, how do I find where exactly an intersection occurred?

After drawing coordinates out on a map:
How do I find the coordinates of where the intersection occurred. I'm able to find what other LineStrings intersect with a specific LineString using this:
dbo.collection('loc').find({ "loc" : {
"$geoIntersects" : {
"$geometry" : obj //Specific Line String
}
} }).toArray(function(err, result) {
if (err) throw err
console.log('geointerescts ',result, '-=-=-=-')
})
And that returns the correct linestrings that it intersects with including itself. Something like this when I select Boston to New Orleans:
geointerescts [
{
_id: 5e88ecc6f7d52d95b764da87,
loc: {
Name: 'Directions from Boston, MA, USA to New Orleans, LA, USA',
type: 'LineString',
coordinates: [Array]
}
},
{
_id: 5e88f5875dfdd396d60e6fd4,
loc: {
Name: 'Directions from Chicago, IL, USA to Miami, FL, USA',
type: 'LineString',
coordinates: [Array]
}
},
{
_id: 5e88fe29a44e5ba462a702ad,
loc: {
Name: 'Directions from Austin, TX, USA to Charlotte, NC, USA',
type: 'LineString',
coordinates: [Array]
}
}
]
How do I get the points of intersection? Something like an array of coords in Georgia or Alabama in this example.

Return nearest point from an array of points using geospatial query in Mongodb

I have a collection that has an array of geo_json objects which looks like below:
{
id: 1,
title: 'test',
description: 'test',
locations: [
{
geo_json: {
type: 'Point',
coordinates: [121.21, 14.58]
}
},
{
geo_json: {
type: 'Point',
coordinates: [111.11, 10.28]
}
}
]
}
I have a 2DSphere index on that field, and my query looks like this:
query = {
'locations.geo_json': {
'$near': {
'$geometry': {
'type': 'Point',
'coordinates': [lng, lat]
},
'$maxDistance': 5000
}
}
}
It does what is supposed to do, which is, giving back the collection items that are within the designated radius (max distance), my problem is, I want to return only the actual point in the array that is "near" the coordinates specified, not the whole array of locations.
So for example, like the above, if I query with lat=14.58, lng=121.21, I'll get the item with id=1, but in the locations field I only need the matching location there, which is [121.21, 14.58] and not including [111.11, 10.28].
So it will return like this:
{
id: 1,
title: 'test',
description: 'test',
locations: [
{
geo_json: {
type: 'Point',
coordinates: [121.21, 14.58]
}
}
]
}
This is will help in plotting items that surround the point queried.
Hope someone can help :)

I couldn't able to fetch the records by using latitude and longitude, using Mongodb

I'm trying to fetch the records based on latitude and longitude using mongodb. I've gone through many examples nothing worked out for me.
Here is my Schema structue.
latlang: {
type: { type: String, default: 'Point'},
coordinates: [Number]
}
After storing the values it is looking like
latlang:{
type: "Point",
coordinates: [77.6836, 12.8486]
}
I'm setting index for the latlang field like
schema.index({ 'latlang.coordinates' : '2dsphere' });
I've multiple records like as below
latlang:{
type: "Point",
coordinates: [77.6836, 12.8486]
}
latlang:{
type: "Point",
coordinates: [77.5712, 12.9766]
}
latlang:{
type: "Point",
coordinates: [77.6174, 12.9226]
}
when i'm tring to fetch the records with the below query i'm getting null response
User.find({ loc:{ $near:{ $geometry: {type: "Point" , coordinates:[77.6974,12.9591] }, $maxDistance:10000 }}}).exec();
Any help would be greatly appreciated. Thanks in advance!
Create index for latlang:
db.<schema>.createIndex({"latlang":"2dsphere"});
then make a query like
User.find({
latlang: {
$near: {
$geometry: {
type: "Point",
coordinates: coords
},
$maxDistance: 10000
}
}
})
Hope this helps!

Get lat and lng using $near and $geometry not working on Mongo + meteor

I am trying to get the all docs that is within 200m from a center point but i am having this error
Exception from sub getLocNearMe id hg3jRDv8onsZEGvBM Error: Exception
while polling query
{"collectionName":"Col_Location","selector":{"loc":{"$near":{"$geometry":{"type":"Point","coordinates":[1.3852457,103.88112509999999]},"$maxDistance":200}}},"options":{"transform":null}}:
$near requires a point, given { type: "Point", coordinates: [
1.3852457, 103.8811251 ] }
client/component/map.jsx
navigator.geolocation.getCurrentPosition(function (pos) {
const sub = Meteor.subscribe("getLocNearMe", pos.coords.latitude, pos.coords.longitude)
Tracker.autorun(function () {
if (sub.ready()) {
Data.MarkersRawData = Col_Location.find().fetch()
}
})
})
lib/collections.jsx
Meteor.publish("getLocNearMe", function(lng, lat) {
check(lat, Number)
check(lng, Number)
const data = Col_Location.find({
loc: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [lng, lat]
},
$maxDistance: 200
}
}
})
console.log(data)
if (data) {
return data
}
return this.ready()
})
server/server.jsx
Col_AllQuestion._ensureIndex({"loc": "2dsphere"})
Col_Location.insert({
loc: {
type: "Point",
coordinates: [103.8, 1.31]
}
})
Testing you "Point" with http://geojsonlint.com/ gives several problems. It seems the (somewhat nitpicky) spec demands your keys to be quoted strings (which i think meteor handles for you) but also the fact that your coordinates are flipped (lat/long).
Putting you sample in like this gives a valid GeoJSON result:
{
"type": "Point",
"coordinates": [ 103.8811251, 1.3852457 ]
}

Sails.js $near query does not work and asks for indices

I'm trying to query the nearest points to some coordinate in Sails.js using MongoDB, but I'm getting the following error:
{ [MongoError: can't find any special indices: 2d (needs index), 2dsphere (needs index), for: { $near: { $geometry: { type: "Point", coordinates: [ "4.3795912", "51.9985675" ] }, $maxDistance: 1000 } }] name: 'MongoError' }
I made sure I had this in bootstrap.js:
sails.models.location.native(function (err, collection) {
collection.ensureIndex({ coordinates: '2dsphere' }, function () {
cb();
});
});
And my Location model looks like this:
attributes: {
coordinates: {
type: 'json'
},
user: {
model: 'user'
}
}
My controller code is the following:
Location.native(function(err, collection) {
var query = {};
collection.find(
query.coordinates = {
$near: {
$geometry: {
type: "Point",
coordinates: [
user.locations[0].lng,
user.locations[0].lat
]
},
$maxDistance : 1000
}
}
).toArray(function(err, result){
if(err) {
console.log(err);
}
else
return res.json(result);
});
});
I'm pretty sure I did just what I was supposed to do, but apparently I have done something wrong or I forgot something. Anyone any idea how to get this to work? Thanks.
I have solved the problem. There were two things I did wrong. First of all, every time I called sails lift the index I created would get removed and I did not know that. Second problem was that my location point was not in proper GeoJSON format:
{
"type": "Point",
"coordinates": [
4.373654,
51.998715
]
}