CartoDB-SQL-API/app/models/formats/shp.js

102 lines
2.7 KiB
JavaScript
Raw Normal View History

2013-05-16 17:24:52 +08:00
var crypto = require('crypto');
var Step = require('step');
var fs = require('fs');
var spawn = require('child_process').spawn;
var ogr = require('./ogr');
2013-05-16 17:24:52 +08:00
function shp() {
}
shp.prototype = new ogr('shp');
2013-05-16 17:24:52 +08:00
var p = shp.prototype;
2013-05-16 17:24:52 +08:00
p._contentType = "application/zip; charset=utf-8";
p._fileExtension = "zip";
2013-05-16 17:24:52 +08:00
p.generate = function(options, callback) {
var o = options;
this.toSHP(o.database, o.user_id, o.gn, o.sql, o.skipfields, o.filename, callback);
2013-05-16 17:24:52 +08:00
};
p.toSHP = function (dbname, user_id, gcol, sql, skipfields, filename, callback) {
var fmtObj = this;
2013-05-16 17:24:52 +08:00
var zip = 'zip'; // FIXME: make configurable
var tmpdir = global.settings.tmpDir || '/tmp';
var reqKey = [ 'shp', dbname, user_id, gcol, this.generateMD5(sql) ].concat(skipfields).join(':');
2013-05-16 17:24:52 +08:00
var outdirpath = tmpdir + '/sqlapi-' + reqKey;
var zipfile = outdirpath + '.zip';
var shapefile = outdirpath + '/' + filename + '.shp';
// TODO: following tests:
// - fetch query with no "the_geom" column
Step (
function createOutDir() {
fs.mkdir(outdirpath, 0777, this);
},
function spawnDumper(err) {
if ( err ) throw err;
fmtObj.toOGR(dbname, user_id, gcol, sql, skipfields, 'ESRI Shapefile', shapefile, this);
2013-05-16 17:24:52 +08:00
},
function doZip(err) {
if ( err ) throw err;
var next = this;
var child = spawn(zip, ['-qrj', zipfile, outdirpath ]);
child.on('exit', function(code) {
//console.log("Zip complete, zip return code was " + code);
if (code) {
next(new Error("Zip command return code " + code));
//res.statusCode = 500;
}
next(null);
});
},
function cleanupDir(topError) {
var next = this;
//console.log("Cleaning up " + outdirpath);
// Unlink the dir content
var unlinkall = function(dir, files, finish) {
var f = files.shift();
if ( ! f ) { finish(null); return; }
var fn = dir + '/' + f;
fs.unlink(fn, function(err) {
if ( err ) {
console.log("Unlinking " + fn + ": " + err);
finish(err);
}
else unlinkall(dir, files, finish)
});
}
fs.readdir(outdirpath, function(err, files) {
if ( err ) {
if ( err.code != 'ENOENT' ) {
next(new Error([topError, err].join('\n')));
} else {
next(topError);
}
} else {
unlinkall(outdirpath, files, function(err) {
fs.rmdir(outdirpath, function(err) {
if ( err ) console.log("Removing dir " + path + ": " + err);
callback(topError, zipfile);
});
});
}
});
}
);
};
2013-05-16 17:24:52 +08:00
module.exports = shp;
2013-05-16 17:24:52 +08:00