aboutsummaryrefslogblamecommitdiffstats
path: root/src/nodejs/main.js
blob: 80bd051d36d5fb225e144f238bb0ef26cf2fd5aa (plain) (tree)
1
2
3
4
5
6
7
8
9
                               
                           
                       
                       
                                                
                           
                                   
                                 
                                     
                                
           































                                                            
                       



                          


                                                                   

                                   
               

         


                
                                     






                                            
                          
                      


                                                                   
                           


                               

         




                                                            






                                                  
 









                                                                
               














                                                                                               
                                                                             


                                           
 
                                          

     

                                               
       



                                                 

         
                                                                           


                                                                                 

                                  
                                               
         
 
                            
     
 



                                      
                                                                        
             
         
                   
     
    
                                                                                  

                           
 

                                                                

     


                                                            

                                                
 
                                 
                                                               
     
 
                
 




                            
 
 
 
 


                                                               
                                   










                                                      
                                                 


                                                       
 
                                                                          
                               
 
                                     

                                                                                            
 
                                         
                             
           
 
                                    
                        
           
 
                                       
                                      
                              
           
       


                                                
                                                       
 

                                    

                                                 

 

                                                                         
                                     

                            
                                                                              
                                                                                           
 
                                         
                             
           
 
                                    

                             

             
 
                                       





                                                                               
                                    
                                    
                     

                                                  
                                                
                   
             
                                      
           
       
 
 
 
                             
 
                       
 


































                                                          
 













                                                      
                                 


                                                 
                                                                   
                                                                      

 
                          


                                                 
var clutch = require('clutch');
var http = require('http');
var fs = require('fs');
var pg = require('pg');
var xmlGenerator = require('./xmlGenerator.js');
var opts = require('opts');
var osmRes = require('./response');
var log4js = require('log4js')();
var log = log4js.getLogger('global');
var parser = require('./parse');
var config;

// #################### MAY be put to different module later

function toISO8601(date) {
    //2007-03-31T00:09:22+01:00
    var pad_two = function(n) {
        return (n < 10 ? '0' : '') + n;
    };

    return [
        date.getUTCFullYear(),
        '-',
        pad_two(date.getUTCMonth() + 1),
        '-',
        pad_two(date.getUTCDate()),
        'T',
        pad_two(date.getUTCHours()),
        ':',
        pad_two(date.getUTCMinutes()),
        ':',
        pad_two(date.getUTCSeconds()),
        '+01:00'    //FIX ME
            ].join('');
}

function rowToNode(row){
    var node = {
        'id' : row.id,
        'timestamp': toISO8601(row.tstamp),
        'version': row.version,
        'changeset': row.changeset_id,
        'lat' : row.lat,
        'lon' : row.lon
    };

    if(row.tags != '{}') {
        node.tags = [];
        temp = row.tags.replace("{","").replace("}","").split(",");
        for(var x=0;x<temp.length;x=x+2){
            node.tags.push({
                'key' : temp[x],
                'value' : temp[x+1]
            });
        }
    }
    return node;
}

//FIXME: parsing of ways is meesed up
function rowToWay(row){
    var way = {
        'id' : row.id,
        'timestamp' : toISO8601(row.tstamp),
        'version' : row.version,
        'changeset' : row.changeset_id
    };
    if(row.tags != '{}') {
        way.tags = [];
        // FIXME: something doesnt work at all
        temp = row.tags.replace("{","").replace("}","").split(",");
        for(var x=0;x<temp.length;x=x+2){
            way.tags.push({
                'k' : temp[x],
                'v' : temp[x+1]
            });
        }
    }
    return way;
}

// #################### MAY be put to different module later

var options = [
      { short       : 'c',
        long        : 'config',
        description : 'Select configuration file',
        value       : true
      }
];

//
// {
// object = node/way/relation/* ,
// bbox = { left : 1.0 , right : 1.0 , top : 1.0, bottom : 1.0 }
// tag = { key : [ ], value [ ] } 
// }


function buildMainQuery(reqJso){

    var id = 1;
    var replacements = Array();
    
    var selectMap = {
        'node' : 'id,user_id,tstamp,version,changeset_id,hstore_to_array(tags) as tags, ' + 
                    'X(geom) as lat, Y(geom) as lon',
        'way' :  'id,tstamp,version,changeset_id,nodes,user_id,hstore_to_array(tags) as tags ',
        'relation' : '' //FIXME: plz
    }   
    
    // FIXME: help me i am not side effect free
    function buildTagsQuery(map){

        tagQueries = new Array();

        for(tagkey in map){
            tagQueries.push("tags @> hstore($" + id++  +  ",$" + id++ + ")");
            replacements.push(tagkey);
            replacements.push(map[tagkey]);
        }

        return tagQueries.join(" OR  \n");
    }

    // FIXME: help me i am not side effect free
    function buildBbox(object,bbox){
       
        var colName = {
            node : 'geom',
            way : 'linestring',
            relation : '' // FIXME: whats my name
        }

        bboxQueryStr =  colName[object] + ' && st_setsrid(st_makebox2d( ' +
              ' st_setsrid(st_makepoint($' + id++ + ', $' + id++ + '), 4326), ' +
              ' st_setsrid(st_makepoint($' + id++ + ', $' + id++ + '), 4326) ' +
              ' ), 4326) ';
        
        for( direction in bbox ) {
            replacements.push(bbox[direction]);
        }

        return bboxQueryStr;
    }

    function explodeTags(keys,values){
        var map = {};
        for(key in keys) {
            for(value in values) {
                map[keys[key]]=values[value]; // FIXME: das ist scheiße
            }
        }
        return map;
    }
    
    query = "SELECT " + selectMap[reqJso.object] + " FROM " + reqJso.object + "s";
    
    whereClauses = Array();

    if(reqJso.bbox != undefined){
        whereClauses.push(buildBbox(reqJso.object,reqJso.bbox));
    }
    
    // FIXME: rename tag to tags key to keys value to values
    if(reqJso.tag != undefined){
        tags = explodeTags(reqJso.tag.key,reqJso.tag.value);
        whereClauses.push(buildTagsQuery(tags));
    }

    if(whereClauses.length > 0) {
        query += ' WHERE (' + whereClauses.join(' AND ') + ')';
    }

    query += ';'

    return {
        text:query,
        values:replacements,
        name: query
        };
}



function dbConnect(res, callback) {
    pg.connect(config.connectionString, function(err, client) {
        if(err) {
            log.error(err.message);
            console.log(config.connectionString);
            console.log(err);
            res.writeHead(404,{});
            res.end();
        } else {
            log.info("db connection was successfull");
            callback(client);
        }
    });
}

function nodeWorldHandler(req, res, key, value) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(' key:' +key +' value:'+value+'\n');
}

function nodeBboxHandler(req, res, key, value, left, bottom, right, top) {
    res = osmRes.mkXmlRes(res);

    dbConnect(res, function(client) {
        var success = false;
        var query = client.query(createNodeBboxQuery(key, value, left, bottom, right, top));

        query.on('error', function(err) {
            res.endWith500();
        });

        query.on('end', function() {
            res.atEnd();
        });

        query.on('row', function(row) {
            var pojo = rowToNode(row);
            res.putNode(pojo);
        });
    });
}

function wayWorldHandler(req, res, key, value) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
}

function connectionError(err, res) {
    log.error(err);
    log.fatal("connectionError not implemented");
}


function wayBboxHandler(req, res, key, value, left, bottom, right, top) {
    dbConnect(res, function(client) {
        var count = 0;
        var success = false;
        console.log(createWayBboxQuery(key, value, left, bottom, right, top));
        var query = client.query(createWayBboxQuery(key, value, left, bottom, right, top));

        query.on('error', function(err) {
            res.endWith500();
        });

        query.on('end', function() {
            if(count === 0) {
                res.atEnd();
            }
        });

        query.on('row', function(row) {
            if(row.nodes != '{}') {
                count++;
                var subquery = client.query(createNodesForWayQuery(row.nodes));
                subquery.on('error',function(err) {});
                subquery.on('end', function() {
                    count--;
                    if(count === 0){
                        res.atEnd();
                    }
                });
                subquery.on('row', function(row) {
                    res.putNode(rowToNode(row));
                });
            }
            res.putRow(rowToWay(row));
        });
    });
}


function myFunction(req,res){

    res.writeHead(200);

    var reqObj = parser.urlToXpathObj(req.url);
    
    var queryDict = buildMainQuery(reqObj);
    
    var resXml = osmRes.mkXmlRes(res);
    

    console.log(JSON.stringify(queryDict));
    console.log("??????????????????????????????");
    console.log(JSON.stringify(reqObj));
    dbConnect(resXml, function(client) {
        var success = false;
        var query = client.query(queryDict);

        query.on('error', function(err) {
            res.endWith500();
        });

        query.on('end', function() {
            console.log(" EEEND ");           
            res.atEnd();
        });

        query.on('row', function(row) {
            //console.log(JSON.stringify(row));           
            if(reqObj.object == "node") {
                var pojo = rowToNode(row);
                res.putNode(pojo);
            }
            else if(reqObj.object == "way") {
                var pojo = rowToWay(row);
                res.putWay(pojo);}
        });
    });
}

function getConfig(configPath, callback) {
    if( configPath[0] != '/'){
            configPath = __dirname + '/' + configPath;
    }
    fs.readFile(configPath, function(err, data) {
        if (err) {
            throw err;
        }
        callback(JSON.parse(data));
    });
}

function init(newConfig) {
    config = newConfig;
    xmlGenerator.config = config;
    log.setLevel(config.logLevel);
    log.info("server starting...");
    log.info("loaded config from " + configPath);
    http.createServer(myFunction).listen(config.port, config.host);
    log.info("Started server at " + config.host + ":" + config.port );
}

opts.parse(options, true);
configPath = opts.get('config') || "config.json";
console.log("loading config " + configPath);
config = getConfig(configPath, init);