@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.
Files changed (209) hide show
  1. package/dist/index.cjs +2411 -469
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.d.ts +31 -12
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +39 -15
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts +21 -0
  8. package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts.map +1 -0
  9. package/dist/lib/binary-geometry-api/binary-geometry-info.js +49 -0
  10. package/dist/lib/binary-geometry-api/binary-geometry-info.js.map +1 -0
  11. package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts +5 -0
  12. package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts.map +1 -0
  13. package/dist/lib/binary-geometry-api/concat-binary-geometry.js +51 -0
  14. package/dist/lib/binary-geometry-api/concat-binary-geometry.js.map +1 -0
  15. package/dist/lib/{binary-features/transform.d.ts → binary-geometry-api/transform-coordinates.d.ts} +1 -2
  16. package/dist/lib/binary-geometry-api/transform-coordinates.d.ts.map +1 -0
  17. package/dist/lib/{binary-features/transform.js → binary-geometry-api/transform-coordinates.js} +1 -1
  18. package/dist/lib/binary-geometry-api/transform-coordinates.js.map +1 -0
  19. package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts +16 -0
  20. package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts.map +1 -0
  21. package/dist/lib/{binary-features/binary-to-geojson.js → feature-collection-converters/convert-binary-features-to-geojson.js} +4 -90
  22. package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.js.map +1 -0
  23. package/dist/lib/{binary-features/flat-geojson-to-binary.d.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts} +6 -9
  24. package/dist/lib/feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts.map +1 -0
  25. package/dist/lib/{binary-features/flat-geojson-to-binary.js → feature-collection-converters/convert-flat-geojson-to-binary-features.js} +6 -5
  26. package/dist/lib/feature-collection-converters/convert-flat-geojson-to-binary-features.js.map +1 -0
  27. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts +74 -0
  28. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts.map +1 -0
  29. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.js +378 -0
  30. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.js.map +1 -0
  31. package/dist/lib/{binary-features/geojson-to-binary.d.ts → feature-collection-converters/convert-geojson-to-binary-features.d.ts} +2 -2
  32. package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.d.ts.map +1 -0
  33. package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.js +25 -0
  34. package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.js.map +1 -0
  35. package/dist/lib/{binary-features/geojson-to-flat-geojson.d.ts → feature-collection-converters/convert-geojson-to-flat-geojson.d.ts} +2 -2
  36. package/dist/lib/feature-collection-converters/convert-geojson-to-flat-geojson.d.ts.map +1 -0
  37. package/dist/lib/{binary-features/geojson-to-flat-geojson.js → feature-collection-converters/convert-geojson-to-flat-geojson.js} +5 -1
  38. package/dist/lib/feature-collection-converters/convert-geojson-to-flat-geojson.js.map +1 -0
  39. package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.d.ts.map +1 -0
  40. package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.js +5 -0
  41. package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.js.map +1 -0
  42. package/dist/lib/geometry-api/geometry-info.d.ts +21 -0
  43. package/dist/lib/geometry-api/geometry-info.d.ts.map +1 -0
  44. package/dist/lib/{binary-features/extract-geometry-info.js → geometry-api/geometry-info.js} +5 -1
  45. package/dist/lib/geometry-api/geometry-info.js.map +1 -0
  46. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts +4 -0
  47. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts.map +1 -0
  48. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.js +92 -0
  49. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.js.map +1 -0
  50. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts +13 -0
  51. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts.map +1 -0
  52. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.js +165 -0
  53. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.js.map +1 -0
  54. package/dist/lib/geometry-converters/convert-to-geojson.d.ts +6 -0
  55. package/dist/lib/geometry-converters/convert-to-geojson.d.ts.map +1 -0
  56. package/dist/lib/geometry-converters/convert-to-geojson.js +40 -0
  57. package/dist/lib/geometry-converters/convert-to-geojson.js.map +1 -0
  58. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts +6 -0
  59. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts.map +1 -0
  60. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.js +196 -0
  61. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.js.map +1 -0
  62. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts +9 -0
  63. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts.map +1 -0
  64. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.js +274 -0
  65. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.js.map +1 -0
  66. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts +8 -0
  67. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts.map +1 -0
  68. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.js +45 -0
  69. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.js.map +1 -0
  70. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts +10 -0
  71. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts.map +1 -0
  72. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.js +255 -0
  73. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.js.map +1 -0
  74. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts +3 -0
  75. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts.map +1 -0
  76. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.js +165 -0
  77. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.js.map +1 -0
  78. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts +11 -0
  79. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts.map +1 -0
  80. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.js +10 -0
  81. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.js.map +1 -0
  82. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts +16 -0
  83. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts.map +1 -0
  84. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.js +259 -0
  85. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.js.map +1 -0
  86. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts +43 -0
  87. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts.map +1 -0
  88. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.js +175 -0
  89. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.js.map +1 -0
  90. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts +64 -0
  91. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts.map +1 -0
  92. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.js +47 -0
  93. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.js.map +1 -0
  94. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts +21 -0
  95. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts.map +1 -0
  96. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.js +65 -0
  97. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.js.map +1 -0
  98. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts +8 -0
  99. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts.map +1 -0
  100. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.js +34 -0
  101. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.js.map +1 -0
  102. package/dist/lib/table-converters/convert-geoarrow-table.d.ts +27 -0
  103. package/dist/lib/table-converters/convert-geoarrow-table.d.ts.map +1 -0
  104. package/dist/lib/table-converters/convert-geoarrow-table.js +155 -0
  105. package/dist/lib/table-converters/convert-geoarrow-table.js.map +1 -0
  106. package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts +4 -0
  107. package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts.map +1 -0
  108. package/dist/lib/{tables/convert-table-to-geojson.js → table-converters/convert-wkb-table-to-geojson.js} +11 -16
  109. package/dist/lib/table-converters/convert-wkb-table-to-geojson.js.map +1 -0
  110. package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts +6 -0
  111. package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts.map +1 -0
  112. package/dist/lib/table-converters/make-arrow-batch-iterator.js +36 -0
  113. package/dist/lib/table-converters/make-arrow-batch-iterator.js.map +1 -0
  114. package/dist/lib/utils/base64-encoder.d.ts +5 -0
  115. package/dist/lib/utils/base64-encoder.d.ts.map +1 -0
  116. package/dist/lib/utils/base64-encoder.js +154 -0
  117. package/dist/lib/utils/base64-encoder.js.map +1 -0
  118. package/dist/lib/utils/binary-reader.d.ts +18 -0
  119. package/dist/lib/utils/binary-reader.d.ts.map +1 -0
  120. package/dist/lib/utils/binary-reader.js +70 -0
  121. package/dist/lib/utils/binary-reader.js.map +1 -0
  122. package/dist/lib/utils/binary-writer.d.ts +30 -0
  123. package/dist/lib/utils/binary-writer.d.ts.map +1 -0
  124. package/dist/lib/utils/binary-writer.js +128 -0
  125. package/dist/lib/utils/binary-writer.js.map +1 -0
  126. package/dist/lib/utils/concat-typed-arrays.d.ts +3 -0
  127. package/dist/lib/utils/concat-typed-arrays.d.ts.map +1 -0
  128. package/dist/lib/utils/concat-typed-arrays.js +19 -0
  129. package/dist/lib/utils/concat-typed-arrays.js.map +1 -0
  130. package/dist/lib/utils/hex-encoder.d.ts +15 -0
  131. package/dist/lib/utils/hex-encoder.d.ts.map +1 -0
  132. package/dist/lib/utils/hex-encoder.js +55 -0
  133. package/dist/lib/utils/hex-encoder.js.map +1 -0
  134. package/dist/lib/utils/hex-transcoder.d.ts +15 -0
  135. package/dist/lib/utils/hex-transcoder.d.ts.map +1 -0
  136. package/dist/lib/utils/hex-transcoder.js +51 -0
  137. package/dist/lib/utils/hex-transcoder.js.map +1 -0
  138. package/dist/lib/wkt-crs/encode-wkt-crs.d.ts +10 -0
  139. package/dist/lib/wkt-crs/encode-wkt-crs.d.ts.map +1 -0
  140. package/dist/lib/wkt-crs/encode-wkt-crs.js +36 -0
  141. package/dist/lib/wkt-crs/encode-wkt-crs.js.map +1 -0
  142. package/dist/lib/wkt-crs/parse-wkt-crs.d.ts +15 -0
  143. package/dist/lib/wkt-crs/parse-wkt-crs.d.ts.map +1 -0
  144. package/dist/lib/wkt-crs/parse-wkt-crs.js +121 -0
  145. package/dist/lib/wkt-crs/parse-wkt-crs.js.map +1 -0
  146. package/package.json +7 -5
  147. package/src/index.ts +87 -14
  148. package/src/lib/binary-geometry-api/binary-geometry-info.ts +75 -0
  149. package/src/lib/binary-geometry-api/concat-binary-geometry.ts +78 -0
  150. package/src/lib/{binary-features/transform.ts → binary-geometry-api/transform-coordinates.ts} +0 -1
  151. package/src/lib/{binary-features/binary-to-geojson.ts → feature-collection-converters/convert-binary-features-to-geojson.ts} +5 -142
  152. package/src/lib/{binary-features/flat-geojson-to-binary.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.ts} +14 -9
  153. package/src/lib/feature-collection-converters/convert-geoarrow-to-binary-features.ts +496 -0
  154. package/src/lib/{binary-features/geojson-to-binary.ts → feature-collection-converters/convert-geojson-to-binary-features.ts} +11 -7
  155. package/src/lib/{binary-features/geojson-to-flat-geojson.ts → feature-collection-converters/convert-geojson-to-flat-geojson.ts} +5 -1
  156. package/src/lib/{binary-features → feature-collection-converters/helpers}/flat-geojson-to-binary-types.ts +4 -0
  157. package/src/lib/{binary-features/extract-geometry-info.ts → geometry-api/geometry-info.ts} +20 -2
  158. package/src/lib/geometry-converters/convert-binary-geometry-to-geojson.ts +148 -0
  159. package/src/lib/geometry-converters/convert-geoarrow-to-geojson.ts +193 -0
  160. package/src/lib/geometry-converters/convert-to-geojson.ts +52 -0
  161. package/src/lib/geometry-converters/wkb/convert-geometry-to-twkb.ts +308 -0
  162. package/src/lib/geometry-converters/wkb/convert-geometry-to-wkb.ts +365 -0
  163. package/src/lib/geometry-converters/wkb/convert-geometry-to-wkt.ts +54 -0
  164. package/src/lib/geometry-converters/wkb/convert-twkb-to-geometry.ts +366 -0
  165. package/src/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.ts +238 -0
  166. package/src/lib/geometry-converters/wkb/convert-wkb-to-geometry.ts +23 -0
  167. package/src/lib/geometry-converters/wkb/convert-wkt-to-geometry.ts +294 -0
  168. package/src/lib/geometry-converters/wkb/helpers/parse-wkb-header.ts +213 -0
  169. package/src/lib/geometry-converters/wkb/helpers/wkb-types.ts +82 -0
  170. package/src/lib/geometry-converters/wkb/helpers/wkb-utils.ts +85 -0
  171. package/src/lib/geometry-converters/wkb/helpers/write-wkb-header.ts +41 -0
  172. package/src/lib/table-converters/convert-geoarrow-table.ts +218 -0
  173. package/src/lib/{tables/convert-table-to-geojson.ts → table-converters/convert-wkb-table-to-geojson.ts} +10 -23
  174. package/src/lib/table-converters/make-arrow-batch-iterator.ts +53 -0
  175. package/src/lib/utils/base64-encoder.ts +157 -0
  176. package/src/lib/utils/binary-reader.ts +76 -0
  177. package/src/lib/utils/binary-writer.ts +136 -0
  178. package/src/lib/utils/concat-typed-arrays.ts +24 -0
  179. package/src/lib/utils/hex-encoder.ts +60 -0
  180. package/src/lib/utils/hex-transcoder.ts +54 -0
  181. package/src/lib/wkt-crs/encode-wkt-crs.ts +41 -0
  182. package/src/lib/wkt-crs/parse-wkt-crs.ts +149 -0
  183. package/dist/lib/binary-features/binary-to-geojson.d.ts +0 -18
  184. package/dist/lib/binary-features/binary-to-geojson.d.ts.map +0 -1
  185. package/dist/lib/binary-features/extract-geometry-info.d.ts +0 -8
  186. package/dist/lib/binary-features/extract-geometry-info.d.ts.map +0 -1
  187. package/dist/lib/binary-features/flat-geojson-to-binary-types.d.ts.map +0 -1
  188. package/dist/lib/binary-features/flat-geojson-to-binary-types.js +0 -1
  189. package/dist/lib/binary-features/flat-geojson-to-binary.d.ts.map +0 -1
  190. package/dist/lib/binary-features/geojson-to-binary.d.ts.map +0 -1
  191. package/dist/lib/binary-features/geojson-to-binary.js +0 -21
  192. package/dist/lib/binary-features/geojson-to-flat-geojson.d.ts.map +0 -1
  193. package/dist/lib/binary-features/transform.d.ts.map +0 -1
  194. package/dist/lib/geo/geoarrow-metadata.d.ts +0 -27
  195. package/dist/lib/geo/geoarrow-metadata.d.ts.map +0 -1
  196. package/dist/lib/geo/geoarrow-metadata.js +0 -70
  197. package/dist/lib/geo/geoparquet-metadata-schema.d.ts +0 -79
  198. package/dist/lib/geo/geoparquet-metadata-schema.d.ts.map +0 -1
  199. package/dist/lib/geo/geoparquet-metadata-schema.js +0 -69
  200. package/dist/lib/geo/geoparquet-metadata.d.ts +0 -45
  201. package/dist/lib/geo/geoparquet-metadata.d.ts.map +0 -1
  202. package/dist/lib/geo/geoparquet-metadata.js +0 -117
  203. package/dist/lib/tables/convert-table-to-geojson.d.ts +0 -5
  204. package/dist/lib/tables/convert-table-to-geojson.d.ts.map +0 -1
  205. package/src/lib/geo/geoarrow-metadata.ts +0 -100
  206. package/src/lib/geo/geoparquet-metadata-schema.json +0 -60
  207. package/src/lib/geo/geoparquet-metadata-schema.ts +0 -71
  208. package/src/lib/geo/geoparquet-metadata.ts +0 -191
  209. /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
+ }