Improved generation of TileJSONs

This commit is contained in:
Petr Sloup 2016-03-02 13:11:43 +01:00
parent 92b502af36
commit 565ed2dd74
4 changed files with 55 additions and 62 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "tileserver-gl", "name": "tileserver-gl",
"version": "0.0.1", "version": "0.0.1",
"description": "", "description": "Map tile server for JSON GL styles - serverside generated raster tiles",
"main": "src/main.js", "main": "src/main.js",
"authors": [ "authors": [
"Petr Sloup <petr.sloup@klokantech.com>" "Petr Sloup <petr.sloup@klokantech.com>"
@ -17,7 +17,6 @@
"clone": "1.0.2", "clone": "1.0.2",
"concat-stream": "1.5.1", "concat-stream": "1.5.1",
"cors": "2.7.1", "cors": "2.7.1",
"debug": "2.2.0",
"express": "4.13.4", "express": "4.13.4",
"mapbox-gl-native": "3.0.2-earcut", "mapbox-gl-native": "3.0.2-earcut",
"mbtiles": "0.8.2", "mbtiles": "0.8.2",

View file

@ -5,15 +5,12 @@ var async = require('async'),
crypto = require('crypto'), crypto = require('crypto'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
stream = require('stream'),
url = require('url'),
util = require('util'), util = require('util'),
zlib = require('zlib'); zlib = require('zlib');
var abaculus = require('abaculus'), var abaculus = require('abaculus'),
clone = require('clone'), clone = require('clone'),
concat = require('concat-stream'), concat = require('concat-stream'),
debug = require('debug'),
express = require('express'), express = require('express'),
mercator = new (require('sphericalmercator'))(), mercator = new (require('sphericalmercator'))(),
mbgl = require('mapbox-gl-native'), mbgl = require('mapbox-gl-native'),
@ -21,7 +18,7 @@ var abaculus = require('abaculus'),
PNG = require('pngjs').PNG, PNG = require('pngjs').PNG,
request = require('request'); request = require('request');
debug = debug('tileserver-gl'); var utils = require('./utils');
var FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+\.?\\d+)'; var FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+\.?\\d+)';
var SCALE_PATTERN = '@[23]x'; var SCALE_PATTERN = '@[23]x';
@ -30,28 +27,9 @@ var getScale = function(scale) {
return (scale || '@1x').slice(1, 2) | 0; return (scale || '@1x').slice(1, 2) | 0;
}; };
var getTileUrls = function(domains, host, path, tilePath, format, key, protocol) { mbgl.on('message', function(e) {
domains = domains && domains.length > 0 ? domains : [host]; console.log('mbgl:', e);
var query = (key && key.length > 0) ? ('?key=' + key) : ''; });
if (path == '/') {
path = '';
}
var uris = [];
domains.forEach(function(domain) {
uris.push(protocol + '://' + domain + path +
tilePath.replace('{format}', format).replace(/\/+/g, '/') +
query);
});
return uris;
};
var md5sum = function(data) {
var hash = crypto.createHash('md5');
hash.update(data);
return hash.digest();
};
module.exports = function(maps, options, prefix) { module.exports = function(maps, options, prefix) {
var lock = new asyncLock(); var lock = new asyncLock();
@ -70,7 +48,7 @@ module.exports = function(maps, options, prefix) {
var map = { var map = {
renderer: null, renderer: null,
sources: {}, sources: {},
styleJSON: {} tileJSON: {}
}; };
if (!maps[prefix]) { if (!maps[prefix]) {
map.renderer = new mbgl.Map({ map.renderer = new mbgl.Map({
@ -139,11 +117,23 @@ module.exports = function(maps, options, prefix) {
} }
}); });
map.styleJSON = require(path.join(rootPath, styleUrl)); var styleJSON = require(path.join(rootPath, styleUrl));
map.tileJSON = {
'tilejson': '2.0.0',
'name': styleJSON.name,
'basename': prefix.substr(1),
'minzoom': 0,
'maxzoom': 20,
'bounds': [-180, -85.0511, 180, 85.0511],
'format': 'png',
'type': 'baselayer'
};
Object.assign(map.tileJSON, options.options || {});
var queue = []; var queue = [];
Object.keys(map.styleJSON.sources).forEach(function(name) { Object.keys(styleJSON.sources).forEach(function(name) {
var source = map.styleJSON.sources[name]; var source = styleJSON.sources[name];
var url = source.url; var url = source.url;
if (url.lastIndexOf('mbtiles:', 0) === 0) { if (url.lastIndexOf('mbtiles:', 0) === 0) {
// found mbtiles source, replace with info from local file // found mbtiles source, replace with info from local file
@ -156,6 +146,7 @@ module.exports = function(maps, options, prefix) {
Object.assign(source, info); Object.assign(source, info);
source.basename = name; source.basename = name;
source.tiles = [ source.tiles = [
// meta url which will be detected when requested
'mbtiles://' + name + tilePath.replace('{format}', 'pbf') 'mbtiles://' + name + tilePath.replace('{format}', 'pbf')
]; ];
callback(null); callback(null);
@ -166,7 +157,7 @@ module.exports = function(maps, options, prefix) {
}); });
async.parallel(queue, function(err, results) { async.parallel(queue, function(err, results) {
map.renderer.load(map.styleJSON); map.renderer.load(styleJSON);
}); });
maps[prefix] = map; maps[prefix] = map;
@ -196,14 +187,13 @@ module.exports = function(maps, options, prefix) {
zoom: z, zoom: z,
center: tileCenter, center: tileCenter,
width: 2 * tileSize, width: 2 * tileSize,
height: 2 * tileSize, height: 2 * tileSize/*,
ratio: scale,
debug: { debug: {
tileBorders: true, tileBorders: true,
parseStatus: true, parseStatus: true,
timestamps: true, timestamps: true,
collision: true collision: true
} }*/
}, function(err, data) { }, function(err, data) {
done(); done();
if (err) console.log(err); if (err) console.log(err);
@ -219,8 +209,9 @@ module.exports = function(maps, options, prefix) {
return callback(null, null); return callback(null, null);
} }
var md5 = crypto.createHash('md5').update(buffer).digest('base64');
var headers = { var headers = {
'content-md5': md5sum(buffer).toString('base64'), 'content-md5': md5,
'content-type': 'image/png' 'content-type': 'image/png'
}; };
/* /*
@ -320,21 +311,13 @@ module.exports = function(maps, options, prefix) {
}); });
app.get('/index.json', function(req, res, next) { app.get('/index.json', function(req, res, next) {
var info = clone(map.styleJSON); var info = clone(map.tileJSON);
if (prefix.length > 1) { info.tiles = utils.getTileUrls(req.protocol, domains, req.headers.host,
info.basename = prefix.substr(1); prefix, tilePath, 'png', req.query.key);
}
info.tiles = getTileUrls(domains, req.headers.host, prefix,
tilePath, 'png',
req.query.key, req.protocol);
info.tilejson = '2.0.0';
return res.send(info); return res.send(info);
}); });
return app; return app;
}; };
module.exports.getTileUrls = getTileUrls;

View file

@ -10,13 +10,11 @@ var fs = require('fs'),
var async = require('async'), var async = require('async'),
clone = require('clone'), clone = require('clone'),
cors = require('cors'), cors = require('cors'),
debug = require('debug'),
express = require('express'), express = require('express'),
morgan = require('morgan'); morgan = require('morgan');
var serve = require('./app'); var serve = require('./app'),
utils = require('./utils');
debug = debug('tileserver-gl');
module.exports = function(opts, callback) { module.exports = function(opts, callback) {
var app = express().disable('x-powered-by'), var app = express().disable('x-powered-by'),
@ -50,23 +48,17 @@ module.exports = function(opts, callback) {
Object.keys(config).forEach(function(prefix) { Object.keys(config).forEach(function(prefix) {
var map = maps[prefix]; var map = maps[prefix];
queue.push(function(callback) { queue.push(function(callback) {
var info = clone(map.styleJSON); var info = clone(map.tileJSON);
var domains = [], var domains = [],
tilePath = config[prefix].tilePath || '/{z}/{x}/{y}.{format}'; tilePath = '/{z}/{x}/{y}.{format}';
if (config[prefix].domains && config[prefix].domains.length > 0) { if (config[prefix].domains && config[prefix].domains.length > 0) {
domains = config[prefix].domains.split(','); domains = config[prefix].domains.split(',');
} }
if (prefix.length > 1) { info.tiles = utils.getTileUrls(req.protocol, domains, req.headers.host,
info.basename = prefix.substr(1); prefix, tilePath, 'png', req.query.key);
}
info.tiles = serve.getTileUrls(domains, req.headers.host, prefix,
tilePath, 'png',
req.query.key, req.protocol);
info.tilejson = '2.0.0';
callback(null, info); callback(null, info);
}); });

19
src/utils.js Normal file
View file

@ -0,0 +1,19 @@
'use strict';
module.exports.getTileUrls = function(
protocol, domains, host, path, tilePath, format, key) {
domains = domains && domains.length > 0 ? domains : [host];
var query = (key && key.length > 0) ? ('?key=' + key) : '';
if (path == '/') {
path = '';
}
var uris = [];
domains.forEach(function(domain) {
uris.push(protocol + '://' + domain + path +
tilePath.replace('{format}', format).replace(/\/+/g, '/') +
query);
});
return uris;
};