tileserver-gl-light 5.1.3 → 5.2.0-pre.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/.github/workflows/automerger.yml +1 -0
- package/.github/workflows/ci.yml +5 -0
- package/CHANGELOG.md +8 -0
- package/Dockerfile +33 -36
- package/Dockerfile_build +38 -0
- package/changelog_for_version.md +6 -1
- package/docs/config.rst +4 -1
- package/package.json +12 -2
- package/public/resources/elevation-control.js +1 -1
- package/src/serve_data.js +8 -6
- package/src/serve_light.js +1 -0
- package/src/serve_rendered.js +30 -10
- package/src/serve_style.js +4 -10
- package/src/server.js +31 -4
- package/public/resources/leaflet-hash.js +0 -162
- package/public/resources/leaflet.css +0 -661
- package/public/resources/leaflet.js +0 -6
- package/public/resources/leaflet.js.map +0 -1
- package/public/resources/mapbox-gl-rtl-text.js +0 -6
- package/public/resources/maplibre-gl-inspect.css +0 -40
- package/public/resources/maplibre-gl-inspect.js +0 -2858
- package/public/resources/maplibre-gl-inspect.js.map +0 -1
- package/public/resources/maplibre-gl.css +0 -1
- package/public/resources/maplibre-gl.js +0 -59
- package/public/resources/maplibre-gl.js.map +0 -1
package/.github/workflows/ci.yml
CHANGED
|
@@ -21,6 +21,11 @@ jobs:
|
|
|
21
21
|
with:
|
|
22
22
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
23
23
|
|
|
24
|
+
- name: Install dependencies (Ubuntu) 🚀
|
|
25
|
+
run: >-
|
|
26
|
+
sudo apt-get install -qq libcairo2-dev libjpeg8-dev libpango1.0-dev
|
|
27
|
+
libgif-dev build-essential
|
|
28
|
+
|
|
24
29
|
- name: Setup node env 📦
|
|
25
30
|
uses: actions/setup-node@v4
|
|
26
31
|
with:
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# tileserver-gl changelog
|
|
2
2
|
|
|
3
|
+
## 5.2.0-pre.1
|
|
4
|
+
* Use npm packages for public/resources (https://github.com/maptiler/tileserver-gl/pull/1427) by @okimiko
|
|
5
|
+
* use ttf files of googlefonts/opensans (https://github.com/maptiler/tileserver-gl/pull/1447) by @okimiko
|
|
6
|
+
* Limit Elevation Lat/Long Output Length (https://github.com/maptiler/tileserver-gl/pull/1457) by @okimiko
|
|
7
|
+
* Fetch style from url (https://github.com/maptiler/tileserver-gl/pull/1462) by @YoelRidgway
|
|
8
|
+
* fix: memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
|
|
9
|
+
* fix: resolves Unimplemented type: 3 error for geojson format #1465
|
|
10
|
+
|
|
3
11
|
## 5.1.3
|
|
4
12
|
* Fix SIGHUP (broken since 5.1.x) (https://github.com/maptiler/tileserver-gl/pull/1452) by @okimiko
|
|
5
13
|
|
package/Dockerfile
CHANGED
|
@@ -5,49 +5,46 @@ ENV \
|
|
|
5
5
|
CHOKIDAR_USEPOLLING=1 \
|
|
6
6
|
CHOKIDAR_INTERVAL=500
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
apt-get -
|
|
8
|
+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
9
|
+
|
|
10
|
+
RUN export DEBIAN_FRONTEND=noninteractive && \
|
|
11
|
+
groupadd -r node && \
|
|
12
|
+
useradd -r -g node node && \
|
|
13
|
+
apt-get -qq update && \
|
|
14
|
+
apt-get install -y --no-install-recommends --no-install-suggests \
|
|
14
15
|
ca-certificates \
|
|
15
16
|
curl \
|
|
16
|
-
gnupg
|
|
17
|
-
mkdir -p /etc/apt/keyrings
|
|
18
|
-
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
|
19
|
-
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
|
|
20
|
-
apt-get -qq update
|
|
21
|
-
apt-get install -y nodejs
|
|
22
|
-
npm i -g npm@latest
|
|
23
|
-
apt-get -y remove curl gnupg
|
|
24
|
-
apt-get -y --purge autoremove
|
|
25
|
-
apt-get clean
|
|
26
|
-
rm -rf /var/lib/apt/lists
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
gnupg && \
|
|
18
|
+
mkdir -p /etc/apt/keyrings && \
|
|
19
|
+
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
|
|
20
|
+
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
|
|
21
|
+
apt-get -qq update && \
|
|
22
|
+
apt-get install -y --no-install-recommends --no-install-suggests nodejs && \
|
|
23
|
+
npm i -g npm@latest && \
|
|
24
|
+
apt-get -y remove curl gnupg && \
|
|
25
|
+
apt-get -y --purge autoremove && \
|
|
26
|
+
apt-get clean && \
|
|
27
|
+
rm -rf /var/lib/apt/lists/*
|
|
28
|
+
|
|
29
|
+
WORKDIR /usr/src/app
|
|
30
|
+
COPY . .
|
|
31
|
+
|
|
32
|
+
RUN npm config set maxsockets 1 && \
|
|
33
|
+
npm config set fetch-retries 5 && \
|
|
34
|
+
npm config set fetch-retry-mintimeout 100000 && \
|
|
35
|
+
npm config set fetch-retry-maxtimeout 600000 && \
|
|
36
|
+
npm install --omit=dev && \
|
|
37
|
+
chown -R root:root . && \
|
|
38
|
+
chmod +x ./docker-entrypoint.sh
|
|
39
|
+
|
|
40
|
+
RUN mkdir -p /data && chown node:node /data
|
|
34
41
|
VOLUME /data
|
|
35
|
-
|
|
36
42
|
WORKDIR /data
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
RUN cd /usr/src/app; \
|
|
41
|
-
npm config set maxsockets 1; \
|
|
42
|
-
npm config set fetch-retries 5; \
|
|
43
|
-
npm config set fetch-retry-mintimeout 100000; \
|
|
44
|
-
npm config set fetch-retry-maxtimeout 600000; \
|
|
45
|
-
npm install --omit=dev; \
|
|
46
|
-
chown -R root:root /usr/src/app; \
|
|
47
|
-
chmod +x /usr/src/app/docker-entrypoint.sh;
|
|
44
|
+
EXPOSE 8080
|
|
48
45
|
|
|
49
46
|
USER node:node
|
|
50
47
|
|
|
51
48
|
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
|
|
52
49
|
|
|
53
|
-
HEALTHCHECK CMD node /usr/src/app/src/healthcheck.js
|
|
50
|
+
HEALTHCHECK CMD node /usr/src/app/src/healthcheck.js
|
package/Dockerfile_build
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
FROM ubuntu:jammy AS builder
|
|
2
|
+
|
|
3
|
+
ENV NODE_ENV="devel"
|
|
4
|
+
|
|
5
|
+
RUN export DEBIAN_FRONTEND=noninteractive && \
|
|
6
|
+
apt-get update && \
|
|
7
|
+
apt-get install -y --no-install-recommends --no-install-suggests \
|
|
8
|
+
build-essential \
|
|
9
|
+
ca-certificates \
|
|
10
|
+
curl \
|
|
11
|
+
gnupg \
|
|
12
|
+
pkg-config \
|
|
13
|
+
xvfb \
|
|
14
|
+
libglfw3-dev \
|
|
15
|
+
libuv1-dev \
|
|
16
|
+
libjpeg-turbo8 \
|
|
17
|
+
libicu70 \
|
|
18
|
+
libcairo2-dev \
|
|
19
|
+
libpango1.0-dev \
|
|
20
|
+
libjpeg-dev \
|
|
21
|
+
libgif-dev \
|
|
22
|
+
librsvg2-dev \
|
|
23
|
+
gir1.2-rsvg-2.0 \
|
|
24
|
+
librsvg2-2 \
|
|
25
|
+
librsvg2-common \
|
|
26
|
+
libcurl4-openssl-dev \
|
|
27
|
+
libpixman-1-dev \
|
|
28
|
+
libpixman-1-0 && \
|
|
29
|
+
mkdir -p /etc/apt/keyrings && \
|
|
30
|
+
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
|
|
31
|
+
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
|
|
32
|
+
apt-get -qq update && \
|
|
33
|
+
apt-get install -y --no-install-recommends --no-install-suggests nodejs && \
|
|
34
|
+
npm i -g npm@latest && \
|
|
35
|
+
apt-get -y remove curl gnupg && \
|
|
36
|
+
apt-get -y --purge autoremove && \
|
|
37
|
+
apt-get clean && \
|
|
38
|
+
rm -rf /var/lib/apt/lists/*
|
package/changelog_for_version.md
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
*
|
|
1
|
+
* Use npm packages for public/resources (https://github.com/maptiler/tileserver-gl/pull/1427) by @okimiko
|
|
2
|
+
* use ttf files of googlefonts/opensans (https://github.com/maptiler/tileserver-gl/pull/1447) by @okimiko
|
|
3
|
+
* Limit Elevation Lat/Long Output Length (https://github.com/maptiler/tileserver-gl/pull/1457) by @okimiko
|
|
4
|
+
* Fetch style from url (https://github.com/maptiler/tileserver-gl/pull/1462) by @YoelRidgway
|
|
5
|
+
* fix: memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
|
|
6
|
+
* fix: resolves Unimplemented type: 3 error for geojson format #1465
|
|
2
7
|
|
package/docs/config.rst
CHANGED
|
@@ -57,6 +57,9 @@ Example:
|
|
|
57
57
|
"tilejson": {
|
|
58
58
|
"format": "webp"
|
|
59
59
|
}
|
|
60
|
+
},
|
|
61
|
+
"remote": {
|
|
62
|
+
"style": "https://demotiles.maplibre.org/style.json"
|
|
60
63
|
}
|
|
61
64
|
},
|
|
62
65
|
"data": {
|
|
@@ -209,7 +212,7 @@ Not used by default.
|
|
|
209
212
|
|
|
210
213
|
Each item in this object defines one style (map). It can have the following options:
|
|
211
214
|
|
|
212
|
-
* ``style`` -- name of the style json file [required]
|
|
215
|
+
* ``style`` -- name of the style json file or url of a remote hosted style [required]
|
|
213
216
|
* ``serve_rendered`` -- whether to render the raster tiles for this style or not
|
|
214
217
|
* ``serve_data`` -- whether to allow access to the original tiles, sprites and required glyphs
|
|
215
218
|
* ``tilejson`` -- properties to add to the TileJSON created for the raster data
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileserver-gl-light",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.0-pre.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
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
|
+
"copy:maplibre": "copyfiles -EVf node_modules/maplibre-gl/dist/maplibre-gl.js node_modules/maplibre-gl/dist/maplibre-gl.js.map node_modules/maplibre-gl/dist/maplibre-gl.css public/resources/",
|
|
10
|
+
"copy:maplibre-inspect": "copyfiles -EVf node_modules/@maplibre/maplibre-gl-inspect/dist/maplibre-gl-inspect.js node_modules/@maplibre/maplibre-gl-inspect/dist/maplibre-gl-inspect.js.map node_modules/@maplibre/maplibre-gl-inspect/dist/maplibre-gl-inspect.css public/resources/",
|
|
11
|
+
"copy:mapbox-rtl-text": "copyfiles -EVf node_modules/@mapbox/mapbox-gl-rtl-text/dist/mapbox-gl-rtl-text.js public/resources/",
|
|
12
|
+
"copy:leaflet": "copyfiles -EVf node_modules/leaflet/dist/leaflet.js node_modules/leaflet/dist/leaflet.js.map node_modules/leaflet/dist/leaflet.css node_modules/leaflet/dist/leaflet-hash.js public/resources/",
|
|
13
|
+
"copy:leaflet-hash": "copyfiles -EVf node_modules/leaflet-hash/leaflet-hash.js public/resources/",
|
|
9
14
|
"test": "mocha test/**.js --timeout 10000 --exit",
|
|
10
15
|
"test-docker": "xvfb-run npm test",
|
|
11
16
|
"lint:yml": "yamllint --schema=CORE_SCHEMA *.{yml,yaml}",
|
|
@@ -19,14 +24,16 @@
|
|
|
19
24
|
},
|
|
20
25
|
"dependencies": {
|
|
21
26
|
"@jsse/pbfont": "^0.2.2",
|
|
27
|
+
"@mapbox/mapbox-gl-rtl-text": "0.3.0",
|
|
22
28
|
"@mapbox/mbtiles": "0.12.1",
|
|
23
29
|
"@mapbox/polyline": "^1.2.1",
|
|
24
30
|
"@mapbox/sphericalmercator": "1.2.0",
|
|
25
31
|
"@mapbox/vector-tile": "2.0.3",
|
|
32
|
+
"@maplibre/maplibre-gl-inspect": "1.7.0",
|
|
26
33
|
"@maplibre/maplibre-gl-style-spec": "20.3.1",
|
|
27
34
|
"@sindresorhus/fnv1a": "3.1.0",
|
|
28
35
|
"advanced-pool": "0.3.3",
|
|
29
|
-
"axios": "^1.
|
|
36
|
+
"axios": "^1.8.2",
|
|
30
37
|
"chokidar": "3.6.0",
|
|
31
38
|
"clone": "2.1.2",
|
|
32
39
|
"color": "4.2.3",
|
|
@@ -35,6 +42,9 @@
|
|
|
35
42
|
"express": "5.0.1",
|
|
36
43
|
"handlebars": "4.7.8",
|
|
37
44
|
"http-shutdown": "1.2.2",
|
|
45
|
+
"leaflet": "1.9.4",
|
|
46
|
+
"leaflet-hash": "0.2.1",
|
|
47
|
+
"maplibre-gl": "4.7.1",
|
|
38
48
|
"morgan": "1.10.0",
|
|
39
49
|
"pbf": "4.0.1",
|
|
40
50
|
"pmtiles": "3.0.7",
|
|
@@ -18,7 +18,7 @@ class ElevationInfoControl {
|
|
|
18
18
|
|
|
19
19
|
map.on('click', (e) => {
|
|
20
20
|
var url = this.url;
|
|
21
|
-
var coord = {"z": Math.floor(map.getZoom()), "x": e.lngLat["lng"], "y": e.lngLat["lat"]};
|
|
21
|
+
var coord = {"z": Math.floor(map.getZoom()), "x": e.lngLat["lng"].toFixed(7), "y": e.lngLat["lat"].toFixed(7)};
|
|
22
22
|
for(var key in coord) {
|
|
23
23
|
url = url.replace(new RegExp('{'+ key +'}','g'), coord[key]);
|
|
24
24
|
}
|
package/src/serve_data.js
CHANGED
|
@@ -21,6 +21,7 @@ import { openMbTilesWrapper } from './mbtiles_wrapper.js';
|
|
|
21
21
|
|
|
22
22
|
import fs from 'node:fs';
|
|
23
23
|
import { fileURLToPath } from 'url';
|
|
24
|
+
|
|
24
25
|
const packageJson = JSON.parse(
|
|
25
26
|
fs.readFileSync(
|
|
26
27
|
path.dirname(fileURLToPath(import.meta.url)) + '/../package.json',
|
|
@@ -113,12 +114,13 @@ export const serve_data = {
|
|
|
113
114
|
let headers = fetchTile.headers;
|
|
114
115
|
let isGzipped = data.slice(0, 2).indexOf(Buffer.from([0x1f, 0x8b])) === 0;
|
|
115
116
|
|
|
117
|
+
if (isGzipped) {
|
|
118
|
+
data = await gunzipP(data);
|
|
119
|
+
isGzipped = false;
|
|
120
|
+
}
|
|
121
|
+
|
|
116
122
|
if (tileJSONFormat === 'pbf') {
|
|
117
123
|
if (options.dataDecoratorFunc) {
|
|
118
|
-
if (isGzipped) {
|
|
119
|
-
data = await gunzipP(data);
|
|
120
|
-
isGzipped = false;
|
|
121
|
-
}
|
|
122
124
|
data = options.dataDecoratorFunc(
|
|
123
125
|
req.params.id,
|
|
124
126
|
'data',
|
|
@@ -259,8 +261,8 @@ export const serve_data = {
|
|
|
259
261
|
|
|
260
262
|
let data = fetchTile.data;
|
|
261
263
|
var param = {
|
|
262
|
-
long: bbox[0],
|
|
263
|
-
lat: bbox[1],
|
|
264
|
+
long: bbox[0].toFixed(7),
|
|
265
|
+
lat: bbox[1].toFixed(7),
|
|
264
266
|
encoding,
|
|
265
267
|
format,
|
|
266
268
|
tile_size: TILE_SIZE,
|
package/src/serve_light.js
CHANGED
|
@@ -6,6 +6,7 @@ export const serve_rendered = {
|
|
|
6
6
|
init: (options, repo, programOpts) => {},
|
|
7
7
|
add: (options, repo, params, id, programOpts, dataResolver) => {},
|
|
8
8
|
remove: (repo, id) => {},
|
|
9
|
+
clear: (repo) => {},
|
|
9
10
|
getTerrainElevation: (data, param) => {
|
|
10
11
|
param['elevation'] = 'not supported in light';
|
|
11
12
|
return param;
|
package/src/serve_rendered.js
CHANGED
|
@@ -15,7 +15,6 @@ import '@maplibre/maplibre-gl-native';
|
|
|
15
15
|
import advancedPool from 'advanced-pool';
|
|
16
16
|
import path from 'path';
|
|
17
17
|
import url from 'url';
|
|
18
|
-
import util from 'util';
|
|
19
18
|
import sharp from 'sharp';
|
|
20
19
|
import clone from 'clone';
|
|
21
20
|
import Color from 'color';
|
|
@@ -1028,10 +1027,19 @@ export const serve_rendered = {
|
|
|
1028
1027
|
* @param {object} params Parameters object.
|
|
1029
1028
|
* @param {string} id ID of the item.
|
|
1030
1029
|
* @param {object} programOpts - An object containing the program options
|
|
1030
|
+
* @param {object} style pre-fetched/read StyleJSON object.
|
|
1031
1031
|
* @param {Function} dataResolver Function to resolve data.
|
|
1032
1032
|
* @returns {Promise<void>}
|
|
1033
1033
|
*/
|
|
1034
|
-
add: async function (
|
|
1034
|
+
add: async function (
|
|
1035
|
+
options,
|
|
1036
|
+
repo,
|
|
1037
|
+
params,
|
|
1038
|
+
id,
|
|
1039
|
+
programOpts,
|
|
1040
|
+
style,
|
|
1041
|
+
dataResolver,
|
|
1042
|
+
) {
|
|
1035
1043
|
const map = {
|
|
1036
1044
|
renderers: [],
|
|
1037
1045
|
renderersStatic: [],
|
|
@@ -1041,7 +1049,7 @@ export const serve_rendered = {
|
|
|
1041
1049
|
|
|
1042
1050
|
const { publicUrl, verbose } = programOpts;
|
|
1043
1051
|
|
|
1044
|
-
|
|
1052
|
+
const styleJSON = clone(style);
|
|
1045
1053
|
/**
|
|
1046
1054
|
* Creates a pool of renderers.
|
|
1047
1055
|
* @param {number} ratio Pixel ratio
|
|
@@ -1230,12 +1238,6 @@ export const serve_rendered = {
|
|
|
1230
1238
|
|
|
1231
1239
|
const styleFile = params.style;
|
|
1232
1240
|
const styleJSONPath = path.resolve(options.paths.styles, styleFile);
|
|
1233
|
-
try {
|
|
1234
|
-
styleJSON = JSON.parse(await fsp.readFile(styleJSONPath));
|
|
1235
|
-
} catch (e) {
|
|
1236
|
-
console.log('Error parsing style file');
|
|
1237
|
-
return false;
|
|
1238
|
-
}
|
|
1239
1241
|
|
|
1240
1242
|
if (styleJSON.sprite) {
|
|
1241
1243
|
if (!Array.isArray(styleJSON.sprite)) {
|
|
@@ -1458,7 +1460,25 @@ export const serve_rendered = {
|
|
|
1458
1460
|
}
|
|
1459
1461
|
delete repo[id];
|
|
1460
1462
|
},
|
|
1461
|
-
|
|
1463
|
+
/**
|
|
1464
|
+
* Removes all items from the repository.
|
|
1465
|
+
* @param {object} repo Repository object.
|
|
1466
|
+
* @returns {void}
|
|
1467
|
+
*/
|
|
1468
|
+
clear: function (repo) {
|
|
1469
|
+
Object.keys(repo).forEach((id) => {
|
|
1470
|
+
const item = repo[id];
|
|
1471
|
+
if (item) {
|
|
1472
|
+
item.map.renderers.forEach((pool) => {
|
|
1473
|
+
pool.close();
|
|
1474
|
+
});
|
|
1475
|
+
item.map.renderersStatic.forEach((pool) => {
|
|
1476
|
+
pool.close();
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
delete repo[id];
|
|
1480
|
+
});
|
|
1481
|
+
},
|
|
1462
1482
|
/**
|
|
1463
1483
|
* Get the elevation of terrain tile data by rendering it to a canvas image
|
|
1464
1484
|
* @param {object} data The background color (or empty string for transparent).
|
package/src/serve_style.js
CHANGED
|
@@ -196,9 +196,10 @@ export const serve_style = {
|
|
|
196
196
|
* @param {object} params Parameters object containing style path
|
|
197
197
|
* @param {string} id ID of the style.
|
|
198
198
|
* @param {object} programOpts - An object containing the program options
|
|
199
|
+
* @param {object} style pre-fetched/read StyleJSON object.
|
|
199
200
|
* @param {Function} reportTiles Function for reporting tile sources.
|
|
200
201
|
* @param {Function} reportFont Function for reporting font usage
|
|
201
|
-
* @returns {boolean} true if add is
|
|
202
|
+
* @returns {boolean} true if add is successful
|
|
202
203
|
*/
|
|
203
204
|
add: function (
|
|
204
205
|
options,
|
|
@@ -206,21 +207,14 @@ export const serve_style = {
|
|
|
206
207
|
params,
|
|
207
208
|
id,
|
|
208
209
|
programOpts,
|
|
210
|
+
style,
|
|
209
211
|
reportTiles,
|
|
210
212
|
reportFont,
|
|
211
213
|
) {
|
|
212
214
|
const { publicUrl } = programOpts;
|
|
213
215
|
const styleFile = path.resolve(options.paths.styles, params.style);
|
|
216
|
+
const styleJSON = clone(style);
|
|
214
217
|
|
|
215
|
-
let styleFileData;
|
|
216
|
-
try {
|
|
217
|
-
styleFileData = fs.readFileSync(styleFile); // TODO: could be made async if this function was
|
|
218
|
-
} catch (e) {
|
|
219
|
-
console.log(`Error reading style file "${params.style}"`);
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const styleJSON = JSON.parse(styleFileData);
|
|
224
218
|
const validationErrors = validateStyleMin(styleJSON);
|
|
225
219
|
if (validationErrors.length > 0) {
|
|
226
220
|
console.log(`The file "${params.style}" is not a valid style file:`);
|
package/src/server.js
CHANGED
|
@@ -178,10 +178,29 @@ async function start(opts) {
|
|
|
178
178
|
* @param {object} item - The style configuration object.
|
|
179
179
|
* @param {boolean} allowMoreData - Whether to allow adding more data sources.
|
|
180
180
|
* @param {boolean} reportFonts - Whether to report fonts.
|
|
181
|
-
* @returns {void}
|
|
181
|
+
* @returns {Promise<void>}
|
|
182
182
|
*/
|
|
183
|
-
function addStyle(id, item, allowMoreData, reportFonts) {
|
|
183
|
+
async function addStyle(id, item, allowMoreData, reportFonts) {
|
|
184
184
|
let success = true;
|
|
185
|
+
|
|
186
|
+
let styleJSON;
|
|
187
|
+
try {
|
|
188
|
+
if (isValidHttpUrl(item.style)) {
|
|
189
|
+
const res = await fetch(item.style);
|
|
190
|
+
if (!res.ok) {
|
|
191
|
+
throw new Error(`fetch error ${res.status}`);
|
|
192
|
+
}
|
|
193
|
+
styleJSON = await res.json();
|
|
194
|
+
} else {
|
|
195
|
+
const styleFile = path.resolve(options.paths.styles, item.style);
|
|
196
|
+
const styleFileData = await fs.promises.readFile(styleFile);
|
|
197
|
+
styleJSON = JSON.parse(styleFileData);
|
|
198
|
+
}
|
|
199
|
+
} catch (e) {
|
|
200
|
+
console.log(`Error getting style file "${item.style}"`);
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
185
204
|
if (item.serve_data !== false) {
|
|
186
205
|
success = serve_style.add(
|
|
187
206
|
options,
|
|
@@ -189,6 +208,7 @@ async function start(opts) {
|
|
|
189
208
|
item,
|
|
190
209
|
id,
|
|
191
210
|
opts,
|
|
211
|
+
styleJSON,
|
|
192
212
|
(styleSourceId, protocol) => {
|
|
193
213
|
let dataItemId;
|
|
194
214
|
for (const id of Object.keys(data)) {
|
|
@@ -246,6 +266,7 @@ async function start(opts) {
|
|
|
246
266
|
item,
|
|
247
267
|
id,
|
|
248
268
|
opts,
|
|
269
|
+
styleJSON,
|
|
249
270
|
function dataResolver(styleSourceId) {
|
|
250
271
|
let fileType;
|
|
251
272
|
let inputFile;
|
|
@@ -271,6 +292,7 @@ async function start(opts) {
|
|
|
271
292
|
item.serve_rendered = false;
|
|
272
293
|
}
|
|
273
294
|
}
|
|
295
|
+
return success;
|
|
274
296
|
}
|
|
275
297
|
|
|
276
298
|
for (const id of Object.keys(config.styles || {})) {
|
|
@@ -279,8 +301,7 @@ async function start(opts) {
|
|
|
279
301
|
console.log(`Missing "style" property for ${id}`);
|
|
280
302
|
continue;
|
|
281
303
|
}
|
|
282
|
-
|
|
283
|
-
addStyle(id, item, true, true);
|
|
304
|
+
startupPromises.push(addStyle(id, item, true, true));
|
|
284
305
|
}
|
|
285
306
|
startupPromises.push(
|
|
286
307
|
serve_font(options, serving.fonts, opts).then((sub) => {
|
|
@@ -743,6 +764,7 @@ async function start(opts) {
|
|
|
743
764
|
app,
|
|
744
765
|
server,
|
|
745
766
|
startupPromise,
|
|
767
|
+
serving,
|
|
746
768
|
};
|
|
747
769
|
}
|
|
748
770
|
/**
|
|
@@ -777,8 +799,13 @@ export async function server(opts) {
|
|
|
777
799
|
|
|
778
800
|
running.server.shutdown(async () => {
|
|
779
801
|
const restarted = await start(opts);
|
|
802
|
+
if (!isLight) {
|
|
803
|
+
serve_rendered.clear(running.serving.rendered);
|
|
804
|
+
}
|
|
780
805
|
running.server = restarted.server;
|
|
781
806
|
running.app = restarted.app;
|
|
807
|
+
running.startupPromise = restarted.startupPromise;
|
|
808
|
+
running.serving = restarted.serving;
|
|
782
809
|
});
|
|
783
810
|
});
|
|
784
811
|
return running;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
(function(window) {
|
|
2
|
-
var HAS_HASHCHANGE = (function() {
|
|
3
|
-
var doc_mode = window.documentMode;
|
|
4
|
-
return ('onhashchange' in window) &&
|
|
5
|
-
(doc_mode === undefined || doc_mode > 7);
|
|
6
|
-
})();
|
|
7
|
-
|
|
8
|
-
L.Hash = function(map) {
|
|
9
|
-
this.onHashChange = L.Util.bind(this.onHashChange, this);
|
|
10
|
-
|
|
11
|
-
if (map) {
|
|
12
|
-
this.init(map);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
L.Hash.parseHash = function(hash) {
|
|
17
|
-
if(hash.indexOf('#') === 0) {
|
|
18
|
-
hash = hash.substr(1);
|
|
19
|
-
}
|
|
20
|
-
var args = hash.split("/");
|
|
21
|
-
if (args.length == 3) {
|
|
22
|
-
var zoom = parseInt(args[0], 10),
|
|
23
|
-
lat = parseFloat(args[1]),
|
|
24
|
-
lon = parseFloat(args[2]);
|
|
25
|
-
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
|
|
26
|
-
return false;
|
|
27
|
-
} else {
|
|
28
|
-
return {
|
|
29
|
-
center: new L.LatLng(lat, lon),
|
|
30
|
-
zoom: zoom
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
L.Hash.formatHash = function(map) {
|
|
39
|
-
var center = map.getCenter(),
|
|
40
|
-
zoom = map.getZoom(),
|
|
41
|
-
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
|
|
42
|
-
|
|
43
|
-
return "#" + [zoom,
|
|
44
|
-
center.lat.toFixed(precision),
|
|
45
|
-
center.lng.toFixed(precision)
|
|
46
|
-
].join("/");
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
L.Hash.prototype = {
|
|
50
|
-
map: null,
|
|
51
|
-
lastHash: null,
|
|
52
|
-
|
|
53
|
-
parseHash: L.Hash.parseHash,
|
|
54
|
-
formatHash: L.Hash.formatHash,
|
|
55
|
-
|
|
56
|
-
init: function(map) {
|
|
57
|
-
this.map = map;
|
|
58
|
-
|
|
59
|
-
// reset the hash
|
|
60
|
-
this.lastHash = null;
|
|
61
|
-
this.onHashChange();
|
|
62
|
-
|
|
63
|
-
if (!this.isListening) {
|
|
64
|
-
this.startListening();
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
removeFrom: function(map) {
|
|
69
|
-
if (this.changeTimeout) {
|
|
70
|
-
clearTimeout(this.changeTimeout);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (this.isListening) {
|
|
74
|
-
this.stopListening();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.map = null;
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
onMapMove: function() {
|
|
81
|
-
// bail if we're moving the map (updating from a hash),
|
|
82
|
-
// or if the map is not yet loaded
|
|
83
|
-
|
|
84
|
-
if (this.movingMap || !this.map._loaded) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
var hash = this.formatHash(this.map);
|
|
89
|
-
if (this.lastHash != hash) {
|
|
90
|
-
location.replace(hash);
|
|
91
|
-
this.lastHash = hash;
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
movingMap: false,
|
|
96
|
-
update: function() {
|
|
97
|
-
var hash = location.hash;
|
|
98
|
-
if (hash === this.lastHash) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
var parsed = this.parseHash(hash);
|
|
102
|
-
if (parsed) {
|
|
103
|
-
this.movingMap = true;
|
|
104
|
-
|
|
105
|
-
this.map.setView(parsed.center, parsed.zoom);
|
|
106
|
-
|
|
107
|
-
this.movingMap = false;
|
|
108
|
-
} else {
|
|
109
|
-
this.onMapMove(this.map);
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
// defer hash change updates every 100ms
|
|
114
|
-
changeDefer: 100,
|
|
115
|
-
changeTimeout: null,
|
|
116
|
-
onHashChange: function() {
|
|
117
|
-
// throttle calls to update() so that they only happen every
|
|
118
|
-
// `changeDefer` ms
|
|
119
|
-
if (!this.changeTimeout) {
|
|
120
|
-
var that = this;
|
|
121
|
-
this.changeTimeout = setTimeout(function() {
|
|
122
|
-
that.update();
|
|
123
|
-
that.changeTimeout = null;
|
|
124
|
-
}, this.changeDefer);
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
|
|
128
|
-
isListening: false,
|
|
129
|
-
hashChangeInterval: null,
|
|
130
|
-
startListening: function() {
|
|
131
|
-
this.map.on("moveend", this.onMapMove, this);
|
|
132
|
-
|
|
133
|
-
if (HAS_HASHCHANGE) {
|
|
134
|
-
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
|
|
135
|
-
} else {
|
|
136
|
-
clearInterval(this.hashChangeInterval);
|
|
137
|
-
this.hashChangeInterval = setInterval(this.onHashChange, 50);
|
|
138
|
-
}
|
|
139
|
-
this.isListening = true;
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
stopListening: function() {
|
|
143
|
-
this.map.off("moveend", this.onMapMove, this);
|
|
144
|
-
|
|
145
|
-
if (HAS_HASHCHANGE) {
|
|
146
|
-
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
|
|
147
|
-
} else {
|
|
148
|
-
clearInterval(this.hashChangeInterval);
|
|
149
|
-
}
|
|
150
|
-
this.isListening = false;
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
L.hash = function(map) {
|
|
154
|
-
return new L.Hash(map);
|
|
155
|
-
};
|
|
156
|
-
L.Map.prototype.addHash = function() {
|
|
157
|
-
this._hash = L.hash(this);
|
|
158
|
-
};
|
|
159
|
-
L.Map.prototype.removeHash = function() {
|
|
160
|
-
this._hash.removeFrom();
|
|
161
|
-
};
|
|
162
|
-
})(window);
|