@loaders.gl/mvt 4.3.0-alpha.1 → 4.3.0-alpha.3

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 (93) hide show
  1. package/dist/dist.dev.js +1289 -807
  2. package/dist/dist.min.js +1 -1
  3. package/dist/index.cjs +923 -773
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +7 -6
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +6 -2
  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/parse-tilejson.js +1 -1
  13. package/dist/lib/utils/geometry-utils.d.ts +38 -1
  14. package/dist/lib/utils/geometry-utils.d.ts.map +1 -1
  15. package/dist/lib/utils/geometry-utils.js +65 -6
  16. package/dist/lib/vector-tile/vector-tile-feature.d.ts +28 -9
  17. package/dist/lib/vector-tile/vector-tile-feature.d.ts.map +1 -1
  18. package/dist/lib/vector-tile/vector-tile-feature.js +47 -50
  19. package/dist/lib/{geojsonvt/clip.d.ts → vector-tiler/features/clip-features.d.ts} +4 -4
  20. package/dist/lib/vector-tiler/features/clip-features.d.ts.map +1 -0
  21. package/dist/lib/{geojsonvt/clip.js → vector-tiler/features/clip-features.js} +4 -4
  22. package/dist/lib/vector-tiler/features/convert-feature.d.ts +18 -0
  23. package/dist/lib/vector-tiler/features/convert-feature.d.ts.map +1 -0
  24. package/dist/lib/vector-tiler/features/convert-feature.js +140 -0
  25. package/dist/lib/vector-tiler/features/proto-feature.d.ts +30 -0
  26. package/dist/lib/vector-tiler/features/proto-feature.d.ts.map +1 -0
  27. package/dist/lib/vector-tiler/features/proto-feature.js +52 -0
  28. package/dist/lib/{geojsonvt/simplify.d.ts → vector-tiler/features/simplify-path.d.ts} +2 -2
  29. package/dist/lib/vector-tiler/features/simplify-path.d.ts.map +1 -0
  30. package/dist/lib/{geojsonvt/simplify.js → vector-tiler/features/simplify-path.js} +3 -3
  31. package/dist/lib/{geojsonvt/wrap.d.ts → vector-tiler/features/wrap-features.d.ts} +5 -5
  32. package/dist/lib/vector-tiler/features/wrap-features.d.ts.map +1 -0
  33. package/dist/lib/{geojsonvt/wrap.js → vector-tiler/features/wrap-features.js} +33 -26
  34. package/dist/lib/vector-tiler/proto-tile.d.ts +40 -0
  35. package/dist/lib/vector-tiler/proto-tile.d.ts.map +1 -0
  36. package/dist/lib/vector-tiler/proto-tile.js +138 -0
  37. package/dist/lib/vector-tiler/tile-to-geojson.d.ts +12 -0
  38. package/dist/lib/vector-tiler/tile-to-geojson.d.ts.map +1 -0
  39. package/dist/lib/vector-tiler/tile-to-geojson.js +81 -0
  40. package/dist/lib/vector-tiler/transform-tile.d.ts +7 -0
  41. package/dist/lib/vector-tiler/transform-tile.d.ts.map +1 -0
  42. package/dist/lib/vector-tiler/transform-tile.js +41 -0
  43. package/dist/mvt-loader.d.ts +1 -1
  44. package/dist/mvt-loader.js +1 -1
  45. package/dist/mvt-source.d.ts +35 -18
  46. package/dist/mvt-source.d.ts.map +1 -1
  47. package/dist/mvt-source.js +30 -10
  48. package/dist/mvt-worker.js +101 -56
  49. package/dist/table-tile-source.d.ts +148 -0
  50. package/dist/table-tile-source.d.ts.map +1 -0
  51. package/dist/table-tile-source.js +420 -0
  52. package/dist/tilejson-loader.js +1 -1
  53. package/package.json +7 -6
  54. package/src/index.ts +14 -7
  55. package/src/lib/parse-mvt.ts +4 -33
  56. package/src/lib/parse-tilejson.ts +6 -6
  57. package/src/lib/utils/geometry-utils.ts +66 -1
  58. package/src/lib/vector-tile/vector-tile-feature.ts +65 -56
  59. package/src/lib/{geojsonvt/clip.ts → vector-tiler/features/clip-features.ts} +8 -8
  60. package/src/lib/vector-tiler/features/convert-feature.ts +191 -0
  61. package/src/lib/vector-tiler/features/proto-feature.ts +104 -0
  62. package/src/lib/{geojsonvt/simplify.ts → vector-tiler/features/simplify-path.ts} +8 -3
  63. package/src/lib/{geojsonvt/wrap.ts → vector-tiler/features/wrap-features.ts} +44 -29
  64. package/src/lib/vector-tiler/proto-tile.ts +217 -0
  65. package/src/lib/vector-tiler/tile-to-geojson.ts +105 -0
  66. package/src/lib/vector-tiler/transform-tile.ts +57 -0
  67. package/src/mvt-source.ts +47 -24
  68. package/src/table-tile-source.ts +553 -0
  69. package/src/tilejson-loader.ts +2 -2
  70. package/dist/geojson-tile-source.d.ts +0 -79
  71. package/dist/geojson-tile-source.d.ts.map +0 -1
  72. package/dist/geojson-tile-source.js +0 -319
  73. package/dist/lib/geojsonvt/clip.d.ts.map +0 -1
  74. package/dist/lib/geojsonvt/convert.d.ts +0 -10
  75. package/dist/lib/geojsonvt/convert.d.ts.map +0 -1
  76. package/dist/lib/geojsonvt/convert.js +0 -132
  77. package/dist/lib/geojsonvt/feature.d.ts +0 -3
  78. package/dist/lib/geojsonvt/feature.d.ts.map +0 -1
  79. package/dist/lib/geojsonvt/feature.js +0 -44
  80. package/dist/lib/geojsonvt/simplify.d.ts.map +0 -1
  81. package/dist/lib/geojsonvt/tile.d.ts +0 -38
  82. package/dist/lib/geojsonvt/tile.d.ts.map +0 -1
  83. package/dist/lib/geojsonvt/tile.js +0 -123
  84. package/dist/lib/geojsonvt/transform.d.ts +0 -7
  85. package/dist/lib/geojsonvt/transform.d.ts.map +0 -1
  86. package/dist/lib/geojsonvt/transform.js +0 -41
  87. package/dist/lib/geojsonvt/wrap.d.ts.map +0 -1
  88. package/src/geojson-tile-source.ts +0 -422
  89. package/src/lib/geojsonvt/convert.ts +0 -160
  90. package/src/lib/geojsonvt/feature.ts +0 -47
  91. package/src/lib/geojsonvt/tile.ts +0 -187
  92. package/src/lib/geojsonvt/transform.ts +0 -57
  93. /package/src/lib/{geojsonvt → vector-tiler}/LICENSE +0 -0
@@ -0,0 +1,553 @@
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
+ import {Source} from '@loaders.gl/loader-utils';
7
+ import type {
8
+ VectorTileSourceProps,
9
+ GetTileDataParameters,
10
+ GetTileParameters,
11
+ LoaderWithParser
12
+ } from '@loaders.gl/loader-utils';
13
+ import {VectorTileSource, TileSourceMetadata, log} from '@loaders.gl/loader-utils';
14
+ import {Schema, GeoJSONTable, Feature, BinaryFeatureCollection} from '@loaders.gl/schema';
15
+ import {deduceTableSchema} from '@loaders.gl/schema';
16
+ import {Stats, Stat} from '@probe.gl/stats';
17
+
18
+ import type {ProtoFeature} from './lib/vector-tiler/features/proto-feature';
19
+ import type {ProtoTile} from './lib/vector-tiler/proto-tile';
20
+ import {createProtoTile} from './lib/vector-tiler/proto-tile';
21
+ import {transformTile} from './lib/vector-tiler/transform-tile'; // coordinate transformation
22
+ import {convertTileToGeoJSON} from './lib/vector-tiler/tile-to-geojson'; // tile clipping and wrapping
23
+ import {convertFeaturesToProtoFeature} from './lib/vector-tiler/features/convert-feature';
24
+ import {clipFeatures} from './lib/vector-tiler/features/clip-features'; // stripe clipping algorithm
25
+ import {wrapFeatures} from './lib/vector-tiler/features/wrap-features'; // date line processing
26
+
27
+ /** Options to configure tiling */
28
+ export const TableTileSource = {
29
+ name: 'TableTiler',
30
+ id: 'table-tiler',
31
+ version: '0.0.0',
32
+ extensions: ['mvt'],
33
+ mimeTypes: ['application/octet-stream'],
34
+ options: {
35
+ table: {
36
+ coordinates: 'local',
37
+ promoteId: undefined!,
38
+ maxZoom: 14,
39
+ indexMaxZoom: 5,
40
+ maxPointsPerTile: 10000,
41
+ tolerance: 3,
42
+ extent: 4096,
43
+ buffer: 64,
44
+ generateId: undefined
45
+ }
46
+ },
47
+ type: 'table',
48
+ testURL: (url: string): boolean => url.endsWith('.geojson'),
49
+ createDataSource(
50
+ url: string | Blob | GeoJSONTable | Promise<GeoJSONTable>,
51
+ options: DynamicVectorTileSourceProps
52
+ ): DynamicVectorTileSource {
53
+ const needsLoading = typeof url === 'string' || url instanceof Blob;
54
+ const loader = options?.table?.loaders?.[0]!;
55
+ const tablePromise = needsLoading ? loadTable(url, loader) : url;
56
+ return new DynamicVectorTileSource(tablePromise, options);
57
+ }
58
+ // @ts-expect-error
59
+ } as const satisfies Source<DynamicVectorTileSource, DynamicVectorTileSourceProps>;
60
+
61
+ async function loadTable(url: string | Blob, loader: LoaderWithParser): Promise<GeoJSONTable> {
62
+ if (typeof url === 'string') {
63
+ const response = await fetch(url);
64
+ const data = await response.arrayBuffer();
65
+ return (await loader.parse(data)) as GeoJSONTable;
66
+ }
67
+
68
+ const data = await url.arrayBuffer();
69
+ return (await loader.parse(data)) as GeoJSONTable; // options.loaders, options.loadOptions)
70
+ }
71
+
72
+ /** Options to configure tiling */
73
+ export type DynamicVectorTileSourceProps = VectorTileSourceProps & {
74
+ table: {
75
+ coordinates: 'local' | 'wgs84' | 'EPSG:4326';
76
+ /** max zoom to preserve detail on */
77
+ maxZoom?: number;
78
+ /** max zoom in the tile index */
79
+ indexMaxZoom?: number;
80
+ /** max number of points per tile in the tile index */
81
+ maxPointsPerTile?: number;
82
+ /** simplification tolerance (higher means simpler) */
83
+ tolerance?: number;
84
+ /** tile extent */
85
+ extent?: number;
86
+ /** tile buffer on each side */
87
+ buffer?: number;
88
+ /** name of a feature property to be promoted to feature.id */
89
+ promoteId?: string;
90
+ /** whether to generate feature ids. Cannot be used with promoteId */
91
+ generateId?: boolean;
92
+ /** logging level (0, 1 or 2) */
93
+ debug?: number;
94
+ /** whether to calculate line metrics */
95
+ lineMetrics?: boolean;
96
+ /** table loders */
97
+ loaders?: LoaderWithParser[];
98
+ };
99
+ };
100
+
101
+ /**
102
+ * Dynamically vector tiles a table (the table needs a geometry column)
103
+ * - Tiles are generated when requested.
104
+ * - Each tile contains a tables of clipped features.
105
+ *
106
+ * @note - Currently only accepts `GeoJSONTable` tables
107
+ * @note - Currently only outputs `GeoJSONTable`
108
+ * @note - (can be initialized with a promise that resolves to GeoJSONTable).
109
+ *
110
+ * @todo - metadata should scan all rows to determine schema
111
+ * @todo - metadata scan all rows to determine tilestats (field values[] etc).
112
+ * @todo - handle binary input tables
113
+ * @todo - generate binary output tables
114
+ * @todo - how does TileSourceLayer specify coordinates / decided which layer to render with
115
+ */
116
+ export class DynamicVectorTileSource
117
+ implements VectorTileSource<DynamicVectorTileSourceProps, TileSourceMetadata>
118
+ {
119
+ /** Global stats for all DynamicVectorTileSources */
120
+ static stats = new Stats({
121
+ id: 'table-tile-source-all',
122
+ stats: [new Stat('count', 'tiles'), new Stat('count', 'features')]
123
+ });
124
+
125
+ /** Stats for this DynamicVectorTileSource */
126
+ stats = new Stats({
127
+ id: 'table-tile-source',
128
+ stats: [new Stat('tiles', 'count'), new Stat('features', 'count')]
129
+ });
130
+
131
+ /** MIME type of the tiles emitted by this tile source */
132
+ readonly mimeType = 'application/vnd.mapbox-vector-tile';
133
+ readonly localCoordinates = true;
134
+
135
+ /** The props that this tile source was created with */
136
+ // @ts-expect-error
137
+ props: Required<DynamicVectorTileSourceProps['table']>;
138
+
139
+ /* Schema of the data */
140
+ schema: Schema | null = null;
141
+
142
+ /** Map of generated tiles, indexed by stringified tile coordinates */
143
+ tiles: Record<string, ProtoTile> = {};
144
+ /** Array of tile coordinates */
145
+ tileCoords: {x: number; y: number; z: number}[] = [];
146
+
147
+ /** Input data has loaded, initial top-level tiling is done, sync methods can now be called */
148
+ ready: Promise<void>;
149
+ /** Metadata for the tile source (generated TileJSON/tilestats */
150
+ metadata: Promise<unknown>;
151
+
152
+ constructor(table: GeoJSONTable | Promise<GeoJSONTable>, props?: DynamicVectorTileSourceProps) {
153
+ // @ts-expect-error
154
+ this.props = {...TableTileSource.options.table, ...props?.table};
155
+ this.getTileData = this.getTileData.bind(this);
156
+ this.ready = this.initializeTilesAsync(table);
157
+ this.metadata = this.getMetadata();
158
+ }
159
+
160
+ async initializeTilesAsync(tablePromise: GeoJSONTable | Promise<GeoJSONTable>): Promise<void> {
161
+ const table = await tablePromise;
162
+ this.schema = deduceTableSchema(table);
163
+ this.createRootTiles(table);
164
+ }
165
+
166
+ async getMetadata(): Promise<TileSourceMetadata & {schema: Schema | null}> {
167
+ await this.ready;
168
+ return {schema: this.schema, minZoom: 0, maxZoom: this.props.maxZoom};
169
+ }
170
+
171
+ async getSchema(): Promise<Schema> {
172
+ await this.ready;
173
+ return this.schema!;
174
+ }
175
+
176
+ /**
177
+ * Get a tile at the specified index
178
+ * @param tileIndex z, x, y of tile
179
+ * @returns
180
+ */
181
+ async getVectorTile(tileIndex: GetTileParameters): Promise<GeoJSONTable | null> {
182
+ await this.ready;
183
+ const table = this.getTileSync(tileIndex);
184
+ log.info(2, 'getVectorTile', tileIndex, table)();
185
+ return table;
186
+ }
187
+
188
+ async getTile(tileIndex: {z: number; x: number; y: number}): Promise<GeoJSONTable | null> {
189
+ await this.ready;
190
+ return this.getTileSync(tileIndex);
191
+ }
192
+
193
+ async getTileData(
194
+ tileParams: GetTileDataParameters
195
+ ): Promise<Feature[] | BinaryFeatureCollection> {
196
+ const {x, y, z} = tileParams.index;
197
+ const tile = await this.getVectorTile({x, y, z});
198
+ return tile?.features || [];
199
+ }
200
+
201
+ // Implementation
202
+
203
+ /**
204
+ * Synchronously request a tile
205
+ * @note Application must await `source.ready` before calling sync methods.
206
+ */
207
+ getTileSync(tileIndex: {z: number; x: number; y: number}): GeoJSONTable | null {
208
+ const protoTile = this.getProtoTile(tileIndex);
209
+ if (!protoTile) {
210
+ return null;
211
+ }
212
+
213
+ return convertTileToGeoJSON(protoTile, {
214
+ coordinates: this.props.coordinates,
215
+ tileIndex,
216
+ extent: this.props.extent
217
+ });
218
+ }
219
+
220
+ /**
221
+ * Create the initial tiles
222
+ * @note the tiles stores all the features together with additional data
223
+ */
224
+ createRootTiles(table: GeoJSONTable): void {
225
+ if (this.props.maxZoom < 0 || this.props.maxZoom > 24) {
226
+ throw new Error('maxZoom should be in the 0-24 range');
227
+ }
228
+ if (this.props.promoteId && this.props.generateId) {
229
+ throw new Error('promoteId and generateId cannot be used together.');
230
+ }
231
+
232
+ log.log(1, 'DynamicVectorTileSource creating root tiles', this.props)();
233
+
234
+ // projects and adds simplification info
235
+ log.time(1, 'preprocess table')();
236
+ let features = convertFeaturesToProtoFeature(table, this.props);
237
+ log.timeEnd(1, 'preprocess table')();
238
+
239
+ // wraps features (ie extreme west and extreme east)
240
+ log.time(1, 'generate tiles')();
241
+
242
+ features = wrapFeatures(features, this.props);
243
+
244
+ // start slicing from the top tile down
245
+ if (features.length === 0) {
246
+ log.log(1, 'DynamicVectorTileSource: no features generated')();
247
+ return;
248
+ }
249
+
250
+ this.splitTile(features, 0, 0, 0);
251
+
252
+ const rootTile = this.tiles[0];
253
+ log.log(1, `root tile features: ${rootTile.numFeatures}, points: ${rootTile.numPoints}`)();
254
+
255
+ log.timeEnd(1, 'generate tiles')();
256
+ log.log(
257
+ 1,
258
+ `DynamicVectorTileSource: tiles generated: ${this.stats.get('total').count}`,
259
+ this.stats
260
+ )();
261
+ }
262
+
263
+ /**
264
+ * Return geojsonvt-style "half formed" vector tile
265
+ * @note Application must await `source.ready` before calling sync methods.
266
+ */
267
+ // eslint-disable-next-line complexity, max-statements
268
+ getProtoTile(tileIndex: {z: number; x: number; y: number}): ProtoTile | null {
269
+ const {z, y} = tileIndex;
270
+ let {x} = tileIndex;
271
+ // z = +z;
272
+ // x = +x;
273
+ // y = +y;
274
+
275
+ const {extent} = this.props;
276
+
277
+ if (z < 0 || z > 24) {
278
+ return null;
279
+ }
280
+
281
+ const z2 = 1 << z;
282
+ x = (x + z2) & (z2 - 1); // wrapFeatures tile x coordinate
283
+
284
+ const id = toID(z, x, y);
285
+ if (this.tiles[id]) {
286
+ return transformTile(this.tiles[id], extent);
287
+ }
288
+
289
+ log.log(log, 'drilling down to z%d-%d-%d', z, x, y)();
290
+
291
+ let z0 = z;
292
+ let x0 = x;
293
+ let y0 = y;
294
+ let parent;
295
+
296
+ while (!parent && z0 > 0) {
297
+ z0--;
298
+ x0 = x0 >> 1;
299
+ y0 = y0 >> 1;
300
+ parent = this.tiles[toID(z0, x0, y0)];
301
+ }
302
+
303
+ if (!parent || !parent.sourceFeatures) {
304
+ return null;
305
+ }
306
+
307
+ // if we found a parent tile containing the original geometry, we can drill down from it
308
+ log.log(1, 'found parent tile z%d-%d-%d', z0, x0, y0)();
309
+ log.time(1, 'drilling down')();
310
+
311
+ this.splitTile(parent.sourceFeatures, z0, x0, y0, z, x, y);
312
+
313
+ log.timeEnd(1, 'drilling down')();
314
+
315
+ return this.tiles[id] ? transformTile(this.tiles[id], extent) : null;
316
+ }
317
+
318
+ /**
319
+ * splits features from a parent tile to sub-tiles.
320
+ * @param z, x, and y are the coordinates of the parent tile
321
+ * @param cz, cx, and cy are the coordinates of the target tile
322
+ *
323
+ * If no target tile is specified, splitting stops when we reach the maximum
324
+ * zoom or the number of points is low as specified in the props.
325
+ */
326
+ // eslint-disable-next-line max-params, max-statements, complexity
327
+ splitTile(
328
+ features: ProtoFeature[],
329
+ z: number,
330
+ x: number,
331
+ y: number,
332
+ cz?: number,
333
+ cx?: number,
334
+ cy?: number
335
+ ): void {
336
+ const stack: any[] = [features, z, x, y];
337
+
338
+ // avoid recursion by using a processing queue
339
+ while (stack.length) {
340
+ y = stack.pop();
341
+ x = stack.pop();
342
+ z = stack.pop();
343
+ features = stack.pop();
344
+
345
+ const z2 = 1 << z;
346
+ const id = toID(z, x, y);
347
+ let tile = this.tiles[id];
348
+
349
+ if (!tile) {
350
+ log.time(2, 'tile creation')();
351
+
352
+ tile = this.tiles[id] = createProtoTile(features, z, x, y, this.props);
353
+ this.tileCoords.push({z, x, y});
354
+
355
+ const key = `z${z}`;
356
+ let stat = this.stats.get(key, 'count');
357
+ stat.incrementCount();
358
+
359
+ stat = this.stats.get('total');
360
+ stat.incrementCount();
361
+
362
+ stat = DynamicVectorTileSource.stats.get(key, 'count');
363
+ stat.incrementCount();
364
+
365
+ stat = DynamicVectorTileSource.stats.get('total');
366
+ stat.incrementCount();
367
+
368
+ log.log(
369
+ 2,
370
+ 'tile z%d-%d-%d (features: %d, points: %d, simplified: %d)',
371
+ z,
372
+ x,
373
+ y,
374
+ tile.numFeatures,
375
+ tile.numPoints,
376
+ tile.numSimplified
377
+ )();
378
+ log.timeEnd(2, 'tile creation')();
379
+ }
380
+
381
+ // save reference to original geometry in tile so that we can drill down later if we stop now
382
+ tile.sourceFeatures = features;
383
+
384
+ /* eslint-disable no-continue */
385
+
386
+ // if it's the first-pass tiling
387
+ if (cz === undefined) {
388
+ // stop tiling if we reached max zoom, or if the tile is too simple
389
+ if (z === this.props.indexMaxZoom || tile.numPoints <= this.props.maxPointsPerTile) {
390
+ continue;
391
+ }
392
+ // if a drilldown to a specific tile
393
+ } else if (z === this.props.maxZoom || z === cz) {
394
+ // stop tiling if we reached base zoom or our target tile zoom
395
+ continue;
396
+ } else if (cz !== undefined) {
397
+ // stop tiling if it's not an ancestor of the target tile
398
+ const zoomSteps = cz - z;
399
+ // @ts-expect-error TODO fix the types of cx cy
400
+ if (x !== cx >> zoomSteps || y !== cy >> zoomSteps) {
401
+ continue;
402
+ }
403
+ }
404
+
405
+ // if we slice further down, no need to keep source geometry
406
+ tile.sourceFeatures = null;
407
+
408
+ if (features.length === 0) continue;
409
+
410
+ log.time(2, 'clipping tile')();
411
+
412
+ // values we'll use for clipping
413
+ const k1 = (0.5 * this.props.buffer) / this.props.extent;
414
+ const k2 = 0.5 - k1;
415
+ const k3 = 0.5 + k1;
416
+ const k4 = 1 + k1;
417
+
418
+ let tl: ProtoFeature[] | null = null;
419
+ let bl: ProtoFeature[] | null = null;
420
+ let tr: ProtoFeature[] | null = null;
421
+ let br: ProtoFeature[] | null = null;
422
+
423
+ let left = clipFeatures(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, this.props);
424
+ let right = clipFeatures(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, this.props);
425
+
426
+ // @ts-expect-error - unclear why this is needed?
427
+ features = null;
428
+
429
+ if (left) {
430
+ tl = clipFeatures(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, this.props);
431
+ bl = clipFeatures(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, this.props);
432
+ left = null;
433
+ }
434
+
435
+ if (right) {
436
+ tr = clipFeatures(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, this.props);
437
+ br = clipFeatures(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, this.props);
438
+ right = null;
439
+ }
440
+
441
+ log.timeEnd(2, 'clipping tile')();
442
+
443
+ stack.push(tl || [], z + 1, x * 2, y * 2);
444
+ stack.push(bl || [], z + 1, x * 2, y * 2 + 1);
445
+ stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
446
+ stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1);
447
+ }
448
+ }
449
+ }
450
+
451
+ function toID(z, x, y): number {
452
+ return ((1 << z) * y + x) * 32 + z;
453
+ }
454
+ /*
455
+
456
+ // eslint-disable-next-line max-statements, complexity
457
+ function convertToGeoJSONTable(
458
+ vtTile: ProtoTile,
459
+ props: {
460
+ coordinates: 'local' | 'wgs84' | 'EPSG:4326';
461
+ tileIndex: {x: number; y: number; z: number};
462
+ extent: number;
463
+ }
464
+ ): GeoJSONTable | null {
465
+ const features: Feature[] = [];
466
+ for (const rawFeature of vtTile.features) {
467
+ if (!rawFeature || !rawFeature.geometry) {
468
+ continue;
469
+ }
470
+
471
+ let type:
472
+ | 'Point'
473
+ | 'MultiPoint'
474
+ | 'LineString'
475
+ | 'MultiLineString'
476
+ | 'Polygon'
477
+ | 'MultiPolygon';
478
+
479
+ let coordinates: any;
480
+
481
+ // raw geometry
482
+ switch (rawFeature.type) {
483
+ case 1:
484
+ if (rawFeature.geometry.length === 1) {
485
+ type = 'Point';
486
+ coordinates = rawFeature.geometry[0];
487
+ } else {
488
+ type = 'MultiPoint';
489
+ coordinates = rawFeature.geometry;
490
+ }
491
+ break;
492
+ case 2:
493
+ if (rawFeature.geometry.length === 1) {
494
+ type = 'LineString';
495
+ coordinates = rawFeature.geometry[0];
496
+ } else {
497
+ type = 'MultiLineString';
498
+ coordinates = rawFeature.geometry;
499
+ }
500
+ break;
501
+ case 3:
502
+ if (rawFeature.geometry.length > 1) {
503
+ type = 'MultiPolygon';
504
+ coordinates = [rawFeature.geometry];
505
+ } else {
506
+ type = 'Polygon';
507
+ coordinates = rawFeature.geometry;
508
+ }
509
+ break;
510
+ default:
511
+ continue;
512
+ }
513
+
514
+ switch (props.coordinates) {
515
+ case 'EPSG:4326':
516
+ case 'wgs84':
517
+ projectToLngLat(coordinates, props.tileIndex, props.extent);
518
+ break;
519
+
520
+ case 'local':
521
+ convertToLocalCoordinates(coordinates, props.extent);
522
+ break;
523
+
524
+ default:
525
+ throw new Error(`Unsupported CRS ${props.coordinates}`);
526
+ }
527
+
528
+ const feature: Feature = {
529
+ type: 'Feature',
530
+ geometry: {
531
+ type,
532
+ coordinates
533
+ },
534
+ properties: rawFeature.tags || {},
535
+ id: rawFeature.id
536
+ };
537
+
538
+ features.push(feature);
539
+ }
540
+
541
+ if (features.length === 0) {
542
+ return null;
543
+ }
544
+
545
+ const table: GeoJSONTable = {
546
+ shape: 'geojson-table',
547
+ type: 'FeatureCollection',
548
+ features
549
+ };
550
+
551
+ return table;
552
+ }
553
+ */
@@ -38,13 +38,13 @@ export const TileJSONLoader = {
38
38
  maxValues: undefined
39
39
  }
40
40
  },
41
- parse: async (arrayBuffer, options?: TileJSONLoaderOptions) => {
41
+ parse: async (arrayBuffer: ArrayBuffer, options?: TileJSONLoaderOptions) => {
42
42
  const jsonString = new TextDecoder().decode(arrayBuffer);
43
43
  const json = JSON.parse(jsonString);
44
44
  const tilejsonOptions = {...TileJSONLoader.options.tilejson, ...options?.tilejson};
45
45
  return parseTileJSON(json, tilejsonOptions) as TileJSON;
46
46
  },
47
- parseTextSync: (text, options) => {
47
+ parseTextSync: (text: string, options?: TileJSONLoaderOptions) => {
48
48
  const json = JSON.parse(text);
49
49
  const tilejsonOptions = {...TileJSONLoader.options.tilejson, ...options?.tilejson};
50
50
  return parseTileJSON(json, tilejsonOptions) as TileJSON;
@@ -1,79 +0,0 @@
1
- import { VectorTileSource, VectorTileSourceProps, TileLoadParameters } from '@loaders.gl/loader-utils';
2
- import { GeoJSONTable } from '@loaders.gl/schema';
3
- import type { GeoJSONTile, GeoJSONTileFeature } from "./lib/geojsonvt/tile.js";
4
- /** Options to configure tiling */
5
- export type GeoJSONTileSourceOptions = VectorTileSourceProps & {
6
- maxZoom?: number /** max zoom to preserve detail on */;
7
- indexMaxZoom?: number /** max zoom in the tile index */;
8
- indexMaxPoints?: number /** max number of points per tile in the tile index */;
9
- tolerance?: number /** simplification tolerance (higher means simpler) */;
10
- extent?: number /** tile extent */;
11
- buffer?: number /** tile buffer on each side */;
12
- lineMetrics?: boolean /** whether to calculate line metrics */;
13
- promoteId?: string /** name of a feature property to be promoted to feature.id */;
14
- generateId?: boolean /** whether to generate feature ids. Cannot be used with promoteId */;
15
- debug?: number /** logging level (0, 1 or 2) */;
16
- };
17
- export declare class GeoJSONTileSource implements VectorTileSource<any> {
18
- static defaultOptions: Required<GeoJSONTileSourceOptions>;
19
- mimeType: string;
20
- options: Required<GeoJSONTileSourceOptions>;
21
- tiles: Record<string, GeoJSONTile>;
22
- tileCoords: {
23
- x: number;
24
- y: number;
25
- z: number;
26
- }[];
27
- stats: Record<string, number>;
28
- total: number;
29
- /** Sync methods can be called: the input data promise has been resolved and initial top-level tiling is done */
30
- ready: Promise<void>;
31
- constructor(data: GeoJSONTable | Promise<GeoJSONTable>, options?: GeoJSONTileSourceOptions);
32
- initializeTilesAsync(dataPromise: GeoJSONTable | Promise<GeoJSONTable>): Promise<void>;
33
- initializeTilesSync(data: GeoJSONTable): void;
34
- getMetadata(): Promise<unknown>;
35
- /**
36
- * Get a tile at the specified index
37
- * @param tileIndex z, x, y of tile
38
- * @returns
39
- */
40
- getVectorTile(tileIndex: {
41
- z: number;
42
- x: number;
43
- y: number;
44
- }): Promise<GeoJSONTable | null>;
45
- getTile(tileIndex: {
46
- z: number;
47
- x: number;
48
- y: number;
49
- }): Promise<GeoJSONTable | null>;
50
- getTileData(tileParams: TileLoadParameters): Promise<unknown | null>;
51
- /**
52
- * Synchronously request a tile
53
- * @note Application must await `source.ready` before calling sync methods.
54
- */
55
- getTileSync(tileIndex: {
56
- z: number;
57
- x: number;
58
- y: number;
59
- }): GeoJSONTable | null;
60
- /**
61
- * Return geojsonvt-style "half formed" vector tile
62
- * @note Application must await `source.ready` before calling sync methods.
63
- */
64
- getRawTile(tileIndex: {
65
- z: number;
66
- x: number;
67
- y: number;
68
- }): GeoJSONTile | null;
69
- /**
70
- * splits features from a parent tile to sub-tiles.
71
- * @param z, x, and y are the coordinates of the parent tile
72
- * @param cz, cx, and cy are the coordinates of the target tile
73
- *
74
- * If no target tile is specified, splitting stops when we reach the maximum
75
- * zoom or the number of points is low as specified in the options.
76
- */
77
- splitTile(features: GeoJSONTileFeature[], z: number, x: number, y: number, cz?: number, cx?: number, cy?: number): void;
78
- }
79
- //# sourceMappingURL=geojson-tile-source.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"geojson-tile-source.d.ts","sourceRoot":"","sources":["../src/geojson-tile-source.ts"],"names":[],"mappings":"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"}