@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,294 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
// Fork of https://github.com/mapbox/wellknown under ISC license (MIT/BSD-2-clause equivalent)
|
|
5
|
+
|
|
6
|
+
import type {Geometry} from '@loaders.gl/schema';
|
|
7
|
+
|
|
8
|
+
/* eslint-disable */
|
|
9
|
+
// @ts-nocheck
|
|
10
|
+
|
|
11
|
+
const numberRegexp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/;
|
|
12
|
+
// Matches sequences like '100 100' or '100 100 100'.
|
|
13
|
+
const tuples = new RegExp('^' + numberRegexp.source + '(\\s' + numberRegexp.source + '){1,}');
|
|
14
|
+
|
|
15
|
+
export type ParseWKTOptions = {
|
|
16
|
+
wkt?: {
|
|
17
|
+
/** Whether to add any CRS, if found, as undocumented CRS property on the return geometry */
|
|
18
|
+
crs?: boolean;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** State of parser, passed around between parser functions */
|
|
23
|
+
type ParseWKTState = {
|
|
24
|
+
parts: string[];
|
|
25
|
+
_: string | undefined;
|
|
26
|
+
i: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse WKT and return GeoJSON.
|
|
31
|
+
* @param input A WKT geometry string
|
|
32
|
+
* @return A GeoJSON geometry object
|
|
33
|
+
*
|
|
34
|
+
* @note We only support the "geojson" subset of the OGC simple features standard
|
|
35
|
+
**/
|
|
36
|
+
export function convertWKTToGeometry(input: string, options?: ParseWKTOptions): Geometry | null {
|
|
37
|
+
const parts = input.split(';');
|
|
38
|
+
let _ = parts.pop();
|
|
39
|
+
const srid = (parts.shift() || '').split('=').pop();
|
|
40
|
+
|
|
41
|
+
const state: ParseWKTState = {parts, _, i: 0};
|
|
42
|
+
|
|
43
|
+
const geometry = parseGeometry(state);
|
|
44
|
+
|
|
45
|
+
return options?.wkt?.crs ? addCRS(geometry, srid) : geometry;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function parseGeometry(state: ParseWKTState): Geometry | null {
|
|
49
|
+
return (
|
|
50
|
+
parsePoint(state) ||
|
|
51
|
+
parseLineString(state) ||
|
|
52
|
+
parsePolygon(state) ||
|
|
53
|
+
parseMultiPoint(state) ||
|
|
54
|
+
parseMultiLineString(state) ||
|
|
55
|
+
parseMultiPolygon(state) ||
|
|
56
|
+
parseGeometryCollection(state)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Adds a coordinate reference system as an undocumented */
|
|
61
|
+
function addCRS(obj: Geometry | null, srid?: string): Geometry | null {
|
|
62
|
+
if (obj && srid?.match(/\d+/)) {
|
|
63
|
+
const crs = {
|
|
64
|
+
type: 'name',
|
|
65
|
+
properties: {
|
|
66
|
+
name: 'urn:ogc:def:crs:EPSG::' + srid
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// @ts-expect-error we assign an undocumented property on the geometry
|
|
70
|
+
obj.crs = crs;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// GEOMETRIES
|
|
77
|
+
|
|
78
|
+
function parsePoint(state: ParseWKTState): Geometry | null {
|
|
79
|
+
if (!$(/^(POINT(\sz)?)/i, state)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
white(state);
|
|
83
|
+
if (!$(/^(\()/, state)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const c = coords(state);
|
|
87
|
+
if (!c) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
white(state);
|
|
91
|
+
if (!$(/^(\))/, state)) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
type: 'Point',
|
|
96
|
+
coordinates: c[0]
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function parseMultiPoint(state: ParseWKTState): Geometry | null {
|
|
101
|
+
if (!$(/^(MULTIPOINT)/i, state)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
white(state);
|
|
105
|
+
const newCoordsFormat = state._?.substring(state._?.indexOf('(') + 1, state._.length - 1)
|
|
106
|
+
.replace(/\(/g, '')
|
|
107
|
+
.replace(/\)/g, '');
|
|
108
|
+
state._ = 'MULTIPOINT (' + newCoordsFormat + ')';
|
|
109
|
+
const c = multicoords(state);
|
|
110
|
+
if (!c) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
white(state);
|
|
114
|
+
return {
|
|
115
|
+
type: 'MultiPoint',
|
|
116
|
+
coordinates: c
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function parseLineString(state: ParseWKTState): Geometry | null {
|
|
121
|
+
if (!$(/^(LINESTRING(\sz)?)/i, state)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
white(state);
|
|
125
|
+
if (!$(/^(\()/, state)) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const c = coords(state);
|
|
129
|
+
if (!c) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (!$(/^(\))/, state)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
type: 'LineString',
|
|
137
|
+
coordinates: c
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function parseMultiLineString(state: ParseWKTState): Geometry | null {
|
|
142
|
+
if (!$(/^(MULTILINESTRING)/i, state)) return null;
|
|
143
|
+
white(state);
|
|
144
|
+
const c = multicoords(state);
|
|
145
|
+
if (!c) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
white(state);
|
|
149
|
+
return {
|
|
150
|
+
// @ts-ignore
|
|
151
|
+
type: 'MultiLineString',
|
|
152
|
+
// @ts-expect-error
|
|
153
|
+
coordinates: c
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function parsePolygon(state: ParseWKTState): Geometry | null {
|
|
158
|
+
if (!$(/^(POLYGON(\sz)?)/i, state)) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
white(state);
|
|
162
|
+
const c = multicoords(state);
|
|
163
|
+
if (!c) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
type: 'Polygon',
|
|
169
|
+
// @ts-expect-error
|
|
170
|
+
coordinates: c
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function parseMultiPolygon(state: ParseWKTState): Geometry | null {
|
|
175
|
+
if (!$(/^(MULTIPOLYGON)/i, state)) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
white(state);
|
|
179
|
+
const c = multicoords(state);
|
|
180
|
+
if (!c) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
type: 'MultiPolygon',
|
|
185
|
+
// @ts-expect-error
|
|
186
|
+
coordinates: c
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function parseGeometryCollection(state: ParseWKTState): Geometry | null {
|
|
191
|
+
const geometries: Geometry[] = [];
|
|
192
|
+
let geometry: Geometry | null;
|
|
193
|
+
|
|
194
|
+
if (!$(/^(GEOMETRYCOLLECTION)/i, state)) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
white(state);
|
|
198
|
+
|
|
199
|
+
if (!$(/^(\()/, state)) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
while ((geometry = parseGeometry(state))) {
|
|
203
|
+
geometries.push(geometry);
|
|
204
|
+
white(state);
|
|
205
|
+
$(/^(,)/, state);
|
|
206
|
+
white(state);
|
|
207
|
+
}
|
|
208
|
+
if (!$(/^(\))/, state)) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
type: 'GeometryCollection',
|
|
214
|
+
geometries: geometries
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// COORDINATES
|
|
219
|
+
|
|
220
|
+
function multicoords(state: ParseWKTState): number[][] | null {
|
|
221
|
+
white(state);
|
|
222
|
+
let depth = 0;
|
|
223
|
+
const rings: number[][] = [];
|
|
224
|
+
const stack = [rings];
|
|
225
|
+
let pointer: any = rings;
|
|
226
|
+
let elem;
|
|
227
|
+
|
|
228
|
+
while ((elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state))) {
|
|
229
|
+
if (elem === '(') {
|
|
230
|
+
stack.push(pointer);
|
|
231
|
+
pointer = [];
|
|
232
|
+
stack[stack.length - 1].push(pointer);
|
|
233
|
+
depth++;
|
|
234
|
+
} else if (elem === ')') {
|
|
235
|
+
// For the case: Polygon(), ...
|
|
236
|
+
if (pointer.length === 0) return null;
|
|
237
|
+
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
pointer = stack.pop();
|
|
240
|
+
// the stack was empty, input was malformed
|
|
241
|
+
if (!pointer) return null;
|
|
242
|
+
depth--;
|
|
243
|
+
if (depth === 0) break;
|
|
244
|
+
} else if (elem === ',') {
|
|
245
|
+
pointer = [];
|
|
246
|
+
stack[stack.length - 1].push(pointer);
|
|
247
|
+
} else if (!elem.split(/\s/g).some(isNaN)) {
|
|
248
|
+
Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
|
|
249
|
+
} else {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
white(state);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (depth !== 0) return null;
|
|
256
|
+
|
|
257
|
+
return rings;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function coords(state: ParseWKTState): number[][] | null {
|
|
261
|
+
const list: number[][] = [];
|
|
262
|
+
let item: any;
|
|
263
|
+
let pt;
|
|
264
|
+
while ((pt = $(tuples, state) || $(/^(,)/, state))) {
|
|
265
|
+
if (pt === ',') {
|
|
266
|
+
list.push(item);
|
|
267
|
+
item = [];
|
|
268
|
+
} else if (!pt.split(/\s/g).some(isNaN)) {
|
|
269
|
+
if (!item) item = [];
|
|
270
|
+
Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
|
|
271
|
+
}
|
|
272
|
+
white(state);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (item) list.push(item);
|
|
276
|
+
else return null;
|
|
277
|
+
|
|
278
|
+
return list.length ? list : null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// HELPERS
|
|
282
|
+
|
|
283
|
+
function $(regexp: RegExp, state: ParseWKTState) {
|
|
284
|
+
const match = state._?.substring(state.i).match(regexp);
|
|
285
|
+
if (!match) return null;
|
|
286
|
+
else {
|
|
287
|
+
state.i += match[0].length;
|
|
288
|
+
return match[0];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function white(state: ParseWKTState) {
|
|
293
|
+
$(/^\s*/, state);
|
|
294
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {WKBGeometryType, WKBHeader} from './wkb-types';
|
|
6
|
+
import {
|
|
7
|
+
EWKB_FLAG_Z,
|
|
8
|
+
EWKB_FLAG_M,
|
|
9
|
+
EWKB_FLAG_SRID,
|
|
10
|
+
MAX_SRID,
|
|
11
|
+
WKT_MAGIC_STRINGS,
|
|
12
|
+
WKT_MAGIC_BYTES
|
|
13
|
+
} from './wkb-types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if a string is WKT.
|
|
17
|
+
* @param input A potential WKT geometry string
|
|
18
|
+
* @return `true` if input appears to be a WKT geometry string, `false` otherwise
|
|
19
|
+
|
|
20
|
+
* @note We only support the "geojson" subset of the OGC simple features standard
|
|
21
|
+
* @todo Does not handle leading spaces which appear to be permitted per the spec:
|
|
22
|
+
* "A WKT string contains no white space outside of double quotes.
|
|
23
|
+
* However padding with white space to improve human readability is permitted;
|
|
24
|
+
* the examples of WKT that are included in this document have
|
|
25
|
+
* spaces and line feeds inserted to improve clarity. Any padding is stripped out or ignored by parsers."
|
|
26
|
+
*/
|
|
27
|
+
export function isWKT(input: string | ArrayBufferLike): boolean {
|
|
28
|
+
return getWKTGeometryType(input) !== null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get the geometry type of a WKT string.
|
|
33
|
+
* @param input A potential WKT geometry string
|
|
34
|
+
* @return `true` if input appears to be a WKT geometry string, `false` otherwise
|
|
35
|
+
|
|
36
|
+
* @note We only support the "geojson" subset of the OGC simple features standard
|
|
37
|
+
* @todo Does not handle leading spaces which appear to be permitted per the spec:
|
|
38
|
+
* "A WKT string contains no white space outside of double quotes.
|
|
39
|
+
* However padding with white space to improve human readability is permitted;
|
|
40
|
+
* the examples of WKT that are included in this document have
|
|
41
|
+
* spaces and line feeds inserted to improve clarity. Any padding is stripped out or ignored by parsers."
|
|
42
|
+
*/
|
|
43
|
+
export function getWKTGeometryType(input: string | ArrayBufferLike): WKBGeometryType | null {
|
|
44
|
+
if (typeof input === 'string') {
|
|
45
|
+
const index = WKT_MAGIC_STRINGS.findIndex((magicString) => input.startsWith(magicString));
|
|
46
|
+
return index >= 0 ? ((index + 1) as WKBGeometryType) : null;
|
|
47
|
+
}
|
|
48
|
+
const inputArray = new Uint8Array(input);
|
|
49
|
+
const index = WKT_MAGIC_BYTES.findIndex((magicBytes) =>
|
|
50
|
+
magicBytes.every((value, index) => value === inputArray[index])
|
|
51
|
+
);
|
|
52
|
+
return index >= 0 ? ((index + 1) as WKBGeometryType) : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if an array buffer might be a TWKB array buffer
|
|
57
|
+
* @param arrayBuffer The array buffer to check
|
|
58
|
+
* @returns false if this is definitely not a TWKB array buffer, true if it might be a TWKB array buffer
|
|
59
|
+
*/
|
|
60
|
+
export function isTWKB(arrayBuffer: ArrayBufferLike): boolean {
|
|
61
|
+
const dataView = new DataView(arrayBuffer);
|
|
62
|
+
const byteOffset = 0;
|
|
63
|
+
|
|
64
|
+
const type = dataView.getUint8(byteOffset);
|
|
65
|
+
const geometryType = type & 0x0f;
|
|
66
|
+
|
|
67
|
+
// Only geometry types 1 to 7 (point to geometry collection are currently defined)
|
|
68
|
+
if (geometryType < 1 || geometryType > 7) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Sanity checks that first to 5-9 bytes could represent a supported WKB dialect header */
|
|
76
|
+
export function isWKB(arrayBuffer: ArrayBufferLike): boolean {
|
|
77
|
+
const dataView = new DataView(arrayBuffer);
|
|
78
|
+
let byteOffset = 0;
|
|
79
|
+
|
|
80
|
+
const endianness = dataView.getUint8(byteOffset);
|
|
81
|
+
byteOffset += 1;
|
|
82
|
+
|
|
83
|
+
// Check valid endianness (only 0 or 1 are allowed)
|
|
84
|
+
if (endianness > 1) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const littleEndian = endianness === 1;
|
|
89
|
+
|
|
90
|
+
const geometry = dataView.getUint32(byteOffset, littleEndian);
|
|
91
|
+
byteOffset += 4;
|
|
92
|
+
|
|
93
|
+
// check valid geometry type (we don't support extension geometries)
|
|
94
|
+
const geometryType = geometry & 0x07;
|
|
95
|
+
if (geometryType === 0 || geometryType > 7) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const geometryFlags = geometry - geometryType;
|
|
100
|
+
|
|
101
|
+
// Accept iso-wkb flags
|
|
102
|
+
if (
|
|
103
|
+
geometryFlags === 0 ||
|
|
104
|
+
geometryFlags === 1000 ||
|
|
105
|
+
geometryFlags === 2000 ||
|
|
106
|
+
geometryFlags === 3000
|
|
107
|
+
) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Accept ewkb flags but reject otherwise
|
|
112
|
+
if ((geometryFlags & ~(EWKB_FLAG_Z | EWKB_FLAG_M | EWKB_FLAG_SRID)) !== 0) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (geometryFlags & EWKB_FLAG_SRID) {
|
|
117
|
+
const srid = dataView.getUint32(byteOffset, littleEndian);
|
|
118
|
+
byteOffset += 4;
|
|
119
|
+
|
|
120
|
+
if (srid > MAX_SRID) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Parses header and provides a byteOffset to start of geometry data
|
|
130
|
+
* @param dataView
|
|
131
|
+
* @param target optionally supply a WKBHeader object to avoid creating a new object for every call
|
|
132
|
+
* @returns a header object describing the WKB data
|
|
133
|
+
*/
|
|
134
|
+
// eslint-disable-next-line max-statements, complexity
|
|
135
|
+
export function parseWKBHeader(dataView: DataView, target?: WKBHeader): WKBHeader {
|
|
136
|
+
const wkbHeader: WKBHeader = Object.assign(target || {}, {
|
|
137
|
+
type: 'wkb',
|
|
138
|
+
variant: 'wkb',
|
|
139
|
+
geometryType: 1,
|
|
140
|
+
dimensions: 2,
|
|
141
|
+
coordinates: 'xy',
|
|
142
|
+
littleEndian: true,
|
|
143
|
+
byteOffset: 0
|
|
144
|
+
} as WKBHeader);
|
|
145
|
+
|
|
146
|
+
if (isWKT(dataView.buffer)) {
|
|
147
|
+
// TODO - WKB header could include WKT type
|
|
148
|
+
throw new Error('WKB: Cannot parse WKT data');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check endianness of data
|
|
152
|
+
wkbHeader.littleEndian = dataView.getUint8(wkbHeader.byteOffset) === 1;
|
|
153
|
+
wkbHeader.byteOffset++;
|
|
154
|
+
|
|
155
|
+
// 4-digit code representing dimension and type of geometry
|
|
156
|
+
const geometryCode = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
|
|
157
|
+
wkbHeader.byteOffset += 4;
|
|
158
|
+
|
|
159
|
+
wkbHeader.geometryType = (geometryCode & 0x7) as 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
160
|
+
|
|
161
|
+
// Check if iso-wkb variant: iso-wkb adds 1000, 2000 or 3000 to the geometry code
|
|
162
|
+
const isoType = (geometryCode - wkbHeader.geometryType) / 1000;
|
|
163
|
+
switch (isoType) {
|
|
164
|
+
case 0:
|
|
165
|
+
break;
|
|
166
|
+
case 1:
|
|
167
|
+
wkbHeader.variant = 'iso-wkb';
|
|
168
|
+
wkbHeader.dimensions = 3;
|
|
169
|
+
wkbHeader.coordinates = 'xyz';
|
|
170
|
+
break;
|
|
171
|
+
case 2:
|
|
172
|
+
wkbHeader.variant = 'iso-wkb';
|
|
173
|
+
wkbHeader.dimensions = 3;
|
|
174
|
+
wkbHeader.coordinates = 'xym';
|
|
175
|
+
break;
|
|
176
|
+
case 3:
|
|
177
|
+
wkbHeader.variant = 'iso-wkb';
|
|
178
|
+
wkbHeader.dimensions = 4;
|
|
179
|
+
wkbHeader.coordinates = 'xyzm';
|
|
180
|
+
break;
|
|
181
|
+
default:
|
|
182
|
+
throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Check if EWKB variant. Uses bitmasks for Z&M dimensions as well as optional SRID field
|
|
186
|
+
const ewkbZ = geometryCode & EWKB_FLAG_Z;
|
|
187
|
+
const ewkbM = geometryCode & EWKB_FLAG_M;
|
|
188
|
+
const ewkbSRID = geometryCode & EWKB_FLAG_SRID;
|
|
189
|
+
|
|
190
|
+
if (ewkbZ && ewkbM) {
|
|
191
|
+
wkbHeader.variant = 'ewkb';
|
|
192
|
+
wkbHeader.dimensions = 4;
|
|
193
|
+
wkbHeader.coordinates = 'xyzm';
|
|
194
|
+
} else if (ewkbZ) {
|
|
195
|
+
wkbHeader.variant = 'ewkb';
|
|
196
|
+
wkbHeader.dimensions = 3;
|
|
197
|
+
wkbHeader.coordinates = 'xyz';
|
|
198
|
+
} else if (ewkbM) {
|
|
199
|
+
wkbHeader.variant = 'ewkb';
|
|
200
|
+
wkbHeader.dimensions = 3;
|
|
201
|
+
wkbHeader.coordinates = 'xym';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// If SRID present read four more bytes
|
|
205
|
+
if (ewkbSRID) {
|
|
206
|
+
wkbHeader.variant = 'ewkb';
|
|
207
|
+
// 4-digit code representing dimension and type of geometry
|
|
208
|
+
wkbHeader.srid = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
|
|
209
|
+
wkbHeader.byteOffset += 4;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return wkbHeader;
|
|
213
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Integer codes for geometry types in WKB and related formats
|
|
7
|
+
* @see: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
|
8
|
+
*/
|
|
9
|
+
export enum WKBGeometryType {
|
|
10
|
+
Point = 1,
|
|
11
|
+
LineString = 2,
|
|
12
|
+
Polygon = 3,
|
|
13
|
+
MultiPoint = 4,
|
|
14
|
+
MultiLineString = 5,
|
|
15
|
+
MultiPolygon = 6,
|
|
16
|
+
GeometryCollection = 7
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Parsed WKB header */
|
|
20
|
+
export type WKBHeader = {
|
|
21
|
+
/** WKB or TWKB */
|
|
22
|
+
type: 'wkb' | 'twkb';
|
|
23
|
+
/** WKB variant */
|
|
24
|
+
variant: 'wkb' | 'ewkb' | 'iso-wkb' | 'twkb';
|
|
25
|
+
/** geometry type encoded in this WKB: point, line, polygon etc */
|
|
26
|
+
geometryType: 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
27
|
+
/** Number of dimensions for coordinate data */
|
|
28
|
+
dimensions: 2 | 3 | 4;
|
|
29
|
+
/** Coordinate names, Z and M are controlled by flags */
|
|
30
|
+
coordinates: 'xy' | 'xyz' | 'xym' | 'xyzm';
|
|
31
|
+
/** WKB Geometry has a spatial coordinate reference system id */
|
|
32
|
+
srid?: number;
|
|
33
|
+
/** true if binary data is stored as little endian */
|
|
34
|
+
littleEndian: boolean;
|
|
35
|
+
/** Offset to start of geometry */
|
|
36
|
+
byteOffset: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Options for writing WKB
|
|
41
|
+
*/
|
|
42
|
+
export type WKBOptions = {
|
|
43
|
+
/** Does the GeoJSON input have Z values? */
|
|
44
|
+
hasZ?: boolean;
|
|
45
|
+
/** Does the GeoJSON input have M values? */
|
|
46
|
+
hasM?: boolean;
|
|
47
|
+
/** Spatial reference for input GeoJSON */
|
|
48
|
+
srid?: any;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** WKB Geometry has a z coordinate */
|
|
52
|
+
export const EWKB_FLAG_Z = 0x80000000;
|
|
53
|
+
/** WKB Geometry has an m coordinate */
|
|
54
|
+
export const EWKB_FLAG_M = 0x40000000;
|
|
55
|
+
/** WKB Geometry has a spatial coordinate reference system id */
|
|
56
|
+
export const EWKB_FLAG_SRID = 0x20000000;
|
|
57
|
+
/** @todo: Assume no more than 10K SRIDs are defined */
|
|
58
|
+
export const MAX_SRID = 10000;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @see: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
|
62
|
+
* @note Order matches WKBGeometryType enum (need to add 1)
|
|
63
|
+
* @note: We only support this "geojson" subset of the OGC simple features standard
|
|
64
|
+
*/
|
|
65
|
+
export const WKT_MAGIC_STRINGS = [
|
|
66
|
+
'POINT(',
|
|
67
|
+
'LINESTRING(',
|
|
68
|
+
'POLYGON(',
|
|
69
|
+
'MULTIPOINT(',
|
|
70
|
+
'MULTILINESTRING(',
|
|
71
|
+
'MULTIPOLYGON(',
|
|
72
|
+
'GEOMETRYCOLLECTION('
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const textEncoder = new TextEncoder();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @see: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
|
79
|
+
* @note Order matches WKBGeometryType enum (need to add 1)
|
|
80
|
+
* @note: We only support this "geojson" subset of the OGC simple features standard
|
|
81
|
+
*/
|
|
82
|
+
export const WKT_MAGIC_BYTES = WKT_MAGIC_STRINGS.map((string) => textEncoder.encode(string));
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {WKBOptions} from './wkb-types';
|
|
6
|
+
import {WKBGeometryType} from './wkb-types';
|
|
7
|
+
|
|
8
|
+
const WKBGeometryTypeNames = {
|
|
9
|
+
Point: WKBGeometryType.Point,
|
|
10
|
+
LineString: WKBGeometryType.LineString,
|
|
11
|
+
Polygon: WKBGeometryType.Polygon,
|
|
12
|
+
MultiPoint: WKBGeometryType.MultiPoint,
|
|
13
|
+
MultiLineString: WKBGeometryType.MultiLineString,
|
|
14
|
+
MultiPolygon: WKBGeometryType.MultiPolygon,
|
|
15
|
+
GeometryCollection: WKBGeometryType.GeometryCollection
|
|
16
|
+
} as const satisfies Record<string, WKBGeometryType>;
|
|
17
|
+
|
|
18
|
+
/** Convert a WKB geometry type integer to GeoJSON style geometry type string*/
|
|
19
|
+
export function getGeometryTypeFromWKBType(
|
|
20
|
+
wkbGeometryType: WKBGeometryType
|
|
21
|
+
): keyof typeof WKBGeometryTypeNames {
|
|
22
|
+
for (const key in WKBGeometryTypeNames) {
|
|
23
|
+
if (WKBGeometryTypeNames[key] === wkbGeometryType) {
|
|
24
|
+
return key as keyof typeof WKBGeometryTypeNames;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
throw new Error(String(wkbGeometryType));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Convert a GeoJSON style geometry type string to a WKB geometry type integer*/
|
|
31
|
+
export function getWKBTypeFromGeometryType(
|
|
32
|
+
geometryType: keyof typeof WKBGeometryTypeNames
|
|
33
|
+
): WKBGeometryType {
|
|
34
|
+
return WKBGeometryTypeNames[geometryType];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Sanity: Adjust Z/M dimensions with actual point size */
|
|
38
|
+
export function matchWKBOptionsToPointSize(
|
|
39
|
+
pointSize: number,
|
|
40
|
+
options?: WKBOptions
|
|
41
|
+
): Required<WKBOptions> {
|
|
42
|
+
const wkbOptions: Required<WKBOptions> = {hasZ: false, hasM: false, srid: undefined, ...options};
|
|
43
|
+
|
|
44
|
+
// Align options with actual point size
|
|
45
|
+
switch (pointSize) {
|
|
46
|
+
case 4:
|
|
47
|
+
wkbOptions.hasZ = true;
|
|
48
|
+
wkbOptions.hasM = true;
|
|
49
|
+
break;
|
|
50
|
+
|
|
51
|
+
case 3:
|
|
52
|
+
// Prefer Z over M
|
|
53
|
+
if (wkbOptions.hasZ && wkbOptions.hasM) {
|
|
54
|
+
wkbOptions.hasM = false;
|
|
55
|
+
}
|
|
56
|
+
if (!wkbOptions.hasZ && !wkbOptions.hasM) {
|
|
57
|
+
wkbOptions.hasZ = true;
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 2:
|
|
62
|
+
wkbOptions.hasZ = false;
|
|
63
|
+
wkbOptions.hasM = false;
|
|
64
|
+
break;
|
|
65
|
+
|
|
66
|
+
default:
|
|
67
|
+
// ignore - broken input data?
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return wkbOptions;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Get coordinate size given Z/M dimensions */
|
|
74
|
+
export function getCoordinateByteSize(options?: WKBOptions): number {
|
|
75
|
+
let coordinateByteSize = 16;
|
|
76
|
+
|
|
77
|
+
if (options?.hasZ) {
|
|
78
|
+
coordinateByteSize += 8;
|
|
79
|
+
}
|
|
80
|
+
if (options?.hasM) {
|
|
81
|
+
coordinateByteSize += 8;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return coordinateByteSize;
|
|
85
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {BinaryWriter} from '../../../utils/binary-writer';
|
|
6
|
+
import type {WKBOptions} from './wkb-types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Construct and write WKB integer code
|
|
10
|
+
* Reference: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
|
11
|
+
*/
|
|
12
|
+
export function writeWkbHeader(
|
|
13
|
+
writer: BinaryWriter,
|
|
14
|
+
geometryType: number,
|
|
15
|
+
options?: WKBOptions
|
|
16
|
+
): void {
|
|
17
|
+
// little endian
|
|
18
|
+
writer.writeInt8(1);
|
|
19
|
+
const {hasZ, hasM, srid} = options || {};
|
|
20
|
+
|
|
21
|
+
let dimensionType = 0;
|
|
22
|
+
|
|
23
|
+
if (!srid) {
|
|
24
|
+
if (hasZ && hasM) {
|
|
25
|
+
dimensionType += 3000;
|
|
26
|
+
} else if (hasZ) {
|
|
27
|
+
dimensionType += 1000;
|
|
28
|
+
} else if (hasM) {
|
|
29
|
+
dimensionType += 2000;
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
if (hasZ) {
|
|
33
|
+
dimensionType |= 0x80000000;
|
|
34
|
+
}
|
|
35
|
+
if (hasM) {
|
|
36
|
+
dimensionType |= 0x40000000;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
writer.writeUInt32LE((dimensionType + geometryType) >>> 0);
|
|
41
|
+
}
|