@versatiles/container 1.0.0 → 1.0.2
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/README.md +94 -142
- package/dist/index.d.ts +31 -29
- package/dist/index.js +67 -76
- package/dist/interfaces.d.ts +8 -4
- package/dist/reader_file.js +11 -1
- package/dist/reader_http.js +22 -1
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -1,29 +1,5 @@
|
|
|
1
1
|
A client library for [VersaTiles containers](https://github.com/versatiles-org/versatiles-spec).
|
|
2
2
|
|
|
3
|
-
# Table of Content
|
|
4
|
-
|
|
5
|
-
* [Install](#install)
|
|
6
|
-
* [Usage Example](#usage-example)
|
|
7
|
-
* [API](#api)
|
|
8
|
-
* [Class: VersaTiles](#class_versatiles)
|
|
9
|
-
* [constructor: new VersaTiles(source, options)](#constructor-new-versatilessource-options)
|
|
10
|
-
* [async getHeader()](#async-getheader)
|
|
11
|
-
* [async getMetadata()](#async-getmetadata)
|
|
12
|
-
* [async getTileFormat()](#async-gettileformat)
|
|
13
|
-
* [async getBlockIndex()](#async-getblockindex)
|
|
14
|
-
* [async getTileIndex(block)](#async-gettileindexblock)
|
|
15
|
-
* [async getTile(z, x, y)](#async-gettilez-x-y)
|
|
16
|
-
* [async getTileUncompressed(z, x, y)](#async-gettileuncompressedz-x-y)
|
|
17
|
-
* [Interface: Block](#interface_block)
|
|
18
|
-
* [Interface: Header](#interface_header)
|
|
19
|
-
* [Interface: Options](#interface_options)
|
|
20
|
-
* [Interface: TileIndex](#interface_tileindex)
|
|
21
|
-
* [Type: Compression](#type_compression)
|
|
22
|
-
* [Type: Format](#type_format)
|
|
23
|
-
* [Type: Reader](#type_reader)
|
|
24
|
-
* [License](#license)
|
|
25
|
-
* [Future work](#future-work)
|
|
26
|
-
|
|
27
3
|
# Install
|
|
28
4
|
|
|
29
5
|
`npm i versatiles`
|
|
@@ -42,199 +18,175 @@ fs.writeFileSync('tile.' + header.tile_format, tile);
|
|
|
42
18
|
|
|
43
19
|
# API
|
|
44
20
|
|
|
45
|
-
|
|
21
|
+
<!--- This chapter is generated automatically --->
|
|
22
|
+
|
|
23
|
+
<details>
|
|
24
|
+
|
|
25
|
+
<summary><h2>Class: <code>VersaTiles</code><a id="class_versatiles"></a></h2></summary>
|
|
46
26
|
|
|
47
27
|
The `VersaTiles` class is a wrapper around a `.versatiles` container file. It provides methods\
|
|
48
|
-
to access tile data, metadata, and other properties within the container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/
|
|
28
|
+
to access tile data, metadata, and other properties within the container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L27">\[src]</a></sup>
|
|
29
|
+
|
|
30
|
+
<details>
|
|
49
31
|
|
|
50
|
-
|
|
32
|
+
<summary><h3>Constructor: <code>new VersaTiles(source, options)</code></h3></summary>
|
|
51
33
|
|
|
52
|
-
Constructs a new instance of the VersaTiles class. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/
|
|
34
|
+
Constructs a new instance of the VersaTiles class. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L50">\[src]</a></sup>
|
|
53
35
|
|
|
54
36
|
**Parameters:**
|
|
55
37
|
|
|
56
|
-
*
|
|
38
|
+
* <code>source: string | [Reader](#type_reader)</code>\
|
|
57
39
|
The data source for the tiles. This can be a URL starting with `http://` or `https://`,
|
|
58
40
|
a path to a local file, or a custom `Reader` function that reads data chunks based on offset and length.
|
|
59
|
-
*
|
|
41
|
+
* <code>options: [Options](#interface_options)</code> (optional)\
|
|
60
42
|
Optional settings that configure tile handling.
|
|
61
43
|
|
|
62
|
-
**Returns:** [
|
|
63
|
-
**Methods**
|
|
44
|
+
**Returns:** <code>[VersaTiles](#class_versatiles)</code>
|
|
64
45
|
|
|
65
|
-
|
|
46
|
+
</details>
|
|
66
47
|
|
|
67
|
-
|
|
68
|
-
This method is primarily for internal use. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/575beea/container/src/index.ts#L75">\[src]</a></sup>
|
|
48
|
+
<details>
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### `async getMetadata()`
|
|
73
|
-
|
|
74
|
-
Asynchronously retrieves the metadata associated with the `.versatiles` container.\
|
|
75
|
-
Metadata typically includes information about `vector_layers` for vector tiles.
|
|
76
|
-
If the container does not include metadata, this method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/575beea/container/src/index.ts#L133">\[src]</a></sup>
|
|
50
|
+
<summary><h3>Method: <code>getHeader()</code></h3></summary>
|
|
77
51
|
|
|
78
|
-
|
|
52
|
+
Asynchronously retrieves the header information from the `.versatiles` container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L74">\[src]</a></sup>
|
|
79
53
|
|
|
80
|
-
|
|
54
|
+
**Returns:** <code>Promise<[Header](#interface_header)></code>
|
|
81
55
|
|
|
82
|
-
|
|
56
|
+
</details>
|
|
83
57
|
|
|
84
|
-
|
|
58
|
+
<details>
|
|
85
59
|
|
|
86
|
-
|
|
60
|
+
<summary><h3>Method: <code>getMetadata()</code></h3></summary>
|
|
87
61
|
|
|
88
|
-
Asynchronously retrieves
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
**Returns:** `Map<string,`[`Block`](#interface_block)`>`
|
|
92
|
-
|
|
93
|
-
### `async getTileIndex(block)`
|
|
94
|
-
|
|
95
|
-
Asynchronously retrieves the tile index for a specified block. This is an internal method used to\
|
|
96
|
-
maintain a lookup for every tile within a block. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/575beea/container/src/index.ts#L244">\[src]</a></sup>
|
|
62
|
+
Asynchronously retrieves the metadata associated with the `.versatiles` container.\
|
|
63
|
+
Metadata typically includes information about `vector_layers` for vector tiles.
|
|
64
|
+
If the container does not include metadata, this method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L132">\[src]</a></sup>
|
|
97
65
|
|
|
98
|
-
**
|
|
66
|
+
**Returns:** <code>Promise\<null | object></code>
|
|
99
67
|
|
|
100
|
-
|
|
101
|
-
The block for which to retrieve the tile index.
|
|
68
|
+
</details>
|
|
102
69
|
|
|
103
|
-
|
|
70
|
+
<details>
|
|
104
71
|
|
|
105
|
-
|
|
72
|
+
<summary><h3>Method: <code>getTile(z, x, y)</code></h3></summary>
|
|
106
73
|
|
|
107
74
|
Asynchronously retrieves a specific tile's data as a Buffer. If the tile data is compressed as\
|
|
108
75
|
defined in the container header, the returned Buffer will contain the compressed data.
|
|
109
76
|
To obtain uncompressed data, use the `getTileUncompressed` method.
|
|
110
|
-
If the specified tile does not exist, the method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/
|
|
77
|
+
If the specified tile does not exist, the method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L158">\[src]</a></sup>
|
|
111
78
|
|
|
112
79
|
**Parameters:**
|
|
113
80
|
|
|
114
|
-
*
|
|
81
|
+
* <code>z: number</code>\
|
|
115
82
|
The zoom level of the tile.
|
|
116
|
-
*
|
|
83
|
+
* <code>x: number</code>\
|
|
117
84
|
The x coordinate of the tile within its zoom level.
|
|
118
|
-
*
|
|
85
|
+
* <code>y: number</code>\
|
|
119
86
|
The y coordinate of the tile within its zoom level.
|
|
120
87
|
|
|
121
|
-
**Returns:**
|
|
88
|
+
**Returns:** <code>Promise\<null | Buffer></code>
|
|
89
|
+
|
|
90
|
+
</details>
|
|
122
91
|
|
|
123
|
-
|
|
92
|
+
<details>
|
|
93
|
+
|
|
94
|
+
<summary><h3>Method: <code>getTileUncompressed(z, x, y)</code></h3></summary>
|
|
124
95
|
|
|
125
96
|
Asynchronously retrieves a specific tile's uncompressed data as a Buffer. This method first\
|
|
126
97
|
retrieves the compressed tile data using `getTile` and then decompresses it based on the
|
|
127
98
|
compression setting in the container header.
|
|
128
|
-
If the specified tile does not exist, the method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/
|
|
99
|
+
If the specified tile does not exist, the method returns `null`. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/index.ts#L206">\[src]</a></sup>
|
|
129
100
|
|
|
130
101
|
**Parameters:**
|
|
131
102
|
|
|
132
|
-
*
|
|
103
|
+
* <code>z: number</code>\
|
|
133
104
|
The zoom level of the tile.
|
|
134
|
-
*
|
|
105
|
+
* <code>x: number</code>\
|
|
135
106
|
The x coordinate of the tile within its zoom level.
|
|
136
|
-
*
|
|
107
|
+
* <code>y: number</code>\
|
|
137
108
|
The y coordinate of the tile within its zoom level.
|
|
138
109
|
|
|
139
|
-
**Returns:**
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
*
|
|
152
|
-
The row position of this block at the current zoom level.
|
|
153
|
-
* `colMin: number`\
|
|
154
|
-
Minimum column index for tiles stored in this block (range: 0-255).
|
|
155
|
-
* `rowMin: number`\
|
|
156
|
-
Minimum row index for tiles stored in this block (range: 0-255).
|
|
157
|
-
* `colMax: number`\
|
|
158
|
-
Maximum column index for tiles stored in this block (range: 0-255).
|
|
159
|
-
* `rowMax: number`\
|
|
160
|
-
Maximum row index for tiles stored in this block (range: 0-255).
|
|
161
|
-
* `blockOffset: number`\
|
|
162
|
-
Byte position where this block starts in the file container.
|
|
163
|
-
* `tileIndexOffset: number`\
|
|
164
|
-
Byte position where the tile index starts within the container.
|
|
165
|
-
* `tileIndexLength: number`\
|
|
166
|
-
Length of the tile index in bytes.
|
|
167
|
-
* `tileCount: number`\
|
|
168
|
-
The number of tiles contained in this block.
|
|
169
|
-
* `tileIndex: `[`TileIndex`](#interface_tileindex) (optional)\
|
|
170
|
-
Optional tile index if it has been fetched.
|
|
171
|
-
|
|
172
|
-
## Interface: `Header`<a id="interface_header"></a>
|
|
173
|
-
|
|
174
|
-
Interface for the metadata header of a `*.Versatiles` container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/575beea/container/src/interfaces.ts#L52">\[src]</a></sup>
|
|
175
|
-
**Properties**
|
|
176
|
-
|
|
177
|
-
* `magic: string`\
|
|
110
|
+
**Returns:** <code>Promise\<null | Buffer></code>
|
|
111
|
+
|
|
112
|
+
</details>
|
|
113
|
+
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
|
|
118
|
+
<summary><h2>Interface: <code>Header</code><a id="interface_header"></a></h2></summary>
|
|
119
|
+
|
|
120
|
+
Interface for the metadata header of a `*.Versatiles` container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/interfaces.ts#L56">\[src]</a></sup>
|
|
121
|
+
|
|
122
|
+
* <code>magic: string</code>\
|
|
178
123
|
Identifier for the container format, usually "versatiles\_v02".
|
|
179
|
-
*
|
|
124
|
+
* <code>version: string</code>\
|
|
180
125
|
Version of the container format, typically "v02".
|
|
181
|
-
*
|
|
126
|
+
* <code>tileFormat: [Format](#type_format)</code>\
|
|
182
127
|
The format used for storing tiles.
|
|
183
|
-
*
|
|
128
|
+
* <code>tileCompression: [Compression](#type_compression)</code>\
|
|
184
129
|
The type of compression applied to tiles.
|
|
185
|
-
*
|
|
130
|
+
* <code>zoomMin: number</code>\
|
|
186
131
|
The minimum zoom level.
|
|
187
|
-
*
|
|
132
|
+
* <code>zoomMax: number</code>\
|
|
188
133
|
The maximum zoom level.
|
|
189
|
-
*
|
|
134
|
+
* <code>bbox: \[number, number, number, number]</code>\
|
|
190
135
|
Bounding box coordinates as \[lon\_min, lat\_min, lon\_max, lat\_max].
|
|
191
|
-
*
|
|
136
|
+
* <code>metaOffset: number</code>\
|
|
192
137
|
The byte offset for metadata within the container.
|
|
193
|
-
*
|
|
138
|
+
* <code>metaLength: number</code>\
|
|
194
139
|
The byte size of the metadata. A value of 0 means no metadata.
|
|
195
|
-
*
|
|
140
|
+
* <code>blockIndexOffset: number</code>\
|
|
196
141
|
The byte offset for the block index within the container.
|
|
197
|
-
*
|
|
142
|
+
* <code>blockIndexLength: number</code>\
|
|
198
143
|
The byte size of the block index. A value of 0 indicates no tiles in the container.
|
|
199
144
|
|
|
200
|
-
|
|
145
|
+
</details>
|
|
201
146
|
|
|
202
|
-
|
|
203
|
-
**Properties**
|
|
147
|
+
<details>
|
|
204
148
|
|
|
205
|
-
|
|
206
|
-
If set to true, uses the [TMS (Tile Map Service) tile ordering](https://wiki.openstreetmap.org/wiki/TMS) where y=0 is the southernmost point.
|
|
149
|
+
<summary><h2>Interface: <code>Options</code><a id="interface_options"></a></h2></summary>
|
|
207
150
|
|
|
208
|
-
|
|
151
|
+
Interface for defining the options available for reading a container. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/interfaces.ts#L123">\[src]</a></sup>
|
|
209
152
|
|
|
210
|
-
|
|
211
|
-
|
|
153
|
+
* <code>tms: boolean</code>\
|
|
154
|
+
If set to true, uses the [TMS (Tile Map Service) tile ordering](https://wiki.openstreetmap.org/wiki/TMS) where y=0 is the southernmost point.
|
|
155
|
+
|
|
156
|
+
</details>
|
|
212
157
|
|
|
213
|
-
|
|
214
|
-
Array indicating the start byte positions of tiles within the block.
|
|
215
|
-
* `lengths: Float64Array`\
|
|
216
|
-
Array specifying the byte lengths of the tiles. A length of 0 means the tile is not stored.
|
|
158
|
+
<details>
|
|
217
159
|
|
|
218
|
-
|
|
160
|
+
<summary><h2>Type: <code>Compression</code><a id="type_compression"></a></h2></summary>
|
|
219
161
|
|
|
220
162
|
Supported compression.\
|
|
221
|
-
`null` signifies that the data is uncompressed. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/
|
|
163
|
+
`null` signifies that the data is uncompressed. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/interfaces.ts#L5">\[src]</a></sup>
|
|
164
|
+
|
|
165
|
+
**Type:** <code>"br" | "gzip" | null</code>
|
|
166
|
+
|
|
167
|
+
</details>
|
|
168
|
+
|
|
169
|
+
<details>
|
|
170
|
+
|
|
171
|
+
<summary><h2>Type: <code>Format</code><a id="type_format"></a></h2></summary>
|
|
172
|
+
|
|
173
|
+
Supported tile formats. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/interfaces.ts#L11">\[src]</a></sup>
|
|
222
174
|
|
|
223
|
-
**Type:**
|
|
175
|
+
**Type:** <code>"avif" | "bin" | "geojson" | "jpeg" | "json" | "pbf" | "png" | "svg" | "topojson" | "webp" | null</code>
|
|
224
176
|
|
|
225
|
-
|
|
177
|
+
</details>
|
|
226
178
|
|
|
227
|
-
|
|
179
|
+
<details>
|
|
228
180
|
|
|
229
|
-
|
|
181
|
+
<summary><h2>Type: <code>Reader</code><a id="type_reader"></a></h2></summary>
|
|
230
182
|
|
|
231
|
-
|
|
183
|
+
Type definition for reading content from a VersaTiles container.
|
|
232
184
|
|
|
233
|
-
|
|
185
|
+
This is useful for implementing new container readers, e.g. reading over other network protocols. <sup><a href="https://github.com/versatiles-org/node-versatiles/blob/8921e07/versatiles-container/src/interfaces.ts#L37">\[src]</a></sup>
|
|
234
186
|
|
|
235
|
-
|
|
187
|
+
**Type:** <code>(position: number, length: number) => Promise<Buffer></code>
|
|
236
188
|
|
|
237
|
-
|
|
189
|
+
</details>
|
|
238
190
|
|
|
239
191
|
# License
|
|
240
192
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import type { Block,
|
|
3
|
-
export type {
|
|
2
|
+
import type { Block, Header, OpenOptions, Reader, TileIndex } from './interfaces.js';
|
|
3
|
+
export type { Compression, Format, Header, OpenOptions, Reader } from './interfaces.js';
|
|
4
4
|
/**
|
|
5
5
|
* The `VersaTiles` class is a wrapper around a `.versatiles` container file. It provides methods
|
|
6
6
|
* to access tile data, metadata, and other properties within the container.
|
|
@@ -15,10 +15,9 @@ export declare class VersaTiles {
|
|
|
15
15
|
* @param options - Optional settings that configure tile handling.
|
|
16
16
|
* @throws Will throw an error if the provided source is neither a string nor a Reader function.
|
|
17
17
|
*/
|
|
18
|
-
constructor(source: Reader | string, options?:
|
|
18
|
+
constructor(source: Reader | string, options?: OpenOptions);
|
|
19
19
|
/**
|
|
20
20
|
* Asynchronously retrieves the header information from the `.versatiles` container.
|
|
21
|
-
* This method is primarily for internal use.
|
|
22
21
|
*
|
|
23
22
|
* @returns A promise that resolves with the header object.
|
|
24
23
|
* @throws Will throw an error if the container does not start with expected magic bytes indicating a valid format.
|
|
@@ -29,32 +28,9 @@ export declare class VersaTiles {
|
|
|
29
28
|
* Metadata typically includes information about `vector_layers` for vector tiles.
|
|
30
29
|
* If the container does not include metadata, this method returns `null`.
|
|
31
30
|
*
|
|
32
|
-
* @returns A promise that resolves with an object representing the metadata
|
|
31
|
+
* @returns A promise that resolves with an object representing the metadata.
|
|
33
32
|
*/
|
|
34
|
-
getMetadata(): Promise<
|
|
35
|
-
/**
|
|
36
|
-
* Asynchronously determines the tile format, such as "png" or "pbf", based on the header information.
|
|
37
|
-
*
|
|
38
|
-
* @returns A promise that resolves with the tile format string, or null if the format is undefined.
|
|
39
|
-
*/
|
|
40
|
-
getTileFormat(): Promise<Format | null>;
|
|
41
|
-
/**
|
|
42
|
-
* Asynchronously retrieves a mapping of tile block indices. The map's keys are formatted as "{z},{x},{y}".
|
|
43
|
-
* This method is for internal use to manage tile lookup within the container.
|
|
44
|
-
*
|
|
45
|
-
* @returns A promise that resolves with the block index map.
|
|
46
|
-
* @internal
|
|
47
|
-
*/
|
|
48
|
-
getBlockIndex(): Promise<Map<string, Block>>;
|
|
49
|
-
/**
|
|
50
|
-
* Asynchronously retrieves the tile index for a specified block. This is an internal method used to
|
|
51
|
-
* maintain a lookup for every tile within a block.
|
|
52
|
-
*
|
|
53
|
-
* @param block - The block for which to retrieve the tile index.
|
|
54
|
-
* @returns A promise that resolves with the tile index.
|
|
55
|
-
* @internal
|
|
56
|
-
*/
|
|
57
|
-
getTileIndex(block: Block): Promise<TileIndex>;
|
|
33
|
+
getMetadata(): Promise<unknown>;
|
|
58
34
|
/**
|
|
59
35
|
* Asynchronously retrieves a specific tile's data as a Buffer. If the tile data is compressed as
|
|
60
36
|
* defined in the container header, the returned Buffer will contain the compressed data.
|
|
@@ -79,4 +55,30 @@ export declare class VersaTiles {
|
|
|
79
55
|
* @returns A promise that resolves with the uncompressed tile data as a Buffer, or null if the tile cannot be found.
|
|
80
56
|
*/
|
|
81
57
|
getTileUncompressed(z: number, x: number, y: number): Promise<Buffer | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Asynchronously retrieves a mapping of tile block indices. The map's keys are formatted as "{z},{x},{y}".
|
|
60
|
+
* This method is for internal use to manage tile lookup within the container.
|
|
61
|
+
*
|
|
62
|
+
* @returns A promise that resolves with the block index map.
|
|
63
|
+
* @protected
|
|
64
|
+
*/
|
|
65
|
+
protected getBlockIndex(): Promise<Map<string, Block>>;
|
|
66
|
+
/**
|
|
67
|
+
* Asynchronously retrieves the tile index for a specified block. This is an internal method used to
|
|
68
|
+
* maintain a lookup for every tile within a block.
|
|
69
|
+
*
|
|
70
|
+
* @param block - The block for which to retrieve the tile index.
|
|
71
|
+
* @returns A promise that resolves with the tile index.
|
|
72
|
+
* @protected
|
|
73
|
+
*/
|
|
74
|
+
protected getTileIndex(block: Block): Promise<TileIndex>;
|
|
75
|
+
/**
|
|
76
|
+
* A protected method to read a chunk of data from the source based on the specified offset and length.
|
|
77
|
+
*
|
|
78
|
+
* @param offset - The offset from the start of the source data to begin reading.
|
|
79
|
+
* @param length - The number of bytes to read from the source.
|
|
80
|
+
* @returns A promise that resolves with the read data as a Buffer.
|
|
81
|
+
* @protected
|
|
82
|
+
*/
|
|
83
|
+
protected read(offset: number, length: number): Promise<Buffer>;
|
|
82
84
|
}
|
package/dist/index.js
CHANGED
|
@@ -53,7 +53,6 @@ export class VersaTiles {
|
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Asynchronously retrieves the header information from the `.versatiles` container.
|
|
56
|
-
* This method is primarily for internal use.
|
|
57
56
|
*
|
|
58
57
|
* @returns A promise that resolves with the header object.
|
|
59
58
|
* @throws Will throw an error if the container does not start with expected magic bytes indicating a valid format.
|
|
@@ -62,7 +61,7 @@ export class VersaTiles {
|
|
|
62
61
|
// deliver if known
|
|
63
62
|
if (this.#header)
|
|
64
63
|
return this.#header;
|
|
65
|
-
const data = await this
|
|
64
|
+
const data = await this.read(0, 66);
|
|
66
65
|
// check magic bytes
|
|
67
66
|
if (!/^versatiles_v0[12]$/.test(data.toString('utf8', 0, 14))) {
|
|
68
67
|
throw new Error('Invalid Container');
|
|
@@ -109,7 +108,7 @@ export class VersaTiles {
|
|
|
109
108
|
* Metadata typically includes information about `vector_layers` for vector tiles.
|
|
110
109
|
* If the container does not include metadata, this method returns `null`.
|
|
111
110
|
*
|
|
112
|
-
* @returns A promise that resolves with an object representing the metadata
|
|
111
|
+
* @returns A promise that resolves with an object representing the metadata.
|
|
113
112
|
*/
|
|
114
113
|
async getMetadata() {
|
|
115
114
|
if (this.#metadata !== undefined)
|
|
@@ -119,33 +118,86 @@ export class VersaTiles {
|
|
|
119
118
|
this.#metadata = null;
|
|
120
119
|
}
|
|
121
120
|
else {
|
|
122
|
-
let buffer = await this
|
|
121
|
+
let buffer = await this.read(header.metaOffset, header.metaLength);
|
|
123
122
|
buffer = await this.#decompress(buffer, header.tileCompression);
|
|
124
123
|
this.#metadata = JSON.parse(buffer.toString());
|
|
125
124
|
}
|
|
126
125
|
return this.#metadata;
|
|
127
126
|
}
|
|
128
127
|
/**
|
|
129
|
-
* Asynchronously
|
|
128
|
+
* Asynchronously retrieves a specific tile's data as a Buffer. If the tile data is compressed as
|
|
129
|
+
* defined in the container header, the returned Buffer will contain the compressed data.
|
|
130
|
+
* To obtain uncompressed data, use the `getTileUncompressed` method.
|
|
131
|
+
* If the specified tile does not exist, the method returns `null`.
|
|
132
|
+
*
|
|
133
|
+
* @param z - The zoom level of the tile.
|
|
134
|
+
* @param x - The x coordinate of the tile within its zoom level.
|
|
135
|
+
* @param y - The y coordinate of the tile within its zoom level.
|
|
136
|
+
* @returns A promise that resolves with the tile data as a Buffer, or null if the tile cannot be found.
|
|
137
|
+
*/
|
|
138
|
+
async getTile(z, x, y) {
|
|
139
|
+
// when y index is inverted
|
|
140
|
+
if (this.#options.tms)
|
|
141
|
+
y = Math.pow(2, z) - y - 1;
|
|
142
|
+
// ensure block index is loaded
|
|
143
|
+
const blockIndex = await this.getBlockIndex();
|
|
144
|
+
// block xy
|
|
145
|
+
const bx = x >> 8;
|
|
146
|
+
const by = y >> 8;
|
|
147
|
+
// tile xy (within block)
|
|
148
|
+
const tx = x & 0xFF;
|
|
149
|
+
const ty = y & 0xFF;
|
|
150
|
+
// check if block containing tile is within bounds
|
|
151
|
+
const blockKey = `${z},${bx},${by}`;
|
|
152
|
+
const block = blockIndex.get(blockKey);
|
|
153
|
+
if (!block)
|
|
154
|
+
return null;
|
|
155
|
+
// check if block contains tile
|
|
156
|
+
if (tx < block.colMin || tx > block.colMax)
|
|
157
|
+
return null;
|
|
158
|
+
if (ty < block.rowMin || ty > block.rowMax)
|
|
159
|
+
return null;
|
|
160
|
+
// calculate sequential tile number
|
|
161
|
+
const j = (ty - block.rowMin) * (block.colMax - block.colMin + 1) + (tx - block.colMin);
|
|
162
|
+
// get tile index
|
|
163
|
+
const tileIndex = await this.getTileIndex(block);
|
|
164
|
+
const offset = tileIndex.offsets[j];
|
|
165
|
+
const length = tileIndex.lengths[j];
|
|
166
|
+
if (length === 0)
|
|
167
|
+
return null;
|
|
168
|
+
return this.read(offset, length);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Asynchronously retrieves a specific tile's uncompressed data as a Buffer. This method first
|
|
172
|
+
* retrieves the compressed tile data using `getTile` and then decompresses it based on the
|
|
173
|
+
* compression setting in the container header.
|
|
174
|
+
* If the specified tile does not exist, the method returns `null`.
|
|
130
175
|
*
|
|
131
|
-
* @
|
|
176
|
+
* @param z - The zoom level of the tile.
|
|
177
|
+
* @param x - The x coordinate of the tile within its zoom level.
|
|
178
|
+
* @param y - The y coordinate of the tile within its zoom level.
|
|
179
|
+
* @returns A promise that resolves with the uncompressed tile data as a Buffer, or null if the tile cannot be found.
|
|
132
180
|
*/
|
|
133
|
-
async
|
|
134
|
-
|
|
181
|
+
async getTileUncompressed(z, x, y) {
|
|
182
|
+
const tile = await this.getTile(z, x, y);
|
|
183
|
+
if (!tile)
|
|
184
|
+
return null;
|
|
185
|
+
const header = await this.getHeader();
|
|
186
|
+
return this.#decompress(tile, header.tileCompression);
|
|
135
187
|
}
|
|
136
188
|
/**
|
|
137
189
|
* Asynchronously retrieves a mapping of tile block indices. The map's keys are formatted as "{z},{x},{y}".
|
|
138
190
|
* This method is for internal use to manage tile lookup within the container.
|
|
139
191
|
*
|
|
140
192
|
* @returns A promise that resolves with the block index map.
|
|
141
|
-
* @
|
|
193
|
+
* @protected
|
|
142
194
|
*/
|
|
143
195
|
async getBlockIndex() {
|
|
144
196
|
if (this.#blockIndex)
|
|
145
197
|
return this.#blockIndex;
|
|
146
198
|
const header = await this.getHeader();
|
|
147
199
|
// read block_index buffer
|
|
148
|
-
let data = await this
|
|
200
|
+
let data = await this.read(header.blockIndexOffset, header.blockIndexLength);
|
|
149
201
|
data = await this.#decompress(data, 'br');
|
|
150
202
|
// read index from buffer
|
|
151
203
|
const blocks = [];
|
|
@@ -199,12 +251,12 @@ export class VersaTiles {
|
|
|
199
251
|
*
|
|
200
252
|
* @param block - The block for which to retrieve the tile index.
|
|
201
253
|
* @returns A promise that resolves with the tile index.
|
|
202
|
-
* @
|
|
254
|
+
* @protected
|
|
203
255
|
*/
|
|
204
256
|
async getTileIndex(block) {
|
|
205
257
|
if (block.tileIndex)
|
|
206
258
|
return block.tileIndex;
|
|
207
|
-
let buffer = await this
|
|
259
|
+
let buffer = await this.read(block.tileIndexOffset, block.tileIndexLength);
|
|
208
260
|
buffer = await this.#decompress(buffer, 'br');
|
|
209
261
|
const offsets = new Float64Array(block.tileCount);
|
|
210
262
|
const lengths = new Float64Array(block.tileCount);
|
|
@@ -216,75 +268,14 @@ export class VersaTiles {
|
|
|
216
268
|
return block.tileIndex;
|
|
217
269
|
}
|
|
218
270
|
/**
|
|
219
|
-
*
|
|
220
|
-
* defined in the container header, the returned Buffer will contain the compressed data.
|
|
221
|
-
* To obtain uncompressed data, use the `getTileUncompressed` method.
|
|
222
|
-
* If the specified tile does not exist, the method returns `null`.
|
|
223
|
-
*
|
|
224
|
-
* @param z - The zoom level of the tile.
|
|
225
|
-
* @param x - The x coordinate of the tile within its zoom level.
|
|
226
|
-
* @param y - The y coordinate of the tile within its zoom level.
|
|
227
|
-
* @returns A promise that resolves with the tile data as a Buffer, or null if the tile cannot be found.
|
|
228
|
-
*/
|
|
229
|
-
async getTile(z, x, y) {
|
|
230
|
-
// when y index is inverted
|
|
231
|
-
if (this.#options.tms)
|
|
232
|
-
y = Math.pow(2, z) - y - 1;
|
|
233
|
-
// ensure block index is loaded
|
|
234
|
-
const blockIndex = await this.getBlockIndex();
|
|
235
|
-
// block xy
|
|
236
|
-
const bx = x >> 8;
|
|
237
|
-
const by = y >> 8;
|
|
238
|
-
// tile xy (within block)
|
|
239
|
-
const tx = x & 0xFF;
|
|
240
|
-
const ty = y & 0xFF;
|
|
241
|
-
// check if block containing tile is within bounds
|
|
242
|
-
const blockKey = `${z},${bx},${by}`;
|
|
243
|
-
const block = blockIndex.get(blockKey);
|
|
244
|
-
if (!block)
|
|
245
|
-
return null;
|
|
246
|
-
// check if block contains tile
|
|
247
|
-
if (tx < block.colMin || tx > block.colMax)
|
|
248
|
-
return null;
|
|
249
|
-
if (ty < block.rowMin || ty > block.rowMax)
|
|
250
|
-
return null;
|
|
251
|
-
// calculate sequential tile number
|
|
252
|
-
const j = (ty - block.rowMin) * (block.colMax - block.colMin + 1) + (tx - block.colMin);
|
|
253
|
-
// get tile index
|
|
254
|
-
const tileIndex = await this.getTileIndex(block);
|
|
255
|
-
const offset = tileIndex.offsets[j];
|
|
256
|
-
const length = tileIndex.lengths[j];
|
|
257
|
-
if (length === 0)
|
|
258
|
-
return null;
|
|
259
|
-
return this.#read(offset, length);
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Asynchronously retrieves a specific tile's uncompressed data as a Buffer. This method first
|
|
263
|
-
* retrieves the compressed tile data using `getTile` and then decompresses it based on the
|
|
264
|
-
* compression setting in the container header.
|
|
265
|
-
* If the specified tile does not exist, the method returns `null`.
|
|
266
|
-
*
|
|
267
|
-
* @param z - The zoom level of the tile.
|
|
268
|
-
* @param x - The x coordinate of the tile within its zoom level.
|
|
269
|
-
* @param y - The y coordinate of the tile within its zoom level.
|
|
270
|
-
* @returns A promise that resolves with the uncompressed tile data as a Buffer, or null if the tile cannot be found.
|
|
271
|
-
*/
|
|
272
|
-
async getTileUncompressed(z, x, y) {
|
|
273
|
-
const tile = await this.getTile(z, x, y);
|
|
274
|
-
if (!tile)
|
|
275
|
-
return null;
|
|
276
|
-
const header = await this.getHeader();
|
|
277
|
-
return this.#decompress(tile, header.tileCompression);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* A private method to read a chunk of data from the source based on the specified offset and length.
|
|
271
|
+
* A protected method to read a chunk of data from the source based on the specified offset and length.
|
|
281
272
|
*
|
|
282
273
|
* @param offset - The offset from the start of the source data to begin reading.
|
|
283
274
|
* @param length - The number of bytes to read from the source.
|
|
284
275
|
* @returns A promise that resolves with the read data as a Buffer.
|
|
285
|
-
* @
|
|
276
|
+
* @protected
|
|
286
277
|
*/
|
|
287
|
-
async
|
|
278
|
+
async read(offset, length) {
|
|
288
279
|
if (length === 0)
|
|
289
280
|
return Buffer.allocUnsafe(0);
|
|
290
281
|
return this.#reader(offset, length);
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -17,12 +17,16 @@ export type Format = 'avif' | 'bin' | 'geojson' | 'jpeg' | 'json' | 'pbf' | 'png
|
|
|
17
17
|
*/
|
|
18
18
|
export type Decompressor = (data: Buffer, compression: Compression) => Promise<Buffer>;
|
|
19
19
|
/**
|
|
20
|
-
* Type definition for
|
|
20
|
+
* Type definition for reading content from a VersaTiles container.
|
|
21
|
+
*
|
|
22
|
+
* This is useful for implementing new container readers, e.g. reading over other network protocols.
|
|
21
23
|
*
|
|
22
|
-
* This can be useful for accessing data stored in various storage mediums.
|
|
23
24
|
* @param {number} position - The byte offset at which to start reading.
|
|
24
25
|
* @param {number} length - The number of bytes to read.
|
|
25
|
-
* @returns {Promise<Buffer>}
|
|
26
|
+
* @returns {Promise<Buffer>} A promise that resolves with the data read as a Buffer.
|
|
27
|
+
* @throws {RangeError} If `position` is less than 0 or if `length` is less than 0.
|
|
28
|
+
* @throws {RangeError} If the sum of `position` and `length` exceeds the size of the content (filesize).
|
|
29
|
+
* @throws {Error} If there is any filesystem or network error such as the content not being accessible or readable.
|
|
26
30
|
*/
|
|
27
31
|
export type Reader = (position: number, length: number) => Promise<Buffer>;
|
|
28
32
|
/**
|
|
@@ -98,6 +102,6 @@ export interface TileIndex {
|
|
|
98
102
|
* Interface for defining the options available for reading a container.
|
|
99
103
|
* @property {boolean} tms - If set to true, uses the [TMS (Tile Map Service) tile ordering](https://wiki.openstreetmap.org/wiki/TMS) where y=0 is the southernmost point.
|
|
100
104
|
*/
|
|
101
|
-
export interface
|
|
105
|
+
export interface OpenOptions {
|
|
102
106
|
tms: boolean;
|
|
103
107
|
}
|
package/dist/reader_file.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
1
|
+
import fs from 'node:fs';
|
|
2
2
|
/**
|
|
3
3
|
* Creates a file reader function for reading chunks of data from a file. This reader abstracts
|
|
4
4
|
* the file reading process and provides a simple async interface to read data from the specified file.
|
|
@@ -18,6 +18,7 @@ import fs from 'fs';
|
|
|
18
18
|
*/
|
|
19
19
|
export default function getFileReader(filename) {
|
|
20
20
|
const fd = fs.openSync(filename, 'r');
|
|
21
|
+
const { size } = fs.statSync(filename);
|
|
21
22
|
/**
|
|
22
23
|
* Reads a chunk of data from the file at the specified position and length.
|
|
23
24
|
* It creates a buffer of the specified `length`, seeks to the `position` in the file,
|
|
@@ -37,6 +38,15 @@ export default function getFileReader(filename) {
|
|
|
37
38
|
* promise will be rejected with an error.
|
|
38
39
|
*/
|
|
39
40
|
return async function read(position, length) {
|
|
41
|
+
if (position < 0) {
|
|
42
|
+
throw new RangeError(`Invalid read position: ${position}. The read position must be a non-negative integer.`);
|
|
43
|
+
}
|
|
44
|
+
if (length < 0) {
|
|
45
|
+
throw new RangeError(`Invalid read length: ${length}. The read length must be a non-negative integer.`);
|
|
46
|
+
}
|
|
47
|
+
if (position + length > size) {
|
|
48
|
+
throw new RangeError(`Read range out of bounds: The requested range ends at position ${position + length}, which exceeds the file's limit of ${size} bytes.`);
|
|
49
|
+
}
|
|
40
50
|
return new Promise((resolve, reject) => {
|
|
41
51
|
fs.read(fd, {
|
|
42
52
|
buffer: Buffer.alloc(length),
|
package/dist/reader_http.js
CHANGED
|
@@ -27,6 +27,12 @@ export default function getHTTPReader(url) {
|
|
|
27
27
|
* the promise is rejected with an error.
|
|
28
28
|
*/
|
|
29
29
|
return async function read(position, length) {
|
|
30
|
+
if (position < 0) {
|
|
31
|
+
throw new RangeError(`Invalid read position: ${position}. The read position must be a non-negative integer.`);
|
|
32
|
+
}
|
|
33
|
+
if (length < 0) {
|
|
34
|
+
throw new RangeError(`Invalid read length: ${length}. The read length must be a non-negative integer.`);
|
|
35
|
+
}
|
|
30
36
|
const headers = {
|
|
31
37
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
32
38
|
'user-agent': 'Mozilla/5.0 (compatible; versatiles; +https://www.npmjs.com/package/versatiles)',
|
|
@@ -61,9 +67,24 @@ export default function getHTTPReader(url) {
|
|
|
61
67
|
})
|
|
62
68
|
.end();
|
|
63
69
|
});
|
|
70
|
+
const contentRange = message.headers['content-range'];
|
|
71
|
+
if (contentRange == null)
|
|
72
|
+
throw Error('The response header does not contain "content-range"');
|
|
73
|
+
const parts = /^bytes (\d+)\-(\d+)\/(\d+)/i.exec(contentRange);
|
|
74
|
+
if (parts == null)
|
|
75
|
+
throw Error('"content-range" in response header is malformed');
|
|
76
|
+
if (position !== parseInt(parts[1], 10))
|
|
77
|
+
throw Error(`requestet position (${position}) and returned offset (${parts[1]}) must be equal`);
|
|
78
|
+
if (position + length > parseInt(parts[3], 10)) {
|
|
79
|
+
throw new RangeError(`Read range out of bounds: The requested range ends at position ${position + length}, which exceeds the file's limit of ${parts[3]} bytes.`);
|
|
80
|
+
}
|
|
81
|
+
const returnedLength = parseInt(parts[2], 10) + 1 - position;
|
|
82
|
+
if (length !== returnedLength) {
|
|
83
|
+
throw new Error(`Returned length (${returnedLength}) is not requested length (${length}).`);
|
|
84
|
+
}
|
|
64
85
|
if ((message.statusCode == null) || Math.floor(message.statusCode / 100) !== 2) {
|
|
65
86
|
message.destroy();
|
|
66
|
-
throw new Error(`Server responded with status code: ${message.statusCode}`);
|
|
87
|
+
throw new Error(`Server responded with status code: ${message.statusCode} `);
|
|
67
88
|
}
|
|
68
89
|
/**
|
|
69
90
|
* Collects and concatenates response data chunks into a buffer.
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versatiles/container",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A client library for reading VersaTiles containers",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"check": "npm run lint && npm run build && npm run test",
|
|
7
6
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
7
|
+
"check": "npm run lint && npm run test && npm run build",
|
|
8
|
+
"doc": "npx vrt ts2md src/index.ts tsconfig.build.json | npx vrt insertmd README.md '# API' true",
|
|
9
|
+
"lint": "eslint . --color",
|
|
10
|
+
"prepublish": "npm run build && npm run doc",
|
|
11
|
+
"test": "cd ..; NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern versatiles-container"
|
|
11
12
|
},
|
|
12
13
|
"files": [
|
|
13
14
|
"dist/**/*.js",
|
|
@@ -46,7 +47,8 @@
|
|
|
46
47
|
],
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/node": "^20.9.0",
|
|
49
|
-
"
|
|
50
|
-
"typescript": "^5.2.2"
|
|
50
|
+
"tsx": "^4.1.0",
|
|
51
|
+
"typescript": "^5.2.2",
|
|
52
|
+
"@versatiles/release-tool": "^1.0.0"
|
|
51
53
|
}
|
|
52
54
|
}
|