tileserver-gl-light 5.5.0-pre.4 → 5.5.0-pre.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -1
- package/docs/config.rst +11 -10
- package/docs/usage.rst +21 -0
- package/package.json +6 -6
- package/public/resources/maplibre-gl-inspect.js +12 -8
- package/public/resources/maplibre-gl-inspect.js.map +1 -1
- package/public/resources/maplibre-gl.js +4 -4
- package/public/resources/maplibre-gl.js.map +1 -1
- package/src/main.js +15 -3
- package/src/pmtiles_adapter.js +27 -3
- package/src/serve_data.js +22 -11
- package/src/serve_font.js +2 -2
- package/src/serve_rendered.js +132 -76
- package/src/serve_style.js +29 -8
- package/src/server.js +87 -35
- package/src/utils.js +1 -2
- package/test/tiles_data.js +1 -1
package/src/main.js
CHANGED
|
@@ -82,7 +82,10 @@ program
|
|
|
82
82
|
)
|
|
83
83
|
.option(
|
|
84
84
|
'-V, --verbose [level]',
|
|
85
|
-
'More verbose output (
|
|
85
|
+
'More verbose output (level 1-3)\n' +
|
|
86
|
+
'\t-V, --verbose, -V 1, or --verbose 1: Important operations\n' +
|
|
87
|
+
'\t-V 2 or --verbose 2: Detailed operations\n' +
|
|
88
|
+
'\t-V 3 or --verbose 3: All requests and debug info',
|
|
86
89
|
(value) => {
|
|
87
90
|
// If no value provided, return 1 (boolean true case)
|
|
88
91
|
if (value === undefined || value === true) return 1;
|
|
@@ -92,6 +95,14 @@ program
|
|
|
92
95
|
return isNaN(level) ? 1 : Math.min(Math.max(level, 1), 3);
|
|
93
96
|
},
|
|
94
97
|
)
|
|
98
|
+
.option(
|
|
99
|
+
'--fetch-timeout <ms>',
|
|
100
|
+
'External fetch timeout in milliseconds for renderer HTTP requests (default 15000)',
|
|
101
|
+
(value) => {
|
|
102
|
+
const v = parseInt(value, 10);
|
|
103
|
+
return isNaN(v) ? 15000 : v;
|
|
104
|
+
},
|
|
105
|
+
)
|
|
95
106
|
.option('-s, --silent', 'Less verbose output')
|
|
96
107
|
.option('-l|--log_file <file>', 'output log file (defaults to standard out)')
|
|
97
108
|
.option(
|
|
@@ -119,6 +130,7 @@ const startServer = (configPath, config) => {
|
|
|
119
130
|
silent: opts.silent,
|
|
120
131
|
logFile: opts.log_file,
|
|
121
132
|
logFormat: opts.log_format,
|
|
133
|
+
fetchTimeout: opts.fetchTimeout,
|
|
122
134
|
publicUrl,
|
|
123
135
|
});
|
|
124
136
|
};
|
|
@@ -246,7 +258,7 @@ const startWithInputFile = async (inputFile) => {
|
|
|
246
258
|
}
|
|
247
259
|
}
|
|
248
260
|
|
|
249
|
-
if (opts.verbose) {
|
|
261
|
+
if (opts.verbose >= 1) {
|
|
250
262
|
console.log(JSON.stringify(config, undefined, 2));
|
|
251
263
|
} else {
|
|
252
264
|
console.log('Run with --verbose to see the config file here.');
|
|
@@ -304,7 +316,7 @@ const startWithInputFile = async (inputFile) => {
|
|
|
304
316
|
};
|
|
305
317
|
}
|
|
306
318
|
|
|
307
|
-
if (opts.verbose) {
|
|
319
|
+
if (opts.verbose >= 1) {
|
|
308
320
|
console.log(JSON.stringify(config, undefined, 2));
|
|
309
321
|
} else {
|
|
310
322
|
console.log('Run with --verbose to see the config file here.');
|
package/src/pmtiles_adapter.js
CHANGED
|
@@ -18,7 +18,7 @@ class S3Source {
|
|
|
18
18
|
* @param {boolean} [configRequestPayer] - Optional flag from config for requester pays buckets.
|
|
19
19
|
* @param {string} [configRegion] - Optional AWS region from config.
|
|
20
20
|
* @param {string} [s3UrlFormat] - Optional S3 URL format from config: 'aws' or 'custom'.
|
|
21
|
-
* @param {
|
|
21
|
+
* @param {number} [verbose] - Verbosity level (1-3). 1=important, 2=detailed, 3=debug/all requests.
|
|
22
22
|
*/
|
|
23
23
|
constructor(
|
|
24
24
|
s3Url,
|
|
@@ -147,7 +147,7 @@ class S3Source {
|
|
|
147
147
|
* @param {string|null} endpoint - The custom endpoint URL, or null for default AWS S3.
|
|
148
148
|
* @param {string} region - The AWS region.
|
|
149
149
|
* @param {string} [profile] - Optional AWS credential profile name.
|
|
150
|
-
* @param {
|
|
150
|
+
* @param {number} [verbose] - Verbosity level (1-3). 1=important, 2=detailed, 3=debug/all requests.
|
|
151
151
|
* @returns {S3Client} - Configured S3Client instance.
|
|
152
152
|
*/
|
|
153
153
|
createS3Client(endpoint, region, profile, verbose) {
|
|
@@ -308,14 +308,18 @@ async function readFileBytes(fd, buffer, offset) {
|
|
|
308
308
|
});
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
// Cache for PMTiles objects to avoid creating multiple instances for the same URL
|
|
312
|
+
const pmtilesCache = new Map();
|
|
313
|
+
|
|
311
314
|
/**
|
|
312
315
|
* Opens a PMTiles file from local filesystem, HTTP URL, or S3 URL.
|
|
316
|
+
* Uses caching to avoid creating multiple PMTiles instances for the same file.
|
|
313
317
|
* @param {string} filePath - The path to the PMTiles file.
|
|
314
318
|
* @param {string} [s3Profile] - Optional AWS credential profile name.
|
|
315
319
|
* @param {boolean} [requestPayer] - Optional flag for requester pays buckets.
|
|
316
320
|
* @param {string} [s3Region] - Optional AWS region.
|
|
317
321
|
* @param {string} [s3UrlFormat] - Optional S3 URL format: 'aws' or 'custom'.
|
|
318
|
-
* @param {
|
|
322
|
+
* @param {number} [verbose] - Verbosity level (1-3). 1=important, 2=detailed, 3=debug/all requests.
|
|
319
323
|
* @returns {PMTiles} - A PMTiles instance.
|
|
320
324
|
*/
|
|
321
325
|
export function openPMtiles(
|
|
@@ -326,6 +330,23 @@ export function openPMtiles(
|
|
|
326
330
|
s3UrlFormat,
|
|
327
331
|
verbose = 0,
|
|
328
332
|
) {
|
|
333
|
+
// Create a cache key that includes all parameters that affect the source
|
|
334
|
+
const cacheKey = JSON.stringify({
|
|
335
|
+
filePath,
|
|
336
|
+
s3Profile,
|
|
337
|
+
requestPayer,
|
|
338
|
+
s3Region,
|
|
339
|
+
s3UrlFormat,
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Check if we already have a PMTiles object for this configuration
|
|
343
|
+
if (pmtilesCache.has(cacheKey)) {
|
|
344
|
+
if (verbose >= 2) {
|
|
345
|
+
console.log(`Using cached PMTiles instance for: ${filePath}`);
|
|
346
|
+
}
|
|
347
|
+
return pmtilesCache.get(cacheKey);
|
|
348
|
+
}
|
|
349
|
+
|
|
329
350
|
let pmtiles = undefined;
|
|
330
351
|
|
|
331
352
|
if (isS3Url(filePath)) {
|
|
@@ -357,6 +378,9 @@ export function openPMtiles(
|
|
|
357
378
|
pmtiles = new PMTiles(source);
|
|
358
379
|
}
|
|
359
380
|
|
|
381
|
+
// Cache the PMTiles object
|
|
382
|
+
pmtilesCache.set(cacheKey, pmtiles);
|
|
383
|
+
|
|
360
384
|
return pmtiles;
|
|
361
385
|
}
|
|
362
386
|
|
package/src/serve_data.js
CHANGED
|
@@ -58,7 +58,7 @@ export const serve_data = {
|
|
|
58
58
|
* @returns {Promise<void>}
|
|
59
59
|
*/
|
|
60
60
|
app.get('/:id/:z/:x/:y.:format', async (req, res) => {
|
|
61
|
-
if (verbose) {
|
|
61
|
+
if (verbose >= 1) {
|
|
62
62
|
console.log(
|
|
63
63
|
`Handling tile request for: /data/%s/%s/%s/%s.%s`,
|
|
64
64
|
String(req.params.id).replace(/\n|\r/g, ''),
|
|
@@ -109,10 +109,10 @@ export const serve_data = {
|
|
|
109
109
|
x,
|
|
110
110
|
y,
|
|
111
111
|
);
|
|
112
|
-
if (fetchTile == null
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return res.status(204).send();
|
|
112
|
+
if (fetchTile == null) {
|
|
113
|
+
// sparse=true (default) -> 404 (allows overzoom)
|
|
114
|
+
// sparse=false -> 204 (empty tile, no overzoom)
|
|
115
|
+
return res.status(item.sparse ? 404 : 204).send();
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
let data = fetchTile.data;
|
|
@@ -180,7 +180,7 @@ export const serve_data = {
|
|
|
180
180
|
*/
|
|
181
181
|
app.get('/:id/elevation/:z/:x/:y', async (req, res, next) => {
|
|
182
182
|
try {
|
|
183
|
-
if (verbose) {
|
|
183
|
+
if (verbose >= 1) {
|
|
184
184
|
console.log(
|
|
185
185
|
`Handling elevation request for: /data/%s/elevation/%s/%s/%s`,
|
|
186
186
|
String(req.params.id).replace(/\n|\r/g, ''),
|
|
@@ -261,7 +261,11 @@ export const serve_data = {
|
|
|
261
261
|
xy[0],
|
|
262
262
|
xy[1],
|
|
263
263
|
);
|
|
264
|
-
if (fetchTile == null)
|
|
264
|
+
if (fetchTile == null) {
|
|
265
|
+
// sparse=true (default) -> 404 (allows overzoom)
|
|
266
|
+
// sparse=false -> 204 (empty tile, no overzoom)
|
|
267
|
+
return res.status(item.sparse ? 404 : 204).send();
|
|
268
|
+
}
|
|
265
269
|
|
|
266
270
|
let data = fetchTile.data;
|
|
267
271
|
var param = {
|
|
@@ -294,7 +298,7 @@ export const serve_data = {
|
|
|
294
298
|
* @returns {Promise<void>}
|
|
295
299
|
*/
|
|
296
300
|
app.get('/:id.json', (req, res) => {
|
|
297
|
-
if (verbose) {
|
|
301
|
+
if (verbose >= 1) {
|
|
298
302
|
console.log(
|
|
299
303
|
`Handling tilejson request for: /data/%s.json`,
|
|
300
304
|
String(req.params.id).replace(/\n|\r/g, ''),
|
|
@@ -331,7 +335,7 @@ export const serve_data = {
|
|
|
331
335
|
* @param {string} id ID of the data source.
|
|
332
336
|
* @param {object} programOpts - An object containing the program options
|
|
333
337
|
* @param {string} programOpts.publicUrl Public URL for the data.
|
|
334
|
-
* @param {
|
|
338
|
+
* @param {number} programOpts.verbose Verbosity level (1-3). 1=important, 2=detailed, 3=debug/all requests.
|
|
335
339
|
* @returns {Promise<void>}
|
|
336
340
|
*/
|
|
337
341
|
add: async function (options, repo, params, id, programOpts) {
|
|
@@ -359,7 +363,7 @@ export const serve_data = {
|
|
|
359
363
|
}
|
|
360
364
|
}
|
|
361
365
|
|
|
362
|
-
if (verbose
|
|
366
|
+
if (verbose >= 1) {
|
|
363
367
|
console.log(`[INFO] Loading data source '${id}' from: ${inputFile}`);
|
|
364
368
|
}
|
|
365
369
|
|
|
@@ -381,7 +385,6 @@ export const serve_data = {
|
|
|
381
385
|
tileJSON['format'] = 'pbf';
|
|
382
386
|
tileJSON['encoding'] = params['encoding'];
|
|
383
387
|
tileJSON['tileSize'] = params['tileSize'];
|
|
384
|
-
tileJSON['sparse'] = params['sparse'];
|
|
385
388
|
|
|
386
389
|
if (inputType === 'pmtiles') {
|
|
387
390
|
source = openPMtiles(
|
|
@@ -415,12 +418,20 @@ export const serve_data = {
|
|
|
415
418
|
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
|
|
416
419
|
}
|
|
417
420
|
|
|
421
|
+
// Determine sparse: per-source overrides global, then format-based default
|
|
422
|
+
// sparse=true -> 404 (allows overzoom)
|
|
423
|
+
// sparse=false -> 204 (empty tile, no overzoom)
|
|
424
|
+
// Default: vector tiles (pbf) -> false, raster tiles -> true
|
|
425
|
+
const isVector = tileJSON.format === 'pbf';
|
|
426
|
+
const sparse = params.sparse ?? options.sparse ?? !isVector;
|
|
427
|
+
|
|
418
428
|
// eslint-disable-next-line security/detect-object-injection -- id is from config file data source names
|
|
419
429
|
repo[id] = {
|
|
420
430
|
tileJSON,
|
|
421
431
|
publicUrl,
|
|
422
432
|
source,
|
|
423
433
|
sourceType,
|
|
434
|
+
sparse,
|
|
424
435
|
};
|
|
425
436
|
},
|
|
426
437
|
};
|
package/src/serve_font.js
CHANGED
|
@@ -36,7 +36,7 @@ export async function serve_font(options, allowedFonts, programOpts) {
|
|
|
36
36
|
'',
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
-
if (verbose) {
|
|
39
|
+
if (verbose >= 1) {
|
|
40
40
|
console.log(
|
|
41
41
|
`Handling font request for: /fonts/%s/%s.pbf`,
|
|
42
42
|
sFontStack,
|
|
@@ -86,7 +86,7 @@ export async function serve_font(options, allowedFonts, programOpts) {
|
|
|
86
86
|
* @returns {void}
|
|
87
87
|
*/
|
|
88
88
|
app.get('/fonts.json', (req, res) => {
|
|
89
|
-
if (verbose) {
|
|
89
|
+
if (verbose >= 1) {
|
|
90
90
|
console.log('Handling list font request for /fonts.json');
|
|
91
91
|
}
|
|
92
92
|
res.header('Content-type', 'application/json');
|