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