@loaders.gl/mvt 4.2.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 (120) hide show
  1. package/dist/dist.dev.js +1784 -847
  2. package/dist/dist.min.js +1 -1
  3. package/dist/index.cjs +713 -640
  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 +2 -1
  9. package/dist/lib/parse-mvt.d.ts.map +1 -1
  10. package/dist/lib/parse-mvt.js +15 -45
  11. package/dist/lib/parse-tilejson.d.ts +4 -4
  12. package/dist/lib/parse-tilejson.d.ts.map +1 -1
  13. package/dist/lib/types.d.ts +1 -39
  14. package/dist/lib/types.d.ts.map +1 -1
  15. package/dist/lib/utils/geometry-utils.d.ts +83 -0
  16. package/dist/lib/utils/geometry-utils.d.ts.map +1 -0
  17. package/dist/lib/utils/geometry-utils.js +206 -0
  18. package/dist/lib/vector-tile/vector-tile-feature.d.ts +72 -0
  19. package/dist/lib/vector-tile/vector-tile-feature.d.ts.map +1 -0
  20. package/dist/lib/vector-tile/vector-tile-feature.js +342 -0
  21. package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.d.ts +10 -1
  22. package/dist/lib/vector-tile/vector-tile-layer.d.ts.map +1 -0
  23. package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.js +16 -1
  24. package/dist/lib/vector-tile/vector-tile.d.ts.map +1 -0
  25. package/dist/lib/{geojson-tiler → vector-tiler}/clip.d.ts +3 -3
  26. package/dist/lib/vector-tiler/clip.d.ts.map +1 -0
  27. package/dist/lib/vector-tiler/convert.d.ts +18 -0
  28. package/dist/lib/vector-tiler/convert.d.ts.map +1 -0
  29. package/dist/lib/{geojson-tiler → vector-tiler}/convert.js +8 -1
  30. package/dist/lib/vector-tiler/feature.d.ts +3 -0
  31. package/dist/lib/vector-tiler/feature.d.ts.map +1 -0
  32. package/dist/lib/vector-tiler/simplify.d.ts.map +1 -0
  33. package/dist/lib/{geojson-tiler → vector-tiler}/tile.d.ts +4 -4
  34. package/dist/lib/vector-tiler/tile.d.ts.map +1 -0
  35. package/dist/lib/vector-tiler/transform.d.ts +7 -0
  36. package/dist/lib/vector-tiler/transform.d.ts.map +1 -0
  37. package/dist/lib/{geojson-tiler → vector-tiler}/wrap.d.ts +2 -2
  38. package/dist/lib/vector-tiler/wrap.d.ts.map +1 -0
  39. package/dist/mvt-loader.d.ts +19 -8
  40. package/dist/mvt-loader.d.ts.map +1 -1
  41. package/dist/mvt-loader.js +3 -2
  42. package/dist/mvt-source.d.ts +4 -4
  43. package/dist/mvt-source.d.ts.map +1 -1
  44. package/dist/mvt-source.js +7 -7
  45. package/dist/mvt-worker.js +1244 -762
  46. package/dist/table-tile-source.d.ts +118 -0
  47. package/dist/table-tile-source.d.ts.map +1 -0
  48. package/dist/table-tile-source.js +370 -0
  49. package/dist/tilejson-loader.js +1 -1
  50. package/package.json +7 -6
  51. package/src/index.ts +3 -3
  52. package/src/lib/parse-mvt.ts +28 -66
  53. package/src/lib/parse-tilejson.ts +5 -5
  54. package/src/lib/types.ts +1 -39
  55. package/src/lib/utils/geometry-utils.ts +234 -0
  56. package/src/lib/vector-tile/vector-tile-feature.ts +416 -0
  57. package/src/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.ts +28 -2
  58. package/src/lib/{geojson-tiler → vector-tiler}/clip.ts +4 -4
  59. package/src/lib/{geojson-tiler → vector-tiler}/convert.ts +19 -9
  60. package/src/lib/{geojson-tiler → vector-tiler}/feature.ts +3 -3
  61. package/src/lib/{geojson-tiler → vector-tiler}/tile.ts +10 -10
  62. package/src/lib/{geojson-tiler → vector-tiler}/transform.ts +2 -2
  63. package/src/lib/{geojson-tiler → vector-tiler}/wrap.ts +5 -5
  64. package/src/mvt-loader.ts +14 -6
  65. package/src/mvt-source.ts +9 -10
  66. package/src/table-tile-source.ts +508 -0
  67. package/dist/helpers/binary-util-functions.d.ts +0 -35
  68. package/dist/helpers/binary-util-functions.d.ts.map +0 -1
  69. package/dist/helpers/binary-util-functions.js +0 -114
  70. package/dist/helpers/mapbox-util-functions.d.ts +0 -29
  71. package/dist/helpers/mapbox-util-functions.d.ts.map +0 -1
  72. package/dist/helpers/mapbox-util-functions.js +0 -78
  73. package/dist/lib/binary-vector-tile/vector-tile-feature.d.ts +0 -41
  74. package/dist/lib/binary-vector-tile/vector-tile-feature.d.ts.map +0 -1
  75. package/dist/lib/binary-vector-tile/vector-tile-feature.js +0 -163
  76. package/dist/lib/binary-vector-tile/vector-tile-layer.d.ts +0 -23
  77. package/dist/lib/binary-vector-tile/vector-tile-layer.d.ts.map +0 -1
  78. package/dist/lib/binary-vector-tile/vector-tile-layer.js +0 -96
  79. package/dist/lib/binary-vector-tile/vector-tile.d.ts +0 -9
  80. package/dist/lib/binary-vector-tile/vector-tile.d.ts.map +0 -1
  81. package/dist/lib/binary-vector-tile/vector-tile.js +0 -27
  82. package/dist/lib/geojson-tiler/clip.d.ts.map +0 -1
  83. package/dist/lib/geojson-tiler/convert.d.ts +0 -10
  84. package/dist/lib/geojson-tiler/convert.d.ts.map +0 -1
  85. package/dist/lib/geojson-tiler/feature.d.ts +0 -3
  86. package/dist/lib/geojson-tiler/feature.d.ts.map +0 -1
  87. package/dist/lib/geojson-tiler/geojson-tiler.d.ts +0 -44
  88. package/dist/lib/geojson-tiler/geojson-tiler.d.ts.map +0 -1
  89. package/dist/lib/geojson-tiler/geojson-tiler.js +0 -209
  90. package/dist/lib/geojson-tiler/simplify.d.ts.map +0 -1
  91. package/dist/lib/geojson-tiler/tile.d.ts.map +0 -1
  92. package/dist/lib/geojson-tiler/transform.d.ts +0 -7
  93. package/dist/lib/geojson-tiler/transform.d.ts.map +0 -1
  94. package/dist/lib/geojson-tiler/wrap.d.ts.map +0 -1
  95. package/dist/lib/mapbox-vector-tile/vector-tile-feature.d.ts +0 -27
  96. package/dist/lib/mapbox-vector-tile/vector-tile-feature.d.ts.map +0 -1
  97. package/dist/lib/mapbox-vector-tile/vector-tile-feature.js +0 -178
  98. package/dist/lib/mapbox-vector-tile/vector-tile-layer.d.ts.map +0 -1
  99. package/dist/lib/mapbox-vector-tile/vector-tile.d.ts.map +0 -1
  100. package/src/helpers/binary-util-functions.ts +0 -125
  101. package/src/helpers/mapbox-util-functions.ts +0 -82
  102. package/src/lib/binary-vector-tile/vector-tile-feature.ts +0 -203
  103. package/src/lib/binary-vector-tile/vector-tile-layer.ts +0 -113
  104. package/src/lib/binary-vector-tile/vector-tile.ts +0 -36
  105. package/src/lib/geojson-tiler/geojson-tiler.ts +0 -283
  106. package/src/lib/mapbox-vector-tile/LICENSE.txt +0 -31
  107. package/src/lib/mapbox-vector-tile/vector-tile-feature.ts +0 -207
  108. /package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile.d.ts +0 -0
  109. /package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile.js +0 -0
  110. /package/dist/lib/{geojson-tiler → vector-tiler}/clip.js +0 -0
  111. /package/dist/lib/{geojson-tiler → vector-tiler}/feature.js +0 -0
  112. /package/dist/lib/{geojson-tiler → vector-tiler}/simplify.d.ts +0 -0
  113. /package/dist/lib/{geojson-tiler → vector-tiler}/simplify.js +0 -0
  114. /package/dist/lib/{geojson-tiler → vector-tiler}/tile.js +0 -0
  115. /package/dist/lib/{geojson-tiler → vector-tiler}/transform.js +0 -0
  116. /package/dist/lib/{geojson-tiler → vector-tiler}/wrap.js +0 -0
  117. /package/src/lib/{binary-vector-tile → vector-tile}/LICENSE.txt +0 -0
  118. /package/src/lib/{mapbox-vector-tile → vector-tile}/vector-tile.ts +0 -0
  119. /package/src/lib/{geojson-tiler → vector-tiler}/LICENSE +0 -0
  120. /package/src/lib/{geojson-tiler → vector-tiler}/simplify.ts +0 -0
@@ -0,0 +1,416 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
4
+
5
+ // This code is forked from https://github.com/mapbox/vector-tile-js under BSD 3-clause license.
6
+ import {Feature} from '@loaders.gl/schema';
7
+ import {FlatFeature, FlatIndexedGeometry, GeojsonGeometryInfo} from '@loaders.gl/schema';
8
+ import Protobuf from 'pbf';
9
+ import {classifyRings, classifyRingsFlat} from '../utils/geometry-utils';
10
+ import {projectToLngLat, projectToLngLatFlat} from '../utils/geometry-utils';
11
+ import {convertToLocalCoordinates, convertToLocalCoordinatesFlat} from '../utils/geometry-utils';
12
+
13
+ export class VectorTileFeature {
14
+ properties: {[x: string]: string | number | boolean | null};
15
+ extent: any;
16
+ type: number;
17
+ id: number | null;
18
+ _pbf: Protobuf;
19
+ _geometry: number;
20
+ _keys: string[];
21
+ _values: (string | number | boolean | null)[];
22
+ _geometryInfo: GeojsonGeometryInfo;
23
+
24
+ static types: Readonly<string[]> = ['Unknown', 'Point', 'LineString', 'Polygon'];
25
+
26
+ // eslint-disable-next-line max-params
27
+ constructor(
28
+ pbf: Protobuf,
29
+ end: number,
30
+ extent: any,
31
+ keys: string[],
32
+ values: (string | number | boolean | null)[],
33
+ geometryInfo?: GeojsonGeometryInfo
34
+ ) {
35
+ // Public
36
+ this.properties = {};
37
+ this.extent = extent;
38
+ this.type = 0;
39
+ this.id = null;
40
+
41
+ // Private
42
+ this._pbf = pbf;
43
+ this._geometry = -1;
44
+ this._keys = keys;
45
+ this._values = values;
46
+
47
+ // Only used by binary tiles
48
+ this._geometryInfo = geometryInfo!;
49
+
50
+ pbf.readFields(readFeature, this, end);
51
+ }
52
+
53
+ toGeoJSONFeature(
54
+ coordinates: 'wgs84' | 'local',
55
+ tileIndex?: {x: number; y: number; z: number}
56
+ ): Feature {
57
+ const coords = this.loadGeometry();
58
+
59
+ switch (coordinates) {
60
+ case 'wgs84':
61
+ return _toGeoJSONFeature(this, coords, (line: number[][]) =>
62
+ projectToLngLat(line, tileIndex!, this.extent)
63
+ );
64
+
65
+ default:
66
+ return _toGeoJSONFeature(this, coords, convertToLocalCoordinates);
67
+ }
68
+ }
69
+ /**
70
+ *
71
+ * @param options
72
+ * @returns
73
+ */
74
+ toBinaryFeature(
75
+ coordinates: 'wgs84' | 'local',
76
+ tileIndex?: {x: number; y: number; z: number}
77
+ ): FlatFeature {
78
+ const geom = this.loadFlatGeometry();
79
+
80
+ switch (coordinates) {
81
+ case 'wgs84':
82
+ return this._toBinaryCoordinates(geom, (coords: number[]) =>
83
+ projectToLngLatFlat(coords, tileIndex!, this.extent)
84
+ );
85
+
86
+ default:
87
+ return this._toBinaryCoordinates(geom, convertToLocalCoordinatesFlat);
88
+ }
89
+ }
90
+
91
+ /** Read a bounding box from the feature */
92
+ // eslint-disable-next-line max-statements
93
+ bbox() {
94
+ const pbf = this._pbf;
95
+ pbf.pos = this._geometry;
96
+
97
+ const end = pbf.readVarint() + pbf.pos;
98
+ let cmd = 1;
99
+ let length = 0;
100
+ let x = 0;
101
+ let y = 0;
102
+ let x1 = Infinity;
103
+ let x2 = -Infinity;
104
+ let y1 = Infinity;
105
+ let y2 = -Infinity;
106
+
107
+ while (pbf.pos < end) {
108
+ if (length <= 0) {
109
+ const cmdLen = pbf.readVarint();
110
+ cmd = cmdLen & 0x7;
111
+ length = cmdLen >> 3;
112
+ }
113
+
114
+ length--;
115
+
116
+ if (cmd === 1 || cmd === 2) {
117
+ x += pbf.readSVarint();
118
+ y += pbf.readSVarint();
119
+ if (x < x1) x1 = x;
120
+ if (x > x2) x2 = x;
121
+ if (y < y1) y1 = y;
122
+ if (y > y2) y2 = y;
123
+ } else if (cmd !== 7) {
124
+ throw new Error(`unknown command ${cmd}`);
125
+ }
126
+ }
127
+
128
+ return [x1, y1, x2, y2];
129
+ }
130
+
131
+ // BINARY HELPERS
132
+
133
+ /**
134
+ *
135
+ * @param transform
136
+ * @returns result
137
+ */
138
+ _toBinaryCoordinates(
139
+ geom: FlatIndexedGeometry,
140
+ transform: (data: number[], extent: number) => void
141
+ ) {
142
+ let geometry;
143
+
144
+ // Apply the supplied transformation to data
145
+ transform(geom.data, this.extent);
146
+
147
+ const coordLength = 2;
148
+
149
+ // eslint-disable-next-line default-case
150
+ switch (this.type) {
151
+ case 1: // Point
152
+ this._geometryInfo.pointFeaturesCount++;
153
+ this._geometryInfo.pointPositionsCount += geom.indices.length;
154
+ geometry = {type: 'Point', ...geom};
155
+ break;
156
+
157
+ case 2: // LineString
158
+ this._geometryInfo.lineFeaturesCount++;
159
+ this._geometryInfo.linePathsCount += geom.indices.length;
160
+ this._geometryInfo.linePositionsCount += geom.data.length / coordLength;
161
+ geometry = {type: 'LineString', ...geom};
162
+ break;
163
+
164
+ case 3: // Polygon
165
+ geometry = classifyRingsFlat(geom);
166
+
167
+ // Unlike Point & LineString geom.indices is a 2D array, thanks
168
+ // to the classifyRings method
169
+ this._geometryInfo.polygonFeaturesCount++;
170
+ this._geometryInfo.polygonObjectsCount += geometry.indices.length;
171
+
172
+ for (const indices of geometry.indices) {
173
+ this._geometryInfo.polygonRingsCount += indices.length;
174
+ }
175
+ this._geometryInfo.polygonPositionsCount += geometry.data.length / coordLength;
176
+
177
+ break;
178
+ default:
179
+ throw new Error(`Invalid geometry type: ${this.type}`);
180
+ }
181
+
182
+ const result: FlatFeature = {type: 'Feature', geometry, properties: this.properties};
183
+
184
+ if (this.id !== null) {
185
+ result.id = this.id;
186
+ }
187
+
188
+ return result;
189
+ }
190
+
191
+ // GEOJSON HELPER
192
+
193
+ // eslint-disable-next-line complexity, max-statements
194
+ loadGeometry(): number[][][] {
195
+ const pbf = this._pbf;
196
+ pbf.pos = this._geometry;
197
+
198
+ const end = pbf.readVarint() + pbf.pos;
199
+ let cmd = 1;
200
+ let length = 0;
201
+ let x = 0;
202
+ let y = 0;
203
+ const lines: number[][][] = [];
204
+ let line: number[][] | undefined;
205
+
206
+ while (pbf.pos < end) {
207
+ if (length <= 0) {
208
+ const cmdLen = pbf.readVarint();
209
+ cmd = cmdLen & 0x7;
210
+ length = cmdLen >> 3;
211
+ }
212
+
213
+ length--;
214
+
215
+ switch (cmd) {
216
+ case 1:
217
+ case 2:
218
+ x += pbf.readSVarint();
219
+ y += pbf.readSVarint();
220
+
221
+ if (cmd === 1) {
222
+ // moveTo
223
+ if (line) lines.push(line);
224
+ line = [];
225
+ }
226
+ if (line) line.push([x, y]);
227
+ break;
228
+ case 7:
229
+ // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
230
+ if (line) {
231
+ line.push(line[0].slice()); // closePolygon
232
+ }
233
+ break;
234
+ default:
235
+ throw new Error(`unknown command ${cmd}`);
236
+ }
237
+ }
238
+
239
+ if (line) lines.push(line);
240
+
241
+ return lines;
242
+ }
243
+
244
+ /**
245
+ * Expands the protobuf data to an intermediate Flat GeoJSON
246
+ * data format, which maps closely to the binary data buffers.
247
+ * It is similar to GeoJSON, but rather than storing the coordinates
248
+ * in multidimensional arrays, we have a 1D `data` with all the
249
+ * coordinates, and then index into this using the `indices`
250
+ * parameter, e.g.
251
+ *
252
+ * geometry: {
253
+ * type: 'Point', data: [1,2], indices: [0]
254
+ * }
255
+ * geometry: {
256
+ * type: 'LineString', data: [1,2,3,4,...], indices: [0]
257
+ * }
258
+ * geometry: {
259
+ * type: 'Polygon', data: [1,2,3,4,...], indices: [[0, 2]]
260
+ * }
261
+ * Thus the indices member lets us look up the relevant range
262
+ * from the data array.
263
+ * The Multi* versions of the above types share the same data
264
+ * structure, just with multiple elements in the indices array
265
+ */
266
+ // eslint-disable-next-line complexity, max-statements
267
+ loadFlatGeometry(): FlatIndexedGeometry {
268
+ const pbf = this._pbf;
269
+ pbf.pos = this._geometry;
270
+
271
+ const endPos = pbf.readVarint() + pbf.pos;
272
+ let cmd = 1;
273
+ let cmdLen: number;
274
+ let length = 0;
275
+ let x = 0;
276
+ let y = 0;
277
+ let i = 0;
278
+
279
+ // Note: I attempted to replace the `data` array with a
280
+ // Float32Array, but performance was worse, both using
281
+ // `set()` and direct index access. Also, we cannot
282
+ // know how large the buffer should be, so it would
283
+ // increase memory usage
284
+ const indices: number[] = []; // Indices where geometries start
285
+ const data: number[] = []; // Flat array of coordinate data
286
+
287
+ while (pbf.pos < endPos) {
288
+ if (length <= 0) {
289
+ cmdLen = pbf.readVarint();
290
+ cmd = cmdLen & 0x7;
291
+ length = cmdLen >> 3;
292
+ }
293
+
294
+ length--;
295
+
296
+ if (cmd === 1 || cmd === 2) {
297
+ x += pbf.readSVarint();
298
+ y += pbf.readSVarint();
299
+
300
+ if (cmd === 1) {
301
+ // New line
302
+ indices.push(i);
303
+ }
304
+ data.push(x, y);
305
+ i += 2;
306
+ } else if (cmd === 7) {
307
+ // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
308
+ if (i > 0) {
309
+ const start = indices[indices.length - 1]; // start index of polygon
310
+ data.push(data[start], data[start + 1]); // closePolygon
311
+ i += 2;
312
+ }
313
+ } else {
314
+ throw new Error(`unknown command ${cmd}`);
315
+ }
316
+ }
317
+
318
+ return {data, indices};
319
+ }
320
+ }
321
+
322
+ function _toGeoJSONFeature(
323
+ vtFeature: VectorTileFeature,
324
+ coords: number[][][],
325
+ transform: (data: number[][], extent: number) => void
326
+ ): Feature {
327
+ let type = VectorTileFeature.types[vtFeature.type];
328
+ let i: number;
329
+ let j: number;
330
+
331
+ let coordinates: number[][] | number[][][] | number[][][][];
332
+ switch (vtFeature.type) {
333
+ case 1:
334
+ const points: number[][] = [];
335
+ for (i = 0; i < coords.length; i++) {
336
+ points[i] = coords[i][0];
337
+ }
338
+ coordinates = points;
339
+ transform(coordinates, vtFeature.extent);
340
+ break;
341
+
342
+ case 2:
343
+ coordinates = coords;
344
+ for (i = 0; i < coordinates.length; i++) {
345
+ transform(coordinates[i], vtFeature.extent);
346
+ }
347
+ break;
348
+
349
+ case 3:
350
+ coordinates = classifyRings(coords);
351
+ for (i = 0; i < coordinates.length; i++) {
352
+ for (j = 0; j < coordinates[i].length; j++) {
353
+ transform(coordinates[i][j], vtFeature.extent);
354
+ }
355
+ }
356
+ break;
357
+
358
+ default:
359
+ throw new Error('illegal vector tile type');
360
+ }
361
+
362
+ if (coordinates.length === 1) {
363
+ // @ts-expect-error
364
+ coordinates = coordinates[0];
365
+ } else {
366
+ type = `Multi${type}`;
367
+ }
368
+
369
+ const result: Feature = {
370
+ type: 'Feature',
371
+ geometry: {
372
+ type: type as any,
373
+ coordinates: coordinates as any
374
+ },
375
+ properties: vtFeature.properties
376
+ };
377
+
378
+ if (vtFeature.id !== null) {
379
+ result.properties ||= {};
380
+ result.properties.id = vtFeature.id;
381
+ }
382
+
383
+ return result;
384
+ }
385
+
386
+ // PBF READER UTILS
387
+
388
+ /**
389
+ *
390
+ * @param tag
391
+ * @param feature
392
+ * @param pbf
393
+ */
394
+ function readFeature(tag: number, feature?: VectorTileFeature, pbf?: Protobuf): void {
395
+ if (feature && pbf) {
396
+ if (tag === 1) feature.id = pbf.readVarint();
397
+ else if (tag === 2) readTag(pbf, feature);
398
+ else if (tag === 3) feature.type = pbf.readVarint();
399
+ else if (tag === 4) feature._geometry = pbf.pos;
400
+ }
401
+ }
402
+
403
+ /**
404
+ *
405
+ * @param pbf
406
+ * @param feature
407
+ */
408
+ function readTag(pbf: Protobuf, feature: VectorTileFeature): void {
409
+ const end = pbf.readVarint() + pbf.pos;
410
+
411
+ while (pbf.pos < end) {
412
+ const key = feature._keys[pbf.readVarint()];
413
+ const value = feature._values[pbf.readVarint()];
414
+ feature.properties[key] = value;
415
+ }
416
+ }
@@ -7,6 +7,7 @@
7
7
 
8
8
  import Protobuf from 'pbf';
9
9
  import {VectorTileFeature} from './vector-tile-feature';
10
+ import {GeojsonGeometryInfo} from '@loaders.gl/schema';
10
11
 
11
12
  export class VectorTileLayer {
12
13
  version: number;
@@ -17,6 +18,7 @@ export class VectorTileLayer {
17
18
  _keys: string[];
18
19
  _values: (string | number | boolean | null)[];
19
20
  _features: number[];
21
+
20
22
  constructor(pbf: Protobuf, end: number) {
21
23
  // Public
22
24
  this.version = 1;
@@ -40,8 +42,7 @@ export class VectorTileLayer {
40
42
  * @param index
41
43
  * @returns feature
42
44
  */
43
-
44
- feature(i: number): VectorTileFeature {
45
+ getGeoJSONFeature(i: number): VectorTileFeature {
45
46
  if (i < 0 || i >= this._features.length) {
46
47
  throw new Error('feature index out of bounds');
47
48
  }
@@ -51,6 +52,31 @@ export class VectorTileLayer {
51
52
  const end = this._pbf.readVarint() + this._pbf.pos;
52
53
  return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
53
54
  }
55
+
56
+ /**
57
+ * return binary feature `i` from this layer as a `VectorTileFeature`
58
+ *
59
+ * @param index
60
+ * @param geometryInfo
61
+ * @returns binary feature
62
+ */
63
+ getBinaryFeature(i: number, geometryInfo: GeojsonGeometryInfo): VectorTileFeature {
64
+ if (i < 0 || i >= this._features.length) {
65
+ throw new Error('feature index out of bounds');
66
+ }
67
+
68
+ this._pbf.pos = this._features[i];
69
+
70
+ const end = this._pbf.readVarint() + this._pbf.pos;
71
+ return new VectorTileFeature(
72
+ this._pbf,
73
+ end,
74
+ this.extent,
75
+ this._keys,
76
+ this._values,
77
+ geometryInfo
78
+ );
79
+ }
54
80
  }
55
81
 
56
82
  /**
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
5
5
 
6
- import type {GeoJSONTileFeature} from './tile';
6
+ import type {TableTileFeature} from './tile';
7
7
  import {createFeature} from './feature';
8
8
 
9
9
  /* eslint-disable no-continue */
@@ -21,7 +21,7 @@ import {createFeature} from './feature';
21
21
  */
22
22
  // eslint-disable-next-line max-params, complexity, max-statements
23
23
  export function clip(
24
- features: GeoJSONTileFeature[],
24
+ features: TableTileFeature[],
25
25
  scale: number,
26
26
  k1: number,
27
27
  k2: number,
@@ -29,7 +29,7 @@ export function clip(
29
29
  minAll: number,
30
30
  maxAll: number,
31
31
  options: {lineMetrics: boolean}
32
- ): GeoJSONTileFeature[] | null {
32
+ ): TableTileFeature[] | null {
33
33
  k1 /= scale;
34
34
  k2 /= scale;
35
35
 
@@ -41,7 +41,7 @@ export function clip(
41
41
  return null; // trivial reject
42
42
  }
43
43
 
44
- const clipped: GeoJSONTileFeature[] = [];
44
+ const clipped: TableTileFeature[] = [];
45
45
 
46
46
  for (const feature of features) {
47
47
  const geometry = feature.geometry;
@@ -6,15 +6,17 @@
6
6
  /* eslint-disable */
7
7
  // @ts-nocheck
8
8
 
9
- import type {Feature} from '@loaders.gl/schema';
10
- import type {GeoJSONTileFeature} from './tile';
9
+ import type {Feature, FeatureCollection} from '@loaders.gl/schema';
10
+ import type {TableTileFeature} from './tile';
11
11
 
12
12
  import {simplify} from './simplify';
13
13
  import {createFeature} from './feature';
14
14
 
15
- // converts GeoJSON feature into an intermediate projected JSON vector format with simplification data
16
-
17
- export function convert(data: Feature, options): GeoJSONTileFeature[] {
15
+ /**
16
+ * converts a GeoJSON feature into an intermediate projected JSON vector format
17
+ * with simplification data
18
+ */
19
+ export function convert(data: Feature | FeatureCollection, options): TableTileFeature[] {
18
20
  const features = [];
19
21
  if (data.type === 'FeatureCollection') {
20
22
  for (let i = 0; i < data.features.length; i++) {
@@ -31,14 +33,22 @@ export function convert(data: Feature, options): GeoJSONTileFeature[] {
31
33
  }
32
34
 
33
35
  export type ConvertFeatureOptions = {
36
+ /** max zoom to preserve detail on */
34
37
  maxZoom?: number;
35
- tolerance: number;
36
- extent: number;
37
- lineMetrics: boolean;
38
+ /** simplification tolerance (higher means simpler) */
39
+ tolerance?: number;
40
+ /** tile extent */
41
+ extent?: number;
42
+ /** whether to calculate line metrics */
43
+ lineMetrics?: boolean;
38
44
  };
39
45
 
46
+ /**
47
+ * converts a GeoJSON feature into an intermediate projected JSON vector format
48
+ * with simplification data
49
+ */
40
50
  function convertFeature(
41
- features: GeoJSONTileFeature[],
51
+ features: TableTileFeature[],
42
52
  geojson: Feature,
43
53
  options: ConvertFeatureOptions,
44
54
  index: number
@@ -3,10 +3,10 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
5
5
 
6
- import {GeoJSONTileFeature} from './tile';
6
+ import {TableTileFeature} from './tile';
7
7
 
8
- export function createFeature(id, type, geom, tags): GeoJSONTileFeature {
9
- const feature: GeoJSONTileFeature = {
8
+ export function createFeature(id, type, geom, tags): TableTileFeature {
9
+ const feature: TableTileFeature = {
10
10
  // eslint-disable-next-line
11
11
  id: id == null ? null : id,
12
12
  type,
@@ -5,7 +5,7 @@
5
5
 
6
6
  // import type {Feature} from '@loaders.gl/schema';
7
7
 
8
- export type GeoJSONTileFeature = {
8
+ export type TableTileFeature = {
9
9
  type: any;
10
10
  geometry: any;
11
11
 
@@ -20,8 +20,8 @@ export type GeoJSONTileFeature = {
20
20
  maxY: number;
21
21
  };
22
22
 
23
- export type GeoJSONTile = {
24
- features: GeoJSONTileFeature[]; // Feature[]; Doesn't seem JSON compatible??
23
+ export type TableTile = {
24
+ features: TableTileFeature[]; // Feature[]; Doesn't seem JSON compatible??
25
25
  type?: number;
26
26
  tags?: Record<string, string>;
27
27
 
@@ -53,9 +53,9 @@ export type CreateTileOptions = {
53
53
  /**
54
54
  * Create a tile from features and tile index
55
55
  */
56
- export function createTile(features: any[], z, tx, ty, options: CreateTileOptions): GeoJSONTile {
56
+ export function createTile(features: any[], z, tx, ty, options: CreateTileOptions): TableTile {
57
57
  const tolerance = z === options.maxZoom ? 0 : options.tolerance / ((1 << z) * options.extent);
58
- const tile: GeoJSONTile = {
58
+ const tile: TableTile = {
59
59
  features: [],
60
60
  numPoints: 0,
61
61
  numSimplified: 0,
@@ -77,7 +77,7 @@ export function createTile(features: any[], z, tx, ty, options: CreateTileOption
77
77
  }
78
78
 
79
79
  // eslint-disable-next-line complexity, max-statements
80
- function addFeature(tile: GeoJSONTile, feature, tolerance: number, options: CreateTileOptions) {
80
+ function addFeature(tile: TableTile, feature, tolerance: number, options: CreateTileOptions) {
81
81
  const geom = feature.geometry;
82
82
  const type = feature.type;
83
83
  const simplified: number[] = [];
@@ -121,14 +121,14 @@ function addFeature(tile: GeoJSONTile, feature, tolerance: number, options: Crea
121
121
  }
122
122
 
123
123
  // @ts-expect-error TODO - create sub type?
124
- const tileFeature: GeoJSONTileFeature = {
124
+ const tileFeature: TableTileFeature = {
125
125
  geometry: simplified,
126
126
  type:
127
127
  type === 'Polygon' || type === 'MultiPolygon'
128
128
  ? 3
129
129
  : type === 'LineString' || type === 'MultiLineString'
130
- ? 2
131
- : 1,
130
+ ? 2
131
+ : 1,
132
132
  tags
133
133
  };
134
134
  if (feature.id !== null) {
@@ -142,7 +142,7 @@ function addFeature(tile: GeoJSONTile, feature, tolerance: number, options: Crea
142
142
  function addLine(
143
143
  result,
144
144
  geom,
145
- tile: GeoJSONTile,
145
+ tile: TableTile,
146
146
  tolerance: number,
147
147
  isPolygon: boolean,
148
148
  isOuter: boolean
@@ -3,13 +3,13 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
5
5
 
6
- import type {GeoJSONTile} from './tile';
6
+ import type {TableTile} from './tile';
7
7
 
8
8
  /**
9
9
  * Transforms the coordinates of each feature in the given tile from
10
10
  * mercator-projected space into (extent x extent) tile space.
11
11
  */
12
- export function transformTile(tile: GeoJSONTile, extent: number): GeoJSONTile {
12
+ export function transformTile(tile: TableTile, extent: number): TableTile {
13
13
  if (tile.transformed) {
14
14
  return tile;
15
15
  }
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
5
5
 
6
- import type {GeoJSONTileFeature} from './tile';
6
+ import type {TableTileFeature} from './tile';
7
7
  import {clip} from './clip';
8
8
  import {createFeature} from './feature';
9
9
 
@@ -22,9 +22,9 @@ export type WrapOptions = {
22
22
  * @param options buffer and extent
23
23
  * @returns
24
24
  */
25
- export function wrap(features: GeoJSONTileFeature[], options: WrapOptions) {
25
+ export function wrap(features: TableTileFeature[], options: WrapOptions) {
26
26
  const buffer = options.buffer / options.extent;
27
- let merged: GeoJSONTileFeature[] = features;
27
+ let merged: TableTileFeature[] = features;
28
28
  const left = clip(features, 1, -1 - buffer, buffer, 0, -1, 2, options); // left world copy
29
29
  const right = clip(features, 1, 1 - buffer, 2 + buffer, 0, -1, 2, options); // right world copy
30
30
 
@@ -48,8 +48,8 @@ export function wrap(features: GeoJSONTileFeature[], options: WrapOptions) {
48
48
  * @param offset
49
49
  * @returns
50
50
  */
51
- function shiftFeatureCoords(features: GeoJSONTileFeature[], offset: number): GeoJSONTileFeature[] {
52
- const newFeatures: GeoJSONTileFeature[] = [];
51
+ function shiftFeatureCoords(features: TableTileFeature[], offset: number): TableTileFeature[] {
52
+ const newFeatures: TableTileFeature[] = [];
53
53
 
54
54
  for (let i = 0; i < features.length; i++) {
55
55
  const feature = features[i];