146 lines
5.9 KiB
JavaScript
Executable File
146 lines
5.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
var options = argv = require('optimist').argv,
|
|
_ = require('underscore'),
|
|
Step = require('step'),
|
|
sys = require('sys'),
|
|
spawn = require('child_process').spawn,
|
|
MBTiles = require('..').MBTiles,
|
|
utils = require('..').utils,
|
|
mbtiles,
|
|
table,
|
|
total;
|
|
|
|
// @TODO: support specifying a table to be processed, e.g. for processing
|
|
// grids or grid data.
|
|
|
|
// Show help.
|
|
if (argv.help || argv._.length < 2) {
|
|
console.warn('Usage: mbpipe [COMMAND] [FILE]');
|
|
console.warn(' Pipe each tile to stdin of the specified command and');
|
|
console.warn(' write stdout into the mbtiles file.');
|
|
console.warn('Examples:');
|
|
console.warn(' mbpipe "pngquant 32" world.mbtiles');
|
|
process.exit();
|
|
}
|
|
|
|
// Grab args.
|
|
var filename = argv._[1],
|
|
command = {
|
|
command: argv._[0].split(' ')[0],
|
|
args: argv._[0].split(' ').slice(1)
|
|
};
|
|
|
|
Step(
|
|
function() { mbtiles = new MBTiles(filename, this); },
|
|
function(err) {
|
|
if (err) throw err;
|
|
Step(
|
|
function() { mbtiles.db.run('PRAGMA synchronous=0', this); },
|
|
function() { mbtiles.db.run('PRAGMA locking_mode=EXCLUSIVE', this); },
|
|
function() { mbtiles.db.run('PRAGMA journal_mode=TRUNCATE', this); },
|
|
this
|
|
);
|
|
},
|
|
function(err) {
|
|
if (err) throw err;
|
|
mbtiles.exists('tiles', function(err, exists) {
|
|
if (exists) table = 'tiles';
|
|
this();
|
|
}.bind(this));
|
|
},
|
|
function(err) {
|
|
if (err) throw err;
|
|
mbtiles.exists('images', function(err, exists) {
|
|
if (exists) table = 'images';
|
|
this();
|
|
}.bind(this));
|
|
},
|
|
function(err) {
|
|
if (err) throw err;
|
|
if (!table) throw new Error('No usable image table found.');
|
|
mbtiles.db.get('SELECT COUNT(tile_data) AS total FROM ' + table, function(err, row) {
|
|
total = row.total;
|
|
this();
|
|
}.bind(this));
|
|
},
|
|
function(err) {
|
|
if (err) throw err;
|
|
if (!total) throw new Error('No tiles found');
|
|
|
|
var printed = 0;
|
|
var done = this;
|
|
var doit = function(table, limit, offset) {
|
|
process.nextTick(function() {
|
|
var query = table === 'images'
|
|
? mbtiles.db.prepare('SELECT tile_data AS tile_data, tile_id AS id FROM images ORDER BY tile_id ASC LIMIT ? OFFSET ?')
|
|
: mbtiles.db.prepare('SELECT tile_data AS tile_data, zoom_level AS z, tile_column AS x, tile_row AS y FROM tiles ORDER BY z, x, y LIMIT ? OFFSET ?');
|
|
query.all(limit, offset, function(err, rows) {
|
|
Step(
|
|
function() {
|
|
var group = this.group();
|
|
var exec = function(row, callback) {
|
|
row.piped = new Buffer(0);
|
|
var child = spawn(command.command, command.args);
|
|
var stream = function(chunk) {
|
|
var joined = (new Buffer(row.piped.length + chunk.length));
|
|
row.piped.copy(joined, 0, 0);
|
|
chunk.copy(joined, row.piped.length, 0);
|
|
row.piped = joined;
|
|
};
|
|
child.stdin.write(row.tile_data);
|
|
child.stdin.end();
|
|
child.stdout.on('data', stream);
|
|
child.stderr.on('data', stream);
|
|
child.on('exit', function(code) {
|
|
if (code) return callback(null, null);
|
|
if (table === 'images') {
|
|
mbtiles.db.run(
|
|
'INSERT OR REPLACE INTO images (tile_id, tile_data) VALUES(?, ?)',
|
|
row.id,
|
|
row.piped,
|
|
callback
|
|
);
|
|
} else {
|
|
mbtiles.db.run(
|
|
'INSERT OR REPLACE INTO tiles (zoom_level, tile_column, tile_row, tile_data) VALUES(?, ?, ?, ?)',
|
|
row.z,
|
|
row.x,
|
|
row.y,
|
|
row.piped,
|
|
callback
|
|
);
|
|
}
|
|
});
|
|
};
|
|
for (var i = 0; i < rows.length; i++) {
|
|
exec(rows[i], group());
|
|
}
|
|
},
|
|
function(err) {
|
|
var progress = Math.floor(offset / total * 40);
|
|
if (progress > printed) {
|
|
sys.print((new Array(progress - printed + 1)).join('#'));
|
|
printed = progress;
|
|
}
|
|
if (rows.length === limit) {
|
|
doit(table, limit, offset + limit);
|
|
} else {
|
|
mbtiles.db.run('VACUUM', function() {
|
|
sys.print('\n');
|
|
console.warn('Pipe complete.');
|
|
done();
|
|
});
|
|
}
|
|
}
|
|
);
|
|
});
|
|
query.finalize();
|
|
});
|
|
};
|
|
console.warn('00 -------------- 50 -------------- 100');
|
|
doit(table, 255, 0);
|
|
}
|
|
);
|
|
|