first stab at online tiles
This commit is contained in:
@@ -3,6 +3,7 @@ var _ = require('underscore'),
|
||||
Step = require('step'),
|
||||
crypto = require('crypto'),
|
||||
zlib = require('zlib'),
|
||||
get = require('get'),
|
||||
sqlite3 = require('sqlite3');
|
||||
|
||||
// MBTiles
|
||||
@@ -10,8 +11,16 @@ var _ = require('underscore'),
|
||||
// MBTiles class for doing common operations (schema setup, tile reading,
|
||||
// insertion, etc.)
|
||||
function MBTiles(filename, callback) {
|
||||
var mbtiles = this;
|
||||
this.filename = filename;
|
||||
this.db = new sqlite3.Database(filename, callback);
|
||||
this.db = new sqlite3.Database(filename, function(err) {
|
||||
if (err) return callback(err);
|
||||
mbtiles.metadata('online', function(err, value) {
|
||||
// Ignore not-existant key.
|
||||
mbtiles.online = value;
|
||||
if (callback) callback(null);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the schema of the current mbtiles database and inform the caller of
|
||||
@@ -208,16 +217,39 @@ MBTiles.prototype.insertGridTiles = function(map, callback) {
|
||||
// - @param {Number} z tile z coordinate.
|
||||
// - @param {Function} callback
|
||||
MBTiles.prototype.tile = function(x, y, z, callback) {
|
||||
var mbtiles = this;
|
||||
this.db.get('SELECT tile_data FROM tiles WHERE ' +
|
||||
'zoom_level = ? AND tile_column = ? AND tile_row = ?',
|
||||
z, x, y,
|
||||
function(err, row) {
|
||||
if (err) callback(err);
|
||||
else if (!row || !row.tile_data) callback(new Error('Tile does not exist'));
|
||||
else if (!row || !row.tile_data) mbtiles.onlineTile(x, y, z, callback);
|
||||
else callback(null, row.tile_data);
|
||||
});
|
||||
};
|
||||
|
||||
// Requests a tile from an online source and cache it to the database.
|
||||
//
|
||||
// - @param {Number} x tile x coordinate.
|
||||
// - @param {Number} y tile y coordinate.
|
||||
// - @param {Number} z tile z coordinate.
|
||||
// - @param {Function} callback
|
||||
MBTiles.prototype.onlineTile = function(x, y, z, callback) {
|
||||
var mbtiles = this;
|
||||
if (!this.online) {
|
||||
return callback(new Error('Tile does not exist'));
|
||||
}
|
||||
|
||||
var url = this.online.replace(/%x/g, x).replace(/%y/g, Math.pow(2, z) - 1 - y).replace(/%z/g, z);
|
||||
new get(url).asBuffer(function(err, result) {
|
||||
if (err) return callback(new Error(err));
|
||||
|
||||
// Cache image.
|
||||
mbtiles.insertTiles([{ x: x, y: y, z: z, data: result }], function() {});
|
||||
callback(null, result);
|
||||
});
|
||||
};
|
||||
|
||||
// Select a grid and its data from an mbtiles database.
|
||||
//
|
||||
// - @param {Number} x tile x coordinate
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"optimist": "0.2.x",
|
||||
"sqlite3": "2.0.x",
|
||||
"step": "0.0.x",
|
||||
"get": "0.3.x",
|
||||
"underscore": "1.1.x",
|
||||
"zlib": "1.0.x"
|
||||
},
|
||||
|
||||
BIN
test/fixtures/online.mbtiles
vendored
Normal file
BIN
test/fixtures/online.mbtiles
vendored
Normal file
Binary file not shown.
61
test/online.test.js
Normal file
61
test/online.test.js
Normal file
@@ -0,0 +1,61 @@
|
||||
var assert = require('assert');
|
||||
var MBTiles = require('..').MBTiles;
|
||||
|
||||
var fixture = __dirname + '/fixtures/online.mbtiles';
|
||||
|
||||
exports['get online metadata'] = function(beforeExit) {
|
||||
var completion = {};
|
||||
|
||||
var mbtiles = new MBTiles(fixture);
|
||||
mbtiles.metadata('name', function(err, value) { if (err) throw err; completion.name = value; });
|
||||
mbtiles.metadata('type', function(err, value) { if (err) throw err; completion.type = value; });
|
||||
mbtiles.metadata('description', function(err, value) { if (err) throw err; completion.description = value; });
|
||||
mbtiles.metadata('version', function(err, value) { if (err) throw err; completion.version = value; });
|
||||
mbtiles.metadata('formatter', function(err, value) { if (err) throw err; completion.formatter = value; });
|
||||
mbtiles.metadata('bounds', function(err, value) { if (err) throw err; completion.bounds = value; });
|
||||
mbtiles.metadata('online', function(err, value) { if (err) throw err; completion.online = value; });
|
||||
mbtiles.metadata('invalid', function(err, value) { completion.invalid = err.message; });
|
||||
|
||||
beforeExit(function() {
|
||||
assert.deepEqual(completion, {
|
||||
name: 'MapQuest streets',
|
||||
type: 'baselayer',
|
||||
description: 'MapQuest’s OpenStreetMap based street level tiles.',
|
||||
version: '1.0.0',
|
||||
formatter: null,
|
||||
bounds: '-180,-90,180,90',
|
||||
online: 'http://otile1.mqcdn.com/tiles/1.0.0/osm/%z/%x/%y.png',
|
||||
invalid: 'Key does not exist'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
exports['get online tiles'] = function(beforeExit) {
|
||||
var status = {
|
||||
success: 0,
|
||||
error: 0
|
||||
};
|
||||
|
||||
var mbtiles = new MBTiles(fixture);
|
||||
|
||||
mbtiles.db.serialize(function() {
|
||||
mbtiles.db.run("DELETE FROM map");
|
||||
mbtiles.db.run("DELETE FROM images");
|
||||
});
|
||||
|
||||
mbtiles.tile(0, 0, 0, function(err, tile) {
|
||||
if (err) throw new Error(err);
|
||||
status.success++;
|
||||
});
|
||||
|
||||
mbtiles.tile(0, 0, 18, function(err, tile) {
|
||||
if (err) throw new Error(err);
|
||||
status.success++;
|
||||
});
|
||||
|
||||
beforeExit(function() {
|
||||
assert.equal(status.success, 2);
|
||||
assert.equal(status.error, 0);
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user