-
-
Save HenderOrlando/9cf530a185f8cc5eb16daf83d2fcf2b8 to your computer and use it in GitHub Desktop.
Geospatial example in Sails.js using native MongoDB query
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
}); | |
}); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports.models = { | |
// Geospatial queries require MongoDB connection (sails-mongo) | |
connection: 'someMongodbServer' | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); | |
}); | |
}); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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