@loaders.gl/geoarrow 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.
- package/LICENSE +41 -0
- package/README.md +7 -0
- package/dist/geo-column/geo-column-info.d.ts +20 -0
- package/dist/geo-column/geo-column-info.d.ts.map +1 -0
- package/dist/geo-column/geo-column-info.js +74 -0
- package/dist/geo-column/geo-column.d.ts +61 -0
- package/dist/geo-column/geo-column.d.ts.map +1 -0
- package/dist/geo-column/geo-column.js +4 -0
- package/dist/geoarrow-functions.d.ts +131 -0
- package/dist/geoarrow-functions.d.ts.map +1 -0
- package/dist/geoarrow-functions.js +218 -0
- package/dist/geoarrow-types.d.ts +49 -0
- package/dist/geoarrow-types.d.ts.map +1 -0
- package/dist/geoarrow-types.js +4 -0
- package/dist/get-arrow-bounds.d.ts +11 -0
- package/dist/get-arrow-bounds.d.ts.map +1 -0
- package/dist/get-arrow-bounds.js +34 -0
- package/dist/get-geoarrow-geometry-info.d.ts +30 -0
- package/dist/get-geoarrow-geometry-info.d.ts.map +1 -0
- package/dist/get-geoarrow-geometry-info.js +124 -0
- package/dist/index.cjs +430 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/mesharrow/arrow-fixed-size-list-utils.d.ts +11 -0
- package/dist/mesharrow/arrow-fixed-size-list-utils.d.ts.map +1 -0
- package/dist/mesharrow/arrow-fixed-size-list-utils.js +39 -0
- package/dist/mesharrow/arrow-list-of-fixed-size-list-utils.d.ts +11 -0
- package/dist/mesharrow/arrow-list-of-fixed-size-list-utils.d.ts.map +1 -0
- package/dist/mesharrow/arrow-list-of-fixed-size-list-utils.js +31 -0
- package/dist/mesharrow/get-bounding-box.d.ts +5 -0
- package/dist/mesharrow/get-bounding-box.d.ts.map +1 -0
- package/dist/mesharrow/get-bounding-box.js +33 -0
- package/dist/mesharrow/get-deck-binary-data.d.ts +13 -0
- package/dist/mesharrow/get-deck-binary-data.d.ts.map +1 -0
- package/dist/mesharrow/get-deck-binary-data.js +24 -0
- package/dist/mesharrow/mesh-accessors.d.ts +8 -0
- package/dist/mesharrow/mesh-accessors.d.ts.map +1 -0
- package/dist/mesharrow/mesh-accessors.js +18 -0
- package/dist/metadata/geoarrow-metadata.d.ts +27 -0
- package/dist/metadata/geoarrow-metadata.d.ts.map +1 -0
- package/dist/metadata/geoarrow-metadata.js +71 -0
- package/dist/metadata/geoparquet-metadata-schema.d.ts +79 -0
- package/dist/metadata/geoparquet-metadata-schema.d.ts.map +1 -0
- package/dist/metadata/geoparquet-metadata-schema.js +69 -0
- package/dist/metadata/geoparquet-metadata.d.ts +45 -0
- package/dist/metadata/geoparquet-metadata.d.ts.map +1 -0
- package/dist/metadata/geoparquet-metadata.js +131 -0
- package/dist/metadata/metadata-utils.d.ts +21 -0
- package/dist/metadata/metadata-utils.d.ts.map +1 -0
- package/dist/metadata/metadata-utils.js +14 -0
- package/package.json +63 -0
- package/src/geo-column/geo-column-info.ts +114 -0
- package/src/geo-column/geo-column.ts +85 -0
- package/src/geoarrow-functions.ts +258 -0
- package/src/geoarrow-types.ts +72 -0
- package/src/get-arrow-bounds.ts +41 -0
- package/src/get-geo-column-from-geoarrow.ts.disabled +251 -0
- package/src/get-geoarrow-geometry-info.ts +172 -0
- package/src/index.ts +57 -0
- package/src/mesharrow/arrow-fixed-size-list-utils.ts +62 -0
- package/src/mesharrow/arrow-list-of-fixed-size-list-utils.ts +47 -0
- package/src/mesharrow/get-bounding-box.ts +39 -0
- package/src/mesharrow/get-deck-binary-data.ts +43 -0
- package/src/mesharrow/mesh-accessors.ts +27 -0
- package/src/metadata/geoarrow-metadata.ts +102 -0
- package/src/metadata/geoparquet-metadata-schema.ts +71 -0
- package/src/metadata/geoparquet-metadata.ts +195 -0
- package/src/metadata/metadata-utils.ts +32 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import * as arrow from 'apache-arrow';
|
|
6
|
+
import type {GeoArrowEncoding} from './metadata/geoarrow-metadata';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @see https://geoarrow.org/format.html#memory-layouts
|
|
10
|
+
*/
|
|
11
|
+
export type GeoArrowGeometryInfo = {
|
|
12
|
+
/** Geometry encodings that are compatible with this column (Field) */
|
|
13
|
+
compatibleEncodings: GeoArrowEncoding[];
|
|
14
|
+
/** How many levels of List<> nesting */
|
|
15
|
+
nesting: 0 | 1 | 2 | 3;
|
|
16
|
+
/** How many values per coordinate */
|
|
17
|
+
dimension: number;
|
|
18
|
+
/**
|
|
19
|
+
* - 0: A point is just a Coordinate
|
|
20
|
+
* - 1: A line string or a multipoint is a List<Coordinate>
|
|
21
|
+
* - 2: A polygon or a multilinestring are List<List<Coordinate>>
|
|
22
|
+
* - 3: multipolygons are List<List<List<Coordinate>>>
|
|
23
|
+
*/
|
|
24
|
+
/** Coordinate memory layout {x,y,...} vs [x,y,...] */
|
|
25
|
+
coordinates: 'separated' | 'interleaved';
|
|
26
|
+
/** Coordinate */
|
|
27
|
+
valueType: 'double'; // 'float'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Helper type used to test coordinates */
|
|
31
|
+
type CoordinateFieldInfo = {
|
|
32
|
+
coordinates: 'interleaved' | 'separated';
|
|
33
|
+
dimension: 2 | 3 | 4;
|
|
34
|
+
valueType: 'double';
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Examines a column containing GeoArrow formatted data and returns information about the geometry type
|
|
39
|
+
* that can be useful during traversal
|
|
40
|
+
* @see https://geoarrow.org/format.html#memory-layouts
|
|
41
|
+
*/
|
|
42
|
+
// eslint-disable-next-line max-statements
|
|
43
|
+
export function getGeoArrowGeometryInfo(arrowField: arrow.Field): GeoArrowGeometryInfo | null {
|
|
44
|
+
if (arrowField.type instanceof arrow.Utf8) {
|
|
45
|
+
return {
|
|
46
|
+
compatibleEncodings: ['geoarrow.wkt'],
|
|
47
|
+
nesting: 0,
|
|
48
|
+
/** @note: Dimension encoded in WKT */
|
|
49
|
+
dimension: 2,
|
|
50
|
+
coordinates: 'interleaved',
|
|
51
|
+
valueType: 'double'
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (arrowField.type instanceof arrow.Binary || arrowField.type instanceof arrow.LargeBinary) {
|
|
56
|
+
return {
|
|
57
|
+
compatibleEncodings: ['geoarrow.wkb'],
|
|
58
|
+
nesting: 0,
|
|
59
|
+
/** @note: Dimension encoded in WKB */
|
|
60
|
+
dimension: 2,
|
|
61
|
+
coordinates: 'interleaved',
|
|
62
|
+
valueType: 'double'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
let coordinateInfo = getCoordinateFieldInfo(arrowField);
|
|
66
|
+
// A point is just a Coordinate
|
|
67
|
+
if (coordinateInfo) {
|
|
68
|
+
return {
|
|
69
|
+
compatibleEncodings: ['geoarrow.point'],
|
|
70
|
+
nesting: 0,
|
|
71
|
+
...coordinateInfo
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// A line string or a multipoint is a List<Coordinate>
|
|
76
|
+
if (!(arrowField.type instanceof arrow.List)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
arrowField = arrowField.type.children[0];
|
|
80
|
+
|
|
81
|
+
coordinateInfo = getCoordinateFieldInfo(arrowField);
|
|
82
|
+
if (coordinateInfo) {
|
|
83
|
+
return {
|
|
84
|
+
compatibleEncodings: ['geoarrow.linestring', 'geoarrow.multipoint'],
|
|
85
|
+
nesting: 1,
|
|
86
|
+
...coordinateInfo
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// A polygon or a multiline string are List<List<Coordinate>>
|
|
91
|
+
if (!(arrowField.type instanceof arrow.List)) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
arrowField = arrowField.type.children[0];
|
|
95
|
+
|
|
96
|
+
coordinateInfo = getCoordinateFieldInfo(arrowField);
|
|
97
|
+
if (coordinateInfo) {
|
|
98
|
+
return {
|
|
99
|
+
compatibleEncodings: ['geoarrow.polygon', 'geoarrow.multilinestring'],
|
|
100
|
+
nesting: 2,
|
|
101
|
+
...coordinateInfo
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// A multipolygons are List<List<List<Coordinate>>>
|
|
106
|
+
if (!(arrowField.type instanceof arrow.List)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
arrowField = arrowField.type.children[0];
|
|
110
|
+
|
|
111
|
+
coordinateInfo = getCoordinateFieldInfo(arrowField);
|
|
112
|
+
if (coordinateInfo) {
|
|
113
|
+
return {
|
|
114
|
+
compatibleEncodings: ['geoarrow.multipolygon'],
|
|
115
|
+
nesting: 3,
|
|
116
|
+
...coordinateInfo
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @see https://geoarrow.org/format.html#memory-layouts
|
|
125
|
+
*/
|
|
126
|
+
function getCoordinateFieldInfo(arrowField: arrow.Field): CoordinateFieldInfo | null {
|
|
127
|
+
// interleaved case
|
|
128
|
+
if (arrowField.type instanceof arrow.FixedSizeList) {
|
|
129
|
+
const dimension = arrowField.type.listSize;
|
|
130
|
+
if (dimension < 2 || dimension > 4) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const child = arrowField.type.children[0];
|
|
135
|
+
// Spec currently only supports 64 bit coordinates
|
|
136
|
+
if (!(child.type instanceof arrow.Float)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
coordinates: 'interleaved',
|
|
142
|
+
dimension: dimension as 2 | 3 | 4,
|
|
143
|
+
valueType: 'double'
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// separated case
|
|
148
|
+
if (arrowField.type instanceof arrow.Struct) {
|
|
149
|
+
const children = arrowField.type.children;
|
|
150
|
+
|
|
151
|
+
const dimension = children.length;
|
|
152
|
+
if (dimension < 2 || dimension > 4) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Spec currently only supports 64 bit coordinates
|
|
157
|
+
for (const child of children) {
|
|
158
|
+
if (!(child.type instanceof arrow.Float)) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
coordinates: 'separated',
|
|
165
|
+
dimension: dimension as 2 | 3 | 4,
|
|
166
|
+
valueType: 'double'
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// No other types are valid coordinates
|
|
171
|
+
return null;
|
|
172
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// MESH CATEGORY
|
|
6
|
+
|
|
7
|
+
export {getBoundingBoxFromArrowPositions} from './mesharrow/get-bounding-box';
|
|
8
|
+
export {getDeckBinaryDataFromArrowMesh} from './mesharrow/get-deck-binary-data';
|
|
9
|
+
|
|
10
|
+
// GIS CATEGORY - GEOARROW
|
|
11
|
+
export type {GeoArrowMetadata, GeoArrowEncoding} from './metadata/geoarrow-metadata';
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
GeoArrowWKB,
|
|
15
|
+
GeoArrowWKT,
|
|
16
|
+
GeoArrowCoordInterleaved,
|
|
17
|
+
GeoArrowCoordSeparated,
|
|
18
|
+
GeoArrowCoord,
|
|
19
|
+
GeoArrowPoint,
|
|
20
|
+
GeoArrowLineString,
|
|
21
|
+
GeoArrowPolygon,
|
|
22
|
+
GeoArrowMultiPoint,
|
|
23
|
+
GeoArrowMultiLineString,
|
|
24
|
+
GeoArrowMultiPolygon,
|
|
25
|
+
GeoArrowGeometry,
|
|
26
|
+
GeoArrowPointSeparated,
|
|
27
|
+
GeoArrowLineStringSeparated,
|
|
28
|
+
GeoArrowPolygonSeparated,
|
|
29
|
+
GeoArrowMultiPointSeparated,
|
|
30
|
+
GeoArrowMultiLineStringSeparated,
|
|
31
|
+
GeoArrowMultiPolygonSeparated,
|
|
32
|
+
GeoArrowGeometrySeparated
|
|
33
|
+
} from './geoarrow-types';
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
isGeoArrowPoint,
|
|
37
|
+
isGeoArrowLineString,
|
|
38
|
+
isGeoArrowPolygon,
|
|
39
|
+
isGeoArrowMultiPoint,
|
|
40
|
+
isGeoArrowMultiLineString,
|
|
41
|
+
isGeoArrowMultiPolygon,
|
|
42
|
+
isGeoArrowGeometry
|
|
43
|
+
} from './geoarrow-functions';
|
|
44
|
+
|
|
45
|
+
// GEOARROW / GEOPARQUET METADATA
|
|
46
|
+
export {getGeometryColumnsFromSchema} from './metadata/geoarrow-metadata';
|
|
47
|
+
|
|
48
|
+
export type {GeoColumnMetadata} from './metadata/geoparquet-metadata';
|
|
49
|
+
export {
|
|
50
|
+
getGeoMetadata,
|
|
51
|
+
unpackGeoMetadata,
|
|
52
|
+
unpackJSONStringMetadata
|
|
53
|
+
} from './metadata/geoparquet-metadata';
|
|
54
|
+
|
|
55
|
+
export {getGeoArrowGeometryInfo} from './get-geoarrow-geometry-info';
|
|
56
|
+
|
|
57
|
+
export {updateBoundsFromGeoArrowSamples} from './get-arrow-bounds';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {TypedArray} from '@math.gl/types';
|
|
6
|
+
import * as arrow from 'apache-arrow';
|
|
7
|
+
import {getDataTypeFromArray, deserializeArrowType} from '@loaders.gl/schema-utils';
|
|
8
|
+
|
|
9
|
+
export function isFixedSizeList(vector: arrow.Vector): vector is arrow.Vector<arrow.FixedSizeList> {
|
|
10
|
+
return vector.type instanceof arrow.FixedSizeList;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getFixedSizeListSize(vector: arrow.Vector): number {
|
|
14
|
+
return vector.type instanceof arrow.FixedSizeList ? vector.type.listSize : 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
18
|
+
export function getFixedSizeListVector(
|
|
19
|
+
typedArray: TypedArray,
|
|
20
|
+
stride: number
|
|
21
|
+
): arrow.Vector<arrow.FixedSizeList> {
|
|
22
|
+
const data = getFixedSizeListData(typedArray, stride);
|
|
23
|
+
return new arrow.Vector<arrow.FixedSizeList>([data]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
27
|
+
export function getFixedSizeListData(
|
|
28
|
+
typedArray: TypedArray,
|
|
29
|
+
stride: number
|
|
30
|
+
): arrow.Data<arrow.FixedSizeList> {
|
|
31
|
+
const listType = getFixedSizeListType(typedArray, stride);
|
|
32
|
+
const nestedType = listType.children[0].type;
|
|
33
|
+
const buffers: Partial<Record<arrow.BufferType, any>> = {
|
|
34
|
+
// valueOffsets: undefined,
|
|
35
|
+
[arrow.BufferType.DATA]: typedArray // values
|
|
36
|
+
// nullBitmap: undefined,
|
|
37
|
+
// typeIds: undefined
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Note: The contiguous array of data is held by the nested "primitive type" column
|
|
41
|
+
const nestedData = new arrow.Data(nestedType, 0, typedArray.length, 0, buffers);
|
|
42
|
+
|
|
43
|
+
// Wrapped in a FixedSizeList column that provides a "strided" view of the data
|
|
44
|
+
const data = new arrow.Data<arrow.FixedSizeList>(
|
|
45
|
+
listType,
|
|
46
|
+
0,
|
|
47
|
+
typedArray.length / stride,
|
|
48
|
+
0,
|
|
49
|
+
undefined,
|
|
50
|
+
[nestedData]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
57
|
+
export function getFixedSizeListType(typedArray: TypedArray, stride: number): arrow.FixedSizeList {
|
|
58
|
+
const {type} = getDataTypeFromArray(typedArray);
|
|
59
|
+
const arrowType = deserializeArrowType(type);
|
|
60
|
+
const listType = new arrow.FixedSizeList(stride, new arrow.Field('value', arrowType));
|
|
61
|
+
return listType;
|
|
62
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {TypedArray} from '@math.gl/types';
|
|
6
|
+
import * as arrow from 'apache-arrow';
|
|
7
|
+
import {getDataTypeFromArray, deserializeArrowType} from '@loaders.gl/schema-utils';
|
|
8
|
+
|
|
9
|
+
export function isListFixedSizeList(
|
|
10
|
+
vector: arrow.Vector
|
|
11
|
+
): vector is arrow.Vector<arrow.FixedSizeList> {
|
|
12
|
+
return vector.type instanceof arrow.FixedSizeList;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getListFixedSizeListSize(vector: arrow.Vector): number {
|
|
16
|
+
return vector.type instanceof arrow.FixedSizeList ? vector.type.listSize : 1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
20
|
+
export function getListFixedSizeListVector(
|
|
21
|
+
indexes: Uint32Array,
|
|
22
|
+
typedArray: TypedArray,
|
|
23
|
+
stride: number
|
|
24
|
+
): arrow.Vector<arrow.FixedSizeList> {
|
|
25
|
+
const data = getFixedSizeListData(typedArray, stride);
|
|
26
|
+
return new arrow.Vector<arrow.FixedSizeList>([data]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
30
|
+
export function getFixedSizeListData(
|
|
31
|
+
typedArray: TypedArray,
|
|
32
|
+
stride: number
|
|
33
|
+
): arrow.Data<arrow.FixedSizeList> {
|
|
34
|
+
const listType = getFixedSizeListType(typedArray, stride);
|
|
35
|
+
const data = new arrow.Data<arrow.FixedSizeList>(listType, 0, typedArray.length / stride, 0, [
|
|
36
|
+
typedArray
|
|
37
|
+
]);
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Get Arrow FixedSizeList vector from a typed array */
|
|
42
|
+
export function getFixedSizeListType(typedArray: TypedArray, stride: number): arrow.FixedSizeList {
|
|
43
|
+
const {type} = getDataTypeFromArray(typedArray);
|
|
44
|
+
const arrowType = deserializeArrowType(type);
|
|
45
|
+
const listType = new arrow.FixedSizeList(stride, new arrow.Field('value', arrowType));
|
|
46
|
+
return listType;
|
|
47
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import * as arrow from 'apache-arrow';
|
|
6
|
+
|
|
7
|
+
export type BoundingBox = [[number, number, number], [number, number, number]];
|
|
8
|
+
|
|
9
|
+
/** basic helper method to calculate a models upper and lower bounds */
|
|
10
|
+
export function getBoundingBoxFromArrowPositions(
|
|
11
|
+
column: arrow.Vector<arrow.FixedSizeList>
|
|
12
|
+
): BoundingBox {
|
|
13
|
+
const mins: [number, number, number] = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
|
|
14
|
+
const maxs: [number, number, number] = [Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE];
|
|
15
|
+
|
|
16
|
+
const valueColumn = column.getChildAt(0)!;
|
|
17
|
+
for (const data of valueColumn.data) {
|
|
18
|
+
const pointSize = 3; // attributes.POSITION.size;
|
|
19
|
+
const pointData = data.buffers[arrow.BufferType.DATA];
|
|
20
|
+
const pointCount = pointData.length / pointSize;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < pointCount; i += pointSize) {
|
|
23
|
+
const x = pointData[i];
|
|
24
|
+
const y = pointData[i + 1];
|
|
25
|
+
const z = pointData[i + 2];
|
|
26
|
+
|
|
27
|
+
if (x < mins[0]) mins[0] = x;
|
|
28
|
+
else if (x > maxs[0]) maxs[0] = x;
|
|
29
|
+
|
|
30
|
+
if (y < mins[1]) mins[1] = y;
|
|
31
|
+
else if (y > maxs[1]) maxs[1] = y;
|
|
32
|
+
|
|
33
|
+
if (z < mins[2]) mins[2] = z;
|
|
34
|
+
else if (z > maxs[2]) maxs[2] = z;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return [mins, maxs];
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {TypedArray} from '@math.gl/types';
|
|
6
|
+
import {getSizeAndValueFromMeshArrowVector} from './mesh-accessors';
|
|
7
|
+
import * as arrow from 'apache-arrow';
|
|
8
|
+
|
|
9
|
+
/** */
|
|
10
|
+
export type DeckBinaryData = {
|
|
11
|
+
length: number;
|
|
12
|
+
attributes: Record<
|
|
13
|
+
string,
|
|
14
|
+
{
|
|
15
|
+
value: TypedArray;
|
|
16
|
+
size: number;
|
|
17
|
+
}
|
|
18
|
+
>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** */
|
|
22
|
+
export function getDeckBinaryDataFromArrowMesh(table: arrow.Table): DeckBinaryData {
|
|
23
|
+
const positionVector = table.getChild('POSITION');
|
|
24
|
+
if (!positionVector) {
|
|
25
|
+
throw new Error('POSITION attribute not found');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const getPosition = getSizeAndValueFromMeshArrowVector(positionVector);
|
|
29
|
+
|
|
30
|
+
const deckAttributes: DeckBinaryData['attributes'] = {
|
|
31
|
+
getPosition
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const colorVector = table.getChild('COLOR_0');
|
|
35
|
+
if (colorVector) {
|
|
36
|
+
deckAttributes.getColor = getSizeAndValueFromMeshArrowVector(colorVector);
|
|
37
|
+
}
|
|
38
|
+
// Check PointCloudLayer docs for other supported props?
|
|
39
|
+
return {
|
|
40
|
+
length: table.numRows,
|
|
41
|
+
attributes: deckAttributes
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {TypedArray} from '@math.gl/types';
|
|
6
|
+
import {getFixedSizeListSize} from './arrow-fixed-size-list-utils';
|
|
7
|
+
import * as arrow from 'apache-arrow';
|
|
8
|
+
|
|
9
|
+
export function getSizeAndValueFromMeshArrowVector(attributeVector: arrow.Vector): {
|
|
10
|
+
size: number;
|
|
11
|
+
value: TypedArray;
|
|
12
|
+
} {
|
|
13
|
+
const size = getFixedSizeListSize(attributeVector);
|
|
14
|
+
const typedArrays = getTypedArraysFromMeshArrowVector(attributeVector);
|
|
15
|
+
return {size, value: typedArrays[0]};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getTypedArraysFromMeshArrowVector(attributeVector: arrow.Vector): TypedArray[] {
|
|
19
|
+
const typedArrays: TypedArray[] = [];
|
|
20
|
+
for (const attributeData of attributeVector.data) {
|
|
21
|
+
const valueData = attributeData?.children[0];
|
|
22
|
+
const typedArray = valueData.values;
|
|
23
|
+
typedArrays.push(typedArray);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return typedArrays;
|
|
27
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Metadata, SchemaWithMetadata, getMetadataValue} from './metadata-utils';
|
|
6
|
+
|
|
7
|
+
export type GeoArrowEncoding =
|
|
8
|
+
| 'geoarrow.multipolygon'
|
|
9
|
+
| 'geoarrow.polygon'
|
|
10
|
+
| 'geoarrow.multilinestring'
|
|
11
|
+
| 'geoarrow.linestring'
|
|
12
|
+
| 'geoarrow.multipoint'
|
|
13
|
+
| 'geoarrow.point'
|
|
14
|
+
| 'geoarrow.wkb'
|
|
15
|
+
| 'geoarrow.wkt';
|
|
16
|
+
|
|
17
|
+
/** Array containing all encodings */
|
|
18
|
+
const GEOARROW_ENCODINGS = [
|
|
19
|
+
'geoarrow.multipolygon',
|
|
20
|
+
'geoarrow.polygon',
|
|
21
|
+
'geoarrow.multilinestring',
|
|
22
|
+
'geoarrow.linestring',
|
|
23
|
+
'geoarrow.multipoint',
|
|
24
|
+
'geoarrow.point',
|
|
25
|
+
'geoarrow.wkb',
|
|
26
|
+
'geoarrow.wkt'
|
|
27
|
+
] as const satisfies GeoArrowEncoding[];
|
|
28
|
+
|
|
29
|
+
const GEOARROW_ENCODING = 'ARROW:extension:name';
|
|
30
|
+
const GEOARROW_METADATA = 'ARROW:extension:metadata';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Geospatial metadata for one column, extracted from Apache Arrow metadata
|
|
34
|
+
* @see https://github.com/geoarrow/geoarrow/blob/main/extension-types.md
|
|
35
|
+
*/
|
|
36
|
+
export type GeoArrowMetadata = {
|
|
37
|
+
/** Encoding of geometry in this column */
|
|
38
|
+
encoding?: GeoArrowEncoding;
|
|
39
|
+
/** CRS in [PROJJSON](https://proj.org/specifications/projjson.html). Omitted if producer has no information about CRS */
|
|
40
|
+
crs?: Record<string, unknown>;
|
|
41
|
+
/** Edges are either spherical or omitted */
|
|
42
|
+
edges?: 'spherical';
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* get geometry columns from arrow table
|
|
48
|
+
*/
|
|
49
|
+
export function getGeometryColumnsFromSchema(
|
|
50
|
+
schema: SchemaWithMetadata
|
|
51
|
+
): Record<string, GeoArrowMetadata> {
|
|
52
|
+
const geometryColumns: Record<string, GeoArrowMetadata> = {};
|
|
53
|
+
for (const field of schema.fields || []) {
|
|
54
|
+
const metadata = getGeometryMetadataForField(field?.metadata || {});
|
|
55
|
+
if (metadata) {
|
|
56
|
+
geometryColumns[field.name] = metadata;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return geometryColumns;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extracts GeoArrow metadata from a field
|
|
63
|
+
* @param field
|
|
64
|
+
* @returns
|
|
65
|
+
* @see https://github.com/geoarrow/geoarrow/blob/d2f56704414d9ae71e8a5170a8671343ed15eefe/extension-types.md
|
|
66
|
+
*/
|
|
67
|
+
export function getGeometryMetadataForField(fieldMetadata: Metadata): GeoArrowMetadata | null {
|
|
68
|
+
let metadata: GeoArrowMetadata | null = null;
|
|
69
|
+
|
|
70
|
+
// Check for GeoArrow column encoding
|
|
71
|
+
let geoEncoding = getMetadataValue(fieldMetadata, GEOARROW_ENCODING);
|
|
72
|
+
if (geoEncoding) {
|
|
73
|
+
geoEncoding = geoEncoding.toLowerCase();
|
|
74
|
+
// at time of testing, ogr2ogr uses WKB/WKT for encoding.
|
|
75
|
+
if (geoEncoding === 'wkb') {
|
|
76
|
+
geoEncoding = 'geoarrow.wkb';
|
|
77
|
+
}
|
|
78
|
+
if (geoEncoding === 'wkt') {
|
|
79
|
+
geoEncoding = 'geoarrow.wkt';
|
|
80
|
+
}
|
|
81
|
+
if (!GEOARROW_ENCODINGS.includes(geoEncoding as GeoArrowEncoding)) {
|
|
82
|
+
// eslint-disable-next-line no-console
|
|
83
|
+
console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`);
|
|
84
|
+
} else {
|
|
85
|
+
metadata ||= {} as GeoArrowMetadata;
|
|
86
|
+
metadata.encoding = geoEncoding as GeoArrowEncoding;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Check for GeoArrow metadata
|
|
91
|
+
const columnMetadata = getMetadataValue(fieldMetadata, GEOARROW_METADATA);
|
|
92
|
+
if (columnMetadata) {
|
|
93
|
+
try {
|
|
94
|
+
metadata = JSON.parse(columnMetadata);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.warn('Failed to parse GeoArrow metadata', error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return metadata || null;
|
|
102
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/* eslint-disable camelcase */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Geoparquet JSON schema for geo metadata
|
|
9
|
+
* @see https://github.com/geoarrow/geoarrow/blob/main/metadata.md
|
|
10
|
+
* @see https://github.com/opengeospatial/geoparquet/blob/main/format-specs/geoparquet.md
|
|
11
|
+
*/
|
|
12
|
+
export const GEOPARQUET_METADATA_JSON_SCHEMA = {
|
|
13
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
14
|
+
title: 'GeoParquet',
|
|
15
|
+
description: 'Parquet metadata included in the geo field.',
|
|
16
|
+
type: 'object',
|
|
17
|
+
required: ['version', 'primary_column', 'columns'],
|
|
18
|
+
properties: {
|
|
19
|
+
version: {type: 'string', const: '1.0.0-beta.1'},
|
|
20
|
+
primary_column: {type: 'string', minLength: 1},
|
|
21
|
+
columns: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
minProperties: 1,
|
|
24
|
+
patternProperties: {
|
|
25
|
+
'.+': {
|
|
26
|
+
type: 'object',
|
|
27
|
+
required: ['encoding', 'geometry_types'],
|
|
28
|
+
properties: {
|
|
29
|
+
encoding: {type: 'string', const: 'WKB'},
|
|
30
|
+
geometry_types: {
|
|
31
|
+
type: 'array',
|
|
32
|
+
uniqueItems: true,
|
|
33
|
+
items: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
pattern: '^(GeometryCollection|(Multi)?(Point|LineString|Polygon))( Z)?$'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
crs: {
|
|
39
|
+
oneOf: [
|
|
40
|
+
{
|
|
41
|
+
$ref: 'https://proj.org/schemas/v0.5/projjson.schema.json'
|
|
42
|
+
},
|
|
43
|
+
{type: 'null'}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
edges: {type: 'string', enum: ['planar', 'spherical']},
|
|
47
|
+
orientation: {type: 'string', const: 'counterclockwise'},
|
|
48
|
+
bbox: {
|
|
49
|
+
type: 'array',
|
|
50
|
+
items: {type: 'number'},
|
|
51
|
+
oneOf: [
|
|
52
|
+
{
|
|
53
|
+
description: '2D bbox consisting of (xmin, ymin, xmax, ymax)',
|
|
54
|
+
minItems: 4,
|
|
55
|
+
maxItems: 4
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
description: '3D bbox consisting of (xmin, ymin, zmin, xmax, ymax, zmax)',
|
|
59
|
+
minItems: 6,
|
|
60
|
+
maxItems: 6
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
epoch: {type: 'number'}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
additionalProperties: false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|