Add "serveAllStyles" option + watch the directory
This commit is contained in:
parent
cb700181d3
commit
d7a34f3a74
5 changed files with 110 additions and 29 deletions
|
@ -27,6 +27,7 @@ Example::
|
|||
"maxSize": 2048,
|
||||
"pbfAlias": "pbf",
|
||||
"serveAllFonts": false,
|
||||
"serveAllStyles": false,
|
||||
"serveStaticMaps": true,
|
||||
"tileMargin": 0
|
||||
},
|
||||
|
@ -99,9 +100,9 @@ Default is ``2048``.
|
|||
``tileMargin``
|
||||
--------------
|
||||
|
||||
Additional image side length added during tile rendering that is cropped from the delivered tile. This is useful for resolving the issue with cropped labels,
|
||||
Additional image side length added during tile rendering that is cropped from the delivered tile. This is useful for resolving the issue with cropped labels,
|
||||
but it does come with a performance degradation, because additional, adjacent vector tiles need to be loaded to genenrate a single tile.
|
||||
Default is ``0`` to disable this processing.
|
||||
Default is ``0`` to disable this processing.
|
||||
|
||||
``minRendererPoolSizes``
|
||||
------------------------
|
||||
|
@ -124,6 +125,13 @@ If you have plenty of memory, try setting these equal to or slightly above your
|
|||
If you need to conserve memory, try lower values for scale factors that are less common.
|
||||
Default is ``[16, 8, 4]``.
|
||||
|
||||
``serveAllStyles``
|
||||
------------------------
|
||||
|
||||
If this option is enabled, all the styles from the ``paths.styles`` will be served. (No recursion, only ``.json`` files are used.)
|
||||
The process will also watch for changes in this directory and remove/add more styles dynamically.
|
||||
It is recommended to also use the ``serveAllFonts`` option when using this option.
|
||||
|
||||
``watermark``
|
||||
-----------
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"handlebars": "4.5.3",
|
||||
"http-shutdown": "1.2.1",
|
||||
"morgan": "1.9.1",
|
||||
"node-watch": "0.6.3",
|
||||
"pbf": "3.2.1",
|
||||
"proj4": "2.6.0",
|
||||
"request": "2.88.0",
|
||||
|
|
|
@ -663,7 +663,12 @@ module.exports = {
|
|||
|
||||
const styleFile = params.style;
|
||||
const styleJSONPath = path.resolve(options.paths.styles, styleFile);
|
||||
styleJSON = clone(require(styleJSONPath));
|
||||
try {
|
||||
styleJSON = JSON.parse(fs.readFileSync(styleJSONPath));
|
||||
} catch (e) {
|
||||
console.log('Error parsing style file');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (styleJSON.sprite && !httpTester.test(styleJSON.sprite)) {
|
||||
styleJSON.sprite = 'sprites://' +
|
||||
|
@ -798,5 +803,14 @@ module.exports = {
|
|||
});
|
||||
|
||||
return Promise.all([renderersReadyPromise]);
|
||||
}
|
||||
},
|
||||
remove: (repo, id) => {
|
||||
let item = repo[id];
|
||||
if (item) {
|
||||
item.map.renderers.forEach(pool => {
|
||||
pool.close();
|
||||
});
|
||||
}
|
||||
delete repo[id];
|
||||
},
|
||||
};
|
||||
|
|
|
@ -72,10 +72,19 @@ module.exports = {
|
|||
|
||||
return app;
|
||||
},
|
||||
remove: (repo, id) => {
|
||||
delete repo[id];
|
||||
},
|
||||
add: (options, repo, params, id, publicUrl, reportTiles, reportFont) => {
|
||||
const styleFile = path.resolve(options.paths.styles, params.style);
|
||||
let styleJSON;
|
||||
try {
|
||||
styleJSON = JSON.parse(fs.readFileSync(styleFile));
|
||||
} catch (e) {
|
||||
console.log('Error parsing style file');
|
||||
return false;
|
||||
}
|
||||
|
||||
const styleJSON = clone(require(styleFile));
|
||||
for (const name of Object.keys(styleJSON.sources)) {
|
||||
const source = styleJSON.sources[name];
|
||||
const url = source.url;
|
||||
|
@ -92,6 +101,9 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
const identifier = reportTiles(mbtilesFile, fromData);
|
||||
if (!identifier) {
|
||||
return false;
|
||||
}
|
||||
source.url = `local://data/${identifier}.json`;
|
||||
}
|
||||
}
|
||||
|
@ -128,5 +140,7 @@ module.exports = {
|
|||
publicUrl,
|
||||
name: styleJSON.name
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ const express = require('express');
|
|||
const handlebars = require('handlebars');
|
||||
const mercator = new (require('@mapbox/sphericalmercator'))();
|
||||
const morgan = require('morgan');
|
||||
const watch = require('node-watch');
|
||||
|
||||
const packageJson = require('../package');
|
||||
const serve_font = require('./serve_font');
|
||||
|
@ -114,15 +115,10 @@ function start(opts) {
|
|||
);
|
||||
}
|
||||
|
||||
for (const id of Object.keys(config.styles || {})) {
|
||||
const item = config.styles[id];
|
||||
if (!item.style || item.style.length === 0) {
|
||||
console.log(`Missing "style" property for ${id}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let addStyle = (id, item, allowMoreData, reportFonts) => {
|
||||
let success = true;
|
||||
if (item.serve_data !== false) {
|
||||
serve_style.add(options, serving.styles, item, id, opts.publicUrl,
|
||||
success = serve_style.add(options, serving.styles, item, id, opts.publicUrl,
|
||||
(mbtiles, fromData) => {
|
||||
let dataItemId;
|
||||
for (const id of Object.keys(data)) {
|
||||
|
@ -138,22 +134,26 @@ function start(opts) {
|
|||
}
|
||||
if (dataItemId) { // mbtiles exist in the data config
|
||||
return dataItemId;
|
||||
} else if (fromData) {
|
||||
console.log(`ERROR: data "${mbtiles}" not found!`);
|
||||
process.exit(1);
|
||||
} else {
|
||||
let id = mbtiles.substr(0, mbtiles.lastIndexOf('.')) || mbtiles;
|
||||
while (data[id]) id += '_';
|
||||
data[id] = {
|
||||
'mbtiles': mbtiles
|
||||
};
|
||||
return id;
|
||||
if (fromData || !allowMoreData) {
|
||||
console.log(`ERROR: style "${file.name}" using unknown mbtiles "${mbtiles}"! Skipping...`);
|
||||
return undefined;
|
||||
} else {
|
||||
let id = mbtiles.substr(0, mbtiles.lastIndexOf('.')) || mbtiles;
|
||||
while (data[id]) id += '_';
|
||||
data[id] = {
|
||||
'mbtiles': mbtiles
|
||||
};
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}, font => {
|
||||
serving.fonts[font] = true;
|
||||
if (reportFonts) {
|
||||
serving.fonts[font] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (item.serve_rendered !== false) {
|
||||
if (success && item.serve_rendered !== false) {
|
||||
if (serve_rendered) {
|
||||
startupPromises.push(serve_rendered.add(options, serving.rendered, item, id, opts.publicUrl,
|
||||
mbtiles => {
|
||||
|
@ -170,6 +170,16 @@ function start(opts) {
|
|||
item.serve_rendered = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const id of Object.keys(config.styles || {})) {
|
||||
const item = config.styles[id];
|
||||
if (!item.style || item.style.length === 0) {
|
||||
console.log(`Missing "style" property for ${id}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
addStyle(id, item, true, true);
|
||||
}
|
||||
|
||||
startupPromises.push(
|
||||
|
@ -190,6 +200,41 @@ function start(opts) {
|
|||
);
|
||||
}
|
||||
|
||||
if (options.serveAllStyles) {
|
||||
fs.readdir(options.paths.styles, {withFileTypes: true}, (err, files) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
for (const file of files) {
|
||||
if (file.isFile() &&
|
||||
path.extname(file.name).toLowerCase() == '.json') {
|
||||
let id = path.basename(file.name, '.json');
|
||||
let item = {
|
||||
style: file.name
|
||||
};
|
||||
addStyle(id, item, false, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.paths.styles,
|
||||
{ persistent: false, filter: /\.json$/ },
|
||||
(eventType, filename) => {
|
||||
let id = path.basename(filename, '.json');
|
||||
console.log(`Style "${id}" changed, updating...`);
|
||||
|
||||
serve_style.remove(serving.styles, id);
|
||||
serve_rendered.remove(serving.rendered, id);
|
||||
|
||||
if (eventType == "update") {
|
||||
let item = {
|
||||
style: filename
|
||||
};
|
||||
addStyle(id, item, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
app.get('/styles.json', (req, res, next) => {
|
||||
const result = [];
|
||||
const query = req.query.key ? (`?key=${req.query.key}`) : '';
|
||||
|
@ -207,10 +252,9 @@ function start(opts) {
|
|||
|
||||
const addTileJSONs = (arr, req, type) => {
|
||||
for (const id of Object.keys(serving[type])) {
|
||||
let info = clone(serving[type][id]);
|
||||
const info = clone(serving[type][id].tileJSON);
|
||||
let path = '';
|
||||
if (type === 'rendered') {
|
||||
info = info.tileJSON;
|
||||
path = `styles/${id}`;
|
||||
} else {
|
||||
path = `${type}/${id}`;
|
||||
|
@ -280,7 +324,7 @@ function start(opts) {
|
|||
};
|
||||
|
||||
serveTemplate('/$', 'index', req => {
|
||||
const styles = clone(config.styles || {});
|
||||
const styles = clone(serving.styles || {});
|
||||
for (const id of Object.keys(styles)) {
|
||||
const style = styles[id];
|
||||
style.name = (serving.styles[id] || serving.rendered[id] || {}).name;
|
||||
|
@ -341,7 +385,7 @@ function start(opts) {
|
|||
|
||||
serveTemplate('/styles/:id/$', 'viewer', req => {
|
||||
const id = req.params.id;
|
||||
const style = clone((config.styles || {})[id]);
|
||||
const style = clone(((serving.styles || {})[id] || {}).styleJSON);
|
||||
if (!style) {
|
||||
return null;
|
||||
}
|
||||
|
@ -359,7 +403,7 @@ function start(opts) {
|
|||
*/
|
||||
serveTemplate('/styles/:id/wmts.xml', 'wmts', req => {
|
||||
const id = req.params.id;
|
||||
const wmts = clone((config.styles || {})[id]);
|
||||
const wmts = clone((serving.styles || {})[id]);
|
||||
if (!wmts) {
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue