@loaders.gl/arrow 4.0.2 → 4.0.4

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 (119) hide show
  1. package/dist/arrow-loader.d.ts +6 -3
  2. package/dist/arrow-loader.d.ts.map +1 -1
  3. package/dist/arrow-loader.js +9 -1
  4. package/dist/arrow-loader.js.map +1 -1
  5. package/dist/arrow-worker.js +37 -537
  6. package/dist/arrow-writer.d.ts +2 -2
  7. package/dist/arrow-writer.d.ts.map +1 -1
  8. package/dist/arrow-writer.js.map +1 -1
  9. package/dist/dist.dev.js +1615 -246
  10. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.d.ts +31 -1
  11. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.d.ts.map +1 -1
  12. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.js +133 -23
  13. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.js.map +1 -1
  14. package/dist/geoarrow/convert-geoarrow-to-geojson.d.ts +2 -1
  15. package/dist/geoarrow/convert-geoarrow-to-geojson.d.ts.map +1 -1
  16. package/dist/geoarrow/convert-geoarrow-to-geojson.js +4 -0
  17. package/dist/geoarrow/convert-geoarrow-to-geojson.js.map +1 -1
  18. package/dist/geoarrow-loader.d.ts +19 -0
  19. package/dist/geoarrow-loader.d.ts.map +1 -0
  20. package/dist/geoarrow-loader.js +24 -0
  21. package/dist/geoarrow-loader.js.map +1 -0
  22. package/dist/geoarrow-writer.d.ts +9 -0
  23. package/dist/geoarrow-writer.d.ts.map +1 -0
  24. package/dist/geoarrow-writer.js +19 -0
  25. package/dist/geoarrow-writer.js.map +1 -0
  26. package/dist/index.cjs +508 -284
  27. package/dist/index.d.ts +9 -12
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +7 -13
  30. package/dist/index.js.map +1 -1
  31. package/dist/lib/arrow-table-batch.d.ts.map +1 -1
  32. package/dist/lib/arrow-table-batch.js.map +1 -1
  33. package/dist/lib/encode-arrow.d.ts.map +1 -1
  34. package/dist/lib/encode-arrow.js.map +1 -1
  35. package/dist/lib/encode-geoarrow.d.ts +15 -0
  36. package/dist/lib/encode-geoarrow.d.ts.map +1 -0
  37. package/dist/lib/encode-geoarrow.js +22 -0
  38. package/dist/lib/encode-geoarrow.js.map +1 -0
  39. package/dist/{lib → parsers}/parse-arrow-in-batches.d.ts +1 -1
  40. package/dist/parsers/parse-arrow-in-batches.d.ts.map +1 -0
  41. package/dist/parsers/parse-arrow-in-batches.js.map +1 -0
  42. package/dist/parsers/parse-arrow-sync.d.ts +6 -0
  43. package/dist/parsers/parse-arrow-sync.d.ts.map +1 -0
  44. package/dist/parsers/parse-arrow-sync.js +26 -0
  45. package/dist/parsers/parse-arrow-sync.js.map +1 -0
  46. package/dist/parsers/parse-geoarrow-in-batches.d.ts +6 -0
  47. package/dist/parsers/parse-geoarrow-in-batches.d.ts.map +1 -0
  48. package/dist/parsers/parse-geoarrow-in-batches.js +5 -0
  49. package/dist/parsers/parse-geoarrow-in-batches.js.map +1 -0
  50. package/dist/parsers/parse-geoarrow-sync.d.ts +6 -0
  51. package/dist/parsers/parse-geoarrow-sync.d.ts.map +1 -0
  52. package/dist/parsers/parse-geoarrow-sync.js +14 -0
  53. package/dist/parsers/parse-geoarrow-sync.js.map +1 -0
  54. package/dist/schema/convert-arrow-schema.d.ts.map +1 -1
  55. package/dist/schema/convert-arrow-schema.js +32 -5
  56. package/dist/schema/convert-arrow-schema.js.map +1 -1
  57. package/dist/tables/convert-arrow-to-columnar-table.d.ts +8 -0
  58. package/dist/tables/convert-arrow-to-columnar-table.d.ts.map +1 -0
  59. package/dist/tables/convert-arrow-to-columnar-table.js +14 -0
  60. package/dist/tables/convert-arrow-to-columnar-table.js.map +1 -0
  61. package/dist/tables/convert-arrow-to-geojson-table.d.ts +16 -0
  62. package/dist/tables/convert-arrow-to-geojson-table.d.ts.map +1 -0
  63. package/dist/tables/convert-arrow-to-geojson-table.js +33 -0
  64. package/dist/tables/convert-arrow-to-geojson-table.js.map +1 -0
  65. package/dist/tables/convert-columnar-to-row-table.d.ts +7 -0
  66. package/dist/tables/convert-columnar-to-row-table.d.ts.map +1 -0
  67. package/dist/tables/convert-columnar-to-row-table.js +18 -0
  68. package/dist/tables/convert-columnar-to-row-table.js.map +1 -0
  69. package/dist/triangulate-on-worker.d.ts +36 -0
  70. package/dist/triangulate-on-worker.d.ts.map +1 -0
  71. package/dist/triangulate-on-worker.js +14 -0
  72. package/dist/triangulate-on-worker.js.map +1 -0
  73. package/dist/triangulation-worker.js +880 -0
  74. package/dist/workers/arrow-worker.js +1 -1
  75. package/dist/workers/arrow-worker.js.map +1 -1
  76. package/dist/workers/triangulation-worker-node.d.ts +2 -0
  77. package/dist/workers/triangulation-worker-node.d.ts.map +1 -0
  78. package/dist/workers/triangulation-worker-node.js +2 -0
  79. package/dist/workers/triangulation-worker-node.js.map +1 -0
  80. package/dist/workers/triangulation-worker.d.ts +2 -0
  81. package/dist/workers/triangulation-worker.d.ts.map +1 -0
  82. package/dist/workers/triangulation-worker.js +24 -0
  83. package/dist/workers/triangulation-worker.js.map +1 -0
  84. package/package.json +9 -7
  85. package/src/arrow-loader.ts +25 -3
  86. package/src/arrow-writer.ts +2 -2
  87. package/src/geoarrow/convert-geoarrow-to-binary-geometry.ts +221 -30
  88. package/src/geoarrow/convert-geoarrow-to-geojson.ts +6 -2
  89. package/src/geoarrow-loader.ts +55 -0
  90. package/src/geoarrow-writer.ts +41 -0
  91. package/src/index.ts +30 -36
  92. package/src/lib/arrow-table-batch.ts +3 -0
  93. package/src/lib/encode-arrow.ts +3 -0
  94. package/src/lib/encode-geoarrow.ts +45 -0
  95. package/src/{lib → parsers}/parse-arrow-in-batches.ts +4 -2
  96. package/src/parsers/parse-arrow-sync.ts +38 -0
  97. package/src/parsers/parse-geoarrow-in-batches.ts +15 -0
  98. package/src/parsers/parse-geoarrow-sync.ts +22 -0
  99. package/src/schema/convert-arrow-schema.ts +32 -7
  100. package/src/tables/convert-arrow-to-columnar-table.ts +29 -0
  101. package/src/tables/convert-arrow-to-geojson-table.ts +54 -0
  102. package/src/tables/convert-columnar-to-row-table.ts +29 -0
  103. package/src/triangulate-on-worker.ts +47 -0
  104. package/src/workers/arrow-worker.ts +1 -1
  105. package/src/workers/triangulation-worker-node.ts +4 -0
  106. package/src/workers/triangulation-worker.ts +39 -0
  107. package/dist/lib/parse-arrow-in-batches.d.ts.map +0 -1
  108. package/dist/lib/parse-arrow-in-batches.js.map +0 -1
  109. package/dist/lib/parse-arrow-sync.d.ts +0 -5
  110. package/dist/lib/parse-arrow-sync.d.ts.map +0 -1
  111. package/dist/lib/parse-arrow-sync.js +0 -21
  112. package/dist/lib/parse-arrow-sync.js.map +0 -1
  113. package/dist/tables/convert-arrow-to-table.d.ts +0 -21
  114. package/dist/tables/convert-arrow-to-table.d.ts.map +0 -1
  115. package/dist/tables/convert-arrow-to-table.js +0 -37
  116. package/dist/tables/convert-arrow-to-table.js.map +0 -1
  117. package/src/lib/parse-arrow-sync.ts +0 -35
  118. package/src/tables/convert-arrow-to-table.ts +0 -68
  119. /package/dist/{lib → parsers}/parse-arrow-in-batches.js +0 -0
@@ -1,4 +1,4 @@
1
1
  import { createLoaderWorker } from '@loaders.gl/loader-utils';
2
- import { ArrowLoader } from "../index.js";
2
+ import { ArrowLoader } from "../arrow-loader.js";
3
3
  createLoaderWorker(ArrowLoader);
4
4
  //# sourceMappingURL=arrow-worker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arrow-worker.js","names":["createLoaderWorker","ArrowLoader"],"sources":["../../src/workers/arrow-worker.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport {createLoaderWorker} from '@loaders.gl/loader-utils';\nimport {ArrowLoader} from '../index';\n\ncreateLoaderWorker(ArrowLoader);\n"],"mappings":"AAGA,SAAQA,kBAAkB,QAAO,0BAA0B;AAAC,SACpDC,WAAW;AAEnBD,kBAAkB,CAACC,WAAW,CAAC"}
1
+ {"version":3,"file":"arrow-worker.js","names":["createLoaderWorker","ArrowLoader"],"sources":["../../src/workers/arrow-worker.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport {createLoaderWorker} from '@loaders.gl/loader-utils';\nimport {ArrowLoader} from '../arrow-loader';\n\ncreateLoaderWorker(ArrowLoader);\n"],"mappings":"AAGA,SAAQA,kBAAkB,QAAO,0BAA0B;AAAC,SACpDC,WAAW;AAEnBD,kBAAkB,CAACC,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ import './triangulation-worker';
2
+ //# sourceMappingURL=triangulation-worker-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triangulation-worker-node.d.ts","sourceRoot":"","sources":["../../src/workers/triangulation-worker-node.ts"],"names":[],"mappings":"AAGA,OAAO,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import "./triangulation-worker.js";
2
+ //# sourceMappingURL=triangulation-worker-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triangulation-worker-node.js","names":[],"sources":["../../src/workers/triangulation-worker-node.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport './triangulation-worker';\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=triangulation-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triangulation-worker.d.ts","sourceRoot":"","sources":["../../src/workers/triangulation-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { createWorker } from '@loaders.gl/worker-utils';
2
+ import { getTriangleIndices } from "../geoarrow/convert-geoarrow-to-binary-geometry.js";
3
+ createWorker(async function (data) {
4
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5
+ const input = data;
6
+ const operation = input === null || input === void 0 ? void 0 : input.operation;
7
+ switch (operation) {
8
+ case 'test':
9
+ return input;
10
+ case 'triangulate':
11
+ return triangulateBatch(data);
12
+ default:
13
+ throw new Error(`TriangulationWorker: Unsupported operation ${operation}. Expected 'triangulate'`);
14
+ }
15
+ });
16
+ function triangulateBatch(data) {
17
+ console.error('TriangulationWorker: tessellating batch', data);
18
+ const triangleIndices = getTriangleIndices(data.polygonIndices, data.primitivePolygonIndices, data.flatCoordinateArray, data.nDim);
19
+ return {
20
+ ...data,
21
+ triangleIndices
22
+ };
23
+ }
24
+ //# sourceMappingURL=triangulation-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triangulation-worker.js","names":["createWorker","getTriangleIndices","data","options","arguments","length","undefined","input","operation","triangulateBatch","Error","console","error","triangleIndices","polygonIndices","primitivePolygonIndices","flatCoordinateArray","nDim"],"sources":["../../src/workers/triangulation-worker.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport {createWorker} from '@loaders.gl/worker-utils';\nimport {getTriangleIndices} from '../geoarrow/convert-geoarrow-to-binary-geometry';\nimport type {\n TriangulationWorkerInput,\n TriangulateInput,\n TriangulateResult\n} from '../triangulate-on-worker';\n\ncreateWorker(async (data, options = {}) => {\n const input = data as TriangulationWorkerInput;\n const operation = input?.operation;\n switch (operation) {\n case 'test':\n return input;\n case 'triangulate':\n return triangulateBatch(data);\n default:\n throw new Error(\n `TriangulationWorker: Unsupported operation ${operation}. Expected 'triangulate'`\n );\n }\n});\n\nfunction triangulateBatch(data: TriangulateInput): TriangulateResult {\n // Parse any WKT/WKB geometries\n // Build binary geometries\n // Call earcut and triangulate\n console.error('TriangulationWorker: tessellating batch', data);\n const triangleIndices = getTriangleIndices(\n data.polygonIndices,\n data.primitivePolygonIndices,\n data.flatCoordinateArray,\n data.nDim\n );\n return {...data, triangleIndices};\n}\n"],"mappings":"AAGA,SAAQA,YAAY,QAAO,0BAA0B;AAAC,SAC9CC,kBAAkB;AAO1BD,YAAY,CAAC,gBAAOE,IAAI,EAAmB;EAAA,IAAjBC,OAAO,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EACpC,MAAMG,KAAK,GAAGL,IAAgC;EAC9C,MAAMM,SAAS,GAAGD,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEC,SAAS;EAClC,QAAQA,SAAS;IACf,KAAK,MAAM;MACT,OAAOD,KAAK;IACd,KAAK,aAAa;MAChB,OAAOE,gBAAgB,CAACP,IAAI,CAAC;IAC/B;MACE,MAAM,IAAIQ,KAAK,CACZ,8CAA6CF,SAAU,0BAC1D,CAAC;EACL;AACF,CAAC,CAAC;AAEF,SAASC,gBAAgBA,CAACP,IAAsB,EAAqB;EAInES,OAAO,CAACC,KAAK,CAAC,yCAAyC,EAAEV,IAAI,CAAC;EAC9D,MAAMW,eAAe,GAAGZ,kBAAkB,CACxCC,IAAI,CAACY,cAAc,EACnBZ,IAAI,CAACa,uBAAuB,EAC5Bb,IAAI,CAACc,mBAAmB,EACxBd,IAAI,CAACe,IACP,CAAC;EACD,OAAO;IAAC,GAAGf,IAAI;IAAEW;EAAe,CAAC;AACnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/arrow",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Simple columnar table loader for the Apache Arrow format",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,17 +39,19 @@
39
39
  "fs": false
40
40
  },
41
41
  "scripts": {
42
- "pre-build": "npm run build-worker && npm run build-bundle && npm run build-bundle -- --env=dev",
42
+ "pre-build": "npm run build-worker && npm run build-bundle && npm run build-bundle -- --env=dev && npm run build-triangulation-worker",
43
43
  "build-bundle": "ocular-bundle ./src/index.ts",
44
- "build-worker": "esbuild src/workers/arrow-worker.ts --bundle --outfile=dist/arrow-worker.js --platform=browser --external:{stream} --define:__VERSION__=\\\"$npm_package_version\\\"",
44
+ "build-triangulation-worker": "esbuild src/workers/triangulation-worker.ts --bundle --outfile=dist/triangulation-worker.js --platform=browser --external:{stream} --define:__VERSION__=\\\"$npm_package_version\\\"",
45
45
  "pre-build2": "cp fixed-package.json ../../node_modules/apache-arrow/package.json && npm run build-bundle && npm run build-worker",
46
+ "build-worker": "esbuild src/workers/arrow-worker.ts --bundle --outfile=dist/arrow-worker.js --platform=browser --external:{stream} --define:__VERSION__=\\\"$npm_package_version\\\"",
46
47
  "build-worker2": "esbuild src/workers/arrow-worker.ts --bundle --outfile=dist/arrow-worker.js --platform=browser --external:{stream}"
47
48
  },
48
49
  "dependencies": {
49
- "@loaders.gl/gis": "4.0.2",
50
- "@loaders.gl/loader-utils": "4.0.2",
51
- "@loaders.gl/schema": "4.0.2",
50
+ "@loaders.gl/gis": "4.0.4",
51
+ "@loaders.gl/loader-utils": "4.0.4",
52
+ "@loaders.gl/schema": "4.0.4",
53
+ "@math.gl/polygon": "4.0.0",
52
54
  "apache-arrow": "^13.0.0"
53
55
  },
54
- "gitHead": "471058d109d5652f28c32c1f296fd632f9a5c806"
56
+ "gitHead": "4dc810fa04bb400f4aedfef98a83c7ef882ed3d7"
55
57
  }
@@ -1,8 +1,16 @@
1
1
  // loaders.gl, MIT license
2
2
  // Copyright (c) vis.gl contributors
3
3
 
4
- import type {Loader, LoaderOptions} from '@loaders.gl/loader-utils';
4
+ import type {Loader, LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
5
+ import type {
6
+ ArrayRowTable,
7
+ ArrowTableBatch,
8
+ ColumnarTable,
9
+ ObjectRowTable
10
+ } from '@loaders.gl/schema';
5
11
  import type {ArrowTable} from './lib/arrow-table';
12
+ import {parseArrowSync} from './parsers/parse-arrow-sync';
13
+ import {parseArrowInBatches} from './parsers/parse-arrow-in-batches';
6
14
 
7
15
  // __VERSION__ is injected by babel-plugin-version-inline
8
16
  // @ts-ignore TS2304: Cannot find name '__VERSION__'.
@@ -10,12 +18,12 @@ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
10
18
 
11
19
  export type ArrowLoaderOptions = LoaderOptions & {
12
20
  arrow?: {
13
- shape: 'arrow-table' | 'columnar-table' | 'row-table' | 'array-row-table' | 'object-row-table';
21
+ shape: 'arrow-table' | 'columnar-table' | 'array-row-table' | 'object-row-table';
14
22
  };
15
23
  };
16
24
 
17
25
  /** ArrowJS table loader */
18
- export const ArrowLoader: Loader<ArrowTable, never, ArrowLoaderOptions> = {
26
+ export const ArrowWorkerLoader: Loader<ArrowTable, never, ArrowLoaderOptions> = {
19
27
  name: 'Apache Arrow',
20
28
  id: 'arrow',
21
29
  module: 'arrow',
@@ -36,3 +44,17 @@ export const ArrowLoader: Loader<ArrowTable, never, ArrowLoaderOptions> = {
36
44
  }
37
45
  }
38
46
  };
47
+
48
+ /** ArrowJS table loader */
49
+ export const ArrowLoader: LoaderWithParser<
50
+ ArrowTable | ColumnarTable | ObjectRowTable | ArrayRowTable,
51
+ ArrowTableBatch,
52
+ ArrowLoaderOptions
53
+ > = {
54
+ ...ArrowWorkerLoader,
55
+ parse: async (arraybuffer: ArrayBuffer, options?: ArrowLoaderOptions) =>
56
+ parseArrowSync(arraybuffer, options?.arrow),
57
+ parseSync: (arraybuffer: ArrayBuffer, options?: ArrowLoaderOptions) =>
58
+ parseArrowSync(arraybuffer, options?.arrow),
59
+ parseInBatches: parseArrowInBatches
60
+ };
@@ -1,6 +1,6 @@
1
1
  // import type {} from '@loaders.gl/loader-utils';
2
2
 
3
- import type {Writer, WriterOptions} from '@loaders.gl/loader-utils';
3
+ import type {WriterWithEncoder, WriterOptions} from '@loaders.gl/loader-utils';
4
4
  import {ColumnarTable} from './lib/encode-arrow';
5
5
  import {encodeArrowSync} from './lib/encode-arrow';
6
6
 
@@ -13,7 +13,7 @@ type ArrowWriterOptions = WriterOptions & {
13
13
  };
14
14
 
15
15
  /** Apache Arrow writer */
16
- export const ArrowWriter: Writer<ColumnarTable, never, ArrowWriterOptions> = {
16
+ export const ArrowWriter: WriterWithEncoder<ColumnarTable, never, ArrowWriterOptions> = {
17
17
  name: 'Apache Arrow',
18
18
  id: 'arrow',
19
19
  module: 'arrow',
@@ -2,28 +2,49 @@
2
2
  // Copyright (c) vis.gl contributors
3
3
 
4
4
  import * as arrow from 'apache-arrow';
5
+ import {earcut} from '@math.gl/polygon';
5
6
  import {BinaryFeatureCollection as BinaryFeatures} from '@loaders.gl/schema';
6
7
  import {GeoArrowEncoding} from '@loaders.gl/gis';
7
8
  import {updateBoundsFromGeoArrowSamples} from './get-arrow-bounds';
9
+ import {TypedArray} from '@loaders.gl/loader-utils';
8
10
 
9
11
  /**
10
12
  * Binary data from geoarrow column and can be used by e.g. deck.gl GeojsonLayer
11
13
  */
12
14
  export type BinaryDataFromGeoArrow = {
15
+ /** Binary format geometries, an array of BinaryFeatureCollection */
13
16
  binaryGeometries: BinaryFeatures[];
17
+ /** Boundary of the binary geometries */
14
18
  bounds: [number, number, number, number];
19
+ /** Feature types of the binary geometries */
15
20
  featureTypes: {polygon: boolean; point: boolean; line: boolean};
21
+ /** (Optional) mean centers of the binary geometries for e.g. polygon filtering */
22
+ meanCenters?: number[][];
16
23
  };
17
24
 
25
+ /**
26
+ * Binary geometry content returned from getBinaryGeometriesFromChunk
27
+ */
18
28
  type BinaryGeometryContent = {
29
+ // Array of Point feature indexes by vertex
19
30
  featureIds: Uint32Array;
31
+ /** Flat coordinate array of e.g. x, y or x,y,z */
20
32
  flatCoordinateArray: Float64Array;
33
+ /** Dimention of each position */
21
34
  nDim: number;
35
+ /** Array of geometry offsets: the start index of primitive geometry */
22
36
  geomOffset: Int32Array;
37
+ /** Array of geometry indicies: the start index of each geometry */
23
38
  geometryIndicies: Uint16Array;
39
+ /** (Optional) indices of triangels returned from polygon tessellation (Polygon only) */
40
+ triangles?: Uint32Array;
41
+ /** (Optional) array of mean center of each geometry */
42
+ meanCenters?: Float64Array;
24
43
  };
25
44
 
26
- // binary geometry template, see deck.gl BinaryGeometry
45
+ /**
46
+ * binary geometry template, see deck.gl BinaryGeometry
47
+ */
27
48
  export const BINARY_GEOMETRY_TEMPLATE = {
28
49
  globalFeatureIds: {value: new Uint32Array(0), size: 1},
29
50
  positions: {value: new Float32Array(0), size: 2},
@@ -32,16 +53,25 @@ export const BINARY_GEOMETRY_TEMPLATE = {
32
53
  featureIds: {value: new Uint32Array(0), size: 1}
33
54
  };
34
55
 
56
+ export type BinaryGeometriesFromArrowOptions = {
57
+ /** option to specify which chunk to get binary geometries from, for progressive rendering */
58
+ chunkIndex?: number;
59
+ /** option to get mean centers from geometries, for polygon filtering */
60
+ meanCenter?: boolean;
61
+ };
62
+
35
63
  /**
36
64
  * get binary geometries from geoarrow column
37
65
  *
38
66
  * @param geoColumn the geoarrow column, e.g. arrowTable.getChildAt(geoColumnIndex)
39
67
  * @param geoEncoding the geo encoding of the geoarrow column, e.g. getGeoArrowEncoding(arrowTable.schema, geoColumnName)
68
+ * @param options options for getting binary geometries {meanCenter: boolean}
40
69
  * @returns BinaryDataFromGeoArrow
41
70
  */
42
71
  export function getBinaryGeometriesFromArrow(
43
72
  geoColumn: arrow.Vector,
44
- geoEncoding: GeoArrowEncoding
73
+ geoEncoding: GeoArrowEncoding,
74
+ options?: BinaryGeometriesFromArrowOptions
45
75
  ): BinaryDataFromGeoArrow {
46
76
  const featureTypes = {
47
77
  polygon: geoEncoding === 'geoarrow.multipolygon' || geoEncoding === 'geoarrow.polygon',
@@ -49,20 +79,17 @@ export function getBinaryGeometriesFromArrow(
49
79
  line: geoEncoding === 'geoarrow.multilinestring' || geoEncoding === 'geoarrow.linestring'
50
80
  };
51
81
 
52
- const chunks = geoColumn.data;
82
+ const chunks = options?.chunkIndex ? [geoColumn.data[options?.chunkIndex]] : geoColumn.data;
53
83
  let bounds: [number, number, number, number] = [Infinity, Infinity, -Infinity, -Infinity];
54
84
  let globalFeatureIdOffset = 0;
55
85
  const binaryGeometries: BinaryFeatures[] = [];
56
86
 
57
87
  chunks.forEach((chunk) => {
58
- const {featureIds, flatCoordinateArray, nDim, geomOffset} = getBinaryGeometriesFromChunk(
59
- chunk,
60
- geoEncoding
61
- );
88
+ const {featureIds, flatCoordinateArray, nDim, geomOffset, triangles} =
89
+ getBinaryGeometriesFromChunk(chunk, geoEncoding);
62
90
 
63
- const numOfVertices = flatCoordinateArray.length / nDim;
64
- const globalFeatureIds = new Uint32Array(numOfVertices);
65
- for (let i = 0; i < numOfVertices; i++) {
91
+ const globalFeatureIds = new Uint32Array(featureIds.length);
92
+ for (let i = 0; i < featureIds.length; i++) {
66
93
  globalFeatureIds[i] = featureIds[i] + globalFeatureIdOffset;
67
94
  }
68
95
 
@@ -80,7 +107,6 @@ export function getBinaryGeometriesFromArrow(
80
107
 
81
108
  // TODO: check if chunks are sequentially accessed
82
109
  globalFeatureIdOffset += chunk.length;
83
-
84
110
  // NOTE: deck.gl defines the BinaryFeatures structure must have points, lines, polygons even if they are empty
85
111
  binaryGeometries.push({
86
112
  shape: 'binary-feature-collection',
@@ -100,22 +126,111 @@ export function getBinaryGeometriesFromArrow(
100
126
  ...BINARY_GEOMETRY_TEMPLATE,
101
127
  ...(featureTypes.polygon ? binaryContent : {}),
102
128
  polygonIndices: {
103
- // TODO why deck.gl's tessellatePolygon performance is not good when using geometryIndicies
104
- // even when there is no hole in any polygon
129
+ // use geomOffset as polygonIndices same as primitivePolygonIndices since we are using earcut to get triangule indices
105
130
  value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
106
131
  size: 1
107
132
  },
108
133
  primitivePolygonIndices: {
109
134
  value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
110
135
  size: 1
111
- }
136
+ },
137
+ ...(triangles ? {triangles: {value: triangles, size: 1}} : {})
112
138
  }
113
139
  });
114
140
 
115
141
  bounds = updateBoundsFromGeoArrowSamples(flatCoordinateArray, nDim, bounds);
116
142
  });
117
143
 
118
- return {binaryGeometries, bounds, featureTypes};
144
+ return {
145
+ binaryGeometries,
146
+ bounds,
147
+ featureTypes,
148
+ ...(options?.meanCenter
149
+ ? {meanCenters: getMeanCentersFromBinaryGeometries(binaryGeometries)}
150
+ : {})
151
+ };
152
+ }
153
+
154
+ /**
155
+ * Get mean centers from binary geometries
156
+ * @param binaryGeometries binary geometries from geoarrow column, an array of BinaryFeatureCollection
157
+ * @returns mean centers of the binary geometries
158
+ */
159
+ export function getMeanCentersFromBinaryGeometries(binaryGeometries: BinaryFeatures[]): number[][] {
160
+ const globalMeanCenters: number[][] = [];
161
+ binaryGeometries.forEach((binaryGeometry: BinaryFeatures) => {
162
+ let binaryGeometryType: string | null = null;
163
+ if (binaryGeometry.points && binaryGeometry.points.positions.value.length > 0) {
164
+ binaryGeometryType = 'points';
165
+ } else if (binaryGeometry.lines && binaryGeometry.lines.positions.value.length > 0) {
166
+ binaryGeometryType = 'lines';
167
+ } else if (binaryGeometry.polygons && binaryGeometry.polygons.positions.value.length > 0) {
168
+ binaryGeometryType = 'polygons';
169
+ }
170
+
171
+ const binaryContent = binaryGeometryType ? binaryGeometry[binaryGeometryType] : null;
172
+ if (binaryContent && binaryGeometryType !== null) {
173
+ const featureIds = binaryContent.featureIds.value;
174
+ const flatCoordinateArray = binaryContent.positions.value;
175
+ const nDim = binaryContent.positions.size;
176
+ const primitivePolygonIndices = binaryContent.primitivePolygonIndices?.value;
177
+
178
+ const meanCenters = getMeanCentersFromGeometry(
179
+ featureIds,
180
+ flatCoordinateArray,
181
+ nDim,
182
+ binaryGeometryType,
183
+ primitivePolygonIndices
184
+ );
185
+ meanCenters.forEach((center) => {
186
+ globalMeanCenters.push(center);
187
+ });
188
+ }
189
+ });
190
+ return globalMeanCenters;
191
+ }
192
+
193
+ /**
194
+ * Get mean centers from raw coordinates and feature ids
195
+ * @param featureIds Array of feature ids indexes by vertex
196
+ * @param flatCoordinateArray Array of vertex, e.g. x, y or x, y, z, positions
197
+ * @param nDim number of dimensions per position
198
+ * @returns - mean centers of each polygon
199
+ */
200
+ function getMeanCentersFromGeometry(
201
+ featureIds: TypedArray,
202
+ flatCoordinateArray: TypedArray,
203
+ nDim: number,
204
+ geometryType: string,
205
+ primitivePolygonIndices?: TypedArray
206
+ ) {
207
+ const meanCenters: number[][] = [];
208
+ const vertexCount = flatCoordinateArray.length;
209
+ let vertexIndex = 0;
210
+ while (vertexIndex < vertexCount) {
211
+ const featureId = featureIds[vertexIndex / nDim];
212
+ const center = [0, 0];
213
+ let vertexCountInFeature = 0;
214
+ while (vertexIndex < vertexCount && featureIds[vertexIndex / nDim] === featureId) {
215
+ if (
216
+ geometryType === 'polygons' &&
217
+ primitivePolygonIndices &&
218
+ primitivePolygonIndices.indexOf(vertexIndex / nDim) >= 0
219
+ ) {
220
+ // skip the first point since it is the same as the last point in each ring for polygons
221
+ vertexIndex += nDim;
222
+ } else {
223
+ center[0] += flatCoordinateArray[vertexIndex];
224
+ center[1] += flatCoordinateArray[vertexIndex + 1];
225
+ vertexIndex += nDim;
226
+ vertexCountInFeature++;
227
+ }
228
+ }
229
+ center[0] /= vertexCountInFeature;
230
+ center[1] /= vertexCountInFeature;
231
+ meanCenters.push(center);
232
+ }
233
+ return meanCenters;
119
234
  }
120
235
 
121
236
  /**
@@ -143,6 +258,53 @@ function getBinaryGeometriesFromChunk(
143
258
  }
144
259
  }
145
260
 
261
+ /**
262
+ * get triangle indices. Allows deck.gl to skip performing costly triangulation on main thread.
263
+ * @param polygonIndices Indices within positions of the start of each simple Polygon
264
+ * @param primitivePolygonIndices Indices within positions of the start of each primitive Polygon/ring
265
+ * @param flatCoordinateArray Array of x, y or x, y, z positions
266
+ * @param nDim - number of dimensions per position
267
+ * @returns
268
+ */
269
+ export function getTriangleIndices(
270
+ polygonIndices: Uint16Array,
271
+ primitivePolygonIndices: Int32Array,
272
+ flatCoordinateArray: Float64Array,
273
+ nDim: number
274
+ ): Uint32Array {
275
+ let primitiveIndex = 0;
276
+ const triangles: number[] = [];
277
+ // loop polygonIndices to get triangles
278
+ for (let i = 0; i < polygonIndices.length - 1; i++) {
279
+ const startIdx = polygonIndices[i];
280
+ const endIdx = polygonIndices[i + 1];
281
+ // get subarray of flatCoordinateArray
282
+ const slicedFlatCoords = flatCoordinateArray.subarray(startIdx * nDim, endIdx * nDim);
283
+ // get holeIndices for earcut
284
+ const holeIndices: number[] = [];
285
+ while (primitivePolygonIndices[primitiveIndex] < endIdx) {
286
+ if (primitivePolygonIndices[primitiveIndex] > startIdx) {
287
+ holeIndices.push(primitivePolygonIndices[primitiveIndex] - startIdx);
288
+ }
289
+ primitiveIndex++;
290
+ }
291
+ const triangleIndices = earcut(
292
+ slicedFlatCoords,
293
+ holeIndices.length > 0 ? holeIndices : undefined,
294
+ nDim
295
+ );
296
+ for (let j = 0; j < triangleIndices.length; j++) {
297
+ triangles.push(triangleIndices[j] + startIdx);
298
+ }
299
+ }
300
+ // convert traingles to Uint32Array
301
+ const trianglesUint32 = new Uint32Array(triangles.length);
302
+ for (let i = 0; i < triangles.length; i++) {
303
+ trianglesUint32[i] = triangles[i];
304
+ }
305
+ return trianglesUint32;
306
+ }
307
+
146
308
  /**
147
309
  * get binary polygons from geoarrow polygon column
148
310
  * @param chunk one chunk of geoarrow polygon column
@@ -153,6 +315,10 @@ function getBinaryPolygonsFromChunk(chunk: arrow.Data, geoEncoding: string): Bin
153
315
  const isMultiPolygon = geoEncoding === 'geoarrow.multipolygon';
154
316
 
155
317
  const polygonData = isMultiPolygon ? chunk.children[0] : chunk;
318
+ const polygonOffset = polygonData.valueOffsets;
319
+ const partData = isMultiPolygon
320
+ ? chunk.valueOffsets.map((i) => polygonOffset.at(i) || i)
321
+ : chunk.valueOffsets;
156
322
  const ringData = polygonData.children[0];
157
323
  const pointData = ringData.children[0];
158
324
  const coordData = pointData.children[0];
@@ -160,28 +326,29 @@ function getBinaryPolygonsFromChunk(chunk: arrow.Data, geoEncoding: string): Bin
160
326
  const geomOffset = ringData.valueOffsets;
161
327
  const flatCoordinateArray = coordData.values;
162
328
 
163
- const geometryIndicies = new Uint16Array(chunk.length + 1);
164
- for (let i = 0; i < chunk.length; i++) {
165
- geometryIndicies[i] = geomOffset[chunk.valueOffsets[i]];
329
+ const geometryIndicies = new Uint16Array(polygonOffset.length);
330
+ for (let i = 0; i < polygonOffset.length; i++) {
331
+ geometryIndicies[i] = geomOffset[polygonOffset[i]];
166
332
  }
167
- geometryIndicies[chunk.length] = flatCoordinateArray.length / nDim;
168
333
 
169
334
  const numOfVertices = flatCoordinateArray.length / nDim;
170
335
  const featureIds = new Uint32Array(numOfVertices);
171
- for (let i = 0; i < chunk.length - 1; i++) {
172
- const startIdx = geomOffset[chunk.valueOffsets[i]];
173
- const endIdx = geomOffset[chunk.valueOffsets[i + 1]];
336
+ for (let i = 0; i < partData.length - 1; i++) {
337
+ const startIdx = geomOffset[partData[i]];
338
+ const endIdx = geomOffset[partData[i + 1]];
174
339
  for (let j = startIdx; j < endIdx; j++) {
175
340
  featureIds[j] = i;
176
341
  }
177
342
  }
178
343
 
344
+ const triangles = getTriangleIndices(geometryIndicies, geomOffset, flatCoordinateArray, nDim);
179
345
  return {
180
346
  featureIds,
181
347
  flatCoordinateArray,
182
348
  nDim,
183
349
  geomOffset,
184
- geometryIndicies
350
+ geometryIndicies,
351
+ triangles
185
352
  };
186
353
  }
187
354
 
@@ -207,11 +374,23 @@ function getBinaryLinesFromChunk(chunk: arrow.Data, geoEncoding: string): Binary
207
374
 
208
375
  const numOfVertices = flatCoordinateArray.length / nDim;
209
376
  const featureIds = new Uint32Array(numOfVertices);
210
- for (let i = 0; i < chunk.length; i++) {
211
- const startIdx = geomOffset[i];
212
- const endIdx = geomOffset[i + 1];
213
- for (let j = startIdx; j < endIdx; j++) {
214
- featureIds[j] = i;
377
+
378
+ if (isMultiLineString) {
379
+ const partData = chunk.valueOffsets;
380
+ for (let i = 0; i < partData.length - 1; i++) {
381
+ const startIdx = geomOffset[partData[i]];
382
+ const endIdx = geomOffset[partData[i + 1]];
383
+ for (let j = startIdx; j < endIdx; j++) {
384
+ featureIds[j] = i;
385
+ }
386
+ }
387
+ } else {
388
+ for (let i = 0; i < chunk.length; i++) {
389
+ const startIdx = geomOffset[i];
390
+ const endIdx = geomOffset[i + 1];
391
+ for (let j = startIdx; j < endIdx; j++) {
392
+ featureIds[j] = i;
393
+ }
215
394
  }
216
395
  }
217
396
 
@@ -246,8 +425,20 @@ function getBinaryPointsFromChunk(chunk: arrow.Data, geoEncoding: string): Binar
246
425
 
247
426
  const numOfVertices = flatCoordinateArray.length / nDim;
248
427
  const featureIds = new Uint32Array(numOfVertices);
249
- for (let i = 0; i < chunk.length; i++) {
250
- featureIds[i] = i;
428
+
429
+ if (isMultiPoint) {
430
+ const partData = chunk.valueOffsets;
431
+ for (let i = 0; i < partData.length - 1; i++) {
432
+ const startIdx = partData[i];
433
+ const endIdx = partData[i + 1];
434
+ for (let j = startIdx; j < endIdx; j++) {
435
+ featureIds[j] = i;
436
+ }
437
+ }
438
+ } else {
439
+ for (let i = 0; i < chunk.length; i++) {
440
+ featureIds[i] = i;
441
+ }
251
442
  }
252
443
 
253
444
  return {
@@ -15,8 +15,8 @@ import {
15
15
  import type {GeoArrowEncoding} from '@loaders.gl/gis';
16
16
 
17
17
  type RawArrowFeature = {
18
+ data: arrow.Vector;
18
19
  encoding?: GeoArrowEncoding;
19
- data: any;
20
20
  };
21
21
 
22
22
  /**
@@ -30,7 +30,7 @@ type RawArrowFeature = {
30
30
  * @returns Feature or null
31
31
  */
32
32
  export function parseGeometryFromArrow(rawData: RawArrowFeature): Feature | null {
33
- const encoding = rawData.encoding?.toLowerCase();
33
+ const encoding = rawData.encoding?.toLowerCase() as typeof rawData.encoding;
34
34
  const data = rawData.data;
35
35
  if (!encoding || !data) {
36
36
  return null;
@@ -57,6 +57,10 @@ export function parseGeometryFromArrow(rawData: RawArrowFeature): Feature | null
57
57
  case 'geoarrow.linestring':
58
58
  geometry = arrowLineStringToFeature(data);
59
59
  break;
60
+ case 'geoarrow.wkb':
61
+ throw Error(`GeoArrow encoding not supported ${encoding}`);
62
+ case 'geoarrow.wkt':
63
+ throw Error(`GeoArrow encoding not supported ${encoding}`);
60
64
  default: {
61
65
  throw Error(`GeoArrow encoding not supported ${encoding}`);
62
66
  }
@@ -0,0 +1,55 @@
1
+ // loaders.gl, MIT license
2
+ // Copyright (c) vis.gl contributors
3
+
4
+ import type {Loader, LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
5
+ import {ArrowWorkerLoader} from './arrow-loader';
6
+ import type {GeoJSONTable, GeoJSONTableBatch, BinaryGeometry} from '@loaders.gl/schema';
7
+ import type {ArrowTable, ArrowTableBatch} from './lib/arrow-table';
8
+ import {parseGeoArrowSync} from './parsers/parse-geoarrow-sync';
9
+ import {parseGeoArrowInBatches} from './parsers/parse-geoarrow-in-batches';
10
+
11
+ // __VERSION__ is injected by babel-plugin-version-inline
12
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
13
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
14
+
15
+ export type GeoArrowLoaderOptions = LoaderOptions & {
16
+ arrow?: {
17
+ shape: 'arrow-table' | 'binary-geometry';
18
+ };
19
+ };
20
+
21
+ /** ArrowJS table loader */
22
+ export const GeoArrowWorkerLoader: Loader<
23
+ ArrowTable | BinaryGeometry,
24
+ never,
25
+ GeoArrowLoaderOptions
26
+ > = {
27
+ ...ArrowWorkerLoader,
28
+ options: {
29
+ arrow: {
30
+ shape: 'arrow-table'
31
+ }
32
+ }
33
+ };
34
+
35
+ /**
36
+ * GeoArrowLoader loads an Apache Arrow table, parses GeoArrow type extension data
37
+ * to convert it to a GeoJSON table or a BinaryGeometry
38
+ */
39
+ export const GeoArrowLoader: LoaderWithParser<
40
+ ArrowTable | GeoJSONTable, // | BinaryGeometry,
41
+ ArrowTableBatch | GeoJSONTableBatch, // | BinaryGeometry,
42
+ GeoArrowLoaderOptions
43
+ > = {
44
+ ...ArrowWorkerLoader,
45
+ options: {
46
+ arrow: {
47
+ shape: 'arrow-table'
48
+ }
49
+ },
50
+ parse: async (arraybuffer: ArrayBuffer, options?: GeoArrowLoaderOptions) =>
51
+ parseGeoArrowSync(arraybuffer, options?.arrow),
52
+ parseSync: (arraybuffer: ArrayBuffer, options?: GeoArrowLoaderOptions) =>
53
+ parseGeoArrowSync(arraybuffer, options?.arrow),
54
+ parseInBatches: parseGeoArrowInBatches
55
+ };