@loaders.gl/arrow 4.3.0-alpha.7 → 4.3.0-beta.1

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 (132) hide show
  1. package/dist/arrow-loader.d.ts +6 -38
  2. package/dist/arrow-loader.d.ts.map +1 -1
  3. package/dist/arrow-loader.js +2 -29
  4. package/dist/arrow-worker.js +2654 -1710
  5. package/dist/arrow-writer.d.ts +1 -1
  6. package/dist/arrow-writer.d.ts.map +1 -1
  7. package/dist/arrow-writer.js +2 -2
  8. package/dist/dist.dev.js +1873 -1833
  9. package/dist/dist.min.js +5 -5
  10. package/dist/exports/arrow-loader.d.ts +34 -0
  11. package/dist/exports/arrow-loader.d.ts.map +1 -0
  12. package/dist/exports/arrow-loader.js +30 -0
  13. package/dist/exports/geoarrow-loader.d.ts +27 -0
  14. package/dist/exports/geoarrow-loader.d.ts.map +1 -0
  15. package/dist/exports/geoarrow-loader.js +13 -0
  16. package/dist/geoarrow-loader.d.ts +3 -27
  17. package/dist/geoarrow-loader.d.ts.map +1 -1
  18. package/dist/geoarrow-loader.js +2 -12
  19. package/dist/geoarrow-writer.d.ts +2 -2
  20. package/dist/geoarrow-writer.d.ts.map +1 -1
  21. package/dist/geoarrow-writer.js +2 -2
  22. package/dist/index.cjs +426 -387
  23. package/dist/index.cjs.map +4 -4
  24. package/dist/index.d.ts +14 -13
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +16 -12
  27. package/dist/lib/encoders/encode-arrow.d.ts.map +1 -0
  28. package/dist/lib/encoders/encode-geoarrow.d.ts.map +1 -0
  29. package/dist/lib/geoarrow/convert-geoarrow-to-binary-geometry.d.ts.map +1 -0
  30. package/dist/lib/geoarrow/convert-geoarrow-to-geojson-geometry.d.ts.map +1 -0
  31. package/dist/lib/geoarrow/get-arrow-bounds.d.ts.map +1 -0
  32. package/dist/lib/parsers/parse-arrow.d.ts +9 -0
  33. package/dist/lib/parsers/parse-arrow.d.ts.map +1 -0
  34. package/dist/{parsers/parse-arrow-in-batches.js → lib/parsers/parse-arrow.js} +7 -3
  35. package/dist/lib/parsers/parse-geoarrow.d.ts +9 -0
  36. package/dist/lib/parsers/parse-geoarrow.d.ts.map +1 -0
  37. package/dist/{parsers/parse-geoarrow-sync.js → lib/parsers/parse-geoarrow.js} +9 -3
  38. package/dist/{schema → lib/tables}/convert-arrow-schema.d.ts +4 -0
  39. package/dist/lib/tables/convert-arrow-schema.d.ts.map +1 -0
  40. package/dist/{schema → lib/tables}/convert-arrow-schema.js +8 -0
  41. package/dist/lib/tables/convert-arrow-to-table.d.ts +15 -0
  42. package/dist/lib/tables/convert-arrow-to-table.d.ts.map +1 -0
  43. package/dist/lib/tables/convert-arrow-to-table.js +104 -0
  44. package/dist/lib/tables/convert-table-to-arrow.d.ts +16 -0
  45. package/dist/lib/tables/convert-table-to-arrow.d.ts.map +1 -0
  46. package/dist/lib/tables/convert-table-to-arrow.js +56 -0
  47. package/dist/lib/types.d.ts.map +1 -0
  48. package/dist/{lib → schema}/arrow-table-batch.d.ts +2 -1
  49. package/dist/schema/arrow-table-batch.d.ts.map +1 -0
  50. package/dist/{lib → schema}/arrow-table-batch.js +1 -0
  51. package/dist/{lib/arrow-table.d.ts → schema/arrow-table-type.d.ts} +3 -1
  52. package/dist/schema/arrow-table-type.d.ts.map +1 -0
  53. package/dist/triangulate-on-worker.js +1 -1
  54. package/dist/triangulation-worker.js +25 -72
  55. package/dist/workers/triangulation-worker.js +1 -1
  56. package/package.json +12 -8
  57. package/src/arrow-loader.ts +6 -57
  58. package/src/arrow-writer.ts +1 -2
  59. package/src/exports/arrow-loader.ts +49 -0
  60. package/src/exports/geoarrow-loader.ts +24 -0
  61. package/src/geoarrow-loader.ts +6 -22
  62. package/src/geoarrow-writer.ts +1 -1
  63. package/src/index.ts +23 -23
  64. package/src/{parsers/parse-arrow-in-batches.ts → lib/parsers/parse-arrow.ts} +11 -5
  65. package/src/lib/parsers/parse-geoarrow.ts +32 -0
  66. package/src/{schema → lib/tables}/convert-arrow-schema.ts +10 -0
  67. package/src/lib/tables/convert-arrow-to-table.ts +144 -0
  68. package/src/lib/tables/convert-table-to-arrow.ts +72 -0
  69. package/src/{lib → schema}/arrow-table-batch.ts +2 -1
  70. package/src/{lib/arrow-table.ts → schema/arrow-table-type.ts} +2 -0
  71. package/src/workers/triangulation-worker.ts +1 -1
  72. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.d.ts.map +0 -1
  73. package/dist/geoarrow/convert-geoarrow-to-geojson-geometry.d.ts.map +0 -1
  74. package/dist/geoarrow/get-arrow-bounds.d.ts.map +0 -1
  75. package/dist/lib/arrow-table-batch.d.ts.map +0 -1
  76. package/dist/lib/arrow-table.d.ts.map +0 -1
  77. package/dist/lib/encode-arrow.d.ts.map +0 -1
  78. package/dist/lib/encode-geoarrow.d.ts.map +0 -1
  79. package/dist/parsers/parse-arrow-in-batches.d.ts +0 -6
  80. package/dist/parsers/parse-arrow-in-batches.d.ts.map +0 -1
  81. package/dist/parsers/parse-arrow-sync.d.ts +0 -6
  82. package/dist/parsers/parse-arrow-sync.d.ts.map +0 -1
  83. package/dist/parsers/parse-arrow-sync.js +0 -32
  84. package/dist/parsers/parse-geoarrow-in-batches.d.ts +0 -6
  85. package/dist/parsers/parse-geoarrow-in-batches.d.ts.map +0 -1
  86. package/dist/parsers/parse-geoarrow-in-batches.js +0 -10
  87. package/dist/parsers/parse-geoarrow-sync.d.ts +0 -6
  88. package/dist/parsers/parse-geoarrow-sync.d.ts.map +0 -1
  89. package/dist/schema/arrow-type-utils.d.ts +0 -5
  90. package/dist/schema/arrow-type-utils.d.ts.map +0 -1
  91. package/dist/schema/arrow-type-utils.js +0 -51
  92. package/dist/schema/convert-arrow-schema.d.ts.map +0 -1
  93. package/dist/tables/convert-arrow-to-columnar-table.d.ts +0 -8
  94. package/dist/tables/convert-arrow-to-columnar-table.d.ts.map +0 -1
  95. package/dist/tables/convert-arrow-to-columnar-table.js +0 -24
  96. package/dist/tables/convert-arrow-to-geojson-table.d.ts +0 -16
  97. package/dist/tables/convert-arrow-to-geojson-table.d.ts.map +0 -1
  98. package/dist/tables/convert-arrow-to-geojson-table.js +0 -54
  99. package/dist/tables/convert-columnar-to-row-table.d.ts +0 -7
  100. package/dist/tables/convert-columnar-to-row-table.d.ts.map +0 -1
  101. package/dist/tables/convert-columnar-to-row-table.js +0 -25
  102. package/dist/tables/convert-table-to-arrow.d.ts +0 -42
  103. package/dist/tables/convert-table-to-arrow.d.ts.map +0 -1
  104. package/dist/tables/convert-table-to-arrow.js +0 -59
  105. package/dist/types.d.ts.map +0 -1
  106. package/src/parsers/parse-arrow-sync.ts +0 -44
  107. package/src/parsers/parse-geoarrow-in-batches.ts +0 -16
  108. package/src/parsers/parse-geoarrow-sync.ts +0 -23
  109. package/src/schema/arrow-type-utils.ts +0 -55
  110. package/src/tables/convert-arrow-to-columnar-table.ts +0 -31
  111. package/src/tables/convert-arrow-to-geojson-table.ts +0 -66
  112. package/src/tables/convert-columnar-to-row-table.ts +0 -31
  113. package/src/tables/convert-table-to-arrow.ts +0 -61
  114. /package/dist/lib/{encode-arrow.d.ts → encoders/encode-arrow.d.ts} +0 -0
  115. /package/dist/lib/{encode-arrow.js → encoders/encode-arrow.js} +0 -0
  116. /package/dist/lib/{encode-geoarrow.d.ts → encoders/encode-geoarrow.d.ts} +0 -0
  117. /package/dist/lib/{encode-geoarrow.js → encoders/encode-geoarrow.js} +0 -0
  118. /package/dist/{geoarrow → lib/geoarrow}/convert-geoarrow-to-binary-geometry.d.ts +0 -0
  119. /package/dist/{geoarrow → lib/geoarrow}/convert-geoarrow-to-binary-geometry.js +0 -0
  120. /package/dist/{geoarrow → lib/geoarrow}/convert-geoarrow-to-geojson-geometry.d.ts +0 -0
  121. /package/dist/{geoarrow → lib/geoarrow}/convert-geoarrow-to-geojson-geometry.js +0 -0
  122. /package/dist/{geoarrow → lib/geoarrow}/get-arrow-bounds.d.ts +0 -0
  123. /package/dist/{geoarrow → lib/geoarrow}/get-arrow-bounds.js +0 -0
  124. /package/dist/{types.d.ts → lib/types.d.ts} +0 -0
  125. /package/dist/{types.js → lib/types.js} +0 -0
  126. /package/dist/{lib/arrow-table.js → schema/arrow-table-type.js} +0 -0
  127. /package/src/lib/{encode-arrow.ts → encoders/encode-arrow.ts} +0 -0
  128. /package/src/lib/{encode-geoarrow.ts → encoders/encode-geoarrow.ts} +0 -0
  129. /package/src/{geoarrow → lib/geoarrow}/convert-geoarrow-to-binary-geometry.ts +0 -0
  130. /package/src/{geoarrow → lib/geoarrow}/convert-geoarrow-to-geojson-geometry.ts +0 -0
  131. /package/src/{geoarrow → lib/geoarrow}/get-arrow-bounds.ts +0 -0
  132. /package/src/{types.ts → lib/types.ts} +0 -0
package/dist/dist.dev.js CHANGED
@@ -60,12 +60,14 @@ var __exports__ = (() => {
60
60
  GeoArrowWorkerLoader: () => GeoArrowWorkerLoader,
61
61
  TriangulationWorker: () => TriangulationWorker,
62
62
  VECTOR_TYPES: () => VECTOR_TYPES,
63
- convertArrowToGeoJSONTable: () => convertArrowToGeoJSONTable,
63
+ convertArrowToSchema: () => convertArrowToSchema,
64
+ convertArrowToTable: () => convertArrowToTable,
65
+ convertSchemaToArrow: () => convertSchemaToArrow,
66
+ convertTableToArrow: () => convertTableToArrow,
64
67
  deserializeArrowField: () => deserializeArrowField,
65
68
  deserializeArrowMetadata: () => deserializeArrowMetadata,
66
69
  deserializeArrowSchema: () => deserializeArrowSchema,
67
70
  deserializeArrowType: () => deserializeArrowType,
68
- getArrowType: () => getArrowType,
69
71
  getBinaryGeometriesFromArrow: () => getBinaryGeometriesFromArrow,
70
72
  getBinaryGeometryTemplate: () => getBinaryGeometryTemplate,
71
73
  getMeanCentersFromBinaryGeometries: () => getMeanCentersFromBinaryGeometries,
@@ -82,6 +84,13 @@ var __exports__ = (() => {
82
84
  });
83
85
  __reExport(bundle_exports, __toESM(require_core(), 1));
84
86
 
87
+ // src/lib/types.ts
88
+ var VECTOR_TYPES = /* @__PURE__ */ ((VECTOR_TYPES2) => {
89
+ VECTOR_TYPES2[VECTOR_TYPES2["FLOAT"] = 0] = "FLOAT";
90
+ VECTOR_TYPES2[VECTOR_TYPES2["DATE"] = 1] = "DATE";
91
+ return VECTOR_TYPES2;
92
+ })(VECTOR_TYPES || {});
93
+
85
94
  // ../schema/src/lib/table/simple-table/data-type.ts
86
95
  function getDataTypeFromValue(value, defaultNumberType = "float32") {
87
96
  if (value instanceof Date) {
@@ -575,6 +584,29 @@ var __exports__ = (() => {
575
584
  throw new Error("table");
576
585
  }
577
586
  }
587
+ function getTableNumCols(table) {
588
+ if (table.schema) {
589
+ return table.schema.fields.length;
590
+ }
591
+ if (getTableLength(table) === 0) {
592
+ throw new Error("empty table");
593
+ }
594
+ switch (table.shape) {
595
+ case "array-row-table":
596
+ return table.data[0].length;
597
+ case "object-row-table":
598
+ return Object.keys(table.data[0]).length;
599
+ case "geojson-table":
600
+ return Object.keys(table.features[0]).length;
601
+ case "columnar-table":
602
+ return Object.keys(table.data).length;
603
+ case "arrow-table":
604
+ const arrowTable = table.data;
605
+ return arrowTable.numCols;
606
+ default:
607
+ throw new Error("table");
608
+ }
609
+ }
578
610
  function getTableCell(table, rowIndex, columnName) {
579
611
  switch (table.shape) {
580
612
  case "array-row-table":
@@ -597,6 +629,27 @@ var __exports__ = (() => {
597
629
  throw new Error("todo");
598
630
  }
599
631
  }
632
+ function getTableCellAt(table, rowIndex, columnIndex) {
633
+ switch (table.shape) {
634
+ case "array-row-table":
635
+ return table.data[rowIndex][columnIndex];
636
+ case "object-row-table":
637
+ const columnName1 = getTableColumnName(table, columnIndex);
638
+ return table.data[rowIndex][columnName1];
639
+ case "geojson-table":
640
+ const columnName2 = getTableColumnName(table, columnIndex);
641
+ return table.features[rowIndex][columnName2];
642
+ case "columnar-table":
643
+ const columnName3 = getTableColumnName(table, columnIndex);
644
+ const column = table.data[columnName3];
645
+ return column[rowIndex];
646
+ case "arrow-table":
647
+ const arrowTable = table.data;
648
+ return arrowTable.getChildAt(columnIndex)?.get(rowIndex);
649
+ default:
650
+ throw new Error("todo");
651
+ }
652
+ }
600
653
  function getTableColumnIndex(table, columnName) {
601
654
  const columnIndex = table.schema?.fields.findIndex((field) => field.name === columnName);
602
655
  if (columnIndex === void 0) {
@@ -604,6 +657,13 @@ var __exports__ = (() => {
604
657
  }
605
658
  return columnIndex;
606
659
  }
660
+ function getTableColumnName(table, columnIndex) {
661
+ const columnName = table.schema?.fields[columnIndex]?.name;
662
+ if (!columnName) {
663
+ throw new Error(`${columnIndex}`);
664
+ }
665
+ return columnName;
666
+ }
607
667
  function getTableRowAsObject(table, rowIndex, target, copy2) {
608
668
  switch (table.shape) {
609
669
  case "object-row-table":
@@ -923,16 +983,24 @@ var __exports__ = (() => {
923
983
  if (!Symbol.asyncIterator)
924
984
  throw new TypeError("Symbol.asyncIterator is not defined.");
925
985
  var g = generator.apply(thisArg, _arguments || []), i, q = [];
926
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
986
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
927
987
  return this;
928
988
  }, i;
929
- function verb(n) {
930
- if (g[n])
989
+ function awaitReturn(f) {
990
+ return function(v) {
991
+ return Promise.resolve(v).then(f, reject);
992
+ };
993
+ }
994
+ function verb(n, f) {
995
+ if (g[n]) {
931
996
  i[n] = function(v) {
932
997
  return new Promise(function(a, b) {
933
998
  q.push([n, v, a, b]) > 1 || resume(n, v);
934
999
  });
935
1000
  };
1001
+ if (f)
1002
+ i[n] = f(i[n]);
1003
+ }
936
1004
  }
937
1005
  function resume(n, v) {
938
1006
  try {
@@ -12711,7 +12779,7 @@ return true;`);
12711
12779
  RecordBatchFileWriter["throughDOM"] = recordBatchWriterThroughDOMStream;
12712
12780
  RecordBatchStreamWriter["throughDOM"] = recordBatchWriterThroughDOMStream;
12713
12781
 
12714
- // src/lib/arrow-table-batch.ts
12782
+ // src/schema/arrow-table-batch.ts
12715
12783
  var ArrowTableBatchAggregator = class extends ColumnarTableBatchAggregator {
12716
12784
  arrowSchema;
12717
12785
  constructor(schema, options) {
@@ -12770,649 +12838,182 @@ return true;`);
12770
12838
  return arrowVectors;
12771
12839
  }
12772
12840
 
12773
- // src/schema/arrow-type-utils.ts
12774
- function getArrowType(array) {
12775
- switch (array.constructor) {
12776
- case Int8Array:
12777
- return new Int8();
12778
- case Uint8Array:
12779
- return new Uint8();
12780
- case Int16Array:
12781
- return new Int16();
12782
- case Uint16Array:
12783
- return new Uint16();
12784
- case Int32Array:
12785
- return new Int32();
12786
- case Uint32Array:
12787
- return new Uint32();
12788
- case Float32Array:
12789
- return new Float32();
12790
- case Float64Array:
12791
- return new Float64();
12792
- default:
12793
- throw new Error("array type not supported");
12841
+ // src/exports/arrow-loader.ts
12842
+ var VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
12843
+ var ArrowWorkerLoader = {
12844
+ dataType: null,
12845
+ batchType: null,
12846
+ name: "Apache Arrow",
12847
+ id: "arrow",
12848
+ module: "arrow",
12849
+ version: VERSION,
12850
+ // worker: true,
12851
+ category: "table",
12852
+ extensions: ["arrow", "feather"],
12853
+ mimeTypes: [
12854
+ "application/vnd.apache.arrow.file",
12855
+ "application/vnd.apache.arrow.stream",
12856
+ "application/octet-stream"
12857
+ ],
12858
+ binary: true,
12859
+ tests: ["ARROW"],
12860
+ options: {
12861
+ arrow: {
12862
+ shape: "columnar-table"
12863
+ }
12794
12864
  }
12795
- }
12796
-
12797
- // src/types.ts
12798
- var VECTOR_TYPES = /* @__PURE__ */ ((VECTOR_TYPES2) => {
12799
- VECTOR_TYPES2[VECTOR_TYPES2["FLOAT"] = 0] = "FLOAT";
12800
- VECTOR_TYPES2[VECTOR_TYPES2["DATE"] = 1] = "DATE";
12801
- return VECTOR_TYPES2;
12802
- })(VECTOR_TYPES || {});
12865
+ };
12803
12866
 
12804
- // src/tables/convert-arrow-to-columnar-table.ts
12805
- function convertArrowToColumnarTable(table) {
12806
- const arrowTable = table.data;
12807
- const columnarTable = {};
12808
- for (const field of arrowTable.schema.fields) {
12809
- const arrowColumn = arrowTable.getChild(field.name);
12810
- const values = arrowColumn?.toArray();
12811
- columnarTable[field.name] = values;
12867
+ // ../gis/src/lib/geo/geoarrow-metadata.ts
12868
+ var GEOARROW_ENCODINGS = [
12869
+ "geoarrow.multipolygon",
12870
+ "geoarrow.polygon",
12871
+ "geoarrow.multilinestring",
12872
+ "geoarrow.linestring",
12873
+ "geoarrow.multipoint",
12874
+ "geoarrow.point",
12875
+ "geoarrow.wkb",
12876
+ "geoarrow.wkt"
12877
+ ];
12878
+ var GEOARROW_COLUMN_METADATA_ENCODING = "ARROW:extension:name";
12879
+ var GEOARROW_COLUMN_METADATA_METADATA = "ARROW:extension:metadata";
12880
+ function getGeometryColumnsFromSchema(schema) {
12881
+ const geometryColumns = {};
12882
+ for (const field of schema.fields) {
12883
+ const metadata = getGeometryMetadataForField(field);
12884
+ if (metadata) {
12885
+ geometryColumns[field.name] = metadata;
12886
+ }
12812
12887
  }
12813
- return {
12814
- shape: "columnar-table",
12815
- schema: table.schema,
12816
- data: columnarTable
12817
- };
12888
+ return geometryColumns;
12889
+ }
12890
+ function getGeometryMetadataForField(field) {
12891
+ let metadata = null;
12892
+ let geoEncoding = field.metadata?.[GEOARROW_COLUMN_METADATA_ENCODING];
12893
+ if (geoEncoding) {
12894
+ geoEncoding = geoEncoding.toLowerCase();
12895
+ if (geoEncoding === "wkb") {
12896
+ geoEncoding = "geoarrow.wkb";
12897
+ }
12898
+ if (geoEncoding === "wkt") {
12899
+ geoEncoding = "geoarrow.wkt";
12900
+ }
12901
+ if (!GEOARROW_ENCODINGS.includes(geoEncoding)) {
12902
+ console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`);
12903
+ } else {
12904
+ metadata = metadata || {};
12905
+ metadata.encoding = geoEncoding;
12906
+ }
12907
+ }
12908
+ const columnMetadata = field.metadata?.[GEOARROW_COLUMN_METADATA_METADATA];
12909
+ if (columnMetadata) {
12910
+ try {
12911
+ metadata = JSON.parse(columnMetadata);
12912
+ } catch (error) {
12913
+ console.warn("Failed to parse GeoArrow metadata", error);
12914
+ }
12915
+ }
12916
+ return metadata || null;
12818
12917
  }
12819
12918
 
12820
- // src/schema/convert-arrow-schema.ts
12821
- function serializeArrowSchema(arrowSchema) {
12822
- return {
12823
- fields: arrowSchema.fields.map((arrowField) => serializeArrowField(arrowField)),
12824
- metadata: serializeArrowMetadata(arrowSchema.metadata)
12825
- };
12919
+ // ../../node_modules/@math.gl/polygon/dist/polygon-utils.js
12920
+ var DimIndex = {
12921
+ x: 0,
12922
+ y: 1,
12923
+ z: 2
12924
+ };
12925
+ function getPolygonSignedArea(points, options = {}) {
12926
+ const { start = 0, end = points.length, plane = "xy" } = options;
12927
+ const dim = options.size || 2;
12928
+ let area2 = 0;
12929
+ const i0 = DimIndex[plane[0]];
12930
+ const i1 = DimIndex[plane[1]];
12931
+ for (let i = start, j = end - dim; i < end; i += dim) {
12932
+ area2 += (points[i + i0] - points[j + i0]) * (points[i + i1] + points[j + i1]);
12933
+ j = i;
12934
+ }
12935
+ return area2 / 2;
12826
12936
  }
12827
- function deserializeArrowSchema(schema) {
12828
- return new Schema2(
12829
- schema.fields.map((field) => deserializeArrowField(field)),
12830
- deserializeArrowMetadata(schema.metadata)
12831
- );
12937
+
12938
+ // ../../node_modules/@math.gl/polygon/dist/earcut.js
12939
+ function earcut(positions, holeIndices, dim = 2, areas, plane = "xy") {
12940
+ const hasHoles = holeIndices && holeIndices.length;
12941
+ const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
12942
+ let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0], plane);
12943
+ const triangles = [];
12944
+ if (!outerNode || outerNode.next === outerNode.prev)
12945
+ return triangles;
12946
+ let invSize;
12947
+ let maxX;
12948
+ let maxY;
12949
+ let minX;
12950
+ let minY;
12951
+ let x;
12952
+ let y;
12953
+ if (hasHoles)
12954
+ outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas, plane);
12955
+ if (positions.length > 80 * dim) {
12956
+ minX = maxX = positions[0];
12957
+ minY = maxY = positions[1];
12958
+ for (let i = dim; i < outerLen; i += dim) {
12959
+ x = positions[i];
12960
+ y = positions[i + 1];
12961
+ if (x < minX)
12962
+ minX = x;
12963
+ if (y < minY)
12964
+ minY = y;
12965
+ if (x > maxX)
12966
+ maxX = x;
12967
+ if (y > maxY)
12968
+ maxY = y;
12969
+ }
12970
+ invSize = Math.max(maxX - minX, maxY - minY);
12971
+ invSize = invSize !== 0 ? 32767 / invSize : 0;
12972
+ }
12973
+ earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
12974
+ return triangles;
12832
12975
  }
12833
- function serializeArrowMetadata(arrowMetadata) {
12834
- return Object.fromEntries(arrowMetadata);
12976
+ function linkedList(data, start, end, dim, clockwise, area2, plane) {
12977
+ let i;
12978
+ let last;
12979
+ if (area2 === void 0) {
12980
+ area2 = getPolygonSignedArea(data, { start, end, size: dim, plane });
12981
+ }
12982
+ let i0 = DimIndex[plane[0]];
12983
+ let i1 = DimIndex[plane[1]];
12984
+ if (clockwise === area2 < 0) {
12985
+ for (i = start; i < end; i += dim)
12986
+ last = insertNode(i, data[i + i0], data[i + i1], last);
12987
+ } else {
12988
+ for (i = end - dim; i >= start; i -= dim)
12989
+ last = insertNode(i, data[i + i0], data[i + i1], last);
12990
+ }
12991
+ if (last && equals(last, last.next)) {
12992
+ removeNode(last);
12993
+ last = last.next;
12994
+ }
12995
+ return last;
12835
12996
  }
12836
- function deserializeArrowMetadata(metadata) {
12837
- return metadata ? new Map(Object.entries(metadata)) : /* @__PURE__ */ new Map();
12838
- }
12839
- function serializeArrowField(field) {
12840
- return {
12841
- name: field.name,
12842
- type: serializeArrowType(field.type),
12843
- nullable: field.nullable,
12844
- metadata: serializeArrowMetadata(field.metadata)
12845
- };
12846
- }
12847
- function deserializeArrowField(field) {
12848
- return new Field2(
12849
- field.name,
12850
- deserializeArrowType(field.type),
12851
- field.nullable,
12852
- deserializeArrowMetadata(field.metadata)
12853
- );
12854
- }
12855
- function serializeArrowType(arrowType) {
12856
- switch (arrowType.constructor) {
12857
- case Null2:
12858
- return "null";
12859
- case Binary2:
12860
- return "binary";
12861
- case Bool2:
12862
- return "bool";
12863
- case Int_:
12864
- const intType = arrowType;
12865
- return `${intType.isSigned ? "u" : ""}int${intType.bitWidth}`;
12866
- case Int8:
12867
- return "int8";
12868
- case Int16:
12869
- return "int16";
12870
- case Int32:
12871
- return "int32";
12872
- case Int64:
12873
- return "int64";
12874
- case Uint8:
12875
- return "uint8";
12876
- case Uint16:
12877
- return "uint16";
12878
- case Uint32:
12879
- return "uint32";
12880
- case Uint64:
12881
- return "uint64";
12882
- case Float:
12883
- const precision = arrowType.precision;
12884
- switch (precision) {
12885
- case Precision.HALF:
12886
- return "float16";
12887
- case Precision.SINGLE:
12888
- return "float32";
12889
- case Precision.DOUBLE:
12890
- return "float64";
12891
- default:
12892
- return "float16";
12893
- }
12894
- case Float16:
12895
- return "float16";
12896
- case Float32:
12897
- return "float32";
12898
- case Float64:
12899
- return "float64";
12900
- case Utf82:
12901
- return "utf8";
12902
- case Decimal2:
12903
- const decimal = arrowType;
12904
- return {
12905
- type: "decimal",
12906
- bitWidth: decimal.bitWidth,
12907
- precision: decimal.precision,
12908
- scale: decimal.scale
12909
- };
12910
- case Date_:
12911
- const dateUnit = arrowType.unit;
12912
- return dateUnit === DateUnit.DAY ? "date-day" : "date-millisecond";
12913
- case DateDay:
12914
- return "date-day";
12915
- case DateMillisecond:
12916
- return "date-millisecond";
12917
- case Time_:
12918
- const timeUnit = arrowType.unit;
12919
- switch (timeUnit) {
12920
- case TimeUnit.SECOND:
12921
- return "time-second";
12922
- case TimeUnit.MILLISECOND:
12923
- return "time-millisecond";
12924
- case TimeUnit.MICROSECOND:
12925
- return "time-microsecond";
12926
- case TimeUnit.NANOSECOND:
12927
- return "time-nanosecond";
12928
- default:
12929
- return "time-second";
12930
- }
12931
- case TimeMillisecond:
12932
- return "time-millisecond";
12933
- case TimeSecond:
12934
- return "time-second";
12935
- case TimeMicrosecond:
12936
- return "time-microsecond";
12937
- case TimeNanosecond:
12938
- return "time-nanosecond";
12939
- case Timestamp_:
12940
- const timeStampUnit = arrowType.unit;
12941
- switch (timeStampUnit) {
12942
- case TimeUnit.SECOND:
12943
- return "timestamp-second";
12944
- case TimeUnit.MILLISECOND:
12945
- return "timestamp-millisecond";
12946
- case TimeUnit.MICROSECOND:
12947
- return "timestamp-microsecond";
12948
- case TimeUnit.NANOSECOND:
12949
- return "timestamp-nanosecond";
12950
- default:
12951
- return "timestamp-second";
12952
- }
12953
- case TimestampSecond:
12954
- return "timestamp-second";
12955
- case TimestampMillisecond:
12956
- return "timestamp-millisecond";
12957
- case TimestampMicrosecond:
12958
- return "timestamp-microsecond";
12959
- case TimestampNanosecond:
12960
- return "timestamp-nanosecond";
12961
- case Interval_:
12962
- const intervalUnit = arrowType.unit;
12963
- switch (intervalUnit) {
12964
- case IntervalUnit.DAY_TIME:
12965
- return "interval-daytime";
12966
- case IntervalUnit.YEAR_MONTH:
12967
- return "interval-yearmonth";
12968
- default:
12969
- return "interval-daytime";
12970
- }
12971
- case IntervalDayTime:
12972
- return "interval-daytime";
12973
- case IntervalYearMonth:
12974
- return "interval-yearmonth";
12975
- case Map_:
12976
- const mapType = arrowType;
12977
- return {
12978
- type: "map",
12979
- keysSorted: mapType.keysSorted,
12980
- children: mapType.children.map((arrowField) => serializeArrowField(arrowField))
12981
- };
12982
- case List2:
12983
- const listType = arrowType;
12984
- const listField = listType.valueField;
12985
- return {
12986
- type: "list",
12987
- children: [serializeArrowField(listField)]
12988
- };
12989
- case FixedSizeList2:
12990
- const fixedSizeList = arrowType;
12991
- return {
12992
- type: "fixed-size-list",
12993
- listSize: fixedSizeList.listSize,
12994
- children: [serializeArrowField(fixedSizeList.children[0])]
12995
- };
12996
- case Struct:
12997
- const structType = arrowType;
12998
- return {
12999
- type: "struct",
13000
- children: structType.children.map((arrowField) => serializeArrowField(arrowField))
13001
- };
13002
- default:
13003
- throw new Error(`arrow type not supported: ${arrowType.constructor.name}`);
13004
- }
13005
- }
13006
- function deserializeArrowType(dataType) {
13007
- if (typeof dataType === "object") {
13008
- switch (dataType.type) {
13009
- case "decimal":
13010
- return new Decimal2(dataType.precision, dataType.scale, dataType.bitWidth);
13011
- case "map":
13012
- let children = dataType.children.map((arrowField) => deserializeArrowField(arrowField));
13013
- return new Map_(children, dataType.keysSorted);
13014
- case "list":
13015
- const field = deserializeArrowField(dataType.children[0]);
13016
- return new List2(field);
13017
- case "fixed-size-list":
13018
- const child = deserializeArrowField(dataType.children[0]);
13019
- return new FixedSizeList2(dataType.listSize, child);
13020
- case "struct":
13021
- children = dataType.children.map((arrowField) => deserializeArrowField(arrowField));
13022
- return new Struct(children);
13023
- default:
13024
- throw new Error("array type not supported");
13025
- }
13026
- }
13027
- switch (dataType) {
13028
- case "null":
13029
- return new Null2();
13030
- case "binary":
13031
- return new Binary2();
13032
- case "bool":
13033
- return new Bool2();
13034
- case "int8":
13035
- return new Int8();
13036
- case "int16":
13037
- return new Int16();
13038
- case "int32":
13039
- return new Int32();
13040
- case "int64":
13041
- return new Int64();
13042
- case "uint8":
13043
- return new Uint8();
13044
- case "uint16":
13045
- return new Uint16();
13046
- case "uint32":
13047
- return new Uint32();
13048
- case "uint64":
13049
- return new Uint64();
13050
- case "float16":
13051
- return new Float16();
13052
- case "float32":
13053
- return new Float32();
13054
- case "float64":
13055
- return new Float64();
13056
- case "utf8":
13057
- return new Utf82();
13058
- case "date-day":
13059
- return new DateDay();
13060
- case "date-millisecond":
13061
- return new DateMillisecond();
13062
- case "time-second":
13063
- return new TimeSecond();
13064
- case "time-millisecond":
13065
- return new TimeMillisecond();
13066
- case "time-microsecond":
13067
- return new TimeMicrosecond();
13068
- case "time-nanosecond":
13069
- return new TimeNanosecond();
13070
- case "timestamp-second":
13071
- return new TimestampSecond();
13072
- case "timestamp-millisecond":
13073
- return new TimestampMillisecond();
13074
- case "timestamp-microsecond":
13075
- return new TimestampMicrosecond();
13076
- case "timestamp-nanosecond":
13077
- return new TimestampNanosecond();
13078
- case "interval-daytime":
13079
- return new IntervalDayTime();
13080
- case "interval-yearmonth":
13081
- return new IntervalYearMonth();
13082
- default:
13083
- throw new Error("array type not supported");
13084
- }
13085
- }
13086
-
13087
- // src/parsers/parse-arrow-sync.ts
13088
- function parseArrowSync(arrayBuffer, options) {
13089
- const apacheArrowTable = tableFromIPC([new Uint8Array(arrayBuffer)]);
13090
- const arrowTable = {
13091
- shape: "arrow-table",
13092
- schema: serializeArrowSchema(apacheArrowTable.schema),
13093
- data: apacheArrowTable
13094
- };
13095
- const shape = options?.shape || "arrow-table";
13096
- switch (shape) {
13097
- case "arrow-table":
13098
- return arrowTable;
13099
- case "columnar-table":
13100
- return convertArrowToColumnarTable(arrowTable);
13101
- case "object-row-table":
13102
- let columnarTable = convertArrowToColumnarTable(arrowTable);
13103
- return convertTable(columnarTable, "object-row-table");
13104
- case "array-row-table":
13105
- columnarTable = convertArrowToColumnarTable(arrowTable);
13106
- return convertTable(columnarTable, "array-row-table");
13107
- default:
13108
- throw new Error(shape);
13109
- }
13110
- }
13111
-
13112
- // src/parsers/parse-arrow-in-batches.ts
13113
- function parseArrowInBatches(asyncIterator, options) {
13114
- async function* makeArrowAsyncIterator() {
13115
- const readers = RecordBatchReader.readAll(asyncIterator);
13116
- for await (const reader of readers) {
13117
- for await (const recordBatch of reader) {
13118
- if (options?.arrow?.batchDebounceMs !== void 0 && options?.arrow?.batchDebounceMs > 0) {
13119
- await new Promise((resolve) => setTimeout(resolve, options.arrow?.batchDebounceMs || 0));
13120
- }
13121
- const arrowTabledBatch = {
13122
- shape: "arrow-table",
13123
- batchType: "data",
13124
- data: new Table([recordBatch]),
13125
- length: recordBatch.data.length
13126
- };
13127
- yield arrowTabledBatch;
13128
- }
13129
- break;
13130
- }
13131
- }
13132
- return makeArrowAsyncIterator();
13133
- }
13134
-
13135
- // src/arrow-loader.ts
13136
- var VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
13137
- var ArrowWorkerLoader = {
13138
- dataType: null,
13139
- batchType: null,
13140
- name: "Apache Arrow",
13141
- id: "arrow",
13142
- module: "arrow",
13143
- version: VERSION,
13144
- // worker: true,
13145
- category: "table",
13146
- extensions: ["arrow", "feather"],
13147
- mimeTypes: [
13148
- "application/vnd.apache.arrow.file",
13149
- "application/vnd.apache.arrow.stream",
13150
- "application/octet-stream"
13151
- ],
13152
- binary: true,
13153
- tests: ["ARROW"],
13154
- options: {
13155
- arrow: {
13156
- shape: "columnar-table"
13157
- }
13158
- }
13159
- };
13160
- var ArrowLoader = {
13161
- ...ArrowWorkerLoader,
13162
- parse: async (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
13163
- parseSync: (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
13164
- parseInBatches: parseArrowInBatches
13165
- };
13166
-
13167
- // src/lib/encode-arrow.ts
13168
- function encodeArrowSync(data) {
13169
- const vectors = {};
13170
- for (const arrayData of data) {
13171
- const arrayVector = createVector(arrayData.array, arrayData.type);
13172
- vectors[arrayData.name] = arrayVector;
13173
- }
13174
- const table = new Table(vectors);
13175
- const arrowBuffer = tableToIPC(table);
13176
- return arrowBuffer;
13177
- }
13178
- function createVector(array, type) {
13179
- switch (type) {
13180
- case 1 /* DATE */:
13181
- return vectorFromArray(array);
13182
- case 0 /* FLOAT */:
13183
- default:
13184
- return vectorFromArray(array);
13185
- }
13186
- }
13187
-
13188
- // src/arrow-writer.ts
13189
- var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
13190
- var ArrowWriter = {
13191
- name: "Apache Arrow",
13192
- id: "arrow",
13193
- module: "arrow",
13194
- version: VERSION2,
13195
- extensions: ["arrow", "feather"],
13196
- mimeTypes: [
13197
- "application/vnd.apache.arrow.file",
13198
- "application/vnd.apache.arrow.stream",
13199
- "application/octet-stream"
13200
- ],
13201
- binary: true,
13202
- options: {},
13203
- encode: async function encodeArrow(data, options) {
13204
- return encodeArrowSync(data);
13205
- },
13206
- encodeSync(data, options) {
13207
- return encodeArrowSync(data);
13208
- }
13209
- };
13210
-
13211
- // ../gis/src/lib/geo/geoarrow-metadata.ts
13212
- var GEOARROW_ENCODINGS = [
13213
- "geoarrow.multipolygon",
13214
- "geoarrow.polygon",
13215
- "geoarrow.multilinestring",
13216
- "geoarrow.linestring",
13217
- "geoarrow.multipoint",
13218
- "geoarrow.point",
13219
- "geoarrow.wkb",
13220
- "geoarrow.wkt"
13221
- ];
13222
- var GEOARROW_COLUMN_METADATA_ENCODING = "ARROW:extension:name";
13223
- var GEOARROW_COLUMN_METADATA_METADATA = "ARROW:extension:metadata";
13224
- function getGeometryColumnsFromSchema(schema) {
13225
- const geometryColumns = {};
13226
- for (const field of schema.fields) {
13227
- const metadata = getGeometryMetadataForField(field);
13228
- if (metadata) {
13229
- geometryColumns[field.name] = metadata;
13230
- }
13231
- }
13232
- return geometryColumns;
13233
- }
13234
- function getGeometryMetadataForField(field) {
13235
- let metadata = null;
13236
- let geoEncoding = field.metadata?.[GEOARROW_COLUMN_METADATA_ENCODING];
13237
- if (geoEncoding) {
13238
- geoEncoding = geoEncoding.toLowerCase();
13239
- if (geoEncoding === "wkb") {
13240
- geoEncoding = "geoarrow.wkb";
13241
- }
13242
- if (geoEncoding === "wkt") {
13243
- geoEncoding = "geoarrow.wkt";
13244
- }
13245
- if (!GEOARROW_ENCODINGS.includes(geoEncoding)) {
13246
- console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`);
13247
- } else {
13248
- metadata = metadata || {};
13249
- metadata.encoding = geoEncoding;
13250
- }
13251
- }
13252
- const columnMetadata = field.metadata?.[GEOARROW_COLUMN_METADATA_METADATA];
13253
- if (columnMetadata) {
13254
- try {
13255
- metadata = JSON.parse(columnMetadata);
13256
- } catch (error) {
13257
- console.warn("Failed to parse GeoArrow metadata", error);
13258
- }
13259
- }
13260
- return metadata || null;
13261
- }
13262
-
13263
- // ../../node_modules/@babel/runtime/helpers/esm/typeof.js
13264
- function _typeof(obj) {
13265
- "@babel/helpers - typeof";
13266
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj2) {
13267
- return typeof obj2;
13268
- } : function(obj2) {
13269
- return obj2 && "function" == typeof Symbol && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
13270
- }, _typeof(obj);
13271
- }
13272
-
13273
- // ../../node_modules/@babel/runtime/helpers/esm/toPrimitive.js
13274
- function _toPrimitive(input, hint) {
13275
- if (_typeof(input) !== "object" || input === null)
13276
- return input;
13277
- var prim = input[Symbol.toPrimitive];
13278
- if (prim !== void 0) {
13279
- var res = prim.call(input, hint || "default");
13280
- if (_typeof(res) !== "object")
13281
- return res;
13282
- throw new TypeError("@@toPrimitive must return a primitive value.");
13283
- }
13284
- return (hint === "string" ? String : Number)(input);
13285
- }
13286
-
13287
- // ../../node_modules/@babel/runtime/helpers/esm/toPropertyKey.js
13288
- function _toPropertyKey(arg) {
13289
- var key = _toPrimitive(arg, "string");
13290
- return _typeof(key) === "symbol" ? key : String(key);
13291
- }
13292
-
13293
- // ../../node_modules/@babel/runtime/helpers/esm/defineProperty.js
13294
- function _defineProperty(obj, key, value) {
13295
- key = _toPropertyKey(key);
13296
- if (key in obj) {
13297
- Object.defineProperty(obj, key, {
13298
- value,
13299
- enumerable: true,
13300
- configurable: true,
13301
- writable: true
13302
- });
13303
- } else {
13304
- obj[key] = value;
13305
- }
13306
- return obj;
13307
- }
13308
-
13309
- // ../../node_modules/@math.gl/polygon/dist/polygon-utils.js
13310
- var DimIndex = {
13311
- x: 0,
13312
- y: 1,
13313
- z: 2
13314
- };
13315
- function getPolygonSignedArea(points, options = {}) {
13316
- const {
13317
- start = 0,
13318
- end = points.length,
13319
- plane = "xy"
13320
- } = options;
13321
- const dim = options.size || 2;
13322
- let area2 = 0;
13323
- const i0 = DimIndex[plane[0]];
13324
- const i1 = DimIndex[plane[1]];
13325
- for (let i = start, j = end - dim; i < end; i += dim) {
13326
- area2 += (points[i + i0] - points[j + i0]) * (points[i + i1] + points[j + i1]);
13327
- j = i;
13328
- }
13329
- return area2 / 2;
13330
- }
13331
-
13332
- // ../../node_modules/@math.gl/polygon/dist/earcut.js
13333
- function earcut(positions, holeIndices, dim = 2, areas, plane = "xy") {
13334
- const hasHoles = holeIndices && holeIndices.length;
13335
- const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
13336
- let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0], plane);
13337
- const triangles = [];
13338
- if (!outerNode || outerNode.next === outerNode.prev)
13339
- return triangles;
13340
- let invSize;
13341
- let maxX;
13342
- let maxY;
13343
- let minX;
13344
- let minY;
13345
- let x;
13346
- let y;
13347
- if (hasHoles)
13348
- outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas, plane);
13349
- if (positions.length > 80 * dim) {
13350
- minX = maxX = positions[0];
13351
- minY = maxY = positions[1];
13352
- for (let i = dim; i < outerLen; i += dim) {
13353
- x = positions[i];
13354
- y = positions[i + 1];
13355
- if (x < minX)
13356
- minX = x;
13357
- if (y < minY)
13358
- minY = y;
13359
- if (x > maxX)
13360
- maxX = x;
13361
- if (y > maxY)
13362
- maxY = y;
13363
- }
13364
- invSize = Math.max(maxX - minX, maxY - minY);
13365
- invSize = invSize !== 0 ? 32767 / invSize : 0;
13366
- }
13367
- earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
13368
- return triangles;
13369
- }
13370
- function linkedList(data, start, end, dim, clockwise, area2, plane) {
13371
- let i;
13372
- let last;
13373
- if (area2 === void 0) {
13374
- area2 = getPolygonSignedArea(data, {
13375
- start,
13376
- end,
13377
- size: dim,
13378
- plane
13379
- });
13380
- }
13381
- let i0 = DimIndex[plane[0]];
13382
- let i1 = DimIndex[plane[1]];
13383
- if (clockwise === area2 < 0) {
13384
- for (i = start; i < end; i += dim)
13385
- last = insertNode(i, data[i + i0], data[i + i1], last);
13386
- } else {
13387
- for (i = end - dim; i >= start; i -= dim)
13388
- last = insertNode(i, data[i + i0], data[i + i1], last);
13389
- }
13390
- if (last && equals(last, last.next)) {
13391
- removeNode(last);
13392
- last = last.next;
13393
- }
13394
- return last;
13395
- }
13396
- function filterPoints(start, end) {
13397
- if (!start)
13398
- return start;
13399
- if (!end)
13400
- end = start;
13401
- let p = start;
13402
- let again;
13403
- do {
13404
- again = false;
13405
- if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
13406
- removeNode(p);
13407
- p = end = p.prev;
13408
- if (p === p.next)
13409
- break;
13410
- again = true;
13411
- } else {
13412
- p = p.next;
13413
- }
13414
- } while (again || p !== end);
13415
- return end;
12997
+ function filterPoints(start, end) {
12998
+ if (!start)
12999
+ return start;
13000
+ if (!end)
13001
+ end = start;
13002
+ let p = start;
13003
+ let again;
13004
+ do {
13005
+ again = false;
13006
+ if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
13007
+ removeNode(p);
13008
+ p = end = p.prev;
13009
+ if (p === p.next)
13010
+ break;
13011
+ again = true;
13012
+ } else {
13013
+ p = p.next;
13014
+ }
13015
+ } while (again || p !== end);
13016
+ return end;
13416
13017
  }
13417
13018
  function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
13418
13019
  if (!ear)
@@ -13667,615 +13268,515 @@ return true;`);
13667
13268
  pSize--;
13668
13269
  } else {
13669
13270
  e = q;
13670
- q = q.nextZ;
13671
- qSize--;
13672
- }
13673
- if (tail)
13674
- tail.nextZ = e;
13675
- else
13676
- list = e;
13677
- e.prevZ = tail;
13678
- tail = e;
13679
- }
13680
- p = q;
13681
- }
13682
- tail.nextZ = null;
13683
- inSize *= 2;
13684
- } while (numMerges > 1);
13685
- return list;
13686
- }
13687
- function zOrder(x, y, minX, minY, invSize) {
13688
- x = (x - minX) * invSize | 0;
13689
- y = (y - minY) * invSize | 0;
13690
- x = (x | x << 8) & 16711935;
13691
- x = (x | x << 4) & 252645135;
13692
- x = (x | x << 2) & 858993459;
13693
- x = (x | x << 1) & 1431655765;
13694
- y = (y | y << 8) & 16711935;
13695
- y = (y | y << 4) & 252645135;
13696
- y = (y | y << 2) & 858993459;
13697
- y = (y | y << 1) & 1431655765;
13698
- return x | y << 1;
13699
- }
13700
- function getLeftmost(start) {
13701
- let p = start;
13702
- let leftmost = start;
13703
- do {
13704
- if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
13705
- leftmost = p;
13706
- p = p.next;
13707
- } while (p !== start);
13708
- return leftmost;
13709
- }
13710
- function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
13711
- return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
13712
- }
13713
- function isValidDiagonal(a, b) {
13714
- return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && (area(a.prev, a, b.prev) || area(a, b.prev, b)) || equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
13715
- }
13716
- function area(p, q, r) {
13717
- return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
13718
- }
13719
- function equals(p1, p2) {
13720
- return p1.x === p2.x && p1.y === p2.y;
13721
- }
13722
- function intersects(p1, q1, p2, q2) {
13723
- const o1 = sign(area(p1, q1, p2));
13724
- const o2 = sign(area(p1, q1, q2));
13725
- const o3 = sign(area(p2, q2, p1));
13726
- const o4 = sign(area(p2, q2, q1));
13727
- if (o1 !== o2 && o3 !== o4)
13728
- return true;
13729
- if (o1 === 0 && onSegment(p1, p2, q1))
13730
- return true;
13731
- if (o2 === 0 && onSegment(p1, q2, q1))
13732
- return true;
13733
- if (o3 === 0 && onSegment(p2, p1, q2))
13734
- return true;
13735
- if (o4 === 0 && onSegment(p2, q1, q2))
13736
- return true;
13737
- return false;
13738
- }
13739
- function onSegment(p, q, r) {
13740
- return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
13741
- }
13742
- function sign(num) {
13743
- return num > 0 ? 1 : num < 0 ? -1 : 0;
13744
- }
13745
- function intersectsPolygon(a, b) {
13746
- let p = a;
13747
- do {
13748
- if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
13749
- return true;
13750
- p = p.next;
13751
- } while (p !== a);
13752
- return false;
13753
- }
13754
- function locallyInside(a, b) {
13755
- return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
13756
- }
13757
- function middleInside(a, b) {
13758
- let p = a;
13759
- let inside = false;
13760
- const px = (a.x + b.x) / 2;
13761
- const py = (a.y + b.y) / 2;
13762
- do {
13763
- if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
13764
- inside = !inside;
13765
- p = p.next;
13766
- } while (p !== a);
13767
- return inside;
13768
- }
13769
- function splitPolygon(a, b) {
13770
- const a2 = new Vertex(a.i, a.x, a.y);
13771
- const b2 = new Vertex(b.i, b.x, b.y);
13772
- const an = a.next;
13773
- const bp = b.prev;
13774
- a.next = b;
13775
- b.prev = a;
13776
- a2.next = an;
13777
- an.prev = a2;
13778
- b2.next = a2;
13779
- a2.prev = b2;
13780
- bp.next = b2;
13781
- b2.prev = bp;
13782
- return b2;
13783
- }
13784
- function insertNode(i, x, y, last) {
13785
- const p = new Vertex(i, x, y);
13786
- if (!last) {
13787
- p.prev = p;
13788
- p.next = p;
13789
- } else {
13790
- p.next = last.next;
13791
- p.prev = last;
13792
- last.next.prev = p;
13793
- last.next = p;
13794
- }
13795
- return p;
13796
- }
13797
- function removeNode(p) {
13798
- p.next.prev = p.prev;
13799
- p.prev.next = p.next;
13800
- if (p.prevZ)
13801
- p.prevZ.nextZ = p.nextZ;
13802
- if (p.nextZ)
13803
- p.nextZ.prevZ = p.prevZ;
13804
- }
13805
- var Vertex = class {
13806
- constructor(i, x, y) {
13807
- _defineProperty(this, "i", void 0);
13808
- _defineProperty(this, "x", void 0);
13809
- _defineProperty(this, "y", void 0);
13810
- _defineProperty(this, "prev", null);
13811
- _defineProperty(this, "next", null);
13812
- _defineProperty(this, "z", 0);
13813
- _defineProperty(this, "prevZ", null);
13814
- _defineProperty(this, "nextZ", null);
13815
- _defineProperty(this, "steiner", false);
13816
- this.i = i;
13817
- this.x = x;
13818
- this.y = y;
13819
- }
13820
- };
13821
-
13822
- // ../gis/src/lib/binary-features/binary-to-geojson.ts
13823
- function binaryToGeometry(data, startIndex, endIndex) {
13824
- switch (data.type) {
13825
- case "Point":
13826
- return pointToGeoJson(data, startIndex, endIndex);
13827
- case "LineString":
13828
- return lineStringToGeoJson(data, startIndex, endIndex);
13829
- case "Polygon":
13830
- return polygonToGeoJson(data, startIndex, endIndex);
13831
- default:
13832
- const unexpectedInput = data;
13833
- throw new Error(`Unsupported geometry type: ${unexpectedInput?.type}`);
13834
- }
13835
- }
13836
- function polygonToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
13837
- const { positions } = data;
13838
- const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
13839
- const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
13840
- (x) => x >= startIndex && x <= endIndex
13841
- );
13842
- const multi = polygonIndices.length > 2;
13843
- if (!multi) {
13844
- const coordinates2 = [];
13845
- for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
13846
- const startRingIndex = primitivePolygonIndices[i];
13847
- const endRingIndex = primitivePolygonIndices[i + 1];
13848
- const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
13849
- coordinates2.push(ringCoordinates);
13271
+ q = q.nextZ;
13272
+ qSize--;
13273
+ }
13274
+ if (tail)
13275
+ tail.nextZ = e;
13276
+ else
13277
+ list = e;
13278
+ e.prevZ = tail;
13279
+ tail = e;
13280
+ }
13281
+ p = q;
13850
13282
  }
13851
- return { type: "Polygon", coordinates: coordinates2 };
13852
- }
13853
- const coordinates = [];
13854
- for (let i = 0; i < polygonIndices.length - 1; i++) {
13855
- const startPolygonIndex = polygonIndices[i];
13856
- const endPolygonIndex = polygonIndices[i + 1];
13857
- const polygonCoordinates = polygonToGeoJson(
13858
- data,
13859
- startPolygonIndex,
13860
- endPolygonIndex
13861
- ).coordinates;
13862
- coordinates.push(polygonCoordinates);
13863
- }
13864
- return { type: "MultiPolygon", coordinates };
13283
+ tail.nextZ = null;
13284
+ inSize *= 2;
13285
+ } while (numMerges > 1);
13286
+ return list;
13865
13287
  }
13866
- function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
13867
- const { positions } = data;
13868
- const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
13869
- const multi = pathIndices.length > 2;
13870
- if (!multi) {
13871
- const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
13872
- return { type: "LineString", coordinates: coordinates2 };
13873
- }
13874
- const coordinates = [];
13875
- for (let i = 0; i < pathIndices.length - 1; i++) {
13876
- const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
13877
- coordinates.push(ringCoordinates);
13878
- }
13879
- return { type: "MultiLineString", coordinates };
13288
+ function zOrder(x, y, minX, minY, invSize) {
13289
+ x = (x - minX) * invSize | 0;
13290
+ y = (y - minY) * invSize | 0;
13291
+ x = (x | x << 8) & 16711935;
13292
+ x = (x | x << 4) & 252645135;
13293
+ x = (x | x << 2) & 858993459;
13294
+ x = (x | x << 1) & 1431655765;
13295
+ y = (y | y << 8) & 16711935;
13296
+ y = (y | y << 4) & 252645135;
13297
+ y = (y | y << 2) & 858993459;
13298
+ y = (y | y << 1) & 1431655765;
13299
+ return x | y << 1;
13880
13300
  }
13881
- function pointToGeoJson(data, startIndex, endIndex) {
13882
- const { positions } = data;
13883
- const coordinates = ringToGeoJson(positions, startIndex, endIndex);
13884
- const multi = coordinates.length > 1;
13885
- if (multi) {
13886
- return { type: "MultiPoint", coordinates };
13887
- }
13888
- return { type: "Point", coordinates: coordinates[0] };
13301
+ function getLeftmost(start) {
13302
+ let p = start;
13303
+ let leftmost = start;
13304
+ do {
13305
+ if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
13306
+ leftmost = p;
13307
+ p = p.next;
13308
+ } while (p !== start);
13309
+ return leftmost;
13889
13310
  }
13890
- function ringToGeoJson(positions, startIndex, endIndex) {
13891
- startIndex = startIndex || 0;
13892
- endIndex = endIndex || positions.value.length / positions.size;
13893
- const ringCoordinates = [];
13894
- for (let j = startIndex; j < endIndex; j++) {
13895
- const coord = Array();
13896
- for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
13897
- coord.push(Number(positions.value[k]));
13898
- }
13899
- ringCoordinates.push(coord);
13900
- }
13901
- return ringCoordinates;
13311
+ function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
13312
+ return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
13902
13313
  }
13903
-
13904
- // src/tables/convert-arrow-to-geojson-table.ts
13905
- function convertArrowToGeoJSONTable(table) {
13906
- const arrowTable = table.data;
13907
- const schema = serializeArrowSchema(arrowTable.schema);
13908
- const geometryColumns = getGeometryColumnsFromSchema(schema);
13909
- const encoding = geometryColumns.geometry.encoding;
13910
- const features = [];
13911
- const propertyColumnNames = arrowTable.schema.fields.map((field) => field.name).filter((name) => !(name in geometryColumns));
13912
- const propertiesTable = arrowTable.select(propertyColumnNames);
13913
- const arrowGeometryColumn = arrowTable.getChild("geometry");
13914
- for (let row = 0; row < arrowTable.numRows; row++) {
13915
- const arrowGeometry = arrowGeometryColumn?.get(row);
13916
- const feature = parseGeometryFromArrow(arrowGeometry, encoding);
13917
- if (feature) {
13918
- const properties = propertiesTable.get(row)?.toJSON() || {};
13919
- features.push({ type: "Feature", geometry: feature, properties });
13920
- }
13921
- }
13922
- return {
13923
- shape: "geojson-table",
13924
- type: "FeatureCollection",
13925
- schema: table.schema,
13926
- features
13927
- };
13314
+ function isValidDiagonal(a, b) {
13315
+ return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
13316
+ (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
13317
+ (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
13318
+ equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
13928
13319
  }
13929
-
13930
- // src/parsers/parse-geoarrow-sync.ts
13931
- function parseGeoArrowSync(arrayBuffer, options) {
13932
- const table = parseArrowSync(arrayBuffer, { shape: "arrow-table" });
13933
- switch (options?.shape) {
13934
- case "geojson-table":
13935
- return convertArrowToGeoJSONTable(table);
13936
- default:
13937
- return table;
13938
- }
13320
+ function area(p, q, r) {
13321
+ return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
13939
13322
  }
13940
-
13941
- // src/parsers/parse-geoarrow-in-batches.ts
13942
- function parseGeoArrowInBatches(asyncIterator) {
13943
- return parseArrowInBatches(asyncIterator);
13323
+ function equals(p1, p2) {
13324
+ return p1.x === p2.x && p1.y === p2.y;
13944
13325
  }
13945
-
13946
- // src/geoarrow-loader.ts
13947
- var GeoArrowWorkerLoader = {
13948
- ...ArrowWorkerLoader,
13949
- options: {
13950
- arrow: {
13951
- shape: "arrow-table"
13952
- }
13953
- }
13954
- };
13955
- var GeoArrowLoader = {
13956
- ...GeoArrowWorkerLoader,
13957
- parse: async (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
13958
- parseSync: (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
13959
- parseInBatches: parseGeoArrowInBatches
13960
- };
13961
-
13962
- // src/geoarrow/get-arrow-bounds.ts
13963
- function updateBoundsFromGeoArrowSamples(flatCoords, nDim, bounds, sampleSize = 100) {
13964
- const numberOfFeatures = flatCoords.length / nDim;
13965
- const sampleStep = Math.max(Math.floor(numberOfFeatures / sampleSize), 1);
13966
- const newBounds = [...bounds];
13967
- for (let i = 0; i < numberOfFeatures; i += sampleStep) {
13968
- const lng = flatCoords[i * nDim];
13969
- const lat = flatCoords[i * nDim + 1];
13970
- if (lng < newBounds[0]) {
13971
- newBounds[0] = lng;
13972
- }
13973
- if (lat < newBounds[1]) {
13974
- newBounds[1] = lat;
13975
- }
13976
- if (lng > newBounds[2]) {
13977
- newBounds[2] = lng;
13978
- }
13979
- if (lat > newBounds[3]) {
13980
- newBounds[3] = lat;
13981
- }
13982
- }
13983
- return newBounds;
13326
+ function intersects(p1, q1, p2, q2) {
13327
+ const o1 = sign(area(p1, q1, p2));
13328
+ const o2 = sign(area(p1, q1, q2));
13329
+ const o3 = sign(area(p2, q2, p1));
13330
+ const o4 = sign(area(p2, q2, q1));
13331
+ if (o1 !== o2 && o3 !== o4)
13332
+ return true;
13333
+ if (o1 === 0 && onSegment(p1, p2, q1))
13334
+ return true;
13335
+ if (o2 === 0 && onSegment(p1, q2, q1))
13336
+ return true;
13337
+ if (o3 === 0 && onSegment(p2, p1, q2))
13338
+ return true;
13339
+ if (o4 === 0 && onSegment(p2, q1, q2))
13340
+ return true;
13341
+ return false;
13984
13342
  }
13985
-
13986
- // src/geoarrow/convert-geoarrow-to-binary-geometry.ts
13987
- function getBinaryGeometryTemplate() {
13988
- return {
13989
- globalFeatureIds: { value: new Uint32Array(0), size: 1 },
13990
- positions: { value: new Float32Array(0), size: 2 },
13991
- properties: [],
13992
- numericProps: {},
13993
- featureIds: { value: new Uint32Array(0), size: 1 }
13994
- };
13343
+ function onSegment(p, q, r) {
13344
+ return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
13995
13345
  }
13996
- function getBinaryGeometriesFromArrow(geoColumn, geoEncoding, options) {
13997
- const featureTypes = {
13998
- polygon: geoEncoding === "geoarrow.multipolygon" || geoEncoding === "geoarrow.polygon",
13999
- point: geoEncoding === "geoarrow.multipoint" || geoEncoding === "geoarrow.point",
14000
- line: geoEncoding === "geoarrow.multilinestring" || geoEncoding === "geoarrow.linestring"
14001
- };
14002
- const chunks = options?.chunkIndex !== void 0 && options?.chunkIndex >= 0 ? [geoColumn.data[options?.chunkIndex]] : geoColumn.data;
14003
- let bounds = [Infinity, Infinity, -Infinity, -Infinity];
14004
- let globalFeatureIdOffset = options?.chunkOffset || 0;
14005
- const binaryGeometries = [];
14006
- chunks.forEach((chunk) => {
14007
- const { featureIds, flatCoordinateArray, nDim, geomOffset, triangles } = getBinaryGeometriesFromChunk(chunk, geoEncoding, options);
14008
- const globalFeatureIds = new Uint32Array(featureIds.length);
14009
- for (let i = 0; i < featureIds.length; i++) {
14010
- globalFeatureIds[i] = featureIds[i] + globalFeatureIdOffset;
14011
- }
14012
- const binaryContent = {
14013
- globalFeatureIds: { value: globalFeatureIds, size: 1 },
14014
- positions: {
14015
- value: flatCoordinateArray,
14016
- size: nDim
14017
- },
14018
- featureIds: { value: featureIds, size: 1 },
14019
- // eslint-disable-next-line no-loop-func
14020
- properties: [...Array(chunk.length).keys()].map((i) => ({
14021
- index: i + globalFeatureIdOffset
14022
- }))
14023
- };
14024
- globalFeatureIdOffset += chunk.length;
14025
- binaryGeometries.push({
14026
- shape: "binary-feature-collection",
14027
- points: {
14028
- type: "Point",
14029
- ...getBinaryGeometryTemplate(),
14030
- ...featureTypes.point ? binaryContent : {}
14031
- },
14032
- lines: {
14033
- type: "LineString",
14034
- ...getBinaryGeometryTemplate(),
14035
- ...featureTypes.line ? binaryContent : {},
14036
- pathIndices: { value: featureTypes.line ? geomOffset : new Uint16Array(0), size: 1 }
14037
- },
14038
- polygons: {
14039
- type: "Polygon",
14040
- ...getBinaryGeometryTemplate(),
14041
- ...featureTypes.polygon ? binaryContent : {},
14042
- polygonIndices: {
14043
- // use geomOffset as polygonIndices same as primitivePolygonIndices since we are using earcut to get triangule indices
14044
- value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
14045
- size: 1
14046
- },
14047
- primitivePolygonIndices: {
14048
- value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
14049
- size: 1
14050
- },
14051
- ...triangles ? { triangles: { value: triangles, size: 1 } } : {}
14052
- }
14053
- });
14054
- bounds = updateBoundsFromGeoArrowSamples(flatCoordinateArray, nDim, bounds);
14055
- });
14056
- return {
14057
- binaryGeometries,
14058
- bounds,
14059
- featureTypes,
14060
- ...options?.calculateMeanCenters ? { meanCenters: getMeanCentersFromBinaryGeometries(binaryGeometries) } : {}
14061
- };
13346
+ function sign(num) {
13347
+ return num > 0 ? 1 : num < 0 ? -1 : 0;
14062
13348
  }
14063
- function getMeanCentersFromBinaryGeometries(binaryGeometries) {
14064
- const globalMeanCenters = [];
14065
- binaryGeometries.forEach((binaryGeometry) => {
14066
- let binaryGeometryType = null;
14067
- if (binaryGeometry.points && binaryGeometry.points.positions.value.length > 0) {
14068
- binaryGeometryType = "points" /* points */;
14069
- } else if (binaryGeometry.lines && binaryGeometry.lines.positions.value.length > 0) {
14070
- binaryGeometryType = "lines" /* lines */;
14071
- } else if (binaryGeometry.polygons && binaryGeometry.polygons.positions.value.length > 0) {
14072
- binaryGeometryType = "polygons" /* polygons */;
14073
- }
14074
- const binaryContent = binaryGeometryType ? binaryGeometry[binaryGeometryType] : null;
14075
- if (binaryContent && binaryGeometryType !== null) {
14076
- const featureIds = binaryContent.featureIds.value;
14077
- const flatCoordinateArray = binaryContent.positions.value;
14078
- const nDim = binaryContent.positions.size;
14079
- const primitivePolygonIndices = binaryContent.type === "Polygon" ? binaryContent.primitivePolygonIndices?.value : void 0;
14080
- const meanCenters = getMeanCentersFromGeometry(
14081
- featureIds,
14082
- flatCoordinateArray,
14083
- nDim,
14084
- binaryGeometryType,
14085
- primitivePolygonIndices
14086
- );
14087
- meanCenters.forEach((center) => {
14088
- globalMeanCenters.push(center);
14089
- });
14090
- }
14091
- });
14092
- return globalMeanCenters;
13349
+ function intersectsPolygon(a, b) {
13350
+ let p = a;
13351
+ do {
13352
+ if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
13353
+ return true;
13354
+ p = p.next;
13355
+ } while (p !== a);
13356
+ return false;
14093
13357
  }
14094
- function getMeanCentersFromGeometry(featureIds, flatCoordinateArray, nDim, geometryType, primitivePolygonIndices) {
14095
- const meanCenters = [];
14096
- const vertexCount = flatCoordinateArray.length;
14097
- let vertexIndex = 0;
14098
- let coordIdx = 0;
14099
- let primitiveIdx = 0;
14100
- while (vertexIndex < vertexCount) {
14101
- const featureId = featureIds[vertexIndex / nDim];
14102
- const center = [0, 0];
14103
- let vertexCountInFeature = 0;
14104
- while (vertexIndex < vertexCount && featureIds[coordIdx] === featureId) {
14105
- if (geometryType === "polygons" /* polygons */ && primitivePolygonIndices?.[primitiveIdx] === coordIdx) {
14106
- vertexIndex += nDim;
14107
- primitiveIdx++;
14108
- } else {
14109
- center[0] += flatCoordinateArray[vertexIndex];
14110
- center[1] += flatCoordinateArray[vertexIndex + 1];
14111
- vertexIndex += nDim;
14112
- vertexCountInFeature++;
14113
- }
14114
- coordIdx += 1;
14115
- }
14116
- center[0] /= vertexCountInFeature;
14117
- center[1] /= vertexCountInFeature;
14118
- meanCenters.push(center);
13358
+ function locallyInside(a, b) {
13359
+ return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
13360
+ }
13361
+ function middleInside(a, b) {
13362
+ let p = a;
13363
+ let inside = false;
13364
+ const px = (a.x + b.x) / 2;
13365
+ const py = (a.y + b.y) / 2;
13366
+ do {
13367
+ if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
13368
+ inside = !inside;
13369
+ p = p.next;
13370
+ } while (p !== a);
13371
+ return inside;
13372
+ }
13373
+ function splitPolygon(a, b) {
13374
+ const a2 = new Vertex(a.i, a.x, a.y);
13375
+ const b2 = new Vertex(b.i, b.x, b.y);
13376
+ const an = a.next;
13377
+ const bp = b.prev;
13378
+ a.next = b;
13379
+ b.prev = a;
13380
+ a2.next = an;
13381
+ an.prev = a2;
13382
+ b2.next = a2;
13383
+ a2.prev = b2;
13384
+ bp.next = b2;
13385
+ b2.prev = bp;
13386
+ return b2;
13387
+ }
13388
+ function insertNode(i, x, y, last) {
13389
+ const p = new Vertex(i, x, y);
13390
+ if (!last) {
13391
+ p.prev = p;
13392
+ p.next = p;
13393
+ } else {
13394
+ p.next = last.next;
13395
+ p.prev = last;
13396
+ last.next.prev = p;
13397
+ last.next = p;
14119
13398
  }
14120
- return meanCenters;
13399
+ return p;
14121
13400
  }
14122
- function getBinaryGeometriesFromChunk(chunk, geoEncoding, options) {
14123
- switch (geoEncoding) {
14124
- case "geoarrow.point":
14125
- case "geoarrow.multipoint":
14126
- return getBinaryPointsFromChunk(chunk, geoEncoding);
14127
- case "geoarrow.linestring":
14128
- case "geoarrow.multilinestring":
14129
- return getBinaryLinesFromChunk(chunk, geoEncoding);
14130
- case "geoarrow.polygon":
14131
- case "geoarrow.multipolygon":
14132
- return getBinaryPolygonsFromChunk(chunk, geoEncoding, options);
13401
+ function removeNode(p) {
13402
+ p.next.prev = p.prev;
13403
+ p.prev.next = p.next;
13404
+ if (p.prevZ)
13405
+ p.prevZ.nextZ = p.nextZ;
13406
+ if (p.nextZ)
13407
+ p.nextZ.prevZ = p.prevZ;
13408
+ }
13409
+ var Vertex = class {
13410
+ constructor(i, x, y) {
13411
+ this.prev = null;
13412
+ this.next = null;
13413
+ this.z = 0;
13414
+ this.prevZ = null;
13415
+ this.nextZ = null;
13416
+ this.steiner = false;
13417
+ this.i = i;
13418
+ this.x = x;
13419
+ this.y = y;
13420
+ }
13421
+ };
13422
+
13423
+ // ../gis/src/lib/binary-features/binary-to-geojson.ts
13424
+ function binaryToGeometry(data, startIndex, endIndex) {
13425
+ switch (data.type) {
13426
+ case "Point":
13427
+ return pointToGeoJson(data, startIndex, endIndex);
13428
+ case "LineString":
13429
+ return lineStringToGeoJson(data, startIndex, endIndex);
13430
+ case "Polygon":
13431
+ return polygonToGeoJson(data, startIndex, endIndex);
14133
13432
  default:
14134
- throw Error("invalid geoarrow encoding");
13433
+ const unexpectedInput = data;
13434
+ throw new Error(`Unsupported geometry type: ${unexpectedInput?.type}`);
14135
13435
  }
14136
13436
  }
14137
- function getTriangleIndices(polygonIndices, primitivePolygonIndices, flatCoordinateArray, nDim) {
14138
- try {
14139
- let primitiveIndex = 0;
14140
- const triangles = [];
14141
- for (let i = 0; i < polygonIndices.length - 1; i++) {
14142
- const startIdx = polygonIndices[i];
14143
- const endIdx = polygonIndices[i + 1];
14144
- const slicedFlatCoords = flatCoordinateArray.subarray(startIdx * nDim, endIdx * nDim);
14145
- const holeIndices = [];
14146
- while (primitivePolygonIndices[primitiveIndex] < endIdx) {
14147
- if (primitivePolygonIndices[primitiveIndex] > startIdx) {
14148
- holeIndices.push(primitivePolygonIndices[primitiveIndex] - startIdx);
14149
- }
14150
- primitiveIndex++;
14151
- }
14152
- const triangleIndices = earcut(
14153
- slicedFlatCoords,
14154
- holeIndices.length > 0 ? holeIndices : void 0,
14155
- nDim
14156
- );
14157
- if (triangleIndices.length === 0) {
14158
- throw Error("earcut failed e.g. invalid polygon");
14159
- }
14160
- for (let j = 0; j < triangleIndices.length; j++) {
14161
- triangles.push(triangleIndices[j] + startIdx);
14162
- }
14163
- }
14164
- const trianglesUint32 = new Uint32Array(triangles.length);
14165
- for (let i = 0; i < triangles.length; i++) {
14166
- trianglesUint32[i] = triangles[i];
13437
+ function polygonToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
13438
+ const { positions } = data;
13439
+ const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
13440
+ const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
13441
+ (x) => x >= startIndex && x <= endIndex
13442
+ );
13443
+ const multi = polygonIndices.length > 2;
13444
+ if (!multi) {
13445
+ const coordinates2 = [];
13446
+ for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
13447
+ const startRingIndex = primitivePolygonIndices[i];
13448
+ const endRingIndex = primitivePolygonIndices[i + 1];
13449
+ const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
13450
+ coordinates2.push(ringCoordinates);
14167
13451
  }
14168
- return trianglesUint32;
14169
- } catch (error) {
14170
- return null;
13452
+ return { type: "Polygon", coordinates: coordinates2 };
14171
13453
  }
13454
+ const coordinates = [];
13455
+ for (let i = 0; i < polygonIndices.length - 1; i++) {
13456
+ const startPolygonIndex = polygonIndices[i];
13457
+ const endPolygonIndex = polygonIndices[i + 1];
13458
+ const polygonCoordinates = polygonToGeoJson(
13459
+ data,
13460
+ startPolygonIndex,
13461
+ endPolygonIndex
13462
+ ).coordinates;
13463
+ coordinates.push(polygonCoordinates);
13464
+ }
13465
+ return { type: "MultiPolygon", coordinates };
14172
13466
  }
14173
- function getBinaryPolygonsFromChunk(chunk, geoEncoding, options) {
14174
- const isMultiPolygon = geoEncoding === "geoarrow.multipolygon";
14175
- const polygonData = isMultiPolygon ? chunk.children[0] : chunk;
14176
- const polygonOffset = polygonData.valueOffsets;
14177
- const partData = isMultiPolygon ? chunk.valueOffsets.map((i) => polygonOffset.at(i) || i) : chunk.valueOffsets;
14178
- const ringData = polygonData.children[0];
14179
- const pointData = ringData.children[0];
14180
- const coordData = pointData.children[0];
14181
- const nDim = pointData.stride;
14182
- const geomOffset = ringData.valueOffsets;
14183
- const flatCoordinateArray = coordData.values;
14184
- const geometryIndicies = new Uint16Array(polygonOffset.length);
14185
- for (let i = 0; i < polygonOffset.length; i++) {
14186
- geometryIndicies[i] = geomOffset[polygonOffset[i]];
13467
+ function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
13468
+ const { positions } = data;
13469
+ const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
13470
+ const multi = pathIndices.length > 2;
13471
+ if (!multi) {
13472
+ const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
13473
+ return { type: "LineString", coordinates: coordinates2 };
14187
13474
  }
14188
- const numOfVertices = flatCoordinateArray.length / nDim;
14189
- const featureIds = new Uint32Array(numOfVertices);
14190
- for (let i = 0; i < partData.length - 1; i++) {
14191
- const startIdx = geomOffset[partData[i]];
14192
- const endIdx = geomOffset[partData[i + 1]];
14193
- for (let j = startIdx; j < endIdx; j++) {
14194
- featureIds[j] = i;
13475
+ const coordinates = [];
13476
+ for (let i = 0; i < pathIndices.length - 1; i++) {
13477
+ const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
13478
+ coordinates.push(ringCoordinates);
13479
+ }
13480
+ return { type: "MultiLineString", coordinates };
13481
+ }
13482
+ function pointToGeoJson(data, startIndex, endIndex) {
13483
+ const { positions } = data;
13484
+ const coordinates = ringToGeoJson(positions, startIndex, endIndex);
13485
+ const multi = coordinates.length > 1;
13486
+ if (multi) {
13487
+ return { type: "MultiPoint", coordinates };
13488
+ }
13489
+ return { type: "Point", coordinates: coordinates[0] };
13490
+ }
13491
+ function ringToGeoJson(positions, startIndex, endIndex) {
13492
+ startIndex = startIndex || 0;
13493
+ endIndex = endIndex || positions.value.length / positions.size;
13494
+ const ringCoordinates = [];
13495
+ for (let j = startIndex; j < endIndex; j++) {
13496
+ const coord = Array();
13497
+ for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
13498
+ coord.push(Number(positions.value[k]));
14195
13499
  }
13500
+ ringCoordinates.push(coord);
14196
13501
  }
14197
- const triangles = options?.triangulate ? getTriangleIndices(geometryIndicies, geomOffset, flatCoordinateArray, nDim) : null;
13502
+ return ringCoordinates;
13503
+ }
13504
+
13505
+ // src/lib/tables/convert-arrow-schema.ts
13506
+ function convertArrowToSchema(arrowSchema) {
13507
+ return serializeArrowSchema(arrowSchema);
13508
+ }
13509
+ function convertSchemaToArrow(schema) {
13510
+ return deserializeArrowSchema(schema);
13511
+ }
13512
+ function serializeArrowSchema(arrowSchema) {
14198
13513
  return {
14199
- featureIds,
14200
- nDim,
14201
- flatCoordinateArray,
14202
- geomOffset,
14203
- geometryIndicies,
14204
- ...options?.triangulate && triangles ? { triangles } : {}
13514
+ fields: arrowSchema.fields.map((arrowField) => serializeArrowField(arrowField)),
13515
+ metadata: serializeArrowMetadata(arrowSchema.metadata)
14205
13516
  };
14206
13517
  }
14207
- function getBinaryLinesFromChunk(chunk, geoEncoding) {
14208
- const isMultiLineString = geoEncoding === "geoarrow.multilinestring";
14209
- const lineData = isMultiLineString ? chunk.children[0] : chunk;
14210
- const pointData = lineData.children[0];
14211
- const coordData = pointData.children[0];
14212
- const nDim = pointData.stride;
14213
- const geomOffset = lineData.valueOffsets;
14214
- const flatCoordinateArray = coordData.values;
14215
- const geometryIndicies = new Uint16Array(0);
14216
- const numOfVertices = flatCoordinateArray.length / nDim;
14217
- const featureIds = new Uint32Array(numOfVertices);
14218
- if (isMultiLineString) {
14219
- const partData = chunk.valueOffsets;
14220
- for (let i = 0; i < partData.length - 1; i++) {
14221
- const startIdx = geomOffset[partData[i]];
14222
- const endIdx = geomOffset[partData[i + 1]];
14223
- for (let j = startIdx; j < endIdx; j++) {
14224
- featureIds[j] = i;
14225
- }
14226
- }
14227
- } else {
14228
- for (let i = 0; i < chunk.length; i++) {
14229
- const startIdx = geomOffset[i];
14230
- const endIdx = geomOffset[i + 1];
14231
- for (let j = startIdx; j < endIdx; j++) {
14232
- featureIds[j] = i;
14233
- }
14234
- }
14235
- }
13518
+ function deserializeArrowSchema(schema) {
13519
+ return new Schema2(
13520
+ schema.fields.map((field) => deserializeArrowField(field)),
13521
+ deserializeArrowMetadata(schema.metadata)
13522
+ );
13523
+ }
13524
+ function serializeArrowMetadata(arrowMetadata) {
13525
+ return Object.fromEntries(arrowMetadata);
13526
+ }
13527
+ function deserializeArrowMetadata(metadata) {
13528
+ return metadata ? new Map(Object.entries(metadata)) : /* @__PURE__ */ new Map();
13529
+ }
13530
+ function serializeArrowField(field) {
14236
13531
  return {
14237
- featureIds,
14238
- flatCoordinateArray,
14239
- nDim,
14240
- geomOffset,
14241
- geometryIndicies
13532
+ name: field.name,
13533
+ type: serializeArrowType(field.type),
13534
+ nullable: field.nullable,
13535
+ metadata: serializeArrowMetadata(field.metadata)
14242
13536
  };
14243
13537
  }
14244
- function getBinaryPointsFromChunk(chunk, geoEncoding) {
14245
- const isMultiPoint = geoEncoding === "geoarrow.multipoint";
14246
- const pointData = isMultiPoint ? chunk.children[0] : chunk;
14247
- const coordData = pointData.children[0];
14248
- const nDim = pointData.stride;
14249
- const flatCoordinateArray = coordData.values;
14250
- const geometryIndicies = new Uint16Array(0);
14251
- const geomOffset = new Int32Array(0);
14252
- const numOfVertices = flatCoordinateArray.length / nDim;
14253
- const featureIds = new Uint32Array(numOfVertices);
14254
- if (isMultiPoint) {
14255
- const partData = chunk.valueOffsets;
14256
- for (let i = 0; i < partData.length - 1; i++) {
14257
- const startIdx = partData[i];
14258
- const endIdx = partData[i + 1];
14259
- for (let j = startIdx; j < endIdx; j++) {
14260
- featureIds[j] = i;
13538
+ function deserializeArrowField(field) {
13539
+ return new Field2(
13540
+ field.name,
13541
+ deserializeArrowType(field.type),
13542
+ field.nullable,
13543
+ deserializeArrowMetadata(field.metadata)
13544
+ );
13545
+ }
13546
+ function serializeArrowType(arrowType) {
13547
+ switch (arrowType.constructor) {
13548
+ case Null2:
13549
+ return "null";
13550
+ case Binary2:
13551
+ return "binary";
13552
+ case Bool2:
13553
+ return "bool";
13554
+ case Int_:
13555
+ const intType = arrowType;
13556
+ return `${intType.isSigned ? "u" : ""}int${intType.bitWidth}`;
13557
+ case Int8:
13558
+ return "int8";
13559
+ case Int16:
13560
+ return "int16";
13561
+ case Int32:
13562
+ return "int32";
13563
+ case Int64:
13564
+ return "int64";
13565
+ case Uint8:
13566
+ return "uint8";
13567
+ case Uint16:
13568
+ return "uint16";
13569
+ case Uint32:
13570
+ return "uint32";
13571
+ case Uint64:
13572
+ return "uint64";
13573
+ case Float:
13574
+ const precision = arrowType.precision;
13575
+ switch (precision) {
13576
+ case Precision.HALF:
13577
+ return "float16";
13578
+ case Precision.SINGLE:
13579
+ return "float32";
13580
+ case Precision.DOUBLE:
13581
+ return "float64";
13582
+ default:
13583
+ return "float16";
14261
13584
  }
14262
- }
14263
- } else {
14264
- for (let i = 0; i < chunk.length; i++) {
14265
- featureIds[i] = i;
13585
+ case Float16:
13586
+ return "float16";
13587
+ case Float32:
13588
+ return "float32";
13589
+ case Float64:
13590
+ return "float64";
13591
+ case Utf82:
13592
+ return "utf8";
13593
+ case Decimal2:
13594
+ const decimal = arrowType;
13595
+ return {
13596
+ type: "decimal",
13597
+ bitWidth: decimal.bitWidth,
13598
+ precision: decimal.precision,
13599
+ scale: decimal.scale
13600
+ };
13601
+ case Date_:
13602
+ const dateUnit = arrowType.unit;
13603
+ return dateUnit === DateUnit.DAY ? "date-day" : "date-millisecond";
13604
+ case DateDay:
13605
+ return "date-day";
13606
+ case DateMillisecond:
13607
+ return "date-millisecond";
13608
+ case Time_:
13609
+ const timeUnit = arrowType.unit;
13610
+ switch (timeUnit) {
13611
+ case TimeUnit.SECOND:
13612
+ return "time-second";
13613
+ case TimeUnit.MILLISECOND:
13614
+ return "time-millisecond";
13615
+ case TimeUnit.MICROSECOND:
13616
+ return "time-microsecond";
13617
+ case TimeUnit.NANOSECOND:
13618
+ return "time-nanosecond";
13619
+ default:
13620
+ return "time-second";
13621
+ }
13622
+ case TimeMillisecond:
13623
+ return "time-millisecond";
13624
+ case TimeSecond:
13625
+ return "time-second";
13626
+ case TimeMicrosecond:
13627
+ return "time-microsecond";
13628
+ case TimeNanosecond:
13629
+ return "time-nanosecond";
13630
+ case Timestamp_:
13631
+ const timeStampUnit = arrowType.unit;
13632
+ switch (timeStampUnit) {
13633
+ case TimeUnit.SECOND:
13634
+ return "timestamp-second";
13635
+ case TimeUnit.MILLISECOND:
13636
+ return "timestamp-millisecond";
13637
+ case TimeUnit.MICROSECOND:
13638
+ return "timestamp-microsecond";
13639
+ case TimeUnit.NANOSECOND:
13640
+ return "timestamp-nanosecond";
13641
+ default:
13642
+ return "timestamp-second";
13643
+ }
13644
+ case TimestampSecond:
13645
+ return "timestamp-second";
13646
+ case TimestampMillisecond:
13647
+ return "timestamp-millisecond";
13648
+ case TimestampMicrosecond:
13649
+ return "timestamp-microsecond";
13650
+ case TimestampNanosecond:
13651
+ return "timestamp-nanosecond";
13652
+ case Interval_:
13653
+ const intervalUnit = arrowType.unit;
13654
+ switch (intervalUnit) {
13655
+ case IntervalUnit.DAY_TIME:
13656
+ return "interval-daytime";
13657
+ case IntervalUnit.YEAR_MONTH:
13658
+ return "interval-yearmonth";
13659
+ default:
13660
+ return "interval-daytime";
13661
+ }
13662
+ case IntervalDayTime:
13663
+ return "interval-daytime";
13664
+ case IntervalYearMonth:
13665
+ return "interval-yearmonth";
13666
+ case Map_:
13667
+ const mapType = arrowType;
13668
+ return {
13669
+ type: "map",
13670
+ keysSorted: mapType.keysSorted,
13671
+ children: mapType.children.map((arrowField) => serializeArrowField(arrowField))
13672
+ };
13673
+ case List2:
13674
+ const listType = arrowType;
13675
+ const listField = listType.valueField;
13676
+ return {
13677
+ type: "list",
13678
+ children: [serializeArrowField(listField)]
13679
+ };
13680
+ case FixedSizeList2:
13681
+ const fixedSizeList = arrowType;
13682
+ return {
13683
+ type: "fixed-size-list",
13684
+ listSize: fixedSizeList.listSize,
13685
+ children: [serializeArrowField(fixedSizeList.children[0])]
13686
+ };
13687
+ case Struct:
13688
+ const structType = arrowType;
13689
+ return {
13690
+ type: "struct",
13691
+ children: structType.children.map((arrowField) => serializeArrowField(arrowField))
13692
+ };
13693
+ default:
13694
+ throw new Error(`arrow type not supported: ${arrowType.constructor.name}`);
13695
+ }
13696
+ }
13697
+ function deserializeArrowType(dataType) {
13698
+ if (typeof dataType === "object") {
13699
+ switch (dataType.type) {
13700
+ case "decimal":
13701
+ return new Decimal2(dataType.precision, dataType.scale, dataType.bitWidth);
13702
+ case "map":
13703
+ let children = dataType.children.map((arrowField) => deserializeArrowField(arrowField));
13704
+ return new Map_(children, dataType.keysSorted);
13705
+ case "list":
13706
+ const field = deserializeArrowField(dataType.children[0]);
13707
+ return new List2(field);
13708
+ case "fixed-size-list":
13709
+ const child = deserializeArrowField(dataType.children[0]);
13710
+ return new FixedSizeList2(dataType.listSize, child);
13711
+ case "struct":
13712
+ children = dataType.children.map((arrowField) => deserializeArrowField(arrowField));
13713
+ return new Struct(children);
13714
+ default:
13715
+ throw new Error("array type not supported");
14266
13716
  }
14267
13717
  }
14268
- return {
14269
- featureIds,
14270
- flatCoordinateArray,
14271
- nDim,
14272
- geomOffset,
14273
- geometryIndicies
14274
- };
13718
+ switch (dataType) {
13719
+ case "null":
13720
+ return new Null2();
13721
+ case "binary":
13722
+ return new Binary2();
13723
+ case "bool":
13724
+ return new Bool2();
13725
+ case "int8":
13726
+ return new Int8();
13727
+ case "int16":
13728
+ return new Int16();
13729
+ case "int32":
13730
+ return new Int32();
13731
+ case "int64":
13732
+ return new Int64();
13733
+ case "uint8":
13734
+ return new Uint8();
13735
+ case "uint16":
13736
+ return new Uint16();
13737
+ case "uint32":
13738
+ return new Uint32();
13739
+ case "uint64":
13740
+ return new Uint64();
13741
+ case "float16":
13742
+ return new Float16();
13743
+ case "float32":
13744
+ return new Float32();
13745
+ case "float64":
13746
+ return new Float64();
13747
+ case "utf8":
13748
+ return new Utf82();
13749
+ case "date-day":
13750
+ return new DateDay();
13751
+ case "date-millisecond":
13752
+ return new DateMillisecond();
13753
+ case "time-second":
13754
+ return new TimeSecond();
13755
+ case "time-millisecond":
13756
+ return new TimeMillisecond();
13757
+ case "time-microsecond":
13758
+ return new TimeMicrosecond();
13759
+ case "time-nanosecond":
13760
+ return new TimeNanosecond();
13761
+ case "timestamp-second":
13762
+ return new TimestampSecond();
13763
+ case "timestamp-millisecond":
13764
+ return new TimestampMillisecond();
13765
+ case "timestamp-microsecond":
13766
+ return new TimestampMicrosecond();
13767
+ case "timestamp-nanosecond":
13768
+ return new TimestampNanosecond();
13769
+ case "interval-daytime":
13770
+ return new IntervalDayTime();
13771
+ case "interval-yearmonth":
13772
+ return new IntervalYearMonth();
13773
+ default:
13774
+ throw new Error("array type not supported");
13775
+ }
14275
13776
  }
14276
13777
 
14277
13778
  // ../wkt/src/lib/utils/version.ts
14278
- var VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
13779
+ var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
14279
13780
 
14280
13781
  // ../wkt/src/lib/parse-wkt.ts
14281
13782
  var numberRegexp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/;
@@ -14293,747 +13794,1286 @@ return true;`);
14293
13794
  function isWKT(input) {
14294
13795
  return WKT_MAGIC_STRINGS.some((magicString) => input.startsWith(magicString));
14295
13796
  }
14296
- function parseWKT(input, options) {
14297
- return parseWKTToGeometry(input, options);
13797
+ function parseWKT(input, options) {
13798
+ return parseWKTToGeometry(input, options);
13799
+ }
13800
+ function parseWKTToGeometry(input, options) {
13801
+ const parts = input.split(";");
13802
+ let _ = parts.pop();
13803
+ const srid = (parts.shift() || "").split("=").pop();
13804
+ const state = { parts, _, i: 0 };
13805
+ const geometry = parseGeometry(state);
13806
+ return options?.wkt?.crs ? addCRS(geometry, srid) : geometry;
13807
+ }
13808
+ function parseGeometry(state) {
13809
+ return parsePoint(state) || parseLineString(state) || parsePolygon(state) || parseMultiPoint(state) || parseMultiLineString(state) || parseMultiPolygon(state) || parseGeometryCollection(state);
13810
+ }
13811
+ function addCRS(obj, srid) {
13812
+ if (obj && srid?.match(/\d+/)) {
13813
+ const crs = {
13814
+ type: "name",
13815
+ properties: {
13816
+ name: "urn:ogc:def:crs:EPSG::" + srid
13817
+ }
13818
+ };
13819
+ obj.crs = crs;
13820
+ }
13821
+ return obj;
13822
+ }
13823
+ function parsePoint(state) {
13824
+ if (!$(/^(POINT(\sz)?)/i, state)) {
13825
+ return null;
13826
+ }
13827
+ white(state);
13828
+ if (!$(/^(\()/, state)) {
13829
+ return null;
13830
+ }
13831
+ const c = coords(state);
13832
+ if (!c) {
13833
+ return null;
13834
+ }
13835
+ white(state);
13836
+ if (!$(/^(\))/, state)) {
13837
+ return null;
13838
+ }
13839
+ return {
13840
+ type: "Point",
13841
+ coordinates: c[0]
13842
+ };
13843
+ }
13844
+ function parseMultiPoint(state) {
13845
+ if (!$(/^(MULTIPOINT)/i, state)) {
13846
+ return null;
13847
+ }
13848
+ white(state);
13849
+ const newCoordsFormat = state._?.substring(state._?.indexOf("(") + 1, state._.length - 1).replace(/\(/g, "").replace(/\)/g, "");
13850
+ state._ = "MULTIPOINT (" + newCoordsFormat + ")";
13851
+ const c = multicoords(state);
13852
+ if (!c) {
13853
+ return null;
13854
+ }
13855
+ white(state);
13856
+ return {
13857
+ type: "MultiPoint",
13858
+ coordinates: c
13859
+ };
13860
+ }
13861
+ function parseLineString(state) {
13862
+ if (!$(/^(LINESTRING(\sz)?)/i, state)) {
13863
+ return null;
13864
+ }
13865
+ white(state);
13866
+ if (!$(/^(\()/, state)) {
13867
+ return null;
13868
+ }
13869
+ const c = coords(state);
13870
+ if (!c) {
13871
+ return null;
13872
+ }
13873
+ if (!$(/^(\))/, state)) {
13874
+ return null;
13875
+ }
13876
+ return {
13877
+ type: "LineString",
13878
+ coordinates: c
13879
+ };
13880
+ }
13881
+ function parseMultiLineString(state) {
13882
+ if (!$(/^(MULTILINESTRING)/i, state))
13883
+ return null;
13884
+ white(state);
13885
+ const c = multicoords(state);
13886
+ if (!c) {
13887
+ return null;
13888
+ }
13889
+ white(state);
13890
+ return {
13891
+ // @ts-ignore
13892
+ type: "MultiLineString",
13893
+ // @ts-expect-error
13894
+ coordinates: c
13895
+ };
13896
+ }
13897
+ function parsePolygon(state) {
13898
+ if (!$(/^(POLYGON(\sz)?)/i, state)) {
13899
+ return null;
13900
+ }
13901
+ white(state);
13902
+ const c = multicoords(state);
13903
+ if (!c) {
13904
+ return null;
13905
+ }
13906
+ return {
13907
+ // @ts-ignore
13908
+ type: "Polygon",
13909
+ // @ts-expect-error
13910
+ coordinates: c
13911
+ };
13912
+ }
13913
+ function parseMultiPolygon(state) {
13914
+ if (!$(/^(MULTIPOLYGON)/i, state)) {
13915
+ return null;
13916
+ }
13917
+ white(state);
13918
+ const c = multicoords(state);
13919
+ if (!c) {
13920
+ return null;
13921
+ }
13922
+ return {
13923
+ type: "MultiPolygon",
13924
+ // @ts-expect-error
13925
+ coordinates: c
13926
+ };
13927
+ }
13928
+ function parseGeometryCollection(state) {
13929
+ const geometries = [];
13930
+ let geometry;
13931
+ if (!$(/^(GEOMETRYCOLLECTION)/i, state)) {
13932
+ return null;
13933
+ }
13934
+ white(state);
13935
+ if (!$(/^(\()/, state)) {
13936
+ return null;
13937
+ }
13938
+ while (geometry = parseGeometry(state)) {
13939
+ geometries.push(geometry);
13940
+ white(state);
13941
+ $(/^(,)/, state);
13942
+ white(state);
13943
+ }
13944
+ if (!$(/^(\))/, state)) {
13945
+ return null;
13946
+ }
13947
+ return {
13948
+ type: "GeometryCollection",
13949
+ geometries
13950
+ };
13951
+ }
13952
+ function multicoords(state) {
13953
+ white(state);
13954
+ let depth = 0;
13955
+ const rings = [];
13956
+ const stack = [rings];
13957
+ let pointer = rings;
13958
+ let elem;
13959
+ while (elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state)) {
13960
+ if (elem === "(") {
13961
+ stack.push(pointer);
13962
+ pointer = [];
13963
+ stack[stack.length - 1].push(pointer);
13964
+ depth++;
13965
+ } else if (elem === ")") {
13966
+ if (pointer.length === 0)
13967
+ return null;
13968
+ pointer = stack.pop();
13969
+ if (!pointer)
13970
+ return null;
13971
+ depth--;
13972
+ if (depth === 0)
13973
+ break;
13974
+ } else if (elem === ",") {
13975
+ pointer = [];
13976
+ stack[stack.length - 1].push(pointer);
13977
+ } else if (!elem.split(/\s/g).some(isNaN)) {
13978
+ Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
13979
+ } else {
13980
+ return null;
13981
+ }
13982
+ white(state);
13983
+ }
13984
+ if (depth !== 0)
13985
+ return null;
13986
+ return rings;
13987
+ }
13988
+ function coords(state) {
13989
+ const list = [];
13990
+ let item;
13991
+ let pt;
13992
+ while (pt = $(tuples, state) || $(/^(,)/, state)) {
13993
+ if (pt === ",") {
13994
+ list.push(item);
13995
+ item = [];
13996
+ } else if (!pt.split(/\s/g).some(isNaN)) {
13997
+ if (!item)
13998
+ item = [];
13999
+ Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
14000
+ }
14001
+ white(state);
14002
+ }
14003
+ if (item)
14004
+ list.push(item);
14005
+ else
14006
+ return null;
14007
+ return list.length ? list : null;
14298
14008
  }
14299
- function parseWKTToGeometry(input, options) {
14300
- const parts = input.split(";");
14301
- let _ = parts.pop();
14302
- const srid = (parts.shift() || "").split("=").pop();
14303
- const state = { parts, _, i: 0 };
14304
- const geometry = parseGeometry(state);
14305
- return options?.wkt?.crs ? addCRS(geometry, srid) : geometry;
14009
+ function $(regexp, state) {
14010
+ const match = state._?.substring(state.i).match(regexp);
14011
+ if (!match)
14012
+ return null;
14013
+ else {
14014
+ state.i += match[0].length;
14015
+ return match[0];
14016
+ }
14306
14017
  }
14307
- function parseGeometry(state) {
14308
- return parsePoint(state) || parseLineString(state) || parsePolygon(state) || parseMultiPoint(state) || parseMultiLineString(state) || parseMultiPolygon(state) || parseGeometryCollection(state);
14018
+ function white(state) {
14019
+ $(/^\s*/, state);
14309
14020
  }
14310
- function addCRS(obj, srid) {
14311
- if (obj && srid?.match(/\d+/)) {
14312
- const crs = {
14313
- type: "name",
14314
- properties: {
14315
- name: "urn:ogc:def:crs:EPSG::" + srid
14316
- }
14317
- };
14318
- obj.crs = crs;
14021
+
14022
+ // ../wkt/src/wkt-loader.ts
14023
+ var WKTWorkerLoader = {
14024
+ dataType: null,
14025
+ batchType: null,
14026
+ name: "WKT (Well-Known Text)",
14027
+ id: "wkt",
14028
+ module: "wkt",
14029
+ version: VERSION2,
14030
+ worker: true,
14031
+ extensions: ["wkt"],
14032
+ mimeTypes: ["text/plain"],
14033
+ category: "geometry",
14034
+ text: true,
14035
+ tests: WKT_MAGIC_STRINGS,
14036
+ testText: isWKT,
14037
+ options: {
14038
+ wkt: {
14039
+ shape: "geojson-geometry",
14040
+ crs: true
14041
+ }
14319
14042
  }
14320
- return obj;
14043
+ };
14044
+ var WKTLoader = {
14045
+ ...WKTWorkerLoader,
14046
+ parse: async (arrayBuffer, options) => parseWKT(new TextDecoder().decode(arrayBuffer), options),
14047
+ parseTextSync: (string, options) => parseWKT(string, options)
14048
+ };
14049
+
14050
+ // ../wkt/src/lib/parse-wkb-header.ts
14051
+ var EWKB_FLAG_Z = 2147483648;
14052
+ var EWKB_FLAG_M = 1073741824;
14053
+ var EWKB_FLAG_SRID = 536870912;
14054
+ var MAX_SRID = 1e4;
14055
+ function isWKB(arrayBuffer) {
14056
+ const dataView = new DataView(arrayBuffer);
14057
+ let byteOffset = 0;
14058
+ const endianness = dataView.getUint8(byteOffset);
14059
+ byteOffset += 1;
14060
+ if (endianness > 1) {
14061
+ return false;
14062
+ }
14063
+ const littleEndian = endianness === 1;
14064
+ const geometry = dataView.getUint32(byteOffset, littleEndian);
14065
+ byteOffset += 4;
14066
+ const geometryType = geometry & 7;
14067
+ if (geometryType === 0 || geometryType > 7) {
14068
+ return false;
14069
+ }
14070
+ const geometryFlags = geometry - geometryType;
14071
+ if (geometryFlags === 0 || geometryFlags === 1e3 || geometryFlags === 2e3 || geometryFlags === 3e3) {
14072
+ return true;
14073
+ }
14074
+ if ((geometryFlags & ~(EWKB_FLAG_Z | EWKB_FLAG_M | EWKB_FLAG_SRID)) !== 0) {
14075
+ return false;
14076
+ }
14077
+ if (geometryFlags & EWKB_FLAG_SRID) {
14078
+ const srid = dataView.getUint32(byteOffset, littleEndian);
14079
+ byteOffset += 4;
14080
+ if (srid > MAX_SRID) {
14081
+ return false;
14082
+ }
14083
+ }
14084
+ return true;
14321
14085
  }
14322
- function parsePoint(state) {
14323
- if (!$(/^(POINT(\sz)?)/i, state)) {
14324
- return null;
14086
+ function parseWKBHeader(dataView, target) {
14087
+ const wkbHeader = Object.assign(target || {}, {
14088
+ type: "wkb",
14089
+ geometryType: 1,
14090
+ dimensions: 2,
14091
+ coordinates: "xy",
14092
+ littleEndian: true,
14093
+ byteOffset: 0
14094
+ });
14095
+ wkbHeader.littleEndian = dataView.getUint8(wkbHeader.byteOffset) === 1;
14096
+ wkbHeader.byteOffset++;
14097
+ const geometryCode = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
14098
+ wkbHeader.byteOffset += 4;
14099
+ wkbHeader.geometryType = geometryCode & 7;
14100
+ const isoType = (geometryCode - wkbHeader.geometryType) / 1e3;
14101
+ switch (isoType) {
14102
+ case 0:
14103
+ break;
14104
+ case 1:
14105
+ wkbHeader.type = "iso-wkb";
14106
+ wkbHeader.dimensions = 3;
14107
+ wkbHeader.coordinates = "xyz";
14108
+ break;
14109
+ case 2:
14110
+ wkbHeader.type = "iso-wkb";
14111
+ wkbHeader.dimensions = 3;
14112
+ wkbHeader.coordinates = "xym";
14113
+ break;
14114
+ case 3:
14115
+ wkbHeader.type = "iso-wkb";
14116
+ wkbHeader.dimensions = 4;
14117
+ wkbHeader.coordinates = "xyzm";
14118
+ break;
14119
+ default:
14120
+ throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`);
14325
14121
  }
14326
- white(state);
14327
- if (!$(/^(\()/, state)) {
14328
- return null;
14122
+ const ewkbZ = geometryCode & EWKB_FLAG_Z;
14123
+ const ewkbM = geometryCode & EWKB_FLAG_M;
14124
+ const ewkbSRID = geometryCode & EWKB_FLAG_SRID;
14125
+ if (ewkbZ && ewkbM) {
14126
+ wkbHeader.type = "ewkb";
14127
+ wkbHeader.dimensions = 4;
14128
+ wkbHeader.coordinates = "xyzm";
14129
+ } else if (ewkbZ) {
14130
+ wkbHeader.type = "ewkb";
14131
+ wkbHeader.dimensions = 3;
14132
+ wkbHeader.coordinates = "xyz";
14133
+ } else if (ewkbM) {
14134
+ wkbHeader.type = "ewkb";
14135
+ wkbHeader.dimensions = 3;
14136
+ wkbHeader.coordinates = "xym";
14329
14137
  }
14330
- const c = coords(state);
14331
- if (!c) {
14332
- return null;
14138
+ if (ewkbSRID) {
14139
+ wkbHeader.type = "ewkb";
14140
+ wkbHeader.srid = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
14141
+ wkbHeader.byteOffset += 4;
14333
14142
  }
14334
- white(state);
14335
- if (!$(/^(\))/, state)) {
14336
- return null;
14143
+ return wkbHeader;
14144
+ }
14145
+
14146
+ // ../wkt/src/lib/parse-wkb.ts
14147
+ function parseWKB(arrayBuffer, options) {
14148
+ const binaryGeometry = parseWKBToBinary(arrayBuffer, options);
14149
+ const shape = options?.wkb?.shape || "binary-geometry";
14150
+ switch (shape) {
14151
+ case "binary-geometry":
14152
+ return binaryGeometry;
14153
+ case "geojson-geometry":
14154
+ return binaryToGeometry(binaryGeometry);
14155
+ case "geometry":
14156
+ console.error('WKBLoader: "geometry" shape is deprecated, use "binary-geometry" instead');
14157
+ return binaryToGeometry(binaryGeometry);
14158
+ default:
14159
+ throw new Error(shape);
14337
14160
  }
14338
- return {
14339
- type: "Point",
14340
- coordinates: c[0]
14341
- };
14342
14161
  }
14343
- function parseMultiPoint(state) {
14344
- if (!$(/^(MULTIPOINT)/i, state)) {
14345
- return null;
14162
+ function parseWKBToBinary(arrayBuffer, options) {
14163
+ const dataView = new DataView(arrayBuffer);
14164
+ const wkbHeader = parseWKBHeader(dataView);
14165
+ const { geometryType, dimensions, littleEndian } = wkbHeader;
14166
+ const offset = wkbHeader.byteOffset;
14167
+ switch (geometryType) {
14168
+ case 1 /* Point */:
14169
+ const point = parsePoint2(dataView, offset, dimensions, littleEndian);
14170
+ return point.geometry;
14171
+ case 2 /* LineString */:
14172
+ const line = parseLineString2(dataView, offset, dimensions, littleEndian);
14173
+ return line.geometry;
14174
+ case 3 /* Polygon */:
14175
+ const polygon = parsePolygon2(dataView, offset, dimensions, littleEndian);
14176
+ return polygon.geometry;
14177
+ case 4 /* MultiPoint */:
14178
+ const multiPoint = parseMultiPoint2(dataView, offset, dimensions, littleEndian);
14179
+ multiPoint.type = "Point";
14180
+ return multiPoint;
14181
+ case 5 /* MultiLineString */:
14182
+ const multiLine = parseMultiLineString2(dataView, offset, dimensions, littleEndian);
14183
+ multiLine.type = "LineString";
14184
+ return multiLine;
14185
+ case 6 /* MultiPolygon */:
14186
+ const multiPolygon = parseMultiPolygon2(dataView, offset, dimensions, littleEndian);
14187
+ multiPolygon.type = "Polygon";
14188
+ return multiPolygon;
14189
+ default:
14190
+ throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
14346
14191
  }
14347
- white(state);
14348
- const newCoordsFormat = state._?.substring(state._?.indexOf("(") + 1, state._.length - 1).replace(/\(/g, "").replace(/\)/g, "");
14349
- state._ = "MULTIPOINT (" + newCoordsFormat + ")";
14350
- const c = multicoords(state);
14351
- if (!c) {
14352
- return null;
14192
+ }
14193
+ function parsePoint2(dataView, offset, dimension, littleEndian) {
14194
+ const positions = new Float64Array(dimension);
14195
+ for (let i = 0; i < dimension; i++) {
14196
+ positions[i] = dataView.getFloat64(offset, littleEndian);
14197
+ offset += 8;
14353
14198
  }
14354
- white(state);
14355
14199
  return {
14356
- type: "MultiPoint",
14357
- coordinates: c
14200
+ geometry: { type: "Point", positions: { value: positions, size: dimension } },
14201
+ offset
14358
14202
  };
14359
14203
  }
14360
- function parseLineString(state) {
14361
- if (!$(/^(LINESTRING(\sz)?)/i, state)) {
14362
- return null;
14363
- }
14364
- white(state);
14365
- if (!$(/^(\()/, state)) {
14366
- return null;
14367
- }
14368
- const c = coords(state);
14369
- if (!c) {
14370
- return null;
14204
+ function parseLineString2(dataView, offset, dimension, littleEndian) {
14205
+ const nPoints = dataView.getUint32(offset, littleEndian);
14206
+ offset += 4;
14207
+ const positions = new Float64Array(nPoints * dimension);
14208
+ for (let i = 0; i < nPoints * dimension; i++) {
14209
+ positions[i] = dataView.getFloat64(offset, littleEndian);
14210
+ offset += 8;
14371
14211
  }
14372
- if (!$(/^(\))/, state)) {
14373
- return null;
14212
+ const pathIndices = [0];
14213
+ if (nPoints > 0) {
14214
+ pathIndices.push(nPoints);
14374
14215
  }
14375
14216
  return {
14376
- type: "LineString",
14377
- coordinates: c
14217
+ geometry: {
14218
+ type: "LineString",
14219
+ positions: { value: positions, size: dimension },
14220
+ pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
14221
+ },
14222
+ offset
14378
14223
  };
14379
14224
  }
14380
- function parseMultiLineString(state) {
14381
- if (!$(/^(MULTILINESTRING)/i, state))
14382
- return null;
14383
- white(state);
14384
- const c = multicoords(state);
14385
- if (!c) {
14386
- return null;
14225
+ var cumulativeSum = (sum) => (value) => sum += value;
14226
+ function parsePolygon2(dataView, offset, dimension, littleEndian) {
14227
+ const nRings = dataView.getUint32(offset, littleEndian);
14228
+ offset += 4;
14229
+ const rings = [];
14230
+ for (let i = 0; i < nRings; i++) {
14231
+ const parsed = parseLineString2(dataView, offset, dimension, littleEndian);
14232
+ const { positions } = parsed.geometry;
14233
+ offset = parsed.offset;
14234
+ rings.push(positions.value);
14387
14235
  }
14388
- white(state);
14236
+ const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer);
14237
+ const polygonIndices = [0];
14238
+ if (concatenatedPositions.length > 0) {
14239
+ polygonIndices.push(concatenatedPositions.length / dimension);
14240
+ }
14241
+ const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum(0));
14242
+ primitivePolygonIndices.unshift(0);
14389
14243
  return {
14390
- // @ts-ignore
14391
- type: "MultiLineString",
14392
- // @ts-expect-error
14393
- coordinates: c
14244
+ geometry: {
14245
+ type: "Polygon",
14246
+ positions: { value: concatenatedPositions, size: dimension },
14247
+ polygonIndices: {
14248
+ value: new Uint32Array(polygonIndices),
14249
+ size: 1
14250
+ },
14251
+ primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
14252
+ },
14253
+ offset
14394
14254
  };
14395
14255
  }
14396
- function parsePolygon(state) {
14397
- if (!$(/^(POLYGON(\sz)?)/i, state)) {
14398
- return null;
14256
+ function parseMultiPoint2(dataView, offset, dimension, littleEndian) {
14257
+ const nPoints = dataView.getUint32(offset, littleEndian);
14258
+ offset += 4;
14259
+ const binaryPointGeometries = [];
14260
+ for (let i = 0; i < nPoints; i++) {
14261
+ const littleEndianPoint = dataView.getUint8(offset) === 1;
14262
+ offset++;
14263
+ if (dataView.getUint32(offset, littleEndianPoint) % 1e3 !== 1) {
14264
+ throw new Error("WKB: Inner geometries of MultiPoint not of type Point");
14265
+ }
14266
+ offset += 4;
14267
+ const parsed = parsePoint2(dataView, offset, dimension, littleEndianPoint);
14268
+ offset = parsed.offset;
14269
+ binaryPointGeometries.push(parsed.geometry);
14399
14270
  }
14400
- white(state);
14401
- const c = multicoords(state);
14402
- if (!c) {
14403
- return null;
14271
+ return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
14272
+ }
14273
+ function parseMultiLineString2(dataView, offset, dimension, littleEndian) {
14274
+ const nLines = dataView.getUint32(offset, littleEndian);
14275
+ offset += 4;
14276
+ const binaryLineGeometries = [];
14277
+ for (let i = 0; i < nLines; i++) {
14278
+ const littleEndianLine = dataView.getUint8(offset) === 1;
14279
+ offset++;
14280
+ if (dataView.getUint32(offset, littleEndianLine) % 1e3 !== 2) {
14281
+ throw new Error("WKB: Inner geometries of MultiLineString not of type LineString");
14282
+ }
14283
+ offset += 4;
14284
+ const parsed = parseLineString2(dataView, offset, dimension, littleEndianLine);
14285
+ offset = parsed.offset;
14286
+ binaryLineGeometries.push(parsed.geometry);
14287
+ }
14288
+ return concatenateBinaryLineGeometries(binaryLineGeometries, dimension);
14289
+ }
14290
+ function parseMultiPolygon2(dataView, offset, dimension, littleEndian) {
14291
+ const nPolygons = dataView.getUint32(offset, littleEndian);
14292
+ offset += 4;
14293
+ const binaryPolygonGeometries = [];
14294
+ for (let i = 0; i < nPolygons; i++) {
14295
+ const littleEndianPolygon = dataView.getUint8(offset) === 1;
14296
+ offset++;
14297
+ if (dataView.getUint32(offset, littleEndianPolygon) % 1e3 !== 3) {
14298
+ throw new Error("WKB: Inner geometries of MultiPolygon not of type Polygon");
14299
+ }
14300
+ offset += 4;
14301
+ const parsed = parsePolygon2(dataView, offset, dimension, littleEndianPolygon);
14302
+ offset = parsed.offset;
14303
+ binaryPolygonGeometries.push(parsed.geometry);
14404
14304
  }
14305
+ return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension);
14306
+ }
14307
+ function concatenateBinaryPointGeometries(binaryPointGeometries, dimension) {
14308
+ const positions = binaryPointGeometries.map((geometry) => geometry.positions.value);
14309
+ const concatenatedPositions = new Float64Array(concatTypedArrays(positions).buffer);
14405
14310
  return {
14406
- // @ts-ignore
14407
- type: "Polygon",
14408
- // @ts-expect-error
14409
- coordinates: c
14311
+ type: "Point",
14312
+ positions: { value: concatenatedPositions, size: dimension }
14410
14313
  };
14411
14314
  }
14412
- function parseMultiPolygon(state) {
14413
- if (!$(/^(MULTIPOLYGON)/i, state)) {
14414
- return null;
14415
- }
14416
- white(state);
14417
- const c = multicoords(state);
14418
- if (!c) {
14419
- return null;
14420
- }
14315
+ function concatenateBinaryLineGeometries(binaryLineGeometries, dimension) {
14316
+ const lines = binaryLineGeometries.map((geometry) => geometry.positions.value);
14317
+ const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer);
14318
+ const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0));
14319
+ pathIndices.unshift(0);
14421
14320
  return {
14422
- type: "MultiPolygon",
14423
- // @ts-expect-error
14424
- coordinates: c
14321
+ type: "LineString",
14322
+ positions: { value: concatenatedPositions, size: dimension },
14323
+ pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
14425
14324
  };
14426
14325
  }
14427
- function parseGeometryCollection(state) {
14428
- const geometries = [];
14429
- let geometry;
14430
- if (!$(/^(GEOMETRYCOLLECTION)/i, state)) {
14431
- return null;
14432
- }
14433
- white(state);
14434
- if (!$(/^(\()/, state)) {
14435
- return null;
14436
- }
14437
- while (geometry = parseGeometry(state)) {
14438
- geometries.push(geometry);
14439
- white(state);
14440
- $(/^(,)/, state);
14441
- white(state);
14326
+ function concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension) {
14327
+ const polygons = [];
14328
+ const primitivePolygons = [];
14329
+ for (const binaryPolygon of binaryPolygonGeometries) {
14330
+ const { positions, primitivePolygonIndices: primitivePolygonIndices2 } = binaryPolygon;
14331
+ polygons.push(positions.value);
14332
+ primitivePolygons.push(primitivePolygonIndices2.value);
14442
14333
  }
14443
- if (!$(/^(\))/, state)) {
14444
- return null;
14334
+ const concatenatedPositions = new Float64Array(concatTypedArrays(polygons).buffer);
14335
+ const polygonIndices = polygons.map((p) => p.length / dimension).map(cumulativeSum(0));
14336
+ polygonIndices.unshift(0);
14337
+ const primitivePolygonIndices = [0];
14338
+ for (const primitivePolygon of primitivePolygons) {
14339
+ primitivePolygonIndices.push(
14340
+ ...primitivePolygon.filter((x) => x > 0).map((x) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])
14341
+ );
14445
14342
  }
14446
14343
  return {
14447
- type: "GeometryCollection",
14448
- geometries
14344
+ type: "Polygon",
14345
+ positions: { value: concatenatedPositions, size: dimension },
14346
+ polygonIndices: { value: new Uint32Array(polygonIndices), size: 1 },
14347
+ primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
14449
14348
  };
14450
14349
  }
14451
- function multicoords(state) {
14452
- white(state);
14453
- let depth = 0;
14454
- const rings = [];
14455
- const stack = [rings];
14456
- let pointer = rings;
14457
- let elem;
14458
- while (elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state)) {
14459
- if (elem === "(") {
14460
- stack.push(pointer);
14461
- pointer = [];
14462
- stack[stack.length - 1].push(pointer);
14463
- depth++;
14464
- } else if (elem === ")") {
14465
- if (pointer.length === 0)
14466
- return null;
14467
- pointer = stack.pop();
14468
- if (!pointer)
14469
- return null;
14470
- depth--;
14471
- if (depth === 0)
14472
- break;
14473
- } else if (elem === ",") {
14474
- pointer = [];
14475
- stack[stack.length - 1].push(pointer);
14476
- } else if (!elem.split(/\s/g).some(isNaN)) {
14477
- Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
14478
- } else {
14479
- return null;
14480
- }
14481
- white(state);
14350
+ function concatTypedArrays(arrays) {
14351
+ let byteLength = 0;
14352
+ for (let i = 0; i < arrays.length; ++i) {
14353
+ byteLength += arrays[i].byteLength;
14482
14354
  }
14483
- if (depth !== 0)
14484
- return null;
14485
- return rings;
14486
- }
14487
- function coords(state) {
14488
- const list = [];
14489
- let item;
14490
- let pt;
14491
- while (pt = $(tuples, state) || $(/^(,)/, state)) {
14492
- if (pt === ",") {
14493
- list.push(item);
14494
- item = [];
14495
- } else if (!pt.split(/\s/g).some(isNaN)) {
14496
- if (!item)
14497
- item = [];
14498
- Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
14355
+ const buffer = new Uint8Array(byteLength);
14356
+ let byteOffset = 0;
14357
+ for (let i = 0; i < arrays.length; ++i) {
14358
+ const data = new Uint8Array(arrays[i].buffer);
14359
+ byteLength = data.length;
14360
+ for (let j = 0; j < byteLength; ++j) {
14361
+ buffer[byteOffset++] = data[j];
14499
14362
  }
14500
- white(state);
14501
- }
14502
- if (item)
14503
- list.push(item);
14504
- else
14505
- return null;
14506
- return list.length ? list : null;
14507
- }
14508
- function $(regexp, state) {
14509
- const match = state._?.substring(state.i).match(regexp);
14510
- if (!match)
14511
- return null;
14512
- else {
14513
- state.i += match[0].length;
14514
- return match[0];
14515
14363
  }
14516
- }
14517
- function white(state) {
14518
- $(/^\s*/, state);
14364
+ return buffer;
14519
14365
  }
14520
14366
 
14521
- // ../wkt/src/wkt-loader.ts
14522
- var WKTWorkerLoader = {
14367
+ // ../wkt/src/wkb-loader.ts
14368
+ var WKBWorkerLoader = {
14523
14369
  dataType: null,
14524
14370
  batchType: null,
14525
- name: "WKT (Well-Known Text)",
14526
- id: "wkt",
14371
+ name: "WKB",
14372
+ id: "wkb",
14527
14373
  module: "wkt",
14528
- version: VERSION3,
14374
+ version: VERSION2,
14529
14375
  worker: true,
14530
- extensions: ["wkt"],
14531
- mimeTypes: ["text/plain"],
14532
14376
  category: "geometry",
14533
- text: true,
14534
- tests: WKT_MAGIC_STRINGS,
14535
- testText: isWKT,
14377
+ extensions: ["wkb"],
14378
+ mimeTypes: [],
14379
+ // TODO can we define static, serializable tests, eg. some binary strings?
14380
+ tests: [isWKB],
14536
14381
  options: {
14537
- wkt: {
14538
- shape: "geojson-geometry",
14539
- crs: true
14382
+ wkb: {
14383
+ shape: "binary-geometry"
14384
+ // 'geojson-geometry'
14540
14385
  }
14541
14386
  }
14542
14387
  };
14543
- var WKTLoader = {
14544
- ...WKTWorkerLoader,
14545
- parse: async (arrayBuffer, options) => parseWKT(new TextDecoder().decode(arrayBuffer), options),
14546
- parseTextSync: (string, options) => parseWKT(string, options)
14388
+ var WKBLoader = {
14389
+ ...WKBWorkerLoader,
14390
+ parse: async (arrayBuffer) => parseWKB(arrayBuffer),
14391
+ parseSync: parseWKB
14547
14392
  };
14548
14393
 
14549
- // ../wkt/src/lib/parse-wkb-header.ts
14550
- var EWKB_FLAG_Z = 2147483648;
14551
- var EWKB_FLAG_M = 1073741824;
14552
- var EWKB_FLAG_SRID = 536870912;
14553
- var MAX_SRID = 1e4;
14554
- function isWKB(arrayBuffer) {
14555
- const dataView = new DataView(arrayBuffer);
14556
- let byteOffset = 0;
14557
- const endianness = dataView.getUint8(byteOffset);
14558
- byteOffset += 1;
14559
- if (endianness > 1) {
14560
- return false;
14561
- }
14562
- const littleEndian = endianness === 1;
14563
- const geometry = dataView.getUint32(byteOffset, littleEndian);
14564
- byteOffset += 4;
14565
- const geometryType = geometry & 7;
14566
- if (geometryType === 0 || geometryType > 7) {
14567
- return false;
14394
+ // src/lib/geoarrow/convert-geoarrow-to-geojson-geometry.ts
14395
+ function parseGeometryFromArrow(arrowCellValue, encoding) {
14396
+ encoding = encoding?.toLowerCase();
14397
+ if (!encoding || !arrowCellValue) {
14398
+ return null;
14568
14399
  }
14569
- const geometryFlags = geometry - geometryType;
14570
- if (geometryFlags === 0 || geometryFlags === 1e3 || geometryFlags === 2e3 || geometryFlags === 3e3) {
14571
- return true;
14400
+ let geometry;
14401
+ switch (encoding) {
14402
+ case "geoarrow.multipolygon":
14403
+ geometry = arrowMultiPolygonToFeature(arrowCellValue);
14404
+ break;
14405
+ case "geoarrow.polygon":
14406
+ geometry = arrowPolygonToFeature(arrowCellValue);
14407
+ break;
14408
+ case "geoarrow.multipoint":
14409
+ geometry = arrowMultiPointToFeature(arrowCellValue);
14410
+ break;
14411
+ case "geoarrow.point":
14412
+ geometry = arrowPointToFeature(arrowCellValue);
14413
+ break;
14414
+ case "geoarrow.multilinestring":
14415
+ geometry = arrowMultiLineStringToFeature(arrowCellValue);
14416
+ break;
14417
+ case "geoarrow.linestring":
14418
+ geometry = arrowLineStringToFeature(arrowCellValue);
14419
+ break;
14420
+ case "geoarrow.wkb":
14421
+ geometry = arrowWKBToFeature(arrowCellValue);
14422
+ break;
14423
+ case "geoarrow.wkt":
14424
+ geometry = arrowWKTToFeature(arrowCellValue);
14425
+ break;
14426
+ default: {
14427
+ throw Error(`GeoArrow encoding not supported ${encoding}`);
14428
+ }
14572
14429
  }
14573
- if ((geometryFlags & ~(EWKB_FLAG_Z | EWKB_FLAG_M | EWKB_FLAG_SRID)) !== 0) {
14574
- return false;
14430
+ return geometry;
14431
+ }
14432
+ function arrowWKBToFeature(arrowCellValue) {
14433
+ const arrayBuffer = arrowCellValue.buffer.slice(
14434
+ arrowCellValue.byteOffset,
14435
+ arrowCellValue.byteOffset + arrowCellValue.byteLength
14436
+ );
14437
+ const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer);
14438
+ const geometry = binaryToGeometry(binaryGeometry);
14439
+ return geometry;
14440
+ }
14441
+ function arrowWKTToFeature(arrowCellValue) {
14442
+ const string = arrowCellValue;
14443
+ return WKTLoader.parseTextSync?.(string);
14444
+ }
14445
+ function arrowMultiPolygonToFeature(arrowMultiPolygon) {
14446
+ const multiPolygon = [];
14447
+ for (let m = 0; m < arrowMultiPolygon.length; m++) {
14448
+ const arrowPolygon = arrowMultiPolygon.get(m);
14449
+ const polygon = [];
14450
+ for (let i = 0; arrowPolygon && i < arrowPolygon?.length; i++) {
14451
+ const arrowRing = arrowPolygon?.get(i);
14452
+ const ring = [];
14453
+ for (let j = 0; arrowRing && j < arrowRing.length; j++) {
14454
+ const arrowCoord = arrowRing.get(j);
14455
+ const coord = Array.from(arrowCoord);
14456
+ ring.push(coord);
14457
+ }
14458
+ polygon.push(ring);
14459
+ }
14460
+ multiPolygon.push(polygon);
14575
14461
  }
14576
- if (geometryFlags & EWKB_FLAG_SRID) {
14577
- const srid = dataView.getUint32(byteOffset, littleEndian);
14578
- byteOffset += 4;
14579
- if (srid > MAX_SRID) {
14580
- return false;
14462
+ const geometry = {
14463
+ type: "MultiPolygon",
14464
+ coordinates: multiPolygon
14465
+ };
14466
+ return geometry;
14467
+ }
14468
+ function arrowPolygonToFeature(arrowPolygon) {
14469
+ const polygon = [];
14470
+ for (let i = 0; arrowPolygon && i < arrowPolygon.length; i++) {
14471
+ const arrowRing = arrowPolygon.get(i);
14472
+ const ring = [];
14473
+ for (let j = 0; arrowRing && j < arrowRing.length; j++) {
14474
+ const arrowCoord = arrowRing.get(j);
14475
+ const coords2 = Array.from(arrowCoord);
14476
+ ring.push(coords2);
14581
14477
  }
14478
+ polygon.push(ring);
14582
14479
  }
14583
- return true;
14480
+ const geometry = {
14481
+ type: "Polygon",
14482
+ coordinates: polygon
14483
+ };
14484
+ return geometry;
14584
14485
  }
14585
- function parseWKBHeader(dataView, target) {
14586
- const wkbHeader = Object.assign(target || {}, {
14587
- type: "wkb",
14588
- geometryType: 1,
14589
- dimensions: 2,
14590
- coordinates: "xy",
14591
- littleEndian: true,
14592
- byteOffset: 0
14593
- });
14594
- wkbHeader.littleEndian = dataView.getUint8(wkbHeader.byteOffset) === 1;
14595
- wkbHeader.byteOffset++;
14596
- const geometryCode = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
14597
- wkbHeader.byteOffset += 4;
14598
- wkbHeader.geometryType = geometryCode & 7;
14599
- const isoType = (geometryCode - wkbHeader.geometryType) / 1e3;
14600
- switch (isoType) {
14601
- case 0:
14602
- break;
14603
- case 1:
14604
- wkbHeader.type = "iso-wkb";
14605
- wkbHeader.dimensions = 3;
14606
- wkbHeader.coordinates = "xyz";
14607
- break;
14608
- case 2:
14609
- wkbHeader.type = "iso-wkb";
14610
- wkbHeader.dimensions = 3;
14611
- wkbHeader.coordinates = "xym";
14612
- break;
14613
- case 3:
14614
- wkbHeader.type = "iso-wkb";
14615
- wkbHeader.dimensions = 4;
14616
- wkbHeader.coordinates = "xyzm";
14617
- break;
14618
- default:
14619
- throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`);
14486
+ function arrowMultiPointToFeature(arrowMultiPoint) {
14487
+ const multiPoint = [];
14488
+ for (let i = 0; arrowMultiPoint && i < arrowMultiPoint.length; i++) {
14489
+ const arrowPoint = arrowMultiPoint.get(i);
14490
+ if (arrowPoint) {
14491
+ const coord = Array.from(arrowPoint);
14492
+ multiPoint.push(coord);
14493
+ }
14620
14494
  }
14621
- const ewkbZ = geometryCode & EWKB_FLAG_Z;
14622
- const ewkbM = geometryCode & EWKB_FLAG_M;
14623
- const ewkbSRID = geometryCode & EWKB_FLAG_SRID;
14624
- if (ewkbZ && ewkbM) {
14625
- wkbHeader.type = "ewkb";
14626
- wkbHeader.dimensions = 4;
14627
- wkbHeader.coordinates = "xyzm";
14628
- } else if (ewkbZ) {
14629
- wkbHeader.type = "ewkb";
14630
- wkbHeader.dimensions = 3;
14631
- wkbHeader.coordinates = "xyz";
14632
- } else if (ewkbM) {
14633
- wkbHeader.type = "ewkb";
14634
- wkbHeader.dimensions = 3;
14635
- wkbHeader.coordinates = "xym";
14495
+ return {
14496
+ type: "MultiPoint",
14497
+ coordinates: multiPoint
14498
+ };
14499
+ }
14500
+ function arrowPointToFeature(arrowPoint) {
14501
+ const point = Array.from(arrowPoint);
14502
+ return {
14503
+ type: "Point",
14504
+ coordinates: point
14505
+ };
14506
+ }
14507
+ function arrowMultiLineStringToFeature(arrowMultiLineString) {
14508
+ const multiLineString = [];
14509
+ for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
14510
+ const arrowLineString = arrowMultiLineString.get(i);
14511
+ const lineString = [];
14512
+ for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
14513
+ const arrowCoord = arrowLineString.get(j);
14514
+ if (arrowCoord) {
14515
+ const coords2 = Array.from(arrowCoord);
14516
+ lineString.push(coords2);
14517
+ }
14518
+ }
14519
+ multiLineString.push(lineString);
14636
14520
  }
14637
- if (ewkbSRID) {
14638
- wkbHeader.type = "ewkb";
14639
- wkbHeader.srid = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
14640
- wkbHeader.byteOffset += 4;
14521
+ return {
14522
+ type: "MultiLineString",
14523
+ coordinates: multiLineString
14524
+ };
14525
+ }
14526
+ function arrowLineStringToFeature(arrowLineString) {
14527
+ const lineString = [];
14528
+ for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
14529
+ const arrowCoord = arrowLineString.get(i);
14530
+ if (arrowCoord) {
14531
+ const coords2 = Array.from(arrowCoord);
14532
+ lineString.push(coords2);
14533
+ }
14641
14534
  }
14642
- return wkbHeader;
14535
+ return {
14536
+ type: "LineString",
14537
+ coordinates: lineString
14538
+ };
14643
14539
  }
14644
14540
 
14645
- // ../wkt/src/lib/parse-wkb.ts
14646
- function parseWKB(arrayBuffer, options) {
14647
- const binaryGeometry = parseWKBToBinary(arrayBuffer, options);
14648
- const shape = options?.wkb?.shape || "binary-geometry";
14541
+ // src/lib/tables/convert-arrow-to-table.ts
14542
+ function convertArrowToTable(arrowTable, shape) {
14649
14543
  switch (shape) {
14650
- case "binary-geometry":
14651
- return binaryGeometry;
14652
- case "geojson-geometry":
14653
- return binaryToGeometry(binaryGeometry);
14654
- case "geometry":
14655
- console.error('WKBLoader: "geometry" shape is deprecated, use "binary-geometry" instead');
14656
- return binaryToGeometry(binaryGeometry);
14544
+ case "arrow-table":
14545
+ return convertArrowToArrowTable(arrowTable);
14546
+ case "array-row-table":
14547
+ return convertArrowToArrayRowTable(arrowTable);
14548
+ case "object-row-table":
14549
+ return convertArrowToObjectRowTable(arrowTable);
14550
+ case "columnar-table":
14551
+ return convertArrowToColumnarTable(arrowTable);
14552
+ case "geojson-table":
14553
+ return convertArrowToGeoJSONTable(arrowTable);
14657
14554
  default:
14658
14555
  throw new Error(shape);
14659
14556
  }
14660
14557
  }
14661
- function parseWKBToBinary(arrayBuffer, options) {
14662
- const dataView = new DataView(arrayBuffer);
14663
- const wkbHeader = parseWKBHeader(dataView);
14664
- const { geometryType, dimensions, littleEndian } = wkbHeader;
14665
- const offset = wkbHeader.byteOffset;
14666
- switch (geometryType) {
14667
- case 1 /* Point */:
14668
- const point = parsePoint2(dataView, offset, dimensions, littleEndian);
14669
- return point.geometry;
14670
- case 2 /* LineString */:
14671
- const line = parseLineString2(dataView, offset, dimensions, littleEndian);
14672
- return line.geometry;
14673
- case 3 /* Polygon */:
14674
- const polygon = parsePolygon2(dataView, offset, dimensions, littleEndian);
14675
- return polygon.geometry;
14676
- case 4 /* MultiPoint */:
14677
- const multiPoint = parseMultiPoint2(dataView, offset, dimensions, littleEndian);
14678
- multiPoint.type = "Point";
14679
- return multiPoint;
14680
- case 5 /* MultiLineString */:
14681
- const multiLine = parseMultiLineString2(dataView, offset, dimensions, littleEndian);
14682
- multiLine.type = "LineString";
14683
- return multiLine;
14684
- case 6 /* MultiPolygon */:
14685
- const multiPolygon = parseMultiPolygon2(dataView, offset, dimensions, littleEndian);
14686
- multiPolygon.type = "Polygon";
14687
- return multiPolygon;
14688
- default:
14689
- throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
14690
- }
14558
+ function convertArrowToArrowTable(arrowTable) {
14559
+ return {
14560
+ shape: "arrow-table",
14561
+ schema: convertArrowToSchema(arrowTable.schema),
14562
+ data: arrowTable
14563
+ };
14691
14564
  }
14692
- function parsePoint2(dataView, offset, dimension, littleEndian) {
14693
- const positions = new Float64Array(dimension);
14694
- for (let i = 0; i < dimension; i++) {
14695
- positions[i] = dataView.getFloat64(offset, littleEndian);
14696
- offset += 8;
14565
+ function convertArrowToArrayRowTable(arrowTable) {
14566
+ const columnarTable = convertArrowToColumnarTable(arrowTable);
14567
+ return convertTable(columnarTable, "array-row-table");
14568
+ }
14569
+ function convertArrowToObjectRowTable(arrowTable) {
14570
+ const columnarTable = convertArrowToColumnarTable(arrowTable);
14571
+ return convertTable(columnarTable, "object-row-table");
14572
+ }
14573
+ function convertArrowToColumnarTable(arrowTable) {
14574
+ const columns = {};
14575
+ for (const field of arrowTable.schema.fields) {
14576
+ const arrowColumn = arrowTable.getChild(field.name);
14577
+ const values = arrowColumn?.toArray();
14578
+ columns[field.name] = values;
14697
14579
  }
14580
+ const schema = convertArrowToSchema(arrowTable.schema);
14698
14581
  return {
14699
- geometry: { type: "Point", positions: { value: positions, size: dimension } },
14700
- offset
14582
+ shape: "columnar-table",
14583
+ schema,
14584
+ data: columns
14701
14585
  };
14702
14586
  }
14703
- function parseLineString2(dataView, offset, dimension, littleEndian) {
14704
- const nPoints = dataView.getUint32(offset, littleEndian);
14705
- offset += 4;
14706
- const positions = new Float64Array(nPoints * dimension);
14707
- for (let i = 0; i < nPoints * dimension; i++) {
14708
- positions[i] = dataView.getFloat64(offset, littleEndian);
14709
- offset += 8;
14710
- }
14711
- const pathIndices = [0];
14712
- if (nPoints > 0) {
14713
- pathIndices.push(nPoints);
14587
+ function convertArrowToGeoJSONTable(arrowTable) {
14588
+ const schema = convertArrowToSchema(arrowTable.schema);
14589
+ const geometryColumns = getGeometryColumnsFromSchema(schema);
14590
+ const encoding = geometryColumns.geometry.encoding;
14591
+ const features = [];
14592
+ const propertyColumnNames = arrowTable.schema.fields.map((field) => field.name).filter((name) => !(name in geometryColumns));
14593
+ const propertiesTable = arrowTable.select(propertyColumnNames);
14594
+ const arrowGeometryColumn = arrowTable.getChild("geometry");
14595
+ for (let row = 0; row < arrowTable.numRows; row++) {
14596
+ const arrowGeometry = arrowGeometryColumn?.get(row);
14597
+ const feature = parseGeometryFromArrow(arrowGeometry, encoding);
14598
+ if (feature) {
14599
+ const properties = propertiesTable.get(row)?.toJSON() || {};
14600
+ features.push({ type: "Feature", geometry: feature, properties });
14601
+ }
14714
14602
  }
14715
14603
  return {
14716
- geometry: {
14717
- type: "LineString",
14718
- positions: { value: positions, size: dimension },
14719
- pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
14720
- },
14721
- offset
14604
+ shape: "geojson-table",
14605
+ type: "FeatureCollection",
14606
+ schema,
14607
+ features
14722
14608
  };
14723
14609
  }
14724
- var cumulativeSum = (sum) => (value) => sum += value;
14725
- function parsePolygon2(dataView, offset, dimension, littleEndian) {
14726
- const nRings = dataView.getUint32(offset, littleEndian);
14727
- offset += 4;
14728
- const rings = [];
14729
- for (let i = 0; i < nRings; i++) {
14730
- const parsed = parseLineString2(dataView, offset, dimension, littleEndian);
14731
- const { positions } = parsed.geometry;
14732
- offset = parsed.offset;
14733
- rings.push(positions.value);
14610
+
14611
+ // src/lib/parsers/parse-arrow.ts
14612
+ function parseArrowSync(arrayBuffer, options) {
14613
+ const shape = options?.shape || "arrow-table";
14614
+ const arrowTable = tableFromIPC([new Uint8Array(arrayBuffer)]);
14615
+ return convertArrowToTable(arrowTable, shape);
14616
+ }
14617
+ function parseArrowInBatches(asyncIterator, options) {
14618
+ async function* makeArrowAsyncIterator() {
14619
+ const readers = RecordBatchReader.readAll(asyncIterator);
14620
+ for await (const reader of readers) {
14621
+ for await (const recordBatch of reader) {
14622
+ if (options?.arrow?.batchDebounceMs !== void 0 && options?.arrow?.batchDebounceMs > 0) {
14623
+ await new Promise((resolve) => setTimeout(resolve, options.arrow?.batchDebounceMs || 0));
14624
+ }
14625
+ const arrowTabledBatch = {
14626
+ shape: "arrow-table",
14627
+ batchType: "data",
14628
+ data: new Table([recordBatch]),
14629
+ length: recordBatch.data.length
14630
+ };
14631
+ yield arrowTabledBatch;
14632
+ }
14633
+ break;
14634
+ }
14734
14635
  }
14735
- const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer);
14736
- const polygonIndices = [0];
14737
- if (concatenatedPositions.length > 0) {
14738
- polygonIndices.push(concatenatedPositions.length / dimension);
14636
+ return makeArrowAsyncIterator();
14637
+ }
14638
+
14639
+ // src/arrow-loader.ts
14640
+ var ArrowLoader = {
14641
+ ...ArrowWorkerLoader,
14642
+ parse: async (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
14643
+ parseSync: (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
14644
+ parseInBatches: parseArrowInBatches
14645
+ };
14646
+
14647
+ // src/lib/encoders/encode-arrow.ts
14648
+ function encodeArrowSync(data) {
14649
+ const vectors = {};
14650
+ for (const arrayData of data) {
14651
+ const arrayVector = createVector(arrayData.array, arrayData.type);
14652
+ vectors[arrayData.name] = arrayVector;
14739
14653
  }
14740
- const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum(0));
14741
- primitivePolygonIndices.unshift(0);
14742
- return {
14743
- geometry: {
14744
- type: "Polygon",
14745
- positions: { value: concatenatedPositions, size: dimension },
14746
- polygonIndices: {
14747
- value: new Uint32Array(polygonIndices),
14748
- size: 1
14749
- },
14750
- primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
14751
- },
14752
- offset
14753
- };
14654
+ const table = new Table(vectors);
14655
+ const arrowBuffer = tableToIPC(table);
14656
+ return arrowBuffer;
14754
14657
  }
14755
- function parseMultiPoint2(dataView, offset, dimension, littleEndian) {
14756
- const nPoints = dataView.getUint32(offset, littleEndian);
14757
- offset += 4;
14758
- const binaryPointGeometries = [];
14759
- for (let i = 0; i < nPoints; i++) {
14760
- const littleEndianPoint = dataView.getUint8(offset) === 1;
14761
- offset++;
14762
- if (dataView.getUint32(offset, littleEndianPoint) % 1e3 !== 1) {
14763
- throw new Error("WKB: Inner geometries of MultiPoint not of type Point");
14658
+ function createVector(array, type) {
14659
+ switch (type) {
14660
+ case 1 /* DATE */:
14661
+ return vectorFromArray(array);
14662
+ case 0 /* FLOAT */:
14663
+ default:
14664
+ return vectorFromArray(array);
14665
+ }
14666
+ }
14667
+
14668
+ // src/arrow-writer.ts
14669
+ var VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
14670
+ var ArrowWriter = {
14671
+ name: "Apache Arrow",
14672
+ id: "arrow",
14673
+ module: "arrow",
14674
+ version: VERSION3,
14675
+ extensions: ["arrow", "feather"],
14676
+ mimeTypes: [
14677
+ "application/vnd.apache.arrow.file",
14678
+ "application/vnd.apache.arrow.stream",
14679
+ "application/octet-stream"
14680
+ ],
14681
+ binary: true,
14682
+ options: {},
14683
+ encode: async function encodeArrow(data, options) {
14684
+ return encodeArrowSync(data);
14685
+ },
14686
+ encodeSync(data, options) {
14687
+ return encodeArrowSync(data);
14688
+ }
14689
+ };
14690
+
14691
+ // src/exports/geoarrow-loader.ts
14692
+ var GeoArrowWorkerLoader = {
14693
+ ...ArrowWorkerLoader,
14694
+ options: {
14695
+ arrow: {
14696
+ shape: "arrow-table"
14764
14697
  }
14765
- offset += 4;
14766
- const parsed = parsePoint2(dataView, offset, dimension, littleEndianPoint);
14767
- offset = parsed.offset;
14768
- binaryPointGeometries.push(parsed.geometry);
14769
14698
  }
14770
- return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
14699
+ };
14700
+
14701
+ // src/lib/parsers/parse-geoarrow.ts
14702
+ function parseGeoArrowSync(arrayBuffer, options) {
14703
+ const table = parseArrowSync(arrayBuffer, { shape: "arrow-table" });
14704
+ switch (options?.shape) {
14705
+ case "geojson-table":
14706
+ return convertArrowToTable(table.data, "geojson-table");
14707
+ default:
14708
+ return table;
14709
+ }
14710
+ }
14711
+ function parseGeoArrowInBatches(asyncIterator) {
14712
+ return parseArrowInBatches(asyncIterator);
14713
+ }
14714
+
14715
+ // src/geoarrow-loader.ts
14716
+ var GeoArrowLoader = {
14717
+ ...GeoArrowWorkerLoader,
14718
+ parse: async (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
14719
+ parseSync: (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
14720
+ parseInBatches: parseGeoArrowInBatches
14721
+ };
14722
+
14723
+ // src/lib/tables/convert-table-to-arrow.ts
14724
+ function convertTableToArrow(table, options) {
14725
+ switch (table.shape) {
14726
+ case "arrow-table":
14727
+ return table.data;
14728
+ case "columnar-table":
14729
+ default:
14730
+ const arrowBatchIterator = makeTableToArrowBatchesIterator(table, options);
14731
+ return new Table(arrowBatchIterator);
14732
+ }
14771
14733
  }
14772
- function parseMultiLineString2(dataView, offset, dimension, littleEndian) {
14773
- const nLines = dataView.getUint32(offset, littleEndian);
14774
- offset += 4;
14775
- const binaryLineGeometries = [];
14776
- for (let i = 0; i < nLines; i++) {
14777
- const littleEndianLine = dataView.getUint8(offset) === 1;
14778
- offset++;
14779
- if (dataView.getUint32(offset, littleEndianLine) % 1e3 !== 2) {
14780
- throw new Error("WKB: Inner geometries of MultiLineString not of type LineString");
14734
+ function* makeTableToArrowBatchesIterator(table, options) {
14735
+ const arrowSchema = deserializeArrowSchema(table.schema);
14736
+ const length = getTableLength(table);
14737
+ const numColumns = getTableNumCols(table);
14738
+ const batchSize = options?.batchSize || length;
14739
+ const builders = arrowSchema?.fields.map((arrowField) => makeBuilder(arrowField));
14740
+ const structField = new Struct(arrowSchema.fields);
14741
+ let batchLength = 0;
14742
+ for (let rowIndex = 0; rowIndex < length; rowIndex++) {
14743
+ for (let columnIndex = 0; columnIndex < numColumns; ++columnIndex) {
14744
+ const value = getTableCellAt(table, rowIndex, columnIndex);
14745
+ const builder = builders[columnIndex];
14746
+ builder.append(value);
14747
+ batchLength++;
14748
+ if (batchLength >= batchSize) {
14749
+ const datas = builders.map((builder2) => builder2.flush());
14750
+ const structData = new Data(structField, 0, batchLength, 0, void 0, datas);
14751
+ yield new RecordBatch2(arrowSchema, structData);
14752
+ batchLength = 0;
14753
+ }
14781
14754
  }
14782
- offset += 4;
14783
- const parsed = parseLineString2(dataView, offset, dimension, littleEndianLine);
14784
- offset = parsed.offset;
14785
- binaryLineGeometries.push(parsed.geometry);
14786
14755
  }
14787
- return concatenateBinaryLineGeometries(binaryLineGeometries, dimension);
14756
+ if (batchLength > 0) {
14757
+ const datas = builders.map((builder) => builder.flush());
14758
+ const structData = new Data(structField, 0, batchLength, 0, void 0, datas);
14759
+ yield new RecordBatch2(arrowSchema, structData);
14760
+ batchLength = 0;
14761
+ }
14762
+ builders.map((builder) => builder.finish());
14788
14763
  }
14789
- function parseMultiPolygon2(dataView, offset, dimension, littleEndian) {
14790
- const nPolygons = dataView.getUint32(offset, littleEndian);
14791
- offset += 4;
14792
- const binaryPolygonGeometries = [];
14793
- for (let i = 0; i < nPolygons; i++) {
14794
- const littleEndianPolygon = dataView.getUint8(offset) === 1;
14795
- offset++;
14796
- if (dataView.getUint32(offset, littleEndianPolygon) % 1e3 !== 3) {
14797
- throw new Error("WKB: Inner geometries of MultiPolygon not of type Polygon");
14764
+
14765
+ // src/lib/geoarrow/get-arrow-bounds.ts
14766
+ function updateBoundsFromGeoArrowSamples(flatCoords, nDim, bounds, sampleSize = 100) {
14767
+ const numberOfFeatures = flatCoords.length / nDim;
14768
+ const sampleStep = Math.max(Math.floor(numberOfFeatures / sampleSize), 1);
14769
+ const newBounds = [...bounds];
14770
+ for (let i = 0; i < numberOfFeatures; i += sampleStep) {
14771
+ const lng = flatCoords[i * nDim];
14772
+ const lat = flatCoords[i * nDim + 1];
14773
+ if (lng < newBounds[0]) {
14774
+ newBounds[0] = lng;
14775
+ }
14776
+ if (lat < newBounds[1]) {
14777
+ newBounds[1] = lat;
14778
+ }
14779
+ if (lng > newBounds[2]) {
14780
+ newBounds[2] = lng;
14781
+ }
14782
+ if (lat > newBounds[3]) {
14783
+ newBounds[3] = lat;
14798
14784
  }
14799
- offset += 4;
14800
- const parsed = parsePolygon2(dataView, offset, dimension, littleEndianPolygon);
14801
- offset = parsed.offset;
14802
- binaryPolygonGeometries.push(parsed.geometry);
14803
14785
  }
14804
- return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension);
14786
+ return newBounds;
14805
14787
  }
14806
- function concatenateBinaryPointGeometries(binaryPointGeometries, dimension) {
14807
- const positions = binaryPointGeometries.map((geometry) => geometry.positions.value);
14808
- const concatenatedPositions = new Float64Array(concatTypedArrays(positions).buffer);
14788
+
14789
+ // src/lib/geoarrow/convert-geoarrow-to-binary-geometry.ts
14790
+ function getBinaryGeometryTemplate() {
14809
14791
  return {
14810
- type: "Point",
14811
- positions: { value: concatenatedPositions, size: dimension }
14792
+ globalFeatureIds: { value: new Uint32Array(0), size: 1 },
14793
+ positions: { value: new Float32Array(0), size: 2 },
14794
+ properties: [],
14795
+ numericProps: {},
14796
+ featureIds: { value: new Uint32Array(0), size: 1 }
14812
14797
  };
14813
14798
  }
14814
- function concatenateBinaryLineGeometries(binaryLineGeometries, dimension) {
14815
- const lines = binaryLineGeometries.map((geometry) => geometry.positions.value);
14816
- const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer);
14817
- const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0));
14818
- pathIndices.unshift(0);
14819
- return {
14820
- type: "LineString",
14821
- positions: { value: concatenatedPositions, size: dimension },
14822
- pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
14799
+ function getBinaryGeometriesFromArrow(geoColumn, geoEncoding, options) {
14800
+ const featureTypes = {
14801
+ polygon: geoEncoding === "geoarrow.multipolygon" || geoEncoding === "geoarrow.polygon",
14802
+ point: geoEncoding === "geoarrow.multipoint" || geoEncoding === "geoarrow.point",
14803
+ line: geoEncoding === "geoarrow.multilinestring" || geoEncoding === "geoarrow.linestring"
14823
14804
  };
14824
- }
14825
- function concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension) {
14826
- const polygons = [];
14827
- const primitivePolygons = [];
14828
- for (const binaryPolygon of binaryPolygonGeometries) {
14829
- const { positions, primitivePolygonIndices: primitivePolygonIndices2 } = binaryPolygon;
14830
- polygons.push(positions.value);
14831
- primitivePolygons.push(primitivePolygonIndices2.value);
14832
- }
14833
- const concatenatedPositions = new Float64Array(concatTypedArrays(polygons).buffer);
14834
- const polygonIndices = polygons.map((p) => p.length / dimension).map(cumulativeSum(0));
14835
- polygonIndices.unshift(0);
14836
- const primitivePolygonIndices = [0];
14837
- for (const primitivePolygon of primitivePolygons) {
14838
- primitivePolygonIndices.push(
14839
- ...primitivePolygon.filter((x) => x > 0).map((x) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])
14840
- );
14841
- }
14805
+ const chunks = options?.chunkIndex !== void 0 && options?.chunkIndex >= 0 ? [geoColumn.data[options?.chunkIndex]] : geoColumn.data;
14806
+ let bounds = [Infinity, Infinity, -Infinity, -Infinity];
14807
+ let globalFeatureIdOffset = options?.chunkOffset || 0;
14808
+ const binaryGeometries = [];
14809
+ chunks.forEach((chunk) => {
14810
+ const { featureIds, flatCoordinateArray, nDim, geomOffset, triangles } = getBinaryGeometriesFromChunk(chunk, geoEncoding, options);
14811
+ const globalFeatureIds = new Uint32Array(featureIds.length);
14812
+ for (let i = 0; i < featureIds.length; i++) {
14813
+ globalFeatureIds[i] = featureIds[i] + globalFeatureIdOffset;
14814
+ }
14815
+ const binaryContent = {
14816
+ globalFeatureIds: { value: globalFeatureIds, size: 1 },
14817
+ positions: {
14818
+ value: flatCoordinateArray,
14819
+ size: nDim
14820
+ },
14821
+ featureIds: { value: featureIds, size: 1 },
14822
+ // eslint-disable-next-line no-loop-func
14823
+ properties: [...Array(chunk.length).keys()].map((i) => ({
14824
+ index: i + globalFeatureIdOffset
14825
+ }))
14826
+ };
14827
+ globalFeatureIdOffset += chunk.length;
14828
+ binaryGeometries.push({
14829
+ shape: "binary-feature-collection",
14830
+ points: {
14831
+ type: "Point",
14832
+ ...getBinaryGeometryTemplate(),
14833
+ ...featureTypes.point ? binaryContent : {}
14834
+ },
14835
+ lines: {
14836
+ type: "LineString",
14837
+ ...getBinaryGeometryTemplate(),
14838
+ ...featureTypes.line ? binaryContent : {},
14839
+ pathIndices: { value: featureTypes.line ? geomOffset : new Uint16Array(0), size: 1 }
14840
+ },
14841
+ polygons: {
14842
+ type: "Polygon",
14843
+ ...getBinaryGeometryTemplate(),
14844
+ ...featureTypes.polygon ? binaryContent : {},
14845
+ polygonIndices: {
14846
+ // use geomOffset as polygonIndices same as primitivePolygonIndices since we are using earcut to get triangule indices
14847
+ value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
14848
+ size: 1
14849
+ },
14850
+ primitivePolygonIndices: {
14851
+ value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
14852
+ size: 1
14853
+ },
14854
+ ...triangles ? { triangles: { value: triangles, size: 1 } } : {}
14855
+ }
14856
+ });
14857
+ bounds = updateBoundsFromGeoArrowSamples(flatCoordinateArray, nDim, bounds);
14858
+ });
14842
14859
  return {
14843
- type: "Polygon",
14844
- positions: { value: concatenatedPositions, size: dimension },
14845
- polygonIndices: { value: new Uint32Array(polygonIndices), size: 1 },
14846
- primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
14860
+ binaryGeometries,
14861
+ bounds,
14862
+ featureTypes,
14863
+ ...options?.calculateMeanCenters ? { meanCenters: getMeanCentersFromBinaryGeometries(binaryGeometries) } : {}
14847
14864
  };
14848
14865
  }
14849
- function concatTypedArrays(arrays) {
14850
- let byteLength = 0;
14851
- for (let i = 0; i < arrays.length; ++i) {
14852
- byteLength += arrays[i].byteLength;
14853
- }
14854
- const buffer = new Uint8Array(byteLength);
14855
- let byteOffset = 0;
14856
- for (let i = 0; i < arrays.length; ++i) {
14857
- const data = new Uint8Array(arrays[i].buffer);
14858
- byteLength = data.length;
14859
- for (let j = 0; j < byteLength; ++j) {
14860
- buffer[byteOffset++] = data[j];
14866
+ function getMeanCentersFromBinaryGeometries(binaryGeometries) {
14867
+ const globalMeanCenters = [];
14868
+ binaryGeometries.forEach((binaryGeometry) => {
14869
+ let binaryGeometryType = null;
14870
+ if (binaryGeometry.points && binaryGeometry.points.positions.value.length > 0) {
14871
+ binaryGeometryType = "points" /* points */;
14872
+ } else if (binaryGeometry.lines && binaryGeometry.lines.positions.value.length > 0) {
14873
+ binaryGeometryType = "lines" /* lines */;
14874
+ } else if (binaryGeometry.polygons && binaryGeometry.polygons.positions.value.length > 0) {
14875
+ binaryGeometryType = "polygons" /* polygons */;
14861
14876
  }
14862
- }
14863
- return buffer;
14864
- }
14865
-
14866
- // ../wkt/src/wkb-loader.ts
14867
- var WKBWorkerLoader = {
14868
- dataType: null,
14869
- batchType: null,
14870
- name: "WKB",
14871
- id: "wkb",
14872
- module: "wkt",
14873
- version: VERSION3,
14874
- worker: true,
14875
- category: "geometry",
14876
- extensions: ["wkb"],
14877
- mimeTypes: [],
14878
- // TODO can we define static, serializable tests, eg. some binary strings?
14879
- tests: [isWKB],
14880
- options: {
14881
- wkb: {
14882
- shape: "binary-geometry"
14883
- // 'geojson-geometry'
14877
+ const binaryContent = binaryGeometryType ? binaryGeometry[binaryGeometryType] : null;
14878
+ if (binaryContent && binaryGeometryType !== null) {
14879
+ const featureIds = binaryContent.featureIds.value;
14880
+ const flatCoordinateArray = binaryContent.positions.value;
14881
+ const nDim = binaryContent.positions.size;
14882
+ const primitivePolygonIndices = binaryContent.type === "Polygon" ? binaryContent.primitivePolygonIndices?.value : void 0;
14883
+ const meanCenters = getMeanCentersFromGeometry(
14884
+ featureIds,
14885
+ flatCoordinateArray,
14886
+ nDim,
14887
+ binaryGeometryType,
14888
+ primitivePolygonIndices
14889
+ );
14890
+ meanCenters.forEach((center) => {
14891
+ globalMeanCenters.push(center);
14892
+ });
14884
14893
  }
14894
+ });
14895
+ return globalMeanCenters;
14896
+ }
14897
+ function getMeanCentersFromGeometry(featureIds, flatCoordinateArray, nDim, geometryType, primitivePolygonIndices) {
14898
+ const meanCenters = [];
14899
+ const vertexCount = flatCoordinateArray.length;
14900
+ let vertexIndex = 0;
14901
+ let coordIdx = 0;
14902
+ let primitiveIdx = 0;
14903
+ while (vertexIndex < vertexCount) {
14904
+ const featureId = featureIds[vertexIndex / nDim];
14905
+ const center = [0, 0];
14906
+ let vertexCountInFeature = 0;
14907
+ while (vertexIndex < vertexCount && featureIds[coordIdx] === featureId) {
14908
+ if (geometryType === "polygons" /* polygons */ && primitivePolygonIndices?.[primitiveIdx] === coordIdx) {
14909
+ vertexIndex += nDim;
14910
+ primitiveIdx++;
14911
+ } else {
14912
+ center[0] += flatCoordinateArray[vertexIndex];
14913
+ center[1] += flatCoordinateArray[vertexIndex + 1];
14914
+ vertexIndex += nDim;
14915
+ vertexCountInFeature++;
14916
+ }
14917
+ coordIdx += 1;
14918
+ }
14919
+ center[0] /= vertexCountInFeature;
14920
+ center[1] /= vertexCountInFeature;
14921
+ meanCenters.push(center);
14885
14922
  }
14886
- };
14887
- var WKBLoader = {
14888
- ...WKBWorkerLoader,
14889
- parse: async (arrayBuffer) => parseWKB(arrayBuffer),
14890
- parseSync: parseWKB
14891
- };
14892
-
14893
- // src/geoarrow/convert-geoarrow-to-geojson-geometry.ts
14894
- function parseGeometryFromArrow(arrowCellValue, encoding) {
14895
- encoding = encoding?.toLowerCase();
14896
- if (!encoding || !arrowCellValue) {
14897
- return null;
14898
- }
14899
- let geometry;
14900
- switch (encoding) {
14901
- case "geoarrow.multipolygon":
14902
- geometry = arrowMultiPolygonToFeature(arrowCellValue);
14903
- break;
14904
- case "geoarrow.polygon":
14905
- geometry = arrowPolygonToFeature(arrowCellValue);
14906
- break;
14907
- case "geoarrow.multipoint":
14908
- geometry = arrowMultiPointToFeature(arrowCellValue);
14909
- break;
14923
+ return meanCenters;
14924
+ }
14925
+ function getBinaryGeometriesFromChunk(chunk, geoEncoding, options) {
14926
+ switch (geoEncoding) {
14910
14927
  case "geoarrow.point":
14911
- geometry = arrowPointToFeature(arrowCellValue);
14912
- break;
14913
- case "geoarrow.multilinestring":
14914
- geometry = arrowMultiLineStringToFeature(arrowCellValue);
14915
- break;
14928
+ case "geoarrow.multipoint":
14929
+ return getBinaryPointsFromChunk(chunk, geoEncoding);
14916
14930
  case "geoarrow.linestring":
14917
- geometry = arrowLineStringToFeature(arrowCellValue);
14918
- break;
14919
- case "geoarrow.wkb":
14920
- geometry = arrowWKBToFeature(arrowCellValue);
14921
- break;
14922
- case "geoarrow.wkt":
14923
- geometry = arrowWKTToFeature(arrowCellValue);
14924
- break;
14925
- default: {
14926
- throw Error(`GeoArrow encoding not supported ${encoding}`);
14927
- }
14931
+ case "geoarrow.multilinestring":
14932
+ return getBinaryLinesFromChunk(chunk, geoEncoding);
14933
+ case "geoarrow.polygon":
14934
+ case "geoarrow.multipolygon":
14935
+ return getBinaryPolygonsFromChunk(chunk, geoEncoding, options);
14936
+ default:
14937
+ throw Error("invalid geoarrow encoding");
14928
14938
  }
14929
- return geometry;
14930
- }
14931
- function arrowWKBToFeature(arrowCellValue) {
14932
- const arrayBuffer = arrowCellValue.buffer.slice(
14933
- arrowCellValue.byteOffset,
14934
- arrowCellValue.byteOffset + arrowCellValue.byteLength
14935
- );
14936
- const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer);
14937
- const geometry = binaryToGeometry(binaryGeometry);
14938
- return geometry;
14939
- }
14940
- function arrowWKTToFeature(arrowCellValue) {
14941
- const string = arrowCellValue;
14942
- return WKTLoader.parseTextSync?.(string);
14943
14939
  }
14944
- function arrowMultiPolygonToFeature(arrowMultiPolygon) {
14945
- const multiPolygon = [];
14946
- for (let m = 0; m < arrowMultiPolygon.length; m++) {
14947
- const arrowPolygon = arrowMultiPolygon.get(m);
14948
- const polygon = [];
14949
- for (let i = 0; arrowPolygon && i < arrowPolygon?.length; i++) {
14950
- const arrowRing = arrowPolygon?.get(i);
14951
- const ring = [];
14952
- for (let j = 0; arrowRing && j < arrowRing.length; j++) {
14953
- const arrowCoord = arrowRing.get(j);
14954
- const coord = Array.from(arrowCoord);
14955
- ring.push(coord);
14940
+ function getTriangleIndices(polygonIndices, primitivePolygonIndices, flatCoordinateArray, nDim) {
14941
+ try {
14942
+ let primitiveIndex = 0;
14943
+ const triangles = [];
14944
+ for (let i = 0; i < polygonIndices.length - 1; i++) {
14945
+ const startIdx = polygonIndices[i];
14946
+ const endIdx = polygonIndices[i + 1];
14947
+ const slicedFlatCoords = flatCoordinateArray.subarray(startIdx * nDim, endIdx * nDim);
14948
+ const holeIndices = [];
14949
+ while (primitivePolygonIndices[primitiveIndex] < endIdx) {
14950
+ if (primitivePolygonIndices[primitiveIndex] > startIdx) {
14951
+ holeIndices.push(primitivePolygonIndices[primitiveIndex] - startIdx);
14952
+ }
14953
+ primitiveIndex++;
14954
+ }
14955
+ const triangleIndices = earcut(
14956
+ slicedFlatCoords,
14957
+ holeIndices.length > 0 ? holeIndices : void 0,
14958
+ nDim
14959
+ );
14960
+ if (triangleIndices.length === 0) {
14961
+ throw Error("earcut failed e.g. invalid polygon");
14962
+ }
14963
+ for (let j = 0; j < triangleIndices.length; j++) {
14964
+ triangles.push(triangleIndices[j] + startIdx);
14956
14965
  }
14957
- polygon.push(ring);
14958
14966
  }
14959
- multiPolygon.push(polygon);
14960
- }
14961
- const geometry = {
14962
- type: "MultiPolygon",
14963
- coordinates: multiPolygon
14964
- };
14965
- return geometry;
14966
- }
14967
- function arrowPolygonToFeature(arrowPolygon) {
14968
- const polygon = [];
14969
- for (let i = 0; arrowPolygon && i < arrowPolygon.length; i++) {
14970
- const arrowRing = arrowPolygon.get(i);
14971
- const ring = [];
14972
- for (let j = 0; arrowRing && j < arrowRing.length; j++) {
14973
- const arrowCoord = arrowRing.get(j);
14974
- const coords2 = Array.from(arrowCoord);
14975
- ring.push(coords2);
14967
+ const trianglesUint32 = new Uint32Array(triangles.length);
14968
+ for (let i = 0; i < triangles.length; i++) {
14969
+ trianglesUint32[i] = triangles[i];
14976
14970
  }
14977
- polygon.push(ring);
14971
+ return trianglesUint32;
14972
+ } catch (error) {
14973
+ return null;
14978
14974
  }
14979
- const geometry = {
14980
- type: "Polygon",
14981
- coordinates: polygon
14982
- };
14983
- return geometry;
14984
14975
  }
14985
- function arrowMultiPointToFeature(arrowMultiPoint) {
14986
- const multiPoint = [];
14987
- for (let i = 0; arrowMultiPoint && i < arrowMultiPoint.length; i++) {
14988
- const arrowPoint = arrowMultiPoint.get(i);
14989
- if (arrowPoint) {
14990
- const coord = Array.from(arrowPoint);
14991
- multiPoint.push(coord);
14976
+ function getBinaryPolygonsFromChunk(chunk, geoEncoding, options) {
14977
+ const isMultiPolygon = geoEncoding === "geoarrow.multipolygon";
14978
+ const polygonData = isMultiPolygon ? chunk.children[0] : chunk;
14979
+ const polygonOffset = polygonData.valueOffsets;
14980
+ const partData = isMultiPolygon ? chunk.valueOffsets.map((i) => polygonOffset.at(i) || i) : chunk.valueOffsets;
14981
+ const ringData = polygonData.children[0];
14982
+ const pointData = ringData.children[0];
14983
+ const coordData = pointData.children[0];
14984
+ const nDim = pointData.stride;
14985
+ const geomOffset = ringData.valueOffsets;
14986
+ const flatCoordinateArray = coordData.values;
14987
+ const geometryIndicies = new Uint16Array(polygonOffset.length);
14988
+ for (let i = 0; i < polygonOffset.length; i++) {
14989
+ geometryIndicies[i] = geomOffset[polygonOffset[i]];
14990
+ }
14991
+ const numOfVertices = flatCoordinateArray.length / nDim;
14992
+ const featureIds = new Uint32Array(numOfVertices);
14993
+ for (let i = 0; i < partData.length - 1; i++) {
14994
+ const startIdx = geomOffset[partData[i]];
14995
+ const endIdx = geomOffset[partData[i + 1]];
14996
+ for (let j = startIdx; j < endIdx; j++) {
14997
+ featureIds[j] = i;
14992
14998
  }
14993
14999
  }
15000
+ const triangles = options?.triangulate ? getTriangleIndices(geometryIndicies, geomOffset, flatCoordinateArray, nDim) : null;
14994
15001
  return {
14995
- type: "MultiPoint",
14996
- coordinates: multiPoint
14997
- };
14998
- }
14999
- function arrowPointToFeature(arrowPoint) {
15000
- const point = Array.from(arrowPoint);
15001
- return {
15002
- type: "Point",
15003
- coordinates: point
15002
+ featureIds,
15003
+ nDim,
15004
+ flatCoordinateArray,
15005
+ geomOffset,
15006
+ geometryIndicies,
15007
+ ...options?.triangulate && triangles ? { triangles } : {}
15004
15008
  };
15005
15009
  }
15006
- function arrowMultiLineStringToFeature(arrowMultiLineString) {
15007
- const multiLineString = [];
15008
- for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
15009
- const arrowLineString = arrowMultiLineString.get(i);
15010
- const lineString = [];
15011
- for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
15012
- const arrowCoord = arrowLineString.get(j);
15013
- if (arrowCoord) {
15014
- const coords2 = Array.from(arrowCoord);
15015
- lineString.push(coords2);
15010
+ function getBinaryLinesFromChunk(chunk, geoEncoding) {
15011
+ const isMultiLineString = geoEncoding === "geoarrow.multilinestring";
15012
+ const lineData = isMultiLineString ? chunk.children[0] : chunk;
15013
+ const pointData = lineData.children[0];
15014
+ const coordData = pointData.children[0];
15015
+ const nDim = pointData.stride;
15016
+ const geomOffset = lineData.valueOffsets;
15017
+ const flatCoordinateArray = coordData.values;
15018
+ const geometryIndicies = new Uint16Array(0);
15019
+ const numOfVertices = flatCoordinateArray.length / nDim;
15020
+ const featureIds = new Uint32Array(numOfVertices);
15021
+ if (isMultiLineString) {
15022
+ const partData = chunk.valueOffsets;
15023
+ for (let i = 0; i < partData.length - 1; i++) {
15024
+ const startIdx = geomOffset[partData[i]];
15025
+ const endIdx = geomOffset[partData[i + 1]];
15026
+ for (let j = startIdx; j < endIdx; j++) {
15027
+ featureIds[j] = i;
15028
+ }
15029
+ }
15030
+ } else {
15031
+ for (let i = 0; i < chunk.length; i++) {
15032
+ const startIdx = geomOffset[i];
15033
+ const endIdx = geomOffset[i + 1];
15034
+ for (let j = startIdx; j < endIdx; j++) {
15035
+ featureIds[j] = i;
15016
15036
  }
15017
15037
  }
15018
- multiLineString.push(lineString);
15019
15038
  }
15020
15039
  return {
15021
- type: "MultiLineString",
15022
- coordinates: multiLineString
15040
+ featureIds,
15041
+ flatCoordinateArray,
15042
+ nDim,
15043
+ geomOffset,
15044
+ geometryIndicies
15023
15045
  };
15024
15046
  }
15025
- function arrowLineStringToFeature(arrowLineString) {
15026
- const lineString = [];
15027
- for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
15028
- const arrowCoord = arrowLineString.get(i);
15029
- if (arrowCoord) {
15030
- const coords2 = Array.from(arrowCoord);
15031
- lineString.push(coords2);
15047
+ function getBinaryPointsFromChunk(chunk, geoEncoding) {
15048
+ const isMultiPoint = geoEncoding === "geoarrow.multipoint";
15049
+ const pointData = isMultiPoint ? chunk.children[0] : chunk;
15050
+ const coordData = pointData.children[0];
15051
+ const nDim = pointData.stride;
15052
+ const flatCoordinateArray = coordData.values;
15053
+ const geometryIndicies = new Uint16Array(0);
15054
+ const geomOffset = new Int32Array(0);
15055
+ const numOfVertices = flatCoordinateArray.length / nDim;
15056
+ const featureIds = new Uint32Array(numOfVertices);
15057
+ if (isMultiPoint) {
15058
+ const partData = chunk.valueOffsets;
15059
+ for (let i = 0; i < partData.length - 1; i++) {
15060
+ const startIdx = partData[i];
15061
+ const endIdx = partData[i + 1];
15062
+ for (let j = startIdx; j < endIdx; j++) {
15063
+ featureIds[j] = i;
15064
+ }
15065
+ }
15066
+ } else {
15067
+ for (let i = 0; i < chunk.length; i++) {
15068
+ featureIds[i] = i;
15032
15069
  }
15033
15070
  }
15034
15071
  return {
15035
- type: "LineString",
15036
- coordinates: lineString
15072
+ featureIds,
15073
+ flatCoordinateArray,
15074
+ nDim,
15075
+ geomOffset,
15076
+ geometryIndicies
15037
15077
  };
15038
15078
  }
15039
15079