@loaders.gl/gis 4.3.1 → 4.4.0-alpha.1

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 (173) 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 +38 -15
  6. package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts +21 -0
  7. package/dist/lib/binary-geometry-api/binary-geometry-info.d.ts.map +1 -0
  8. package/dist/lib/binary-geometry-api/binary-geometry-info.js +48 -0
  9. package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts +5 -0
  10. package/dist/lib/binary-geometry-api/concat-binary-geometry.d.ts.map +1 -0
  11. package/dist/lib/binary-geometry-api/concat-binary-geometry.js +50 -0
  12. package/dist/lib/{binary-features/transform.d.ts → binary-geometry-api/transform-coordinates.d.ts} +1 -2
  13. package/dist/lib/binary-geometry-api/transform-coordinates.d.ts.map +1 -0
  14. package/dist/lib/{binary-features/transform.js → binary-geometry-api/transform-coordinates.js} +0 -1
  15. package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts +16 -0
  16. package/dist/lib/feature-collection-converters/convert-binary-features-to-geojson.d.ts.map +1 -0
  17. package/dist/lib/{binary-features/binary-to-geojson.js → feature-collection-converters/convert-binary-features-to-geojson.js} +3 -90
  18. package/dist/lib/{binary-features/flat-geojson-to-binary.d.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts} +6 -9
  19. package/dist/lib/feature-collection-converters/convert-flat-geojson-to-binary-features.d.ts.map +1 -0
  20. package/dist/lib/{binary-features/flat-geojson-to-binary.js → feature-collection-converters/convert-flat-geojson-to-binary-features.js} +5 -5
  21. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts +74 -0
  22. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.d.ts.map +1 -0
  23. package/dist/lib/feature-collection-converters/convert-geoarrow-to-binary-features.js +377 -0
  24. package/dist/lib/{binary-features/geojson-to-binary.d.ts → feature-collection-converters/convert-geojson-to-binary-features.d.ts} +2 -2
  25. package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.d.ts.map +1 -0
  26. package/dist/lib/feature-collection-converters/convert-geojson-to-binary-features.js +24 -0
  27. package/dist/lib/{binary-features/geojson-to-flat-geojson.d.ts → feature-collection-converters/convert-geojson-to-flat-geojson.d.ts} +2 -2
  28. package/dist/lib/feature-collection-converters/convert-geojson-to-flat-geojson.d.ts.map +1 -0
  29. package/dist/lib/{binary-features/geojson-to-flat-geojson.js → feature-collection-converters/convert-geojson-to-flat-geojson.js} +4 -1
  30. package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.d.ts.map +1 -0
  31. package/dist/lib/feature-collection-converters/helpers/flat-geojson-to-binary-types.js +4 -0
  32. package/dist/lib/geometry-api/geometry-info.d.ts +21 -0
  33. package/dist/lib/geometry-api/geometry-info.d.ts.map +1 -0
  34. package/dist/lib/{binary-features/extract-geometry-info.js → geometry-api/geometry-info.js} +4 -1
  35. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts +4 -0
  36. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.d.ts.map +1 -0
  37. package/dist/lib/geometry-converters/convert-binary-geometry-to-geojson.js +91 -0
  38. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts +13 -0
  39. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.d.ts.map +1 -0
  40. package/dist/lib/geometry-converters/convert-geoarrow-to-geojson.js +164 -0
  41. package/dist/lib/geometry-converters/convert-to-geojson.d.ts +6 -0
  42. package/dist/lib/geometry-converters/convert-to-geojson.d.ts.map +1 -0
  43. package/dist/lib/geometry-converters/convert-to-geojson.js +39 -0
  44. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts +6 -0
  45. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.d.ts.map +1 -0
  46. package/dist/lib/geometry-converters/wkb/convert-geometry-to-twkb.js +195 -0
  47. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts +9 -0
  48. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.d.ts.map +1 -0
  49. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkb.js +273 -0
  50. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts +8 -0
  51. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.d.ts.map +1 -0
  52. package/dist/lib/geometry-converters/wkb/convert-geometry-to-wkt.js +44 -0
  53. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts +10 -0
  54. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.d.ts.map +1 -0
  55. package/dist/lib/geometry-converters/wkb/convert-twkb-to-geometry.js +254 -0
  56. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts +3 -0
  57. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.d.ts.map +1 -0
  58. package/dist/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.js +164 -0
  59. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts +11 -0
  60. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.d.ts.map +1 -0
  61. package/dist/lib/geometry-converters/wkb/convert-wkb-to-geometry.js +9 -0
  62. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts +16 -0
  63. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.d.ts.map +1 -0
  64. package/dist/lib/geometry-converters/wkb/convert-wkt-to-geometry.js +258 -0
  65. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts +43 -0
  66. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.d.ts.map +1 -0
  67. package/dist/lib/geometry-converters/wkb/helpers/parse-wkb-header.js +174 -0
  68. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts +64 -0
  69. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.d.ts.map +1 -0
  70. package/dist/lib/geometry-converters/wkb/helpers/wkb-types.js +46 -0
  71. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts +21 -0
  72. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.d.ts.map +1 -0
  73. package/dist/lib/geometry-converters/wkb/helpers/wkb-utils.js +64 -0
  74. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts +8 -0
  75. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.d.ts.map +1 -0
  76. package/dist/lib/geometry-converters/wkb/helpers/write-wkb-header.js +33 -0
  77. package/dist/lib/table-converters/convert-geoarrow-table.d.ts +27 -0
  78. package/dist/lib/table-converters/convert-geoarrow-table.d.ts.map +1 -0
  79. package/dist/lib/table-converters/convert-geoarrow-table.js +154 -0
  80. package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts +4 -0
  81. package/dist/lib/table-converters/convert-wkb-table-to-geojson.d.ts.map +1 -0
  82. package/dist/lib/{tables/convert-table-to-geojson.js → table-converters/convert-wkb-table-to-geojson.js} +10 -16
  83. package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts +6 -0
  84. package/dist/lib/table-converters/make-arrow-batch-iterator.d.ts.map +1 -0
  85. package/dist/lib/table-converters/make-arrow-batch-iterator.js +35 -0
  86. package/dist/lib/utils/base64-encoder.d.ts +5 -0
  87. package/dist/lib/utils/base64-encoder.d.ts.map +1 -0
  88. package/dist/lib/utils/base64-encoder.js +153 -0
  89. package/dist/lib/utils/binary-reader.d.ts +18 -0
  90. package/dist/lib/utils/binary-reader.d.ts.map +1 -0
  91. package/dist/lib/utils/binary-reader.js +69 -0
  92. package/dist/lib/utils/binary-writer.d.ts +30 -0
  93. package/dist/lib/utils/binary-writer.d.ts.map +1 -0
  94. package/dist/lib/utils/binary-writer.js +127 -0
  95. package/dist/lib/utils/concat-typed-arrays.d.ts +3 -0
  96. package/dist/lib/utils/concat-typed-arrays.d.ts.map +1 -0
  97. package/dist/lib/utils/concat-typed-arrays.js +18 -0
  98. package/dist/lib/utils/hex-encoder.d.ts +15 -0
  99. package/dist/lib/utils/hex-encoder.d.ts.map +1 -0
  100. package/dist/lib/utils/hex-encoder.js +54 -0
  101. package/dist/lib/utils/hex-transcoder.d.ts +15 -0
  102. package/dist/lib/utils/hex-transcoder.d.ts.map +1 -0
  103. package/dist/lib/utils/hex-transcoder.js +50 -0
  104. package/dist/lib/wkt-crs/encode-wkt-crs.d.ts +10 -0
  105. package/dist/lib/wkt-crs/encode-wkt-crs.d.ts.map +1 -0
  106. package/dist/lib/wkt-crs/encode-wkt-crs.js +35 -0
  107. package/dist/lib/wkt-crs/parse-wkt-crs.d.ts +15 -0
  108. package/dist/lib/wkt-crs/parse-wkt-crs.d.ts.map +1 -0
  109. package/dist/lib/wkt-crs/parse-wkt-crs.js +120 -0
  110. package/package.json +7 -5
  111. package/src/index.ts +87 -14
  112. package/src/lib/binary-geometry-api/binary-geometry-info.ts +75 -0
  113. package/src/lib/binary-geometry-api/concat-binary-geometry.ts +78 -0
  114. package/src/lib/{binary-features/transform.ts → binary-geometry-api/transform-coordinates.ts} +0 -1
  115. package/src/lib/{binary-features/binary-to-geojson.ts → feature-collection-converters/convert-binary-features-to-geojson.ts} +5 -142
  116. package/src/lib/{binary-features/flat-geojson-to-binary.ts → feature-collection-converters/convert-flat-geojson-to-binary-features.ts} +14 -9
  117. package/src/lib/feature-collection-converters/convert-geoarrow-to-binary-features.ts +496 -0
  118. package/src/lib/{binary-features/geojson-to-binary.ts → feature-collection-converters/convert-geojson-to-binary-features.ts} +11 -7
  119. package/src/lib/{binary-features/geojson-to-flat-geojson.ts → feature-collection-converters/convert-geojson-to-flat-geojson.ts} +5 -1
  120. package/src/lib/{binary-features → feature-collection-converters/helpers}/flat-geojson-to-binary-types.ts +4 -0
  121. package/src/lib/{binary-features/extract-geometry-info.ts → geometry-api/geometry-info.ts} +20 -2
  122. package/src/lib/geometry-converters/convert-binary-geometry-to-geojson.ts +148 -0
  123. package/src/lib/geometry-converters/convert-geoarrow-to-geojson.ts +193 -0
  124. package/src/lib/geometry-converters/convert-to-geojson.ts +52 -0
  125. package/src/lib/geometry-converters/wkb/convert-geometry-to-twkb.ts +308 -0
  126. package/src/lib/geometry-converters/wkb/convert-geometry-to-wkb.ts +365 -0
  127. package/src/lib/geometry-converters/wkb/convert-geometry-to-wkt.ts +54 -0
  128. package/src/lib/geometry-converters/wkb/convert-twkb-to-geometry.ts +366 -0
  129. package/src/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.ts +238 -0
  130. package/src/lib/geometry-converters/wkb/convert-wkb-to-geometry.ts +23 -0
  131. package/src/lib/geometry-converters/wkb/convert-wkt-to-geometry.ts +294 -0
  132. package/src/lib/geometry-converters/wkb/helpers/parse-wkb-header.ts +213 -0
  133. package/src/lib/geometry-converters/wkb/helpers/wkb-types.ts +82 -0
  134. package/src/lib/geometry-converters/wkb/helpers/wkb-utils.ts +85 -0
  135. package/src/lib/geometry-converters/wkb/helpers/write-wkb-header.ts +41 -0
  136. package/src/lib/table-converters/convert-geoarrow-table.ts +218 -0
  137. package/src/lib/{tables/convert-table-to-geojson.ts → table-converters/convert-wkb-table-to-geojson.ts} +10 -23
  138. package/src/lib/table-converters/make-arrow-batch-iterator.ts +53 -0
  139. package/src/lib/utils/base64-encoder.ts +157 -0
  140. package/src/lib/utils/binary-reader.ts +76 -0
  141. package/src/lib/utils/binary-writer.ts +136 -0
  142. package/src/lib/utils/concat-typed-arrays.ts +24 -0
  143. package/src/lib/utils/hex-encoder.ts +60 -0
  144. package/src/lib/utils/hex-transcoder.ts +54 -0
  145. package/src/lib/wkt-crs/encode-wkt-crs.ts +41 -0
  146. package/src/lib/wkt-crs/parse-wkt-crs.ts +149 -0
  147. package/dist/lib/binary-features/binary-to-geojson.d.ts +0 -18
  148. package/dist/lib/binary-features/binary-to-geojson.d.ts.map +0 -1
  149. package/dist/lib/binary-features/extract-geometry-info.d.ts +0 -8
  150. package/dist/lib/binary-features/extract-geometry-info.d.ts.map +0 -1
  151. package/dist/lib/binary-features/flat-geojson-to-binary-types.d.ts.map +0 -1
  152. package/dist/lib/binary-features/flat-geojson-to-binary-types.js +0 -1
  153. package/dist/lib/binary-features/flat-geojson-to-binary.d.ts.map +0 -1
  154. package/dist/lib/binary-features/geojson-to-binary.d.ts.map +0 -1
  155. package/dist/lib/binary-features/geojson-to-binary.js +0 -21
  156. package/dist/lib/binary-features/geojson-to-flat-geojson.d.ts.map +0 -1
  157. package/dist/lib/binary-features/transform.d.ts.map +0 -1
  158. package/dist/lib/geo/geoarrow-metadata.d.ts +0 -27
  159. package/dist/lib/geo/geoarrow-metadata.d.ts.map +0 -1
  160. package/dist/lib/geo/geoarrow-metadata.js +0 -70
  161. package/dist/lib/geo/geoparquet-metadata-schema.d.ts +0 -79
  162. package/dist/lib/geo/geoparquet-metadata-schema.d.ts.map +0 -1
  163. package/dist/lib/geo/geoparquet-metadata-schema.js +0 -69
  164. package/dist/lib/geo/geoparquet-metadata.d.ts +0 -45
  165. package/dist/lib/geo/geoparquet-metadata.d.ts.map +0 -1
  166. package/dist/lib/geo/geoparquet-metadata.js +0 -117
  167. package/dist/lib/tables/convert-table-to-geojson.d.ts +0 -5
  168. package/dist/lib/tables/convert-table-to-geojson.d.ts.map +0 -1
  169. package/src/lib/geo/geoarrow-metadata.ts +0 -100
  170. package/src/lib/geo/geoparquet-metadata-schema.json +0 -60
  171. package/src/lib/geo/geoparquet-metadata-schema.ts +0 -71
  172. package/src/lib/geo/geoparquet-metadata.ts +0 -191
  173. /package/dist/lib/{binary-features → feature-collection-converters/helpers}/flat-geojson-to-binary-types.d.ts +0 -0
@@ -0,0 +1,218 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import * as arrow from 'apache-arrow';
6
+ import type {
7
+ Table,
8
+ ArrayRowTable,
9
+ ColumnarTable,
10
+ ObjectRowTable,
11
+ GeoJSONTable,
12
+ ArrowTable,
13
+ Feature
14
+ } from '@loaders.gl/schema';
15
+
16
+ import {
17
+ convertTable,
18
+ convertArrowToSchema,
19
+ convertSchemaToArrow,
20
+ getTableLength,
21
+ getTableNumCols,
22
+ getTableCellAt
23
+ } from '@loaders.gl/schema-utils';
24
+ import {getGeometryColumnsFromSchema} from '@loaders.gl/geoarrow';
25
+ import {convertGeoArrowGeometryToGeoJSON} from '../geometry-converters/convert-geoarrow-to-geojson';
26
+
27
+ /**
28
+ * * Convert a loaders.gl Table to an Apache Arrow Table
29
+ * @param mesh
30
+ * @param metadata
31
+ * @param batchSize
32
+ * @returns
33
+ */
34
+ export function convertTableToArrow(table: Table, options?: {batchSize?: number}): arrow.Table {
35
+ switch (table.shape) {
36
+ case 'arrow-table':
37
+ return table.data;
38
+
39
+ case 'columnar-table':
40
+ // TODO - optimized implementation is possible
41
+ // return convertColumnarTableToArrow(table, options);
42
+
43
+ // fall through
44
+
45
+ default:
46
+ const arrowBatchIterator = makeTableToArrowBatchesIterator(table, options);
47
+ return new arrow.Table(arrowBatchIterator);
48
+ }
49
+ }
50
+
51
+ export function* makeTableToArrowBatchesIterator(
52
+ table: Table,
53
+ options?: {batchSize?: number}
54
+ ): IterableIterator<arrow.RecordBatch> {
55
+ const arrowSchema = convertSchemaToArrow(table.schema!);
56
+
57
+ const length = getTableLength(table);
58
+ const numColumns = getTableNumCols(table);
59
+ const batchSize = options?.batchSize || length;
60
+
61
+ const builders = arrowSchema?.fields.map((arrowField) => arrow.makeBuilder(arrowField));
62
+ const structField = new arrow.Struct(arrowSchema.fields);
63
+
64
+ let batchLength = 0;
65
+ for (let rowIndex = 0; rowIndex < length; rowIndex++) {
66
+ for (let columnIndex = 0; columnIndex < numColumns; ++columnIndex) {
67
+ const value = getTableCellAt(table, rowIndex, columnIndex);
68
+
69
+ const builder = builders[columnIndex];
70
+ builder.append(value);
71
+ batchLength++;
72
+
73
+ if (batchLength >= batchSize) {
74
+ const datas = builders.map((builder) => builder.flush());
75
+ const structData = new arrow.Data(structField, 0, batchLength, 0, undefined, datas);
76
+ yield new arrow.RecordBatch(arrowSchema, structData);
77
+ batchLength = 0;
78
+ }
79
+ }
80
+ }
81
+
82
+ if (batchLength > 0) {
83
+ const datas = builders.map((builder) => builder.flush());
84
+ const structData = new arrow.Data(structField, 0, batchLength, 0, undefined, datas);
85
+ yield new arrow.RecordBatch(arrowSchema, structData);
86
+ batchLength = 0;
87
+ }
88
+
89
+ builders.map((builder) => builder.finish());
90
+ }
91
+
92
+ /**
93
+ * Convert an Apache Arrow table to a loaders.gl Table
94
+ * @note Currently does not convert schema
95
+ */
96
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: 'arrow-table'): ArrowTable;
97
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: 'columnar-table'): ColumnarTable;
98
+ export function convertGeoArrowToTable(
99
+ arrow: arrow.Table,
100
+ shape: 'object-row-table'
101
+ ): ObjectRowTable;
102
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: 'array-row-table'): ArrayRowTable;
103
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: 'geojson-table'): GeoJSONTable;
104
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: 'columnar-table'): ColumnarTable;
105
+ export function convertGeoArrowToTable(arrow: arrow.Table, shape: Table['shape']): Table;
106
+
107
+ /**
108
+ * Convert an Apache Arrow table to a loaders.gl Table
109
+ * @note Currently does not convert schema
110
+ */
111
+ export function convertGeoArrowToTable(arrowTable: arrow.Table, shape: Table['shape']): Table {
112
+ switch (shape) {
113
+ case 'arrow-table':
114
+ return convertArrowToArrowTable(arrowTable);
115
+ case 'array-row-table':
116
+ return convertArrowToArrayRowTable(arrowTable);
117
+ case 'object-row-table':
118
+ return convertArrowToObjectRowTable(arrowTable);
119
+ case 'columnar-table':
120
+ return convertArrowToColumnarTable(arrowTable);
121
+ case 'geojson-table':
122
+ return convertArrowToGeoJSONTable(arrowTable);
123
+ default:
124
+ throw new Error(shape);
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Wrap an apache arrow table in a loaders.gl table wrapper.
130
+ * From this additional conversions are available.
131
+ * @param arrowTable
132
+ * @returns
133
+ */
134
+ function convertArrowToArrowTable(arrowTable: arrow.Table): ArrowTable {
135
+ return {
136
+ shape: 'arrow-table',
137
+ schema: convertArrowToSchema(arrowTable.schema),
138
+ data: arrowTable
139
+ };
140
+ }
141
+
142
+ function convertArrowToArrayRowTable(arrowTable: arrow.Table): Table {
143
+ const columnarTable = convertArrowToColumnarTable(arrowTable);
144
+ return convertTable(columnarTable, 'array-row-table');
145
+ }
146
+
147
+ function convertArrowToObjectRowTable(arrowTable: arrow.Table): Table {
148
+ const columnarTable = convertArrowToColumnarTable(arrowTable);
149
+ return convertTable(columnarTable, 'object-row-table');
150
+ }
151
+
152
+ /**
153
+ * Convert an Apache Arrow table to a ColumnarTable
154
+ * @note Currently does not convert schema
155
+ */
156
+ function convertArrowToColumnarTable(arrowTable: arrow.Table): ColumnarTable {
157
+ // TODO - avoid calling `getColumn` on columns we are not interested in?
158
+ // Add options object?
159
+
160
+ const columns: ColumnarTable['data'] = {};
161
+
162
+ for (const field of arrowTable.schema.fields) {
163
+ // This (is intended to) coalesce all record batches into a single typed array
164
+ const arrowColumn = arrowTable.getChild(field.name);
165
+ const values = arrowColumn?.toArray();
166
+ columns[field.name] = values;
167
+ }
168
+
169
+ const schema = convertArrowToSchema(arrowTable.schema);
170
+
171
+ return {
172
+ shape: 'columnar-table',
173
+ schema,
174
+ data: columns
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Convert an Apache Arrow table to a GeoJSONTable
180
+ * @note Currently does not convert schema
181
+ */
182
+ function convertArrowToGeoJSONTable(arrowTable: arrow.Table): GeoJSONTable {
183
+ const schema = convertArrowToSchema(arrowTable.schema);
184
+ const geometryColumns = getGeometryColumnsFromSchema(schema);
185
+
186
+ // get encoding from geometryColumns['geometry']
187
+ const encoding = geometryColumns.geometry.encoding;
188
+
189
+ const features: Feature[] = [];
190
+
191
+ // Remove geometry columns
192
+ const propertyColumnNames = arrowTable.schema.fields
193
+ .map((field) => field.name)
194
+ // TODO - this deletes all geometry columns
195
+ .filter((name) => !(name in geometryColumns));
196
+ const propertiesTable = arrowTable.select(propertyColumnNames);
197
+
198
+ const arrowGeometryColumn = arrowTable.getChild('geometry');
199
+
200
+ for (let row = 0; row < arrowTable.numRows; row++) {
201
+ // get the geometry value from arrow geometry column
202
+ // Note that type can vary
203
+ const arrowGeometry = arrowGeometryColumn?.get(row);
204
+ // parse arrow geometry to geojson feature
205
+ const feature = convertGeoArrowGeometryToGeoJSON(arrowGeometry, encoding);
206
+ if (feature) {
207
+ const properties = propertiesTable.get(row)?.toJSON() || {};
208
+ features.push({type: 'Feature', geometry: feature, properties});
209
+ }
210
+ }
211
+
212
+ return {
213
+ shape: 'geojson-table',
214
+ type: 'FeatureCollection',
215
+ schema,
216
+ features
217
+ };
218
+ }
@@ -2,7 +2,6 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {LoaderWithParser} from '@loaders.gl/loader-utils';
6
5
  import type {
7
6
  ArrayRowTable,
8
7
  GeoJSONTable,
@@ -11,17 +10,17 @@ import type {
11
10
  Feature,
12
11
  Geometry
13
12
  } from '@loaders.gl/schema';
14
- import {getTableLength, getTableRowAsObject} from '@loaders.gl/schema';
15
-
16
- import {GeoColumnMetadata, getGeoMetadata} from '../geo/geoparquet-metadata';
13
+ import {getTableLength, getTableRowAsObject} from '@loaders.gl/schema-utils';
14
+ import {GeoColumnMetadata, getGeoMetadata} from '@loaders.gl/geoarrow';
15
+ import {convertWKBToGeometry} from '../geometry-converters/wkb/convert-wkb-to-geometry';
16
+ import {convertWKTToGeometry} from '../geometry-converters/wkb/convert-wkt-to-geometry';
17
17
 
18
18
  /** TODO - move to loaders.gl/gis? */
19
19
  export function convertWKBTableToGeoJSON(
20
20
  table: ArrayRowTable | ObjectRowTable,
21
- schema: Schema,
22
- loaders: LoaderWithParser[]
21
+ schema: Schema
23
22
  ): GeoJSONTable {
24
- const geoMetadata = getGeoMetadata(schema);
23
+ const geoMetadata = getGeoMetadata(schema.metadata);
25
24
  const primaryColumn = geoMetadata?.primary_column;
26
25
  if (!primaryColumn) {
27
26
  throw new Error('no geometry column');
@@ -33,7 +32,7 @@ export function convertWKBTableToGeoJSON(
33
32
  const length = getTableLength(table);
34
33
  for (let rowIndex = 0; rowIndex < length; rowIndex++) {
35
34
  const row = getTableRowAsObject(table, rowIndex);
36
- const geometry = parseGeometry(row[primaryColumn], columnMetadata, loaders);
35
+ const geometry = parseGeometry(row[primaryColumn], columnMetadata);
37
36
  delete row[primaryColumn];
38
37
  const feature: Feature = {type: 'Feature', geometry: geometry!, properties: row};
39
38
  features.push(feature);
@@ -42,27 +41,15 @@ export function convertWKBTableToGeoJSON(
42
41
  return {shape: 'geojson-table', schema, type: 'FeatureCollection', features};
43
42
  }
44
43
 
45
- function parseGeometry(
46
- geometry: unknown,
47
- columnMetadata: GeoColumnMetadata,
48
- loaders: LoaderWithParser[]
49
- ): Geometry | null {
44
+ function parseGeometry(geometry: unknown, columnMetadata: GeoColumnMetadata): Geometry | null {
50
45
  switch (columnMetadata.encoding) {
51
46
  case 'wkt':
52
- const wktLoader = loaders.find((loader) => loader.id === 'wkt');
53
- return wktLoader?.parseTextSync?.(geometry as string) || null;
47
+ return convertWKTToGeometry(geometry as string) || null;
54
48
  case 'wkb':
55
49
  default:
56
- const wkbLoader = loaders.find((loader) => loader.id === 'wkb');
57
50
  const arrayBuffer = ArrayBuffer.isView(geometry)
58
51
  ? geometry.buffer.slice(geometry.byteOffset, geometry.byteOffset + geometry.byteLength)
59
52
  : (geometry as ArrayBuffer);
60
- const geojson = wkbLoader?.parseSync?.(arrayBuffer, {
61
- wkb: {shape: 'geojson-geometry'}
62
- }) as unknown as Geometry;
63
- return geojson; // binaryGeometry ? binaryToGeometry(binaryGeometry) : null;
64
- // const binaryGeometry = WKBLoader.parseSync?.(geometry);
65
- // ts-ignore
66
- // return binaryGeometry ? binaryToGeometry(binaryGeometry) : null;
53
+ return convertWKBToGeometry(arrayBuffer);
67
54
  }
68
55
  }
@@ -0,0 +1,53 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import * as arrow from 'apache-arrow';
6
+ import type {Table} from '@loaders.gl/schema';
7
+ import {
8
+ convertSchemaToArrow,
9
+ getTableLength,
10
+ getTableNumCols,
11
+ getTableCellAt
12
+ } from '@loaders.gl/schema-utils';
13
+
14
+ export function* makeTableToArrowBatchesIterator(
15
+ table: Table,
16
+ options?: {batchSize?: number}
17
+ ): IterableIterator<arrow.RecordBatch> {
18
+ const arrowSchema = convertSchemaToArrow(table.schema!);
19
+
20
+ const length = getTableLength(table);
21
+ const numColumns = getTableNumCols(table);
22
+ const batchSize = options?.batchSize || length;
23
+
24
+ const builders = arrowSchema?.fields.map((arrowField) => arrow.makeBuilder(arrowField));
25
+ const structField = new arrow.Struct(arrowSchema.fields);
26
+
27
+ let batchLength = 0;
28
+ for (let rowIndex = 0; rowIndex < length; rowIndex++) {
29
+ for (let columnIndex = 0; columnIndex < numColumns; ++columnIndex) {
30
+ const value = getTableCellAt(table, rowIndex, columnIndex);
31
+
32
+ const builder = builders[columnIndex];
33
+ builder.append(value);
34
+ batchLength++;
35
+
36
+ if (batchLength >= batchSize) {
37
+ const datas = builders.map((builder) => builder.flush());
38
+ const structData = new arrow.Data(structField, 0, batchLength, 0, undefined, datas);
39
+ yield new arrow.RecordBatch(arrowSchema, structData);
40
+ batchLength = 0;
41
+ }
42
+ }
43
+ }
44
+
45
+ if (batchLength > 0) {
46
+ const datas = builders.map((builder) => builder.flush());
47
+ const structData = new arrow.Data(structField, 0, batchLength, 0, undefined, datas);
48
+ yield new arrow.RecordBatch(arrowSchema, structData);
49
+ batchLength = 0;
50
+ }
51
+
52
+ builders.map((builder) => builder.finish());
53
+ }
@@ -0,0 +1,157 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /*
6
+ const binary_to_b64_map = [
7
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
8
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
9
+ 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
10
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
11
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
12
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
13
+ '2', '3', '4', '5', '6', '7', '8', '9', '+',
14
+ '/', '='
15
+ ];
16
+ const b64_to_binary_map = {
17
+ '0': 52, '1': 53, '2': 54, '3': 55, '4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61,
18
+ A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11, M: 12, N: 13, O: 14,
19
+ P: 15, Q: 16, R: 17, S: 18, T: 19, U: 20, V: 21, W: 22, X: 23, Y: 24, Z: 25, a: 26, b: 27,
20
+ c: 28, d: 29, e: 30, f: 31, g: 32, h: 33, i: 34, j: 35, k: 36, l: 37, m: 38, n: 39, o: 40,
21
+ p: 41, q: 42, r: 43, s: 44, t: 45, u: 46, v: 47, w: 48, x: 49, y: 50, z: 51, '+': 62, '/': 63,
22
+ '=': 64
23
+ };
24
+
25
+ */
26
+
27
+ export class Base64Encoder {
28
+ getDecodedLength(array: Uint8Array): number {
29
+ return Math.ceil(array.byteLength / 4) * 3;
30
+ }
31
+
32
+ decode(array: Uint8Array, target?: ArrayBuffer) {} // eslint-disable-line
33
+ }
34
+
35
+ /*
36
+
37
+ //generates an array iterator that returns 3 elements at a time. Use to loop through the Uint8Array Array Buffer
38
+ // to be converted to Base64. (binary array buffer) 8bits * 3 = 6bits * 4 (base64 representation)
39
+ const generateTripleIterator = (arr) => {
40
+ return {
41
+ *[Symbol.iterator]() {
42
+ for(let n = 0; n < arr.length; n+=3) {
43
+ let result = [];
44
+ result.push(arr[n]);
45
+
46
+ if(n+1 < arr.length)
47
+ result.push(arr[n+1]);
48
+ if(n+2 < arr.length)
49
+ result.push(arr[n+2]);
50
+
51
+ yield result;
52
+ }
53
+ }
54
+ };
55
+ };
56
+
57
+ //generates an array iterator that returns 4 elements at a time. Use to loop through
58
+ // Base64 string because Base64 string is multiples of 4 characters.
59
+ const generateQuadrupleIterator = (arr) => {
60
+ return {
61
+ *[Symbol.iterator]() {
62
+ for(let n = 0; n < arr.length; n+=4) {
63
+ yield [...arr.slice(n, n+4)];
64
+ }
65
+ }
66
+ };
67
+ };
68
+
69
+ // Converts a triple of 8 bits into a quadruple of 6 bits. use to convert binary to base64 representation
70
+ const tripleConvert = (first, second, third) => {
71
+ let [] = triple;
72
+ let binary = null, a = null, b = null, c = null, d = null;
73
+ if (triple.length === 1) {
74
+ binary = (first << 4);
75
+ a = ((binary & 4032) >>> 6);
76
+ b = (binary & 63);
77
+ c = 64;
78
+ d = 64;
79
+ } else if (triple.length === 2) {
80
+ binary = ((first << 10) | (second << 2));
81
+ a = ((binary & 258048) >>> 12);
82
+ b = ((binary & 4032) >>> 6);
83
+ c = (binary & 63);
84
+ d = 64;
85
+ } else {
86
+ binary = ((first << 16) | (second << 8) | third);
87
+ a = ((binary & 16515072) >>> 18);
88
+ b = ((binary & 258048) >>> 12);
89
+ c = ((binary & 4032) >>> 6);
90
+ d = (binary & 63);
91
+ }
92
+
93
+ return [a, b, c, d];
94
+ };
95
+
96
+ // Converts a quadruple of 6 bits into a triple of 8 bits. use to convert base64 representation into binary
97
+ const quadrupleConvert = (quadruple) => {
98
+ let [a, b, c, d] = quadruple;
99
+ let binary = null, first = null, second = null, third = null;
100
+
101
+ if(c === 64 && d === 64) {
102
+ //two padding
103
+ binary = ((a << 6) | b);
104
+ first = (binary >> 4); //shift off 4 bits, 2 bits per padding
105
+ } else if(d === 64) {
106
+ //one padding
107
+ binary = ((a << 12) | (b << 6) | c );
108
+ binary = (binary >> 2); //shift off 2 bits
109
+ first = binary >> 8;
110
+ second = ((binary << 24) >>> 24);
111
+ } else {
112
+ //no padding
113
+ binary = ((a << 18) | (b << 12) | (c << 6) | d );
114
+ first = (binary >>> 16);
115
+ second = ((binary << 16) >>> 24);
116
+ third = ((binary << 24) >>> 24);
117
+ }
118
+
119
+ return [first, second, third];
120
+ };
121
+
122
+ // Convert 8Bits Array Buffer to Base64 string
123
+ export const ab2b64 = (buffer) => {
124
+ const b64strArray = [];
125
+ const view = new Uint8Array(buffer);
126
+ let iterator = generateTripleIterator(view);
127
+ for(let triple of iterator) {
128
+ b64strArray.push(...tripleConvert(triple));
129
+ }
130
+ return b64strArray.map(b64CharCodePoint => binary_to_b64_map[b64CharCodePoint]).join("");
131
+ };
132
+
133
+ // Convert Base64 String to 8Bits Array Buffer
134
+ export const b642ab = (b64str) => {
135
+ let buffer_length = (b64str.length / 4) * 3;
136
+ if(b64str.slice(-2) === '==') {
137
+ buffer_length -= 2;
138
+ } else if(b64str.slice(-1) === '=') {
139
+ buffer_length -= 1;
140
+ }
141
+
142
+ let buffer = new ArrayBuffer(buffer_length);
143
+ const view = new Uint8Array(buffer);
144
+ let iterator = generateQuadrupleIterator(b64str.split("").map(b64char => b64_to_binary_map[b64char]));
145
+ let byteIndex = 0;
146
+ for(let quadruple of iterator) {
147
+ quadrupleConvert(quadruple).forEach(byte => {
148
+ if(byte != null) {
149
+ view[byteIndex] = byte;
150
+ byteIndex++;
151
+ }
152
+ });
153
+ }
154
+ return buffer;
155
+ };
156
+
157
+ */
@@ -0,0 +1,76 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /** A DataView that tracks byte offset when reading. */
6
+ export class BinaryReader {
7
+ arrayBuffer: ArrayBuffer;
8
+ dataView: DataView;
9
+ byteOffset: number;
10
+ littleEndian: boolean;
11
+
12
+ constructor(arrayBuffer: ArrayBuffer, isBigEndian: boolean = false) {
13
+ this.arrayBuffer = arrayBuffer;
14
+ this.dataView = new DataView(arrayBuffer);
15
+ this.byteOffset = 0;
16
+ this.littleEndian = !isBigEndian;
17
+ }
18
+
19
+ readUInt8() {
20
+ const value = this.dataView.getUint8(this.byteOffset);
21
+ this.byteOffset += 1;
22
+ return value;
23
+ }
24
+ readUInt16() {
25
+ const value = this.dataView.getUint16(this.byteOffset, this.littleEndian);
26
+ this.byteOffset += 2;
27
+ return value;
28
+ }
29
+ readUInt32() {
30
+ const value = this.dataView.getUint32(this.byteOffset, this.littleEndian);
31
+ this.byteOffset += 4;
32
+ return value;
33
+ }
34
+ readInt8() {
35
+ const value = this.dataView.getInt8(this.byteOffset);
36
+ this.byteOffset += 1;
37
+ return value;
38
+ }
39
+ readInt16() {
40
+ const value = this.dataView.getInt16(this.byteOffset, this.littleEndian);
41
+ this.byteOffset += 2;
42
+ return value;
43
+ }
44
+ readInt32() {
45
+ const value = this.dataView.getInt32(this.byteOffset, this.littleEndian);
46
+ this.byteOffset += 4;
47
+ return value;
48
+ }
49
+ readFloat() {
50
+ const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian);
51
+ this.byteOffset += 4;
52
+ return value;
53
+ }
54
+ readDouble() {
55
+ const value = this.dataView.getFloat64(this.byteOffset, this.littleEndian);
56
+ this.byteOffset += 8;
57
+ return value;
58
+ }
59
+
60
+ readVarInt() {
61
+ let result = 0;
62
+ let bytesRead = 0;
63
+
64
+ let nextByte;
65
+ do {
66
+ // TODO - this needs to be accessed via data view?
67
+ nextByte = this.dataView.getUint8(this.byteOffset + bytesRead);
68
+ result += (nextByte & 0x7f) << (7 * bytesRead);
69
+ bytesRead++;
70
+ } while (nextByte >= 0x80);
71
+
72
+ this.byteOffset += bytesRead;
73
+
74
+ return result;
75
+ }
76
+ }