tileserver-gl-light 5.3.1 → 5.4.0-pre.0
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 +6 -3
- package/docs/config.rst +30 -7
- package/package.json +7 -7
- package/public/resources/maplibre-gl.js +4 -4
- package/public/resources/maplibre-gl.js.map +1 -1
- package/src/serve_data.js +20 -32
- package/src/serve_rendered.js +15 -1
- package/src/server.js +69 -12
- package/src/utils.js +4 -1
package/src/serve_data.js
CHANGED
|
@@ -108,7 +108,11 @@ export const serve_data = {
|
|
|
108
108
|
x,
|
|
109
109
|
y,
|
|
110
110
|
);
|
|
111
|
-
if (fetchTile == null
|
|
111
|
+
if (fetchTile == null && item.tileJSON.sparse) {
|
|
112
|
+
return res.status(410).send();
|
|
113
|
+
} else if (fetchTile == null) {
|
|
114
|
+
return res.status(204).send();
|
|
115
|
+
}
|
|
112
116
|
|
|
113
117
|
let data = fetchTile.data;
|
|
114
118
|
let headers = fetchTile.headers;
|
|
@@ -366,51 +370,35 @@ export const serve_data = {
|
|
|
366
370
|
|
|
367
371
|
let source;
|
|
368
372
|
let sourceType;
|
|
373
|
+
tileJSON['name'] = id;
|
|
374
|
+
tileJSON['format'] = 'pbf';
|
|
375
|
+
tileJSON['encoding'] = params['encoding'];
|
|
376
|
+
tileJSON['tileSize'] = params['tileSize'];
|
|
377
|
+
tileJSON['sparse'] = params['sparse'];
|
|
378
|
+
|
|
369
379
|
if (inputType === 'pmtiles') {
|
|
370
380
|
source = openPMtiles(inputFile);
|
|
371
381
|
sourceType = 'pmtiles';
|
|
372
382
|
const metadata = await getPMtilesInfo(source);
|
|
373
|
-
|
|
374
|
-
tileJSON['encoding'] = params['encoding'];
|
|
375
|
-
tileJSON['tileSize'] = params['tileSize'];
|
|
376
|
-
tileJSON['name'] = id;
|
|
377
|
-
tileJSON['format'] = 'pbf';
|
|
378
383
|
Object.assign(tileJSON, metadata);
|
|
379
|
-
|
|
380
|
-
tileJSON['tilejson'] = '2.0.0';
|
|
381
|
-
delete tileJSON['filesize'];
|
|
382
|
-
delete tileJSON['mtime'];
|
|
383
|
-
delete tileJSON['scheme'];
|
|
384
|
-
|
|
385
|
-
Object.assign(tileJSON, params.tilejson || {});
|
|
386
|
-
fixTileJSONCenter(tileJSON);
|
|
387
|
-
|
|
388
|
-
if (options.dataDecoratorFunc) {
|
|
389
|
-
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
|
|
390
|
-
}
|
|
391
384
|
} else if (inputType === 'mbtiles') {
|
|
392
385
|
sourceType = 'mbtiles';
|
|
393
386
|
const mbw = await openMbTilesWrapper(inputFile);
|
|
394
387
|
const info = await mbw.getInfo();
|
|
395
388
|
source = mbw.getMbTiles();
|
|
396
|
-
tileJSON['encoding'] = params['encoding'];
|
|
397
|
-
tileJSON['tileSize'] = params['tileSize'];
|
|
398
|
-
tileJSON['name'] = id;
|
|
399
|
-
tileJSON['format'] = 'pbf';
|
|
400
|
-
|
|
401
389
|
Object.assign(tileJSON, info);
|
|
390
|
+
}
|
|
402
391
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
392
|
+
delete tileJSON['filesize'];
|
|
393
|
+
delete tileJSON['mtime'];
|
|
394
|
+
delete tileJSON['scheme'];
|
|
395
|
+
tileJSON['tilejson'] = '3.0.0';
|
|
407
396
|
|
|
408
|
-
|
|
409
|
-
|
|
397
|
+
Object.assign(tileJSON, params.tilejson || {});
|
|
398
|
+
fixTileJSONCenter(tileJSON);
|
|
410
399
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
400
|
+
if (options.dataDecoratorFunc) {
|
|
401
|
+
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
|
|
414
402
|
}
|
|
415
403
|
|
|
416
404
|
repo[id] = {
|
package/src/serve_rendered.js
CHANGED
|
@@ -1005,6 +1005,7 @@ export const serve_rendered = {
|
|
|
1005
1005
|
);
|
|
1006
1006
|
}
|
|
1007
1007
|
const info = clone(item.tileJSON);
|
|
1008
|
+
info.tileSize = tileSize != undefined ? tileSize : 256;
|
|
1008
1009
|
info.tiles = getTileUrls(
|
|
1009
1010
|
req,
|
|
1010
1011
|
info.tiles,
|
|
@@ -1122,7 +1123,16 @@ export const serve_rendered = {
|
|
|
1122
1123
|
x,
|
|
1123
1124
|
y,
|
|
1124
1125
|
);
|
|
1125
|
-
if (fetchTile == null) {
|
|
1126
|
+
if (fetchTile == null && sourceInfo.sparse == true) {
|
|
1127
|
+
if (verbose) {
|
|
1128
|
+
console.log(
|
|
1129
|
+
'fetchTile warning on %s, sparse response',
|
|
1130
|
+
req.url,
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
callback();
|
|
1134
|
+
return;
|
|
1135
|
+
} else if (fetchTile == null) {
|
|
1126
1136
|
if (verbose) {
|
|
1127
1137
|
console.log(
|
|
1128
1138
|
'fetchTile error on %s, serving empty response',
|
|
@@ -1308,6 +1318,7 @@ export const serve_rendered = {
|
|
|
1308
1318
|
|
|
1309
1319
|
for (const name of Object.keys(styleJSON.sources)) {
|
|
1310
1320
|
let sourceType;
|
|
1321
|
+
let sparse;
|
|
1311
1322
|
let source = styleJSON.sources[name];
|
|
1312
1323
|
let url = source.url;
|
|
1313
1324
|
if (
|
|
@@ -1332,6 +1343,7 @@ export const serve_rendered = {
|
|
|
1332
1343
|
if (dataInfo.inputFile) {
|
|
1333
1344
|
inputFile = dataInfo.inputFile;
|
|
1334
1345
|
sourceType = dataInfo.fileType;
|
|
1346
|
+
sparse = dataInfo.sparse;
|
|
1335
1347
|
} else {
|
|
1336
1348
|
console.error(`ERROR: data "${inputFile}" not found!`);
|
|
1337
1349
|
process.exit(1);
|
|
@@ -1360,6 +1372,7 @@ export const serve_rendered = {
|
|
|
1360
1372
|
const type = source.type;
|
|
1361
1373
|
Object.assign(source, metadata);
|
|
1362
1374
|
source.type = type;
|
|
1375
|
+
source.sparse = sparse;
|
|
1363
1376
|
source.tiles = [
|
|
1364
1377
|
// meta url which will be detected when requested
|
|
1365
1378
|
`pmtiles://${name}/{z}/{x}/{y}.${metadata.format || 'pbf'}`,
|
|
@@ -1399,6 +1412,7 @@ export const serve_rendered = {
|
|
|
1399
1412
|
const type = source.type;
|
|
1400
1413
|
Object.assign(source, info);
|
|
1401
1414
|
source.type = type;
|
|
1415
|
+
source.sparse = sparse;
|
|
1402
1416
|
source.tiles = [
|
|
1403
1417
|
// meta url which will be detected when requested
|
|
1404
1418
|
`mbtiles://${name}/{z}/{x}/{y}.${info.format || 'pbf'}`,
|
package/src/server.js
CHANGED
|
@@ -268,23 +268,80 @@ async function start(opts) {
|
|
|
268
268
|
opts,
|
|
269
269
|
styleJSON,
|
|
270
270
|
function dataResolver(styleSourceId) {
|
|
271
|
-
let
|
|
272
|
-
let
|
|
271
|
+
let resolvedFileType;
|
|
272
|
+
let resolvedInputFile;
|
|
273
|
+
let resolvedSparse = false;
|
|
274
|
+
|
|
273
275
|
for (const id of Object.keys(data)) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
276
|
+
const sourceData = data[id];
|
|
277
|
+
let currentFileType;
|
|
278
|
+
let currentInputFileValue;
|
|
279
|
+
|
|
280
|
+
// Check for recognized file type keys
|
|
281
|
+
if (sourceData.hasOwnProperty('pmtiles')) {
|
|
282
|
+
currentFileType = 'pmtiles';
|
|
283
|
+
currentInputFileValue = sourceData.pmtiles;
|
|
284
|
+
} else if (sourceData.hasOwnProperty('mbtiles')) {
|
|
285
|
+
currentFileType = 'mbtiles';
|
|
286
|
+
currentInputFileValue = sourceData.mbtiles;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (currentFileType && currentInputFileValue) {
|
|
290
|
+
// Check if this source matches the styleSourceId
|
|
291
|
+
if (
|
|
292
|
+
styleSourceId === id ||
|
|
293
|
+
styleSourceId === currentInputFileValue
|
|
294
|
+
) {
|
|
295
|
+
resolvedFileType = currentFileType;
|
|
296
|
+
resolvedInputFile = currentInputFileValue;
|
|
297
|
+
|
|
298
|
+
// Get sparse flag specifically from this matching source
|
|
299
|
+
// Default to false if 'sparse' key doesn't exist or is falsy in a boolean context
|
|
300
|
+
if (sourceData.hasOwnProperty('sparse')) {
|
|
301
|
+
resolvedSparse = !!sourceData.sparse; // Ensure boolean
|
|
302
|
+
} else {
|
|
303
|
+
resolvedSparse = false; // Explicitly set default if not present on item
|
|
304
|
+
}
|
|
305
|
+
break; // Found our match, exit the outer loop
|
|
306
|
+
}
|
|
281
307
|
}
|
|
282
308
|
}
|
|
283
|
-
|
|
284
|
-
|
|
309
|
+
|
|
310
|
+
// If no match was found
|
|
311
|
+
if (!resolvedInputFile || !resolvedFileType) {
|
|
312
|
+
console.warn(
|
|
313
|
+
`Data source not found for styleSourceId: ${styleSourceId}`,
|
|
314
|
+
);
|
|
315
|
+
return {
|
|
316
|
+
inputFile: undefined,
|
|
317
|
+
fileType: undefined,
|
|
318
|
+
sparse: false,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (!isValidHttpUrl(resolvedInputFile)) {
|
|
323
|
+
// Ensure options.paths and options.paths[resolvedFileType] exist before trying to use them
|
|
324
|
+
if (
|
|
325
|
+
options &&
|
|
326
|
+
options.paths &&
|
|
327
|
+
options.paths[resolvedFileType]
|
|
328
|
+
) {
|
|
329
|
+
resolvedInputFile = path.resolve(
|
|
330
|
+
options.paths[resolvedFileType],
|
|
331
|
+
resolvedInputFile,
|
|
332
|
+
);
|
|
333
|
+
} else {
|
|
334
|
+
console.warn(
|
|
335
|
+
`Path configuration missing for fileType: ${resolvedFileType}. Using relative path for: ${resolvedInputFile}`,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
285
338
|
}
|
|
286
339
|
|
|
287
|
-
return {
|
|
340
|
+
return {
|
|
341
|
+
inputFile: resolvedInputFile,
|
|
342
|
+
fileType: resolvedFileType,
|
|
343
|
+
sparse: resolvedSparse,
|
|
344
|
+
};
|
|
288
345
|
},
|
|
289
346
|
),
|
|
290
347
|
);
|
package/src/utils.js
CHANGED
|
@@ -198,9 +198,12 @@ export function getTileUrls(
|
|
|
198
198
|
const uris = [];
|
|
199
199
|
if (!publicUrl) {
|
|
200
200
|
let xForwardedPath = `${req.get('X-Forwarded-Path') ? '/' + req.get('X-Forwarded-Path') : ''}`;
|
|
201
|
+
let protocol = req.get('X-Forwarded-Protocol')
|
|
202
|
+
? req.get('X-Forwarded-Protocol')
|
|
203
|
+
: req.protocol;
|
|
201
204
|
for (const domain of domains) {
|
|
202
205
|
uris.push(
|
|
203
|
-
`${
|
|
206
|
+
`${protocol}://${domain}${xForwardedPath}/${path}/${tileParams}${format}${query}`,
|
|
204
207
|
);
|
|
205
208
|
}
|
|
206
209
|
} else {
|