Support for serving raw vector tiles

This commit is contained in:
Petr Sloup 2016-03-02 17:51:50 +01:00
parent 75e5fd1018
commit 7bef26baed
4 changed files with 122 additions and 18 deletions

View file

@ -37,13 +37,9 @@ module.exports = function(maps, options, prefix) {
var lock = new asyncLock();
var app = express().disable('x-powered-by'),
domains = [],
domains = options.domains,
tilePath = '/{z}/{x}/{y}.{format}';
if (options.domains && options.domains.length > 0) {
domains = options.domains.split(',');
}
var rootPath = path.join(process.cwd(), options.root);
var styleUrl = options.style;

101
src/serve_vector.js Normal file
View file

@ -0,0 +1,101 @@
'use strict';
var async = require('async'),
asyncLock = require('async-lock'),
crypto = require('crypto'),
fs = require('fs'),
path = require('path'),
util = require('util'),
zlib = require('zlib');
var abaculus = require('abaculus'),
clone = require('clone'),
concat = require('concat-stream'),
express = require('express'),
mercator = new (require('sphericalmercator'))(),
mbgl = require('mapbox-gl-native'),
mbtiles = require('mbtiles'),
request = require('request');
var utils = require('./utils');
module.exports = function(maps, options, prefix) {
var lock = new asyncLock();
var app = express().disable('x-powered-by'),
domains = options.domains,
tilePath = '/{z}/{x}/{y}.pbf';
var rootPath = path.join(process.cwd(), options.root);
var mbtilesPath = options.mbtiles;
var map = {
tileJSON: {}
};
maps[prefix] = map;
var source = new mbtiles(path.join(rootPath, mbtilesPath), function(err) {
source.getInfo(function(err, info) {
map.tileJSON['name'] = prefix.substr(1);
Object.assign(map.tileJSON, info);
map.tileJSON['tilejson'] = '2.0.0';
map.tileJSON['basename'] = prefix.substr(1);
map.tileJSON['format'] = 'pbf';
Object.assign(map.tileJSON, options.options || {});
});
});
var tilePattern = tilePath
.replace('{z}', ':z(\\d+)')
.replace('{x}', ':x(\\d+)')
.replace('{y}', ':y(\\d+)');
var getTile = function(z, x, y, callback) {
source.getTile(z, x, y, function(err, data, headers) {
if (err) {
callback(err);
} else {
var md5 = crypto.createHash('md5').update(data).digest('base64');
headers['content-md5'] = md5;
headers['content-type'] = 'application/x-protobuf';
headers['content-encoding'] = 'gzip';
callback(null, data, headers);
}
});
};
app.get(tilePattern, function(req, res, next) {
var z = req.params.z | 0,
x = req.params.x | 0,
y = req.params.y | 0;
return getTile(z, x, y, function(err, data, headers) {
if (err) {
return next(err);
}
if (headers) {
res.set(headers);
}
if (data == null) {
return res.status(404).send('Not found');
} else {
return res.status(200).send(data);
}
}, res, next);
});
app.get('/index.json', function(req, res, next) {
var info = clone(map.tileJSON);
info.tiles = utils.getTileUrls(req.protocol, domains, req.headers.host,
prefix, tilePath, info.format,
req.query.key);
return res.send(info);
});
return app;
};

View file

@ -13,7 +13,8 @@ var async = require('async'),
express = require('express'),
morgan = require('morgan');
var serve = require('./app'),
var serve_raster = require('./serve_raster'),
serve_vector = require('./serve_vector'),
utils = require('./utils');
module.exports = function(opts, callback) {
@ -36,7 +37,11 @@ module.exports = function(opts, callback) {
app.use(prefix, cors());
}
app.use(prefix, serve(maps, config[prefix], prefix));
if (config[prefix].style) {
app.use(prefix, serve_raster(maps, config[prefix], prefix));
} else {
app.use(prefix, serve_vector(maps, config[prefix], prefix));
}
});
// serve index.html on the root
@ -50,16 +55,9 @@ module.exports = function(opts, callback) {
queue.push(function(callback) {
var info = clone(map.tileJSON);
var domains = [],
tilePath = '/{z}/{x}/{y}.{format}';
if (config[prefix].domains && config[prefix].domains.length > 0) {
domains = config[prefix].domains.split(',');
}
info.tiles = utils.getTileUrls(req.protocol, domains, req.headers.host,
prefix, tilePath, info.format,
req.query.key);
info.tiles = utils.getTileUrls(
req.protocol, config[prefix].domains, req.headers.host,
prefix, '/{z}/{x}/{y}.{format}', info.format, req.query.key);
callback(null, info);
});

View file

@ -2,7 +2,16 @@
module.exports.getTileUrls = function(
protocol, domains, host, path, tilePath, format, key) {
domains = domains && domains.length > 0 ? domains : [host];
if (domains) {
if (domains.constructor === String && domains.length > 0) {
domains = domains.split(',');
}
}
if (!domains || domains.length == 0) {
domains = [host];
}
var query = (key && key.length > 0) ? ('?key=' + key) : '';
if (path == '/') {
path = '';