styled-map-package 1.0.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.
Files changed (60) hide show
  1. package/.github/workflows/node.yml +30 -0
  2. package/.github/workflows/release.yml +47 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.nvmrc +1 -0
  5. package/LICENSE.md +7 -0
  6. package/README.md +28 -0
  7. package/bin/smp-download.js +83 -0
  8. package/bin/smp-view.js +52 -0
  9. package/bin/smp.js +11 -0
  10. package/eslint.config.js +17 -0
  11. package/lib/download.js +114 -0
  12. package/lib/index.js +6 -0
  13. package/lib/reader.js +150 -0
  14. package/lib/reporters.js +92 -0
  15. package/lib/server.js +64 -0
  16. package/lib/style-downloader.js +363 -0
  17. package/lib/tile-downloader.js +188 -0
  18. package/lib/types.ts +104 -0
  19. package/lib/utils/fetch.js +100 -0
  20. package/lib/utils/file-formats.js +85 -0
  21. package/lib/utils/geo.js +87 -0
  22. package/lib/utils/mapbox.js +155 -0
  23. package/lib/utils/misc.js +26 -0
  24. package/lib/utils/streams.js +162 -0
  25. package/lib/utils/style.js +174 -0
  26. package/lib/utils/templates.js +136 -0
  27. package/lib/writer.js +478 -0
  28. package/map-viewer/index.html +89 -0
  29. package/package.json +103 -0
  30. package/test/download-write-read.js +43 -0
  31. package/test/fixtures/invalid-styles/empty.json +1 -0
  32. package/test/fixtures/invalid-styles/missing-source.json +10 -0
  33. package/test/fixtures/invalid-styles/no-layers.json +4 -0
  34. package/test/fixtures/invalid-styles/no-sources.json +4 -0
  35. package/test/fixtures/invalid-styles/null.json +1 -0
  36. package/test/fixtures/invalid-styles/unsupported-version.json +5 -0
  37. package/test/fixtures/valid-styles/external-geojson.input.json +66 -0
  38. package/test/fixtures/valid-styles/external-geojson.output.json +93 -0
  39. package/test/fixtures/valid-styles/inline-geojson.input.json +421 -0
  40. package/test/fixtures/valid-styles/inline-geojson.output.json +1573 -0
  41. package/test/fixtures/valid-styles/maplibre-demotiles.input.json +831 -0
  42. package/test/fixtures/valid-styles/maplibre-unlabelled.input.json +496 -0
  43. package/test/fixtures/valid-styles/maplibre-unlabelled.output.json +1573 -0
  44. package/test/fixtures/valid-styles/minimal-labelled.input.json +37 -0
  45. package/test/fixtures/valid-styles/minimal-labelled.output.json +72 -0
  46. package/test/fixtures/valid-styles/minimal-sprites.input.json +37 -0
  47. package/test/fixtures/valid-styles/minimal-sprites.output.json +58 -0
  48. package/test/fixtures/valid-styles/minimal.input.json +54 -0
  49. package/test/fixtures/valid-styles/minimal.output.json +92 -0
  50. package/test/fixtures/valid-styles/multiple-sprites.input.json +46 -0
  51. package/test/fixtures/valid-styles/multiple-sprites.output.json +128 -0
  52. package/test/fixtures/valid-styles/raster-sources.input.json +33 -0
  53. package/test/fixtures/valid-styles/raster-sources.output.json +69 -0
  54. package/test/utils/assert-bbox-equal.js +19 -0
  55. package/test/utils/digest-stream.js +36 -0
  56. package/test/utils/image-streams.js +30 -0
  57. package/test/utils/reader-helper.js +72 -0
  58. package/test/write-read.js +620 -0
  59. package/tsconfig.json +18 -0
  60. package/types/buffer-peek-stream.d.ts +12 -0
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "MapLibre",
3
+ "zoom": 0.8619833357855968,
4
+ "pitch": 0,
5
+ "center": [17.65431710431244, 32.954120326746775],
6
+ "glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
7
+ "layers": [
8
+ {
9
+ "id": "countries-label",
10
+ "type": "symbol",
11
+ "paint": {
12
+ "text-color": "rgba(8, 37, 77, 1)",
13
+ "text-halo-color": "rgba(255, 255, 255, 1)"
14
+ },
15
+ "filter": ["all"],
16
+ "layout": {
17
+ "text-font": ["Open Sans Semibold"],
18
+ "text-size": 12,
19
+ "text-field": "{NAME}",
20
+ "visibility": "visible",
21
+ "text-max-width": 10
22
+ },
23
+ "source": "maplibre",
24
+ "maxzoom": 24,
25
+ "minzoom": 2,
26
+ "source-layer": "centroids"
27
+ }
28
+ ],
29
+ "bearing": 0,
30
+ "sources": {
31
+ "maplibre": {
32
+ "url": "https://demotiles.maplibre.org/tiles/tiles.json",
33
+ "type": "vector"
34
+ }
35
+ },
36
+ "version": 8
37
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "MapLibre",
3
+ "zoom": 0,
4
+ "pitch": 0,
5
+ "center": [
6
+ 0,
7
+ 0
8
+ ],
9
+ "glyphs": "smp://maps.v1/fonts/{fontstack}/{range}.pbf.gz",
10
+ "layers": [
11
+ {
12
+ "id": "countries-label",
13
+ "type": "symbol",
14
+ "paint": {
15
+ "text-color": "rgba(8, 37, 77, 1)",
16
+ "text-halo-color": "rgba(255, 255, 255, 1)"
17
+ },
18
+ "filter": [
19
+ "all"
20
+ ],
21
+ "layout": {
22
+ "text-font": [
23
+ "Open Sans Semibold"
24
+ ],
25
+ "text-size": 12,
26
+ "text-field": [
27
+ "to-string",
28
+ [
29
+ "get",
30
+ "NAME"
31
+ ]
32
+ ],
33
+ "visibility": "visible",
34
+ "text-max-width": 10
35
+ },
36
+ "source": "maplibre",
37
+ "maxzoom": 24,
38
+ "minzoom": 2,
39
+ "source-layer": "centroids"
40
+ }
41
+ ],
42
+ "bearing": 0,
43
+ "sources": {
44
+ "maplibre": {
45
+ "type": "vector",
46
+ "minzoom": 0,
47
+ "maxzoom": 0,
48
+ "bounds": [
49
+ -180,
50
+ -85.051129,
51
+ 180,
52
+ 85.051129
53
+ ],
54
+ "tiles": [
55
+ "smp://maps.v1/s/0/{z}/{x}/{y}.mvt.gz"
56
+ ]
57
+ }
58
+ },
59
+ "version": 8,
60
+ "metadata": {
61
+ "smp:bounds": [
62
+ -180,
63
+ -85.051129,
64
+ 180,
65
+ 85.051129
66
+ ],
67
+ "smp:maxzoom": 0,
68
+ "smp:sourceFolders": {
69
+ "maplibre": "0"
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "version": 8,
3
+ "name": "OSM Bright",
4
+ "sources": {
5
+ "openmaptiles": {
6
+ "type": "vector",
7
+ "url": "https://demotiles.maplibre.org/tiles-omt/tiles.json"
8
+ }
9
+ },
10
+ "sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite",
11
+ "layers": [
12
+ {
13
+ "id": "background",
14
+ "type": "background",
15
+ "paint": {
16
+ "background-color": "#f8f4f0"
17
+ }
18
+ },
19
+ {
20
+ "id": "poi-level-1",
21
+ "type": "symbol",
22
+ "source": "openmaptiles",
23
+ "source-layer": "poi",
24
+ "minzoom": 14,
25
+ "filter": [
26
+ "all",
27
+ ["==", "$type", "Point"],
28
+ ["<=", "rank", 14],
29
+ ["has", "name"],
30
+ ["any", ["!has", "level"], ["==", "level", 0]]
31
+ ],
32
+ "layout": {
33
+ "icon-image": "{class}_11"
34
+ }
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "version": 8,
3
+ "name": "OSM Bright",
4
+ "sources": {
5
+ "openmaptiles": {
6
+ "type": "vector",
7
+ "minzoom": 0,
8
+ "maxzoom": 0,
9
+ "bounds": [-180, -85.051129, 180, 85.051129],
10
+ "tiles": ["smp://maps.v1/s/0/{z}/{x}/{y}.mvt.gz"]
11
+ }
12
+ },
13
+ "sprite": "smp://maps.v1/sprites/default/sprite",
14
+ "layers": [
15
+ {
16
+ "id": "background",
17
+ "type": "background",
18
+ "paint": {
19
+ "background-color": "#f8f4f0"
20
+ }
21
+ },
22
+ {
23
+ "id": "poi-level-1",
24
+ "type": "symbol",
25
+ "source": "openmaptiles",
26
+ "source-layer": "poi",
27
+ "minzoom": 14,
28
+ "filter": [
29
+ "all",
30
+ ["==", ["geometry-type"], "Point"],
31
+ ["<=", ["get", "rank"], 14],
32
+ ["has", "name"],
33
+ [
34
+ "any",
35
+ ["!", ["has", "level"]],
36
+ [
37
+ "case",
38
+ ["==", ["typeof", ["get", "level"]], "number"],
39
+ ["==", ["get", "level"], 0],
40
+ false
41
+ ]
42
+ ]
43
+ ],
44
+ "layout": {
45
+ "icon-image": ["concat", ["get", "class"], "_11"]
46
+ }
47
+ }
48
+ ],
49
+ "metadata": {
50
+ "smp:bounds": [-180, -85.051129, 180, 85.051129],
51
+ "smp:maxzoom": 0,
52
+ "smp:sourceFolders": {
53
+ "openmaptiles": "0"
54
+ }
55
+ },
56
+ "center": [0, 0],
57
+ "zoom": 0
58
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "MapLibre",
3
+ "zoom": 0.8619833357855968,
4
+ "pitch": 0,
5
+ "center": [17.65431710431244, 32.954120326746775],
6
+ "layers": [
7
+ {
8
+ "id": "background",
9
+ "type": "background",
10
+ "paint": {
11
+ "background-color": "#D8F2FF"
12
+ },
13
+ "filter": ["all"],
14
+ "layout": {
15
+ "visibility": "visible"
16
+ },
17
+ "maxzoom": 24
18
+ },
19
+ {
20
+ "id": "coastline",
21
+ "type": "line",
22
+ "paint": {
23
+ "line-blur": 0.5,
24
+ "line-color": "#198EC8",
25
+ "line-width": {
26
+ "stops": [
27
+ [0, 2],
28
+ [6, 6],
29
+ [14, 9],
30
+ [22, 18]
31
+ ]
32
+ }
33
+ },
34
+ "filter": ["all"],
35
+ "layout": {
36
+ "line-cap": "round",
37
+ "line-join": "round",
38
+ "visibility": "visible"
39
+ },
40
+ "source": "maplibre",
41
+ "maxzoom": 24,
42
+ "minzoom": 0,
43
+ "source-layer": "countries"
44
+ }
45
+ ],
46
+ "bearing": 0,
47
+ "sources": {
48
+ "maplibre": {
49
+ "url": "https://demotiles.maplibre.org/tiles/tiles.json",
50
+ "type": "vector"
51
+ }
52
+ },
53
+ "version": 8
54
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "MapLibre",
3
+ "zoom": 3,
4
+ "pitch": 0,
5
+ "center": [
6
+ 56.25,
7
+ 10.53212169788165
8
+ ],
9
+ "layers": [
10
+ {
11
+ "id": "background",
12
+ "type": "background",
13
+ "paint": {
14
+ "background-color": "#D8F2FF"
15
+ },
16
+ "filter": [
17
+ "all"
18
+ ],
19
+ "layout": {
20
+ "visibility": "visible"
21
+ },
22
+ "maxzoom": 24
23
+ },
24
+ {
25
+ "id": "coastline",
26
+ "type": "line",
27
+ "paint": {
28
+ "line-blur": 0.5,
29
+ "line-color": "#198EC8",
30
+ "line-width": [
31
+ "interpolate",
32
+ [
33
+ "linear"
34
+ ],
35
+ [
36
+ "zoom"
37
+ ],
38
+ 0,
39
+ 2,
40
+ 6,
41
+ 6,
42
+ 14,
43
+ 9,
44
+ 22,
45
+ 18
46
+ ]
47
+ },
48
+ "filter": [
49
+ "all"
50
+ ],
51
+ "layout": {
52
+ "line-cap": "round",
53
+ "line-join": "round",
54
+ "visibility": "visible"
55
+ },
56
+ "source": "maplibre",
57
+ "maxzoom": 24,
58
+ "minzoom": 0,
59
+ "source-layer": "countries"
60
+ }
61
+ ],
62
+ "bearing": 0,
63
+ "sources": {
64
+ "maplibre": {
65
+ "type": "vector",
66
+ "minzoom": 0,
67
+ "maxzoom": 5,
68
+ "bounds": [
69
+ -45,
70
+ -55.776573018667676,
71
+ 157.5,
72
+ 76.84081641443098
73
+ ],
74
+ "tiles": [
75
+ "smp://maps.v1/s/0/{z}/{x}/{y}.mvt.gz"
76
+ ]
77
+ }
78
+ },
79
+ "version": 8,
80
+ "metadata": {
81
+ "smp:bounds": [
82
+ -45,
83
+ -55.776573018667676,
84
+ 157.5,
85
+ 76.84081641443098
86
+ ],
87
+ "smp:maxzoom": 5,
88
+ "smp:sourceFolders": {
89
+ "maplibre": "0"
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "version": 8,
3
+ "name": "OSM Bright",
4
+ "sources": {
5
+ "openmaptiles": {
6
+ "type": "vector",
7
+ "url": "https://demotiles.maplibre.org/tiles-omt/tiles.json"
8
+ }
9
+ },
10
+ "sprite": [
11
+ {
12
+ "id": "roadsigns",
13
+ "url": "https://example.com/myroadsigns"
14
+ },
15
+ {
16
+ "id": "default",
17
+ "url": "https://example2.com/anotherurl"
18
+ }
19
+ ],
20
+ "layers": [
21
+ {
22
+ "id": "background",
23
+ "type": "background",
24
+ "paint": {
25
+ "background-color": "#f8f4f0"
26
+ }
27
+ },
28
+ {
29
+ "id": "poi-level-1",
30
+ "type": "symbol",
31
+ "source": "openmaptiles",
32
+ "source-layer": "poi",
33
+ "minzoom": 14,
34
+ "filter": [
35
+ "all",
36
+ ["==", "$type", "Point"],
37
+ ["<=", "rank", 14],
38
+ ["has", "name"],
39
+ ["any", ["!has", "level"], ["==", "level", 0]]
40
+ ],
41
+ "layout": {
42
+ "icon-image": "{class}_11"
43
+ }
44
+ }
45
+ ]
46
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "version": 8,
3
+ "name": "OSM Bright",
4
+ "sources": {
5
+ "openmaptiles": {
6
+ "type": "vector",
7
+ "minzoom": 0,
8
+ "maxzoom": 0,
9
+ "bounds": [
10
+ -180,
11
+ -85.051129,
12
+ 180,
13
+ 85.051129
14
+ ],
15
+ "tiles": [
16
+ "/s/0/{z}/{x}/{y}.mvt.gz"
17
+ ]
18
+ }
19
+ },
20
+ "sprite": [
21
+ {
22
+ "id": "roadsigns",
23
+ "url": "/sprites/roadsigns/sprite"
24
+ },
25
+ {
26
+ "id": "default",
27
+ "url": "/sprites/default/sprite"
28
+ }
29
+ ],
30
+ "layers": [
31
+ {
32
+ "id": "background",
33
+ "type": "background",
34
+ "paint": {
35
+ "background-color": "#f8f4f0"
36
+ }
37
+ },
38
+ {
39
+ "id": "poi-level-1",
40
+ "type": "symbol",
41
+ "source": "openmaptiles",
42
+ "source-layer": "poi",
43
+ "minzoom": 14,
44
+ "filter": [
45
+ "all",
46
+ [
47
+ "==",
48
+ [
49
+ "geometry-type"
50
+ ],
51
+ "Point"
52
+ ],
53
+ [
54
+ "<=",
55
+ [
56
+ "get",
57
+ "rank"
58
+ ],
59
+ 14
60
+ ],
61
+ [
62
+ "has",
63
+ "name"
64
+ ],
65
+ [
66
+ "any",
67
+ [
68
+ "!",
69
+ [
70
+ "has",
71
+ "level"
72
+ ]
73
+ ],
74
+ [
75
+ "case",
76
+ [
77
+ "==",
78
+ [
79
+ "typeof",
80
+ [
81
+ "get",
82
+ "level"
83
+ ]
84
+ ],
85
+ "number"
86
+ ],
87
+ [
88
+ "==",
89
+ [
90
+ "get",
91
+ "level"
92
+ ],
93
+ 0
94
+ ],
95
+ false
96
+ ]
97
+ ]
98
+ ],
99
+ "layout": {
100
+ "icon-image": [
101
+ "concat",
102
+ [
103
+ "get",
104
+ "class"
105
+ ],
106
+ "_11"
107
+ ]
108
+ }
109
+ }
110
+ ],
111
+ "metadata": {
112
+ "smp:bounds": [
113
+ -180,
114
+ -85.051129,
115
+ 180,
116
+ 85.051129
117
+ ],
118
+ "smp:maxzoom": 0,
119
+ "smp:sourceFolders": {
120
+ "openmaptiles": "0"
121
+ }
122
+ },
123
+ "center": [
124
+ 0,
125
+ 0
126
+ ],
127
+ "zoom": 0
128
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "version": 8,
3
+ "sources": {
4
+ "jpg-tiles": {
5
+ "type": "raster",
6
+ "tiles": ["https://example1.com/{z}/{x}/{y}.jpg"],
7
+ "tileSize": 256
8
+ },
9
+ "png-tiles": {
10
+ "type": "raster",
11
+ "tiles": ["https://example2.com/{z}/{x}/{y}.png"],
12
+ "tileSize": 256
13
+ }
14
+ },
15
+ "layers": [
16
+ {
17
+ "id": "jpg-tiles",
18
+ "type": "raster",
19
+ "source": "jpg-tiles",
20
+ "minzoom": 0,
21
+ "maxzoom": 22
22
+ },
23
+ {
24
+ "id": "png-tiles",
25
+ "type": "raster",
26
+ "source": "png-tiles",
27
+ "minzoom": 0,
28
+ "maxzoom": 22
29
+ }
30
+ ],
31
+ "center": [-74.5, 40],
32
+ "zoom": 2
33
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "version": 8,
3
+ "sources": {
4
+ "png-tiles": {
5
+ "type": "raster",
6
+ "tileSize": 256,
7
+ "minzoom": 0,
8
+ "maxzoom": 0,
9
+ "bounds": [
10
+ -180,
11
+ -85.051129,
12
+ 180,
13
+ 85.051129
14
+ ],
15
+ "tiles": [
16
+ "smp://maps.v1/s/0/{z}/{x}/{y}.png"
17
+ ]
18
+ },
19
+ "jpg-tiles": {
20
+ "type": "raster",
21
+ "tileSize": 256,
22
+ "minzoom": 0,
23
+ "maxzoom": 0,
24
+ "bounds": [
25
+ -180,
26
+ -85.051129,
27
+ 180,
28
+ 85.051129
29
+ ],
30
+ "tiles": [
31
+ "smp://maps.v1/s/1/{z}/{x}/{y}.jpg"
32
+ ]
33
+ }
34
+ },
35
+ "layers": [
36
+ {
37
+ "id": "jpg-tiles",
38
+ "type": "raster",
39
+ "source": "jpg-tiles",
40
+ "minzoom": 0,
41
+ "maxzoom": 22
42
+ },
43
+ {
44
+ "id": "png-tiles",
45
+ "type": "raster",
46
+ "source": "png-tiles",
47
+ "minzoom": 0,
48
+ "maxzoom": 22
49
+ }
50
+ ],
51
+ "center": [
52
+ 0,
53
+ 0
54
+ ],
55
+ "zoom": 0,
56
+ "metadata": {
57
+ "smp:bounds": [
58
+ -180,
59
+ -85.051129,
60
+ 180,
61
+ 85.051129
62
+ ],
63
+ "smp:maxzoom": 0,
64
+ "smp:sourceFolders": {
65
+ "png-tiles": "0",
66
+ "jpg-tiles": "1"
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,19 @@
1
+ import assert from 'node:assert/strict'
2
+
3
+ const PRECISION = 1e-6
4
+
5
+ /**
6
+ * Assert that two bounding boxes are equal within 6 decimal places.
7
+ * @param {number[]} actual
8
+ * @param {number[]} expected
9
+ * @param {string} msg
10
+ */
11
+ export function assertBboxEqual(actual, expected, msg) {
12
+ assert.equal(actual.length, expected.length, `${msg}: length`)
13
+ for (let i = 0; i < actual.length; i++) {
14
+ assert(
15
+ Math.abs(actual[i] - expected[i]) < PRECISION,
16
+ `${msg}:\n ${actual[i]} - ${expected[i]} > ${PRECISION}`,
17
+ )
18
+ }
19
+ }
@@ -0,0 +1,36 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { Transform } from 'node:stream'
3
+
4
+ /**
5
+ * A passthrough stream that calculates a digest of the data passing through it.
6
+ */
7
+ export class DigestStream extends Transform {
8
+ #hash
9
+ /** @param {string} algorithm */
10
+ constructor(algorithm) {
11
+ super()
12
+ this.#hash = createHash(algorithm)
13
+ }
14
+ /**
15
+ * @param {*} chunk
16
+ * @param {BufferEncoding} encoding
17
+ * @param {import('node:stream').TransformCallback} callback
18
+ */
19
+ _transform(chunk, encoding, callback) {
20
+ this.#hash.update(chunk)
21
+ callback(null, chunk)
22
+ }
23
+ /**
24
+ * Calculates the digest of all of the data passed through the stream. If
25
+ * encoding is provided a string will be returned; otherwise a Buffer is
26
+ * returned.
27
+ *
28
+ * The stream can not be used again after the `digest()` method has been
29
+ * called. Multiple calls will cause an error to be thrown.
30
+ *
31
+ * @param {import('node:crypto').BinaryToTextEncoding} [encoding]
32
+ */
33
+ digest(encoding = 'binary') {
34
+ return this.#hash.digest(encoding)
35
+ }
36
+ }