@loaders.gl/arrow 4.0.3 → 4.0.5

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 (111) 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/dist.dev.js +1573 -231
  7. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.d.ts +31 -1
  8. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.d.ts.map +1 -1
  9. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.js +123 -13
  10. package/dist/geoarrow/convert-geoarrow-to-binary-geometry.js.map +1 -1
  11. package/dist/geoarrow/convert-geoarrow-to-geojson.d.ts +2 -1
  12. package/dist/geoarrow/convert-geoarrow-to-geojson.d.ts.map +1 -1
  13. package/dist/geoarrow/convert-geoarrow-to-geojson.js +4 -0
  14. package/dist/geoarrow/convert-geoarrow-to-geojson.js.map +1 -1
  15. package/dist/geoarrow-loader.d.ts +19 -0
  16. package/dist/geoarrow-loader.d.ts.map +1 -0
  17. package/dist/geoarrow-loader.js +24 -0
  18. package/dist/geoarrow-loader.js.map +1 -0
  19. package/dist/geoarrow-writer.d.ts +9 -0
  20. package/dist/geoarrow-writer.d.ts.map +1 -0
  21. package/dist/geoarrow-writer.js +19 -0
  22. package/dist/geoarrow-writer.js.map +1 -0
  23. package/dist/index.cjs +472 -275
  24. package/dist/index.d.ts +9 -12
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +7 -13
  27. package/dist/index.js.map +1 -1
  28. package/dist/lib/arrow-table-batch.d.ts.map +1 -1
  29. package/dist/lib/arrow-table-batch.js.map +1 -1
  30. package/dist/lib/encode-arrow.d.ts.map +1 -1
  31. package/dist/lib/encode-arrow.js.map +1 -1
  32. package/dist/lib/encode-geoarrow.d.ts +15 -0
  33. package/dist/lib/encode-geoarrow.d.ts.map +1 -0
  34. package/dist/lib/encode-geoarrow.js +22 -0
  35. package/dist/lib/encode-geoarrow.js.map +1 -0
  36. package/dist/{lib → parsers}/parse-arrow-in-batches.d.ts +1 -1
  37. package/dist/parsers/parse-arrow-in-batches.d.ts.map +1 -0
  38. package/dist/parsers/parse-arrow-in-batches.js.map +1 -0
  39. package/dist/parsers/parse-arrow-sync.d.ts +6 -0
  40. package/dist/parsers/parse-arrow-sync.d.ts.map +1 -0
  41. package/dist/parsers/parse-arrow-sync.js +26 -0
  42. package/dist/parsers/parse-arrow-sync.js.map +1 -0
  43. package/dist/parsers/parse-geoarrow-in-batches.d.ts +6 -0
  44. package/dist/parsers/parse-geoarrow-in-batches.d.ts.map +1 -0
  45. package/dist/parsers/parse-geoarrow-in-batches.js +5 -0
  46. package/dist/parsers/parse-geoarrow-in-batches.js.map +1 -0
  47. package/dist/parsers/parse-geoarrow-sync.d.ts +6 -0
  48. package/dist/parsers/parse-geoarrow-sync.d.ts.map +1 -0
  49. package/dist/parsers/parse-geoarrow-sync.js +14 -0
  50. package/dist/parsers/parse-geoarrow-sync.js.map +1 -0
  51. package/dist/tables/convert-arrow-to-columnar-table.d.ts +8 -0
  52. package/dist/tables/convert-arrow-to-columnar-table.d.ts.map +1 -0
  53. package/dist/tables/convert-arrow-to-columnar-table.js +14 -0
  54. package/dist/tables/convert-arrow-to-columnar-table.js.map +1 -0
  55. package/dist/tables/convert-arrow-to-geojson-table.d.ts +16 -0
  56. package/dist/tables/convert-arrow-to-geojson-table.d.ts.map +1 -0
  57. package/dist/tables/convert-arrow-to-geojson-table.js +33 -0
  58. package/dist/tables/convert-arrow-to-geojson-table.js.map +1 -0
  59. package/dist/tables/convert-columnar-to-row-table.d.ts +7 -0
  60. package/dist/tables/convert-columnar-to-row-table.d.ts.map +1 -0
  61. package/dist/tables/convert-columnar-to-row-table.js +18 -0
  62. package/dist/tables/convert-columnar-to-row-table.js.map +1 -0
  63. package/dist/triangulate-on-worker.d.ts +36 -0
  64. package/dist/triangulate-on-worker.d.ts.map +1 -0
  65. package/dist/triangulate-on-worker.js +14 -0
  66. package/dist/triangulate-on-worker.js.map +1 -0
  67. package/dist/triangulation-worker.js +880 -0
  68. package/dist/workers/arrow-worker.js +1 -1
  69. package/dist/workers/arrow-worker.js.map +1 -1
  70. package/dist/workers/triangulation-worker-node.d.ts +2 -0
  71. package/dist/workers/triangulation-worker-node.d.ts.map +1 -0
  72. package/dist/workers/triangulation-worker-node.js +2 -0
  73. package/dist/workers/triangulation-worker-node.js.map +1 -0
  74. package/dist/workers/triangulation-worker.d.ts +2 -0
  75. package/dist/workers/triangulation-worker.d.ts.map +1 -0
  76. package/dist/workers/triangulation-worker.js +24 -0
  77. package/dist/workers/triangulation-worker.js.map +1 -0
  78. package/package.json +9 -7
  79. package/src/arrow-loader.ts +25 -3
  80. package/src/geoarrow/convert-geoarrow-to-binary-geometry.ts +209 -20
  81. package/src/geoarrow/convert-geoarrow-to-geojson.ts +6 -2
  82. package/src/geoarrow-loader.ts +55 -0
  83. package/src/geoarrow-writer.ts +41 -0
  84. package/src/index.ts +30 -36
  85. package/src/lib/arrow-table-batch.ts +3 -0
  86. package/src/lib/encode-arrow.ts +3 -0
  87. package/src/lib/encode-geoarrow.ts +45 -0
  88. package/src/{lib → parsers}/parse-arrow-in-batches.ts +4 -2
  89. package/src/parsers/parse-arrow-sync.ts +38 -0
  90. package/src/parsers/parse-geoarrow-in-batches.ts +15 -0
  91. package/src/parsers/parse-geoarrow-sync.ts +22 -0
  92. package/src/tables/convert-arrow-to-columnar-table.ts +29 -0
  93. package/src/tables/convert-arrow-to-geojson-table.ts +54 -0
  94. package/src/tables/convert-columnar-to-row-table.ts +29 -0
  95. package/src/triangulate-on-worker.ts +47 -0
  96. package/src/workers/arrow-worker.ts +1 -1
  97. package/src/workers/triangulation-worker-node.ts +4 -0
  98. package/src/workers/triangulation-worker.ts +39 -0
  99. package/dist/lib/parse-arrow-in-batches.d.ts.map +0 -1
  100. package/dist/lib/parse-arrow-in-batches.js.map +0 -1
  101. package/dist/lib/parse-arrow-sync.d.ts +0 -5
  102. package/dist/lib/parse-arrow-sync.d.ts.map +0 -1
  103. package/dist/lib/parse-arrow-sync.js +0 -21
  104. package/dist/lib/parse-arrow-sync.js.map +0 -1
  105. package/dist/tables/convert-arrow-to-table.d.ts +0 -21
  106. package/dist/tables/convert-arrow-to-table.d.ts.map +0 -1
  107. package/dist/tables/convert-arrow-to-table.js +0 -37
  108. package/dist/tables/convert-arrow-to-table.js.map +0 -1
  109. package/src/lib/parse-arrow-sync.ts +0 -35
  110. package/src/tables/convert-arrow-to-table.ts +0 -68
  111. /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.3",
3
+ "version": "4.0.5",
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.3",
50
- "@loaders.gl/loader-utils": "4.0.3",
51
- "@loaders.gl/schema": "4.0.3",
50
+ "@loaders.gl/gis": "4.0.5",
51
+ "@loaders.gl/loader-utils": "4.0.5",
52
+ "@loaders.gl/schema": "4.0.5",
53
+ "@math.gl/polygon": "4.0.0",
52
54
  "apache-arrow": "^13.0.0"
53
55
  },
54
- "gitHead": "03c871839b36c997249dabae1844df53a35d3760"
56
+ "gitHead": "9cc48b95bdad8842ebfd9a19f487c534f32526e9"
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
+ };
@@ -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,16 +79,14 @@ 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
91
  const globalFeatureIds = new Uint32Array(featureIds.length);
64
92
  for (let i = 0; i < featureIds.length; i++) {
@@ -79,7 +107,6 @@ export function getBinaryGeometriesFromArrow(
79
107
 
80
108
  // TODO: check if chunks are sequentially accessed
81
109
  globalFeatureIdOffset += chunk.length;
82
-
83
110
  // NOTE: deck.gl defines the BinaryFeatures structure must have points, lines, polygons even if they are empty
84
111
  binaryGeometries.push({
85
112
  shape: 'binary-feature-collection',
@@ -99,22 +126,111 @@ export function getBinaryGeometriesFromArrow(
99
126
  ...BINARY_GEOMETRY_TEMPLATE,
100
127
  ...(featureTypes.polygon ? binaryContent : {}),
101
128
  polygonIndices: {
102
- // TODO why deck.gl's tessellatePolygon performance is not good when using geometryIndicies
103
- // 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
104
130
  value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
105
131
  size: 1
106
132
  },
107
133
  primitivePolygonIndices: {
108
134
  value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
109
135
  size: 1
110
- }
136
+ },
137
+ ...(triangles ? {triangles: {value: triangles, size: 1}} : {})
111
138
  }
112
139
  });
113
140
 
114
141
  bounds = updateBoundsFromGeoArrowSamples(flatCoordinateArray, nDim, bounds);
115
142
  });
116
143
 
117
- 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;
118
234
  }
119
235
 
120
236
  /**
@@ -142,6 +258,53 @@ function getBinaryGeometriesFromChunk(
142
258
  }
143
259
  }
144
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
+
145
308
  /**
146
309
  * get binary polygons from geoarrow polygon column
147
310
  * @param chunk one chunk of geoarrow polygon column
@@ -178,12 +341,14 @@ function getBinaryPolygonsFromChunk(chunk: arrow.Data, geoEncoding: string): Bin
178
341
  }
179
342
  }
180
343
 
344
+ const triangles = getTriangleIndices(geometryIndicies, geomOffset, flatCoordinateArray, nDim);
181
345
  return {
182
346
  featureIds,
183
347
  flatCoordinateArray,
184
348
  nDim,
185
349
  geomOffset,
186
- geometryIndicies
350
+ geometryIndicies,
351
+ triangles
187
352
  };
188
353
  }
189
354
 
@@ -209,11 +374,23 @@ function getBinaryLinesFromChunk(chunk: arrow.Data, geoEncoding: string): Binary
209
374
 
210
375
  const numOfVertices = flatCoordinateArray.length / nDim;
211
376
  const featureIds = new Uint32Array(numOfVertices);
212
- for (let i = 0; i < chunk.length; i++) {
213
- const startIdx = geomOffset[i];
214
- const endIdx = geomOffset[i + 1];
215
- for (let j = startIdx; j < endIdx; j++) {
216
- 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
+ }
217
394
  }
218
395
  }
219
396
 
@@ -248,8 +425,20 @@ function getBinaryPointsFromChunk(chunk: arrow.Data, geoEncoding: string): Binar
248
425
 
249
426
  const numOfVertices = flatCoordinateArray.length / nDim;
250
427
  const featureIds = new Uint32Array(numOfVertices);
251
- for (let i = 0; i < chunk.length; i++) {
252
- 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
+ }
253
442
  }
254
443
 
255
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
+ };
@@ -0,0 +1,41 @@
1
+ // import type {} from '@loaders.gl/loader-utils';
2
+
3
+ import type {WriterWithEncoder, WriterOptions} from '@loaders.gl/loader-utils';
4
+ import {GeoJSONTable, BinaryGeometry} from '@loaders.gl/schema';
5
+ import {encodeGeoArrowSync} from './lib/encode-geoarrow';
6
+
7
+ // __VERSION__ is injected by babel-plugin-version-inline
8
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
9
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
10
+
11
+ type ArrowWriterOptions = WriterOptions & {
12
+ arrow?: {};
13
+ };
14
+
15
+ /** Apache Arrow writer */
16
+ export const GeoArrowWriter: WriterWithEncoder<
17
+ GeoJSONTable | BinaryGeometry,
18
+ never,
19
+ ArrowWriterOptions
20
+ > = {
21
+ name: 'Apache Arrow',
22
+ id: 'arrow',
23
+ module: 'arrow',
24
+ version: VERSION,
25
+ extensions: ['arrow', 'feather'],
26
+ mimeTypes: [
27
+ 'application/vnd.apache.arrow.file',
28
+ 'application/vnd.apache.arrow.stream',
29
+ 'application/octet-stream'
30
+ ],
31
+ binary: true,
32
+ options: {},
33
+ encode: async function encodeArrow(data, options?): Promise<ArrayBuffer> {
34
+ // @ts-expect-error
35
+ return encodeGeoArrowSync(data);
36
+ },
37
+ encodeSync(data, options?) {
38
+ // @ts-expect-error
39
+ return encodeGeoArrowSync(data);
40
+ }
41
+ };