Improved font serving
This commit is contained in:
parent
bbc14abb4a
commit
509d32da68
4 changed files with 71 additions and 18 deletions
|
@ -1,7 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
var clone = require('clone'),
|
||||
express = require('express');
|
||||
express = require('express'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
|
@ -12,14 +14,29 @@ module.exports = function(options, allowedFonts) {
|
|||
|
||||
var fontPath = options.paths.fonts;
|
||||
|
||||
var existingFonts = {};
|
||||
fs.readdir(options.paths.fonts, function(err, files) {
|
||||
files.forEach(function(file) {
|
||||
fs.stat(path.join(fontPath, file), function(err, stats) {
|
||||
if (!err) {
|
||||
if (stats.isDirectory()) {
|
||||
existingFonts[path.basename(file)] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/:fontstack/:range([\\d]+-[\\d]+).pbf',
|
||||
function(req, res, next) {
|
||||
var fontstack = decodeURI(req.params.fontstack);
|
||||
var range = req.params.range;
|
||||
|
||||
return utils.getFontsPbf(allowedFonts, fontPath, fontstack, range,
|
||||
return utils.getFontsPbf(allowedFonts, fontPath, fontstack, range, existingFonts,
|
||||
function(err, concated) {
|
||||
if (err || concated.length === 0) {
|
||||
console.log(err);
|
||||
console.log(concated.length);
|
||||
return res.status(400).send('');
|
||||
} else {
|
||||
res.header('Content-type', 'application/x-protobuf');
|
||||
|
|
|
@ -49,6 +49,19 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
sources: {}
|
||||
};
|
||||
|
||||
var existingFonts = {};
|
||||
fs.readdir(options.paths.fonts, function(err, files) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var styleJSON;
|
||||
var createPool = function(ratio, min, max) {
|
||||
var createRenderer = function(ratio, createCallback) {
|
||||
|
@ -67,7 +80,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
var parts = req.url.split('/');
|
||||
var fontstack = unescape(parts[2]);
|
||||
var range = parts[3].split('.')[0];
|
||||
utils.getFontsPbf(null, options.paths[protocol], fontstack, range,
|
||||
utils.getFontsPbf(null, options.paths[protocol], fontstack, range, existingFonts,
|
||||
function(err, concated) {
|
||||
callback(err, {data: concated});
|
||||
});
|
||||
|
@ -148,13 +161,13 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
styleJSON = clone(require(styleJSONPath));
|
||||
|
||||
var httpTester = /^(http(s)?:)?\/\//;
|
||||
if (!httpTester.test(styleJSON.sprite)) {
|
||||
if (styleJSON.sprite && !httpTester.test(styleJSON.sprite)) {
|
||||
styleJSON.sprite = 'sprites://' +
|
||||
styleJSON.sprite
|
||||
.replace('{style}', path.basename(styleFile, '.json'))
|
||||
.replace('{styleJsonFolder}', path.relative(options.paths.sprites, path.dirname(styleJSONPath)));
|
||||
}
|
||||
if (!httpTester.test(styleJSON.glyphs)) {
|
||||
if (styleJSON.glyphs && !httpTester.test(styleJSON.glyphs)) {
|
||||
styleJSON.glyphs = 'fonts://' + styleJSON.glyphs;
|
||||
}
|
||||
|
||||
|
@ -204,6 +217,9 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
}
|
||||
map.sources[name] = new mbtiles(mbtilesFile, function(err) {
|
||||
map.sources[name].getInfo(function(err, info) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
var type = source.type;
|
||||
Object.assign(source, info);
|
||||
source.type = type;
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
|
|||
var spritePath;
|
||||
|
||||
var httpTester = /^(http(s)?:)?\/\//;
|
||||
if (!httpTester.test(styleJSON.sprite)) {
|
||||
if (styleJSON.sprite && !httpTester.test(styleJSON.sprite)) {
|
||||
spritePath = path.join(options.paths.sprites,
|
||||
styleJSON.sprite
|
||||
.replace('{style}', path.basename(styleFile, '.json'))
|
||||
|
@ -54,20 +54,23 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
|
|||
);
|
||||
styleJSON.sprite = 'local://styles/' + id + '/sprite';
|
||||
}
|
||||
if (!httpTester.test(styleJSON.glyphs)) {
|
||||
if (styleJSON.glyphs && !httpTester.test(styleJSON.glyphs)) {
|
||||
styleJSON.glyphs = 'local://fonts/{fontstack}/{range}.pbf';
|
||||
}
|
||||
|
||||
repo[id] = styleJSON;
|
||||
|
||||
app.get('/' + id + '.json', function(req, res, next) {
|
||||
var fixUrl = function(url, opt_nokey) {
|
||||
var queryParams = ['style=' + id];
|
||||
var fixUrl = function(url, opt_nokey, opt_nostyle) {
|
||||
var queryParams = [];
|
||||
if (!opt_nostyle) {
|
||||
queryParams.push('style=' + id);
|
||||
}
|
||||
if (!opt_nokey && req.query.key) {
|
||||
queryParams.unshift('key=' + req.query.key);
|
||||
}
|
||||
var query = '';
|
||||
if (!opt_nokey) {
|
||||
if (queryParams.length) {
|
||||
query = '?' + queryParams.join('&');
|
||||
}
|
||||
return url.replace(
|
||||
|
@ -80,8 +83,12 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
|
|||
source.url = fixUrl(source.url);
|
||||
});
|
||||
// mapbox-gl-js viewer cannot handle sprite urls with query
|
||||
styleJSON_.sprite = fixUrl(styleJSON_.sprite, true);
|
||||
styleJSON_.glyphs = fixUrl(styleJSON_.glyphs);
|
||||
if (styleJSON_.sprite) {
|
||||
styleJSON_.sprite = fixUrl(styleJSON_.sprite, true, true);
|
||||
}
|
||||
if (styleJSON_.glyphs) {
|
||||
styleJSON_.glyphs = fixUrl(styleJSON_.glyphs, false, true);
|
||||
}
|
||||
return res.send(styleJSON_);
|
||||
});
|
||||
|
||||
|
|
25
src/utils.js
25
src/utils.js
|
@ -4,7 +4,8 @@ var async = require('async'),
|
|||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var glyphCompose = require('glyph-pbf-composite');
|
||||
var clone = require('clone'),
|
||||
glyphCompose = require('glyph-pbf-composite');
|
||||
|
||||
module.exports.getTileUrls = function(req, domains, path, format) {
|
||||
|
||||
|
@ -51,13 +52,25 @@ module.exports.fixTileJSONCenter = function(tileJSON) {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports.getFontsPbf = function(allowedFonts, fontPath, names, range, callback) {
|
||||
var getFontPbf = function(name, range, callback) {
|
||||
if (!allowedFonts || allowedFonts[name]) {
|
||||
module.exports.getFontsPbf = function(allowedFonts, fontPath, names, range, fallbacks, callback) {
|
||||
var getFontPbf = function(allowedFonts, name, range, callback, fallbacks) {
|
||||
if (!allowedFonts || (allowedFonts[name] && fallbacks)) {
|
||||
var filename = path.join(fontPath, name, range + '.pbf');
|
||||
if (!fallbacks) {
|
||||
fallbacks = clone(allowedFonts || {});
|
||||
}
|
||||
delete fallbacks[name];
|
||||
return fs.readFile(filename, function(err, data) {
|
||||
if (err) {
|
||||
return callback(new Error('Font load error: ' + name));
|
||||
console.error('ERROR: Font not found:', name);
|
||||
if (fallbacks && Object.keys(fallbacks).length) {
|
||||
var fallbackName = Object.keys(fallbacks)[0];
|
||||
console.error('ERROR: Trying to use', fallbackName, 'as a fallback');
|
||||
delete fallbacks[fallbackName];
|
||||
return getFontPbf(null, fallbackName, range, callback, fallbacks);
|
||||
} else {
|
||||
return callback(new Error('Font load error: ' + name));
|
||||
}
|
||||
} else {
|
||||
return callback(null, data);
|
||||
}
|
||||
|
@ -71,7 +84,7 @@ module.exports.getFontsPbf = function(allowedFonts, fontPath, names, range, call
|
|||
var queue = [];
|
||||
fonts.forEach(function(font) {
|
||||
queue.push(function(callback) {
|
||||
getFontPbf(font, range, callback);
|
||||
getFontPbf(allowedFonts, font, range, callback, clone(allowedFonts || fallbacks));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue