@math.gl/geoarrow 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +140 -0
  2. package/README.md +311 -0
  3. package/dist/builder.d.ts +90 -0
  4. package/dist/builder.d.ts.map +1 -0
  5. package/dist/builder.js +428 -0
  6. package/dist/builder.js.map +1 -0
  7. package/dist/codecs.d.ts +10 -0
  8. package/dist/codecs.d.ts.map +1 -0
  9. package/dist/codecs.js +122 -0
  10. package/dist/codecs.js.map +1 -0
  11. package/dist/index.cjs +1651 -0
  12. package/dist/index.cjs.map +6 -0
  13. package/dist/index.d.ts +12 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +10 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/kernels.d.ts +51 -0
  18. package/dist/kernels.d.ts.map +1 -0
  19. package/dist/kernels.js +359 -0
  20. package/dist/kernels.js.map +1 -0
  21. package/dist/layout.d.ts +52 -0
  22. package/dist/layout.d.ts.map +1 -0
  23. package/dist/layout.js +669 -0
  24. package/dist/layout.js.map +1 -0
  25. package/dist/tessellate.d.ts +31 -0
  26. package/dist/tessellate.d.ts.map +1 -0
  27. package/dist/tessellate.js +102 -0
  28. package/dist/tessellate.js.map +1 -0
  29. package/dist/types.d.ts +113 -0
  30. package/dist/types.d.ts.map +1 -0
  31. package/dist/types.js +41 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/worker.cjs +73 -0
  34. package/dist/worker.cjs.map +6 -0
  35. package/dist/worker.d.ts +11 -0
  36. package/dist/worker.d.ts.map +1 -0
  37. package/dist/worker.js +10 -0
  38. package/dist/worker.js.map +1 -0
  39. package/package.json +48 -0
  40. package/src/builder.ts +569 -0
  41. package/src/codecs.ts +155 -0
  42. package/src/index.ts +93 -0
  43. package/src/kernels.ts +463 -0
  44. package/src/layout.ts +833 -0
  45. package/src/tessellate.ts +133 -0
  46. package/src/types.ts +200 -0
  47. package/src/worker.ts +20 -0
@@ -0,0 +1,133 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {earcut} from '@math.gl/polygon';
6
+ import type {GeoArrowColumn, GeoArrowGeometryValue} from './types';
7
+ import {getGeoArrowDimensionSize} from './types';
8
+ import {materializeGeoArrowRows} from './layout';
9
+ import {assertGeoArrowResourceLimits, type GeoArrowResourceLimitOptions} from './kernels';
10
+
11
+ /** Options for polygon tessellation. */
12
+ export type TessellateGeoArrowPolygonsOptions = Readonly<{
13
+ /** Number of values emitted for each output vertex. Defaults to the input dimension. */
14
+ positionSize?: 2 | 3 | 4;
15
+ /** Value added to every source row index. */
16
+ sourceRowOffset?: number;
17
+ limits?: GeoArrowResourceLimitOptions;
18
+ }>;
19
+
20
+ /** Flat, renderer-ready output for polygon and multipolygon rows. */
21
+ export type GeoArrowTessellation = Readonly<{
22
+ positions: Float32Array;
23
+ /** Source column row for every emitted vertex. */
24
+ sourceRowIndices: Uint32Array;
25
+ indices: Uint16Array | Uint32Array;
26
+ sourceDimension: 2 | 3 | 4;
27
+ positionSize: 2 | 3 | 4;
28
+ rowCount: number;
29
+ polygonCount: number;
30
+ vertexCount: number;
31
+ triangleCount: number;
32
+ }>;
33
+
34
+ /**
35
+ * Tessellates Polygon and MultiPolygon values with stable source-row attribution.
36
+ *
37
+ * Non-polygon members of mixed columns and geometry collections are skipped. Closing coordinates
38
+ * are removed before triangulation and all input descriptors remain borrowed and untouched.
39
+ */
40
+ export function tessellateGeoArrowPolygons(
41
+ column: GeoArrowColumn,
42
+ options: TessellateGeoArrowPolygonsOptions = {}
43
+ ): GeoArrowTessellation {
44
+ assertGeoArrowResourceLimits(column, options.limits);
45
+ const rows = materializeGeoArrowRows(column);
46
+ const sourceDimension = getGeoArrowDimensionSize(column.dimension);
47
+ const positionSize = options.positionSize || sourceDimension;
48
+ const sourceRowOffset = options.sourceRowOffset || 0;
49
+ const positions: number[] = [];
50
+ const sourceRowIndices: number[] = [];
51
+ const indices: number[] = [];
52
+ let polygonCount = 0;
53
+
54
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
55
+ const row = rows[rowIndex];
56
+ if (row) {
57
+ visitPolygons(row, polygon => {
58
+ const vertexOffset = positions.length / positionSize;
59
+ const flatCoordinates: number[] = [];
60
+ const holeIndices: number[] = [];
61
+ let localVertexCount = 0;
62
+
63
+ for (let ringIndex = 0; ringIndex < polygon.length; ringIndex++) {
64
+ const ring = removeClosingCoordinate(polygon[ringIndex]);
65
+ if (ring.length < 3) continue;
66
+ if (localVertexCount > 0) holeIndices.push(localVertexCount);
67
+ for (const coordinate of ring) {
68
+ for (let component = 0; component < sourceDimension; component++) {
69
+ flatCoordinates.push(coordinate[component] ?? 0);
70
+ }
71
+ for (let component = 0; component < positionSize; component++) {
72
+ positions.push(coordinate[component] ?? 0);
73
+ }
74
+ sourceRowIndices.push(sourceRowOffset + rowIndex);
75
+ localVertexCount++;
76
+ }
77
+ }
78
+
79
+ if (localVertexCount >= 3) {
80
+ const localIndices = earcut(flatCoordinates, holeIndices, sourceDimension);
81
+ for (const index of localIndices) indices.push(vertexOffset + index);
82
+ polygonCount++;
83
+ }
84
+ });
85
+ }
86
+ }
87
+
88
+ const vertexCount = positions.length / positionSize;
89
+ const IndexArray = vertexCount <= 65535 ? Uint16Array : Uint32Array;
90
+ return {
91
+ positions: Float32Array.from(positions),
92
+ sourceRowIndices: Uint32Array.from(sourceRowIndices),
93
+ indices: IndexArray.from(indices),
94
+ sourceDimension,
95
+ positionSize,
96
+ rowCount: rows.length,
97
+ polygonCount,
98
+ vertexCount,
99
+ triangleCount: indices.length / 3
100
+ };
101
+ }
102
+
103
+ function visitPolygons(
104
+ geometry: GeoArrowGeometryValue,
105
+ visitor: (polygon: readonly (readonly (readonly number[])[])[]) => void
106
+ ): void {
107
+ switch (geometry.type) {
108
+ case 'Polygon':
109
+ visitor(geometry.coordinates);
110
+ break;
111
+ case 'MultiPolygon':
112
+ for (const polygon of geometry.coordinates) visitor(polygon);
113
+ break;
114
+ case 'GeometryCollection':
115
+ for (const child of geometry.geometries) visitPolygons(child, visitor);
116
+ break;
117
+ default:
118
+ break;
119
+ }
120
+ }
121
+
122
+ function removeClosingCoordinate(
123
+ ring: readonly (readonly number[])[]
124
+ ): readonly (readonly number[])[] {
125
+ if (ring.length < 2) return ring;
126
+ const first = ring[0];
127
+ const last = ring[ring.length - 1];
128
+ if (first.length !== last.length) return ring;
129
+ for (let index = 0; index < first.length; index++) {
130
+ if (first[index] !== last[index]) return ring;
131
+ }
132
+ return ring.slice(0, -1);
133
+ }
package/src/types.ts ADDED
@@ -0,0 +1,200 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {SpatialReference} from '@math.gl/crs';
6
+ import type {TypedArray} from '@math.gl/types';
7
+ import type {WellKnownGeometry} from '@math.gl/wkb';
8
+
9
+ /** GeoArrow concrete, mixed, bounding-box, and serialized encodings. */
10
+ export type GeoArrowEncoding =
11
+ | 'geoarrow.point'
12
+ | 'geoarrow.linestring'
13
+ | 'geoarrow.polygon'
14
+ | 'geoarrow.multipoint'
15
+ | 'geoarrow.multilinestring'
16
+ | 'geoarrow.multipolygon'
17
+ | 'geoarrow.geometry'
18
+ | 'geoarrow.geometrycollection'
19
+ | 'geoarrow.box'
20
+ | 'geoarrow.wkb'
21
+ | 'geoarrow.wkt';
22
+
23
+ /** Semantic coordinate dimensions. M is never interpreted as Z. */
24
+ export type GeoArrowDimension = 'xy' | 'xyz' | 'xym' | 'xyzm';
25
+
26
+ /** Physical coordinate organization for native geometries. */
27
+ export type GeoArrowCoordinateLayout = 'interleaved' | 'separated';
28
+
29
+ /** Supported list-offset buffers. */
30
+ export type GeoArrowOffsets = Int32Array | BigInt64Array;
31
+
32
+ /** Numeric physical storage accepted by GeoArrow descriptors. */
33
+ export type GeoArrowNumericArray = TypedArray | BigInt64Array | BigUint64Array;
34
+
35
+ /** Borrowed validity bitmap. Set bits are valid rows. */
36
+ export type GeoArrowValidity = Readonly<{
37
+ values: Uint8Array;
38
+ /** Bit position corresponding to logical row zero. */
39
+ bitOffset?: number;
40
+ }>;
41
+
42
+ /** Properties shared by all physical arrays. */
43
+ export type GeoArrowArrayBase = Readonly<{
44
+ /** Number of logical values represented by this array. */
45
+ length: number;
46
+ /** Optional borrowed validity bitmap for this nesting level. */
47
+ validity?: GeoArrowValidity;
48
+ }>;
49
+
50
+ /** Primitive scalar storage, optionally strided within a typed array. */
51
+ export type GeoArrowPrimitive = GeoArrowArrayBase &
52
+ Readonly<{
53
+ kind: 'primitive';
54
+ values: GeoArrowNumericArray;
55
+ /** Scalar offset of logical value zero. */
56
+ offset?: number;
57
+ /** Scalars between consecutive logical values. Defaults to one. */
58
+ stride?: number;
59
+ }>;
60
+
61
+ /** Fixed-size list storage, used for interleaved coordinate tuples. */
62
+ export type GeoArrowFixedSizeList = GeoArrowArrayBase &
63
+ Readonly<{
64
+ kind: 'fixed-size-list';
65
+ size: number;
66
+ child: GeoArrowArray;
67
+ /** Logical list offset into the child. */
68
+ offset?: number;
69
+ }>;
70
+
71
+ /** Variable-size list storage. */
72
+ export type GeoArrowList = GeoArrowArrayBase &
73
+ Readonly<{
74
+ kind: 'list';
75
+ offsets: GeoArrowOffsets;
76
+ /** Index of logical row zero in `offsets`. */
77
+ offset?: number;
78
+ /** Value subtracted from offsets before indexing the supplied child view. */
79
+ offsetBase?: number | bigint;
80
+ child: GeoArrowArray;
81
+ }>;
82
+
83
+ /** Named separated children, used for separated coordinates and boxes. */
84
+ export type GeoArrowStruct = GeoArrowArrayBase &
85
+ Readonly<{
86
+ kind: 'struct';
87
+ children: Readonly<Record<string, GeoArrowArray>>;
88
+ /** Logical struct offset applied to every child. */
89
+ offset?: number;
90
+ }>;
91
+
92
+ /** Struct storage used by `geoarrow.box` minimum/maximum ordinate columns. */
93
+ export type GeoArrowBox = GeoArrowStruct;
94
+
95
+ /** One dense-union child and its stable type ID. */
96
+ export type GeoArrowDenseUnionChild = Readonly<{
97
+ name: string;
98
+ typeId: number;
99
+ data: GeoArrowArray;
100
+ }>;
101
+
102
+ /** Dense-union storage for mixed geometry families. */
103
+ export type GeoArrowDenseUnion = GeoArrowArrayBase &
104
+ Readonly<{
105
+ kind: 'dense-union';
106
+ typeIds: Int8Array | Uint8Array;
107
+ valueOffsets: Int32Array;
108
+ children: readonly GeoArrowDenseUnionChild[];
109
+ /** Logical row offset into typeIds and valueOffsets. */
110
+ offset?: number;
111
+ }>;
112
+
113
+ /** Variable-width binary or UTF-8 storage for WKB and WKT. */
114
+ export type GeoArrowSerialized = GeoArrowArrayBase &
115
+ Readonly<{
116
+ kind: 'serialized';
117
+ encoding: 'binary' | 'utf8';
118
+ offsets: GeoArrowOffsets;
119
+ values: Uint8Array;
120
+ /** Index of logical row zero in `offsets`. */
121
+ offset?: number;
122
+ /** Value subtracted from offsets before indexing `values`. */
123
+ offsetBase?: number | bigint;
124
+ }>;
125
+
126
+ /** Arrow-compatible physical array tree without Arrow runtime classes. */
127
+ export type GeoArrowArray =
128
+ | GeoArrowPrimitive
129
+ | GeoArrowFixedSizeList
130
+ | GeoArrowList
131
+ | GeoArrowStruct
132
+ | GeoArrowDenseUnion
133
+ | GeoArrowSerialized;
134
+
135
+ /** One logical GeoArrow geometry column backed by borrowed chunks. */
136
+ export type GeoArrowColumn = Readonly<{
137
+ encoding: GeoArrowEncoding;
138
+ dimension: GeoArrowDimension;
139
+ coordinateLayout: GeoArrowCoordinateLayout | null;
140
+ chunks: readonly GeoArrowArray[];
141
+ spatialReference?: SpatialReference | null;
142
+ edges?: 'planar' | 'spherical';
143
+ metadata?: Readonly<Record<string, unknown>>;
144
+ }>;
145
+
146
+ /** Materialized geometry value used at codec and builder boundaries. */
147
+ export type GeoArrowGeometryValue = WellKnownGeometry;
148
+
149
+ /** Coordinate callback used by mapping kernels. */
150
+ export type GeoArrowCoordinateMapper = (
151
+ coordinate: readonly number[],
152
+ rowIndex: number
153
+ ) => readonly number[];
154
+
155
+ /** Four-value XY bounds. */
156
+ export type GeoArrowBounds = readonly [number, number, number, number];
157
+
158
+ /** Returns the number of coordinate components for a semantic dimension. */
159
+ export function getGeoArrowDimensionSize(dimension: GeoArrowDimension): 2 | 3 | 4 {
160
+ switch (dimension) {
161
+ case 'xy':
162
+ return 2;
163
+ case 'xyz':
164
+ case 'xym':
165
+ return 3;
166
+ case 'xyzm':
167
+ return 4;
168
+ }
169
+ }
170
+
171
+ /** Returns the concrete geometry family associated with an encoding. */
172
+ export function getGeoArrowGeometryType(
173
+ encoding: GeoArrowEncoding
174
+ ): Exclude<GeoArrowGeometryValue['type'], 'GeometryCollection'> | 'GeometryCollection' | null {
175
+ switch (encoding) {
176
+ case 'geoarrow.point':
177
+ return 'Point';
178
+ case 'geoarrow.linestring':
179
+ return 'LineString';
180
+ case 'geoarrow.polygon':
181
+ return 'Polygon';
182
+ case 'geoarrow.multipoint':
183
+ return 'MultiPoint';
184
+ case 'geoarrow.multilinestring':
185
+ return 'MultiLineString';
186
+ case 'geoarrow.multipolygon':
187
+ return 'MultiPolygon';
188
+ case 'geoarrow.geometrycollection':
189
+ return 'GeometryCollection';
190
+ default:
191
+ return null;
192
+ }
193
+ }
194
+
195
+ /** Returns the canonical concrete encoding for a materialized geometry family. */
196
+ export function getGeoArrowEncodingForGeometry(
197
+ type: GeoArrowGeometryValue['type']
198
+ ): GeoArrowEncoding {
199
+ return `geoarrow.${type.toLowerCase()}` as GeoArrowEncoding;
200
+ }
package/src/worker.ts ADDED
@@ -0,0 +1,20 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {GeoArrowColumn} from './types';
6
+ import {getGeoArrowTransferList} from './layout';
7
+
8
+ export {getGeoArrowTransferList} from './layout';
9
+ export type {GeoArrowColumn} from './types';
10
+
11
+ /** A column and the unique borrowed buffers that may be transferred with it. */
12
+ export type GeoArrowTransfer = Readonly<{
13
+ column: GeoArrowColumn;
14
+ transferList: ArrayBuffer[];
15
+ }>;
16
+
17
+ /** Prepares an explicit structured-clone transfer payload without detaching any buffers. */
18
+ export function prepareGeoArrowTransfer(column: GeoArrowColumn): GeoArrowTransfer {
19
+ return {column, transferList: getGeoArrowTransferList(column)};
20
+ }