I'm developing a hybrid mobile app using meteorjs and cordova. App needs to have offline map support. I exported a .mbtiles file using Maperitive, of area that can be viewed offline and copied the file to my app so I can access it when loading tiles with Leaflet. For that i used cordova plugins for file system (to copy .mbtiles to the right place) and cordova sqlite plugin (for accessing .mbtiles data) and that part works, I can successfully load tile_data when leaflet requests tiles whit z, x and y.
The part that doesn't work is "placing" the tiles on the map. I am using a custom tile layer that accesses .mbtiles sqlite database and gets needed tiles:
//TilesLayer.MBTiles.js
L.TileLayer.MBTiles = L.TileLayer.extend({
mbTilesDB: null,
initialize: function(url, options, db) {
this.mbTilesDB = db;
L.Util.setOptions(this, options);
},
getTileUrl: function (tilePoint, zoom, tile) {
var z = this._getZoomForUrl();
var x = tilePoint.x;
var y = Math.pow(2, z) - tilePoint.y - 1;
var base64Prefix = "data:image/png;base64,";
this.mbTilesDB.readTransaction(function(tdx) {
tdx.executeSql("SELECT tile_data FROM tiles WHERE zoom_level = ? AND tile_column = ? AND tile_row = ?;", [z, x, y], function(tx, res) {
tile.src = base64Prefix + res.rows.item(0).tile_data;
console.log("tile-src" + JSON.stringify(tile.src));
}, function(tx, error) {
console.log('SELECT error: ' + error.message);
});
}, function(error) {
console.log('transaction error: ' + error.message);
}, function() {
console.log('transaction ok');
});
},
_loadTile: function (tile, tilePoint, zoom) {
tile._layer = this;
tile.onload = this._tileOnLoad;
tile.onerror = this._tileOnError;
this.getTileUrl(tilePoint, zoom, tile);
} });
Tiles aren't displayed on the map. Leaflet asks for correct tiles, those tiles are successfully returned from database, but are not displayed.
-Is maybe this line the problem:
tile.src = base64Prefix + res.rows.item(0).tile_data;
Am I not using the tile_data correctly. Do I have to convert it to something else? Tiles in .mbtiles file are stored as BLOB, but are .png images.
-Am I missing a call when I pass the tiles back? Something like:
tilelayer.fire('tileloadstart', {
tile: tile
});
And call it after the tile.src has been set?
Any help would be much appreciated.