Merge remote-tracking branch 'klokantech/master' into public_url
# Conflicts: # src/main.js # src/server.js
This commit is contained in:
93
src/main.js
93
src/main.js
@@ -10,51 +10,55 @@ var mbtiles = require('@mapbox/mbtiles');
|
||||
|
||||
var packageJson = require('../package');
|
||||
|
||||
var opts = require('nomnom')
|
||||
.option('mbtiles', {
|
||||
default: undefined,
|
||||
help: 'MBTiles file (uses demo configuration);\n' +
|
||||
'\t ignored if the configuration file is also specified',
|
||||
position: 0
|
||||
})
|
||||
.option('config', {
|
||||
abbr: 'c',
|
||||
default: 'config.json',
|
||||
help: 'Configuration file'
|
||||
})
|
||||
.option('bind', {
|
||||
abbr: 'b',
|
||||
default: undefined,
|
||||
help: 'Bind address'
|
||||
})
|
||||
.option('port', {
|
||||
abbr: 'p',
|
||||
default: 8080,
|
||||
help: 'Port'
|
||||
})
|
||||
.option('cors', {
|
||||
default: true,
|
||||
help: 'Enable Cross-origin resource sharing headers'
|
||||
})
|
||||
.option('public_url', {
|
||||
abbr: 'u',
|
||||
default: '',
|
||||
help: 'Enable exposing the server on subpaths, not necessarily the root of the domain'
|
||||
})
|
||||
.option('verbose', {
|
||||
abbr: 'V',
|
||||
flag: true,
|
||||
help: 'More verbose output'
|
||||
})
|
||||
.option('version', {
|
||||
abbr: 'v',
|
||||
flag: true,
|
||||
help: 'Version info',
|
||||
callback: function() {
|
||||
return packageJson.name + ' v' + packageJson.version;
|
||||
}
|
||||
}).parse();
|
||||
var args = process.argv;
|
||||
if (args.length >= 3 && args[2][0] != '-') {
|
||||
args.splice(2, 0, '--mbtiles');
|
||||
}
|
||||
|
||||
var opts = require('commander')
|
||||
.description('tileserver-gl startup options')
|
||||
.usage('tileserver-gl [mbtiles] [options]')
|
||||
.option(
|
||||
'--mbtiles <file>',
|
||||
'MBTiles file (uses demo configuration);\n' +
|
||||
'\t ignored if the configuration file is also specified'
|
||||
)
|
||||
.option(
|
||||
'-c, --config <file>',
|
||||
'Configuration file [config.json]',
|
||||
'config.json'
|
||||
)
|
||||
.option(
|
||||
'-b, --bind <address>',
|
||||
'Bind address'
|
||||
)
|
||||
.option(
|
||||
'-p, --port <port>',
|
||||
'Port [8080]',
|
||||
8080,
|
||||
parseInt
|
||||
)
|
||||
.option(
|
||||
'-C|--no-cors',
|
||||
'Disable Cross-origin resource sharing headers'
|
||||
)
|
||||
.option(
|
||||
'-u|--public_url',
|
||||
'Enable exposing the server on subpaths, not necessarily the root of the domain'
|
||||
)
|
||||
.option(
|
||||
'-V, --verbose',
|
||||
'More verbose output'
|
||||
)
|
||||
.option(
|
||||
'-s, --silent',
|
||||
'Less verbose output'
|
||||
)
|
||||
.version(
|
||||
packageJson.version,
|
||||
'-v, --version'
|
||||
)
|
||||
.parse(args);
|
||||
|
||||
console.log('Starting ' + packageJson.name + ' v' + packageJson.version);
|
||||
|
||||
@@ -69,6 +73,7 @@ var startServer = function(configPath, config) {
|
||||
bind: opts.bind,
|
||||
port: opts.port,
|
||||
cors: opts.cors,
|
||||
silent: opts.silent,
|
||||
publicUrl: publicUrl
|
||||
});
|
||||
};
|
||||
|
||||
@@ -37,7 +37,15 @@ module.exports = function(options, repo, params, id, styles, publicUrl) {
|
||||
var source;
|
||||
var sourceInfoPromise = new Promise(function(resolve, reject) {
|
||||
source = new mbtiles(mbtilesFile, function(err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
source.getInfo(function(err, info) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
tileJSON['name'] = id;
|
||||
tileJSON['format'] = 'pbf';
|
||||
|
||||
@@ -81,7 +89,7 @@ module.exports = function(options, repo, params, id, styles, publicUrl) {
|
||||
source.getTile(z, x, y, function(err, data, headers) {
|
||||
if (err) {
|
||||
if (/does not exist/.test(err.message)) {
|
||||
return res.status(404).send(err.message);
|
||||
return res.status(204).send(err.message);
|
||||
} else {
|
||||
return res.status(500).send(err.message);
|
||||
}
|
||||
@@ -176,9 +184,7 @@ module.exports = function(options, repo, params, id, styles, publicUrl) {
|
||||
return res.send(info);
|
||||
});
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
sourceInfoPromise.then(function() {
|
||||
resolve(app);
|
||||
});
|
||||
return sourceInfoPromise.then(function() {
|
||||
return app;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -17,13 +17,19 @@ module.exports = function(options, allowedFonts) {
|
||||
var existingFonts = {};
|
||||
var fontListingPromise = new Promise(function(resolve, reject) {
|
||||
fs.readdir(options.paths.fonts, function(err, files) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
files.forEach(function(file) {
|
||||
fs.stat(path.join(fontPath, file), function(err, stats) {
|
||||
if (!err) {
|
||||
if (stats.isDirectory() &&
|
||||
fs.existsSync(path.join(fontPath, file, '0-255.pbf'))) {
|
||||
existingFonts[path.basename(file)] = true;
|
||||
}
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
if (stats.isDirectory() &&
|
||||
fs.existsSync(path.join(fontPath, file, '0-255.pbf'))) {
|
||||
existingFonts[path.basename(file)] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -54,9 +60,7 @@ module.exports = function(options, allowedFonts) {
|
||||
);
|
||||
});
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
fontListingPromise.then(function() {
|
||||
resolve(app);
|
||||
});
|
||||
return fontListingPromise.then(function() {
|
||||
return app;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -122,12 +122,18 @@ module.exports = function(options, repo, params, id, publicUrl, dataResolver) {
|
||||
var existingFonts = {};
|
||||
var fontListingPromise = new Promise(function(resolve, reject) {
|
||||
fs.readdir(options.paths.fonts, function(err, files) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
files.forEach(function(file) {
|
||||
fs.stat(path.join(options.paths.fonts, file), function(err, stats) {
|
||||
if (!err) {
|
||||
if (stats.isDirectory()) {
|
||||
existingFonts[path.basename(file)] = true;
|
||||
}
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
if (stats.isDirectory()) {
|
||||
existingFonts[path.basename(file)] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -182,7 +188,12 @@ module.exports = function(options, repo, params, id, publicUrl, dataResolver) {
|
||||
}
|
||||
|
||||
if (format == 'pbf') {
|
||||
response.data = zlib.unzipSync(data);
|
||||
try {
|
||||
response.data = zlib.unzipSync(data);
|
||||
}
|
||||
catch (err) {
|
||||
console.log("Skipping incorrect header for tile mbtiles://%s/%s/%s/%s.pbf", id, z, x, y);
|
||||
}
|
||||
if (options.dataDecoratorFunc) {
|
||||
response.data = options.dataDecoratorFunc(
|
||||
sourceId, 'data', response.data, z, x, y);
|
||||
@@ -740,9 +751,8 @@ module.exports = function(options, repo, params, id, publicUrl, dataResolver) {
|
||||
return res.send(info);
|
||||
});
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
Promise.all([fontListingPromise, renderersReadyPromise]).then(function() {
|
||||
resolve(app);
|
||||
});
|
||||
return Promise.all([fontListingPromise, renderersReadyPromise]).then(function() {
|
||||
return app;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -7,8 +7,7 @@ process.env.UV_THREADPOOL_SIZE =
|
||||
var fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var base64url = require('base64url'),
|
||||
clone = require('clone'),
|
||||
var clone = require('clone'),
|
||||
cors = require('cors'),
|
||||
enableShutdown = require('http-shutdown'),
|
||||
express = require('express'),
|
||||
@@ -43,9 +42,13 @@ function start(opts) {
|
||||
app.enable('trust proxy');
|
||||
|
||||
if (process.env.NODE_ENV == 'production') {
|
||||
app.use(morgan('tiny'));
|
||||
app.use(morgan('tiny', {
|
||||
skip: function(req, res) { return opts.silent && (res.statusCode == 200 || res.statusCode == 304) }
|
||||
}));
|
||||
} else if (process.env.NODE_ENV !== 'test') {
|
||||
app.use(morgan('dev'));
|
||||
app.use(morgan('dev', {
|
||||
skip: function(req, res) { return opts.silent && (res.statusCode == 200 || res.statusCode == 304) }
|
||||
}));
|
||||
}
|
||||
|
||||
var config = opts.config || null;
|
||||
@@ -246,8 +249,9 @@ function start(opts) {
|
||||
startupPromises.push(new Promise(function(resolve, reject) {
|
||||
fs.readFile(templateFile, function(err, content) {
|
||||
if (err) {
|
||||
console.error('Template not found:', err);
|
||||
err = new Error('Template not found: ' + err.message);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
var compiled = handlebars.compile(content.toString());
|
||||
|
||||
@@ -265,6 +269,7 @@ function start(opts) {
|
||||
data['key_query_part'] =
|
||||
req.query.key ? 'key=' + req.query.key + '&' : '';
|
||||
data['key_query'] = req.query.key ? '?key=' + req.query.key : '';
|
||||
if (template === 'wmts') res.set('Content-Type', 'text/xml');
|
||||
return res.status(200).send(compiled(data));
|
||||
});
|
||||
resolve();
|
||||
@@ -292,11 +297,6 @@ function start(opts) {
|
||||
Math.floor(centerPx[1] / 256) + '.png';
|
||||
}
|
||||
|
||||
var query = req.query.key ? ('?key=' + req.query.key) : '';
|
||||
style.wmts_link = 'http://wmts.maptiler.com/' +
|
||||
base64url(utils.getPublicUrl(opts.publicUrl, req) +
|
||||
'styles/' + id + '.json' + query) + '/wmts';
|
||||
|
||||
var tiles = utils.getTileUrls(
|
||||
req, style.serving_rendered.tiles,
|
||||
'styles/' + id, style.serving_rendered.format, opts.publicUrl);
|
||||
@@ -321,11 +321,6 @@ function start(opts) {
|
||||
Math.floor(centerPx[1] / 256) + '.' + data_.format;
|
||||
}
|
||||
|
||||
var query = req.query.key ? ('?key=' + req.query.key) : '';
|
||||
data_.wmts_link = 'http://wmts.maptiler.com/' +
|
||||
base64url(utils.getPublicUrl(opts.publicUrl, req) +
|
||||
'data/' + id + '.json' + query) + '/wmts';
|
||||
|
||||
var tiles = utils.getTileUrls(
|
||||
req, data_.tiles, 'data/' + id, data_.format, opts.publicUrl, {
|
||||
'pbf': options.pbfAlias
|
||||
@@ -370,6 +365,20 @@ function start(opts) {
|
||||
return res.redirect(301, '/styles/' + req.params.id + '/');
|
||||
});
|
||||
*/
|
||||
serveTemplate('/styles/:id/wmts.xml', 'wmts', function(req) {
|
||||
var id = req.params.id;
|
||||
var wmts = clone((config.styles || {})[id]);
|
||||
if (!wmts) {
|
||||
return null;
|
||||
}
|
||||
if (wmts.hasOwnProperty("serve_rendered") && !wmts.serve_rendered) {
|
||||
return null;
|
||||
}
|
||||
wmts.id = id;
|
||||
wmts.name = (serving.styles[id] || serving.rendered[id]).name;
|
||||
wmts.baseUrl = (req.get('X-Forwarded-Protocol')?req.get('X-Forwarded-Protocol'):req.protocol) + '://' + req.get('host');
|
||||
return wmts;
|
||||
});
|
||||
|
||||
serveTemplate('/data/:id/$', 'data', function(req) {
|
||||
var id = req.params.id;
|
||||
@@ -416,6 +425,11 @@ function start(opts) {
|
||||
module.exports = function(opts) {
|
||||
var running = start(opts);
|
||||
|
||||
running.startupPromise.catch(function(err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on('SIGINT', function() {
|
||||
process.exit();
|
||||
});
|
||||
|
||||
21
src/utils.js
21
src/utils.js
@@ -93,7 +93,20 @@ var getFontPbf = function(allowedFonts, fontPath, name, range, fallbacks) {
|
||||
if (err) {
|
||||
console.error('ERROR: Font not found:', name);
|
||||
if (fallbacks && Object.keys(fallbacks).length) {
|
||||
var fallbackName = Object.keys(fallbacks)[0];
|
||||
var fallbackName;
|
||||
|
||||
var fontStyle = name.split(' ').pop();
|
||||
if (['Regular', 'Bold', 'Italic'].indexOf(fontStyle) < 0) {
|
||||
fontStyle = 'Regular';
|
||||
}
|
||||
fallbackName = 'Noto Sans ' + fontStyle;
|
||||
if (!fallbacks[fallbackName]) {
|
||||
fallbackName = 'Open Sans ' + fontStyle;
|
||||
if (!fallbacks[fallbackName]) {
|
||||
fallbackName = Object.keys(fallbacks)[0];
|
||||
}
|
||||
}
|
||||
|
||||
console.error('ERROR: Trying to use', fallbackName, 'as a fallback');
|
||||
delete fallbacks[fallbackName];
|
||||
getFontPbf(null, fontPath, fallbackName, range, fallbacks).then(resolve, reject);
|
||||
@@ -119,9 +132,7 @@ module.exports.getFontsPbf = function(allowedFonts, fontPath, names, range, fall
|
||||
);
|
||||
});
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
Promise.all(queue).then(function(values) {
|
||||
return resolve(glyphCompose.combine(values));
|
||||
}, reject);
|
||||
return Promise.all(queue).then(function(values) {
|
||||
return glyphCompose.combine(values);
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user