|
|
|
var url = require('url');
|
|
|
|
var geojsonify = require('../helper/geojsonify');
|
|
|
|
var _ = require('lodash');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a middleware function that converts elasticsearch
|
|
|
|
* results into geocodeJSON format.
|
|
|
|
*
|
|
|
|
* @param {object} [peliasConfig] api portion of pelias config
|
|
|
|
* @param {string} [basePath]
|
|
|
|
* @returns {middleware}
|
|
|
|
*/
|
|
|
|
function setup(peliasConfig, basePath) {
|
|
|
|
|
|
|
|
var opts = {
|
|
|
|
config: peliasConfig || require('pelias-config').generate().api,
|
|
|
|
basePath: basePath || '/'
|
|
|
|
};
|
|
|
|
|
|
|
|
function middleware(req, res, next) {
|
|
|
|
return convertToGeocodeJSON(req, res, next, opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
return middleware;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts elasticsearch results into geocodeJSON format
|
|
|
|
*
|
|
|
|
* @param {object} req
|
|
|
|
* @param {object} res
|
|
|
|
* @param {object} next
|
|
|
|
* @param {object} opts
|
|
|
|
* @param {string} opts.basePath e.g. '/v1/'
|
|
|
|
* @param {string} opts.config.host e.g. 'pelias.mapzen.com'
|
|
|
|
* @param {string} opts.config.version e.g. 1.0
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
function convertToGeocodeJSON(req, res, next, opts) {
|
|
|
|
|
|
|
|
res.body = { geocoding: {} };
|
|
|
|
|
|
|
|
// REQUIRED. A semver.org compliant version number. Describes the version of
|
|
|
|
// the GeocodeJSON spec that is implemented by this instance.
|
|
|
|
res.body.geocoding.version = '0.2';
|
|
|
|
|
|
|
|
// OPTIONAL. Default: null. The attribution of the data. In case of multiple sources,
|
|
|
|
// and then multiple attributions, can be an object with one key by source.
|
|
|
|
// Can be a URI on the server, which outlines attribution details.
|
|
|
|
res.body.geocoding.attribution = opts.config.attributionURL || url.format({
|
|
|
|
protocol: req.protocol,
|
|
|
|
host: req.get('host'),
|
|
|
|
pathname: 'attribution'
|
|
|
|
});
|
|
|
|
|
|
|
|
// OPTIONAL. Default: null. The query that has been issued to trigger the
|
|
|
|
// search.
|
|
|
|
// Freeform object.
|
|
|
|
// This is the equivalent of how the engine interpreted the incoming request.
|
|
|
|
// Helpful for debugging and understanding how the input impacts results.
|
|
|
|
res.body.geocoding.query = req.clean;
|
|
|
|
|
|
|
|
// remove arrays produced by the tokenizer (only intended to be used internally).
|
|
|
|
delete res.body.geocoding.query.tokens_complete;
|
|
|
|
delete res.body.geocoding.query.tokens_incomplete;
|
|
|
|
|
|
|
|
// OPTIONAL. Warnings and errors.
|
|
|
|
addMessages(req, 'warnings', res.body.geocoding);
|
|
|
|
addMessages(req, 'errors', res.body.geocoding);
|
|
|
|
addMessages(req, 'debug', res.body.geocoding);
|
|
|
|
|
|
|
|
// OPTIONAL
|
|
|
|
// Freeform
|
|
|
|
addEngine(opts.config.version, res.body.geocoding);
|
|
|
|
|
|
|
|
// response envelope
|
|
|
|
res.body.geocoding.timestamp = new Date().getTime();
|
|
|
|
|
|
|
|
// convert docs to geojson and merge with geocoding block
|
|
|
|
_.extend(res.body, geojsonify(req.clean, res.data || []));
|
|
|
|
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
|
|
|
|
function addMessages(req, msgType, geocoding) {
|
|
|
|
if (req.hasOwnProperty(msgType) && req[msgType].length) {
|
|
|
|
// cleanup arrays to make sure there are no duplicates
|
|
|
|
geocoding[msgType] = _.uniq(req[msgType]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function addEngine(version, geocoding) {
|
|
|
|
geocoding.engine = {
|
|
|
|
name: 'Pelias',
|
|
|
|
author: 'Mapzen',
|
|
|
|
version: version
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = setup;
|