diff --git a/helper/geojsonify.js b/helper/geojsonify.js index 82c4cf88..cf1f8744 100644 --- a/helper/geojsonify.js +++ b/helper/geojsonify.js @@ -19,7 +19,8 @@ var DETAILS_PROPS = [ 'localadmin', 'locality', 'neighbourhood', - 'confidence' + 'confidence', + 'distance' ]; diff --git a/middleware/distance.js b/middleware/distance.js new file mode 100644 index 00000000..3783119d --- /dev/null +++ b/middleware/distance.js @@ -0,0 +1,32 @@ +var geolib = require('geolib'); + + +function setup() { + + return computeDistances; +} + +function computeDistances(req, res, next) { + + // do nothing if no result data set + if (!req.results || !req.results.data) { + return next(); + } + + if ( !(req.clean.hasOwnProperty('lat') && req.clean.hasOwnProperty('lon')) ) { + return next(); + } + + req.results.data.forEach(function (place) { + // the result of getDistance is in meters, so convert to kilometers + place.distance = geolib.getDistance( + { latitude: req.clean.lat, longitude: req.clean.lon }, + { latitude: place.center_point.lat, longitude: place.center_point.lon } + ) / 1000; + }); + + next(); +} + + +module.exports = setup; diff --git a/package.json b/package.json index a1475a8e..d2853d8c 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "extend": "2.0.1", "geojson": "^0.2.1", "geojson-extent": "^0.3.1", + "geolib": "^2.0.18", "geopipes-elasticsearch-backend": "^0.2.0", "is-object": "^1.0.1", "markdown": "0.5.0", diff --git a/routes/v1.js b/routes/v1.js index 8179149f..592e6ce3 100644 --- a/routes/v1.js +++ b/routes/v1.js @@ -25,6 +25,7 @@ var controllers = { /** ----------------------- controllers ----------------------- **/ var postProc = { + distances: require('../middleware/distance'), confidenceScores: require('../middleware/confidenceScore'), renamePlacenames: require('../middleware/renamePlacenames'), geocodeJSON: require('../middleware/geocodeJSON'), @@ -70,6 +71,7 @@ function addRoutes(app, peliasConfig) { sanitisers.reverse.middleware, controllers.search(undefined, reverseQuery), // TODO: add confidence scores + postProc.distances(), postProc.renamePlacenames(), postProc.geocodeJSON(peliasConfig), postProc.sendJSON diff --git a/test/unit/middleware/distance.js b/test/unit/middleware/distance.js new file mode 100644 index 00000000..fd4c1490 --- /dev/null +++ b/test/unit/middleware/distance.js @@ -0,0 +1,41 @@ +var distance = require('../../../middleware/distance')(); + +module.exports.tests = {}; + +module.exports.tests.computeDistance = function(test, common) { + test('valid lat/lon and results', function(t) { + var req = { + clean: { + lat: 45, + lon: -77 + }, + results: { + data: [ + { + center_point: { + lat: 40, + lon: -71 + } + } + ] + } + }; + + var expected = 742.348; + distance(req, null, function () { + t.equal(req.results.data[0].distance, expected, 'correct distance computed'); + t.end(); + }); + }); +}; + +module.exports.all = function (tape, common) { + + function test(name, testFunction) { + return tape('[middleware] distance: ' + name, testFunction); + } + + for( var testCase in module.exports.tests ){ + module.exports.tests[testCase](test, common); + } +}; diff --git a/test/unit/run.js b/test/unit/run.js index c574fbc8..a8e27d93 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -22,6 +22,7 @@ var tests = [ require('./helper/outputSchema'), require('./helper/types'), require('./sanitiser/_geo_common'), + require('./middleware/distance'), ]; tests.map(function(t) {