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
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.
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'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!
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 ]
}
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
]
}