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.
- package/.github/workflows/node.yml +30 -0
- package/.github/workflows/release.yml +47 -0
- package/.husky/pre-commit +1 -0
- package/.nvmrc +1 -0
- package/LICENSE.md +7 -0
- package/README.md +28 -0
- package/bin/smp-download.js +83 -0
- package/bin/smp-view.js +52 -0
- package/bin/smp.js +11 -0
- package/eslint.config.js +17 -0
- package/lib/download.js +114 -0
- package/lib/index.js +6 -0
- package/lib/reader.js +150 -0
- package/lib/reporters.js +92 -0
- package/lib/server.js +64 -0
- package/lib/style-downloader.js +363 -0
- package/lib/tile-downloader.js +188 -0
- package/lib/types.ts +104 -0
- package/lib/utils/fetch.js +100 -0
- package/lib/utils/file-formats.js +85 -0
- package/lib/utils/geo.js +87 -0
- package/lib/utils/mapbox.js +155 -0
- package/lib/utils/misc.js +26 -0
- package/lib/utils/streams.js +162 -0
- package/lib/utils/style.js +174 -0
- package/lib/utils/templates.js +136 -0
- package/lib/writer.js +478 -0
- package/map-viewer/index.html +89 -0
- package/package.json +103 -0
- package/test/download-write-read.js +43 -0
- package/test/fixtures/invalid-styles/empty.json +1 -0
- package/test/fixtures/invalid-styles/missing-source.json +10 -0
- package/test/fixtures/invalid-styles/no-layers.json +4 -0
- package/test/fixtures/invalid-styles/no-sources.json +4 -0
- package/test/fixtures/invalid-styles/null.json +1 -0
- package/test/fixtures/invalid-styles/unsupported-version.json +5 -0
- package/test/fixtures/valid-styles/external-geojson.input.json +66 -0
- package/test/fixtures/valid-styles/external-geojson.output.json +93 -0
- package/test/fixtures/valid-styles/inline-geojson.input.json +421 -0
- package/test/fixtures/valid-styles/inline-geojson.output.json +1573 -0
- package/test/fixtures/valid-styles/maplibre-demotiles.input.json +831 -0
- package/test/fixtures/valid-styles/maplibre-unlabelled.input.json +496 -0
- package/test/fixtures/valid-styles/maplibre-unlabelled.output.json +1573 -0
- package/test/fixtures/valid-styles/minimal-labelled.input.json +37 -0
- package/test/fixtures/valid-styles/minimal-labelled.output.json +72 -0
- package/test/fixtures/valid-styles/minimal-sprites.input.json +37 -0
- package/test/fixtures/valid-styles/minimal-sprites.output.json +58 -0
- package/test/fixtures/valid-styles/minimal.input.json +54 -0
- package/test/fixtures/valid-styles/minimal.output.json +92 -0
- package/test/fixtures/valid-styles/multiple-sprites.input.json +46 -0
- package/test/fixtures/valid-styles/multiple-sprites.output.json +128 -0
- package/test/fixtures/valid-styles/raster-sources.input.json +33 -0
- package/test/fixtures/valid-styles/raster-sources.output.json +69 -0
- package/test/utils/assert-bbox-equal.js +19 -0
- package/test/utils/digest-stream.js +36 -0
- package/test/utils/image-streams.js +30 -0
- package/test/utils/reader-helper.js +72 -0
- package/test/write-read.js +620 -0
- package/tsconfig.json +18 -0
- package/types/buffer-peek-stream.d.ts +12 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import JPEGEncoder from '@stealthybox/jpg-stream/encoder.js'
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import BlockStream from 'block-stream2'
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import PNGEncoder from 'png-stream/encoder.js'
|
|
7
|
+
import randomBytesReadableStream from 'random-bytes-readable-stream'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create a random-noise image stream with the given dimensions, either PNG or
|
|
11
|
+
* JPEG.
|
|
12
|
+
*
|
|
13
|
+
* @param {object} options
|
|
14
|
+
* @param {number} options.width
|
|
15
|
+
* @param {number} options.height
|
|
16
|
+
* @param {'png' | 'jpg'} options.format
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
export function randomImageStream({ width, height, format }) {
|
|
20
|
+
const encoder =
|
|
21
|
+
format === 'jpg'
|
|
22
|
+
? new JPEGEncoder(width, height, { colorSpace: 'rgb', quality: 30 })
|
|
23
|
+
: new PNGEncoder(width, height, { colorSpace: 'rgb' })
|
|
24
|
+
return (
|
|
25
|
+
randomBytesReadableStream({ size: width * height * 3 })
|
|
26
|
+
// JPEG Encoder requires one line at a time
|
|
27
|
+
.pipe(new BlockStream({ size: width * 3 }))
|
|
28
|
+
.pipe(encoder)
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { once } from 'node:events'
|
|
2
|
+
|
|
3
|
+
import { replaceVariables } from '../../lib/utils/templates.js'
|
|
4
|
+
import { DigestStream } from './digest-stream.js'
|
|
5
|
+
|
|
6
|
+
/** @import { Reader } from '../../lib/index.js' */
|
|
7
|
+
/**
|
|
8
|
+
* A helper class for reading resources from a styled map package.
|
|
9
|
+
*/
|
|
10
|
+
export class ReaderHelper {
|
|
11
|
+
#reader
|
|
12
|
+
/** @type {Awaited<ReturnType<Reader['getStyle']>> | undefined} */
|
|
13
|
+
#style
|
|
14
|
+
/** @param {Reader} reader */
|
|
15
|
+
constructor(reader) {
|
|
16
|
+
this.#reader = reader
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @param {string} path */
|
|
20
|
+
async #digest(path) {
|
|
21
|
+
const resource = await this.#reader.getResource(path)
|
|
22
|
+
const digestStream = new DigestStream('md5')
|
|
23
|
+
resource.stream.pipe(digestStream).resume()
|
|
24
|
+
await once(digestStream, 'finish')
|
|
25
|
+
return digestStream.digest('hex')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {{ z: number, x: number, y: number, sourceId: string }} opts
|
|
30
|
+
*/
|
|
31
|
+
async getTileHash({ z, x, y, sourceId }) {
|
|
32
|
+
const style = this.#style || (this.#style = await this.#reader.getStyle(''))
|
|
33
|
+
const source = style.sources[sourceId]
|
|
34
|
+
if (!source || !('tiles' in source) || !source.tiles) {
|
|
35
|
+
throw new Error(`Source not found: ${sourceId}`)
|
|
36
|
+
}
|
|
37
|
+
const tilePath = replaceVariables(source.tiles[0], { z, x, y })
|
|
38
|
+
return this.#digest(tilePath)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('../../lib/writer.js').GlyphInfo} glyphInfo
|
|
43
|
+
*/
|
|
44
|
+
async getGlyphHash({ font, range }) {
|
|
45
|
+
const style = this.#style || (this.#style = await this.#reader.getStyle(''))
|
|
46
|
+
if (typeof style.glyphs !== 'string') {
|
|
47
|
+
throw new Error('No glyphs defined in style')
|
|
48
|
+
}
|
|
49
|
+
const glyphPath = replaceVariables(style.glyphs, { fontstack: font, range })
|
|
50
|
+
return this.#digest(glyphPath)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @param {{ id?: string, pixelRatio?: 1 | 2 | 3, ext: 'json' | 'png'}} opts */
|
|
54
|
+
async getSpriteHash({ id, pixelRatio = 1, ext }) {
|
|
55
|
+
const style = this.#style || (this.#style = await this.#reader.getStyle(''))
|
|
56
|
+
if (!style.sprite) {
|
|
57
|
+
throw new Error('No sprites defined in style')
|
|
58
|
+
}
|
|
59
|
+
const pixelRatioString = pixelRatio === 1 ? '' : `@${pixelRatio}x`
|
|
60
|
+
let spritePath
|
|
61
|
+
if (typeof style.sprite === 'string') {
|
|
62
|
+
spritePath = style.sprite + pixelRatioString + '.' + ext
|
|
63
|
+
} else {
|
|
64
|
+
const sprite = style.sprite.find((s) => s.id === (id || 'default'))
|
|
65
|
+
if (!sprite) {
|
|
66
|
+
throw new Error(`Sprite not found: ${id}`)
|
|
67
|
+
}
|
|
68
|
+
spritePath = sprite.url + pixelRatioString + '.' + ext
|
|
69
|
+
}
|
|
70
|
+
return this.#digest(spritePath)
|
|
71
|
+
}
|
|
72
|
+
}
|