tileserver-gl-light 4.0.0 → 4.1.1
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/PUBLISHING.md +8 -1
- package/docs/deployment.rst +2 -2
- package/package.json +5 -5
- package/public/resources/maplibre-gl-inspect.css +2 -1
- package/public/templates/index.tmpl +1 -1
- package/publish.js +15 -9
- package/src/main.js +31 -30
- package/src/serve_data.js +22 -22
- package/src/serve_font.js +12 -12
- package/src/serve_light.js +10 -0
- package/src/serve_rendered.js +121 -120
- package/src/serve_style.js +15 -15
- package/src/server.js +122 -121
- package/src/utils.js +13 -15
- package/test/metadata.js +30 -30
- package/test/setup.js +9 -5
- package/test/static.js +4 -4
- package/test/style.js +18 -18
- package/test/tiles_data.js +4 -4
- package/test/tiles_rendered.js +5 -5
package/PUBLISHING.md
CHANGED
|
@@ -3,4 +3,11 @@
|
|
|
3
3
|
- Update version in `package.json`
|
|
4
4
|
- `git tag vx.x.x`
|
|
5
5
|
- `git push --tags`
|
|
6
|
-
- `
|
|
6
|
+
- `docker buildx build --platform linux/amd64 -t maptiler/tileserver-gl:latest -t maptiler/tileserver-gl:[version] .`
|
|
7
|
+
- `docker push maptiler/tileserver-gl --all-tags`
|
|
8
|
+
- `npm publish --access public` or `node publish.js`
|
|
9
|
+
- `node publish.js --no-publish`
|
|
10
|
+
- `cd light`
|
|
11
|
+
- `docker buildx build --platform linux/amd64 -t maptiler/tileserver-gl-light:latest -t maptiler/tileserver-gl-light:[version] .`
|
|
12
|
+
- `docker push maptiler/tileserver-gl-light --all-tags`
|
|
13
|
+
- `npm publish --access public`
|
package/docs/deployment.rst
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Deployment
|
|
3
3
|
==========
|
|
4
4
|
|
|
5
|
-
Typically
|
|
5
|
+
Typically, you should use nginx, lighttpd or apache on the frontend. The tileserver-gl server is hidden behind it in production deployment.
|
|
6
6
|
|
|
7
7
|
Caching
|
|
8
8
|
=======
|
|
@@ -17,4 +17,4 @@ Nginx can be used to add protection via https, password, referrer, IP address re
|
|
|
17
17
|
Running behind a proxy or a load-balancer
|
|
18
18
|
=========================================
|
|
19
19
|
|
|
20
|
-
If you need to run TileServer GL behind a proxy, make sure the proxy sends ``X-Forwarded-*`` headers to the server (most importantly ``X-Forwarded-Host`` and ``X-Forwarded-Proto``) to
|
|
20
|
+
If you need to run TileServer GL behind a proxy, make sure the proxy sends ``X-Forwarded-*`` headers to the server (most importantly ``X-Forwarded-Host`` and ``X-Forwarded-Proto``) to ensure the URLs generated inside TileJSON, etc. are using the desired domain and protocol.
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileserver-gl-light",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Map tile server for JSON GL styles - serving vector tiles",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"bin": "src/main.js",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/maptiler/tileserver-gl.git"
|
|
10
|
+
"url": "git+https://github.com/maptiler/tileserver-gl.git"
|
|
10
11
|
},
|
|
11
12
|
"license": "BSD-2-Clause",
|
|
12
13
|
"engines": {
|
|
13
|
-
"node": ">=
|
|
14
|
+
"node": ">= 14.15.0"
|
|
14
15
|
},
|
|
15
16
|
"scripts": {
|
|
16
17
|
"test": "mocha test/**.js --timeout 10000",
|
|
@@ -18,17 +19,16 @@
|
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@mapbox/glyph-pbf-composite": "0.0.3",
|
|
21
|
-
"@maplibre/maplibre-gl-style-spec": "17.0.1",
|
|
22
22
|
"@mapbox/mbtiles": "0.12.1",
|
|
23
23
|
"@mapbox/sphericalmercator": "1.2.0",
|
|
24
24
|
"@mapbox/vector-tile": "1.3.1",
|
|
25
|
+
"@maplibre/maplibre-gl-style-spec": "17.0.1",
|
|
25
26
|
"advanced-pool": "0.3.3",
|
|
26
27
|
"chokidar": "3.5.3",
|
|
27
28
|
"clone": "2.1.2",
|
|
28
29
|
"color": "4.2.3",
|
|
29
30
|
"commander": "9.4.0",
|
|
30
31
|
"cors": "2.8.5",
|
|
31
|
-
"esm": "3.2.25",
|
|
32
32
|
"express": "4.18.1",
|
|
33
33
|
"handlebars": "4.7.7",
|
|
34
34
|
"http-shutdown": "1.2.2",
|
|
@@ -22,12 +22,13 @@
|
|
|
22
22
|
|
|
23
23
|
.maplibregl-inspect_property-value {
|
|
24
24
|
display: table-cell;
|
|
25
|
-
|
|
25
|
+
word-break: break-all;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.maplibregl-inspect_property-name {
|
|
29
29
|
display: table-cell;
|
|
30
30
|
padding-right: 10px;
|
|
31
|
+
word-break: break-all;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
.maplibregl-ctrl-inspect {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
{{#if serving_data}}| {{/if}}<a href="{{public_url}}styles/{{@key}}.json{{&../key_query}}">TileJSON</a>
|
|
42
42
|
{{/if}}
|
|
43
43
|
{{#if serving_rendered}}
|
|
44
|
-
| <a href="
|
|
44
|
+
| <a href="{{public_url}}styles/{{@key}}/wmts.xml{{&../key_query}}">WMTS</a>
|
|
45
45
|
{{/if}}
|
|
46
46
|
{{#if xyz_link}}
|
|
47
47
|
| <a href="#" onclick="return toggle_xyz('xyz_style_{{@key}}');">XYZ</a>
|
package/publish.js
CHANGED
|
@@ -11,13 +11,19 @@
|
|
|
11
11
|
/* CREATE tileserver-gl-light */
|
|
12
12
|
|
|
13
13
|
// SYNC THE `light` FOLDER
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
import child_process from 'child_process'
|
|
16
|
+
child_process.execSync('rsync -av --exclude="light" --exclude=".git" --exclude="node_modules" --delete . light', {
|
|
15
17
|
stdio: 'inherit'
|
|
16
18
|
});
|
|
17
19
|
|
|
18
20
|
// PATCH `package.json`
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
import fs from 'fs';
|
|
22
|
+
import path from 'path';
|
|
23
|
+
import {fileURLToPath} from 'url';
|
|
24
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
+
const __dirname = path.dirname(__filename);
|
|
26
|
+
const packageJson = JSON.parse(fs.readFileSync(__dirname + '/package.json', 'utf8'))
|
|
21
27
|
|
|
22
28
|
packageJson.name += '-light';
|
|
23
29
|
packageJson.description = 'Map tile server for JSON GL styles - serving vector tiles';
|
|
@@ -28,27 +34,27 @@ delete packageJson.dependencies['sharp'];
|
|
|
28
34
|
delete packageJson.optionalDependencies;
|
|
29
35
|
delete packageJson.devDependencies;
|
|
30
36
|
|
|
31
|
-
packageJson.engines.node = '>=
|
|
37
|
+
packageJson.engines.node = '>= 14.15.0';
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
const str = JSON.stringify(packageJson, undefined, 2);
|
|
34
40
|
fs.writeFileSync('light/package.json', str);
|
|
35
41
|
fs.renameSync('light/README_light.md', 'light/README.md');
|
|
36
42
|
fs.renameSync('light/Dockerfile_light', 'light/Dockerfile');
|
|
37
43
|
fs.renameSync('light/docker-entrypoint_light.sh', 'light/docker-entrypoint.sh');
|
|
38
44
|
|
|
39
45
|
// for Build tileserver-gl-light docker image, don't publish
|
|
40
|
-
if (process.argv.length > 2 && process.argv[2] ==
|
|
41
|
-
process.exit(0)
|
|
46
|
+
if (process.argv.length > 2 && process.argv[2] == '--no-publish') {
|
|
47
|
+
process.exit(0);
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
/* PUBLISH */
|
|
45
51
|
|
|
46
52
|
// tileserver-gl
|
|
47
|
-
|
|
53
|
+
child_process.execSync('npm publish . --access public', {
|
|
48
54
|
stdio: 'inherit'
|
|
49
55
|
});
|
|
50
56
|
|
|
51
57
|
// tileserver-gl-light
|
|
52
|
-
|
|
58
|
+
child_process.execSync('npm publish ./light --access public', {
|
|
53
59
|
stdio: 'inherit'
|
|
54
60
|
});
|
package/src/main.js
CHANGED
|
@@ -2,22 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import {fileURLToPath} from 'url';
|
|
8
|
+
import request from 'request';
|
|
9
|
+
import {server} from './server.js';
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const request = require('request');
|
|
11
|
+
import MBTiles from '@mapbox/mbtiles';
|
|
10
12
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const packageJson =
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
const packageJson = JSON.parse(fs.readFileSync(__dirname + '/../package.json', 'utf8'));
|
|
14
16
|
|
|
15
17
|
const args = process.argv;
|
|
16
18
|
if (args.length >= 3 && args[2][0] !== '-') {
|
|
17
19
|
args.splice(2, 0, '--mbtiles');
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
import {program} from 'commander';
|
|
21
23
|
program
|
|
22
24
|
.description('tileserver-gl startup options')
|
|
23
25
|
.usage('tileserver-gl [mbtiles] [options]')
|
|
@@ -79,7 +81,7 @@ const startServer = (configPath, config) => {
|
|
|
79
81
|
if (publicUrl && publicUrl.lastIndexOf('/') !== publicUrl.length - 1) {
|
|
80
82
|
publicUrl += '/';
|
|
81
83
|
}
|
|
82
|
-
return
|
|
84
|
+
return server({
|
|
83
85
|
configPath: configPath,
|
|
84
86
|
config: config,
|
|
85
87
|
bind: opts.bind,
|
|
@@ -105,7 +107,7 @@ const startWithMBTiles = (mbtilesFile) => {
|
|
|
105
107
|
console.log(`ERROR: Not valid MBTiles file: ${mbtilesFile}`);
|
|
106
108
|
process.exit(1);
|
|
107
109
|
}
|
|
108
|
-
const instance = new MBTiles(mbtilesFile, (err) => {
|
|
110
|
+
const instance = new MBTiles(mbtilesFile + '?mode=ro', (err) => {
|
|
109
111
|
if (err) {
|
|
110
112
|
console.log('ERROR: Unable to open MBTiles.');
|
|
111
113
|
console.log(` Make sure ${path.basename(mbtilesFile)} is valid MBTiles.`);
|
|
@@ -120,38 +122,37 @@ const startWithMBTiles = (mbtilesFile) => {
|
|
|
120
122
|
}
|
|
121
123
|
const bounds = info.bounds;
|
|
122
124
|
|
|
123
|
-
const styleDir = path.resolve(__dirname,
|
|
125
|
+
const styleDir = path.resolve(__dirname, '../node_modules/tileserver-gl-styles/');
|
|
124
126
|
|
|
125
127
|
const config = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
128
|
+
'options': {
|
|
129
|
+
'paths': {
|
|
130
|
+
'root': styleDir,
|
|
131
|
+
'fonts': 'fonts',
|
|
132
|
+
'styles': 'styles',
|
|
133
|
+
'mbtiles': path.dirname(mbtilesFile)
|
|
132
134
|
}
|
|
133
135
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
'styles': {},
|
|
137
|
+
'data': {}
|
|
136
138
|
};
|
|
137
139
|
|
|
138
140
|
if (info.format === 'pbf' &&
|
|
139
141
|
info.name.toLowerCase().indexOf('openmaptiles') > -1) {
|
|
140
|
-
|
|
141
142
|
config['data'][`v3`] = {
|
|
142
|
-
|
|
143
|
+
'mbtiles': path.basename(mbtilesFile)
|
|
143
144
|
};
|
|
144
145
|
|
|
145
146
|
|
|
146
147
|
const styles = fs.readdirSync(path.resolve(styleDir, 'styles'));
|
|
147
|
-
for (
|
|
148
|
+
for (const styleName of styles) {
|
|
148
149
|
const styleFileRel = styleName + '/style.json';
|
|
149
150
|
const styleFile = path.resolve(styleDir, 'styles', styleFileRel);
|
|
150
151
|
if (fs.existsSync(styleFile)) {
|
|
151
152
|
config['styles'][styleName] = {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
'style': styleFileRel,
|
|
154
|
+
'tilejson': {
|
|
155
|
+
'bounds': bounds
|
|
155
156
|
}
|
|
156
157
|
};
|
|
157
158
|
}
|
|
@@ -159,10 +160,10 @@ const startWithMBTiles = (mbtilesFile) => {
|
|
|
159
160
|
} else {
|
|
160
161
|
console.log(`WARN: MBTiles not in "openmaptiles" format. Serving raw data only...`);
|
|
161
162
|
config['data'][(info.id || 'mbtiles')
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
.replace(/\//g, '_')
|
|
164
|
+
.replace(/:/g, '_')
|
|
165
|
+
.replace(/\?/g, '_')] = {
|
|
166
|
+
'mbtiles': path.basename(mbtilesFile)
|
|
166
167
|
};
|
|
167
168
|
}
|
|
168
169
|
|
|
@@ -183,7 +184,7 @@ fs.stat(path.resolve(opts.config), (err, stats) => {
|
|
|
183
184
|
if (!mbtiles) {
|
|
184
185
|
// try to find in the cwd
|
|
185
186
|
const files = fs.readdirSync(process.cwd());
|
|
186
|
-
for (
|
|
187
|
+
for (const filename of files) {
|
|
187
188
|
if (filename.endsWith('.mbtiles')) {
|
|
188
189
|
const mbTilesStats = fs.statSync(filename);
|
|
189
190
|
if (mbTilesStats.isFile() && mbTilesStats.size > 0) {
|
package/src/serve_data.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import zlib from 'zlib';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import clone from 'clone';
|
|
8
|
+
import express from 'express';
|
|
9
|
+
import MBTiles from '@mapbox/mbtiles';
|
|
10
|
+
import Pbf from 'pbf';
|
|
11
|
+
import VectorTile from '@mapbox/vector-tile';
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
import {getTileUrls, fixTileJSONCenter} from './utils.js';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
export const serve_data = {
|
|
16
16
|
init: (options, repo) => {
|
|
17
17
|
const app = express().disable('x-powered-by');
|
|
18
18
|
|
|
@@ -21,7 +21,7 @@ module.exports = {
|
|
|
21
21
|
if (!item) {
|
|
22
22
|
return res.sendStatus(404);
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
const tileJSONFormat = item.tileJSON.format;
|
|
25
25
|
const z = req.params.z | 0;
|
|
26
26
|
const x = req.params.x | 0;
|
|
27
27
|
const y = req.params.y | 0;
|
|
@@ -52,7 +52,7 @@ module.exports = {
|
|
|
52
52
|
} else {
|
|
53
53
|
if (tileJSONFormat === 'pbf') {
|
|
54
54
|
isGzipped = data.slice(0, 2).indexOf(
|
|
55
|
-
|
|
55
|
+
Buffer.from([0x1f, 0x8b])) === 0;
|
|
56
56
|
if (options.dataDecoratorFunc) {
|
|
57
57
|
if (isGzipped) {
|
|
58
58
|
data = zlib.unzipSync(data);
|
|
@@ -73,10 +73,10 @@ module.exports = {
|
|
|
73
73
|
|
|
74
74
|
const tile = new VectorTile(new Pbf(data));
|
|
75
75
|
const geojson = {
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
'type': 'FeatureCollection',
|
|
77
|
+
'features': []
|
|
78
78
|
};
|
|
79
|
-
for (
|
|
79
|
+
for (const layerName in tile.layers) {
|
|
80
80
|
const layer = tile.layers[layerName];
|
|
81
81
|
for (let i = 0; i < layer.length; i++) {
|
|
82
82
|
const feature = layer.feature(i);
|
|
@@ -108,10 +108,10 @@ module.exports = {
|
|
|
108
108
|
return res.sendStatus(404);
|
|
109
109
|
}
|
|
110
110
|
const info = clone(item.tileJSON);
|
|
111
|
-
info.tiles =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
info.tiles = getTileUrls(req, info.tiles,
|
|
112
|
+
`data/${req.params.id}`, info.format, item.publicUrl, {
|
|
113
|
+
'pbf': options.pbfAlias
|
|
114
|
+
});
|
|
115
115
|
return res.send(info);
|
|
116
116
|
});
|
|
117
117
|
|
|
@@ -129,7 +129,7 @@ module.exports = {
|
|
|
129
129
|
}
|
|
130
130
|
let source;
|
|
131
131
|
const sourceInfoPromise = new Promise((resolve, reject) => {
|
|
132
|
-
source = new MBTiles(mbtilesFile, err => {
|
|
132
|
+
source = new MBTiles(mbtilesFile + '?mode=ro', err => {
|
|
133
133
|
if (err) {
|
|
134
134
|
reject(err);
|
|
135
135
|
return;
|
|
@@ -150,7 +150,7 @@ module.exports = {
|
|
|
150
150
|
delete tileJSON['scheme'];
|
|
151
151
|
|
|
152
152
|
Object.assign(tileJSON, params.tilejson || {});
|
|
153
|
-
|
|
153
|
+
fixTileJSONCenter(tileJSON);
|
|
154
154
|
|
|
155
155
|
if (options.dataDecoratorFunc) {
|
|
156
156
|
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
|
|
@@ -165,7 +165,7 @@ module.exports = {
|
|
|
165
165
|
tileJSON,
|
|
166
166
|
publicUrl,
|
|
167
167
|
source
|
|
168
|
-
}
|
|
168
|
+
};
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
171
|
};
|
package/src/serve_font.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import express from 'express';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'path';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import {getFontsPbf} from './utils.js';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
export const serve_font = (options, allowedFonts) => {
|
|
10
10
|
const app = express().disable('x-powered-by');
|
|
11
11
|
|
|
12
12
|
const lastModified = new Date().toUTCString();
|
|
@@ -40,19 +40,19 @@ module.exports = (options, allowedFonts) => {
|
|
|
40
40
|
const fontstack = decodeURI(req.params.fontstack);
|
|
41
41
|
const range = req.params.range;
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
getFontsPbf(options.serveAllFonts ? null : allowedFonts,
|
|
44
|
+
fontPath, fontstack, range, existingFonts).then((concated) => {
|
|
45
|
+
res.header('Content-type', 'application/x-protobuf');
|
|
46
|
+
res.header('Last-Modified', lastModified);
|
|
47
|
+
return res.send(concated);
|
|
48
|
+
}, (err) => res.status(400).send(err)
|
|
49
49
|
);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
app.get('/fonts.json', (req, res, next) => {
|
|
53
53
|
res.header('Content-type', 'application/json');
|
|
54
54
|
return res.send(
|
|
55
|
-
|
|
55
|
+
Object.keys(options.serveAllFonts ? existingFonts : allowedFonts).sort()
|
|
56
56
|
);
|
|
57
57
|
});
|
|
58
58
|
|