mirror of https://github.com/pelias/api.git
Peter Johnson
10 years ago
11 changed files with 225 additions and 5 deletions
@ -0,0 +1,32 @@
|
||||
|
||||
var logger = require('../src/logger'), |
||||
responder = require('../src/responder'), |
||||
query = require('../query/suggest'), |
||||
backend = require('../src/backend'); |
||||
|
||||
module.exports = function( req, res, next ){ |
||||
|
||||
var reply = { |
||||
date: new Date().getTime(), |
||||
body: [] |
||||
}; |
||||
|
||||
var cmd = { |
||||
index: 'pelias', |
||||
body: query( req.clean ) // generate query from clean params
|
||||
}; |
||||
|
||||
// Proxy request to ES backend & map response to a valid FeatureCollection
|
||||
backend().client.suggest( cmd, function( err, data ){ |
||||
|
||||
if( err ){ return responder.error( req, res, next, err ); } |
||||
if( data && data.pelias && data.pelias.length ){ |
||||
|
||||
// map options to reply body
|
||||
reply.body = data['pelias'][0].options; |
||||
} |
||||
|
||||
return responder.cors( req, res, reply ); |
||||
}); |
||||
|
||||
}; |
@ -0,0 +1,12 @@
|
||||
|
||||
// querable indeces
|
||||
|
||||
module.exports = [ |
||||
'geoname', |
||||
'osmnode', |
||||
'osmway', |
||||
'admin0', |
||||
'admin1', |
||||
'admin2', |
||||
'neighborhood' |
||||
]; |
@ -0,0 +1,31 @@
|
||||
|
||||
var logger = require('../src/logger'); |
||||
|
||||
// Build pelias suggest query
|
||||
function generate( params ){ |
||||
|
||||
var cmd = { |
||||
'pelias' : { |
||||
'text' : params.input, |
||||
'completion' : { |
||||
'size' : params.size, |
||||
'field' : 'suggest', |
||||
'context': { |
||||
'dataset': params.layers, |
||||
'location': { |
||||
'value': [ params.lon, params.lat ], |
||||
|
||||
// // commented out until they fix the precision bug in ES 1.3.3
|
||||
'precision': 2 // params.zoom > 9 ? 3 : (params.zoom > 7 ? 2 : 1)
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
logger.log( 'cmd', JSON.stringify( cmd, null, 2 ) ); |
||||
return cmd; |
||||
|
||||
} |
||||
|
||||
module.exports = generate; |
@ -0,0 +1,77 @@
|
||||
|
||||
var logger = require('../src/logger'), |
||||
indeces = require('../query/indeces'); |
||||
|
||||
// validate inputs, convert types and apply defaults
|
||||
function sanitize( params, cb ){ |
||||
|
||||
var clean = {}; |
||||
|
||||
// ensure the input params are a valid object
|
||||
if( Object.prototype.toString.call( params ) !== '[object Object]' ){ |
||||
params = {}; |
||||
} |
||||
|
||||
// input text
|
||||
if('string' !== typeof params.input || !params.input.length){ |
||||
return cb( 'invalid input text length, must be >0' ); |
||||
} |
||||
clean.input = params.input; |
||||
|
||||
// total results
|
||||
var size = parseInt( params.size, 10 ); |
||||
if( !isNaN( size ) ){ |
||||
clean.size = Math.min( size, 40 ); // max
|
||||
} else { |
||||
clean.size = 10; // default
|
||||
} |
||||
|
||||
// which layers to query
|
||||
if('string' === typeof params.layers && params.layers.length){ |
||||
var layers = params.layers.split(',').map( function( layer ){ |
||||
return layer.toLowerCase(); // lowercase inputs
|
||||
}); |
||||
for( var x=0; x<layers.length; x++ ){ |
||||
if( -1 === indeces.indexOf( layers[x] ) ){ |
||||
return cb( 'invalid layer, must be one or more of ' + layers.join(',') ); |
||||
} |
||||
} |
||||
clean.layers = layers; |
||||
} |
||||
else { |
||||
clean.layers = indeces; // default (all layers)
|
||||
} |
||||
|
||||
// lat
|
||||
var lat = parseFloat( params.lat, 10 ); |
||||
if( isNaN( lat ) || lat < 0 || lat > 90 ){ |
||||
return cb( 'invalid lat, must be >0 and <90' ); |
||||
} |
||||
clean.lat = lat; |
||||
|
||||
// lon
|
||||
var lon = parseFloat( params.lon, 10 ); |
||||
if( isNaN( lon ) || lon < -180 || lon > 180 ){ |
||||
return cb( 'invalid lon, must be >-180 and <180' ); |
||||
} |
||||
clean.lon = lon; |
||||
|
||||
// zoom level
|
||||
var zoom = parseInt( params.zoom, 10 ); |
||||
if( !isNaN( zoom ) ){ |
||||
clean.zoom = Math.min( zoom, 18 ); // max
|
||||
} else { |
||||
clean.zoom = 10; // default
|
||||
} |
||||
|
||||
return cb( undefined, clean ); |
||||
|
||||
} |
||||
|
||||
module.exports = function( req, res, next ){ |
||||
sanitize( req.query, function( err, clean ){ |
||||
if( err ){ next( err ); } |
||||
req.clean = clean; |
||||
next(); |
||||
}); |
||||
}; |
@ -0,0 +1,21 @@
|
||||
|
||||
var Backend = require('geopipes-elasticsearch-backend'), |
||||
backends = {}, |
||||
client; |
||||
|
||||
// set env specific client
|
||||
if( process.env.NODE_ENV === 'test' ){ |
||||
client = require('./pelias-mockclient'); |
||||
} else { |
||||
client = require('pelias-esclient')(); |
||||
} |
||||
|
||||
function getBackend( index, type ){ |
||||
var key = ( index + ':' + type ); |
||||
if( !backends[key] ){ |
||||
backends[key] = new Backend( client, index, type ); |
||||
} |
||||
return backends[key]; |
||||
} |
||||
|
||||
module.exports = getBackend; |
@ -0,0 +1,5 @@
|
||||
module.exports = { |
||||
log: console.log.bind( console ), |
||||
warn: console.warn.bind( console ), |
||||
error: console.error.bind( console ) |
||||
}; |
@ -0,0 +1,33 @@
|
||||
|
||||
// send a reply that is capable of JSON, CORS and JSONP
|
||||
function cors( req, res, obj ){ |
||||
res.header('Charset','utf8'); |
||||
res.header('Cache-Control','public,max-age=60'); |
||||
res.header('Access-Control-Allow-Origin', '*'); |
||||
res.header('Access-Control-Allow-Methods', 'GET'); |
||||
res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); |
||||
res.header('Access-Control-Allow-Credentials', true); |
||||
res.header('X-Powered-By', 'pelias'); |
||||
|
||||
// jsonp
|
||||
if( req.query && req.query.callback ){ |
||||
res.header('Content-type','application/javascript'); |
||||
return res.send( req.query.callback + '('+ JSON.stringify( obj ) + ');' ); |
||||
} |
||||
|
||||
// regular json
|
||||
res.header('Content-type','application/json'); |
||||
return res.json( obj ); |
||||
} |
||||
|
||||
// send an error
|
||||
function error( req, res, next, err ){ |
||||
console.error( 'application error:', err ); |
||||
// mask error from user (contains paths)
|
||||
return cors( req, res, { error: 'application error' } ); |
||||
} |
||||
|
||||
module.exports = { |
||||
cors: cors, |
||||
error: error |
||||
}; |
Loading…
Reference in new issue