I am working on an application that will display the posts of people within a certain amount of distance of their location.
Whenever a post is created a value of location is created which is stored with: {"lat":39.7230949,"lng":-104.83521619999999}. The lat and longitude of the current location when the post was made.
This is from a function, Geolocation.latLng();, which prints out the object with the lat and lng of the current device.
I am now trying to figure out how to have the page which lists all the post, only show post that fall within a radius of the devices current location.
Here is my current function which lists all the post from my database.
Template.yakResults.searchResults = function () {
var keyword = Session.get("search-query");
var query = new RegExp( keyword, 'i' );
var results = Yaks.find( { $or: [{'yak': query}] }, {sort: {score: -1}});
return {results: results};
}
What do I have to do to get the results to be with say 10 mile radius of the devices current long/lat which can be found with the function mentioned above.
I imagine I use an if statement of some sort or maybe a filer when I am finding the posts in the Yaks collection?
Does any one have any idea on how I can filter the collection of posts to do something similar to this?
If i need to post up more code to make it easier to understand my question please let me know and I will.
Figured it out. For any one who may be trying to do something similar in the future, here is what I did.
First I had have the posts location formatted to geoJSON before it could go into the database. Here is the code I used in order to achieve this.(NOTE: Gelocation.latLng(); function is from this meteor plugin(https://atmospherejs.com/mdg/geolocation)).
This is the code called whenever the yak is submitted.
Template.yaksSubmit.events({
'submit .yaksSubmitForm': function(event) {
event.preventDefault();
var yak = event.target.yak.value; //get yak input value
var yakLocation = Geolocation.latLng(); // location of yak
var lat = yakLocation.lat;
var lng = yakLocation.lng;
//check if the value is empty
if(yak == "") {
alert("You can't inert a empty yak!");
} else {
Meteor.call('yakInsert', yak, lng, lat);
Router.go('yaksList');
}
}
});
Here is the yakInster method being called from my server.js file.
yakInsert: function(yak, lng, lat) {
var postId = Yaks.insert({
yak: yak,
loc : {
type: "Point",
coordinates: [ lng, lat ]
},
score: 0,
submitted: new Date(),
user: Meteor.userId(),
lng: lng,
lat: lat
// Geolocation.latLng(); JSON.stringify(yakLocation)
});
}
Then I stored the devices long/lat in into a Session with a helper.
Template.yakResults.helpers({
lat: function() {
var currentLocation = Geolocation.latLng(); // location of yak
var lat = currentLocation.lat;
Session.set("device-lat", lat);
},
lng: function() {
var currentLocation = Geolocation.latLng(); // location of yak
var lng = currentLocation.lng;
Session.set("device-lng", lng);
}
});
And then for my function to display all my posts I used the information explained in this blogpost on mongolab(http://blog.mongolab.com/2014/08/a-primer-on-geospatial-data-and-mongodb/). Here is what the function looks like
Template.yakResults.searchResults = function () {
var lng = Session.get("device-lng");
var lat = Session.get("device-lat");
var query = new RegExp( keyword, 'i' );
var results = Yaks.find( {
loc:
{ $near :
{
$geometry:{ type:"Point", coordinates:[ lng, lat]},
$minDistance: 0,
$maxDistance: 5000
}
}
});
return {results: results};
}
This got the posts to display with their order determined by the location of each yak/post relative to the device's location.
the $minDistance & $maxDistance are in meters.
This might not be the best way to make it work but It worked for me. Just thought I would share it incase anybody else could use it.