You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

100 lines
2.9 KiB

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;