@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
package/dist/dist.dev.js CHANGED
@@ -793,14 +793,142 @@ var __exports__ = (() => {
793
793
  // bundle.ts
794
794
  var bundle_exports = {};
795
795
  __export(bundle_exports, {
796
- GeoJSONTileSource: () => GeoJSONTileSource,
797
796
  MVTLoader: () => MVTLoader,
798
797
  MVTSource: () => MVTSource,
799
798
  MVTWorkerLoader: () => MVTWorkerLoader,
799
+ TableTileSource: () => TableTileSource,
800
800
  TileJSONLoader: () => TileJSONLoader
801
801
  });
802
802
  __reExport(bundle_exports, __toESM(require_core(), 1));
803
803
 
804
+ // ../schema/src/lib/table/simple-table/data-type.ts
805
+ function getDataTypeFromValue(value, defaultNumberType = "float32") {
806
+ if (value instanceof Date) {
807
+ return "date-millisecond";
808
+ }
809
+ if (value instanceof Number) {
810
+ return defaultNumberType;
811
+ }
812
+ if (typeof value === "string") {
813
+ return "utf8";
814
+ }
815
+ if (value === null || value === "undefined") {
816
+ return "null";
817
+ }
818
+ return "null";
819
+ }
820
+ function getDataTypeFromArray(array) {
821
+ let type = getDataTypeFromTypedArray(array);
822
+ if (type !== "null") {
823
+ return { type, nullable: false };
824
+ }
825
+ if (array.length > 0) {
826
+ type = getDataTypeFromValue(array[0]);
827
+ return { type, nullable: true };
828
+ }
829
+ return { type: "null", nullable: true };
830
+ }
831
+ function getDataTypeFromTypedArray(array) {
832
+ switch (array.constructor) {
833
+ case Int8Array:
834
+ return "int8";
835
+ case Uint8Array:
836
+ case Uint8ClampedArray:
837
+ return "uint8";
838
+ case Int16Array:
839
+ return "int16";
840
+ case Uint16Array:
841
+ return "uint16";
842
+ case Int32Array:
843
+ return "int32";
844
+ case Uint32Array:
845
+ return "uint32";
846
+ case Float32Array:
847
+ return "float32";
848
+ case Float64Array:
849
+ return "float64";
850
+ default:
851
+ return "null";
852
+ }
853
+ }
854
+
855
+ // ../schema/src/lib/table/simple-table/table-schema.ts
856
+ function deduceTableSchema(table) {
857
+ switch (table.shape) {
858
+ case "array-row-table":
859
+ case "object-row-table":
860
+ return deduceSchemaFromRows(table.data);
861
+ case "geojson-table":
862
+ return deduceSchemaFromGeoJSON(table.features);
863
+ case "columnar-table":
864
+ return deduceSchemaFromColumns(table.data);
865
+ case "arrow-table":
866
+ default:
867
+ throw new Error("Deduce schema");
868
+ }
869
+ }
870
+ function deduceSchemaFromColumns(columnarTable) {
871
+ const fields = [];
872
+ for (const [columnName, column] of Object.entries(columnarTable)) {
873
+ const field = deduceFieldFromColumn(column, columnName);
874
+ fields.push(field);
875
+ }
876
+ return { fields, metadata: {} };
877
+ }
878
+ function deduceSchemaFromRows(rowTable) {
879
+ if (!rowTable.length) {
880
+ throw new Error("deduce from empty table");
881
+ }
882
+ const fields = [];
883
+ const row0 = rowTable[0];
884
+ for (const [columnName, value] of Object.entries(row0)) {
885
+ fields.push(deduceFieldFromValue(value, columnName));
886
+ }
887
+ return { fields, metadata: {} };
888
+ }
889
+ function deduceSchemaFromGeoJSON(features) {
890
+ if (!features.length) {
891
+ throw new Error("deduce from empty table");
892
+ }
893
+ const fields = [];
894
+ const row0 = features[0].properties || {};
895
+ for (const [columnName, value] of Object.entries(row0)) {
896
+ fields.push(deduceFieldFromValue(value, columnName));
897
+ }
898
+ return { fields, metadata: {} };
899
+ }
900
+ function deduceFieldFromColumn(column, name) {
901
+ if (ArrayBuffer.isView(column)) {
902
+ const type = getDataTypeFromArray(column);
903
+ return {
904
+ name,
905
+ type: type.type || "null",
906
+ nullable: type.nullable
907
+ // metadata: {}
908
+ };
909
+ }
910
+ if (Array.isArray(column) && column.length > 0) {
911
+ const value = column[0];
912
+ const type = getDataTypeFromValue(value);
913
+ return {
914
+ name,
915
+ type,
916
+ nullable: true
917
+ // metadata: {},
918
+ };
919
+ }
920
+ throw new Error("empty table");
921
+ }
922
+ function deduceFieldFromValue(value, name) {
923
+ const type = getDataTypeFromValue(value);
924
+ return {
925
+ name,
926
+ type,
927
+ nullable: true
928
+ // metadata: {}
929
+ };
930
+ }
931
+
804
932
  // ../../node_modules/@babel/runtime/helpers/esm/typeof.js
805
933
  function _typeof(obj) {
806
934
  "@babel/helpers - typeof";
@@ -2204,7 +2332,16 @@ var __exports__ = (() => {
2204
2332
  // ../loader-utils/src/lib/log-utils/log.ts
2205
2333
  var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
2206
2334
  var version = VERSION2[0] >= "0" && VERSION2[0] <= "9" ? `v${VERSION2}` : "";
2207
- var log = new Log({ id: `loaders.gl ${version}` });
2335
+ function createLog() {
2336
+ const log2 = new Log({ id: "loaders.gl" });
2337
+ globalThis.loaders = globalThis.loaders || {};
2338
+ globalThis.loaders.log = log2;
2339
+ globalThis.loaders.version = version;
2340
+ globalThis.probe = globalThis.probe || {};
2341
+ globalThis.probe.loaders = log2;
2342
+ return log2;
2343
+ }
2344
+ var log = createLog();
2208
2345
 
2209
2346
  // ../loader-utils/src/lib/path-utils/file-aliases.ts
2210
2347
  var pathPrefix = "";
@@ -2280,6 +2417,39 @@ var __exports__ = (() => {
2280
2417
  }
2281
2418
  return sum;
2282
2419
  }
2420
+ function convertToLocalCoordinates(coordinates, extent) {
2421
+ if (Array.isArray(coordinates[0])) {
2422
+ for (const subcoords of coordinates) {
2423
+ convertToLocalCoordinates(subcoords, extent);
2424
+ }
2425
+ return;
2426
+ }
2427
+ const p = coordinates;
2428
+ p[0] /= extent;
2429
+ p[1] /= extent;
2430
+ }
2431
+ function convertToLocalCoordinatesFlat(data, extent) {
2432
+ for (let i = 0, il = data.length; i < il; ++i) {
2433
+ data[i] /= extent;
2434
+ }
2435
+ }
2436
+ function projectToLngLat(line, tileIndex, extent) {
2437
+ if (typeof line[0][0] !== "number") {
2438
+ for (const point of line) {
2439
+ projectToLngLat(point, tileIndex, extent);
2440
+ }
2441
+ return;
2442
+ }
2443
+ const size = extent * Math.pow(2, tileIndex.z);
2444
+ const x0 = extent * tileIndex.x;
2445
+ const y0 = extent * tileIndex.y;
2446
+ for (let j = 0; j < line.length; j++) {
2447
+ const p = line[j];
2448
+ p[0] = (p[0] + x0) * 360 / size - 180;
2449
+ const y2 = 180 - (p[1] + y0) * 360 / size;
2450
+ p[1] = 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90;
2451
+ }
2452
+ }
2283
2453
  function projectToLngLatFlat(data, tileIndex, extent) {
2284
2454
  const { x, y, z } = tileIndex;
2285
2455
  const size = extent * Math.pow(2, z);
@@ -2389,39 +2559,37 @@ var __exports__ = (() => {
2389
2559
  this._geometryInfo = geometryInfo;
2390
2560
  pbf.readFields(readFeature, this, end);
2391
2561
  }
2392
- toGeoJSON(options) {
2562
+ toGeoJSONFeature(coordinates, tileIndex) {
2393
2563
  const coords = this.loadGeometry();
2394
- if (typeof options === "function") {
2395
- return _toGeoJSON(this, coords, options);
2396
- }
2397
- const { x, y, z } = options;
2398
- const size = this.extent * Math.pow(2, z);
2399
- const x0 = this.extent * x;
2400
- const y0 = this.extent * y;
2401
- function project(line) {
2402
- for (let j = 0; j < line.length; j++) {
2403
- const p = line[j];
2404
- p[0] = (p[0] + x0) * 360 / size - 180;
2405
- const y2 = 180 - (p[1] + y0) * 360 / size;
2406
- p[1] = 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90;
2407
- }
2564
+ switch (coordinates) {
2565
+ case "wgs84":
2566
+ return _toGeoJSONFeature(
2567
+ this,
2568
+ coords,
2569
+ (line) => projectToLngLat(line, tileIndex, this.extent)
2570
+ );
2571
+ default:
2572
+ return _toGeoJSONFeature(this, coords, convertToLocalCoordinates);
2408
2573
  }
2409
- return _toGeoJSON(this, coords, project);
2410
2574
  }
2411
2575
  /**
2412
2576
  *
2413
2577
  * @param options
2414
2578
  * @returns
2415
2579
  */
2416
- toBinaryCoordinates(options) {
2417
- if (typeof options === "function") {
2418
- return this._toBinaryCoordinates(options);
2580
+ toBinaryFeature(coordinates, tileIndex) {
2581
+ const geom = this.loadFlatGeometry();
2582
+ switch (coordinates) {
2583
+ case "wgs84":
2584
+ return this._toBinaryCoordinates(
2585
+ geom,
2586
+ (coords) => projectToLngLatFlat(coords, tileIndex, this.extent)
2587
+ );
2588
+ default:
2589
+ return this._toBinaryCoordinates(geom, convertToLocalCoordinatesFlat);
2419
2590
  }
2420
- const tileIndex = options;
2421
- return this._toBinaryCoordinates(
2422
- (data) => projectToLngLatFlat(data, tileIndex, this.extent)
2423
- );
2424
2591
  }
2592
+ /** Read a bounding box from the feature */
2425
2593
  // eslint-disable-next-line max-statements
2426
2594
  bbox() {
2427
2595
  const pbf = this._pbf;
@@ -2465,10 +2633,9 @@ var __exports__ = (() => {
2465
2633
  * @param transform
2466
2634
  * @returns result
2467
2635
  */
2468
- _toBinaryCoordinates(transform) {
2469
- const geom = this.loadFlatGeometry();
2636
+ _toBinaryCoordinates(geom, transform) {
2470
2637
  let geometry;
2471
- transform(geom.data, this);
2638
+ transform(geom.data, this.extent);
2472
2639
  const coordLength = 2;
2473
2640
  switch (this.type) {
2474
2641
  case 1:
@@ -2545,6 +2712,28 @@ var __exports__ = (() => {
2545
2712
  lines.push(line);
2546
2713
  return lines;
2547
2714
  }
2715
+ /**
2716
+ * Expands the protobuf data to an intermediate Flat GeoJSON
2717
+ * data format, which maps closely to the binary data buffers.
2718
+ * It is similar to GeoJSON, but rather than storing the coordinates
2719
+ * in multidimensional arrays, we have a 1D `data` with all the
2720
+ * coordinates, and then index into this using the `indices`
2721
+ * parameter, e.g.
2722
+ *
2723
+ * geometry: {
2724
+ * type: 'Point', data: [1,2], indices: [0]
2725
+ * }
2726
+ * geometry: {
2727
+ * type: 'LineString', data: [1,2,3,4,...], indices: [0]
2728
+ * }
2729
+ * geometry: {
2730
+ * type: 'Polygon', data: [1,2,3,4,...], indices: [[0, 2]]
2731
+ * }
2732
+ * Thus the indices member lets us look up the relevant range
2733
+ * from the data array.
2734
+ * The Multi* versions of the above types share the same data
2735
+ * structure, just with multiple elements in the indices array
2736
+ */
2548
2737
  // eslint-disable-next-line complexity, max-statements
2549
2738
  loadFlatGeometry() {
2550
2739
  const pbf = this._pbf;
@@ -2587,7 +2776,7 @@ var __exports__ = (() => {
2587
2776
  }
2588
2777
  };
2589
2778
  __publicField(VectorTileFeature, "types", ["Unknown", "Point", "LineString", "Polygon"]);
2590
- function _toGeoJSON(vtFeature, coords, transform) {
2779
+ function _toGeoJSONFeature(vtFeature, coords, transform) {
2591
2780
  let type = VectorTileFeature.types[vtFeature.type];
2592
2781
  let i;
2593
2782
  let j;
@@ -2599,19 +2788,19 @@ var __exports__ = (() => {
2599
2788
  points[i] = coords[i][0];
2600
2789
  }
2601
2790
  coordinates = points;
2602
- transform(coordinates, vtFeature);
2791
+ transform(coordinates, vtFeature.extent);
2603
2792
  break;
2604
2793
  case 2:
2605
2794
  coordinates = coords;
2606
2795
  for (i = 0; i < coordinates.length; i++) {
2607
- transform(coordinates[i], vtFeature);
2796
+ transform(coordinates[i], vtFeature.extent);
2608
2797
  }
2609
2798
  break;
2610
2799
  case 3:
2611
2800
  coordinates = classifyRings(coords);
2612
2801
  for (i = 0; i < coordinates.length; i++) {
2613
2802
  for (j = 0; j < coordinates[i].length; j++) {
2614
- transform(coordinates[i][j], vtFeature);
2803
+ transform(coordinates[i][j], vtFeature.extent);
2615
2804
  }
2616
2805
  }
2617
2806
  break;
@@ -2632,7 +2821,8 @@ var __exports__ = (() => {
2632
2821
  properties: vtFeature.properties
2633
2822
  };
2634
2823
  if (vtFeature.id !== null) {
2635
- result.id = vtFeature.id;
2824
+ result.properties ||= {};
2825
+ result.properties.id = vtFeature.id;
2636
2826
  }
2637
2827
  return result;
2638
2828
  }
@@ -2855,9 +3045,9 @@ var __exports__ = (() => {
2855
3045
  return options.mvt;
2856
3046
  }
2857
3047
  function getDecodedFeature(feature, options, layerName) {
2858
- const decodedFeature = feature.toGeoJSON(
2859
- // @ts-expect-error What is going on here?
2860
- options.coordinates === "wgs84" ? options.tileIndex : transformToLocalCoordinates
3048
+ const decodedFeature = feature.toGeoJSONFeature(
3049
+ options.coordinates || "local",
3050
+ options.tileIndex
2861
3051
  );
2862
3052
  if (options.layerProperty) {
2863
3053
  decodedFeature.properties ||= {};
@@ -2866,29 +3056,12 @@ var __exports__ = (() => {
2866
3056
  return decodedFeature;
2867
3057
  }
2868
3058
  function getDecodedFeatureBinary(feature, options, layerName) {
2869
- const decodedFeature = feature.toBinaryCoordinates(
2870
- // @ts-expect-error
2871
- options.coordinates === "wgs84" ? options.tileIndex : transformToLocalCoordinatesBinary
2872
- );
3059
+ const decodedFeature = feature.toBinaryFeature(options.coordinates || "local", options.tileIndex);
2873
3060
  if (options.layerProperty && decodedFeature.properties) {
2874
3061
  decodedFeature.properties[options.layerProperty] = layerName;
2875
3062
  }
2876
3063
  return decodedFeature;
2877
3064
  }
2878
- function transformToLocalCoordinates(line, feature) {
2879
- const { extent } = feature;
2880
- for (let i = 0; i < line.length; i++) {
2881
- const p = line[i];
2882
- p[0] /= extent;
2883
- p[1] /= extent;
2884
- }
2885
- }
2886
- function transformToLocalCoordinatesBinary(data, feature) {
2887
- const { extent } = feature;
2888
- for (let i = 0, il = data.length; i < il; ++i) {
2889
- data[i] /= extent;
2890
- }
2891
- }
2892
3065
 
2893
3066
  // src/mvt-loader.ts
2894
3067
  var VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
@@ -3615,8 +3788,8 @@ var __exports__ = (() => {
3615
3788
  getTileMIMEType() {
3616
3789
  return this.mimeType;
3617
3790
  }
3618
- async getTile(tileParams) {
3619
- const { x, y, z } = tileParams;
3791
+ async getTile(parameters) {
3792
+ const { x, y, z } = parameters;
3620
3793
  const tileUrl = this.getTileURL(x, y, z);
3621
3794
  const response = await this.fetch(tileUrl);
3622
3795
  if (!response.ok) {
@@ -3627,8 +3800,8 @@ var __exports__ = (() => {
3627
3800
  }
3628
3801
  // Tile Source interface implementation: deck.gl compatible API
3629
3802
  // TODO - currently only handles image tiles, not vector tiles
3630
- async getTileData(tileParams) {
3631
- const { x, y, z } = tileParams.index;
3803
+ async getTileData(parameters) {
3804
+ const { x, y, z } = parameters.index;
3632
3805
  const arrayBuffer = await this.getTile({ x, y, z, layers: [] });
3633
3806
  if (arrayBuffer === null) {
3634
3807
  return null;
@@ -3707,7 +3880,200 @@ var __exports__ = (() => {
3707
3880
  return Math.abs(s.split("").reduce((a, b) => (a << 5) - a + b.charCodeAt(0) | 0, 0));
3708
3881
  }
3709
3882
 
3710
- // src/lib/geojsonvt/simplify.ts
3883
+ // node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
3884
+ function getHiResTimestamp2() {
3885
+ let timestamp;
3886
+ if (typeof window !== "undefined" && window.performance) {
3887
+ timestamp = window.performance.now();
3888
+ } else if (typeof process !== "undefined" && process.hrtime) {
3889
+ const timeParts = process.hrtime();
3890
+ timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6;
3891
+ } else {
3892
+ timestamp = Date.now();
3893
+ }
3894
+ return timestamp;
3895
+ }
3896
+
3897
+ // node_modules/@probe.gl/stats/dist/lib/stat.js
3898
+ var Stat = class {
3899
+ constructor(name, type) {
3900
+ this.sampleSize = 1;
3901
+ this.time = 0;
3902
+ this.count = 0;
3903
+ this.samples = 0;
3904
+ this.lastTiming = 0;
3905
+ this.lastSampleTime = 0;
3906
+ this.lastSampleCount = 0;
3907
+ this._count = 0;
3908
+ this._time = 0;
3909
+ this._samples = 0;
3910
+ this._startTime = 0;
3911
+ this._timerPending = false;
3912
+ this.name = name;
3913
+ this.type = type;
3914
+ this.reset();
3915
+ }
3916
+ reset() {
3917
+ this.time = 0;
3918
+ this.count = 0;
3919
+ this.samples = 0;
3920
+ this.lastTiming = 0;
3921
+ this.lastSampleTime = 0;
3922
+ this.lastSampleCount = 0;
3923
+ this._count = 0;
3924
+ this._time = 0;
3925
+ this._samples = 0;
3926
+ this._startTime = 0;
3927
+ this._timerPending = false;
3928
+ return this;
3929
+ }
3930
+ setSampleSize(samples) {
3931
+ this.sampleSize = samples;
3932
+ return this;
3933
+ }
3934
+ /** Call to increment count (+1) */
3935
+ incrementCount() {
3936
+ this.addCount(1);
3937
+ return this;
3938
+ }
3939
+ /** Call to decrement count (-1) */
3940
+ decrementCount() {
3941
+ this.subtractCount(1);
3942
+ return this;
3943
+ }
3944
+ /** Increase count */
3945
+ addCount(value) {
3946
+ this._count += value;
3947
+ this._samples++;
3948
+ this._checkSampling();
3949
+ return this;
3950
+ }
3951
+ /** Decrease count */
3952
+ subtractCount(value) {
3953
+ this._count -= value;
3954
+ this._samples++;
3955
+ this._checkSampling();
3956
+ return this;
3957
+ }
3958
+ /** Add an arbitrary timing and bump the count */
3959
+ addTime(time) {
3960
+ this._time += time;
3961
+ this.lastTiming = time;
3962
+ this._samples++;
3963
+ this._checkSampling();
3964
+ return this;
3965
+ }
3966
+ /** Start a timer */
3967
+ timeStart() {
3968
+ this._startTime = getHiResTimestamp2();
3969
+ this._timerPending = true;
3970
+ return this;
3971
+ }
3972
+ /** End a timer. Adds to time and bumps the timing count. */
3973
+ timeEnd() {
3974
+ if (!this._timerPending) {
3975
+ return this;
3976
+ }
3977
+ this.addTime(getHiResTimestamp2() - this._startTime);
3978
+ this._timerPending = false;
3979
+ this._checkSampling();
3980
+ return this;
3981
+ }
3982
+ getSampleAverageCount() {
3983
+ return this.sampleSize > 0 ? this.lastSampleCount / this.sampleSize : 0;
3984
+ }
3985
+ /** Calculate average time / count for the previous window */
3986
+ getSampleAverageTime() {
3987
+ return this.sampleSize > 0 ? this.lastSampleTime / this.sampleSize : 0;
3988
+ }
3989
+ /** Calculate counts per second for the previous window */
3990
+ getSampleHz() {
3991
+ return this.lastSampleTime > 0 ? this.sampleSize / (this.lastSampleTime / 1e3) : 0;
3992
+ }
3993
+ getAverageCount() {
3994
+ return this.samples > 0 ? this.count / this.samples : 0;
3995
+ }
3996
+ /** Calculate average time / count */
3997
+ getAverageTime() {
3998
+ return this.samples > 0 ? this.time / this.samples : 0;
3999
+ }
4000
+ /** Calculate counts per second */
4001
+ getHz() {
4002
+ return this.time > 0 ? this.samples / (this.time / 1e3) : 0;
4003
+ }
4004
+ _checkSampling() {
4005
+ if (this._samples === this.sampleSize) {
4006
+ this.lastSampleTime = this._time;
4007
+ this.lastSampleCount = this._count;
4008
+ this.count += this._count;
4009
+ this.time += this._time;
4010
+ this.samples += this._samples;
4011
+ this._time = 0;
4012
+ this._count = 0;
4013
+ this._samples = 0;
4014
+ }
4015
+ }
4016
+ };
4017
+
4018
+ // node_modules/@probe.gl/stats/dist/lib/stats.js
4019
+ var Stats = class {
4020
+ constructor(options) {
4021
+ this.stats = {};
4022
+ this.id = options.id;
4023
+ this.stats = {};
4024
+ this._initializeStats(options.stats);
4025
+ Object.seal(this);
4026
+ }
4027
+ /** Acquire a stat. Create if it doesn't exist. */
4028
+ get(name, type = "count") {
4029
+ return this._getOrCreate({ name, type });
4030
+ }
4031
+ get size() {
4032
+ return Object.keys(this.stats).length;
4033
+ }
4034
+ /** Reset all stats */
4035
+ reset() {
4036
+ for (const stat of Object.values(this.stats)) {
4037
+ stat.reset();
4038
+ }
4039
+ return this;
4040
+ }
4041
+ forEach(fn) {
4042
+ for (const stat of Object.values(this.stats)) {
4043
+ fn(stat);
4044
+ }
4045
+ }
4046
+ getTable() {
4047
+ const table = {};
4048
+ this.forEach((stat) => {
4049
+ table[stat.name] = {
4050
+ time: stat.time || 0,
4051
+ count: stat.count || 0,
4052
+ average: stat.getAverageTime() || 0,
4053
+ hz: stat.getHz() || 0
4054
+ };
4055
+ });
4056
+ return table;
4057
+ }
4058
+ _initializeStats(stats = []) {
4059
+ stats.forEach((stat) => this._getOrCreate(stat));
4060
+ }
4061
+ _getOrCreate(stat) {
4062
+ const { name, type } = stat;
4063
+ let result = this.stats[name];
4064
+ if (!result) {
4065
+ if (stat instanceof Stat) {
4066
+ result = stat;
4067
+ } else {
4068
+ result = new Stat(name, type);
4069
+ }
4070
+ this.stats[name] = result;
4071
+ }
4072
+ return result;
4073
+ }
4074
+ };
4075
+
4076
+ // src/lib/vector-tiler/simplify.ts
3711
4077
  function simplify(coords, first, last, sqTolerance) {
3712
4078
  let maxSqDist = sqTolerance;
3713
4079
  const mid = last - first >> 1;
@@ -3756,7 +4122,7 @@ var __exports__ = (() => {
3756
4122
  return dx * dx + dy * dy;
3757
4123
  }
3758
4124
 
3759
- // src/lib/geojsonvt/feature.ts
4125
+ // src/lib/vector-tiler/feature.ts
3760
4126
  function createFeature(id, type, geom, tags) {
3761
4127
  const feature = {
3762
4128
  // eslint-disable-next-line
@@ -3793,7 +4159,7 @@ var __exports__ = (() => {
3793
4159
  }
3794
4160
  }
3795
4161
 
3796
- // src/lib/geojsonvt/convert.ts
4162
+ // src/lib/vector-tiler/convert.ts
3797
4163
  function convert(data, options) {
3798
4164
  const features = [];
3799
4165
  if (data.type === "FeatureCollection") {
@@ -3911,7 +4277,7 @@ var __exports__ = (() => {
3911
4277
  return y2 < 0 ? 0 : y2 > 1 ? 1 : y2;
3912
4278
  }
3913
4279
 
3914
- // src/lib/geojsonvt/clip.ts
4280
+ // src/lib/vector-tiler/clip.ts
3915
4281
  function clip(features, scale, k1, k2, axis, minAll, maxAll, options) {
3916
4282
  k1 /= scale;
3917
4283
  k2 /= scale;
@@ -4076,7 +4442,7 @@ var __exports__ = (() => {
4076
4442
  return t;
4077
4443
  }
4078
4444
 
4079
- // src/lib/geojsonvt/wrap.ts
4445
+ // src/lib/vector-tiler/wrap.ts
4080
4446
  function wrap(features, options) {
4081
4447
  const buffer = options.buffer / options.extent;
4082
4448
  let merged = features;
@@ -4133,7 +4499,7 @@ var __exports__ = (() => {
4133
4499
  return newPoints;
4134
4500
  }
4135
4501
 
4136
- // src/lib/geojsonvt/transform.ts
4502
+ // src/lib/vector-tiler/transform.ts
4137
4503
  function transformTile(tile, extent) {
4138
4504
  if (tile.transformed) {
4139
4505
  return tile;
@@ -4166,7 +4532,7 @@ var __exports__ = (() => {
4166
4532
  return [Math.round(extent * (x * z2 - tx)), Math.round(extent * (y * z2 - ty))];
4167
4533
  }
4168
4534
 
4169
- // src/lib/geojsonvt/tile.ts
4535
+ // src/lib/vector-tiler/tile.ts
4170
4536
  function createTile(features, z, tx, ty, options) {
4171
4537
  const tolerance = z === options.maxZoom ? 0 : options.tolerance / ((1 << z) * options.extent);
4172
4538
  const tile = {
@@ -4272,61 +4638,46 @@ var __exports__ = (() => {
4272
4638
  }
4273
4639
  }
4274
4640
 
4275
- // src/geojson-tile-source.ts
4276
- var _GeoJSONTileSource = class {
4641
+ // src/table-tile-source.ts
4642
+ var _TableTileSource = class {
4643
+ /** Stats for this TableTileSource */
4644
+ stats = new Stats({
4645
+ id: "table-tile-source",
4646
+ stats: [new Stat("tiles", "count"), new Stat("features", "count")]
4647
+ });
4648
+ /** MIME type of the tiles emitted by this tile source */
4277
4649
  mimeType = "application/vnd.mapbox-vector-tile";
4278
- options;
4279
- // tiles and tileCoords are part of the public API
4650
+ localCoordinates = true;
4651
+ /** The props that this tile source was created with */
4652
+ props;
4653
+ /* Schema of the data */
4654
+ schema = null;
4655
+ /** Map of generated tiles, indexed by stringified tile coordinates */
4280
4656
  tiles = {};
4657
+ /** Array of tile coordinates */
4281
4658
  tileCoords = [];
4282
- stats = {};
4283
- total = 0;
4284
- /** Sync methods can be called: the input data promise has been resolved and initial top-level tiling is done */
4659
+ /** Input data has loaded, initial top-level tiling is done, sync methods can now be called */
4285
4660
  ready;
4286
- constructor(data, options) {
4287
- this.options = { ..._GeoJSONTileSource.defaultOptions, ...options };
4661
+ /** Metadata for the tile source (generated TileJSON/tilestats */
4662
+ metadata;
4663
+ constructor(table, props) {
4664
+ this.props = { ..._TableTileSource.defaultProps, ...props };
4288
4665
  this.getTileData = this.getTileData.bind(this);
4289
- this.ready = this.initializeTilesAsync(data);
4290
- }
4291
- async initializeTilesAsync(dataPromise) {
4292
- const data = await dataPromise;
4293
- this.initializeTilesSync(data);
4294
- }
4295
- initializeTilesSync(data) {
4296
- const options = this.options;
4297
- const debug = options.debug;
4298
- if (debug)
4299
- console.time("preprocess data");
4300
- if (this.options.maxZoom < 0 || this.options.maxZoom > 24) {
4301
- throw new Error("maxZoom should be in the 0-24 range");
4302
- }
4303
- if (options.promoteId && this.options.generateId) {
4304
- throw new Error("promoteId and generateId cannot be used together.");
4305
- }
4306
- let features = convert(data, options);
4307
- if (debug) {
4308
- console.timeEnd("preprocess data");
4309
- console.log(
4310
- "index: maxZoom: %d, maxPoints: %d",
4311
- options.indexMaxZoom,
4312
- options.indexMaxPoints
4313
- );
4314
- console.time("generate tiles");
4315
- }
4316
- features = wrap(features, this.options);
4317
- if (features.length) {
4318
- this.splitTile(features, 0, 0, 0);
4319
- }
4320
- if (debug) {
4321
- if (features.length) {
4322
- console.log("features: %d, points: %d", this.tiles[0].numFeatures, this.tiles[0].numPoints);
4323
- }
4324
- console.timeEnd("generate tiles");
4325
- console.log("tiles generated:", this.total, JSON.stringify(this.stats));
4326
- }
4666
+ this.ready = this.initializeTilesAsync(table);
4667
+ this.metadata = this.getMetadata();
4668
+ }
4669
+ async initializeTilesAsync(tablePromise) {
4670
+ const table = await tablePromise;
4671
+ this.schema = deduceTableSchema(table);
4672
+ this.createRootTiles(table);
4327
4673
  }
4328
4674
  async getMetadata() {
4329
- return {};
4675
+ await this.ready;
4676
+ return { schema: this.schema, minZoom: 0, maxZoom: this.props.maxZoom };
4677
+ }
4678
+ async getSchema() {
4679
+ await this.ready;
4680
+ return this.schema;
4330
4681
  }
4331
4682
  /**
4332
4683
  * Get a tile at the specified index
@@ -4336,6 +4687,7 @@ var __exports__ = (() => {
4336
4687
  async getVectorTile(tileIndex) {
4337
4688
  await this.ready;
4338
4689
  const table = this.getTileSync(tileIndex);
4690
+ log.info(2, "getVectorTile", tileIndex, table)();
4339
4691
  return table;
4340
4692
  }
4341
4693
  async getTile(tileIndex) {
@@ -4344,7 +4696,8 @@ var __exports__ = (() => {
4344
4696
  }
4345
4697
  async getTileData(tileParams) {
4346
4698
  const { x, y, z } = tileParams.index;
4347
- return await this.getVectorTile({ x, y, z });
4699
+ const tile = await this.getVectorTile({ x, y, z });
4700
+ return tile?.features || [];
4348
4701
  }
4349
4702
  // Implementation
4350
4703
  /**
@@ -4356,7 +4709,38 @@ var __exports__ = (() => {
4356
4709
  if (!rawTile) {
4357
4710
  return null;
4358
4711
  }
4359
- return convertToGeoJSONTable(rawTile, this.options.extent);
4712
+ return convertToGeoJSONTable(rawTile, {
4713
+ coordinates: this.props.coordinates,
4714
+ tileIndex,
4715
+ extent: this.props.extent
4716
+ });
4717
+ }
4718
+ /**
4719
+ * Create the initial tiles
4720
+ * @note the tiles stores all the features together with additional data
4721
+ */
4722
+ createRootTiles(table) {
4723
+ if (this.props.maxZoom < 0 || this.props.maxZoom > 24) {
4724
+ throw new Error("maxZoom should be in the 0-24 range");
4725
+ }
4726
+ if (this.props.promoteId && this.props.generateId) {
4727
+ throw new Error("promoteId and generateId cannot be used together.");
4728
+ }
4729
+ log.log(1, "TableTileSource creating root tiles", this.props)();
4730
+ log.time(1, "preprocess table")();
4731
+ let features = convert(table, this.props);
4732
+ log.timeEnd(1, "preprocess table")();
4733
+ log.time(1, "generate tiles")();
4734
+ features = wrap(features, this.props);
4735
+ if (features.length === 0) {
4736
+ log.log(1, "TableTileSource: no features generated")();
4737
+ return;
4738
+ }
4739
+ this.splitTile(features, 0, 0, 0);
4740
+ const rootTile = this.tiles[0];
4741
+ log.log(1, `root tile features: ${rootTile.numFeatures}, points: ${rootTile.numPoints}`)();
4742
+ log.timeEnd(1, "generate tiles")();
4743
+ log.log(1, `TableTileSource: tiles generated: ${this.stats.get("total").count}`, this.stats)();
4360
4744
  }
4361
4745
  /**
4362
4746
  * Return geojsonvt-style "half formed" vector tile
@@ -4366,7 +4750,7 @@ var __exports__ = (() => {
4366
4750
  getRawTile(tileIndex) {
4367
4751
  const { z, y } = tileIndex;
4368
4752
  let { x } = tileIndex;
4369
- const { extent, debug } = this.options;
4753
+ const { extent } = this.props;
4370
4754
  if (z < 0 || z > 24) {
4371
4755
  return null;
4372
4756
  }
@@ -4376,8 +4760,7 @@ var __exports__ = (() => {
4376
4760
  if (this.tiles[id]) {
4377
4761
  return transformTile(this.tiles[id], extent);
4378
4762
  }
4379
- if (debug > 1)
4380
- console.log("drilling down to z%d-%d-%d", z, x, y);
4763
+ log.log(log, "drilling down to z%d-%d-%d", z, x, y)();
4381
4764
  let z0 = z;
4382
4765
  let x0 = x;
4383
4766
  let y0 = y;
@@ -4391,14 +4774,10 @@ var __exports__ = (() => {
4391
4774
  if (!parent || !parent.source) {
4392
4775
  return null;
4393
4776
  }
4394
- if (debug > 1) {
4395
- console.log("found parent tile z%d-%d-%d", z0, x0, y0);
4396
- console.time("drilling down");
4397
- }
4777
+ log.log(1, "found parent tile z%d-%d-%d", z0, x0, y0)();
4778
+ log.time(1, "drilling down")();
4398
4779
  this.splitTile(parent.source, z0, x0, y0, z, x, y);
4399
- if (debug > 1) {
4400
- console.timeEnd("drilling down");
4401
- }
4780
+ log.timeEnd(1, "drilling down")();
4402
4781
  return this.tiles[id] ? transformTile(this.tiles[id], extent) : null;
4403
4782
  }
4404
4783
  /**
@@ -4407,13 +4786,11 @@ var __exports__ = (() => {
4407
4786
  * @param cz, cx, and cy are the coordinates of the target tile
4408
4787
  *
4409
4788
  * If no target tile is specified, splitting stops when we reach the maximum
4410
- * zoom or the number of points is low as specified in the options.
4789
+ * zoom or the number of points is low as specified in the props.
4411
4790
  */
4412
4791
  // eslint-disable-next-line max-params, max-statements, complexity
4413
4792
  splitTile(features, z, x, y, cz, cx, cy) {
4414
4793
  const stack = [features, z, x, y];
4415
- const options = this.options;
4416
- const debug = options.debug;
4417
4794
  while (stack.length) {
4418
4795
  y = stack.pop();
4419
4796
  x = stack.pop();
@@ -4423,46 +4800,48 @@ var __exports__ = (() => {
4423
4800
  const id = toID(z, x, y);
4424
4801
  let tile = this.tiles[id];
4425
4802
  if (!tile) {
4426
- if (debug > 1) {
4427
- console.time("creation");
4428
- }
4429
- tile = this.tiles[id] = createTile(features, z, x, y, options);
4803
+ log.time(2, "tile creation")();
4804
+ tile = this.tiles[id] = createTile(features, z, x, y, this.props);
4430
4805
  this.tileCoords.push({ z, x, y });
4431
- if (debug) {
4432
- if (debug > 1) {
4433
- console.log(
4434
- "tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",
4435
- z,
4436
- x,
4437
- y,
4438
- tile.numFeatures,
4439
- tile.numPoints,
4440
- tile.numSimplified
4441
- );
4442
- console.timeEnd("creation");
4443
- }
4444
- const key = `z${z}`;
4445
- this.stats[key] = (this.stats[key] || 0) + 1;
4446
- this.total++;
4447
- }
4806
+ const key = `z${z}`;
4807
+ let stat = this.stats.get(key, "count");
4808
+ stat.incrementCount();
4809
+ stat = this.stats.get("total");
4810
+ stat.incrementCount();
4811
+ stat = _TableTileSource.stats.get(key, "count");
4812
+ stat.incrementCount();
4813
+ stat = _TableTileSource.stats.get("total");
4814
+ stat.incrementCount();
4815
+ log.log(
4816
+ 2,
4817
+ "tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",
4818
+ z,
4819
+ x,
4820
+ y,
4821
+ tile.numFeatures,
4822
+ tile.numPoints,
4823
+ tile.numSimplified
4824
+ )();
4825
+ log.timeEnd(2, "tile creation")();
4448
4826
  }
4449
4827
  tile.source = features;
4450
4828
  if (cz === void 0) {
4451
- if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints)
4829
+ if (z === this.props.indexMaxZoom || tile.numPoints <= this.props.maxPointsPerTile) {
4452
4830
  continue;
4453
- } else if (z === options.maxZoom || z === cz) {
4831
+ }
4832
+ } else if (z === this.props.maxZoom || z === cz) {
4454
4833
  continue;
4455
4834
  } else if (cz !== void 0) {
4456
4835
  const zoomSteps = cz - z;
4457
- if (x !== cx >> zoomSteps || y !== cy >> zoomSteps)
4836
+ if (x !== cx >> zoomSteps || y !== cy >> zoomSteps) {
4458
4837
  continue;
4838
+ }
4459
4839
  }
4460
4840
  tile.source = null;
4461
4841
  if (features.length === 0)
4462
4842
  continue;
4463
- if (debug > 1)
4464
- console.time("clipping");
4465
- const k1 = 0.5 * options.buffer / options.extent;
4843
+ log.time(2, "clipping tile")();
4844
+ const k1 = 0.5 * this.props.buffer / this.props.extent;
4466
4845
  const k2 = 0.5 - k1;
4467
4846
  const k3 = 0.5 + k1;
4468
4847
  const k4 = 1 + k1;
@@ -4470,21 +4849,20 @@ var __exports__ = (() => {
4470
4849
  let bl = null;
4471
4850
  let tr = null;
4472
4851
  let br = null;
4473
- let left = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, options);
4474
- let right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, options);
4852
+ let left = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, this.props);
4853
+ let right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, this.props);
4475
4854
  features = null;
4476
4855
  if (left) {
4477
- tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
4478
- bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
4856
+ tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, this.props);
4857
+ bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, this.props);
4479
4858
  left = null;
4480
4859
  }
4481
4860
  if (right) {
4482
- tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
4483
- br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
4861
+ tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, this.props);
4862
+ br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, this.props);
4484
4863
  right = null;
4485
4864
  }
4486
- if (debug > 1)
4487
- console.timeEnd("clipping");
4865
+ log.timeEnd(2, "clipping tile")();
4488
4866
  stack.push(tl || [], z + 1, x * 2, y * 2);
4489
4867
  stack.push(bl || [], z + 1, x * 2, y * 2 + 1);
4490
4868
  stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
@@ -4492,13 +4870,15 @@ var __exports__ = (() => {
4492
4870
  }
4493
4871
  }
4494
4872
  };
4495
- var GeoJSONTileSource = _GeoJSONTileSource;
4496
- __publicField(GeoJSONTileSource, "defaultOptions", {
4873
+ var TableTileSource = _TableTileSource;
4874
+ __publicField(TableTileSource, "defaultProps", {
4875
+ coordinates: "wgs84",
4876
+ // coordinates in tile coordinates or lng/lat
4497
4877
  maxZoom: 14,
4498
4878
  // max zoom to preserve detail on
4499
4879
  indexMaxZoom: 5,
4500
4880
  // max zoom in the tile index
4501
- indexMaxPoints: 1e5,
4881
+ maxPointsPerTile: 1e5,
4502
4882
  // max number of points per tile in the tile index
4503
4883
  tolerance: 3,
4504
4884
  // simplification tolerance (higher means simpler)
@@ -4516,10 +4896,15 @@ var __exports__ = (() => {
4516
4896
  debug: 0
4517
4897
  // logging level (0, 1 or 2)
4518
4898
  });
4899
+ /** Global stats for all TableTileSources */
4900
+ __publicField(TableTileSource, "stats", new Stats({
4901
+ id: "table-tile-source-all",
4902
+ stats: [new Stat("count", "tiles"), new Stat("count", "features")]
4903
+ }));
4519
4904
  function toID(z, x, y) {
4520
4905
  return ((1 << z) * y + x) * 32 + z;
4521
4906
  }
4522
- function convertToGeoJSONTable(vtTile, extent) {
4907
+ function convertToGeoJSONTable(vtTile, props) {
4523
4908
  const features = [];
4524
4909
  for (const rawFeature of vtTile.features) {
4525
4910
  if (!rawFeature || !rawFeature.geometry) {
@@ -4558,17 +4943,31 @@ var __exports__ = (() => {
4558
4943
  default:
4559
4944
  continue;
4560
4945
  }
4561
- coordinates = toLngLat(coordinates, extent);
4946
+ switch (props.coordinates) {
4947
+ case "EPSG:4326":
4948
+ case "wgs84":
4949
+ projectToLngLat(coordinates, props.tileIndex, props.extent);
4950
+ break;
4951
+ case "local":
4952
+ convertToLocalCoordinates(coordinates, props.extent);
4953
+ break;
4954
+ default:
4955
+ throw new Error(`Unsupported CRS ${props.coordinates}`);
4956
+ }
4562
4957
  const feature = {
4563
4958
  type: "Feature",
4564
4959
  geometry: {
4565
4960
  type,
4566
4961
  coordinates
4567
4962
  },
4568
- properties: rawFeature.tags || {}
4963
+ properties: rawFeature.tags || {},
4964
+ id: rawFeature.id
4569
4965
  };
4570
4966
  features.push(feature);
4571
4967
  }
4968
+ if (features.length === 0) {
4969
+ return null;
4970
+ }
4572
4971
  const table = {
4573
4972
  shape: "geojson-table",
4574
4973
  type: "FeatureCollection",
@@ -4576,12 +4975,6 @@ var __exports__ = (() => {
4576
4975
  };
4577
4976
  return table;
4578
4977
  }
4579
- function toLngLat(coords, extent) {
4580
- if (Array.isArray(coords[0])) {
4581
- return coords.map((c) => toLngLat(c, extent));
4582
- }
4583
- return [coords[0] / extent, coords[1] / extent];
4584
- }
4585
4978
  return __toCommonJS(bundle_exports);
4586
4979
  })();
4587
4980
  /*! Bundled license information: