styled-map-package 2.2.1 → 4.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/bin/smp-download.js +3 -3
- package/bin/smp-mbtiles.js +1 -1
- package/bin/smp-view.js +15 -4
- package/dist/download.cjs +101 -0
- package/dist/download.d.cts +65 -0
- package/dist/{lib/download.d.ts → download.d.ts} +22 -6
- package/dist/download.js +77 -0
- package/dist/from-mbtiles.cjs +91 -0
- package/dist/from-mbtiles.d.cts +17 -0
- package/dist/from-mbtiles.d.ts +17 -0
- package/dist/from-mbtiles.js +57 -0
- package/dist/index.cjs +49 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +18 -0
- package/dist/reader-watch.cjs +135 -0
- package/dist/reader-watch.d.cts +24 -0
- package/dist/reader-watch.d.ts +24 -0
- package/dist/reader-watch.js +101 -0
- package/dist/reader.cjs +167 -0
- package/dist/reader.d.cts +62 -0
- package/dist/{lib/reader.d.ts → reader.d.ts} +16 -5
- package/dist/reader.js +138 -0
- package/dist/reporters.cjs +122 -0
- package/dist/reporters.d.cts +10 -0
- package/dist/{lib/reporters.d.ts → reporters.d.ts} +5 -2
- package/dist/reporters.js +88 -0
- package/dist/server.cjs +79 -0
- package/dist/server.d.cts +48 -0
- package/dist/server.d.ts +48 -0
- package/dist/server.js +55 -0
- package/dist/style-downloader.cjs +312 -0
- package/dist/style-downloader.d.cts +120 -0
- package/dist/{lib/style-downloader.d.ts → style-downloader.d.ts} +23 -13
- package/dist/style-downloader.js +288 -0
- package/dist/tile-downloader.cjs +158 -0
- package/dist/tile-downloader.d.cts +84 -0
- package/dist/{lib/tile-downloader.d.ts → tile-downloader.d.ts} +22 -10
- package/dist/tile-downloader.js +126 -0
- package/dist/{lib/writer.d.ts → types-B4Xn1F9K.d.cts} +74 -14
- package/dist/types-B4Xn1F9K.d.ts +189 -0
- package/dist/utils/errors.cjs +41 -0
- package/dist/utils/errors.d.cts +18 -0
- package/dist/{lib/utils → utils}/errors.d.ts +4 -2
- package/dist/utils/errors.js +16 -0
- package/dist/utils/fetch.cjs +96 -0
- package/dist/utils/fetch.d.cts +51 -0
- package/dist/{lib/utils → utils}/fetch.d.ts +10 -4
- package/dist/utils/fetch.js +62 -0
- package/dist/utils/file-formats.cjs +98 -0
- package/dist/utils/file-formats.d.cts +35 -0
- package/dist/{lib/utils → utils}/file-formats.d.ts +13 -3
- package/dist/utils/file-formats.js +62 -0
- package/dist/utils/geo.cjs +84 -0
- package/dist/utils/geo.d.cts +46 -0
- package/dist/{lib/utils → utils}/geo.d.ts +8 -6
- 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/{lib/utils/misc.js → dist/utils/misc.d.cts} +5 -9
- package/dist/{lib/utils → utils}/misc.d.ts +5 -3
- package/dist/utils/misc.js +13 -0
- package/dist/utils/streams.cjs +130 -0
- package/dist/utils/streams.d.cts +73 -0
- package/dist/{lib/utils → utils}/streams.d.ts +14 -10
- package/dist/utils/streams.js +103 -0
- package/dist/utils/style.cjs +126 -0
- package/dist/utils/style.d.cts +69 -0
- package/dist/{lib/utils → utils}/style.d.ts +19 -9
- package/dist/utils/style.js +98 -0
- package/dist/utils/templates.cjs +114 -0
- package/dist/utils/templates.d.cts +78 -0
- package/dist/{lib/utils → utils}/templates.d.ts +24 -14
- package/dist/utils/templates.js +79 -0
- package/dist/writer.cjs +401 -0
- package/dist/writer.d.cts +7 -0
- package/dist/writer.d.ts +7 -0
- package/dist/writer.js +374 -0
- package/package.json +107 -41
- package/dist/lib/from-mbtiles.d.ts +0 -13
- package/dist/lib/index.d.ts +0 -10
- package/dist/lib/reader-watch.d.ts +0 -13
- package/dist/lib/server.d.ts +0 -15
- package/dist/lib/types.d.ts +0 -64
- package/dist/lib/utils/mapbox.d.ts +0 -41
- package/lib/download.js +0 -114
- package/lib/from-mbtiles.js +0 -83
- package/lib/index.js +0 -11
- package/lib/reader-watch.js +0 -133
- package/lib/reader.js +0 -165
- package/lib/reporters.js +0 -92
- package/lib/server.js +0 -81
- package/lib/style-downloader.js +0 -363
- package/lib/tile-downloader.js +0 -188
- package/lib/types.ts +0 -104
- package/lib/utils/errors.js +0 -24
- package/lib/utils/fetch.js +0 -100
- package/lib/utils/file-formats.js +0 -85
- package/lib/utils/geo.js +0 -87
- package/lib/utils/mapbox.js +0 -155
- package/lib/utils/streams.js +0 -165
- package/lib/utils/style.js +0 -174
- package/lib/utils/templates.js +0 -136
- package/lib/writer.js +0 -478
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as stream from 'stream';
|
|
2
|
+
import { ProgressCallback } from './streams.cjs';
|
|
3
|
+
import 'readable-stream';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} DownloadResponse
|
|
7
|
+
* @property {import('stream').Readable} body Node ReadableStream of the response body
|
|
8
|
+
* @property {string | null} mimeType Content mime-type (from http content-type header)
|
|
9
|
+
* @property {number | null} contentLength Content length in bytes (from http content-length header)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A wrapper for fetch that limits the number of concurrent downloads.
|
|
13
|
+
*/
|
|
14
|
+
declare class FetchQueue {
|
|
15
|
+
/** @param {number} concurrency */
|
|
16
|
+
constructor(concurrency: number);
|
|
17
|
+
get activeCount(): number;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch a URL, limiting the number of concurrent downloads. Resolves with a
|
|
20
|
+
* `DownloadResponse`, which is a parsed from the Fetch `Response` objects,
|
|
21
|
+
* with `body` as a Node readable stream, and the MIME type and content length
|
|
22
|
+
* of the response.
|
|
23
|
+
*
|
|
24
|
+
* NB: The response body stream must be consumed to the end, otherwise the
|
|
25
|
+
* queue will never be emptied.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} url
|
|
28
|
+
* @param {{ onprogress?: import('./streams.js').ProgressCallback }} opts
|
|
29
|
+
* @returns {Promise<DownloadResponse>}
|
|
30
|
+
*/
|
|
31
|
+
fetch(url: string, { onprogress }?: {
|
|
32
|
+
onprogress?: ProgressCallback;
|
|
33
|
+
}): Promise<DownloadResponse>;
|
|
34
|
+
#private;
|
|
35
|
+
}
|
|
36
|
+
type DownloadResponse = {
|
|
37
|
+
/**
|
|
38
|
+
* Node ReadableStream of the response body
|
|
39
|
+
*/
|
|
40
|
+
body: stream.Readable;
|
|
41
|
+
/**
|
|
42
|
+
* Content mime-type (from http content-type header)
|
|
43
|
+
*/
|
|
44
|
+
mimeType: string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Content length in bytes (from http content-length header)
|
|
47
|
+
*/
|
|
48
|
+
contentLength: number | null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { type DownloadResponse, FetchQueue };
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import * as stream from 'stream';
|
|
2
|
+
import { ProgressCallback } from './streams.js';
|
|
3
|
+
import 'readable-stream';
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* @typedef {object} DownloadResponse
|
|
3
7
|
* @property {import('stream').Readable} body Node ReadableStream of the response body
|
|
@@ -7,7 +11,7 @@
|
|
|
7
11
|
/**
|
|
8
12
|
* A wrapper for fetch that limits the number of concurrent downloads.
|
|
9
13
|
*/
|
|
10
|
-
|
|
14
|
+
declare class FetchQueue {
|
|
11
15
|
/** @param {number} concurrency */
|
|
12
16
|
constructor(concurrency: number);
|
|
13
17
|
get activeCount(): number;
|
|
@@ -25,15 +29,15 @@ export class FetchQueue {
|
|
|
25
29
|
* @returns {Promise<DownloadResponse>}
|
|
26
30
|
*/
|
|
27
31
|
fetch(url: string, { onprogress }?: {
|
|
28
|
-
onprogress?:
|
|
32
|
+
onprogress?: ProgressCallback;
|
|
29
33
|
}): Promise<DownloadResponse>;
|
|
30
34
|
#private;
|
|
31
35
|
}
|
|
32
|
-
|
|
36
|
+
type DownloadResponse = {
|
|
33
37
|
/**
|
|
34
38
|
* Node ReadableStream of the response body
|
|
35
39
|
*/
|
|
36
|
-
body:
|
|
40
|
+
body: stream.Readable;
|
|
37
41
|
/**
|
|
38
42
|
* Content mime-type (from http content-type header)
|
|
39
43
|
*/
|
|
@@ -43,3 +47,5 @@ export type DownloadResponse = {
|
|
|
43
47
|
*/
|
|
44
48
|
contentLength: number | null;
|
|
45
49
|
};
|
|
50
|
+
|
|
51
|
+
export { type DownloadResponse, FetchQueue };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import ky from "ky";
|
|
2
|
+
import { pEvent } from "p-event";
|
|
3
|
+
import pLimit from "p-limit";
|
|
4
|
+
import { fromWebReadableStream, ProgressStream } from "./streams.js";
|
|
5
|
+
class FetchQueue {
|
|
6
|
+
/** @type {import('p-limit').LimitFunction} */
|
|
7
|
+
#limit;
|
|
8
|
+
/** @param {number} concurrency */
|
|
9
|
+
constructor(concurrency) {
|
|
10
|
+
this.#limit = pLimit(concurrency);
|
|
11
|
+
}
|
|
12
|
+
get activeCount() {
|
|
13
|
+
return this.#limit.activeCount;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetch a URL, limiting the number of concurrent downloads. Resolves with a
|
|
17
|
+
* `DownloadResponse`, which is a parsed from the Fetch `Response` objects,
|
|
18
|
+
* with `body` as a Node readable stream, and the MIME type and content length
|
|
19
|
+
* of the response.
|
|
20
|
+
*
|
|
21
|
+
* NB: The response body stream must be consumed to the end, otherwise the
|
|
22
|
+
* queue will never be emptied.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} url
|
|
25
|
+
* @param {{ onprogress?: import('./streams.js').ProgressCallback }} opts
|
|
26
|
+
* @returns {Promise<DownloadResponse>}
|
|
27
|
+
*/
|
|
28
|
+
fetch(url, { onprogress } = {}) {
|
|
29
|
+
return new Promise((resolveResponse, rejectResponse) => {
|
|
30
|
+
this.#limit(fetchStream, {
|
|
31
|
+
url,
|
|
32
|
+
onresponse: resolveResponse,
|
|
33
|
+
onerror: rejectResponse,
|
|
34
|
+
onprogress
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function fetchStream({ url, onresponse, onerror, onprogress }) {
|
|
40
|
+
try {
|
|
41
|
+
const response = await ky(url, { retry: 3 });
|
|
42
|
+
if (!response.body) {
|
|
43
|
+
throw new Error("No body in response");
|
|
44
|
+
}
|
|
45
|
+
const body = fromWebReadableStream(response.body);
|
|
46
|
+
const contentType = response.headers.get("content-type");
|
|
47
|
+
const mimeType = typeof contentType === "string" ? contentType.split(";")[0] : null;
|
|
48
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
49
|
+
const contentLength = contentLengthHeader === null ? null : parseInt(contentLengthHeader, 10);
|
|
50
|
+
onresponse({
|
|
51
|
+
body: onprogress ? body.pipe(new ProgressStream({ onprogress })) : body,
|
|
52
|
+
mimeType,
|
|
53
|
+
contentLength
|
|
54
|
+
});
|
|
55
|
+
await pEvent(body, "end");
|
|
56
|
+
} catch (err) {
|
|
57
|
+
onerror(err instanceof Error ? err : new Error("Unknown error"));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
FetchQueue
|
|
62
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var file_formats_exports = {};
|
|
30
|
+
__export(file_formats_exports, {
|
|
31
|
+
getFormatFromMimeType: () => getFormatFromMimeType,
|
|
32
|
+
getTileFormatFromBuffer: () => getTileFormatFromBuffer,
|
|
33
|
+
getTileFormatFromStream: () => getTileFormatFromStream
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(file_formats_exports);
|
|
36
|
+
var import_buffer_peek_stream = __toESM(require("buffer-peek-stream"), 1);
|
|
37
|
+
var import_misc = require('./misc.cjs');
|
|
38
|
+
const peek = import_buffer_peek_stream.default.promise;
|
|
39
|
+
const MAGIC_BYTES = (
|
|
40
|
+
/** @type {const} */
|
|
41
|
+
{
|
|
42
|
+
png: [137, 80, 78, 71, 13, 10, 26, 10],
|
|
43
|
+
jpg: [255, 216, 255],
|
|
44
|
+
// eslint-disable-next-line no-sparse-arrays
|
|
45
|
+
webp: [82, 73, 70, 70, , , , , 87, 69, 66, 80],
|
|
46
|
+
// Include the compression-type byte, which is always 0x08 (DEFLATE) for gzip
|
|
47
|
+
gz: [31, 139, 8]
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
const MIME_TYPES = (
|
|
51
|
+
/** @type {const} */
|
|
52
|
+
{
|
|
53
|
+
"image/png": "png",
|
|
54
|
+
"image/jpeg": "jpg",
|
|
55
|
+
"image/webp": "webp"
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
const magicByteMap = /* @__PURE__ */ new Map();
|
|
59
|
+
for (const [ext, bytes] of Object.entries(MAGIC_BYTES)) {
|
|
60
|
+
magicByteMap.set(
|
|
61
|
+
bytes[0],
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
ext
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function getTileFormatFromBuffer(buf) {
|
|
67
|
+
const ext = magicByteMap.get(buf[0]);
|
|
68
|
+
if (!ext) {
|
|
69
|
+
throw new Error("Unknown file type");
|
|
70
|
+
}
|
|
71
|
+
const sig = MAGIC_BYTES[ext];
|
|
72
|
+
for (let i = 1; i < sig.length; i++) {
|
|
73
|
+
if (typeof sig[i] !== "undefined" && sig[i] !== buf[i]) {
|
|
74
|
+
throw new Error("Unknown file type");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (ext === "gz") {
|
|
78
|
+
return "mvt";
|
|
79
|
+
}
|
|
80
|
+
return ext;
|
|
81
|
+
}
|
|
82
|
+
async function getTileFormatFromStream(tileData) {
|
|
83
|
+
const [peekedData, outputStream] = await peek(tileData, 16 * 1024);
|
|
84
|
+
tileData = outputStream;
|
|
85
|
+
const format = getTileFormatFromBuffer(peekedData);
|
|
86
|
+
return [format, outputStream];
|
|
87
|
+
}
|
|
88
|
+
function getFormatFromMimeType(mimeType) {
|
|
89
|
+
if (mimeType.startsWith("application/")) return "mvt";
|
|
90
|
+
if ((0, import_misc.hasOwn)(MIME_TYPES, mimeType)) return MIME_TYPES[mimeType];
|
|
91
|
+
throw new Error("Unsupported MIME type " + mimeType);
|
|
92
|
+
}
|
|
93
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
94
|
+
0 && (module.exports = {
|
|
95
|
+
getFormatFromMimeType,
|
|
96
|
+
getTileFormatFromBuffer,
|
|
97
|
+
getTileFormatFromStream
|
|
98
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as stream from 'stream';
|
|
2
|
+
import { c as TileFormat } from '../types-B4Xn1F9K.cjs';
|
|
3
|
+
import '@maplibre/maplibre-gl-style-spec';
|
|
4
|
+
import 'geojson';
|
|
5
|
+
import 'type-fest';
|
|
6
|
+
import 'readable-stream';
|
|
7
|
+
import 'events';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* For a given buffer, determine the tile format based on the magic bytes.
|
|
11
|
+
* Will throw for unknown file types.
|
|
12
|
+
* Smaller and faster version of magic-bytes.js due to the limited use case.
|
|
13
|
+
*
|
|
14
|
+
* @param {Buffer | Uint8Array} buf
|
|
15
|
+
* @returns {import("../writer.js").TileFormat}
|
|
16
|
+
*/
|
|
17
|
+
declare function getTileFormatFromBuffer(buf: Buffer | Uint8Array): TileFormat;
|
|
18
|
+
/**
|
|
19
|
+
* Determine the tile format from either a readable stream, buffer or Uint8Array
|
|
20
|
+
* from the magic bytes at the start of the file. Used if data is served without
|
|
21
|
+
* a content-type header.
|
|
22
|
+
*
|
|
23
|
+
* @param {import('stream').Readable} tileData
|
|
24
|
+
* @returns {Promise<[import("../writer.js").TileFormat, import('stream').Readable]>}
|
|
25
|
+
*/
|
|
26
|
+
declare function getTileFormatFromStream(tileData: stream.Readable): Promise<[TileFormat, stream.Readable]>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the tile format from a MIME type. Throws for unsupported types.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} mimeType
|
|
31
|
+
* @returns {import("../writer.js").TileFormat}
|
|
32
|
+
*/
|
|
33
|
+
declare function getFormatFromMimeType(mimeType: string): TileFormat;
|
|
34
|
+
|
|
35
|
+
export { getFormatFromMimeType, getTileFormatFromBuffer, getTileFormatFromStream };
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import * as stream from 'stream';
|
|
2
|
+
import { c as TileFormat } from '../types-B4Xn1F9K.js';
|
|
3
|
+
import '@maplibre/maplibre-gl-style-spec';
|
|
4
|
+
import 'geojson';
|
|
5
|
+
import 'type-fest';
|
|
6
|
+
import 'readable-stream';
|
|
7
|
+
import 'events';
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* For a given buffer, determine the tile format based on the magic bytes.
|
|
3
11
|
* Will throw for unknown file types.
|
|
@@ -6,7 +14,7 @@
|
|
|
6
14
|
* @param {Buffer | Uint8Array} buf
|
|
7
15
|
* @returns {import("../writer.js").TileFormat}
|
|
8
16
|
*/
|
|
9
|
-
|
|
17
|
+
declare function getTileFormatFromBuffer(buf: Buffer | Uint8Array): TileFormat;
|
|
10
18
|
/**
|
|
11
19
|
* Determine the tile format from either a readable stream, buffer or Uint8Array
|
|
12
20
|
* from the magic bytes at the start of the file. Used if data is served without
|
|
@@ -15,11 +23,13 @@ export function getTileFormatFromBuffer(buf: Buffer | Uint8Array): import("../wr
|
|
|
15
23
|
* @param {import('stream').Readable} tileData
|
|
16
24
|
* @returns {Promise<[import("../writer.js").TileFormat, import('stream').Readable]>}
|
|
17
25
|
*/
|
|
18
|
-
|
|
26
|
+
declare function getTileFormatFromStream(tileData: stream.Readable): Promise<[TileFormat, stream.Readable]>;
|
|
19
27
|
/**
|
|
20
28
|
* Get the tile format from a MIME type. Throws for unsupported types.
|
|
21
29
|
*
|
|
22
30
|
* @param {string} mimeType
|
|
23
31
|
* @returns {import("../writer.js").TileFormat}
|
|
24
32
|
*/
|
|
25
|
-
|
|
33
|
+
declare function getFormatFromMimeType(mimeType: string): TileFormat;
|
|
34
|
+
|
|
35
|
+
export { getFormatFromMimeType, getTileFormatFromBuffer, getTileFormatFromStream };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import BufferPeerStream from "buffer-peek-stream";
|
|
2
|
+
import { hasOwn } from "./misc.js";
|
|
3
|
+
const peek = BufferPeerStream.promise;
|
|
4
|
+
const MAGIC_BYTES = (
|
|
5
|
+
/** @type {const} */
|
|
6
|
+
{
|
|
7
|
+
png: [137, 80, 78, 71, 13, 10, 26, 10],
|
|
8
|
+
jpg: [255, 216, 255],
|
|
9
|
+
// eslint-disable-next-line no-sparse-arrays
|
|
10
|
+
webp: [82, 73, 70, 70, , , , , 87, 69, 66, 80],
|
|
11
|
+
// Include the compression-type byte, which is always 0x08 (DEFLATE) for gzip
|
|
12
|
+
gz: [31, 139, 8]
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
const MIME_TYPES = (
|
|
16
|
+
/** @type {const} */
|
|
17
|
+
{
|
|
18
|
+
"image/png": "png",
|
|
19
|
+
"image/jpeg": "jpg",
|
|
20
|
+
"image/webp": "webp"
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
const magicByteMap = /* @__PURE__ */ new Map();
|
|
24
|
+
for (const [ext, bytes] of Object.entries(MAGIC_BYTES)) {
|
|
25
|
+
magicByteMap.set(
|
|
26
|
+
bytes[0],
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
ext
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function getTileFormatFromBuffer(buf) {
|
|
32
|
+
const ext = magicByteMap.get(buf[0]);
|
|
33
|
+
if (!ext) {
|
|
34
|
+
throw new Error("Unknown file type");
|
|
35
|
+
}
|
|
36
|
+
const sig = MAGIC_BYTES[ext];
|
|
37
|
+
for (let i = 1; i < sig.length; i++) {
|
|
38
|
+
if (typeof sig[i] !== "undefined" && sig[i] !== buf[i]) {
|
|
39
|
+
throw new Error("Unknown file type");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (ext === "gz") {
|
|
43
|
+
return "mvt";
|
|
44
|
+
}
|
|
45
|
+
return ext;
|
|
46
|
+
}
|
|
47
|
+
async function getTileFormatFromStream(tileData) {
|
|
48
|
+
const [peekedData, outputStream] = await peek(tileData, 16 * 1024);
|
|
49
|
+
tileData = outputStream;
|
|
50
|
+
const format = getTileFormatFromBuffer(peekedData);
|
|
51
|
+
return [format, outputStream];
|
|
52
|
+
}
|
|
53
|
+
function getFormatFromMimeType(mimeType) {
|
|
54
|
+
if (mimeType.startsWith("application/")) return "mvt";
|
|
55
|
+
if (hasOwn(MIME_TYPES, mimeType)) return MIME_TYPES[mimeType];
|
|
56
|
+
throw new Error("Unsupported MIME type " + mimeType);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
getFormatFromMimeType,
|
|
60
|
+
getTileFormatFromBuffer,
|
|
61
|
+
getTileFormatFromStream
|
|
62
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
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 geo_exports = {};
|
|
20
|
+
__export(geo_exports, {
|
|
21
|
+
MAX_BOUNDS: () => MAX_BOUNDS,
|
|
22
|
+
getQuadkey: () => getQuadkey,
|
|
23
|
+
getTileUrl: () => getTileUrl,
|
|
24
|
+
tileToBBox: () => tileToBBox,
|
|
25
|
+
unionBBox: () => unionBBox
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(geo_exports);
|
|
28
|
+
const r2d = 180 / Math.PI;
|
|
29
|
+
const MAX_BOUNDS = (
|
|
30
|
+
/** @type {BBox} */
|
|
31
|
+
[
|
|
32
|
+
-180,
|
|
33
|
+
-85.051129,
|
|
34
|
+
180,
|
|
35
|
+
85.051129
|
|
36
|
+
]
|
|
37
|
+
);
|
|
38
|
+
function tileToBBox({ x, y, z }) {
|
|
39
|
+
const e = tile2lon({ x: x + 1, z });
|
|
40
|
+
const w = tile2lon({ x, z });
|
|
41
|
+
const s = tile2lat({ y: y + 1, z });
|
|
42
|
+
const n = tile2lat({ y, z });
|
|
43
|
+
return [w, s, e, n];
|
|
44
|
+
}
|
|
45
|
+
function getQuadkey({ x, y, z }) {
|
|
46
|
+
let quadkey = "";
|
|
47
|
+
let mask;
|
|
48
|
+
for (let i = z; i > 0; i--) {
|
|
49
|
+
mask = 1 << i - 1;
|
|
50
|
+
quadkey += (x & mask ? 1 : 0) + (y & mask ? 2 : 0);
|
|
51
|
+
}
|
|
52
|
+
return quadkey;
|
|
53
|
+
}
|
|
54
|
+
function getTileUrl(urls, { x, y, z, scheme = "xyz" }) {
|
|
55
|
+
const bboxEspg3857 = tileToBBox({ x, y: Math.pow(2, z) - y - 1, z });
|
|
56
|
+
const quadkey = getQuadkey({ x, y, z });
|
|
57
|
+
return urls[(x + y) % urls.length].replace("{prefix}", (x % 16).toString(16) + (y % 16).toString(16)).replace(/{z}/g, String(z)).replace(/{x}/g, String(x)).replace(/{y}/g, String(scheme === "tms" ? Math.pow(2, z) - y - 1 : y)).replace("{quadkey}", quadkey).replace("{bbox-epsg-3857}", bboxEspg3857.join(","));
|
|
58
|
+
}
|
|
59
|
+
function unionBBox(bboxes) {
|
|
60
|
+
let [w, s, e, n] = bboxes[0];
|
|
61
|
+
for (let i = 1; i < bboxes.length; i++) {
|
|
62
|
+
const [w1, s1, e1, n1] = bboxes[i];
|
|
63
|
+
w = Math.min(w, w1);
|
|
64
|
+
s = Math.min(s, s1);
|
|
65
|
+
e = Math.max(e, e1);
|
|
66
|
+
n = Math.max(n, n1);
|
|
67
|
+
}
|
|
68
|
+
return [w, s, e, n];
|
|
69
|
+
}
|
|
70
|
+
function tile2lon({ x, z }) {
|
|
71
|
+
return x / Math.pow(2, z) * 360 - 180;
|
|
72
|
+
}
|
|
73
|
+
function tile2lat({ y, z }) {
|
|
74
|
+
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
|
75
|
+
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
|
76
|
+
}
|
|
77
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
78
|
+
0 && (module.exports = {
|
|
79
|
+
MAX_BOUNDS,
|
|
80
|
+
getQuadkey,
|
|
81
|
+
getTileUrl,
|
|
82
|
+
tileToBBox,
|
|
83
|
+
unionBBox
|
|
84
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {[number, number, number, number]} BBox
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Return the bounding box for the given tile.
|
|
6
|
+
*
|
|
7
|
+
* @param {{ x: number, y: number, z: number }} tile
|
|
8
|
+
* @returns {BBox} Bounding Box [w, s, e, n]
|
|
9
|
+
*/
|
|
10
|
+
declare function tileToBBox({ x, y, z }: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
z: number;
|
|
14
|
+
}): BBox;
|
|
15
|
+
/**
|
|
16
|
+
* @param {{ x: number, y: number, z: number }} tile
|
|
17
|
+
*/
|
|
18
|
+
declare function getQuadkey({ x, y, z }: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z: number;
|
|
22
|
+
}): string;
|
|
23
|
+
/**
|
|
24
|
+
* From an array of tile URL templates, get the URL for the given tile.
|
|
25
|
+
*
|
|
26
|
+
* @param {string[]} urls
|
|
27
|
+
* @param {{ x: number, y: number, z: number, scheme?: 'xyz' | 'tms' }} opts
|
|
28
|
+
*/
|
|
29
|
+
declare function getTileUrl(urls: string[], { x, y, z, scheme }: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
z: number;
|
|
33
|
+
scheme?: "xyz" | "tms";
|
|
34
|
+
}): string;
|
|
35
|
+
/**
|
|
36
|
+
* Returns a bbox that is the smallest bounding box that contains all the input bboxes.
|
|
37
|
+
*
|
|
38
|
+
* @param {[BBox, ...BBox[]]} bboxes
|
|
39
|
+
* @returns {BBox} Bounding Box [w, s, e, n]
|
|
40
|
+
*/
|
|
41
|
+
declare function unionBBox(bboxes: [BBox, ...BBox[]]): BBox;
|
|
42
|
+
/** Spherical Mercator max bounds, rounded to 6 decimal places */
|
|
43
|
+
declare const MAX_BOUNDS: BBox;
|
|
44
|
+
type BBox = [number, number, number, number];
|
|
45
|
+
|
|
46
|
+
export { type BBox, MAX_BOUNDS, getQuadkey, getTileUrl, tileToBBox, unionBBox };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @param {{ x: number, y: number, z: number }} tile
|
|
8
8
|
* @returns {BBox} Bounding Box [w, s, e, n]
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
declare function tileToBBox({ x, y, z }: {
|
|
11
11
|
x: number;
|
|
12
12
|
y: number;
|
|
13
13
|
z: number;
|
|
@@ -15,7 +15,7 @@ export function tileToBBox({ x, y, z }: {
|
|
|
15
15
|
/**
|
|
16
16
|
* @param {{ x: number, y: number, z: number }} tile
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
declare function getQuadkey({ x, y, z }: {
|
|
19
19
|
x: number;
|
|
20
20
|
y: number;
|
|
21
21
|
z: number;
|
|
@@ -26,7 +26,7 @@ export function getQuadkey({ x, y, z }: {
|
|
|
26
26
|
* @param {string[]} urls
|
|
27
27
|
* @param {{ x: number, y: number, z: number, scheme?: 'xyz' | 'tms' }} opts
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
declare function getTileUrl(urls: string[], { x, y, z, scheme }: {
|
|
30
30
|
x: number;
|
|
31
31
|
y: number;
|
|
32
32
|
z: number;
|
|
@@ -38,7 +38,9 @@ export function getTileUrl(urls: string[], { x, y, z, scheme }: {
|
|
|
38
38
|
* @param {[BBox, ...BBox[]]} bboxes
|
|
39
39
|
* @returns {BBox} Bounding Box [w, s, e, n]
|
|
40
40
|
*/
|
|
41
|
-
|
|
41
|
+
declare function unionBBox(bboxes: [BBox, ...BBox[]]): BBox;
|
|
42
42
|
/** Spherical Mercator max bounds, rounded to 6 decimal places */
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
declare const MAX_BOUNDS: BBox;
|
|
44
|
+
type BBox = [number, number, number, number];
|
|
45
|
+
|
|
46
|
+
export { type BBox, MAX_BOUNDS, getQuadkey, getTileUrl, tileToBBox, unionBBox };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const r2d = 180 / Math.PI;
|
|
2
|
+
const MAX_BOUNDS = (
|
|
3
|
+
/** @type {BBox} */
|
|
4
|
+
[
|
|
5
|
+
-180,
|
|
6
|
+
-85.051129,
|
|
7
|
+
180,
|
|
8
|
+
85.051129
|
|
9
|
+
]
|
|
10
|
+
);
|
|
11
|
+
function tileToBBox({ x, y, z }) {
|
|
12
|
+
const e = tile2lon({ x: x + 1, z });
|
|
13
|
+
const w = tile2lon({ x, z });
|
|
14
|
+
const s = tile2lat({ y: y + 1, z });
|
|
15
|
+
const n = tile2lat({ y, z });
|
|
16
|
+
return [w, s, e, n];
|
|
17
|
+
}
|
|
18
|
+
function getQuadkey({ x, y, z }) {
|
|
19
|
+
let quadkey = "";
|
|
20
|
+
let mask;
|
|
21
|
+
for (let i = z; i > 0; i--) {
|
|
22
|
+
mask = 1 << i - 1;
|
|
23
|
+
quadkey += (x & mask ? 1 : 0) + (y & mask ? 2 : 0);
|
|
24
|
+
}
|
|
25
|
+
return quadkey;
|
|
26
|
+
}
|
|
27
|
+
function getTileUrl(urls, { x, y, z, scheme = "xyz" }) {
|
|
28
|
+
const bboxEspg3857 = tileToBBox({ x, y: Math.pow(2, z) - y - 1, z });
|
|
29
|
+
const quadkey = getQuadkey({ x, y, z });
|
|
30
|
+
return urls[(x + y) % urls.length].replace("{prefix}", (x % 16).toString(16) + (y % 16).toString(16)).replace(/{z}/g, String(z)).replace(/{x}/g, String(x)).replace(/{y}/g, String(scheme === "tms" ? Math.pow(2, z) - y - 1 : y)).replace("{quadkey}", quadkey).replace("{bbox-epsg-3857}", bboxEspg3857.join(","));
|
|
31
|
+
}
|
|
32
|
+
function unionBBox(bboxes) {
|
|
33
|
+
let [w, s, e, n] = bboxes[0];
|
|
34
|
+
for (let i = 1; i < bboxes.length; i++) {
|
|
35
|
+
const [w1, s1, e1, n1] = bboxes[i];
|
|
36
|
+
w = Math.min(w, w1);
|
|
37
|
+
s = Math.min(s, s1);
|
|
38
|
+
e = Math.max(e, e1);
|
|
39
|
+
n = Math.max(n, n1);
|
|
40
|
+
}
|
|
41
|
+
return [w, s, e, n];
|
|
42
|
+
}
|
|
43
|
+
function tile2lon({ x, z }) {
|
|
44
|
+
return x / Math.pow(2, z) * 360 - 180;
|
|
45
|
+
}
|
|
46
|
+
function tile2lat({ y, z }) {
|
|
47
|
+
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
|
48
|
+
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
MAX_BOUNDS,
|
|
52
|
+
getQuadkey,
|
|
53
|
+
getTileUrl,
|
|
54
|
+
tileToBBox,
|
|
55
|
+
unionBBox
|
|
56
|
+
};
|