diff options
-rw-r--r-- | README | 59 | ||||
-rw-r--r-- | src/nodejs/start.js | 105 |
2 files changed, 164 insertions, 0 deletions
@@ -0,0 +1,59 @@ +=============== +osm@spline Xapi +=============== + +Aim +============ + +We like to rewrite some parts of the XApi needed for our own application. Our +aim is not get a full implementation of the Xapi, but to answer only specific +requests, at low latency. For this subset of Xapi we want completly cover the +original api. + +Requests +============= + +This is a list of example requests, we want to optimize. + +* xapi.spline.de/api/0.6/node[amenity=*] +* xapi.spline.de/api/0.6/node[highway=busstop] +* xapi.spline.de/api/0.6/node[bbox=-6,50,2,61] +* xapi.spline.de/api/0.6/node[amenity=hospital][bbox=-6,50,2,61] + +a more formal description +------------------------- + +We serve the node endpoint, but no others. We implment the tag based filtering, +for only one tag and a bounding box. + +database shema +================ + +We keep data in a highly specioaliced shema, that allows us to prevent tables +growing to big. And supports our requests at maximum speed. + +| CREATE TABLE <tagname>:<tagvalue> ( +| {bigint id} +| {longitude float4}, +| {latitude float4}, +| {object varchar} +| ) PRIMARY KEY id; + +Implmentation +============= + +Teilprobleme: +.............. + +1. Database import + +mögliche Technologien: +* Osmosis- plugin +* selbst in python (Protobuf consumer, async pgsql schreiber) + + +2. Web API +.............. + +mögliche Technologien: +* node.js diff --git a/src/nodejs/start.js b/src/nodejs/start.js new file mode 100644 index 0000000..2cf923e --- /dev/null +++ b/src/nodejs/start.js @@ -0,0 +1,105 @@ +// imports +var http = require('http'), + querystring = require('querystring'), + pg = require('pg'), + url = require('url'), + querystring = require('querystring'); + +// config +var connectionString = "pg://user:pass@localhost/xapi" + + +function getDataBaseResult(tag,bbox,res){ +pg.connect(connectionString,function(err,client){ + var the_result; + if(err){ + console.log(err); + } else { + client.query(createQuery(tag,bbox),function(err,result){ + if (err) { + console.log(err); + } else { + console.log(result); + res.write(result.rows); + res.end("/n"); + } + + }); + } +}); +} + + +function createQuery(tag,bbox){ + // FIXME: validate + var table = tag[0] + "#" + tag[1]; + var filter = ""; + + // input validation + for(i=0;i<bbox.length;i++){ + bbox[i] = parseFloat(bbox[i]); + } + + if(bbox){ + filter = "WHERE longitude > " + bbox[0] + " AND longitude < " + bbox[1] + + " AND latitude > " + bbox[2] + " AND latitude < " + bbox[3]; + } + return "SELECT * FROM \"" + table + "\" " + filter + ";"; +} + + +RegExp.escape= function(s) { + return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') +}; + + +var PATH_PREFIX = '/api/'; +var base_url_re = new RegExp('^' + RegExp.escape(PATH_PREFIX) + + '(node|way|relation|\\*)(.*)$') +var filter_re = /\[(\w+=[^\]]+)\]/g; + + +http.createServer(function (req, res) { + + if (!base_url_re.test(req.url)) { + res.writeHead(404, {'Content-Type': 'text/plain; charset=utf8'}); + res.end('Not Found\n'); + } + base_url_re.exec(req.url); + var type = RegExp.$1, url_rest = querystring.unescape(RegExp.$2); + + var filters = []; + while (v = filter_re.exec(url_rest)) { + filters.push(v[1]); + } + console.log(filters); + + var tag; + var bbox; + + for(i=0;i<filters.length;i++){ + filters[i]=filters[i].split(/=/); + if(filters[i][0]=="bbox"){ + bbox = filters[i][1].split(/,/); + } + else { + tag = filters[i]; + } + } + + console.log(tag); + console.log(bbox); + + getDataBaseResult(tag,bbox,res); + + res.writeHead(200, {'Content-Type': 'text/plain; charset=utf8', }); + + res.write('URL was: ' + req.url + '\n'); + res.write('type: ' + type + '\n'); + res.write('filters:\n'); + filters.forEach(function(x) { res.write(' ' + x + '\n'); }) + //res.end('\n'); + +}).listen(8124, "127.0.0.1"); + +console.log('Listening on http://127.0.0.1:8124/') |