Skip to content

Instantly share code, notes, and snippets.

@HenderOrlando
Forked from PascalAnimateur/Place.js
Created April 6, 2016 00:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HenderOrlando/9cf530a185f8cc5eb16daf83d2fcf2b8 to your computer and use it in GitHub Desktop.
Save HenderOrlando/9cf530a185f8cc5eb16daf83d2fcf2b8 to your computer and use it in GitHub Desktop.
Geospatial example in Sails.js using native MongoDB query
module.exports.bootstrap = function(cb) {
// Ensure we have 2dsphere index on coordinates attribute of Place.
sails.models.place.native(function (err, collection) {
collection.ensureIndex({ coordinates: '2dsphere' }, function () {
// It's very important to trigger this callback method when you are finished
// with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap)
cb();
});
});
};
module.exports.models = {
// Geospatial queries require MongoDB connection (sails-mongo)
connection: 'someMongodbServer'
};
/* Place model */
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
// This is the attribute used for the place's geolocation.
// Be careful to store it as [ lng, lat ] or else geoNear queries will give imprecise results.
coordinates: {
type: 'json',
required: true
}
},
/**
* Find places closer than a certain distance (in km) from a specified location [ lng, lat ].
* @param conditions
* JSON object should look like this:
* {
* lng: -72.213,
* lat: 45.012,
* maxDistance: 100,
* limit: 20,
* }
*
* @param callback (err, results)
* Returns an array of results (ordered by increasing distance), it looks like this:
* [
* {
* dis: 10.321,
* obj: { JSON object of Place }
* },
* {
* dis: 20.123,
* obj: { JSON object of Place }
* }
* ]
*/
findNear: function (conditions, callback) {
Place.native(function (err, collection) {
if (err) return callback(err);
collection.geoNear({
type: "Point" ,
coordinates: [ conditions.lng, conditions.lat ]
}, {
limit: conditions.limit || 30,
maxDistance: conditions.maxDistance * 1000.0,
distanceMultiplier: 0.001,
spherical : true
}, function (err, places) {
if (err) return callback(err);
return callback(null, places.results);
});
});
}
};
/* Place controller */
module.exports = {
/**
* Create two dummy places.
*/
dummy: function (req, res) {
Place.create({
name: 'New Richmond',
coordinates: [ -65.8716805, 48.1804069 ]
}, function (err, place) {
if (err) return res.negotiate(err);
console.log('Place created: ', place);
res.ok();
});
Place.create({
name: 'Montreal',
coordinates: [ -73.5647636, 45.5158157 ]
}, function (err, place) {
if (err) return res.negotiate(err);
console.log('Place created: ', place);
res.ok();
});
},
/**
* Find places closer than a certain distance (in km) from a specified location [ lng, lat ].
*/
search: function (req, res) {
// TODO: Default values and conditions validation should go in Place.findNear
var conditions = {
lng: parseFloat(req.param('lng')) || 0,
lat: parseFloat(req.param('lat')) || 0,
maxDistance: parseFloat(req.param('maxDistance')) || 1000,
limit: req.param('limit') || 30,
};
Place.findNear(conditions, function (err, results) {
if (err) return res.negotiate(err);
return res.json(results);
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment