Files
node-mbtiles/bin/mbrekey
2011-05-19 18:04:07 -04:00

123 lines
4.1 KiB
JavaScript
Executable File

#!/usr/bin/env node
var options = argv = require('optimist').argv;
var _ = require('underscore');
var sqlite3 = require('sqlite3');
var utils = require('..').utils;
// Show help.
if (argv.help || argv._.length < 1) {
console.warn('Usage: mbrekey [FILE]');
console.warn(' Rekey a compacted mbtiles to save space.');
console.warn('Examples:');
console.warn(' mbrekey world.mbtiles');
process.exit();
}
// Grab args.
var filename = argv._[0];
var db = new sqlite3.Database(filename);
var tables = {};
db.all("SELECT tbl_name FROM sqlite_master WHERE TYPE = 'table'", function(err, map) {
if (err) throw err;
map.forEach(function(row) {
tables[row.tbl_name] = true;
});
});
var tileQueue = new utils.Queue(changeTileID, 1);
var gridQueue = new utils.Queue(changeGridID, 1);
db.run('CREATE INDEX "temp_tile_id_idx" ON "map" ("tile_id")', function(err) {
if (err) throw err;
console.warn('Created temporary index.');
db.run('CREATE TEMP TABLE "tile_hash_id" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "hash" TEXT UNIQUE NOT NULL)', function(err) {
if (err) throw err;
db.run('INSERT INTO tile_hash_id (hash) SELECT tile_id FROM images', function(err) {
if (err) throw err;
db.get('SELECT MAX(id) AS max FROM tile_hash_id', function(err, max) {
if (err) throw err;
max = max.max;
console.warn('Starting tile update... (%d total)', max);
for (var i = 1; i < max; i += 1000) {
tileQueue.add(i);
}
});
});
});
})
tileQueue.on('empty', function() {
if (!tables.grid_utfgrid) {
deleteTempKey();
console.warn("MBtiles file doesn't have interactivity");
return;
}
db.run('CREATE TEMP TABLE "grid_hash_id" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "hash" TEXT UNIQUE NOT NULL)', function(err) {
if (err) throw err;
db.run('INSERT INTO grid_hash_id (hash) SELECT grid_id FROM grid_utfgrid', function(err) {
if (err) throw err;
db.get('SELECT MAX(id) AS max FROM grid_hash_id', function(err, max) {
if (err) throw err;
max = max.max;
console.warn('Starting grid update... (%d total)', max);
for (var i = 1; i < max; i += 1000) {
gridQueue.add(i);
}
});
});
});
});
gridQueue.on('empty', deleteTempKey);
var changedTiles = 0;
function changeTileID(start, done) {
db.all('SELECT id, hash FROM tile_hash_id WHERE id >= ? AND id < ?', start, start + 1000, function(err, rows) {
if (err) throw err;
db.serialize(function() {
db.run('BEGIN');
rows.forEach(function(row) {
db.run('UPDATE images SET tile_id = ? WHERE tile_id = ?', row.id, row.hash);
db.run('UPDATE map SET tile_id = ? WHERE tile_id = ?', row.id, row.hash);
});
db.run('COMMIT', function(err) {
if (err) throw err;
changedTiles += rows.length;
console.warn('Updated %d tiles.', changedTiles);
done();
});
});
});
};
var changedGrids = 0;
function changeGridID(start, done) {
db.all('SELECT id, hash FROM grid_hash_id WHERE id >= ? AND id < ?', start, start + 1000, function(err, rows) {
if (err) throw err;
db.serialize(function() {
db.run('BEGIN');
rows.forEach(function(row) {
db.run('UPDATE grid_key SET grid_id = ? WHERE grid_id = ?', row.id, row.hash);
db.run('UPDATE grid_utfgrid SET grid_id = ? WHERE grid_id = ?', row.id, row.hash);
db.run('UPDATE map SET grid_id = ? WHERE grid_id = ?', row.id, row.hash);
});
db.run('COMMIT', function(err) {
if (err) throw err;
changedGrids += rows.length;
console.warn('Updated %d grids.', changedGrids);
done();
});
});
});
};
function deleteTempKey() {
db.run('DROP INDEX "temp_tile_id_idx"');
}