@loaders.gl/mvt 4.3.0-alpha.1 → 4.3.0-alpha.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.
Files changed (77) hide show
  1. package/dist/dist.dev.js +568 -175
  2. package/dist/dist.min.js +1 -1
  3. package/dist/index.cjs +226 -163
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/lib/parse-mvt.d.ts +1 -1
  9. package/dist/lib/parse-mvt.js +2 -30
  10. package/dist/lib/parse-tilejson.d.ts +4 -4
  11. package/dist/lib/parse-tilejson.d.ts.map +1 -1
  12. package/dist/lib/utils/geometry-utils.d.ts +38 -1
  13. package/dist/lib/utils/geometry-utils.d.ts.map +1 -1
  14. package/dist/lib/utils/geometry-utils.js +65 -6
  15. package/dist/lib/vector-tile/vector-tile-feature.d.ts +28 -9
  16. package/dist/lib/vector-tile/vector-tile-feature.d.ts.map +1 -1
  17. package/dist/lib/vector-tile/vector-tile-feature.js +47 -50
  18. package/dist/lib/{geojsonvt → vector-tiler}/clip.d.ts +3 -3
  19. package/dist/lib/vector-tiler/clip.d.ts.map +1 -0
  20. package/dist/lib/vector-tiler/convert.d.ts +18 -0
  21. package/dist/lib/vector-tiler/convert.d.ts.map +1 -0
  22. package/dist/lib/{geojsonvt → vector-tiler}/convert.js +8 -1
  23. package/dist/lib/vector-tiler/feature.d.ts +3 -0
  24. package/dist/lib/vector-tiler/feature.d.ts.map +1 -0
  25. package/dist/lib/vector-tiler/simplify.d.ts.map +1 -0
  26. package/dist/lib/{geojsonvt → vector-tiler}/tile.d.ts +4 -4
  27. package/dist/lib/vector-tiler/tile.d.ts.map +1 -0
  28. package/dist/lib/vector-tiler/transform.d.ts +7 -0
  29. package/dist/lib/vector-tiler/transform.d.ts.map +1 -0
  30. package/dist/lib/{geojsonvt → vector-tiler}/wrap.d.ts +2 -2
  31. package/dist/lib/vector-tiler/wrap.d.ts.map +1 -0
  32. package/dist/mvt-loader.d.ts +1 -1
  33. package/dist/mvt-loader.js +1 -1
  34. package/dist/mvt-source.d.ts +4 -4
  35. package/dist/mvt-source.d.ts.map +1 -1
  36. package/dist/mvt-source.js +4 -4
  37. package/dist/mvt-worker.js +101 -56
  38. package/dist/table-tile-source.d.ts +118 -0
  39. package/dist/table-tile-source.d.ts.map +1 -0
  40. package/dist/{geojson-tile-source.js → table-tile-source.js} +154 -103
  41. package/dist/tilejson-loader.js +1 -1
  42. package/package.json +7 -6
  43. package/src/index.ts +3 -3
  44. package/src/lib/parse-mvt.ts +4 -33
  45. package/src/lib/parse-tilejson.ts +5 -5
  46. package/src/lib/utils/geometry-utils.ts +66 -1
  47. package/src/lib/vector-tile/vector-tile-feature.ts +65 -56
  48. package/src/lib/{geojsonvt → vector-tiler}/clip.ts +4 -4
  49. package/src/lib/{geojsonvt → vector-tiler}/convert.ts +18 -8
  50. package/src/lib/{geojsonvt → vector-tiler}/feature.ts +3 -3
  51. package/src/lib/{geojsonvt → vector-tiler}/tile.ts +8 -8
  52. package/src/lib/{geojsonvt → vector-tiler}/transform.ts +2 -2
  53. package/src/lib/{geojsonvt → vector-tiler}/wrap.ts +5 -5
  54. package/src/mvt-source.ts +6 -7
  55. package/src/table-tile-source.ts +508 -0
  56. package/dist/geojson-tile-source.d.ts +0 -79
  57. package/dist/geojson-tile-source.d.ts.map +0 -1
  58. package/dist/lib/geojsonvt/clip.d.ts.map +0 -1
  59. package/dist/lib/geojsonvt/convert.d.ts +0 -10
  60. package/dist/lib/geojsonvt/convert.d.ts.map +0 -1
  61. package/dist/lib/geojsonvt/feature.d.ts +0 -3
  62. package/dist/lib/geojsonvt/feature.d.ts.map +0 -1
  63. package/dist/lib/geojsonvt/simplify.d.ts.map +0 -1
  64. package/dist/lib/geojsonvt/tile.d.ts.map +0 -1
  65. package/dist/lib/geojsonvt/transform.d.ts +0 -7
  66. package/dist/lib/geojsonvt/transform.d.ts.map +0 -1
  67. package/dist/lib/geojsonvt/wrap.d.ts.map +0 -1
  68. package/src/geojson-tile-source.ts +0 -422
  69. /package/dist/lib/{geojsonvt → vector-tiler}/clip.js +0 -0
  70. /package/dist/lib/{geojsonvt → vector-tiler}/feature.js +0 -0
  71. /package/dist/lib/{geojsonvt → vector-tiler}/simplify.d.ts +0 -0
  72. /package/dist/lib/{geojsonvt → vector-tiler}/simplify.js +0 -0
  73. /package/dist/lib/{geojsonvt → vector-tiler}/tile.js +0 -0
  74. /package/dist/lib/{geojsonvt → vector-tiler}/transform.js +0 -0
  75. /package/dist/lib/{geojsonvt → vector-tiler}/wrap.js +0 -0
  76. /package/src/lib/{geojsonvt → vector-tiler}/LICENSE +0 -0
  77. /package/src/lib/{geojsonvt → vector-tiler}/simplify.ts +0 -0
@@ -1,422 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT AND ISC
3
- // Copyright (c) vis.gl contributors
4
- // Based on https://github.com/mapbox/geojson-vt under compatible ISC license
5
-
6
- /* eslint-disable no-console, no-continue */
7
-
8
- import {
9
- VectorTileSource,
10
- VectorTileSourceProps,
11
- TileLoadParameters
12
- } from '@loaders.gl/loader-utils';
13
- import {Feature, GeoJSONTable} from '@loaders.gl/schema';
14
-
15
- import type {GeoJSONTile, GeoJSONTileFeature} from './lib/geojsonvt/tile';
16
- import {convert} from './lib/geojsonvt/convert'; // GeoJSON conversion and preprocessing
17
- import {clip} from './lib/geojsonvt/clip'; // stripe clipping algorithm
18
- import {wrap} from './lib/geojsonvt/wrap'; // date line processing
19
- import {transformTile} from './lib/geojsonvt/transform'; // coordinate transformation
20
- import {createTile} from './lib/geojsonvt/tile'; // final simplified tile generation
21
-
22
- /** Options to configure tiling */
23
- export type GeoJSONTileSourceOptions = VectorTileSourceProps & {
24
- maxZoom?: number /** max zoom to preserve detail on */;
25
- indexMaxZoom?: number /** max zoom in the tile index */;
26
- indexMaxPoints?: number /** max number of points per tile in the tile index */;
27
- tolerance?: number /** simplification tolerance (higher means simpler) */;
28
- extent?: number /** tile extent */;
29
- buffer?: number /** tile buffer on each side */;
30
- lineMetrics?: boolean /** whether to calculate line metrics */;
31
- promoteId?: string /** name of a feature property to be promoted to feature.id */;
32
- generateId?: boolean /** whether to generate feature ids. Cannot be used with promoteId */;
33
- debug?: number /** logging level (0, 1 or 2) */;
34
- };
35
-
36
- export class GeoJSONTileSource implements VectorTileSource<any> {
37
- static defaultOptions: Required<GeoJSONTileSourceOptions> = {
38
- maxZoom: 14, // max zoom to preserve detail on
39
- indexMaxZoom: 5, // max zoom in the tile index
40
- indexMaxPoints: 100000, // max number of points per tile in the tile index
41
- tolerance: 3, // simplification tolerance (higher means simpler)
42
- extent: 4096, // tile extent
43
- buffer: 64, // tile buffer on each side
44
- lineMetrics: false, // whether to calculate line metrics
45
- // @ts-expect-error
46
- promoteId: undefined, // name of a feature property to be promoted to feature.id
47
- generateId: false, // whether to generate feature ids. Cannot be used with promoteId
48
- debug: 0 // logging level (0, 1 or 2)
49
- };
50
-
51
- mimeType = 'application/vnd.mapbox-vector-tile';
52
-
53
- options: Required<GeoJSONTileSourceOptions>;
54
-
55
- // tiles and tileCoords are part of the public API
56
- tiles: Record<string, GeoJSONTile> = {};
57
- tileCoords: {x: number; y: number; z: number}[] = [];
58
-
59
- stats: Record<string, number> = {};
60
- total: number = 0;
61
-
62
- /** Sync methods can be called: the input data promise has been resolved and initial top-level tiling is done */
63
- ready: Promise<void>;
64
-
65
- constructor(data: GeoJSONTable | Promise<GeoJSONTable>, options?: GeoJSONTileSourceOptions) {
66
- this.options = {...GeoJSONTileSource.defaultOptions, ...options};
67
- this.getTileData = this.getTileData.bind(this);
68
- this.ready = this.initializeTilesAsync(data);
69
- }
70
-
71
- async initializeTilesAsync(dataPromise: GeoJSONTable | Promise<GeoJSONTable>): Promise<void> {
72
- const data = await dataPromise;
73
- this.initializeTilesSync(data);
74
- }
75
-
76
- initializeTilesSync(data: GeoJSONTable): void {
77
- const options = this.options;
78
- const debug = options.debug;
79
-
80
- if (debug) console.time('preprocess data');
81
-
82
- if (this.options.maxZoom < 0 || this.options.maxZoom > 24) {
83
- throw new Error('maxZoom should be in the 0-24 range');
84
- }
85
- if (options.promoteId && this.options.generateId) {
86
- throw new Error('promoteId and generateId cannot be used together.');
87
- }
88
-
89
- // projects and adds simplification info
90
- let features = convert(data, options);
91
-
92
- if (debug) {
93
- console.timeEnd('preprocess data');
94
- console.log(
95
- 'index: maxZoom: %d, maxPoints: %d',
96
- options.indexMaxZoom,
97
- options.indexMaxPoints
98
- );
99
- console.time('generate tiles');
100
- }
101
-
102
- // wraps features (ie extreme west and extreme east)
103
- features = wrap(features, this.options);
104
-
105
- // start slicing from the top tile down
106
- if (features.length) {
107
- this.splitTile(features, 0, 0, 0);
108
- }
109
-
110
- if (debug) {
111
- if (features.length) {
112
- console.log('features: %d, points: %d', this.tiles[0].numFeatures, this.tiles[0].numPoints);
113
- }
114
- console.timeEnd('generate tiles');
115
- console.log('tiles generated:', this.total, JSON.stringify(this.stats));
116
- }
117
- }
118
-
119
- async getMetadata(): Promise<unknown> {
120
- return {};
121
- }
122
-
123
- /**
124
- * Get a tile at the specified index
125
- * @param tileIndex z, x, y of tile
126
- * @returns
127
- */
128
- async getVectorTile(tileIndex: {z: number; x: number; y: number}): Promise<GeoJSONTable | null> {
129
- await this.ready;
130
- const table = this.getTileSync(tileIndex);
131
- return table;
132
- }
133
-
134
- async getTile(tileIndex: {z: number; x: number; y: number}): Promise<GeoJSONTable | null> {
135
- await this.ready;
136
- return this.getTileSync(tileIndex);
137
- }
138
-
139
- async getTileData(tileParams: TileLoadParameters): Promise<unknown | null> {
140
- const {x, y, z} = tileParams.index;
141
- return await this.getVectorTile({x, y, z});
142
- }
143
-
144
- // Implementation
145
-
146
- /**
147
- * Synchronously request a tile
148
- * @note Application must await `source.ready` before calling sync methods.
149
- */
150
- getTileSync(tileIndex: {z: number; x: number; y: number}): GeoJSONTable | null {
151
- const rawTile = this.getRawTile(tileIndex);
152
- if (!rawTile) {
153
- return null;
154
- }
155
-
156
- return convertToGeoJSONTable(rawTile, this.options.extent);
157
- }
158
-
159
- /**
160
- * Return geojsonvt-style "half formed" vector tile
161
- * @note Application must await `source.ready` before calling sync methods.
162
- */
163
- // eslint-disable-next-line complexity, max-statements
164
- getRawTile(tileIndex: {z: number; x: number; y: number}): GeoJSONTile | null {
165
- const {z, y} = tileIndex;
166
- let {x} = tileIndex;
167
- // z = +z;
168
- // x = +x;
169
- // y = +y;
170
-
171
- const {extent, debug} = this.options;
172
-
173
- if (z < 0 || z > 24) {
174
- return null;
175
- }
176
-
177
- const z2 = 1 << z;
178
- x = (x + z2) & (z2 - 1); // wrap tile x coordinate
179
-
180
- const id = toID(z, x, y);
181
- if (this.tiles[id]) {
182
- return transformTile(this.tiles[id], extent);
183
- }
184
-
185
- if (debug > 1) console.log('drilling down to z%d-%d-%d', z, x, y);
186
-
187
- let z0 = z;
188
- let x0 = x;
189
- let y0 = y;
190
- let parent;
191
-
192
- while (!parent && z0 > 0) {
193
- z0--;
194
- x0 = x0 >> 1;
195
- y0 = y0 >> 1;
196
- parent = this.tiles[toID(z0, x0, y0)];
197
- }
198
-
199
- if (!parent || !parent.source) {
200
- return null;
201
- }
202
-
203
- // if we found a parent tile containing the original geometry, we can drill down from it
204
- if (debug > 1) {
205
- console.log('found parent tile z%d-%d-%d', z0, x0, y0);
206
- console.time('drilling down');
207
- }
208
- this.splitTile(parent.source, z0, x0, y0, z, x, y);
209
- if (debug > 1) {
210
- console.timeEnd('drilling down');
211
- }
212
-
213
- return this.tiles[id] ? transformTile(this.tiles[id], extent) : null;
214
- }
215
-
216
- /**
217
- * splits features from a parent tile to sub-tiles.
218
- * @param z, x, and y are the coordinates of the parent tile
219
- * @param cz, cx, and cy are the coordinates of the target tile
220
- *
221
- * If no target tile is specified, splitting stops when we reach the maximum
222
- * zoom or the number of points is low as specified in the options.
223
- */
224
- // eslint-disable-next-line max-params, max-statements, complexity
225
- splitTile(
226
- features: GeoJSONTileFeature[],
227
- z: number,
228
- x: number,
229
- y: number,
230
- cz?: number,
231
- cx?: number,
232
- cy?: number
233
- ): void {
234
- const stack: any[] = [features, z, x, y];
235
- const options = this.options;
236
- const debug = options.debug;
237
-
238
- // avoid recursion by using a processing queue
239
- while (stack.length) {
240
- y = stack.pop();
241
- x = stack.pop();
242
- z = stack.pop();
243
- features = stack.pop();
244
-
245
- const z2 = 1 << z;
246
- const id = toID(z, x, y);
247
- let tile = this.tiles[id];
248
-
249
- if (!tile) {
250
- if (debug > 1) {
251
- console.time('creation');
252
- }
253
-
254
- tile = this.tiles[id] = createTile(features, z, x, y, options);
255
- this.tileCoords.push({z, x, y});
256
-
257
- if (debug) {
258
- if (debug > 1) {
259
- console.log(
260
- 'tile z%d-%d-%d (features: %d, points: %d, simplified: %d)',
261
- z,
262
- x,
263
- y,
264
- tile.numFeatures,
265
- tile.numPoints,
266
- tile.numSimplified
267
- );
268
- console.timeEnd('creation');
269
- }
270
- const key = `z${z}`;
271
- this.stats[key] = (this.stats[key] || 0) + 1;
272
- this.total++;
273
- }
274
- }
275
-
276
- // save reference to original geometry in tile so that we can drill down later if we stop now
277
- tile.source = features;
278
-
279
- // if it's the first-pass tiling
280
- if (cz === undefined) {
281
- // stop tiling if we reached max zoom, or if the tile is too simple
282
- if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints) continue;
283
- // if a drilldown to a specific tile
284
- } else if (z === options.maxZoom || z === cz) {
285
- // stop tiling if we reached base zoom or our target tile zoom
286
- continue;
287
- } else if (cz !== undefined) {
288
- // stop tiling if it's not an ancestor of the target tile
289
- const zoomSteps = cz - z;
290
- // @ts-expect-error TODO fix the types of cx cy
291
- if (x !== cx >> zoomSteps || y !== cy >> zoomSteps) continue;
292
- }
293
-
294
- // if we slice further down, no need to keep source geometry
295
- tile.source = null;
296
-
297
- if (features.length === 0) continue;
298
-
299
- if (debug > 1) console.time('clipping');
300
-
301
- // values we'll use for clipping
302
- const k1 = (0.5 * options.buffer) / options.extent;
303
- const k2 = 0.5 - k1;
304
- const k3 = 0.5 + k1;
305
- const k4 = 1 + k1;
306
-
307
- let tl: GeoJSONTileFeature[] | null = null;
308
- let bl: GeoJSONTileFeature[] | null = null;
309
- let tr: GeoJSONTileFeature[] | null = null;
310
- let br: GeoJSONTileFeature[] | null = null;
311
-
312
- let left = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, options);
313
- let right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, options);
314
-
315
- // @ts-expect-error - unclear why this is needed?
316
- features = null;
317
-
318
- if (left) {
319
- tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
320
- bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
321
- left = null;
322
- }
323
-
324
- if (right) {
325
- tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
326
- br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
327
- right = null;
328
- }
329
-
330
- if (debug > 1) console.timeEnd('clipping');
331
-
332
- stack.push(tl || [], z + 1, x * 2, y * 2);
333
- stack.push(bl || [], z + 1, x * 2, y * 2 + 1);
334
- stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
335
- stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1);
336
- }
337
- }
338
- }
339
-
340
- function toID(z, x, y): number {
341
- return ((1 << z) * y + x) * 32 + z;
342
- }
343
-
344
- function convertToGeoJSONTable(vtTile: GeoJSONTile, extent: number): GeoJSONTable {
345
- const features: Feature[] = [];
346
- for (const rawFeature of vtTile.features) {
347
- if (!rawFeature || !rawFeature.geometry) {
348
- continue;
349
- }
350
-
351
- let type:
352
- | 'Point'
353
- | 'MultiPoint'
354
- | 'LineString'
355
- | 'MultiLineString'
356
- | 'Polygon'
357
- | 'MultiPolygon';
358
-
359
- let coordinates: any;
360
-
361
- // raw geometry
362
- switch (rawFeature.type) {
363
- case 1:
364
- if (rawFeature.geometry.length === 1) {
365
- type = 'Point';
366
- coordinates = rawFeature.geometry[0];
367
- } else {
368
- type = 'MultiPoint';
369
- coordinates = rawFeature.geometry;
370
- }
371
- break;
372
- case 2:
373
- if (rawFeature.geometry.length === 1) {
374
- type = 'LineString';
375
- coordinates = rawFeature.geometry[0];
376
- } else {
377
- type = 'MultiLineString';
378
- coordinates = rawFeature.geometry;
379
- }
380
- break;
381
- case 3:
382
- if (rawFeature.geometry.length > 1) {
383
- type = 'MultiPolygon';
384
- coordinates = [rawFeature.geometry];
385
- } else {
386
- type = 'Polygon';
387
- coordinates = rawFeature.geometry;
388
- }
389
- break;
390
- default:
391
- continue;
392
- }
393
-
394
- coordinates = toLngLat(coordinates, extent);
395
-
396
- const feature: Feature = {
397
- type: 'Feature',
398
- geometry: {
399
- type,
400
- coordinates
401
- },
402
- properties: rawFeature.tags || {}
403
- };
404
-
405
- features.push(feature);
406
- }
407
-
408
- const table: GeoJSONTable = {
409
- shape: 'geojson-table',
410
- type: 'FeatureCollection',
411
- features
412
- };
413
-
414
- return table;
415
- }
416
-
417
- function toLngLat(coords: any, extent: number): any {
418
- if (Array.isArray(coords[0])) {
419
- return coords.map((c) => toLngLat(c, extent));
420
- }
421
- return [coords[0] / extent, coords[1] / extent];
422
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes