@loaders.gl/gis 4.3.4 → 4.4.0-alpha.10
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/dist/index.cjs +2411 -469
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +31 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -15
- package/dist/index.js.map +1 -0
- package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts +21 -0
- package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts.map +1 -0
- package/dist/lib/binary-geometry-api/binary-geometry-info.js +49 -0
- package/dist/lib/binary-geometry-api/binary-geometry-info.js.map +1 -0
- package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts +5 -0
- package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts.map +1 -0
- package/dist/lib/binary-geometry-api/concat-binary-geometry.js +51 -0
- package/dist/lib/binary-geometry-api/concat-binary-geometry.js.map +1 -0
- package/dist/lib/{binary-features/transform.d.ts → binary-geometry-api/transform-coordinates.d.ts} +1 -2
- package/dist/lib/binary-geometry-api/transform-coordinates.d.ts.map +1 -0
- package/dist/lib/{binary-features/transform.js → binary-geometry-api/transform-coordinates.js} +1 -1
- package/dist/lib/binary-geometry-api/transform-coordinates.js.map +1 -0
- package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts +16 -0
- package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts.map +1 -0
- package/dist/lib/{binary-features/binary-to-geojson.js → feature-collection-converters/convert-binary-features-to-geojson.js} +4 -90
- package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.js.map +1 -0
- package/dist/lib/{binary-features/flat-geojson-to-binary.d.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts} +6 -9
- package/dist/lib/feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts.map +1 -0
- package/dist/lib/{binary-features/flat-geojson-to-binary.js → feature-collection-converters/convert-flat-geojson-to-binary-features.js} +6 -5
- package/dist/lib/feature-collection-converters/convert-flat-geojson-to-binary-features.js.map +1 -0
- package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts +74 -0
- package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts.map +1 -0
- package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.js +378 -0
- package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.js.map +1 -0
- package/dist/lib/{binary-features/geojson-to-binary.d.ts → feature-collection-converters/convert-geojson-to-binary-features.d.ts} +2 -2
- package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.d.ts.map +1 -0
- package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.js +25 -0
- package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.js.map +1 -0
- package/dist/lib/{binary-features/geojson-to-flat-geojson.d.ts → feature-collection-converters/convert-geojson-to-flat-geojson.d.ts} +2 -2
- package/dist/lib/feature-collection-converters/convert-geojson-to-flat-geojson.d.ts.map +1 -0
- package/dist/lib/{binary-features/geojson-to-flat-geojson.js → feature-collection-converters/convert-geojson-to-flat-geojson.js} +5 -1
- package/dist/lib/feature-collection-converters/convert-geojson-to-flat-geojson.js.map +1 -0
- package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.d.ts.map +1 -0
- package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.js +5 -0
- package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.js.map +1 -0
- package/dist/lib/geometry-api/geometry-info.d.ts +21 -0
- package/dist/lib/geometry-api/geometry-info.d.ts.map +1 -0
- package/dist/lib/{binary-features/extract-geometry-info.js → geometry-api/geometry-info.js} +5 -1
- package/dist/lib/geometry-api/geometry-info.js.map +1 -0
- package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts +4 -0
- package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts.map +1 -0
- package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.js +92 -0
- package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.js.map +1 -0
- package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts +13 -0
- package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts.map +1 -0
- package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.js +165 -0
- package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.js.map +1 -0
- package/dist/lib/geometry-converters/convert-to-geojson.d.ts +6 -0
- package/dist/lib/geometry-converters/convert-to-geojson.d.ts.map +1 -0
- package/dist/lib/geometry-converters/convert-to-geojson.js +40 -0
- package/dist/lib/geometry-converters/convert-to-geojson.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts +6 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.js +196 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts +9 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.js +274 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts +8 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.js +45 -0
- package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts +10 -0
- package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.js +255 -0
- package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts +3 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.js +165 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts +11 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.js +10 -0
- package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts +16 -0
- package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.js +259 -0
- package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts +43 -0
- package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.js +175 -0
- package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts +64 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-types.js +47 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-types.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts +21 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.js +65 -0
- package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.js.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts +8 -0
- package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts.map +1 -0
- package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.js +34 -0
- package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.js.map +1 -0
- package/dist/lib/table-converters/convert-geoarrow-table.d.ts +27 -0
- package/dist/lib/table-converters/convert-geoarrow-table.d.ts.map +1 -0
- package/dist/lib/table-converters/convert-geoarrow-table.js +155 -0
- package/dist/lib/table-converters/convert-geoarrow-table.js.map +1 -0
- package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts +4 -0
- package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts.map +1 -0
- package/dist/lib/{tables/convert-table-to-geojson.js → table-converters/convert-wkb-table-to-geojson.js} +11 -16
- package/dist/lib/table-converters/convert-wkb-table-to-geojson.js.map +1 -0
- package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts +6 -0
- package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts.map +1 -0
- package/dist/lib/table-converters/make-arrow-batch-iterator.js +36 -0
- package/dist/lib/table-converters/make-arrow-batch-iterator.js.map +1 -0
- package/dist/lib/utils/base64-encoder.d.ts +5 -0
- package/dist/lib/utils/base64-encoder.d.ts.map +1 -0
- package/dist/lib/utils/base64-encoder.js +154 -0
- package/dist/lib/utils/base64-encoder.js.map +1 -0
- package/dist/lib/utils/binary-reader.d.ts +18 -0
- package/dist/lib/utils/binary-reader.d.ts.map +1 -0
- package/dist/lib/utils/binary-reader.js +70 -0
- package/dist/lib/utils/binary-reader.js.map +1 -0
- package/dist/lib/utils/binary-writer.d.ts +30 -0
- package/dist/lib/utils/binary-writer.d.ts.map +1 -0
- package/dist/lib/utils/binary-writer.js +128 -0
- package/dist/lib/utils/binary-writer.js.map +1 -0
- package/dist/lib/utils/concat-typed-arrays.d.ts +3 -0
- package/dist/lib/utils/concat-typed-arrays.d.ts.map +1 -0
- package/dist/lib/utils/concat-typed-arrays.js +19 -0
- package/dist/lib/utils/concat-typed-arrays.js.map +1 -0
- package/dist/lib/utils/hex-encoder.d.ts +15 -0
- package/dist/lib/utils/hex-encoder.d.ts.map +1 -0
- package/dist/lib/utils/hex-encoder.js +55 -0
- package/dist/lib/utils/hex-encoder.js.map +1 -0
- package/dist/lib/utils/hex-transcoder.d.ts +15 -0
- package/dist/lib/utils/hex-transcoder.d.ts.map +1 -0
- package/dist/lib/utils/hex-transcoder.js +51 -0
- package/dist/lib/utils/hex-transcoder.js.map +1 -0
- package/dist/lib/wkt-crs/encode-wkt-crs.d.ts +10 -0
- package/dist/lib/wkt-crs/encode-wkt-crs.d.ts.map +1 -0
- package/dist/lib/wkt-crs/encode-wkt-crs.js +36 -0
- package/dist/lib/wkt-crs/encode-wkt-crs.js.map +1 -0
- package/dist/lib/wkt-crs/parse-wkt-crs.d.ts +15 -0
- package/dist/lib/wkt-crs/parse-wkt-crs.d.ts.map +1 -0
- package/dist/lib/wkt-crs/parse-wkt-crs.js +121 -0
- package/dist/lib/wkt-crs/parse-wkt-crs.js.map +1 -0
- package/package.json +7 -5
- package/src/index.ts +87 -14
- package/src/lib/binary-geometry-api/binary-geometry-info.ts +75 -0
- package/src/lib/binary-geometry-api/concat-binary-geometry.ts +78 -0
- package/src/lib/{binary-features/transform.ts → binary-geometry-api/transform-coordinates.ts} +0 -1
- package/src/lib/{binary-features/binary-to-geojson.ts → feature-collection-converters/convert-binary-features-to-geojson.ts} +5 -142
- package/src/lib/{binary-features/flat-geojson-to-binary.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.ts} +14 -9
- package/src/lib/feature-collection-converters/convert-geoarrow-to-binary-features.ts +496 -0
- package/src/lib/{binary-features/geojson-to-binary.ts → feature-collection-converters/convert-geojson-to-binary-features.ts} +11 -7
- package/src/lib/{binary-features/geojson-to-flat-geojson.ts → feature-collection-converters/convert-geojson-to-flat-geojson.ts} +5 -1
- package/src/lib/{binary-features → feature-collection-converters/helpers}/flat-geojson-to-binary-types.ts +4 -0
- package/src/lib/{binary-features/extract-geometry-info.ts → geometry-api/geometry-info.ts} +20 -2
- package/src/lib/geometry-converters/convert-binary-geometry-to-geojson.ts +148 -0
- package/src/lib/geometry-converters/convert-geoarrow-to-geojson.ts +193 -0
- package/src/lib/geometry-converters/convert-to-geojson.ts +52 -0
- package/src/lib/geometry-converters/wkb/convert-geometry-to-twkb.ts +308 -0
- package/src/lib/geometry-converters/wkb/convert-geometry-to-wkb.ts +365 -0
- package/src/lib/geometry-converters/wkb/convert-geometry-to-wkt.ts +54 -0
- package/src/lib/geometry-converters/wkb/convert-twkb-to-geometry.ts +366 -0
- package/src/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.ts +238 -0
- package/src/lib/geometry-converters/wkb/convert-wkb-to-geometry.ts +23 -0
- package/src/lib/geometry-converters/wkb/convert-wkt-to-geometry.ts +294 -0
- package/src/lib/geometry-converters/wkb/helpers/parse-wkb-header.ts +213 -0
- package/src/lib/geometry-converters/wkb/helpers/wkb-types.ts +82 -0
- package/src/lib/geometry-converters/wkb/helpers/wkb-utils.ts +85 -0
- package/src/lib/geometry-converters/wkb/helpers/write-wkb-header.ts +41 -0
- package/src/lib/table-converters/convert-geoarrow-table.ts +218 -0
- package/src/lib/{tables/convert-table-to-geojson.ts → table-converters/convert-wkb-table-to-geojson.ts} +10 -23
- package/src/lib/table-converters/make-arrow-batch-iterator.ts +53 -0
- package/src/lib/utils/base64-encoder.ts +157 -0
- package/src/lib/utils/binary-reader.ts +76 -0
- package/src/lib/utils/binary-writer.ts +136 -0
- package/src/lib/utils/concat-typed-arrays.ts +24 -0
- package/src/lib/utils/hex-encoder.ts +60 -0
- package/src/lib/utils/hex-transcoder.ts +54 -0
- package/src/lib/wkt-crs/encode-wkt-crs.ts +41 -0
- package/src/lib/wkt-crs/parse-wkt-crs.ts +149 -0
- package/dist/lib/binary-features/binary-to-geojson.d.ts +0 -18
- package/dist/lib/binary-features/binary-to-geojson.d.ts.map +0 -1
- package/dist/lib/binary-features/extract-geometry-info.d.ts +0 -8
- package/dist/lib/binary-features/extract-geometry-info.d.ts.map +0 -1
- package/dist/lib/binary-features/flat-geojson-to-binary-types.d.ts.map +0 -1
- package/dist/lib/binary-features/flat-geojson-to-binary-types.js +0 -1
- package/dist/lib/binary-features/flat-geojson-to-binary.d.ts.map +0 -1
- package/dist/lib/binary-features/geojson-to-binary.d.ts.map +0 -1
- package/dist/lib/binary-features/geojson-to-binary.js +0 -21
- package/dist/lib/binary-features/geojson-to-flat-geojson.d.ts.map +0 -1
- package/dist/lib/binary-features/transform.d.ts.map +0 -1
- package/dist/lib/geo/geoarrow-metadata.d.ts +0 -27
- package/dist/lib/geo/geoarrow-metadata.d.ts.map +0 -1
- package/dist/lib/geo/geoarrow-metadata.js +0 -70
- package/dist/lib/geo/geoparquet-metadata-schema.d.ts +0 -79
- package/dist/lib/geo/geoparquet-metadata-schema.d.ts.map +0 -1
- package/dist/lib/geo/geoparquet-metadata-schema.js +0 -69
- package/dist/lib/geo/geoparquet-metadata.d.ts +0 -45
- package/dist/lib/geo/geoparquet-metadata.d.ts.map +0 -1
- package/dist/lib/geo/geoparquet-metadata.js +0 -117
- package/dist/lib/tables/convert-table-to-geojson.d.ts +0 -5
- package/dist/lib/tables/convert-table-to-geojson.d.ts.map +0 -1
- package/src/lib/geo/geoarrow-metadata.ts +0 -100
- package/src/lib/geo/geoparquet-metadata-schema.json +0 -60
- package/src/lib/geo/geoparquet-metadata-schema.ts +0 -71
- package/src/lib/geo/geoparquet-metadata.ts +0 -191
- /package/dist/lib/{binary-features → feature-collection-converters/helpers}/flat-geojson-to-binary-types.d.ts +0 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
// Forked from https://github.com/cschwarz/wkx under MIT license, Copyright (c) 2013 Christian Schwarz
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
Geometry,
|
|
8
|
+
GeometryCollection,
|
|
9
|
+
Point,
|
|
10
|
+
LineString,
|
|
11
|
+
Polygon,
|
|
12
|
+
MultiPoint,
|
|
13
|
+
MultiLineString,
|
|
14
|
+
MultiPolygon
|
|
15
|
+
} from '@loaders.gl/schema';
|
|
16
|
+
import {BinaryReader} from '../../utils/binary-reader';
|
|
17
|
+
import {WKBGeometryType} from './helpers/wkb-types';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check if an array buffer might be a TWKB array buffer
|
|
21
|
+
* @param arrayBuffer The array buffer to check
|
|
22
|
+
* @returns false if this is definitely not a TWKB array buffer, true if it might be a TWKB array buffer
|
|
23
|
+
*/
|
|
24
|
+
export function isTWKB(arrayBuffer: ArrayBuffer): boolean {
|
|
25
|
+
const binaryReader = new BinaryReader(arrayBuffer);
|
|
26
|
+
|
|
27
|
+
const type = binaryReader.readUInt8();
|
|
28
|
+
const geometryType = type & 0x0f;
|
|
29
|
+
|
|
30
|
+
// Only geometry types 1 to 7 (point to geometry collection are currently defined)
|
|
31
|
+
if (geometryType < 1 || geometryType > 7) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Passed around between parsing functions, extracted from the header */
|
|
39
|
+
type TWKBHeader = {
|
|
40
|
+
geometryType: WKBGeometryType;
|
|
41
|
+
|
|
42
|
+
hasBoundingBox: boolean;
|
|
43
|
+
hasSizeAttribute: boolean;
|
|
44
|
+
hasIdList: boolean;
|
|
45
|
+
hasExtendedPrecision: boolean;
|
|
46
|
+
isEmpty: boolean;
|
|
47
|
+
|
|
48
|
+
precision: number;
|
|
49
|
+
precisionFactor: number;
|
|
50
|
+
|
|
51
|
+
hasZ: boolean;
|
|
52
|
+
zPrecision: number;
|
|
53
|
+
zPrecisionFactor: number;
|
|
54
|
+
|
|
55
|
+
hasM: boolean;
|
|
56
|
+
mPrecision: number;
|
|
57
|
+
mPrecisionFactor: number;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** Converts a TWKB encoded buffer to a GeoJSON Geometry */
|
|
61
|
+
export function convertTWKBToGeometry(arrayBuffer: ArrayBuffer): Geometry {
|
|
62
|
+
const binaryReader = new BinaryReader(arrayBuffer);
|
|
63
|
+
|
|
64
|
+
const context = parseTWKBHeader(binaryReader);
|
|
65
|
+
|
|
66
|
+
if (context.hasSizeAttribute) {
|
|
67
|
+
binaryReader.readVarInt();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (context.hasBoundingBox) {
|
|
71
|
+
let dimensions = 2;
|
|
72
|
+
|
|
73
|
+
if (context.hasZ) {
|
|
74
|
+
dimensions++;
|
|
75
|
+
}
|
|
76
|
+
if (context.hasM) {
|
|
77
|
+
dimensions++;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// TODO why are we throwing away these datums?
|
|
81
|
+
for (let i = 0; i < dimensions; i++) {
|
|
82
|
+
binaryReader.readVarInt();
|
|
83
|
+
binaryReader.readVarInt();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return parseGeometry(binaryReader, context, context.geometryType);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function parseTWKBHeader(binaryReader: BinaryReader): TWKBHeader {
|
|
91
|
+
const type = binaryReader.readUInt8();
|
|
92
|
+
const metadataHeader = binaryReader.readUInt8();
|
|
93
|
+
|
|
94
|
+
const geometryType = type & 0x0f;
|
|
95
|
+
|
|
96
|
+
const precision = zigZagDecode(type >> 4);
|
|
97
|
+
|
|
98
|
+
const hasExtendedPrecision = Boolean((metadataHeader >> 3) & 1);
|
|
99
|
+
let hasZ = false;
|
|
100
|
+
let hasM = false;
|
|
101
|
+
let zPrecision = 0;
|
|
102
|
+
let zPrecisionFactor = 1;
|
|
103
|
+
let mPrecision = 0;
|
|
104
|
+
let mPrecisionFactor = 1;
|
|
105
|
+
|
|
106
|
+
if (hasExtendedPrecision) {
|
|
107
|
+
const extendedPrecision = binaryReader.readUInt8();
|
|
108
|
+
hasZ = (extendedPrecision & 0x01) === 0x01;
|
|
109
|
+
hasM = (extendedPrecision & 0x02) === 0x02;
|
|
110
|
+
|
|
111
|
+
zPrecision = zigZagDecode((extendedPrecision & 0x1c) >> 2);
|
|
112
|
+
zPrecisionFactor = Math.pow(10, zPrecision);
|
|
113
|
+
|
|
114
|
+
mPrecision = zigZagDecode((extendedPrecision & 0xe0) >> 5);
|
|
115
|
+
mPrecisionFactor = Math.pow(10, mPrecision);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
geometryType,
|
|
120
|
+
|
|
121
|
+
precision,
|
|
122
|
+
precisionFactor: Math.pow(10, precision),
|
|
123
|
+
|
|
124
|
+
hasBoundingBox: Boolean((metadataHeader >> 0) & 1),
|
|
125
|
+
hasSizeAttribute: Boolean((metadataHeader >> 1) & 1),
|
|
126
|
+
hasIdList: Boolean((metadataHeader >> 2) & 1),
|
|
127
|
+
hasExtendedPrecision,
|
|
128
|
+
isEmpty: Boolean((metadataHeader >> 4) & 1),
|
|
129
|
+
|
|
130
|
+
hasZ,
|
|
131
|
+
hasM,
|
|
132
|
+
zPrecision,
|
|
133
|
+
zPrecisionFactor,
|
|
134
|
+
mPrecision,
|
|
135
|
+
mPrecisionFactor
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function parseGeometry(
|
|
140
|
+
binaryReader: BinaryReader,
|
|
141
|
+
context: TWKBHeader,
|
|
142
|
+
geometryType: WKBGeometryType
|
|
143
|
+
): Geometry {
|
|
144
|
+
switch (geometryType) {
|
|
145
|
+
case WKBGeometryType.Point:
|
|
146
|
+
return parsePoint(binaryReader, context);
|
|
147
|
+
case WKBGeometryType.LineString:
|
|
148
|
+
return parseLineString(binaryReader, context);
|
|
149
|
+
case WKBGeometryType.Polygon:
|
|
150
|
+
return parsePolygon(binaryReader, context);
|
|
151
|
+
case WKBGeometryType.MultiPoint:
|
|
152
|
+
return parseMultiPoint(binaryReader, context);
|
|
153
|
+
case WKBGeometryType.MultiLineString:
|
|
154
|
+
return parseMultiLineString(binaryReader, context);
|
|
155
|
+
case WKBGeometryType.MultiPolygon:
|
|
156
|
+
return parseMultiPolygon(binaryReader, context);
|
|
157
|
+
case WKBGeometryType.GeometryCollection:
|
|
158
|
+
return parseGeometryCollection(binaryReader, context);
|
|
159
|
+
default:
|
|
160
|
+
throw new Error(`GeometryType ${geometryType} not supported`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// GEOMETRIES
|
|
165
|
+
|
|
166
|
+
function parsePoint(reader: BinaryReader, context: TWKBHeader): Point {
|
|
167
|
+
if (context.isEmpty) {
|
|
168
|
+
return {type: 'Point', coordinates: []};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {type: 'Point', coordinates: readFirstPoint(reader, context)};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function parseLineString(reader: BinaryReader, context: TWKBHeader): LineString {
|
|
175
|
+
if (context.isEmpty) {
|
|
176
|
+
return {type: 'LineString', coordinates: []};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const pointCount = reader.readVarInt();
|
|
180
|
+
|
|
181
|
+
const previousPoint = makePreviousPoint(context);
|
|
182
|
+
|
|
183
|
+
const points: number[][] = [];
|
|
184
|
+
for (let i = 0; i < pointCount; i++) {
|
|
185
|
+
points.push(parseNextPoint(reader, context, previousPoint));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return {type: 'LineString', coordinates: points};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function parsePolygon(reader: BinaryReader, context: TWKBHeader): Polygon {
|
|
192
|
+
if (context.isEmpty) {
|
|
193
|
+
return {type: 'Polygon', coordinates: []};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const ringCount = reader.readVarInt();
|
|
197
|
+
|
|
198
|
+
const previousPoint = makePreviousPoint(context);
|
|
199
|
+
|
|
200
|
+
const exteriorRingLength = reader.readVarInt();
|
|
201
|
+
const exteriorRing: number[][] = [];
|
|
202
|
+
|
|
203
|
+
for (let i = 0; i < exteriorRingLength; i++) {
|
|
204
|
+
exteriorRing.push(parseNextPoint(reader, context, previousPoint));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const polygon: number[][][] = [exteriorRing];
|
|
208
|
+
for (let i = 1; i < ringCount; i++) {
|
|
209
|
+
const interiorRingCount = reader.readVarInt();
|
|
210
|
+
|
|
211
|
+
const interiorRing: number[][] = [];
|
|
212
|
+
for (let j = 0; j < interiorRingCount; j++) {
|
|
213
|
+
interiorRing.push(parseNextPoint(reader, context, previousPoint));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
polygon.push(interiorRing);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return {type: 'Polygon', coordinates: polygon};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function parseMultiPoint(reader: BinaryReader, context: TWKBHeader): MultiPoint {
|
|
223
|
+
if (context.isEmpty) {
|
|
224
|
+
return {type: 'MultiPoint', coordinates: []};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const previousPoint = makePreviousPoint(context);
|
|
228
|
+
const pointCount = reader.readVarInt();
|
|
229
|
+
|
|
230
|
+
const coordinates: number[][] = [];
|
|
231
|
+
for (let i = 0; i < pointCount; i++) {
|
|
232
|
+
coordinates.push(parseNextPoint(reader, context, previousPoint));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return {type: 'MultiPoint', coordinates};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function parseMultiLineString(reader: BinaryReader, context: TWKBHeader): MultiLineString {
|
|
239
|
+
if (context.isEmpty) {
|
|
240
|
+
return {type: 'MultiLineString', coordinates: []};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const previousPoint = makePreviousPoint(context);
|
|
244
|
+
const lineStringCount = reader.readVarInt();
|
|
245
|
+
|
|
246
|
+
const coordinates: number[][][] = [];
|
|
247
|
+
for (let i = 0; i < lineStringCount; i++) {
|
|
248
|
+
const pointCount = reader.readVarInt();
|
|
249
|
+
|
|
250
|
+
const lineString: number[][] = [];
|
|
251
|
+
for (let j = 0; j < pointCount; j++) {
|
|
252
|
+
lineString.push(parseNextPoint(reader, context, previousPoint));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
coordinates.push(lineString);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return {type: 'MultiLineString', coordinates};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function parseMultiPolygon(reader: BinaryReader, context: TWKBHeader): MultiPolygon {
|
|
262
|
+
if (context.isEmpty) {
|
|
263
|
+
return {type: 'MultiPolygon', coordinates: []};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const previousPoint = makePreviousPoint(context);
|
|
267
|
+
const polygonCount = reader.readVarInt();
|
|
268
|
+
|
|
269
|
+
const polygons: number[][][][] = [];
|
|
270
|
+
for (let i = 0; i < polygonCount; i++) {
|
|
271
|
+
const ringCount = reader.readVarInt();
|
|
272
|
+
|
|
273
|
+
const exteriorPointCount = reader.readVarInt();
|
|
274
|
+
|
|
275
|
+
const exteriorRing: number[][] = [];
|
|
276
|
+
for (let j = 0; j < exteriorPointCount; j++) {
|
|
277
|
+
exteriorRing.push(parseNextPoint(reader, context, previousPoint));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const polygon: number[][][] = exteriorRing ? [exteriorRing] : [];
|
|
281
|
+
|
|
282
|
+
for (let j = 1; j < ringCount; j++) {
|
|
283
|
+
const interiorRing: number[][] = [];
|
|
284
|
+
|
|
285
|
+
const interiorRingLength = reader.readVarInt();
|
|
286
|
+
|
|
287
|
+
for (let k = 0; k < interiorRingLength; k++) {
|
|
288
|
+
interiorRing.push(parseNextPoint(reader, context, previousPoint));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
polygon.push(interiorRing);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
polygons.push(polygon);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return {type: 'MultiPolygon', coordinates: polygons};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Geometry collection not yet supported */
|
|
301
|
+
function parseGeometryCollection(reader: BinaryReader, context: TWKBHeader): GeometryCollection {
|
|
302
|
+
return {type: 'GeometryCollection', geometries: []};
|
|
303
|
+
/**
|
|
304
|
+
if (context.isEmpty) {
|
|
305
|
+
return {type: 'GeometryCollection', geometries: []};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const geometryCount = reader.readVarInt();
|
|
309
|
+
|
|
310
|
+
const geometries: Geometry[] = new Array(geometryCount);
|
|
311
|
+
for (let i = 0; i < geometryCount; i++) {
|
|
312
|
+
const geometry = parseGeometry(reader, context, geometryType);
|
|
313
|
+
geometries.push(geometry);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return {type: 'GeometryCollection', geometries: []};
|
|
317
|
+
*/
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// HELPERS
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Maps negative values to positive values while going back and
|
|
324
|
+
forth (0 = 0, -1 = 1, 1 = 2, -2 = 3, 2 = 4, -3 = 5, 3 = 6 ...)
|
|
325
|
+
*/
|
|
326
|
+
function zigZagDecode(value: number): number {
|
|
327
|
+
return (value >> 1) ^ -(value & 1);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function makePointCoordinates(x: number, y: number, z?: number, m?: number): number[] {
|
|
331
|
+
return (z !== undefined ? (m !== undefined ? [x, y, z, m] : [x, y, z]) : [x, y]) as number[];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function makePreviousPoint(context: TWKBHeader): number[] {
|
|
335
|
+
return makePointCoordinates(0, 0, context.hasZ ? 0 : undefined, context.hasM ? 0 : undefined);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function readFirstPoint(reader: BinaryReader, context: TWKBHeader): number[] {
|
|
339
|
+
const x = zigZagDecode(reader.readVarInt()) / context.precisionFactor;
|
|
340
|
+
const y = zigZagDecode(reader.readVarInt()) / context.precisionFactor;
|
|
341
|
+
const z = context.hasZ ? zigZagDecode(reader.readVarInt()) / context.zPrecisionFactor : undefined;
|
|
342
|
+
const m = context.hasM ? zigZagDecode(reader.readVarInt()) / context.mPrecisionFactor : undefined;
|
|
343
|
+
return makePointCoordinates(x, y, z, m);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Modifies previousPoint
|
|
348
|
+
*/
|
|
349
|
+
function parseNextPoint(
|
|
350
|
+
reader: BinaryReader,
|
|
351
|
+
context: TWKBHeader,
|
|
352
|
+
previousPoint: number[]
|
|
353
|
+
): number[] {
|
|
354
|
+
previousPoint[0] += zigZagDecode(reader.readVarInt()) / context.precisionFactor;
|
|
355
|
+
previousPoint[1] += zigZagDecode(reader.readVarInt()) / context.precisionFactor;
|
|
356
|
+
|
|
357
|
+
if (context.hasZ) {
|
|
358
|
+
previousPoint[2] += zigZagDecode(reader.readVarInt()) / context.zPrecisionFactor;
|
|
359
|
+
}
|
|
360
|
+
if (context.hasM) {
|
|
361
|
+
previousPoint[3] += zigZagDecode(reader.readVarInt()) / context.mPrecisionFactor;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Copy the point
|
|
365
|
+
return previousPoint.slice();
|
|
366
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
TypedArray,
|
|
7
|
+
BinaryGeometry,
|
|
8
|
+
BinaryPointGeometry,
|
|
9
|
+
BinaryLineGeometry,
|
|
10
|
+
BinaryPolygonGeometry
|
|
11
|
+
} from '@loaders.gl/schema';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
concatenateBinaryPointGeometries,
|
|
15
|
+
concatenateBinaryLineGeometries,
|
|
16
|
+
concatenateBinaryPolygonGeometries
|
|
17
|
+
} from '../../binary-geometry-api/concat-binary-geometry';
|
|
18
|
+
import {concatTypedArrays} from '../../utils/concat-typed-arrays';
|
|
19
|
+
import {WKBGeometryType} from './helpers/wkb-types';
|
|
20
|
+
import {parseWKBHeader} from './helpers/parse-wkb-header';
|
|
21
|
+
|
|
22
|
+
export function convertWKBToBinaryGeometry(arrayBuffer: ArrayBufferLike): BinaryGeometry {
|
|
23
|
+
const dataView = new DataView(arrayBuffer);
|
|
24
|
+
|
|
25
|
+
const wkbHeader = parseWKBHeader(dataView);
|
|
26
|
+
|
|
27
|
+
const {geometryType, dimensions, littleEndian} = wkbHeader;
|
|
28
|
+
const offset = wkbHeader.byteOffset;
|
|
29
|
+
|
|
30
|
+
switch (geometryType) {
|
|
31
|
+
case WKBGeometryType.Point:
|
|
32
|
+
const point = parsePoint(dataView, offset, dimensions, littleEndian);
|
|
33
|
+
return point.geometry;
|
|
34
|
+
case WKBGeometryType.LineString:
|
|
35
|
+
const line = parseLineString(dataView, offset, dimensions, littleEndian);
|
|
36
|
+
return line.geometry;
|
|
37
|
+
case WKBGeometryType.Polygon:
|
|
38
|
+
const polygon = parsePolygon(dataView, offset, dimensions, littleEndian);
|
|
39
|
+
return polygon.geometry;
|
|
40
|
+
case WKBGeometryType.MultiPoint:
|
|
41
|
+
const multiPoint = parseMultiPoint(dataView, offset, dimensions, littleEndian);
|
|
42
|
+
multiPoint.type = 'Point';
|
|
43
|
+
return multiPoint;
|
|
44
|
+
case WKBGeometryType.MultiLineString:
|
|
45
|
+
const multiLine = parseMultiLineString(dataView, offset, dimensions, littleEndian);
|
|
46
|
+
multiLine.type = 'LineString';
|
|
47
|
+
return multiLine;
|
|
48
|
+
case WKBGeometryType.MultiPolygon:
|
|
49
|
+
const multiPolygon = parseMultiPolygon(dataView, offset, dimensions, littleEndian);
|
|
50
|
+
multiPolygon.type = 'Polygon';
|
|
51
|
+
return multiPolygon;
|
|
52
|
+
// case WKBGeometryType.GeometryCollection:
|
|
53
|
+
// TODO: handle GeometryCollections
|
|
54
|
+
// return parseGeometryCollection(dataView, offset, dimensions, littleEndian);
|
|
55
|
+
default:
|
|
56
|
+
throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Primitives; parse point and linear ring
|
|
61
|
+
function parsePoint(
|
|
62
|
+
dataView: DataView,
|
|
63
|
+
offset: number,
|
|
64
|
+
dimension: number,
|
|
65
|
+
littleEndian: boolean
|
|
66
|
+
): {geometry: BinaryPointGeometry; offset: number} {
|
|
67
|
+
const positions = new Float64Array(dimension);
|
|
68
|
+
for (let i = 0; i < dimension; i++) {
|
|
69
|
+
positions[i] = dataView.getFloat64(offset, littleEndian);
|
|
70
|
+
offset += 8;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
geometry: {type: 'Point', positions: {value: positions, size: dimension}},
|
|
75
|
+
offset
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function parseLineString(
|
|
80
|
+
dataView: DataView,
|
|
81
|
+
offset: number,
|
|
82
|
+
dimension: number,
|
|
83
|
+
littleEndian: boolean
|
|
84
|
+
): {geometry: BinaryLineGeometry; offset: number} {
|
|
85
|
+
const nPoints = dataView.getUint32(offset, littleEndian);
|
|
86
|
+
offset += 4;
|
|
87
|
+
|
|
88
|
+
// Instantiate array
|
|
89
|
+
const positions = new Float64Array(nPoints * dimension);
|
|
90
|
+
for (let i = 0; i < nPoints * dimension; i++) {
|
|
91
|
+
positions[i] = dataView.getFloat64(offset, littleEndian);
|
|
92
|
+
offset += 8;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const pathIndices = [0];
|
|
96
|
+
if (nPoints > 0) {
|
|
97
|
+
pathIndices.push(nPoints);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
geometry: {
|
|
102
|
+
type: 'LineString',
|
|
103
|
+
positions: {value: positions, size: dimension},
|
|
104
|
+
pathIndices: {value: new Uint32Array(pathIndices), size: 1}
|
|
105
|
+
},
|
|
106
|
+
offset
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// https://stackoverflow.com/a/55261098
|
|
111
|
+
const cumulativeSum = (sum: number) => (value: number) => (sum += value);
|
|
112
|
+
|
|
113
|
+
function parsePolygon(
|
|
114
|
+
dataView: DataView,
|
|
115
|
+
offset: number,
|
|
116
|
+
dimension: number,
|
|
117
|
+
littleEndian: boolean
|
|
118
|
+
): {geometry: BinaryPolygonGeometry; offset: number} {
|
|
119
|
+
const nRings = dataView.getUint32(offset, littleEndian);
|
|
120
|
+
offset += 4;
|
|
121
|
+
|
|
122
|
+
const rings: TypedArray[] = [];
|
|
123
|
+
for (let i = 0; i < nRings; i++) {
|
|
124
|
+
const parsed = parseLineString(dataView, offset, dimension, littleEndian);
|
|
125
|
+
const {positions} = parsed.geometry;
|
|
126
|
+
offset = parsed.offset;
|
|
127
|
+
rings.push(positions.value);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer);
|
|
131
|
+
const polygonIndices = [0];
|
|
132
|
+
if (concatenatedPositions.length > 0) {
|
|
133
|
+
polygonIndices.push(concatenatedPositions.length / dimension);
|
|
134
|
+
}
|
|
135
|
+
const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum(0));
|
|
136
|
+
primitivePolygonIndices.unshift(0);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
geometry: {
|
|
140
|
+
type: 'Polygon',
|
|
141
|
+
positions: {value: concatenatedPositions, size: dimension},
|
|
142
|
+
polygonIndices: {
|
|
143
|
+
value: new Uint32Array(polygonIndices),
|
|
144
|
+
size: 1
|
|
145
|
+
},
|
|
146
|
+
primitivePolygonIndices: {value: new Uint32Array(primitivePolygonIndices), size: 1}
|
|
147
|
+
},
|
|
148
|
+
offset
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function parseMultiPoint(
|
|
153
|
+
dataView: DataView,
|
|
154
|
+
offset: number,
|
|
155
|
+
dimension: number,
|
|
156
|
+
littleEndian: boolean
|
|
157
|
+
): BinaryPointGeometry {
|
|
158
|
+
const nPoints = dataView.getUint32(offset, littleEndian);
|
|
159
|
+
offset += 4;
|
|
160
|
+
|
|
161
|
+
const binaryPointGeometries: BinaryPointGeometry[] = [];
|
|
162
|
+
for (let i = 0; i < nPoints; i++) {
|
|
163
|
+
// Byte order for point
|
|
164
|
+
const littleEndianPoint = dataView.getUint8(offset) === 1;
|
|
165
|
+
offset++;
|
|
166
|
+
|
|
167
|
+
// Assert point type
|
|
168
|
+
if (dataView.getUint32(offset, littleEndianPoint) % 1000 !== 1) {
|
|
169
|
+
throw new Error('WKB: Inner geometries of MultiPoint not of type Point');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
offset += 4;
|
|
173
|
+
|
|
174
|
+
const parsed = parsePoint(dataView, offset, dimension, littleEndianPoint);
|
|
175
|
+
offset = parsed.offset;
|
|
176
|
+
binaryPointGeometries.push(parsed.geometry);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function parseMultiLineString(
|
|
183
|
+
dataView: DataView,
|
|
184
|
+
offset: number,
|
|
185
|
+
dimension: number,
|
|
186
|
+
littleEndian: boolean
|
|
187
|
+
): BinaryLineGeometry {
|
|
188
|
+
const nLines = dataView.getUint32(offset, littleEndian);
|
|
189
|
+
offset += 4;
|
|
190
|
+
|
|
191
|
+
const binaryLineGeometries: BinaryLineGeometry[] = [];
|
|
192
|
+
for (let i = 0; i < nLines; i++) {
|
|
193
|
+
// Byte order for line
|
|
194
|
+
const littleEndianLine = dataView.getUint8(offset) === 1;
|
|
195
|
+
offset++;
|
|
196
|
+
|
|
197
|
+
// Assert type LineString
|
|
198
|
+
if (dataView.getUint32(offset, littleEndianLine) % 1000 !== 2) {
|
|
199
|
+
throw new Error('WKB: Inner geometries of MultiLineString not of type LineString');
|
|
200
|
+
}
|
|
201
|
+
offset += 4;
|
|
202
|
+
|
|
203
|
+
const parsed = parseLineString(dataView, offset, dimension, littleEndianLine);
|
|
204
|
+
offset = parsed.offset;
|
|
205
|
+
binaryLineGeometries.push(parsed.geometry);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return concatenateBinaryLineGeometries(binaryLineGeometries, dimension);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function parseMultiPolygon(
|
|
212
|
+
dataView: DataView,
|
|
213
|
+
offset: number,
|
|
214
|
+
dimension: number,
|
|
215
|
+
littleEndian: boolean
|
|
216
|
+
): BinaryPolygonGeometry {
|
|
217
|
+
const nPolygons = dataView.getUint32(offset, littleEndian);
|
|
218
|
+
offset += 4;
|
|
219
|
+
|
|
220
|
+
const binaryPolygonGeometries: BinaryPolygonGeometry[] = [];
|
|
221
|
+
for (let i = 0; i < nPolygons; i++) {
|
|
222
|
+
// Byte order for polygon
|
|
223
|
+
const littleEndianPolygon = dataView.getUint8(offset) === 1;
|
|
224
|
+
offset++;
|
|
225
|
+
|
|
226
|
+
// Assert type Polygon
|
|
227
|
+
if (dataView.getUint32(offset, littleEndianPolygon) % 1000 !== 3) {
|
|
228
|
+
throw new Error('WKB: Inner geometries of MultiPolygon not of type Polygon');
|
|
229
|
+
}
|
|
230
|
+
offset += 4;
|
|
231
|
+
|
|
232
|
+
const parsed = parsePolygon(dataView, offset, dimension, littleEndianPolygon);
|
|
233
|
+
offset = parsed.offset;
|
|
234
|
+
binaryPolygonGeometries.push(parsed.geometry);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension);
|
|
238
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {Geometry} from '@loaders.gl/schema';
|
|
6
|
+
import {convertBinaryGeometryToGeometry} from '../convert-binary-geometry-to-geojson';
|
|
7
|
+
import {convertWKBToBinaryGeometry} from './convert-wkb-to-binary-geometry';
|
|
8
|
+
|
|
9
|
+
export type convertWKBOptions = {
|
|
10
|
+
/** Does the GeoJSON input have Z values? */
|
|
11
|
+
hasZ?: boolean;
|
|
12
|
+
|
|
13
|
+
/** Does the GeoJSON input have M values? */
|
|
14
|
+
hasM?: boolean;
|
|
15
|
+
|
|
16
|
+
/** Spatial reference for input GeoJSON */
|
|
17
|
+
srid?: any;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function convertWKBToGeometry(arrayBuffer: ArrayBufferLike): Geometry {
|
|
21
|
+
const binaryGeometry = convertWKBToBinaryGeometry(arrayBuffer);
|
|
22
|
+
return convertBinaryGeometryToGeometry(binaryGeometry);
|
|
23
|
+
}
|