@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,148 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
BinaryGeometry,
|
|
7
|
+
BinaryPointGeometry,
|
|
8
|
+
BinaryLineGeometry,
|
|
9
|
+
BinaryPolygonGeometry,
|
|
10
|
+
BinaryAttribute,
|
|
11
|
+
Geometry,
|
|
12
|
+
Position,
|
|
13
|
+
Point,
|
|
14
|
+
MultiPoint,
|
|
15
|
+
LineString,
|
|
16
|
+
MultiLineString,
|
|
17
|
+
Polygon,
|
|
18
|
+
MultiPolygon
|
|
19
|
+
} from '@loaders.gl/schema';
|
|
20
|
+
|
|
21
|
+
/** Parse input binary data and return a valid GeoJSON geometry object */
|
|
22
|
+
export function convertBinaryGeometryToGeometry(
|
|
23
|
+
data: BinaryGeometry,
|
|
24
|
+
startIndex?: number,
|
|
25
|
+
endIndex?: number
|
|
26
|
+
): Geometry {
|
|
27
|
+
switch (data.type) {
|
|
28
|
+
case 'Point':
|
|
29
|
+
return pointToGeoJson(data, startIndex, endIndex);
|
|
30
|
+
case 'LineString':
|
|
31
|
+
return lineStringToGeoJson(data, startIndex, endIndex);
|
|
32
|
+
case 'Polygon':
|
|
33
|
+
return polygonToGeoJson(data, startIndex, endIndex);
|
|
34
|
+
default:
|
|
35
|
+
const unexpectedInput: never = data;
|
|
36
|
+
throw new Error(`Unsupported geometry type: ${(unexpectedInput as any)?.type}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Parse binary data of type Polygon */
|
|
41
|
+
function polygonToGeoJson(
|
|
42
|
+
data: BinaryPolygonGeometry,
|
|
43
|
+
startIndex: number = -Infinity,
|
|
44
|
+
endIndex: number = Infinity
|
|
45
|
+
): Polygon | MultiPolygon {
|
|
46
|
+
const {positions} = data;
|
|
47
|
+
const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
48
|
+
const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
|
|
49
|
+
(x) => x >= startIndex && x <= endIndex
|
|
50
|
+
);
|
|
51
|
+
const multi = polygonIndices.length > 2;
|
|
52
|
+
|
|
53
|
+
// Polygon
|
|
54
|
+
if (!multi) {
|
|
55
|
+
const coordinates: Position[][] = [];
|
|
56
|
+
for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
|
|
57
|
+
const startRingIndex = primitivePolygonIndices[i];
|
|
58
|
+
const endRingIndex = primitivePolygonIndices[i + 1];
|
|
59
|
+
const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
|
|
60
|
+
coordinates.push(ringCoordinates);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {type: 'Polygon', coordinates};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// MultiPolygon
|
|
67
|
+
const coordinates: Position[][][] = [];
|
|
68
|
+
for (let i = 0; i < polygonIndices.length - 1; i++) {
|
|
69
|
+
const startPolygonIndex = polygonIndices[i];
|
|
70
|
+
const endPolygonIndex = polygonIndices[i + 1];
|
|
71
|
+
const polygonCoordinates = polygonToGeoJson(
|
|
72
|
+
data,
|
|
73
|
+
startPolygonIndex,
|
|
74
|
+
endPolygonIndex
|
|
75
|
+
).coordinates;
|
|
76
|
+
coordinates.push(polygonCoordinates as Position[][]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {type: 'MultiPolygon', coordinates};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Parse binary data of type LineString */
|
|
83
|
+
function lineStringToGeoJson(
|
|
84
|
+
data: BinaryLineGeometry,
|
|
85
|
+
startIndex: number = -Infinity,
|
|
86
|
+
endIndex: number = Infinity
|
|
87
|
+
): LineString | MultiLineString {
|
|
88
|
+
const {positions} = data;
|
|
89
|
+
const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
90
|
+
const multi = pathIndices.length > 2;
|
|
91
|
+
|
|
92
|
+
if (!multi) {
|
|
93
|
+
const coordinates = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
|
|
94
|
+
return {type: 'LineString', coordinates};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const coordinates: Position[][] = [];
|
|
98
|
+
for (let i = 0; i < pathIndices.length - 1; i++) {
|
|
99
|
+
const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
|
|
100
|
+
coordinates.push(ringCoordinates);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {type: 'MultiLineString', coordinates};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Parse binary data of type Point */
|
|
107
|
+
function pointToGeoJson(
|
|
108
|
+
data: BinaryPointGeometry,
|
|
109
|
+
startIndex?: number,
|
|
110
|
+
endIndex?: number
|
|
111
|
+
): Point | MultiPoint {
|
|
112
|
+
const {positions} = data;
|
|
113
|
+
const coordinates = ringToGeoJson(positions, startIndex, endIndex);
|
|
114
|
+
const multi = coordinates.length > 1;
|
|
115
|
+
|
|
116
|
+
if (multi) {
|
|
117
|
+
return {type: 'MultiPoint', coordinates};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {type: 'Point', coordinates: coordinates[0]};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Parse a linear ring of positions to a GeoJSON linear ring
|
|
125
|
+
*
|
|
126
|
+
* @param positions Positions TypedArray
|
|
127
|
+
* @param startIndex Start index to include in ring
|
|
128
|
+
* @param endIndex End index to include in ring
|
|
129
|
+
* @returns GeoJSON ring
|
|
130
|
+
*/
|
|
131
|
+
function ringToGeoJson(
|
|
132
|
+
positions: BinaryAttribute,
|
|
133
|
+
startIndex?: number,
|
|
134
|
+
endIndex?: number
|
|
135
|
+
): Position[] {
|
|
136
|
+
startIndex = startIndex || 0;
|
|
137
|
+
endIndex = endIndex || positions.value.length / positions.size;
|
|
138
|
+
|
|
139
|
+
const ringCoordinates: Position[] = [];
|
|
140
|
+
for (let j = startIndex; j < endIndex; j++) {
|
|
141
|
+
const coord = Array<number>();
|
|
142
|
+
for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
|
|
143
|
+
coord.push(Number(positions.value[k]));
|
|
144
|
+
}
|
|
145
|
+
ringCoordinates.push(coord);
|
|
146
|
+
}
|
|
147
|
+
return ringCoordinates;
|
|
148
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
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 {
|
|
7
|
+
MultiPolygon,
|
|
8
|
+
Position,
|
|
9
|
+
Polygon,
|
|
10
|
+
MultiPoint,
|
|
11
|
+
Point,
|
|
12
|
+
MultiLineString,
|
|
13
|
+
LineString,
|
|
14
|
+
Geometry
|
|
15
|
+
} from '@loaders.gl/schema';
|
|
16
|
+
import type {GeoArrowEncoding} from '@loaders.gl/geoarrow';
|
|
17
|
+
import {convertWKBToGeometry} from './wkb/convert-wkb-to-geometry';
|
|
18
|
+
import {convertWKTToGeometry} from './wkb/convert-wkt-to-geometry';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* parse geometry from arrow data that is returned from processArrowData()
|
|
22
|
+
* NOTE: this function could be deduplicated with the binaryToGeometry() 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 convertGeoArrowGeometryToGeoJSON(
|
|
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
|
+
switch (encoding) {
|
|
40
|
+
case 'geoarrow.multipolygon':
|
|
41
|
+
return arrowMultiPolygonToGeometry(arrowCellValue);
|
|
42
|
+
case 'geoarrow.polygon':
|
|
43
|
+
return arrowPolygonToGeometry(arrowCellValue);
|
|
44
|
+
case 'geoarrow.multipoint':
|
|
45
|
+
return arrowMultiPointToGeometry(arrowCellValue);
|
|
46
|
+
case 'geoarrow.point':
|
|
47
|
+
return arrowPointToGeometry(arrowCellValue);
|
|
48
|
+
case 'geoarrow.multilinestring':
|
|
49
|
+
return arrowMultiLineStringToGeometry(arrowCellValue);
|
|
50
|
+
case 'geoarrow.linestring':
|
|
51
|
+
return arrowLineStringToGeometry(arrowCellValue);
|
|
52
|
+
case 'geoarrow.wkb':
|
|
53
|
+
return arrowWKBToGeometry(arrowCellValue);
|
|
54
|
+
case 'geoarrow.wkt':
|
|
55
|
+
return arrowWKTToGeometry(arrowCellValue);
|
|
56
|
+
default: {
|
|
57
|
+
throw Error(`GeoArrow encoding not supported ${encoding}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function arrowWKBToGeometry(arrowCellValue: any): Geometry | null {
|
|
63
|
+
// The actual WKB array buffer starts from byteOffset and ends at byteOffset + byteLength
|
|
64
|
+
const arrayBuffer: ArrayBuffer = arrowCellValue.buffer.slice(
|
|
65
|
+
arrowCellValue.byteOffset,
|
|
66
|
+
arrowCellValue.byteOffset + arrowCellValue.byteLength
|
|
67
|
+
);
|
|
68
|
+
return convertWKBToGeometry(arrayBuffer);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function arrowWKTToGeometry(arrowCellValue: any): Geometry | null {
|
|
72
|
+
const string: string = arrowCellValue;
|
|
73
|
+
return convertWKTToGeometry(string);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* convert Arrow MultiPolygon to geojson Feature
|
|
78
|
+
*/
|
|
79
|
+
function arrowMultiPolygonToGeometry(arrowMultiPolygon: any): MultiPolygon {
|
|
80
|
+
const multiPolygon: Position[][][] = [];
|
|
81
|
+
for (let m = 0; m < arrowMultiPolygon.length; m++) {
|
|
82
|
+
const arrowPolygon = arrowMultiPolygon.get(m);
|
|
83
|
+
const polygon: Position[][] = [];
|
|
84
|
+
for (let i = 0; arrowPolygon && i < arrowPolygon?.length; i++) {
|
|
85
|
+
const arrowRing = arrowPolygon?.get(i);
|
|
86
|
+
const ring: Position[] = [];
|
|
87
|
+
for (let j = 0; arrowRing && j < arrowRing.length; j++) {
|
|
88
|
+
const arrowCoord = arrowRing.get(j);
|
|
89
|
+
const coord: Position = Array.from(arrowCoord);
|
|
90
|
+
ring.push(coord);
|
|
91
|
+
}
|
|
92
|
+
polygon.push(ring);
|
|
93
|
+
}
|
|
94
|
+
multiPolygon.push(polygon);
|
|
95
|
+
}
|
|
96
|
+
const geometry: MultiPolygon = {
|
|
97
|
+
type: 'MultiPolygon',
|
|
98
|
+
coordinates: multiPolygon
|
|
99
|
+
};
|
|
100
|
+
return geometry;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* convert Arrow Polygon to geojson Feature
|
|
105
|
+
*/
|
|
106
|
+
function arrowPolygonToGeometry(arrowPolygon: any): Polygon {
|
|
107
|
+
const polygon: Position[][] = [];
|
|
108
|
+
for (let i = 0; arrowPolygon && i < arrowPolygon.length; i++) {
|
|
109
|
+
const arrowRing = arrowPolygon.get(i);
|
|
110
|
+
const ring: Position[] = [];
|
|
111
|
+
for (let j = 0; arrowRing && j < arrowRing.length; j++) {
|
|
112
|
+
const arrowCoord = arrowRing.get(j);
|
|
113
|
+
const coords: Position = Array.from(arrowCoord);
|
|
114
|
+
ring.push(coords);
|
|
115
|
+
}
|
|
116
|
+
polygon.push(ring);
|
|
117
|
+
}
|
|
118
|
+
const geometry: Polygon = {
|
|
119
|
+
type: 'Polygon',
|
|
120
|
+
coordinates: polygon
|
|
121
|
+
};
|
|
122
|
+
return geometry;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* convert Arrow MultiPoint to geojson MultiPoint
|
|
127
|
+
*/
|
|
128
|
+
function arrowMultiPointToGeometry(arrowMultiPoint: any): MultiPoint {
|
|
129
|
+
const multiPoint: Position[] = [];
|
|
130
|
+
for (let i = 0; arrowMultiPoint && i < arrowMultiPoint.length; i++) {
|
|
131
|
+
const arrowPoint = arrowMultiPoint.get(i);
|
|
132
|
+
if (arrowPoint) {
|
|
133
|
+
const coord: Position = Array.from(arrowPoint);
|
|
134
|
+
multiPoint.push(coord);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
type: 'MultiPoint',
|
|
139
|
+
coordinates: multiPoint
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* convert Arrow Point to geojson Point
|
|
145
|
+
*/
|
|
146
|
+
function arrowPointToGeometry(arrowPoint: any): Point {
|
|
147
|
+
const point: Position = Array.from(arrowPoint);
|
|
148
|
+
return {
|
|
149
|
+
type: 'Point',
|
|
150
|
+
coordinates: point
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* convert Arrow MultiLineString to geojson MultiLineString
|
|
156
|
+
*/
|
|
157
|
+
function arrowMultiLineStringToGeometry(arrowMultiLineString: any): MultiLineString {
|
|
158
|
+
const multiLineString: Position[][] = [];
|
|
159
|
+
for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
|
|
160
|
+
const arrowLineString = arrowMultiLineString.get(i);
|
|
161
|
+
const lineString: Position[] = [];
|
|
162
|
+
for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
|
|
163
|
+
const arrowCoord = arrowLineString.get(j);
|
|
164
|
+
if (arrowCoord) {
|
|
165
|
+
const coords: Position = Array.from(arrowCoord);
|
|
166
|
+
lineString.push(coords);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
multiLineString.push(lineString);
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
type: 'MultiLineString',
|
|
173
|
+
coordinates: multiLineString
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* convert Arrow LineString to geojson LineString
|
|
179
|
+
*/
|
|
180
|
+
function arrowLineStringToGeometry(arrowLineString: any): LineString {
|
|
181
|
+
const lineString: Position[] = [];
|
|
182
|
+
for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
|
|
183
|
+
const arrowCoord = arrowLineString.get(i);
|
|
184
|
+
if (arrowCoord) {
|
|
185
|
+
const coords: Position = Array.from(arrowCoord);
|
|
186
|
+
lineString.push(coords);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
type: 'LineString',
|
|
191
|
+
coordinates: lineString
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {Geometry, BinaryGeometry} from '@loaders.gl/schema';
|
|
6
|
+
|
|
7
|
+
import {convertGeometryToWKB} from './wkb/convert-geometry-to-wkb';
|
|
8
|
+
import {convertGeometryToWKT} from './wkb/convert-geometry-to-wkt';
|
|
9
|
+
import {convertWKBToBinaryGeometry} from './wkb/convert-wkb-to-binary-geometry';
|
|
10
|
+
import {convertWKTToGeometry} from './wkb/convert-wkt-to-geometry';
|
|
11
|
+
|
|
12
|
+
import {convertBinaryGeometryToGeometry} from './convert-binary-geometry-to-geojson';
|
|
13
|
+
|
|
14
|
+
export function convertToGeoJSON(geometry: ArrayBuffer | string): Geometry {
|
|
15
|
+
if (geometry instanceof ArrayBuffer) {
|
|
16
|
+
const binaryGeometry = convertWKBToBinaryGeometry(geometry);
|
|
17
|
+
return convertBinaryGeometryToGeometry(binaryGeometry);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Assume string encoded WKT
|
|
21
|
+
if (typeof geometry === 'string') {
|
|
22
|
+
return convertWKTToGeometry(geometry)!;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
throw new Error('Geo conversion not implemented');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function convertToBinaryGeometry(geometry: ArrayBuffer | string | Geometry): BinaryGeometry {
|
|
29
|
+
if (geometry instanceof ArrayBuffer) {
|
|
30
|
+
return convertWKBToBinaryGeometry(geometry);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Assume string encoded WKT
|
|
34
|
+
if (typeof geometry === 'string') {
|
|
35
|
+
// const geometry = convertWKTToGeometry(geometry);
|
|
36
|
+
// return convertGeometryToBinaryGeometry(geometry);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
throw new Error('Geo conversion not implemented');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function convertToWKT(geometry: Geometry): string {
|
|
43
|
+
return convertGeometryToWKT(geometry);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function convertToWKB(geometry: Geometry): ArrayBuffer {
|
|
47
|
+
return convertGeometryToWKB(geometry);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// export function convertToTWKB(geometry: Geometry): ArrayBuffer {
|
|
51
|
+
// return convertGeometryToTWKB(geometry);
|
|
52
|
+
// }
|
|
@@ -0,0 +1,308 @@
|
|
|
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
|
+
Point,
|
|
8
|
+
MultiPoint,
|
|
9
|
+
LineString,
|
|
10
|
+
MultiLineString,
|
|
11
|
+
Polygon,
|
|
12
|
+
MultiPolygon,
|
|
13
|
+
GeometryCollection,
|
|
14
|
+
Geometry
|
|
15
|
+
} from '@loaders.gl/schema';
|
|
16
|
+
|
|
17
|
+
import {BinaryWriter} from '../../utils/binary-writer';
|
|
18
|
+
import {WKBGeometryType} from './helpers/wkb-types';
|
|
19
|
+
|
|
20
|
+
type TWKBPrecision = {
|
|
21
|
+
xy: number;
|
|
22
|
+
z: number;
|
|
23
|
+
m: number;
|
|
24
|
+
xyFactor: number;
|
|
25
|
+
zFactor: number;
|
|
26
|
+
mFactor: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type TWKBEncoderContext = TWKBPrecision & {
|
|
30
|
+
hasZ?: boolean;
|
|
31
|
+
hasM?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function convertGeometryToTWKB(
|
|
35
|
+
geometry: Geometry,
|
|
36
|
+
options?: {hasZ?: boolean; hasM?: boolean}
|
|
37
|
+
): ArrayBuffer {
|
|
38
|
+
const writer = new BinaryWriter(0, true);
|
|
39
|
+
|
|
40
|
+
const context: TWKBEncoderContext = {
|
|
41
|
+
...getTwkbPrecision(5, 0, 0),
|
|
42
|
+
hasZ: options?.hasZ,
|
|
43
|
+
hasM: options?.hasM
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
encodeGeometry(writer, geometry, context);
|
|
47
|
+
|
|
48
|
+
// TODO - we need to slice it?
|
|
49
|
+
return writer.arrayBuffer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function encodeGeometry(writer: BinaryWriter, geometry: Geometry, context: TWKBEncoderContext) {
|
|
53
|
+
switch (geometry.type) {
|
|
54
|
+
case 'Point':
|
|
55
|
+
return encodePoint(writer, context, geometry);
|
|
56
|
+
case 'LineString':
|
|
57
|
+
return encodeLineString(writer, context, geometry);
|
|
58
|
+
case 'Polygon':
|
|
59
|
+
return encodePolygon(writer, context, geometry);
|
|
60
|
+
case 'MultiPoint':
|
|
61
|
+
return encodeMultiPoint(writer, context, geometry);
|
|
62
|
+
case 'MultiLineString':
|
|
63
|
+
return encodeMultiLineString(writer, context, geometry);
|
|
64
|
+
case 'MultiPolygon':
|
|
65
|
+
return encodeMultiPolygon(writer, context, geometry);
|
|
66
|
+
case 'GeometryCollection':
|
|
67
|
+
return encodeGeometryCollection(writer, context, geometry);
|
|
68
|
+
default:
|
|
69
|
+
throw new Error('unsupported geometry type');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function encodePoint(writer: BinaryWriter, context: TWKBEncoderContext, point: Point): void {
|
|
74
|
+
const isEmpty =
|
|
75
|
+
point.coordinates.length === 0 || point[0] === 'undefined' || point[1] === 'undefined';
|
|
76
|
+
|
|
77
|
+
writeTwkbHeader(writer, context, WKBGeometryType.Point, isEmpty);
|
|
78
|
+
|
|
79
|
+
if (!isEmpty) {
|
|
80
|
+
const previousPoint = [0, 0, 0, 0];
|
|
81
|
+
writeTwkbPoint(writer, context, point.coordinates, previousPoint);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function encodeLineString(
|
|
86
|
+
writer: BinaryWriter,
|
|
87
|
+
context: TWKBEncoderContext,
|
|
88
|
+
lineString: LineString
|
|
89
|
+
): ArrayBuffer {
|
|
90
|
+
const points = lineString.coordinates;
|
|
91
|
+
const isEmpty = points.length === 0;
|
|
92
|
+
|
|
93
|
+
writeTwkbHeader(writer, context, WKBGeometryType.LineString, isEmpty);
|
|
94
|
+
|
|
95
|
+
if (!isEmpty) {
|
|
96
|
+
writer.writeVarInt(points.length);
|
|
97
|
+
const previousPoint = [0, 0, 0, 0];
|
|
98
|
+
for (const point of points) {
|
|
99
|
+
writeTwkbPoint(writer, context, point, previousPoint);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return writer.arrayBuffer;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function encodePolygon(
|
|
107
|
+
writer: BinaryWriter,
|
|
108
|
+
context: TWKBEncoderContext,
|
|
109
|
+
polygon: Polygon
|
|
110
|
+
): ArrayBuffer {
|
|
111
|
+
const polygonRings = polygon.coordinates;
|
|
112
|
+
|
|
113
|
+
const isEmpty = polygonRings.length === 0;
|
|
114
|
+
|
|
115
|
+
writeTwkbHeader(writer, context, WKBGeometryType.Polygon, isEmpty);
|
|
116
|
+
|
|
117
|
+
if (!isEmpty) {
|
|
118
|
+
writer.writeVarInt(polygonRings.length);
|
|
119
|
+
|
|
120
|
+
const previousPoint = [0, 0, 0, 0];
|
|
121
|
+
for (const ring of polygonRings) {
|
|
122
|
+
writer.writeVarInt(ring.length);
|
|
123
|
+
for (const point of ring) {
|
|
124
|
+
writeTwkbPoint(writer, context, previousPoint, point);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return writer.arrayBuffer;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function encodeMultiPoint(
|
|
133
|
+
writer: BinaryWriter,
|
|
134
|
+
context: TWKBEncoderContext,
|
|
135
|
+
multiPoint: MultiPoint
|
|
136
|
+
): void {
|
|
137
|
+
const points = multiPoint.coordinates;
|
|
138
|
+
const isEmpty = points.length === 0;
|
|
139
|
+
|
|
140
|
+
writeTwkbHeader(writer, context, WKBGeometryType.MultiPoint, isEmpty);
|
|
141
|
+
|
|
142
|
+
if (!isEmpty) {
|
|
143
|
+
writer.writeVarInt(points.length);
|
|
144
|
+
|
|
145
|
+
const previousPoint = [0, 0, 0, 0];
|
|
146
|
+
for (let i = 0; i < points.length; i++) {
|
|
147
|
+
writeTwkbPoint(writer, context, previousPoint, points[i]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function encodeMultiLineString(
|
|
153
|
+
writer: BinaryWriter,
|
|
154
|
+
context: TWKBEncoderContext,
|
|
155
|
+
multiLineStrings: MultiLineString
|
|
156
|
+
): ArrayBuffer {
|
|
157
|
+
const lineStrings = multiLineStrings.coordinates;
|
|
158
|
+
const isEmpty = lineStrings.length === 0;
|
|
159
|
+
|
|
160
|
+
writeTwkbHeader(writer, context, WKBGeometryType.MultiLineString, isEmpty);
|
|
161
|
+
|
|
162
|
+
if (!isEmpty) {
|
|
163
|
+
writer.writeVarInt(lineStrings.length);
|
|
164
|
+
|
|
165
|
+
const previousPoint = [0, 0, 0, 0];
|
|
166
|
+
for (const lineString of lineStrings) {
|
|
167
|
+
writer.writeVarInt(lineString.length);
|
|
168
|
+
|
|
169
|
+
for (const point of lineString) {
|
|
170
|
+
writeTwkbPoint(writer, context, previousPoint, point);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return writer.arrayBuffer;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function encodeMultiPolygon(
|
|
179
|
+
writer: BinaryWriter,
|
|
180
|
+
context: TWKBEncoderContext,
|
|
181
|
+
multiPolygon: MultiPolygon
|
|
182
|
+
): void {
|
|
183
|
+
const {coordinates} = multiPolygon;
|
|
184
|
+
const isEmpty = coordinates.length === 0;
|
|
185
|
+
|
|
186
|
+
writeTwkbHeader(writer, context, WKBGeometryType.MultiPolygon, isEmpty);
|
|
187
|
+
|
|
188
|
+
if (!isEmpty) {
|
|
189
|
+
const polygons = coordinates;
|
|
190
|
+
writer.writeVarInt(polygons.length);
|
|
191
|
+
|
|
192
|
+
const previousPoint = [0, 0, 0, 0];
|
|
193
|
+
|
|
194
|
+
for (const polygonRings of polygons) {
|
|
195
|
+
writer.writeVarInt(polygonRings.length);
|
|
196
|
+
for (const ring of polygonRings) {
|
|
197
|
+
writer.writeVarInt(ring.length);
|
|
198
|
+
for (const point of ring) {
|
|
199
|
+
writeTwkbPoint(writer, context, previousPoint, point);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function encodeGeometryCollection(
|
|
207
|
+
writer: BinaryWriter,
|
|
208
|
+
context: TWKBEncoderContext,
|
|
209
|
+
geometryCollection: GeometryCollection
|
|
210
|
+
): void {
|
|
211
|
+
const {geometries} = geometryCollection;
|
|
212
|
+
const isEmpty = geometries.length === 0;
|
|
213
|
+
|
|
214
|
+
writeTwkbHeader(writer, context, WKBGeometryType.GeometryCollection, isEmpty);
|
|
215
|
+
|
|
216
|
+
if (geometries.length > 0) {
|
|
217
|
+
writer.writeVarInt(geometries.length);
|
|
218
|
+
for (const geometry of geometries) {
|
|
219
|
+
encodeGeometry(writer, geometry, context);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
* @param writer
|
|
227
|
+
* @param context
|
|
228
|
+
* @param geometryType
|
|
229
|
+
* @param isEmpty
|
|
230
|
+
*/
|
|
231
|
+
function writeTwkbHeader(
|
|
232
|
+
writer: BinaryWriter,
|
|
233
|
+
context: TWKBEncoderContext,
|
|
234
|
+
geometryType: WKBGeometryType,
|
|
235
|
+
isEmpty: boolean
|
|
236
|
+
) {
|
|
237
|
+
const type = (zigZagEncode(context.xy) << 4) + geometryType;
|
|
238
|
+
let metadataHeader = context.hasZ || context.hasM ? 1 << 3 : 0;
|
|
239
|
+
metadataHeader += isEmpty ? 1 << 4 : 0;
|
|
240
|
+
|
|
241
|
+
writer.writeUInt8(type);
|
|
242
|
+
writer.writeUInt8(metadataHeader);
|
|
243
|
+
|
|
244
|
+
if (context.hasZ || context.hasM) {
|
|
245
|
+
let extendedPrecision = 0;
|
|
246
|
+
if (context.hasZ) {
|
|
247
|
+
extendedPrecision |= 0x1;
|
|
248
|
+
}
|
|
249
|
+
if (context.hasM) {
|
|
250
|
+
extendedPrecision |= 0x2;
|
|
251
|
+
}
|
|
252
|
+
writer.writeUInt8(extendedPrecision);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Write one point to array buffer. ZigZagEncoding the delta fdrom the previous point. Mutates previousPoint.
|
|
258
|
+
* @param writer
|
|
259
|
+
* @param context
|
|
260
|
+
* @param previousPoint - Mutated by this function
|
|
261
|
+
* @param point
|
|
262
|
+
*/
|
|
263
|
+
function writeTwkbPoint(
|
|
264
|
+
writer: BinaryWriter,
|
|
265
|
+
context: TWKBEncoderContext,
|
|
266
|
+
point: number[],
|
|
267
|
+
previousPoint: number[]
|
|
268
|
+
): void {
|
|
269
|
+
const x = point[0] * context.xyFactor;
|
|
270
|
+
const y = point[1] * context.xyFactor;
|
|
271
|
+
const z = point[2] * context.zFactor;
|
|
272
|
+
const m = point[3] * context.mFactor;
|
|
273
|
+
|
|
274
|
+
writer.writeVarInt(zigZagEncode(x - previousPoint[0]));
|
|
275
|
+
writer.writeVarInt(zigZagEncode(y - previousPoint[1]));
|
|
276
|
+
if (context.hasZ) {
|
|
277
|
+
writer.writeVarInt(zigZagEncode(z - previousPoint[2]));
|
|
278
|
+
}
|
|
279
|
+
if (context.hasM) {
|
|
280
|
+
writer.writeVarInt(zigZagEncode(m - previousPoint[3]));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
previousPoint[0] = x;
|
|
284
|
+
previousPoint[1] = y;
|
|
285
|
+
previousPoint[2] = z;
|
|
286
|
+
previousPoint[3] = m;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// HELPERS
|
|
290
|
+
|
|
291
|
+
function zigZagEncode(value: number): number {
|
|
292
|
+
return (value << 1) ^ (value >> 31);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function getTwkbPrecision(
|
|
296
|
+
xyPrecision: number,
|
|
297
|
+
zPrecision: number,
|
|
298
|
+
mPrecision: number
|
|
299
|
+
): TWKBPrecision {
|
|
300
|
+
return {
|
|
301
|
+
xy: xyPrecision,
|
|
302
|
+
z: zPrecision,
|
|
303
|
+
m: mPrecision,
|
|
304
|
+
xyFactor: Math.pow(10, xyPrecision),
|
|
305
|
+
zFactor: Math.pow(10, zPrecision),
|
|
306
|
+
mFactor: Math.pow(10, mPrecision)
|
|
307
|
+
};
|
|
308
|
+
}
|