Skip to content

Commit

Permalink
support local mbtiles
Browse files Browse the repository at this point in the history
  • Loading branch information
MateoV committed Jul 25, 2015
1 parent f0d2b20 commit f945449
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 31 deletions.
113 changes: 82 additions & 31 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ var queue = require('queue-async');
var request = require('request');
var VectorTile = require('vector-tile').VectorTile;
var Pbf = require('pbf');
var MBTiles = require('mbtiles');
var zlib = require('zlib');

module.exports = function (coverArea, opts){
var workers = [];
var tilesCompleted = 0;
var ee = new EventEmitter();
var dbs = {};

// compute cover
var tiles = computeCover(coverArea, opts.zoom);
Expand Down Expand Up @@ -51,52 +54,80 @@ module.exports = function (coverArea, opts){
return ee;
};

function getVectorTile(tile, tileLayer, done){
var layers = {
name:tileLayer.name,
layers:tileLayer.layers
};

function getRemoteVectorTile(tile, tileLayer, done){
var url = tileLayer.url.split('{x}').join(tile[0]);
url = url.split('{y}').join(tile[1]);
url = url.split('{z}').join(tile[2]);
url = url.split('{z}').join(tile[2])

var requestOpts = {
url: url,
gzip: true,
encoding: null
};
request(requestOpts, function(err, res, body) {
var vt;
try {
vt = new VectorTile(new Pbf(new Uint8Array(body)));
} catch(e){
done(e, null);
}
tileLayer.layers.forEach(function(layer){
layers[layer] = turf.featurecollection([]);
if(vt && vt.layers[layer]){
for(var i = 0; i < vt.layers[layer].length; i++){
try {
layers[layer].features.push(vt.layers[layer].feature(i).toGeoJSON(tile[0],tile[1],tile[2]));
} catch(e){
done(e, null);
}
getTileFeatures(tile, body, tileLayer, done);
});
}

function getLocalVectorTile(tile, tileLayer, dbs, done){
var tilename = tileLayer.mbtiles.split('.')[0];

dbs[tilename].getTile(tile[2],tile[0],tile[1],function(err, data) {
if (err) throw err;
zlib.unzip(data, function(err, body) {
getTileFeatures(tile, body, tileLayer, done);
});
});
}

function getTileFeatures(tile, data, tileLayer, cb){
var layers = {
name:tileLayer.name,
layers:tileLayer.layers
};

var vt;
try {
vt = new VectorTile(new Pbf(new Uint8Array(data)));
} catch(e) {
cb(e, null);
}

tileLayer.layers.forEach(function(layer){
layers[layer] = turf.featurecollection([]);
if (vt && vt.layers[layer]) {
for (var i = 0; i < vt.layers[layer].length; i++) {
try {
layers[layer].features.push(vt.layers[layer].feature(i).toGeoJSON(tile[0],tile[1],tile[2]));
} catch(e) {
cb(e, null);
}
}
});
}
});

cb(null, layers);
}

done(null, layers);
function loadTiles(mbtile, dbs, done){
new MBTiles(mbtile, function(err, src) {
if (err) throw err;
dbs[mbtile.split('.')[0]] = src;
done(err, null);
});
}

function sendData (tiles, workers, opts) {
if(!opts.maxrate || opts.maxrate > 200) opts.maxrate = 200;
var getData = rateLimit(opts.maxrate / opts.tileLayers.length, 1000, function(tile){
function sendData (tiles, workers, opts){
var dbs = {};
var rl = false;
var q = queue(4);

var getData = function(tile){
var layerCollection = {};
var q = queue(4);
opts.tileLayers.forEach(function(tileLayer){
q.defer(getVectorTile, tile, tileLayer);
if (tileLayer.url) q.defer(getRemoteVectorTile, tile, tileLayer);
if (tileLayer.mbtiles) q.defer(getLocalVectorTile, tile, tileLayer, dbs);
});
q.awaitAll(function(err, res){
if(res){
Expand All @@ -113,9 +144,26 @@ function sendData (tiles, workers, opts) {
});
}
});
}

opts.tileLayers.forEach(function(tl){
if (tl.url || opts.maxrate) rl = true;
if (tl.mbtiles) {
q.defer(loadTiles, tl.mbtiles, dbs);
}
});
tiles.forEach(function(tile){
getData(tile);

q.awaitAll(function(err, res){
if (rl) {
if(!opts.maxrate || opts.maxrate > 200) opts.maxrate = 200;
tiles.forEach(function(tile){
rateLimit(opts.maxrate / opts.tileLayers.length, 1000, getData(tile));
});
} else {
tiles.forEach(function(tile){
getData(tile);
});
}
});
}

Expand Down Expand Up @@ -200,4 +248,7 @@ module.exports.isValidTile = isValidTile;
module.exports.tilesToZoom = tilesToZoom;
module.exports.sendData = sendData;
module.exports.sendTiles = sendTiles;
module.exports.getVectorTile = getVectorTile;
module.exports.loadTiles = loadTiles;
module.exports.getRemoteVectorTile = getRemoteVectorTile;
module.exports.getLocalVectorTile = getLocalVectorTile;
module.exports.getTileFeatures = getTileFeatures;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"function-rate-limit": "^1.0.1",
"geojson-flatten": "^0.1.0",
"geojson-normalize": "0.0.0",
"mbtiles": "^0.8.0",
"pbf": "^1.3.2",
"queue-async": "^1.0.7",
"request": "^2.54.0",
Expand Down

0 comments on commit f945449

Please sign in to comment.