@loaders.gl/arrow 4.3.2 → 4.4.0-alpha.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 (77) hide show
  1. package/dist/arrow-loader.d.ts +1 -1
  2. package/dist/arrow-worker.js +638 -1292
  3. package/dist/arrow-writer.js +1 -1
  4. package/dist/dist.dev.js +2140 -3383
  5. package/dist/dist.min.js +5 -5
  6. package/dist/exports/arrow-format.d.ts +12 -0
  7. package/dist/exports/arrow-format.d.ts.map +1 -0
  8. package/dist/exports/arrow-format.js +18 -0
  9. package/dist/exports/arrow-loader.d.ts +1 -1
  10. package/dist/exports/arrow-loader.d.ts.map +1 -1
  11. package/dist/exports/arrow-loader.js +1 -1
  12. package/dist/exports/geoarrow-loader.d.ts +1 -1
  13. package/dist/exports/geoarrow-loader.d.ts.map +1 -1
  14. package/dist/geoarrow-loader.d.ts +1 -2
  15. package/dist/geoarrow-loader.d.ts.map +1 -1
  16. package/dist/geoarrow-writer.d.ts +3 -3
  17. package/dist/geoarrow-writer.d.ts.map +1 -1
  18. package/dist/geoarrow-writer.js +1 -1
  19. package/dist/index.cjs +39 -952
  20. package/dist/index.cjs.map +4 -4
  21. package/dist/index.d.ts +1 -9
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +7 -14
  24. package/dist/lib/parsers/parse-arrow.d.ts +1 -2
  25. package/dist/lib/parsers/parse-arrow.d.ts.map +1 -1
  26. package/dist/lib/parsers/parse-arrow.js +1 -1
  27. package/dist/lib/parsers/parse-geoarrow.d.ts +1 -2
  28. package/dist/lib/parsers/parse-geoarrow.d.ts.map +1 -1
  29. package/dist/lib/parsers/parse-geoarrow.js +2 -2
  30. package/dist/triangulate-on-worker.d.ts +2 -1
  31. package/dist/triangulate-on-worker.d.ts.map +1 -1
  32. package/dist/triangulate-on-worker.js +1 -1
  33. package/dist/triangulation-worker.js +212 -154
  34. package/dist/workers/triangulation-worker.js +2 -2
  35. package/package.json +10 -9
  36. package/src/exports/arrow-format.ts +21 -0
  37. package/src/exports/arrow-loader.ts +1 -1
  38. package/src/exports/geoarrow-loader.ts +1 -2
  39. package/src/geoarrow-loader.ts +6 -2
  40. package/src/geoarrow-writer.ts +1 -1
  41. package/src/index.ts +2 -42
  42. package/src/lib/parsers/parse-arrow.ts +2 -3
  43. package/src/lib/parsers/parse-geoarrow.ts +8 -4
  44. package/src/triangulate-on-worker.ts +2 -1
  45. package/src/workers/triangulation-worker.ts +3 -3
  46. package/dist/lib/geoarrow/convert-geoarrow-to-binary-geometry.d.ts +0 -74
  47. package/dist/lib/geoarrow/convert-geoarrow-to-binary-geometry.d.ts.map +0 -1
  48. package/dist/lib/geoarrow/convert-geoarrow-to-binary-geometry.js +0 -377
  49. package/dist/lib/geoarrow/convert-geoarrow-to-geojson-geometry.d.ts +0 -13
  50. package/dist/lib/geoarrow/convert-geoarrow-to-geojson-geometry.d.ts.map +0 -1
  51. package/dist/lib/geoarrow/convert-geoarrow-to-geojson-geometry.js +0 -176
  52. package/dist/lib/geoarrow/get-arrow-bounds.d.ts +0 -11
  53. package/dist/lib/geoarrow/get-arrow-bounds.d.ts.map +0 -1
  54. package/dist/lib/geoarrow/get-arrow-bounds.js +0 -34
  55. package/dist/lib/tables/convert-arrow-schema.d.ts +0 -23
  56. package/dist/lib/tables/convert-arrow-schema.d.ts.map +0 -1
  57. package/dist/lib/tables/convert-arrow-schema.js +0 -280
  58. package/dist/lib/tables/convert-arrow-to-table.d.ts +0 -15
  59. package/dist/lib/tables/convert-arrow-to-table.d.ts.map +0 -1
  60. package/dist/lib/tables/convert-arrow-to-table.js +0 -104
  61. package/dist/lib/tables/convert-table-to-arrow.d.ts +0 -16
  62. package/dist/lib/tables/convert-table-to-arrow.d.ts.map +0 -1
  63. package/dist/lib/tables/convert-table-to-arrow.js +0 -56
  64. package/dist/schema/arrow-table-batch.d.ts +0 -10
  65. package/dist/schema/arrow-table-batch.d.ts.map +0 -1
  66. package/dist/schema/arrow-table-batch.js +0 -67
  67. package/dist/schema/arrow-table-type.d.ts +0 -25
  68. package/dist/schema/arrow-table-type.d.ts.map +0 -1
  69. package/dist/schema/arrow-table-type.js +0 -4
  70. package/src/lib/geoarrow/convert-geoarrow-to-binary-geometry.ts +0 -494
  71. package/src/lib/geoarrow/convert-geoarrow-to-geojson-geometry.ts +0 -207
  72. package/src/lib/geoarrow/get-arrow-bounds.ts +0 -41
  73. package/src/lib/tables/convert-arrow-schema.ts +0 -301
  74. package/src/lib/tables/convert-arrow-to-table.ts +0 -144
  75. package/src/lib/tables/convert-table-to-arrow.ts +0 -72
  76. package/src/schema/arrow-table-batch.ts +0 -82
  77. package/src/schema/arrow-table-type.ts +0 -30
@@ -1,494 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
-
5
- import * as arrow from 'apache-arrow';
6
- import {earcut} from '@math.gl/polygon';
7
- import {BinaryFeatureCollection as BinaryFeatures} from '@loaders.gl/schema';
8
- import {GeoArrowEncoding} from '@loaders.gl/gis';
9
- import {updateBoundsFromGeoArrowSamples} from './get-arrow-bounds';
10
- import {TypedArray} from '@loaders.gl/loader-utils';
11
-
12
- /**
13
- * Binary geometry type
14
- */
15
- enum BinaryGeometryType {
16
- points = 'points',
17
- lines = 'lines',
18
- polygons = 'polygons'
19
- }
20
-
21
- /**
22
- * Binary data from geoarrow column and can be used by e.g. deck.gl GeojsonLayer
23
- */
24
- export type BinaryDataFromGeoArrow = {
25
- /** Binary format geometries, an array of BinaryFeatureCollection */
26
- binaryGeometries: BinaryFeatures[];
27
- /** Boundary of the binary geometries */
28
- bounds: [number, number, number, number];
29
- /** Feature types of the binary geometries */
30
- featureTypes: {polygon: boolean; point: boolean; line: boolean};
31
- /** (Optional) mean centers of the binary geometries for e.g. polygon filtering */
32
- meanCenters?: number[][];
33
- };
34
-
35
- /**
36
- * Binary geometry content returned from getBinaryGeometriesFromChunk
37
- */
38
- type BinaryGeometryContent = {
39
- // Array of Point feature indexes by vertex
40
- featureIds: Uint32Array;
41
- /** Flat coordinate array of e.g. x, y or x,y,z */
42
- flatCoordinateArray: Float64Array;
43
- /** Dimention of each position */
44
- nDim: number;
45
- /** Array of geometry offsets: the start index of primitive geometry */
46
- geomOffset: Int32Array;
47
- /** Array of geometry indicies: the start index of each geometry */
48
- geometryIndicies: Uint16Array;
49
- /** (Optional) indices of triangels returned from polygon triangulation (Polygon only) */
50
- triangles?: Uint32Array;
51
- /** (Optional) array of mean center of each geometry */
52
- meanCenters?: Float64Array;
53
- };
54
-
55
- /**
56
- * binary geometry template, see deck.gl BinaryGeometry
57
- */
58
- export function getBinaryGeometryTemplate() {
59
- return {
60
- globalFeatureIds: {value: new Uint32Array(0), size: 1},
61
- positions: {value: new Float32Array(0), size: 2},
62
- properties: [],
63
- numericProps: {},
64
- featureIds: {value: new Uint32Array(0), size: 1}
65
- };
66
- }
67
-
68
- export type BinaryGeometriesFromArrowOptions = {
69
- /** option to specify which chunk to get binary geometries from, for progressive rendering */
70
- chunkIndex?: number;
71
- /** The offset (beginning index of rows) of input chunk. Used for reconstructing globalFeatureIds in web workers */
72
- chunkOffset?: number;
73
- /** option to get mean centers from geometries, for polygon filtering */
74
- calculateMeanCenters?: boolean;
75
- /** option to compute the triangle indices by tesselating polygons */
76
- triangulate?: boolean;
77
- };
78
-
79
- /**
80
- * get binary geometries from geoarrow column
81
- *
82
- * @param geoColumn the geoarrow column, e.g. arrowTable.getChildAt(geoColumnIndex)
83
- * @param geoEncoding the geo encoding of the geoarrow column, e.g. getGeoArrowEncoding(arrowTable.schema, geoColumnName)
84
- * @param options options for getting binary geometries {meanCenter: boolean}
85
- * @returns BinaryDataFromGeoArrow
86
- */
87
- export function getBinaryGeometriesFromArrow(
88
- geoColumn: arrow.Vector,
89
- geoEncoding: GeoArrowEncoding,
90
- options?: BinaryGeometriesFromArrowOptions
91
- ): BinaryDataFromGeoArrow {
92
- const featureTypes = {
93
- polygon: geoEncoding === 'geoarrow.multipolygon' || geoEncoding === 'geoarrow.polygon',
94
- point: geoEncoding === 'geoarrow.multipoint' || geoEncoding === 'geoarrow.point',
95
- line: geoEncoding === 'geoarrow.multilinestring' || geoEncoding === 'geoarrow.linestring'
96
- };
97
-
98
- const chunks =
99
- options?.chunkIndex !== undefined && options?.chunkIndex >= 0
100
- ? [geoColumn.data[options?.chunkIndex]]
101
- : geoColumn.data;
102
- let bounds: [number, number, number, number] = [Infinity, Infinity, -Infinity, -Infinity];
103
- let globalFeatureIdOffset = options?.chunkOffset || 0;
104
- const binaryGeometries: BinaryFeatures[] = [];
105
-
106
- chunks.forEach((chunk) => {
107
- const {featureIds, flatCoordinateArray, nDim, geomOffset, triangles} =
108
- getBinaryGeometriesFromChunk(chunk, geoEncoding, options);
109
-
110
- const globalFeatureIds = new Uint32Array(featureIds.length);
111
- for (let i = 0; i < featureIds.length; i++) {
112
- globalFeatureIds[i] = featureIds[i] + globalFeatureIdOffset;
113
- }
114
-
115
- const binaryContent = {
116
- globalFeatureIds: {value: globalFeatureIds, size: 1},
117
- positions: {
118
- value: flatCoordinateArray,
119
- size: nDim
120
- },
121
- featureIds: {value: featureIds, size: 1},
122
- // eslint-disable-next-line no-loop-func
123
- properties: [...Array(chunk.length).keys()].map((i) => ({
124
- index: i + globalFeatureIdOffset
125
- }))
126
- };
127
-
128
- // TODO: check if chunks are sequentially accessed
129
- globalFeatureIdOffset += chunk.length;
130
- // NOTE: deck.gl defines the BinaryFeatures structure must have points, lines, polygons even if they are empty
131
- binaryGeometries.push({
132
- shape: 'binary-feature-collection',
133
- points: {
134
- type: 'Point',
135
- ...getBinaryGeometryTemplate(),
136
- ...(featureTypes.point ? binaryContent : {})
137
- },
138
- lines: {
139
- type: 'LineString',
140
- ...getBinaryGeometryTemplate(),
141
- ...(featureTypes.line ? binaryContent : {}),
142
- pathIndices: {value: featureTypes.line ? geomOffset : new Uint16Array(0), size: 1}
143
- },
144
- polygons: {
145
- type: 'Polygon',
146
- ...getBinaryGeometryTemplate(),
147
- ...(featureTypes.polygon ? binaryContent : {}),
148
- polygonIndices: {
149
- // use geomOffset as polygonIndices same as primitivePolygonIndices since we are using earcut to get triangule indices
150
- value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
151
- size: 1
152
- },
153
- primitivePolygonIndices: {
154
- value: featureTypes.polygon ? geomOffset : new Uint16Array(0),
155
- size: 1
156
- },
157
- ...(triangles ? {triangles: {value: triangles, size: 1}} : {})
158
- }
159
- });
160
-
161
- bounds = updateBoundsFromGeoArrowSamples(flatCoordinateArray, nDim, bounds);
162
- });
163
-
164
- return {
165
- binaryGeometries,
166
- bounds,
167
- featureTypes,
168
- ...(options?.calculateMeanCenters
169
- ? {meanCenters: getMeanCentersFromBinaryGeometries(binaryGeometries)}
170
- : {})
171
- };
172
- }
173
-
174
- /**
175
- * Get mean centers from binary geometries
176
- * @param binaryGeometries binary geometries from geoarrow column, an array of BinaryFeatureCollection
177
- * @returns mean centers of the binary geometries
178
- */
179
- export function getMeanCentersFromBinaryGeometries(binaryGeometries: BinaryFeatures[]): number[][] {
180
- const globalMeanCenters: number[][] = [];
181
- binaryGeometries.forEach((binaryGeometry: BinaryFeatures) => {
182
- let binaryGeometryType: keyof typeof BinaryGeometryType | null = null;
183
- if (binaryGeometry.points && binaryGeometry.points.positions.value.length > 0) {
184
- binaryGeometryType = BinaryGeometryType.points;
185
- } else if (binaryGeometry.lines && binaryGeometry.lines.positions.value.length > 0) {
186
- binaryGeometryType = BinaryGeometryType.lines;
187
- } else if (binaryGeometry.polygons && binaryGeometry.polygons.positions.value.length > 0) {
188
- binaryGeometryType = BinaryGeometryType.polygons;
189
- }
190
-
191
- const binaryContent = binaryGeometryType ? binaryGeometry[binaryGeometryType] : null;
192
- if (binaryContent && binaryGeometryType !== null) {
193
- const featureIds = binaryContent.featureIds.value;
194
- const flatCoordinateArray = binaryContent.positions.value;
195
- const nDim = binaryContent.positions.size;
196
- const primitivePolygonIndices =
197
- binaryContent.type === 'Polygon' ? binaryContent.primitivePolygonIndices?.value : undefined;
198
-
199
- const meanCenters = getMeanCentersFromGeometry(
200
- featureIds,
201
- flatCoordinateArray,
202
- nDim,
203
- binaryGeometryType,
204
- primitivePolygonIndices
205
- );
206
- meanCenters.forEach((center) => {
207
- globalMeanCenters.push(center);
208
- });
209
- }
210
- });
211
- return globalMeanCenters;
212
- }
213
-
214
- /**
215
- * Get mean centers from raw coordinates and feature ids
216
- * @param featureIds Array of feature ids indexes by vertex
217
- * @param flatCoordinateArray Array of vertex, e.g. x, y or x, y, z, positions
218
- * @param nDim number of dimensions per position
219
- * @returns - mean centers of each polygon
220
- */
221
- function getMeanCentersFromGeometry(
222
- featureIds: TypedArray,
223
- flatCoordinateArray: TypedArray,
224
- nDim: number,
225
- geometryType: keyof typeof BinaryGeometryType,
226
- primitivePolygonIndices?: TypedArray
227
- ) {
228
- const meanCenters: number[][] = [];
229
- const vertexCount = flatCoordinateArray.length;
230
- let vertexIndex = 0;
231
- let coordIdx = 0;
232
- let primitiveIdx = 0;
233
- while (vertexIndex < vertexCount) {
234
- const featureId = featureIds[vertexIndex / nDim];
235
- const center = [0, 0];
236
- let vertexCountInFeature = 0;
237
- while (vertexIndex < vertexCount && featureIds[coordIdx] === featureId) {
238
- if (
239
- geometryType === BinaryGeometryType.polygons &&
240
- primitivePolygonIndices?.[primitiveIdx] === coordIdx
241
- ) {
242
- // skip the first point since it is the same as the last point in each ring for polygons
243
- vertexIndex += nDim;
244
- primitiveIdx++;
245
- } else {
246
- center[0] += flatCoordinateArray[vertexIndex];
247
- center[1] += flatCoordinateArray[vertexIndex + 1];
248
- vertexIndex += nDim;
249
- vertexCountInFeature++;
250
- }
251
- coordIdx += 1;
252
- }
253
- center[0] /= vertexCountInFeature;
254
- center[1] /= vertexCountInFeature;
255
- meanCenters.push(center);
256
- }
257
- return meanCenters;
258
- }
259
-
260
- /**
261
- * get binary geometries from geoarrow column
262
- * @param chunk one chunk/batch of geoarrow column
263
- * @param geoEncoding geo encoding of the geoarrow column
264
- * @param options options for getting binary geometries
265
- * @returns BinaryGeometryContent
266
- */
267
- function getBinaryGeometriesFromChunk(
268
- chunk: arrow.Data,
269
- geoEncoding: GeoArrowEncoding,
270
- options?: BinaryGeometriesFromArrowOptions
271
- ): BinaryGeometryContent {
272
- switch (geoEncoding) {
273
- case 'geoarrow.point':
274
- case 'geoarrow.multipoint':
275
- return getBinaryPointsFromChunk(chunk, geoEncoding);
276
- case 'geoarrow.linestring':
277
- case 'geoarrow.multilinestring':
278
- return getBinaryLinesFromChunk(chunk, geoEncoding);
279
- case 'geoarrow.polygon':
280
- case 'geoarrow.multipolygon':
281
- return getBinaryPolygonsFromChunk(chunk, geoEncoding, options);
282
- default:
283
- throw Error('invalid geoarrow encoding');
284
- }
285
- }
286
-
287
- /**
288
- * get triangle indices. Allows deck.gl to skip performing costly triangulation on main thread.
289
- * @param polygonIndices Indices within positions of the start of each simple Polygon
290
- * @param primitivePolygonIndices Indices within positions of the start of each primitive Polygon/ring
291
- * @param flatCoordinateArray Array of x, y or x, y, z positions
292
- * @param nDim - number of dimensions per position
293
- * @returns triangle indices or null if invalid polygon and earcut fails
294
- */
295
- export function getTriangleIndices(
296
- polygonIndices: Uint16Array,
297
- primitivePolygonIndices: Int32Array,
298
- flatCoordinateArray: Float64Array,
299
- nDim: number
300
- ): Uint32Array | null {
301
- try {
302
- let primitiveIndex = 0;
303
- const triangles: number[] = [];
304
- // loop polygonIndices to get triangles
305
- for (let i = 0; i < polygonIndices.length - 1; i++) {
306
- const startIdx = polygonIndices[i];
307
- const endIdx = polygonIndices[i + 1];
308
- // get subarray of flatCoordinateArray
309
- const slicedFlatCoords = flatCoordinateArray.subarray(startIdx * nDim, endIdx * nDim);
310
- // get holeIndices for earcut
311
- const holeIndices: number[] = [];
312
- while (primitivePolygonIndices[primitiveIndex] < endIdx) {
313
- if (primitivePolygonIndices[primitiveIndex] > startIdx) {
314
- holeIndices.push(primitivePolygonIndices[primitiveIndex] - startIdx);
315
- }
316
- primitiveIndex++;
317
- }
318
- // TODO check if each ring is closed
319
- const triangleIndices = earcut(
320
- slicedFlatCoords,
321
- holeIndices.length > 0 ? holeIndices : undefined,
322
- nDim
323
- );
324
- if (triangleIndices.length === 0) {
325
- throw Error('earcut failed e.g. invalid polygon');
326
- }
327
- for (let j = 0; j < triangleIndices.length; j++) {
328
- triangles.push(triangleIndices[j] + startIdx);
329
- }
330
- }
331
- // convert traingles to Uint32Array
332
- const trianglesUint32 = new Uint32Array(triangles.length);
333
- for (let i = 0; i < triangles.length; i++) {
334
- trianglesUint32[i] = triangles[i];
335
- }
336
- return trianglesUint32;
337
- } catch (error) {
338
- // if earcut fails, return null
339
- return null;
340
- }
341
- }
342
-
343
- /**
344
- * get binary polygons from geoarrow polygon column
345
- * @param chunk one chunk of geoarrow polygon column
346
- * @param geoEncoding the geo encoding of the geoarrow polygon column
347
- * @param options options for getting binary geometries
348
- * @returns BinaryGeometryContent
349
- */
350
- function getBinaryPolygonsFromChunk(
351
- chunk: arrow.Data,
352
- geoEncoding: string,
353
- options?: BinaryGeometriesFromArrowOptions
354
- ): BinaryGeometryContent {
355
- const isMultiPolygon = geoEncoding === 'geoarrow.multipolygon';
356
-
357
- const polygonData = isMultiPolygon ? chunk.children[0] : chunk;
358
- const polygonOffset = polygonData.valueOffsets;
359
- const partData = isMultiPolygon
360
- ? chunk.valueOffsets.map((i) => polygonOffset.at(i) || i)
361
- : chunk.valueOffsets;
362
- const ringData = polygonData.children[0];
363
- const pointData = ringData.children[0];
364
- const coordData = pointData.children[0];
365
- const nDim = pointData.stride;
366
- const geomOffset = ringData.valueOffsets;
367
- const flatCoordinateArray = coordData.values;
368
-
369
- const geometryIndicies = new Uint16Array(polygonOffset.length);
370
- for (let i = 0; i < polygonOffset.length; i++) {
371
- geometryIndicies[i] = geomOffset[polygonOffset[i]];
372
- }
373
-
374
- const numOfVertices = flatCoordinateArray.length / nDim;
375
- const featureIds = new Uint32Array(numOfVertices);
376
- for (let i = 0; i < partData.length - 1; i++) {
377
- const startIdx = geomOffset[partData[i]];
378
- const endIdx = geomOffset[partData[i + 1]];
379
- for (let j = startIdx; j < endIdx; j++) {
380
- featureIds[j] = i;
381
- }
382
- }
383
-
384
- const triangles = options?.triangulate
385
- ? getTriangleIndices(geometryIndicies, geomOffset, flatCoordinateArray, nDim)
386
- : null;
387
-
388
- return {
389
- featureIds,
390
- nDim,
391
- flatCoordinateArray,
392
- geomOffset,
393
- geometryIndicies,
394
- ...(options?.triangulate && triangles ? {triangles} : {})
395
- };
396
- }
397
-
398
- /**
399
- * get binary lines from geoarrow line column
400
- * @param chunk one chunk/batch of geoarrow column
401
- * @param geoEncoding the geo encoding of the geoarrow column
402
- * @returns BinaryGeometryContent
403
- */
404
- function getBinaryLinesFromChunk(chunk: arrow.Data, geoEncoding: string): BinaryGeometryContent {
405
- const isMultiLineString = geoEncoding === 'geoarrow.multilinestring';
406
-
407
- const lineData = isMultiLineString ? chunk.children[0] : chunk;
408
- const pointData = lineData.children[0];
409
- const coordData = pointData.children[0];
410
-
411
- const nDim = pointData.stride;
412
- const geomOffset = lineData.valueOffsets;
413
- const flatCoordinateArray = coordData.values;
414
-
415
- // geometryIndicies is not needed for line string
416
- const geometryIndicies = new Uint16Array(0);
417
-
418
- const numOfVertices = flatCoordinateArray.length / nDim;
419
- const featureIds = new Uint32Array(numOfVertices);
420
-
421
- if (isMultiLineString) {
422
- const partData = chunk.valueOffsets;
423
- for (let i = 0; i < partData.length - 1; i++) {
424
- const startIdx = geomOffset[partData[i]];
425
- const endIdx = geomOffset[partData[i + 1]];
426
- for (let j = startIdx; j < endIdx; j++) {
427
- featureIds[j] = i;
428
- }
429
- }
430
- } else {
431
- for (let i = 0; i < chunk.length; i++) {
432
- const startIdx = geomOffset[i];
433
- const endIdx = geomOffset[i + 1];
434
- for (let j = startIdx; j < endIdx; j++) {
435
- featureIds[j] = i;
436
- }
437
- }
438
- }
439
-
440
- return {
441
- featureIds,
442
- flatCoordinateArray,
443
- nDim,
444
- geomOffset,
445
- geometryIndicies
446
- };
447
- }
448
-
449
- /**
450
- * get binary points from geoarrow point column
451
- * @param chunk one chunk/batch of geoarrow column
452
- * @param geoEncoding geo encoding of the geoarrow column
453
- * @returns BinaryGeometryContent
454
- */
455
- function getBinaryPointsFromChunk(chunk: arrow.Data, geoEncoding: string): BinaryGeometryContent {
456
- const isMultiPoint = geoEncoding === 'geoarrow.multipoint';
457
-
458
- const pointData = isMultiPoint ? chunk.children[0] : chunk;
459
- const coordData = pointData.children[0];
460
-
461
- const nDim = pointData.stride;
462
- const flatCoordinateArray = coordData.values;
463
-
464
- // geometryIndices is not needed for point
465
- const geometryIndicies = new Uint16Array(0);
466
- // geomOffset is not needed for point
467
- const geomOffset = new Int32Array(0);
468
-
469
- const numOfVertices = flatCoordinateArray.length / nDim;
470
- const featureIds = new Uint32Array(numOfVertices);
471
-
472
- if (isMultiPoint) {
473
- const partData = chunk.valueOffsets;
474
- for (let i = 0; i < partData.length - 1; i++) {
475
- const startIdx = partData[i];
476
- const endIdx = partData[i + 1];
477
- for (let j = startIdx; j < endIdx; j++) {
478
- featureIds[j] = i;
479
- }
480
- }
481
- } else {
482
- for (let i = 0; i < chunk.length; i++) {
483
- featureIds[i] = i;
484
- }
485
- }
486
-
487
- return {
488
- featureIds,
489
- flatCoordinateArray,
490
- nDim,
491
- geomOffset,
492
- geometryIndicies
493
- };
494
- }
@@ -1,207 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
-
5
- // import * as arrow from 'apache-arrow';
6
- import {
7
- MultiPolygon,
8
- Position,
9
- Polygon,
10
- MultiPoint,
11
- Point,
12
- MultiLineString,
13
- LineString,
14
- Geometry,
15
- BinaryGeometry
16
- } from '@loaders.gl/schema';
17
- import {binaryToGeometry, type GeoArrowEncoding} from '@loaders.gl/gis';
18
- import {WKBLoader, WKTLoader} from '@loaders.gl/wkt';
19
-
20
- /**
21
- * parse geometry from arrow data that is returned from processArrowData()
22
- * NOTE: this function could be deduplicated with the binaryToFeature() in deck.gl,
23
- * it is currently used for deck.gl picking because currently deck.gl returns only the index of the feature
24
- *
25
- * @param data data extraced from arrow vector representing a geometry
26
- * @param encoding the geoarrow encoding of the geometry column
27
- * @returns Feature or null
28
- */
29
- export function parseGeometryFromArrow(
30
- arrowCellValue: any,
31
- encoding?: GeoArrowEncoding
32
- ): Geometry | null {
33
- // sanity
34
- encoding = encoding?.toLowerCase() as GeoArrowEncoding;
35
- if (!encoding || !arrowCellValue) {
36
- return null;
37
- }
38
-
39
- let geometry: Geometry;
40
-
41
- switch (encoding) {
42
- case 'geoarrow.multipolygon':
43
- geometry = arrowMultiPolygonToFeature(arrowCellValue);
44
- break;
45
- case 'geoarrow.polygon':
46
- geometry = arrowPolygonToFeature(arrowCellValue);
47
- break;
48
- case 'geoarrow.multipoint':
49
- geometry = arrowMultiPointToFeature(arrowCellValue);
50
- break;
51
- case 'geoarrow.point':
52
- geometry = arrowPointToFeature(arrowCellValue);
53
- break;
54
- case 'geoarrow.multilinestring':
55
- geometry = arrowMultiLineStringToFeature(arrowCellValue);
56
- break;
57
- case 'geoarrow.linestring':
58
- geometry = arrowLineStringToFeature(arrowCellValue);
59
- break;
60
- case 'geoarrow.wkb':
61
- geometry = arrowWKBToFeature(arrowCellValue);
62
- break;
63
- case 'geoarrow.wkt':
64
- geometry = arrowWKTToFeature(arrowCellValue);
65
- break;
66
- default: {
67
- throw Error(`GeoArrow encoding not supported ${encoding}`);
68
- }
69
- }
70
-
71
- return geometry;
72
- }
73
-
74
- function arrowWKBToFeature(arrowCellValue: any) {
75
- // The actual WKB array buffer starts from byteOffset and ends at byteOffset + byteLength
76
- const arrayBuffer: ArrayBuffer = arrowCellValue.buffer.slice(
77
- arrowCellValue.byteOffset,
78
- arrowCellValue.byteOffset + arrowCellValue.byteLength
79
- );
80
- const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer) as BinaryGeometry;
81
- const geometry = binaryToGeometry(binaryGeometry);
82
- return geometry;
83
- }
84
-
85
- function arrowWKTToFeature(arrowCellValue: any) {
86
- const string: string = arrowCellValue;
87
- return WKTLoader.parseTextSync?.(string);
88
- }
89
-
90
- /**
91
- * convert Arrow MultiPolygon to geojson Feature
92
- */
93
- function arrowMultiPolygonToFeature(arrowMultiPolygon: any): MultiPolygon {
94
- const multiPolygon: Position[][][] = [];
95
- for (let m = 0; m < arrowMultiPolygon.length; m++) {
96
- const arrowPolygon = arrowMultiPolygon.get(m);
97
- const polygon: Position[][] = [];
98
- for (let i = 0; arrowPolygon && i < arrowPolygon?.length; i++) {
99
- const arrowRing = arrowPolygon?.get(i);
100
- const ring: Position[] = [];
101
- for (let j = 0; arrowRing && j < arrowRing.length; j++) {
102
- const arrowCoord = arrowRing.get(j);
103
- const coord: Position = Array.from(arrowCoord);
104
- ring.push(coord);
105
- }
106
- polygon.push(ring);
107
- }
108
- multiPolygon.push(polygon);
109
- }
110
- const geometry: MultiPolygon = {
111
- type: 'MultiPolygon',
112
- coordinates: multiPolygon
113
- };
114
- return geometry;
115
- }
116
-
117
- /**
118
- * convert Arrow Polygon to geojson Feature
119
- */
120
- function arrowPolygonToFeature(arrowPolygon: any): Polygon {
121
- const polygon: Position[][] = [];
122
- for (let i = 0; arrowPolygon && i < arrowPolygon.length; i++) {
123
- const arrowRing = arrowPolygon.get(i);
124
- const ring: Position[] = [];
125
- for (let j = 0; arrowRing && j < arrowRing.length; j++) {
126
- const arrowCoord = arrowRing.get(j);
127
- const coords: Position = Array.from(arrowCoord);
128
- ring.push(coords);
129
- }
130
- polygon.push(ring);
131
- }
132
- const geometry: Polygon = {
133
- type: 'Polygon',
134
- coordinates: polygon
135
- };
136
- return geometry;
137
- }
138
-
139
- /**
140
- * convert Arrow MultiPoint to geojson MultiPoint
141
- */
142
- function arrowMultiPointToFeature(arrowMultiPoint: any): MultiPoint {
143
- const multiPoint: Position[] = [];
144
- for (let i = 0; arrowMultiPoint && i < arrowMultiPoint.length; i++) {
145
- const arrowPoint = arrowMultiPoint.get(i);
146
- if (arrowPoint) {
147
- const coord: Position = Array.from(arrowPoint);
148
- multiPoint.push(coord);
149
- }
150
- }
151
- return {
152
- type: 'MultiPoint',
153
- coordinates: multiPoint
154
- };
155
- }
156
-
157
- /**
158
- * convert Arrow Point to geojson Point
159
- */
160
- function arrowPointToFeature(arrowPoint: any): Point {
161
- const point: Position = Array.from(arrowPoint);
162
- return {
163
- type: 'Point',
164
- coordinates: point
165
- };
166
- }
167
-
168
- /**
169
- * convert Arrow MultiLineString to geojson MultiLineString
170
- */
171
- function arrowMultiLineStringToFeature(arrowMultiLineString: any): MultiLineString {
172
- const multiLineString: Position[][] = [];
173
- for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
174
- const arrowLineString = arrowMultiLineString.get(i);
175
- const lineString: Position[] = [];
176
- for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
177
- const arrowCoord = arrowLineString.get(j);
178
- if (arrowCoord) {
179
- const coords: Position = Array.from(arrowCoord);
180
- lineString.push(coords);
181
- }
182
- }
183
- multiLineString.push(lineString);
184
- }
185
- return {
186
- type: 'MultiLineString',
187
- coordinates: multiLineString
188
- };
189
- }
190
-
191
- /**
192
- * convert Arrow LineString to geojson LineString
193
- */
194
- function arrowLineStringToFeature(arrowLineString: any): LineString {
195
- const lineString: Position[] = [];
196
- for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
197
- const arrowCoord = arrowLineString.get(i);
198
- if (arrowCoord) {
199
- const coords: Position = Array.from(arrowCoord);
200
- lineString.push(coords);
201
- }
202
- }
203
- return {
204
- type: 'LineString',
205
- coordinates: lineString
206
- };
207
- }