styled-map-package-api 5.0.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/dist/download.cjs +100 -0
- package/dist/download.d.cts +64 -0
- package/dist/download.d.ts +64 -0
- package/dist/download.js +76 -0
- package/dist/from-mbtiles.cjs +81 -0
- package/dist/from-mbtiles.d.cts +10 -0
- package/dist/from-mbtiles.d.ts +10 -0
- package/dist/from-mbtiles.js +57 -0
- package/dist/index.cjs +46 -0
- package/dist/index.d.cts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +16 -0
- package/dist/reader.cjs +287 -0
- package/dist/reader.d.cts +68 -0
- package/dist/reader.d.ts +68 -0
- package/dist/reader.js +259 -0
- package/dist/server.cjs +73 -0
- package/dist/server.d.cts +46 -0
- package/dist/server.d.ts +46 -0
- package/dist/server.js +49 -0
- package/dist/style-downloader.cjs +314 -0
- package/dist/style-downloader.d.cts +119 -0
- package/dist/style-downloader.d.ts +119 -0
- package/dist/style-downloader.js +290 -0
- package/dist/tile-downloader.cjs +156 -0
- package/dist/tile-downloader.d.cts +83 -0
- package/dist/tile-downloader.d.ts +83 -0
- package/dist/tile-downloader.js +124 -0
- package/dist/types-CJq90eOB.d.cts +184 -0
- package/dist/types-CJq90eOB.d.ts +184 -0
- package/dist/utils/errors.cjs +41 -0
- package/dist/utils/errors.d.cts +18 -0
- package/dist/utils/errors.d.ts +18 -0
- package/dist/utils/errors.js +16 -0
- package/dist/utils/fetch.cjs +97 -0
- package/dist/utils/fetch.d.cts +50 -0
- package/dist/utils/fetch.d.ts +50 -0
- package/dist/utils/fetch.js +63 -0
- package/dist/utils/file-formats.cjs +96 -0
- package/dist/utils/file-formats.d.cts +33 -0
- package/dist/utils/file-formats.d.ts +33 -0
- package/dist/utils/file-formats.js +70 -0
- package/dist/utils/geo.cjs +84 -0
- package/dist/utils/geo.d.cts +46 -0
- package/dist/utils/geo.d.ts +46 -0
- package/dist/utils/geo.js +56 -0
- package/dist/utils/mapbox.cjs +121 -0
- package/dist/utils/mapbox.d.cts +43 -0
- package/dist/utils/mapbox.d.ts +43 -0
- package/dist/utils/mapbox.js +91 -0
- package/dist/utils/misc.cjs +39 -0
- package/dist/utils/misc.d.cts +22 -0
- package/dist/utils/misc.d.ts +22 -0
- package/dist/utils/misc.js +13 -0
- package/dist/utils/streams.cjs +99 -0
- package/dist/utils/streams.d.cts +49 -0
- package/dist/utils/streams.d.ts +49 -0
- package/dist/utils/streams.js +73 -0
- package/dist/utils/style.cjs +126 -0
- package/dist/utils/style.d.cts +67 -0
- package/dist/utils/style.d.ts +67 -0
- package/dist/utils/style.js +98 -0
- package/dist/utils/templates.cjs +124 -0
- package/dist/utils/templates.d.cts +80 -0
- package/dist/utils/templates.d.ts +80 -0
- package/dist/utils/templates.js +85 -0
- package/dist/writer.cjs +465 -0
- package/dist/writer.d.cts +5 -0
- package/dist/writer.d.ts +5 -0
- package/dist/writer.js +452 -0
- package/package.json +161 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { T as TileInfo$1 } from './types-CJq90eOB.js';
|
|
2
|
+
import { BBox } from './utils/geo.js';
|
|
3
|
+
import { FetchQueue } from './utils/fetch.js';
|
|
4
|
+
import '@maplibre/maplibre-gl-style-spec';
|
|
5
|
+
import 'geojson';
|
|
6
|
+
import 'type-fest';
|
|
7
|
+
import 'events';
|
|
8
|
+
import './utils/streams.js';
|
|
9
|
+
import 'stream/web';
|
|
10
|
+
|
|
11
|
+
/** @typedef {Omit<import('./writer.js').TileInfo, 'sourceId'>} TileInfo */
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {object} TileDownloadStats
|
|
14
|
+
* @property {number} total
|
|
15
|
+
* @property {number} downloaded
|
|
16
|
+
* @property {number} skipped
|
|
17
|
+
* @property {number} totalBytes
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Download tiles from a list of tile URLs within a bounding box and zoom range.
|
|
21
|
+
* Returns an async generator of tile data as readable streams and tile info objects.
|
|
22
|
+
*
|
|
23
|
+
* @param {object} opts
|
|
24
|
+
* @param {string[]} opts.tileUrls Array of tile URL templates. Use `{x}`, `{y}`, `{z}` placeholders, and optional `{scheme}` placeholder which can be `xyz` or `tms`.
|
|
25
|
+
* @param {import('./utils/geo.js').BBox} opts.bounds Bounding box of the area to download
|
|
26
|
+
* @param {number} opts.maxzoom Maximum zoom level to download
|
|
27
|
+
* @param {(progress: TileDownloadStats) => void} [opts.onprogress] Callback to report download progress
|
|
28
|
+
* @param {boolean} [opts.trackErrors=false] Include errors in the returned array of skipped tiles - this has memory overhead so should only be used for debugging.
|
|
29
|
+
* @param {import('./utils/geo.js').BBox} [opts.sourceBounds=MAX_BOUNDS] Bounding box of source data.
|
|
30
|
+
* @param {boolean} [opts.boundsBuffer=false] Buffer the bounds by one tile at each zoom level to ensure no tiles are missed at the edges. With this set to false, in most instances the map will appear incomplete when viewed because the downloaded tiles at lower zoom levels will not cover the map view area.
|
|
31
|
+
* @param {number} [opts.minzoom=0] Minimum zoom level to download (for most cases this should be left as `0` - the size overhead is minimal, because each zoom level has 4x as many tiles)
|
|
32
|
+
* @param {number} [opts.concurrency=8] Number of concurrent downloads (ignored if `fetchQueue` is provided)
|
|
33
|
+
* @param {FetchQueue} [opts.fetchQueue=new FetchQueue(concurrency)] Optional fetch queue to use for downloading tiles
|
|
34
|
+
* @param {'xyz' | 'tms'} [opts.scheme='xyz'] Tile scheme to use for tile URLs
|
|
35
|
+
* @returns {AsyncGenerator<[ReadableStream<Uint8Array>, TileInfo]> & { readonly skipped: Array<TileInfo & { error?: Error }>, readonly stats: TileDownloadStats }}
|
|
36
|
+
*/
|
|
37
|
+
declare function downloadTiles({ tileUrls, bounds, maxzoom, onprogress, trackErrors, sourceBounds, boundsBuffer, minzoom, concurrency, fetchQueue, scheme, }: {
|
|
38
|
+
tileUrls: string[];
|
|
39
|
+
bounds: BBox;
|
|
40
|
+
maxzoom: number;
|
|
41
|
+
onprogress?: ((progress: TileDownloadStats) => void) | undefined;
|
|
42
|
+
trackErrors?: boolean | undefined;
|
|
43
|
+
sourceBounds?: BBox | undefined;
|
|
44
|
+
boundsBuffer?: boolean | undefined;
|
|
45
|
+
minzoom?: number | undefined;
|
|
46
|
+
concurrency?: number | undefined;
|
|
47
|
+
fetchQueue?: FetchQueue | undefined;
|
|
48
|
+
scheme?: "xyz" | "tms" | undefined;
|
|
49
|
+
}): AsyncGenerator<[ReadableStream<Uint8Array>, TileInfo]> & {
|
|
50
|
+
readonly skipped: Array<TileInfo & {
|
|
51
|
+
error?: Error;
|
|
52
|
+
}>;
|
|
53
|
+
readonly stats: TileDownloadStats;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param {object} opts
|
|
58
|
+
* @param {import('./utils/geo.js').BBox} [opts.bounds]
|
|
59
|
+
* @param {import('./utils/geo.js').BBox} [opts.sourceBounds]
|
|
60
|
+
* @param {boolean} [opts.boundsBuffer]
|
|
61
|
+
* @param {number} [opts.minzoom]
|
|
62
|
+
* @param {number} opts.maxzoom
|
|
63
|
+
*/
|
|
64
|
+
declare function tileIterator({ bounds, minzoom, maxzoom, sourceBounds, boundsBuffer, }: {
|
|
65
|
+
bounds?: BBox | undefined;
|
|
66
|
+
sourceBounds?: BBox | undefined;
|
|
67
|
+
boundsBuffer?: boolean | undefined;
|
|
68
|
+
minzoom?: number | undefined;
|
|
69
|
+
maxzoom: number;
|
|
70
|
+
}): Generator<{
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
z: number;
|
|
74
|
+
}, void, unknown>;
|
|
75
|
+
type TileInfo = Omit<TileInfo$1, "sourceId">;
|
|
76
|
+
type TileDownloadStats = {
|
|
77
|
+
total: number;
|
|
78
|
+
downloaded: number;
|
|
79
|
+
skipped: number;
|
|
80
|
+
totalBytes: number;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { type TileDownloadStats, type TileInfo, downloadTiles, tileIterator };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import SphericalMercator from "@mapbox/sphericalmercator";
|
|
2
|
+
import Queue from "yocto-queue";
|
|
3
|
+
import { FetchQueue } from "./utils/fetch.js";
|
|
4
|
+
import {
|
|
5
|
+
getFormatFromMimeType,
|
|
6
|
+
getTileFormatFromStream
|
|
7
|
+
} from "./utils/file-formats.js";
|
|
8
|
+
import { getTileUrl, MAX_BOUNDS } from "./utils/geo.js";
|
|
9
|
+
import { noop } from "./utils/misc.js";
|
|
10
|
+
function downloadTiles({
|
|
11
|
+
tileUrls,
|
|
12
|
+
bounds,
|
|
13
|
+
maxzoom,
|
|
14
|
+
onprogress = noop,
|
|
15
|
+
trackErrors = false,
|
|
16
|
+
sourceBounds = MAX_BOUNDS,
|
|
17
|
+
boundsBuffer = false,
|
|
18
|
+
minzoom = 0,
|
|
19
|
+
concurrency = 8,
|
|
20
|
+
fetchQueue = new FetchQueue(concurrency),
|
|
21
|
+
scheme = "xyz"
|
|
22
|
+
}) {
|
|
23
|
+
const skipped = [];
|
|
24
|
+
let completed = 0;
|
|
25
|
+
let stats = {
|
|
26
|
+
total: 0,
|
|
27
|
+
downloaded: 0,
|
|
28
|
+
skipped: 0,
|
|
29
|
+
totalBytes: 0
|
|
30
|
+
};
|
|
31
|
+
function onDownloadProgress({ chunkBytes }) {
|
|
32
|
+
stats.totalBytes += chunkBytes;
|
|
33
|
+
onprogress(stats);
|
|
34
|
+
}
|
|
35
|
+
function onDownloadError(error, tileInfo) {
|
|
36
|
+
if (trackErrors) {
|
|
37
|
+
skipped.push({ ...tileInfo, error });
|
|
38
|
+
} else {
|
|
39
|
+
skipped.push(tileInfo);
|
|
40
|
+
}
|
|
41
|
+
onprogress(stats);
|
|
42
|
+
}
|
|
43
|
+
function onDownloadComplete() {
|
|
44
|
+
stats.downloaded = ++completed - skipped.length;
|
|
45
|
+
stats.skipped = skipped.length;
|
|
46
|
+
onprogress(stats);
|
|
47
|
+
}
|
|
48
|
+
const tiles = (async function* () {
|
|
49
|
+
const queue = new Queue();
|
|
50
|
+
const tiles2 = tileIterator({
|
|
51
|
+
bounds,
|
|
52
|
+
minzoom,
|
|
53
|
+
maxzoom,
|
|
54
|
+
sourceBounds,
|
|
55
|
+
boundsBuffer
|
|
56
|
+
});
|
|
57
|
+
for (const { x, y, z } of tiles2) {
|
|
58
|
+
const tileURL = getTileUrl(tileUrls, { x, y, z, scheme });
|
|
59
|
+
const tileInfo = { z, x, y };
|
|
60
|
+
const result = fetchQueue.fetch(tileURL, { onprogress: onDownloadProgress }).catch((err) => onDownloadError(err, tileInfo));
|
|
61
|
+
queue.enqueue([result, tileInfo]);
|
|
62
|
+
}
|
|
63
|
+
stats.total = queue.size;
|
|
64
|
+
if (onprogress) onprogress(stats);
|
|
65
|
+
for (const [result, tileInfo] of queue) {
|
|
66
|
+
const downloadResponse = await result.catch(noop);
|
|
67
|
+
if (!downloadResponse) continue;
|
|
68
|
+
let { body, mimeType } = downloadResponse;
|
|
69
|
+
let format;
|
|
70
|
+
if (mimeType) {
|
|
71
|
+
format = getFormatFromMimeType(mimeType);
|
|
72
|
+
} else {
|
|
73
|
+
;
|
|
74
|
+
[format, body] = await getTileFormatFromStream(body);
|
|
75
|
+
}
|
|
76
|
+
let stream = body;
|
|
77
|
+
const transform = (
|
|
78
|
+
/** @type {TransformStream<Uint8Array, Uint8Array>} */
|
|
79
|
+
format === "mvt" ? new CompressionStream("gzip") : new TransformStream()
|
|
80
|
+
);
|
|
81
|
+
body.pipeTo(transform.writable).then(onDownloadComplete, (err) => onDownloadError(err, tileInfo));
|
|
82
|
+
stream = transform.readable;
|
|
83
|
+
yield [stream, { ...tileInfo, format }];
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
Object.defineProperty(tiles, "skipped", {
|
|
87
|
+
get() {
|
|
88
|
+
return skipped;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(tiles, "stats", {
|
|
92
|
+
get() {
|
|
93
|
+
return stats;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return tiles;
|
|
97
|
+
}
|
|
98
|
+
function* tileIterator({
|
|
99
|
+
bounds = [...MAX_BOUNDS],
|
|
100
|
+
minzoom = 0,
|
|
101
|
+
maxzoom,
|
|
102
|
+
sourceBounds,
|
|
103
|
+
boundsBuffer = false
|
|
104
|
+
}) {
|
|
105
|
+
const sm = new SphericalMercator({ size: 256 });
|
|
106
|
+
for (let z = minzoom; z <= maxzoom; z++) {
|
|
107
|
+
let { minX, minY, maxX, maxY } = sm.xyz([...bounds], z);
|
|
108
|
+
let sourceXYBounds = sourceBounds ? sm.xyz([...sourceBounds], z) : { minX, minY, maxX, maxY };
|
|
109
|
+
const buffer = boundsBuffer ? 1 : 0;
|
|
110
|
+
minX = Math.max(0, minX - buffer, sourceXYBounds.minX);
|
|
111
|
+
minY = Math.max(0, minY - buffer, sourceXYBounds.minY);
|
|
112
|
+
maxX = Math.min(Math.pow(2, z) - 1, maxX + buffer, sourceXYBounds.maxX);
|
|
113
|
+
maxY = Math.min(Math.pow(2, z) - 1, maxY + buffer, sourceXYBounds.maxY);
|
|
114
|
+
for (let x = minX; x <= maxX; x++) {
|
|
115
|
+
for (let y = minY; y <= maxY; y++) {
|
|
116
|
+
yield { x, y, z };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
downloadTiles,
|
|
123
|
+
tileIterator
|
|
124
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { StyleSpecification, SourceSpecification, GeoJSONSourceSpecification, VectorSourceSpecification, RasterSourceSpecification, RasterDEMSourceSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
2
|
+
import { GeoJSON, BBox } from 'geojson';
|
|
3
|
+
import { SetRequired } from 'type-fest';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
|
|
6
|
+
/** @typedef {string | Uint8Array | ReadableStream } Source */
|
|
7
|
+
/** @typedef {`${number}-${number}`} GlyphRange */
|
|
8
|
+
/** @typedef {'png' | 'mvt' | 'jpg' | 'webp'} TileFormat */
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {object} SourceInfo
|
|
11
|
+
* @property {import('./types.js').SMPSource} source
|
|
12
|
+
* @property {string} encodedSourceId
|
|
13
|
+
* @property {TileFormat} [format]
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} TileInfo
|
|
17
|
+
* @property {number} z
|
|
18
|
+
* @property {number} x
|
|
19
|
+
* @property {number} y
|
|
20
|
+
* @property {string} sourceId
|
|
21
|
+
* @property {TileFormat} [format]
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} GlyphInfo
|
|
25
|
+
* @property {string} font
|
|
26
|
+
* @property {GlyphRange} range
|
|
27
|
+
*/
|
|
28
|
+
/** @import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec' */
|
|
29
|
+
/** @import { InputSource, SMPSource } from './types.js' */
|
|
30
|
+
declare const SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
31
|
+
/**
|
|
32
|
+
* Write a styled map package to a stream. Stream `writer.outputStream` to a
|
|
33
|
+
* destination, e.g. `fs.createWriteStream('my-map.styledmap')`. You must call
|
|
34
|
+
* `witer.finish()` and then wait for your writable stream to `finish` before
|
|
35
|
+
* using the output.
|
|
36
|
+
*/
|
|
37
|
+
declare class Writer extends EventEmitter<[never]> {
|
|
38
|
+
static SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
39
|
+
/**
|
|
40
|
+
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
41
|
+
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
42
|
+
* this is typed as `any` and validated internally)
|
|
43
|
+
*/
|
|
44
|
+
constructor(style: any);
|
|
45
|
+
/**
|
|
46
|
+
* @returns {ReadableStream<Uint8Array>} Readable stream of the styled map package
|
|
47
|
+
*/
|
|
48
|
+
get outputStream(): ReadableStream<Uint8Array>;
|
|
49
|
+
/**
|
|
50
|
+
* Abort the output stream with an error. Call this if an error occurs during
|
|
51
|
+
* writing to propagate the error to consumers of `outputStream`.
|
|
52
|
+
*
|
|
53
|
+
* @param {Error} reason
|
|
54
|
+
*/
|
|
55
|
+
abort(reason: Error): void;
|
|
56
|
+
/**
|
|
57
|
+
* Add a tile to the styled map package
|
|
58
|
+
*
|
|
59
|
+
* @param {Source} tileData
|
|
60
|
+
* @param {TileInfo} opts
|
|
61
|
+
*/
|
|
62
|
+
addTile(tileData: Source, { z, x, y, sourceId, format }: TileInfo): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Create a write stream for adding tiles to the styled map package
|
|
65
|
+
*
|
|
66
|
+
* @param {object} opts
|
|
67
|
+
* @param {number} [opts.concurrency=16] The number of concurrent writes
|
|
68
|
+
*
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
createTileWriteStream({ concurrency }?: {
|
|
72
|
+
concurrency?: number | undefined;
|
|
73
|
+
}): WritableStream<any>;
|
|
74
|
+
/**
|
|
75
|
+
* Add a sprite to the styled map package
|
|
76
|
+
*
|
|
77
|
+
* @param {object} options
|
|
78
|
+
* @param {Source} options.json
|
|
79
|
+
* @param {Source} options.png
|
|
80
|
+
* @param {number} [options.pixelRatio]
|
|
81
|
+
* @param {string} [options.id='default']
|
|
82
|
+
* @returns {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
addSprite({ json, png, pixelRatio, id }: {
|
|
85
|
+
json: Source;
|
|
86
|
+
png: Source;
|
|
87
|
+
pixelRatio?: number | undefined;
|
|
88
|
+
id?: string | undefined;
|
|
89
|
+
}): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Add glyphs to the styled map package
|
|
92
|
+
*
|
|
93
|
+
* @param {Source} glyphData
|
|
94
|
+
* @param {GlyphInfo} glyphInfo
|
|
95
|
+
* @returns {Promise<void>}
|
|
96
|
+
*/
|
|
97
|
+
addGlyphs(glyphData: Source, { font: fontName, range }: GlyphInfo): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Create a write stream for adding glyphs to the styled map package
|
|
100
|
+
*
|
|
101
|
+
* @param {object} opts
|
|
102
|
+
* @param {number} [opts.concurrency=16] The number of concurrent writes
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
createGlyphWriteStream({ concurrency }?: {
|
|
106
|
+
concurrency?: number | undefined;
|
|
107
|
+
}): WritableStream<any>;
|
|
108
|
+
/**
|
|
109
|
+
* Finalize the styled map package and write the style to the archive.
|
|
110
|
+
* This method must be called to complete the archive.
|
|
111
|
+
* You must wait for your destination write stream to 'finish' before using the output.
|
|
112
|
+
*/
|
|
113
|
+
finish(): Promise<void>;
|
|
114
|
+
#private;
|
|
115
|
+
}
|
|
116
|
+
type Source = string | Uint8Array | ReadableStream;
|
|
117
|
+
type GlyphRange = `${number}-${number}`;
|
|
118
|
+
type TileFormat = "png" | "mvt" | "jpg" | "webp";
|
|
119
|
+
type SourceInfo = {
|
|
120
|
+
source: SMPSource;
|
|
121
|
+
encodedSourceId: string;
|
|
122
|
+
format?: TileFormat | undefined;
|
|
123
|
+
};
|
|
124
|
+
type TileInfo = {
|
|
125
|
+
z: number;
|
|
126
|
+
x: number;
|
|
127
|
+
y: number;
|
|
128
|
+
sourceId: string;
|
|
129
|
+
format?: TileFormat | undefined;
|
|
130
|
+
};
|
|
131
|
+
type GlyphInfo = {
|
|
132
|
+
font: string;
|
|
133
|
+
range: GlyphRange;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
type TransformInlinedSource<T extends SourceSpecification> = T extends GeoJSONSourceSpecification ? OmitUnion<T, 'data'> & {
|
|
137
|
+
data: GeoJSON;
|
|
138
|
+
} : T extends VectorSourceSpecification | RasterSourceSpecification | RasterDEMSourceSpecification ? SetRequired<OmitUnion<T, 'url'>, 'tiles'> : T;
|
|
139
|
+
/**
|
|
140
|
+
* This is a slightly stricter version of SourceSpecification that requires
|
|
141
|
+
* sources to be inlined (e.g. no urls to TileJSON or GeoJSON files).
|
|
142
|
+
*/
|
|
143
|
+
type InlinedSource = TransformInlinedSource<SourceSpecification>;
|
|
144
|
+
type SupportedInlinedSource = Extract<InlinedSource, {
|
|
145
|
+
type: (typeof SUPPORTED_SOURCE_TYPES)[number];
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* This is a slightly stricter version of StyleSpecification that requires
|
|
149
|
+
* sources to be inlined (e.g. no urls to TileJSON or GeoJSON files).
|
|
150
|
+
*/
|
|
151
|
+
type StyleInlinedSources = Omit<StyleSpecification, 'sources'> & {
|
|
152
|
+
sources: {
|
|
153
|
+
[_: string]: InlinedSource;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
type SMPSource = TransformSMPInputSource<SupportedInlinedSource>;
|
|
157
|
+
/**
|
|
158
|
+
* This is a slightly stricter version of StyleSpecification that is provided in
|
|
159
|
+
* a Styled Map Package. Tile sources must have tile URLs inlined (they cannot
|
|
160
|
+
* refer to a TileJSON url), and they must have bounds, minzoom, and maxzoom.
|
|
161
|
+
* GeoJSON sources must have inlined GeoJSON (not a URL to a GeoJSON file).
|
|
162
|
+
*/
|
|
163
|
+
type SMPStyle = TransformSMPStyle<StyleSpecification>;
|
|
164
|
+
type TransformSMPInputSource<T extends SupportedInlinedSource> = T extends GeoJSONSourceSpecification ? T & {
|
|
165
|
+
data: {
|
|
166
|
+
bbox: BBox;
|
|
167
|
+
};
|
|
168
|
+
} : T extends RasterSourceSpecification | VectorSourceSpecification ? SetRequired<T, 'bounds' | 'minzoom' | 'maxzoom'> : T;
|
|
169
|
+
type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
170
|
+
metadata: {
|
|
171
|
+
'smp:bounds': [number, number, number, number];
|
|
172
|
+
'smp:maxzoom': 0;
|
|
173
|
+
'smp:sourceFolders': {
|
|
174
|
+
[_: string]: string;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
sources: {
|
|
178
|
+
[_: string]: SMPSource;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
type DownloadStream = ReadableStream<Uint8Array>;
|
|
182
|
+
type OmitUnion<T, K extends keyof any> = T extends unknown ? Omit<T, K> : never;
|
|
183
|
+
|
|
184
|
+
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { StyleSpecification, SourceSpecification, GeoJSONSourceSpecification, VectorSourceSpecification, RasterSourceSpecification, RasterDEMSourceSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
2
|
+
import { GeoJSON, BBox } from 'geojson';
|
|
3
|
+
import { SetRequired } from 'type-fest';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
|
|
6
|
+
/** @typedef {string | Uint8Array | ReadableStream } Source */
|
|
7
|
+
/** @typedef {`${number}-${number}`} GlyphRange */
|
|
8
|
+
/** @typedef {'png' | 'mvt' | 'jpg' | 'webp'} TileFormat */
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {object} SourceInfo
|
|
11
|
+
* @property {import('./types.js').SMPSource} source
|
|
12
|
+
* @property {string} encodedSourceId
|
|
13
|
+
* @property {TileFormat} [format]
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} TileInfo
|
|
17
|
+
* @property {number} z
|
|
18
|
+
* @property {number} x
|
|
19
|
+
* @property {number} y
|
|
20
|
+
* @property {string} sourceId
|
|
21
|
+
* @property {TileFormat} [format]
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} GlyphInfo
|
|
25
|
+
* @property {string} font
|
|
26
|
+
* @property {GlyphRange} range
|
|
27
|
+
*/
|
|
28
|
+
/** @import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec' */
|
|
29
|
+
/** @import { InputSource, SMPSource } from './types.js' */
|
|
30
|
+
declare const SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
31
|
+
/**
|
|
32
|
+
* Write a styled map package to a stream. Stream `writer.outputStream` to a
|
|
33
|
+
* destination, e.g. `fs.createWriteStream('my-map.styledmap')`. You must call
|
|
34
|
+
* `witer.finish()` and then wait for your writable stream to `finish` before
|
|
35
|
+
* using the output.
|
|
36
|
+
*/
|
|
37
|
+
declare class Writer extends EventEmitter<[never]> {
|
|
38
|
+
static SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
39
|
+
/**
|
|
40
|
+
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
41
|
+
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
42
|
+
* this is typed as `any` and validated internally)
|
|
43
|
+
*/
|
|
44
|
+
constructor(style: any);
|
|
45
|
+
/**
|
|
46
|
+
* @returns {ReadableStream<Uint8Array>} Readable stream of the styled map package
|
|
47
|
+
*/
|
|
48
|
+
get outputStream(): ReadableStream<Uint8Array>;
|
|
49
|
+
/**
|
|
50
|
+
* Abort the output stream with an error. Call this if an error occurs during
|
|
51
|
+
* writing to propagate the error to consumers of `outputStream`.
|
|
52
|
+
*
|
|
53
|
+
* @param {Error} reason
|
|
54
|
+
*/
|
|
55
|
+
abort(reason: Error): void;
|
|
56
|
+
/**
|
|
57
|
+
* Add a tile to the styled map package
|
|
58
|
+
*
|
|
59
|
+
* @param {Source} tileData
|
|
60
|
+
* @param {TileInfo} opts
|
|
61
|
+
*/
|
|
62
|
+
addTile(tileData: Source, { z, x, y, sourceId, format }: TileInfo): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Create a write stream for adding tiles to the styled map package
|
|
65
|
+
*
|
|
66
|
+
* @param {object} opts
|
|
67
|
+
* @param {number} [opts.concurrency=16] The number of concurrent writes
|
|
68
|
+
*
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
createTileWriteStream({ concurrency }?: {
|
|
72
|
+
concurrency?: number | undefined;
|
|
73
|
+
}): WritableStream<any>;
|
|
74
|
+
/**
|
|
75
|
+
* Add a sprite to the styled map package
|
|
76
|
+
*
|
|
77
|
+
* @param {object} options
|
|
78
|
+
* @param {Source} options.json
|
|
79
|
+
* @param {Source} options.png
|
|
80
|
+
* @param {number} [options.pixelRatio]
|
|
81
|
+
* @param {string} [options.id='default']
|
|
82
|
+
* @returns {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
addSprite({ json, png, pixelRatio, id }: {
|
|
85
|
+
json: Source;
|
|
86
|
+
png: Source;
|
|
87
|
+
pixelRatio?: number | undefined;
|
|
88
|
+
id?: string | undefined;
|
|
89
|
+
}): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Add glyphs to the styled map package
|
|
92
|
+
*
|
|
93
|
+
* @param {Source} glyphData
|
|
94
|
+
* @param {GlyphInfo} glyphInfo
|
|
95
|
+
* @returns {Promise<void>}
|
|
96
|
+
*/
|
|
97
|
+
addGlyphs(glyphData: Source, { font: fontName, range }: GlyphInfo): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Create a write stream for adding glyphs to the styled map package
|
|
100
|
+
*
|
|
101
|
+
* @param {object} opts
|
|
102
|
+
* @param {number} [opts.concurrency=16] The number of concurrent writes
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
createGlyphWriteStream({ concurrency }?: {
|
|
106
|
+
concurrency?: number | undefined;
|
|
107
|
+
}): WritableStream<any>;
|
|
108
|
+
/**
|
|
109
|
+
* Finalize the styled map package and write the style to the archive.
|
|
110
|
+
* This method must be called to complete the archive.
|
|
111
|
+
* You must wait for your destination write stream to 'finish' before using the output.
|
|
112
|
+
*/
|
|
113
|
+
finish(): Promise<void>;
|
|
114
|
+
#private;
|
|
115
|
+
}
|
|
116
|
+
type Source = string | Uint8Array | ReadableStream;
|
|
117
|
+
type GlyphRange = `${number}-${number}`;
|
|
118
|
+
type TileFormat = "png" | "mvt" | "jpg" | "webp";
|
|
119
|
+
type SourceInfo = {
|
|
120
|
+
source: SMPSource;
|
|
121
|
+
encodedSourceId: string;
|
|
122
|
+
format?: TileFormat | undefined;
|
|
123
|
+
};
|
|
124
|
+
type TileInfo = {
|
|
125
|
+
z: number;
|
|
126
|
+
x: number;
|
|
127
|
+
y: number;
|
|
128
|
+
sourceId: string;
|
|
129
|
+
format?: TileFormat | undefined;
|
|
130
|
+
};
|
|
131
|
+
type GlyphInfo = {
|
|
132
|
+
font: string;
|
|
133
|
+
range: GlyphRange;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
type TransformInlinedSource<T extends SourceSpecification> = T extends GeoJSONSourceSpecification ? OmitUnion<T, 'data'> & {
|
|
137
|
+
data: GeoJSON;
|
|
138
|
+
} : T extends VectorSourceSpecification | RasterSourceSpecification | RasterDEMSourceSpecification ? SetRequired<OmitUnion<T, 'url'>, 'tiles'> : T;
|
|
139
|
+
/**
|
|
140
|
+
* This is a slightly stricter version of SourceSpecification that requires
|
|
141
|
+
* sources to be inlined (e.g. no urls to TileJSON or GeoJSON files).
|
|
142
|
+
*/
|
|
143
|
+
type InlinedSource = TransformInlinedSource<SourceSpecification>;
|
|
144
|
+
type SupportedInlinedSource = Extract<InlinedSource, {
|
|
145
|
+
type: (typeof SUPPORTED_SOURCE_TYPES)[number];
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* This is a slightly stricter version of StyleSpecification that requires
|
|
149
|
+
* sources to be inlined (e.g. no urls to TileJSON or GeoJSON files).
|
|
150
|
+
*/
|
|
151
|
+
type StyleInlinedSources = Omit<StyleSpecification, 'sources'> & {
|
|
152
|
+
sources: {
|
|
153
|
+
[_: string]: InlinedSource;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
type SMPSource = TransformSMPInputSource<SupportedInlinedSource>;
|
|
157
|
+
/**
|
|
158
|
+
* This is a slightly stricter version of StyleSpecification that is provided in
|
|
159
|
+
* a Styled Map Package. Tile sources must have tile URLs inlined (they cannot
|
|
160
|
+
* refer to a TileJSON url), and they must have bounds, minzoom, and maxzoom.
|
|
161
|
+
* GeoJSON sources must have inlined GeoJSON (not a URL to a GeoJSON file).
|
|
162
|
+
*/
|
|
163
|
+
type SMPStyle = TransformSMPStyle<StyleSpecification>;
|
|
164
|
+
type TransformSMPInputSource<T extends SupportedInlinedSource> = T extends GeoJSONSourceSpecification ? T & {
|
|
165
|
+
data: {
|
|
166
|
+
bbox: BBox;
|
|
167
|
+
};
|
|
168
|
+
} : T extends RasterSourceSpecification | VectorSourceSpecification ? SetRequired<T, 'bounds' | 'minzoom' | 'maxzoom'> : T;
|
|
169
|
+
type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
170
|
+
metadata: {
|
|
171
|
+
'smp:bounds': [number, number, number, number];
|
|
172
|
+
'smp:maxzoom': 0;
|
|
173
|
+
'smp:sourceFolders': {
|
|
174
|
+
[_: string]: string;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
sources: {
|
|
178
|
+
[_: string]: SMPSource;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
type DownloadStream = ReadableStream<Uint8Array>;
|
|
182
|
+
type OmitUnion<T, K extends keyof any> = T extends unknown ? Omit<T, K> : never;
|
|
183
|
+
|
|
184
|
+
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var errors_exports = {};
|
|
20
|
+
__export(errors_exports, {
|
|
21
|
+
ENOENT: () => ENOENT,
|
|
22
|
+
isFileNotThereError: () => isFileNotThereError
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(errors_exports);
|
|
25
|
+
class ENOENT extends Error {
|
|
26
|
+
code = "ENOENT";
|
|
27
|
+
/** @param {string} path */
|
|
28
|
+
constructor(path) {
|
|
29
|
+
const message = `ENOENT: no such file or directory, open '${path}'`;
|
|
30
|
+
super(message);
|
|
31
|
+
this.path = path;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isFileNotThereError(error) {
|
|
35
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "EPERM");
|
|
36
|
+
}
|
|
37
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
38
|
+
0 && (module.exports = {
|
|
39
|
+
ENOENT,
|
|
40
|
+
isFileNotThereError
|
|
41
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if the error if because a file is not found. On Windows, some
|
|
3
|
+
* operations like fs.watch() throw an EPERM error rather than ENOENT.
|
|
4
|
+
*
|
|
5
|
+
* @param {unknown} error
|
|
6
|
+
* @returns {error is Error & { code: 'ENOENT' | 'EPERM' }}
|
|
7
|
+
*/
|
|
8
|
+
declare function isFileNotThereError(error: unknown): error is Error & {
|
|
9
|
+
code: "ENOENT" | "EPERM";
|
|
10
|
+
};
|
|
11
|
+
declare class ENOENT extends Error {
|
|
12
|
+
/** @param {string} path */
|
|
13
|
+
constructor(path: string);
|
|
14
|
+
code: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { ENOENT, isFileNotThereError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if the error if because a file is not found. On Windows, some
|
|
3
|
+
* operations like fs.watch() throw an EPERM error rather than ENOENT.
|
|
4
|
+
*
|
|
5
|
+
* @param {unknown} error
|
|
6
|
+
* @returns {error is Error & { code: 'ENOENT' | 'EPERM' }}
|
|
7
|
+
*/
|
|
8
|
+
declare function isFileNotThereError(error: unknown): error is Error & {
|
|
9
|
+
code: "ENOENT" | "EPERM";
|
|
10
|
+
};
|
|
11
|
+
declare class ENOENT extends Error {
|
|
12
|
+
/** @param {string} path */
|
|
13
|
+
constructor(path: string);
|
|
14
|
+
code: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { ENOENT, isFileNotThereError };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class ENOENT extends Error {
|
|
2
|
+
code = "ENOENT";
|
|
3
|
+
/** @param {string} path */
|
|
4
|
+
constructor(path) {
|
|
5
|
+
const message = `ENOENT: no such file or directory, open '${path}'`;
|
|
6
|
+
super(message);
|
|
7
|
+
this.path = path;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function isFileNotThereError(error) {
|
|
11
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "EPERM");
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
ENOENT,
|
|
15
|
+
isFileNotThereError
|
|
16
|
+
};
|