tileserver-gl-light 4.13.3 → 5.1.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/.github/workflows/release.yml +69 -12
- package/CHANGELOG.md +13 -0
- package/Dockerfile +1 -1
- package/PUBLISHING.md +17 -11
- package/changelog_for_version.md +5 -0
- package/docs/config.rst +21 -3
- package/docs/endpoints.rst +8 -0
- package/docs/installation.rst +4 -4
- package/package.json +6 -4
- package/public/resources/elevation-control.js +51 -0
- package/public/resources/index.css +1 -1
- package/public/templates/data.tmpl +121 -42
- package/public/templates/index.tmpl +18 -7
- package/src/main.js +6 -0
- package/src/serve_data.js +335 -140
- package/src/serve_font.js +76 -25
- package/src/serve_light.js +2 -2
- package/src/serve_rendered.js +569 -411
- package/src/serve_style.js +181 -56
- package/src/server.js +189 -92
- package/src/utils.js +251 -69
- package/test/setup.js +2 -2
- package/test/static.js +2 -2
- package/test/tiles_rendered.js +7 -7
- package/.husky/commit-msg +0 -18
- package/.husky/pre-push +0 -1
package/src/server.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
import os from 'os';
|
|
5
|
-
process.env.UV_THREADPOOL_SIZE = Math.ceil(Math.max(4, os.cpus().length * 1.5));
|
|
6
|
-
|
|
7
4
|
import fs from 'node:fs';
|
|
8
5
|
import path from 'path';
|
|
9
6
|
import fnv1a from '@sindresorhus/fnv1a';
|
|
@@ -19,7 +16,12 @@ import morgan from 'morgan';
|
|
|
19
16
|
import { serve_data } from './serve_data.js';
|
|
20
17
|
import { serve_style } from './serve_style.js';
|
|
21
18
|
import { serve_font } from './serve_font.js';
|
|
22
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
allowedTileSizes,
|
|
21
|
+
getTileUrls,
|
|
22
|
+
getPublicUrl,
|
|
23
|
+
isValidHttpUrl,
|
|
24
|
+
} from './utils.js';
|
|
23
25
|
|
|
24
26
|
import { fileURLToPath } from 'url';
|
|
25
27
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -34,10 +36,11 @@ const serve_rendered = (
|
|
|
34
36
|
).serve_rendered;
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @param opts
|
|
39
|
+
* Starts the server.
|
|
40
|
+
* @param {object} opts - Configuration options for the server.
|
|
41
|
+
* @returns {Promise<object>} - A promise that resolves to the server object.
|
|
39
42
|
*/
|
|
40
|
-
function start(opts) {
|
|
43
|
+
async function start(opts) {
|
|
41
44
|
console.log('Starting server');
|
|
42
45
|
|
|
43
46
|
const app = express().disable('x-powered-by');
|
|
@@ -73,7 +76,7 @@ function start(opts) {
|
|
|
73
76
|
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
74
77
|
} catch (e) {
|
|
75
78
|
console.log('ERROR: Config file not found or invalid!');
|
|
76
|
-
console.log('
|
|
79
|
+
console.log(' See README.md for instructions and sample data.');
|
|
77
80
|
process.exit(1);
|
|
78
81
|
}
|
|
79
82
|
}
|
|
@@ -116,8 +119,9 @@ function start(opts) {
|
|
|
116
119
|
* Recursively get all files within a directory.
|
|
117
120
|
* Inspired by https://stackoverflow.com/a/45130990/10133863
|
|
118
121
|
* @param {string} directory Absolute path to a directory to get files from.
|
|
122
|
+
* @returns {Promise<string[]>} - A promise that resolves to an array of file paths relative to the icon directory.
|
|
119
123
|
*/
|
|
120
|
-
|
|
124
|
+
async function getFiles(directory) {
|
|
121
125
|
// Fetch all entries of the directory and attach type information
|
|
122
126
|
const dirEntries = await fs.promises.readdir(directory, {
|
|
123
127
|
withFileTypes: true,
|
|
@@ -136,7 +140,7 @@ function start(opts) {
|
|
|
136
140
|
|
|
137
141
|
// Flatten the list of files to a single array
|
|
138
142
|
return files.flat();
|
|
139
|
-
}
|
|
143
|
+
}
|
|
140
144
|
|
|
141
145
|
// Load all available icons into a settings object
|
|
142
146
|
startupPromises.push(
|
|
@@ -159,18 +163,25 @@ function start(opts) {
|
|
|
159
163
|
app.use(cors());
|
|
160
164
|
}
|
|
161
165
|
|
|
162
|
-
app.use('/data/', serve_data.init(options, serving.data));
|
|
166
|
+
app.use('/data/', serve_data.init(options, serving.data, opts));
|
|
163
167
|
app.use('/files/', express.static(paths.files));
|
|
164
|
-
app.use('/styles/', serve_style.init(options, serving.styles));
|
|
168
|
+
app.use('/styles/', serve_style.init(options, serving.styles, opts));
|
|
165
169
|
if (!isLight) {
|
|
166
170
|
startupPromises.push(
|
|
167
|
-
serve_rendered.init(options, serving.rendered).then((sub) => {
|
|
171
|
+
serve_rendered.init(options, serving.rendered, opts).then((sub) => {
|
|
168
172
|
app.use('/styles/', sub);
|
|
169
173
|
}),
|
|
170
174
|
);
|
|
171
175
|
}
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Adds a style to the server.
|
|
178
|
+
* @param {string} id - The ID of the style.
|
|
179
|
+
* @param {object} item - The style configuration object.
|
|
180
|
+
* @param {boolean} allowMoreData - Whether to allow adding more data sources.
|
|
181
|
+
* @param {boolean} reportFonts - Whether to report fonts.
|
|
182
|
+
* @returns {void}
|
|
183
|
+
*/
|
|
184
|
+
function addStyle(id, item, allowMoreData, reportFonts) {
|
|
174
185
|
let success = true;
|
|
175
186
|
if (item.serve_data !== false) {
|
|
176
187
|
success = serve_style.add(
|
|
@@ -178,7 +189,7 @@ function start(opts) {
|
|
|
178
189
|
serving.styles,
|
|
179
190
|
item,
|
|
180
191
|
id,
|
|
181
|
-
opts
|
|
192
|
+
opts,
|
|
182
193
|
(styleSourceId, protocol) => {
|
|
183
194
|
let dataItemId;
|
|
184
195
|
for (const id of Object.keys(data)) {
|
|
@@ -235,7 +246,7 @@ function start(opts) {
|
|
|
235
246
|
serving.rendered,
|
|
236
247
|
item,
|
|
237
248
|
id,
|
|
238
|
-
opts
|
|
249
|
+
opts,
|
|
239
250
|
function dataResolver(styleSourceId) {
|
|
240
251
|
let fileType;
|
|
241
252
|
let inputFile;
|
|
@@ -261,7 +272,7 @@ function start(opts) {
|
|
|
261
272
|
item.serve_rendered = false;
|
|
262
273
|
}
|
|
263
274
|
}
|
|
264
|
-
}
|
|
275
|
+
}
|
|
265
276
|
|
|
266
277
|
for (const id of Object.keys(config.styles || {})) {
|
|
267
278
|
const item = config.styles[id];
|
|
@@ -272,13 +283,11 @@ function start(opts) {
|
|
|
272
283
|
|
|
273
284
|
addStyle(id, item, true, true);
|
|
274
285
|
}
|
|
275
|
-
|
|
276
286
|
startupPromises.push(
|
|
277
|
-
serve_font(options, serving.fonts).then((sub) => {
|
|
287
|
+
serve_font(options, serving.fonts, opts).then((sub) => {
|
|
278
288
|
app.use('/', sub);
|
|
279
289
|
}),
|
|
280
290
|
);
|
|
281
|
-
|
|
282
291
|
for (const id of Object.keys(data)) {
|
|
283
292
|
const item = data[id];
|
|
284
293
|
const fileType = Object.keys(data[id])[0];
|
|
@@ -288,12 +297,8 @@ function start(opts) {
|
|
|
288
297
|
);
|
|
289
298
|
continue;
|
|
290
299
|
}
|
|
291
|
-
|
|
292
|
-
startupPromises.push(
|
|
293
|
-
serve_data.add(options, serving.data, item, id, opts.publicUrl),
|
|
294
|
-
);
|
|
300
|
+
startupPromises.push(serve_data.add(options, serving.data, item, id, opts));
|
|
295
301
|
}
|
|
296
|
-
|
|
297
302
|
if (options.serveAllStyles) {
|
|
298
303
|
fs.readdir(options.paths.styles, { withFileTypes: true }, (err, files) => {
|
|
299
304
|
if (err) {
|
|
@@ -333,7 +338,13 @@ function start(opts) {
|
|
|
333
338
|
}
|
|
334
339
|
});
|
|
335
340
|
}
|
|
336
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Handles requests for a list of available styles.
|
|
343
|
+
* @param {object} req - Express request object.
|
|
344
|
+
* @param {object} res - Express response object.
|
|
345
|
+
* @param {string} [req.query.key] - Optional API key.
|
|
346
|
+
* @returns {void}
|
|
347
|
+
*/
|
|
337
348
|
app.get('/styles.json', (req, res, next) => {
|
|
338
349
|
const result = [];
|
|
339
350
|
const query = req.query.key
|
|
@@ -354,7 +365,15 @@ function start(opts) {
|
|
|
354
365
|
res.send(result);
|
|
355
366
|
});
|
|
356
367
|
|
|
357
|
-
|
|
368
|
+
/**
|
|
369
|
+
* Adds TileJSON metadata to an array.
|
|
370
|
+
* @param {Array} arr - The array to add TileJSONs to
|
|
371
|
+
* @param {object} req - The express request object.
|
|
372
|
+
* @param {string} type - The type of resource
|
|
373
|
+
* @param {number} tileSize - The tile size.
|
|
374
|
+
* @returns {Array} - An array of TileJSON objects.
|
|
375
|
+
*/
|
|
376
|
+
function addTileJSONs(arr, req, type, tileSize) {
|
|
358
377
|
for (const id of Object.keys(serving[type])) {
|
|
359
378
|
const info = clone(serving[type][id].tileJSON);
|
|
360
379
|
let path = '';
|
|
@@ -377,20 +396,42 @@ function start(opts) {
|
|
|
377
396
|
arr.push(info);
|
|
378
397
|
}
|
|
379
398
|
return arr;
|
|
380
|
-
}
|
|
399
|
+
}
|
|
381
400
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
401
|
+
/**
|
|
402
|
+
* Handles requests for a rendered tilejson endpoint.
|
|
403
|
+
* @param {object} req - Express request object.
|
|
404
|
+
* @param {object} res - Express response object.
|
|
405
|
+
* @param {string} req.params.tileSize - Optional tile size parameter.
|
|
406
|
+
* @returns {void}
|
|
407
|
+
*/
|
|
408
|
+
app.get('{/:tileSize}/rendered.json', (req, res, next) => {
|
|
409
|
+
const tileSize = allowedTileSizes(req.params['tileSize']);
|
|
410
|
+
res.send(addTileJSONs([], req, 'rendered', parseInt(tileSize, 10)));
|
|
385
411
|
});
|
|
386
|
-
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Handles requests for a data tilejson endpoint.
|
|
415
|
+
* @param {object} req - Express request object.
|
|
416
|
+
* @param {object} res - Express response object.
|
|
417
|
+
* @returns {void}
|
|
418
|
+
*/
|
|
419
|
+
app.get('/data.json', (req, res) => {
|
|
387
420
|
res.send(addTileJSONs([], req, 'data', undefined));
|
|
388
421
|
});
|
|
389
|
-
|
|
390
|
-
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Handles requests for a combined rendered and data tilejson endpoint.
|
|
425
|
+
* @param {object} req - Express request object.
|
|
426
|
+
* @param {object} res - Express response object.
|
|
427
|
+
* @param {string} req.params.tileSize - Optional tile size parameter.
|
|
428
|
+
* @returns {void}
|
|
429
|
+
*/
|
|
430
|
+
app.get('{/:tileSize}/index.json', (req, res, next) => {
|
|
431
|
+
const tileSize = allowedTileSizes(req.params['tileSize']);
|
|
391
432
|
res.send(
|
|
392
433
|
addTileJSONs(
|
|
393
|
-
addTileJSONs([], req, 'rendered', tileSize),
|
|
434
|
+
addTileJSONs([], req, 'rendered', parseInt(tileSize, 10)),
|
|
394
435
|
req,
|
|
395
436
|
'data',
|
|
396
437
|
undefined,
|
|
@@ -403,7 +444,15 @@ function start(opts) {
|
|
|
403
444
|
app.use('/', express.static(path.join(__dirname, '../public/resources')));
|
|
404
445
|
|
|
405
446
|
const templates = path.join(__dirname, '../public/templates');
|
|
406
|
-
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Serves a Handlebars template.
|
|
450
|
+
* @param {string} urlPath - The URL path to serve the template at
|
|
451
|
+
* @param {string} template - The name of the template file
|
|
452
|
+
* @param {Function} dataGetter - A function to get data to be passed to the template.
|
|
453
|
+
* @returns {void}
|
|
454
|
+
*/
|
|
455
|
+
function serveTemplate(urlPath, template, dataGetter) {
|
|
407
456
|
let templateFile = `${templates}/${template}.tmpl`;
|
|
408
457
|
if (template === 'index') {
|
|
409
458
|
if (options.frontPage === false) {
|
|
@@ -415,24 +464,17 @@ function start(opts) {
|
|
|
415
464
|
templateFile = path.resolve(paths.root, options.frontPage);
|
|
416
465
|
}
|
|
417
466
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
let data = {};
|
|
430
|
-
if (dataGetter) {
|
|
431
|
-
data = dataGetter(req);
|
|
432
|
-
if (!data) {
|
|
433
|
-
return res.status(404).send('Not found');
|
|
434
|
-
}
|
|
435
|
-
}
|
|
467
|
+
try {
|
|
468
|
+
const content = fs.readFileSync(templateFile, 'utf-8');
|
|
469
|
+
const compiled = handlebars.compile(content.toString());
|
|
470
|
+
app.get(urlPath, (req, res, next) => {
|
|
471
|
+
if (opts.verbose) {
|
|
472
|
+
console.log(`Serving template at path: ${urlPath}`);
|
|
473
|
+
}
|
|
474
|
+
let data = {};
|
|
475
|
+
if (dataGetter) {
|
|
476
|
+
data = dataGetter(req);
|
|
477
|
+
if (data) {
|
|
436
478
|
data['server_version'] =
|
|
437
479
|
`${packageJson.name} v${packageJson.version}`;
|
|
438
480
|
data['public_url'] = opts.publicUrl || '/';
|
|
@@ -445,14 +487,27 @@ function start(opts) {
|
|
|
445
487
|
: '';
|
|
446
488
|
if (template === 'wmts') res.set('Content-Type', 'text/xml');
|
|
447
489
|
return res.status(200).send(compiled(data));
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
490
|
+
} else {
|
|
491
|
+
if (opts.verbose) {
|
|
492
|
+
console.log(`Forwarding request for: ${urlPath} to next route`);
|
|
493
|
+
}
|
|
494
|
+
next('route');
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
} catch (err) {
|
|
499
|
+
console.error(`Error reading template file: ${templateFile}`, err);
|
|
500
|
+
throw new Error(`Template not found: ${err.message}`); //throw an error so that the server doesnt start
|
|
501
|
+
}
|
|
502
|
+
}
|
|
454
503
|
|
|
455
|
-
|
|
504
|
+
/**
|
|
505
|
+
* Handles requests for the index page, providing a list of available styles and data.
|
|
506
|
+
* @param {object} req - Express request object.
|
|
507
|
+
* @param {object} res - Express response object.
|
|
508
|
+
* @returns {void}
|
|
509
|
+
*/
|
|
510
|
+
serveTemplate('/', 'index', (req) => {
|
|
456
511
|
let styles = {};
|
|
457
512
|
for (const id of Object.keys(serving.styles || {})) {
|
|
458
513
|
let style = {
|
|
@@ -464,11 +519,15 @@ function start(opts) {
|
|
|
464
519
|
if (style.serving_rendered) {
|
|
465
520
|
const { center } = style.serving_rendered.tileJSON;
|
|
466
521
|
if (center) {
|
|
467
|
-
style.viewer_hash = `#${center[2]}/${center[1].toFixed(
|
|
522
|
+
style.viewer_hash = `#${center[2]}/${center[1].toFixed(
|
|
523
|
+
5,
|
|
524
|
+
)}/${center[0].toFixed(5)}`;
|
|
468
525
|
|
|
469
526
|
const centerPx = mercator.px([center[0], center[1]], center[2]);
|
|
470
527
|
// Set thumbnail default size to be 256px x 256px
|
|
471
|
-
style.thumbnail = `${
|
|
528
|
+
style.thumbnail = `${Math.floor(center[2])}/${Math.floor(
|
|
529
|
+
centerPx[0] / 256,
|
|
530
|
+
)}/${Math.floor(centerPx[1] / 256)}.png`;
|
|
472
531
|
}
|
|
473
532
|
|
|
474
533
|
const tileSize = 512;
|
|
@@ -484,7 +543,6 @@ function start(opts) {
|
|
|
484
543
|
|
|
485
544
|
styles[id] = style;
|
|
486
545
|
}
|
|
487
|
-
|
|
488
546
|
let datas = {};
|
|
489
547
|
for (const id of Object.keys(serving.data || {})) {
|
|
490
548
|
let data = Object.assign({}, serving.data[id]);
|
|
@@ -498,14 +556,6 @@ function start(opts) {
|
|
|
498
556
|
)}/${center[0].toFixed(5)}`;
|
|
499
557
|
}
|
|
500
558
|
|
|
501
|
-
data.is_vector = tileJSON.format === 'pbf';
|
|
502
|
-
if (!data.is_vector) {
|
|
503
|
-
if (center) {
|
|
504
|
-
const centerPx = mercator.px([center[0], center[1]], center[2]);
|
|
505
|
-
data.thumbnail = `${center[2]}/${Math.floor(centerPx[0] / 256)}/${Math.floor(centerPx[1] / 256)}.${tileJSON.format}`;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
559
|
const tileSize = undefined;
|
|
510
560
|
data.xyz_link = getTileUrls(
|
|
511
561
|
req,
|
|
@@ -519,6 +569,26 @@ function start(opts) {
|
|
|
519
569
|
},
|
|
520
570
|
)[0];
|
|
521
571
|
|
|
572
|
+
data.is_vector = tileJSON.format === 'pbf';
|
|
573
|
+
if (!data.is_vector) {
|
|
574
|
+
if (
|
|
575
|
+
tileJSON.encoding === 'terrarium' ||
|
|
576
|
+
tileJSON.encoding === 'mapbox'
|
|
577
|
+
) {
|
|
578
|
+
data.elevation_link = getTileUrls(
|
|
579
|
+
req,
|
|
580
|
+
tileJSON.tiles,
|
|
581
|
+
`data/${id}/elevation`,
|
|
582
|
+
)[0];
|
|
583
|
+
}
|
|
584
|
+
if (center) {
|
|
585
|
+
const centerPx = mercator.px([center[0], center[1]], center[2]);
|
|
586
|
+
data.thumbnail = `${Math.floor(center[2])}/${Math.floor(
|
|
587
|
+
centerPx[0] / 256,
|
|
588
|
+
)}/${Math.floor(centerPx[1] / 256)}.${tileJSON.format}`;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
522
592
|
if (data.filesize) {
|
|
523
593
|
let suffix = 'kB';
|
|
524
594
|
let size = parseInt(tileJSON.filesize, 10) / 1024;
|
|
@@ -532,24 +602,28 @@ function start(opts) {
|
|
|
532
602
|
}
|
|
533
603
|
data.formatted_filesize = `${size.toFixed(2)} ${suffix}`;
|
|
534
604
|
}
|
|
535
|
-
|
|
536
605
|
datas[id] = data;
|
|
537
606
|
}
|
|
538
|
-
|
|
539
607
|
return {
|
|
540
608
|
styles: Object.keys(styles).length ? styles : null,
|
|
541
609
|
data: Object.keys(datas).length ? datas : null,
|
|
542
610
|
};
|
|
543
611
|
});
|
|
544
612
|
|
|
545
|
-
|
|
613
|
+
/**
|
|
614
|
+
* Handles requests for a map viewer template for a specific style.
|
|
615
|
+
* @param {object} req - Express request object.
|
|
616
|
+
* @param {object} res - Express response object.
|
|
617
|
+
* @param {string} req.params.id - ID of the style.
|
|
618
|
+
* @returns {void}
|
|
619
|
+
*/
|
|
620
|
+
serveTemplate('/styles/:id/', 'viewer', (req) => {
|
|
546
621
|
const { id } = req.params;
|
|
547
622
|
const style = clone(((serving.styles || {})[id] || {}).styleJSON);
|
|
548
623
|
|
|
549
624
|
if (!style) {
|
|
550
625
|
return null;
|
|
551
626
|
}
|
|
552
|
-
|
|
553
627
|
return {
|
|
554
628
|
...style,
|
|
555
629
|
id,
|
|
@@ -559,11 +633,13 @@ function start(opts) {
|
|
|
559
633
|
};
|
|
560
634
|
});
|
|
561
635
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
636
|
+
/**
|
|
637
|
+
* Handles requests for a Web Map Tile Service (WMTS) XML template.
|
|
638
|
+
* @param {object} req - Express request object.
|
|
639
|
+
* @param {object} res - Express response object.
|
|
640
|
+
* @param {string} req.params.id - ID of the style.
|
|
641
|
+
* @returns {void}
|
|
642
|
+
*/
|
|
567
643
|
serveTemplate('/styles/:id/wmts.xml', 'wmts', (req) => {
|
|
568
644
|
const { id } = req.params;
|
|
569
645
|
const wmts = clone((serving.styles || {})[id]);
|
|
@@ -595,18 +671,33 @@ function start(opts) {
|
|
|
595
671
|
};
|
|
596
672
|
});
|
|
597
673
|
|
|
598
|
-
|
|
599
|
-
|
|
674
|
+
/**
|
|
675
|
+
* Handles requests for a data view template for a specific data source.
|
|
676
|
+
* @param {object} req - Express request object.
|
|
677
|
+
* @param {object} res - Express response object.
|
|
678
|
+
* @param {string} req.params.id - ID of the data source.
|
|
679
|
+
* @param {string} [req.params.view] - Optional view type.
|
|
680
|
+
* @returns {void}
|
|
681
|
+
*/
|
|
682
|
+
serveTemplate('/data{/:view}/:id/', 'data', (req) => {
|
|
683
|
+
const { id, view } = req.params;
|
|
600
684
|
const data = serving.data[id];
|
|
601
685
|
|
|
602
686
|
if (!data) {
|
|
603
687
|
return null;
|
|
604
688
|
}
|
|
689
|
+
const is_terrain =
|
|
690
|
+
(data.tileJSON.encoding === 'terrarium' ||
|
|
691
|
+
data.tileJSON.encoding === 'mapbox') &&
|
|
692
|
+
view === 'preview';
|
|
605
693
|
|
|
606
694
|
return {
|
|
607
695
|
...data,
|
|
608
696
|
id,
|
|
609
|
-
|
|
697
|
+
use_maplibre: data.tileJSON.format === 'pbf' || is_terrain,
|
|
698
|
+
is_terrain: is_terrain,
|
|
699
|
+
is_terrainrgb: data.tileJSON.encoding === 'mapbox',
|
|
700
|
+
terrain_encoding: data.tileJSON.encoding,
|
|
610
701
|
};
|
|
611
702
|
});
|
|
612
703
|
|
|
@@ -616,7 +707,13 @@ function start(opts) {
|
|
|
616
707
|
startupComplete = true;
|
|
617
708
|
});
|
|
618
709
|
|
|
619
|
-
|
|
710
|
+
/**
|
|
711
|
+
* Handles requests to see the health of the server.
|
|
712
|
+
* @param {object} req - Express request object.
|
|
713
|
+
* @param {object} res - Express response object.
|
|
714
|
+
* @returns {void}
|
|
715
|
+
*/
|
|
716
|
+
app.get('/health', (req, res) => {
|
|
620
717
|
if (startupComplete) {
|
|
621
718
|
return res.status(200).send('OK');
|
|
622
719
|
} else {
|
|
@@ -645,10 +742,10 @@ function start(opts) {
|
|
|
645
742
|
startupPromise,
|
|
646
743
|
};
|
|
647
744
|
}
|
|
648
|
-
|
|
649
745
|
/**
|
|
650
746
|
* Stop the server gracefully
|
|
651
747
|
* @param {string} signal Name of the received signal
|
|
748
|
+
* @returns {void}
|
|
652
749
|
*/
|
|
653
750
|
function stopGracefully(signal) {
|
|
654
751
|
console.log(`Caught signal ${signal}, stopping gracefully`);
|
|
@@ -656,11 +753,12 @@ function stopGracefully(signal) {
|
|
|
656
753
|
}
|
|
657
754
|
|
|
658
755
|
/**
|
|
659
|
-
*
|
|
660
|
-
* @param opts
|
|
756
|
+
* Starts and manages the server
|
|
757
|
+
* @param {object} opts - Configuration options for the server.
|
|
758
|
+
* @returns {Promise<object>} - A promise that resolves to the running server
|
|
661
759
|
*/
|
|
662
|
-
export function server(opts) {
|
|
663
|
-
const running = start(opts);
|
|
760
|
+
export async function server(opts) {
|
|
761
|
+
const running = await start(opts);
|
|
664
762
|
|
|
665
763
|
running.startupPromise.catch((err) => {
|
|
666
764
|
console.error(err.message);
|
|
@@ -680,6 +778,5 @@ export function server(opts) {
|
|
|
680
778
|
running.app = restarted.app;
|
|
681
779
|
});
|
|
682
780
|
});
|
|
683
|
-
|
|
684
781
|
return running;
|
|
685
782
|
}
|