@loaders.gl/gis 4.0.0-beta.2 → 4.0.0-beta.4

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 (51) hide show
  1. package/dist/index.cjs +708 -0
  2. package/dist/index.js +6 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/{esm/lib → lib}/binary-to-geojson.js +2 -2
  5. package/dist/lib/binary-to-geojson.js.map +1 -0
  6. package/dist/{esm/lib → lib}/extract-geometry-info.js +1 -1
  7. package/dist/lib/extract-geometry-info.js.map +1 -0
  8. package/dist/lib/flat-geojson-to-binary-types.js.map +1 -0
  9. package/dist/lib/flat-geojson-to-binary.js.map +1 -0
  10. package/dist/{esm/lib → lib}/geojson-to-binary.js +3 -3
  11. package/dist/lib/geojson-to-binary.js.map +1 -0
  12. package/dist/{esm/lib → lib}/geojson-to-flat-geojson.js +1 -1
  13. package/dist/lib/geojson-to-flat-geojson.js.map +1 -0
  14. package/dist/lib/transform.js.map +1 -0
  15. package/package.json +16 -8
  16. package/src/lib/flat-geojson-to-binary.ts +0 -1
  17. package/dist/bundle.d.ts +0 -2
  18. package/dist/bundle.d.ts.map +0 -1
  19. package/dist/es5/bundle.js +0 -6
  20. package/dist/es5/bundle.js.map +0 -1
  21. package/dist/es5/index.js +0 -53
  22. package/dist/es5/index.js.map +0 -1
  23. package/dist/es5/lib/binary-to-geojson.js +0 -221
  24. package/dist/es5/lib/binary-to-geojson.js.map +0 -1
  25. package/dist/es5/lib/extract-geometry-info.js +0 -167
  26. package/dist/es5/lib/extract-geometry-info.js.map +0 -1
  27. package/dist/es5/lib/flat-geojson-to-binary-types.js +0 -2
  28. package/dist/es5/lib/flat-geojson-to-binary-types.js.map +0 -1
  29. package/dist/es5/lib/flat-geojson-to-binary.js +0 -355
  30. package/dist/es5/lib/flat-geojson-to-binary.js.map +0 -1
  31. package/dist/es5/lib/geojson-to-binary.js +0 -28
  32. package/dist/es5/lib/geojson-to-binary.js.map +0 -1
  33. package/dist/es5/lib/geojson-to-flat-geojson.js +0 -136
  34. package/dist/es5/lib/geojson-to-flat-geojson.js.map +0 -1
  35. package/dist/es5/lib/transform.js +0 -57
  36. package/dist/es5/lib/transform.js.map +0 -1
  37. package/dist/esm/bundle.js +0 -4
  38. package/dist/esm/bundle.js.map +0 -1
  39. package/dist/esm/index.js +0 -6
  40. package/dist/esm/index.js.map +0 -1
  41. package/dist/esm/lib/binary-to-geojson.js.map +0 -1
  42. package/dist/esm/lib/extract-geometry-info.js.map +0 -1
  43. package/dist/esm/lib/flat-geojson-to-binary-types.js.map +0 -1
  44. package/dist/esm/lib/flat-geojson-to-binary.js.map +0 -1
  45. package/dist/esm/lib/geojson-to-binary.js.map +0 -1
  46. package/dist/esm/lib/geojson-to-flat-geojson.js.map +0 -1
  47. package/dist/esm/lib/transform.js.map +0 -1
  48. package/src/bundle.ts +0 -4
  49. /package/dist/{esm/lib → lib}/flat-geojson-to-binary-types.js +0 -0
  50. /package/dist/{esm/lib → lib}/flat-geojson-to-binary.js +0 -0
  51. /package/dist/{esm/lib → lib}/transform.js +0 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,708 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ binaryToGeojson: () => binaryToGeojson,
24
+ binaryToGeometry: () => binaryToGeometry,
25
+ flatGeojsonToBinary: () => flatGeojsonToBinary,
26
+ geojsonToBinary: () => geojsonToBinary,
27
+ geojsonToFlatGeojson: () => geojsonToFlatGeojson,
28
+ transformBinaryCoords: () => transformBinaryCoords,
29
+ transformGeoJsonCoords: () => transformGeoJsonCoords
30
+ });
31
+ module.exports = __toCommonJS(src_exports);
32
+
33
+ // src/lib/flat-geojson-to-binary.ts
34
+ var import_polygon = require("@math.gl/polygon");
35
+ function flatGeojsonToBinary(features, geometryInfo, options) {
36
+ const propArrayTypes = extractNumericPropTypes(features);
37
+ const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
38
+ return fillArrays(
39
+ features,
40
+ {
41
+ propArrayTypes,
42
+ ...geometryInfo
43
+ },
44
+ {
45
+ numericPropKeys: options && options.numericPropKeys || numericPropKeys,
46
+ PositionDataType: options ? options.PositionDataType : Float32Array,
47
+ triangulate: options ? options.triangulate : true
48
+ }
49
+ );
50
+ }
51
+ function extractNumericPropTypes(features) {
52
+ const propArrayTypes = {};
53
+ for (const feature of features) {
54
+ if (feature.properties) {
55
+ for (const key in feature.properties) {
56
+ const val = feature.properties[key];
57
+ propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
58
+ }
59
+ }
60
+ }
61
+ return propArrayTypes;
62
+ }
63
+ function fillArrays(features, geometryInfo, options) {
64
+ const {
65
+ pointPositionsCount,
66
+ pointFeaturesCount,
67
+ linePositionsCount,
68
+ linePathsCount,
69
+ lineFeaturesCount,
70
+ polygonPositionsCount,
71
+ polygonObjectsCount,
72
+ polygonRingsCount,
73
+ polygonFeaturesCount,
74
+ propArrayTypes,
75
+ coordLength
76
+ } = geometryInfo;
77
+ const { numericPropKeys = [], PositionDataType = Float32Array, triangulate = true } = options;
78
+ const hasGlobalId = features[0] && "id" in features[0];
79
+ const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
80
+ const points = {
81
+ type: "Point",
82
+ positions: new PositionDataType(pointPositionsCount * coordLength),
83
+ globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
84
+ featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount),
85
+ numericProps: {},
86
+ properties: [],
87
+ fields: []
88
+ };
89
+ const lines = {
90
+ type: "LineString",
91
+ pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1),
92
+ positions: new PositionDataType(linePositionsCount * coordLength),
93
+ globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
94
+ featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount),
95
+ numericProps: {},
96
+ properties: [],
97
+ fields: []
98
+ };
99
+ const polygons = {
100
+ type: "Polygon",
101
+ polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1),
102
+ primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1),
103
+ positions: new PositionDataType(polygonPositionsCount * coordLength),
104
+ globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
105
+ featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount),
106
+ numericProps: {},
107
+ properties: [],
108
+ fields: []
109
+ };
110
+ if (triangulate) {
111
+ polygons.triangles = [];
112
+ }
113
+ for (const object of [points, lines, polygons]) {
114
+ for (const propName of numericPropKeys) {
115
+ const T = propArrayTypes[propName];
116
+ object.numericProps[propName] = new T(object.positions.length / coordLength);
117
+ }
118
+ }
119
+ lines.pathIndices[linePathsCount] = linePositionsCount;
120
+ polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount;
121
+ polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount;
122
+ const indexMap = {
123
+ pointPosition: 0,
124
+ pointFeature: 0,
125
+ linePosition: 0,
126
+ linePath: 0,
127
+ lineFeature: 0,
128
+ polygonPosition: 0,
129
+ polygonObject: 0,
130
+ polygonRing: 0,
131
+ polygonFeature: 0,
132
+ feature: 0
133
+ };
134
+ for (const feature of features) {
135
+ const geometry = feature.geometry;
136
+ const properties = feature.properties || {};
137
+ switch (geometry.type) {
138
+ case "Point":
139
+ handlePoint(geometry, points, indexMap, coordLength, properties);
140
+ points.properties.push(keepStringProperties(properties, numericPropKeys));
141
+ if (hasGlobalId) {
142
+ points.fields.push({ id: feature.id });
143
+ }
144
+ indexMap.pointFeature++;
145
+ break;
146
+ case "LineString":
147
+ handleLineString(geometry, lines, indexMap, coordLength, properties);
148
+ lines.properties.push(keepStringProperties(properties, numericPropKeys));
149
+ if (hasGlobalId) {
150
+ lines.fields.push({ id: feature.id });
151
+ }
152
+ indexMap.lineFeature++;
153
+ break;
154
+ case "Polygon":
155
+ handlePolygon(geometry, polygons, indexMap, coordLength, properties);
156
+ polygons.properties.push(keepStringProperties(properties, numericPropKeys));
157
+ if (hasGlobalId) {
158
+ polygons.fields.push({ id: feature.id });
159
+ }
160
+ indexMap.polygonFeature++;
161
+ break;
162
+ default:
163
+ throw new Error("Invalid geometry type");
164
+ }
165
+ indexMap.feature++;
166
+ }
167
+ return makeAccessorObjects(points, lines, polygons, coordLength);
168
+ }
169
+ function handlePoint(geometry, points, indexMap, coordLength, properties) {
170
+ points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
171
+ const nPositions = geometry.data.length / coordLength;
172
+ fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
173
+ points.globalFeatureIds.fill(
174
+ indexMap.feature,
175
+ indexMap.pointPosition,
176
+ indexMap.pointPosition + nPositions
177
+ );
178
+ points.featureIds.fill(
179
+ indexMap.pointFeature,
180
+ indexMap.pointPosition,
181
+ indexMap.pointPosition + nPositions
182
+ );
183
+ indexMap.pointPosition += nPositions;
184
+ }
185
+ function handleLineString(geometry, lines, indexMap, coordLength, properties) {
186
+ lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
187
+ const nPositions = geometry.data.length / coordLength;
188
+ fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
189
+ lines.globalFeatureIds.fill(
190
+ indexMap.feature,
191
+ indexMap.linePosition,
192
+ indexMap.linePosition + nPositions
193
+ );
194
+ lines.featureIds.fill(
195
+ indexMap.lineFeature,
196
+ indexMap.linePosition,
197
+ indexMap.linePosition + nPositions
198
+ );
199
+ for (let i = 0, il = geometry.indices.length; i < il; ++i) {
200
+ const start = geometry.indices[i];
201
+ const end = i === il - 1 ? geometry.data.length : geometry.indices[i + 1];
202
+ lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
203
+ indexMap.linePosition += (end - start) / coordLength;
204
+ }
205
+ }
206
+ function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
207
+ polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
208
+ const nPositions = geometry.data.length / coordLength;
209
+ fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
210
+ polygons.globalFeatureIds.fill(
211
+ indexMap.feature,
212
+ indexMap.polygonPosition,
213
+ indexMap.polygonPosition + nPositions
214
+ );
215
+ polygons.featureIds.fill(
216
+ indexMap.polygonFeature,
217
+ indexMap.polygonPosition,
218
+ indexMap.polygonPosition + nPositions
219
+ );
220
+ for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
221
+ const startPosition = indexMap.polygonPosition;
222
+ polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
223
+ const areas = geometry.areas[l];
224
+ const indices = geometry.indices[l];
225
+ const nextIndices = geometry.indices[l + 1];
226
+ for (let i = 0, il = indices.length; i < il; ++i) {
227
+ const start = indices[i];
228
+ const end = i === il - 1 ? (
229
+ // last line, so either read to:
230
+ nextIndices === void 0 ? geometry.data.length : nextIndices[0]
231
+ ) : indices[i + 1];
232
+ polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
233
+ indexMap.polygonPosition += (end - start) / coordLength;
234
+ }
235
+ const endPosition = indexMap.polygonPosition;
236
+ triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
237
+ }
238
+ }
239
+ function triangulatePolygon(polygons, areas, indices, {
240
+ startPosition,
241
+ endPosition,
242
+ coordLength
243
+ }) {
244
+ if (!polygons.triangles) {
245
+ return;
246
+ }
247
+ const start = startPosition * coordLength;
248
+ const end = endPosition * coordLength;
249
+ const polygonPositions = polygons.positions.subarray(start, end);
250
+ const offset = indices[0];
251
+ const holes = indices.slice(1).map((n) => (n - offset) / coordLength);
252
+ const triangles = (0, import_polygon.earcut)(polygonPositions, holes, coordLength, areas);
253
+ for (let t = 0, tl = triangles.length; t < tl; ++t) {
254
+ polygons.triangles.push(startPosition + triangles[t]);
255
+ }
256
+ }
257
+ function wrapProps(obj, size) {
258
+ const returnObj = {};
259
+ for (const key in obj) {
260
+ returnObj[key] = { value: obj[key], size };
261
+ }
262
+ return returnObj;
263
+ }
264
+ function makeAccessorObjects(points, lines, polygons, coordLength) {
265
+ const binaryFeatures = {
266
+ points: {
267
+ ...points,
268
+ positions: { value: points.positions, size: coordLength },
269
+ globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
270
+ featureIds: { value: points.featureIds, size: 1 },
271
+ numericProps: wrapProps(points.numericProps, 1)
272
+ },
273
+ lines: {
274
+ ...lines,
275
+ positions: { value: lines.positions, size: coordLength },
276
+ pathIndices: { value: lines.pathIndices, size: 1 },
277
+ globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
278
+ featureIds: { value: lines.featureIds, size: 1 },
279
+ numericProps: wrapProps(lines.numericProps, 1)
280
+ },
281
+ polygons: {
282
+ ...polygons,
283
+ positions: { value: polygons.positions, size: coordLength },
284
+ polygonIndices: { value: polygons.polygonIndices, size: 1 },
285
+ primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
286
+ globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
287
+ featureIds: { value: polygons.featureIds, size: 1 },
288
+ numericProps: wrapProps(polygons.numericProps, 1)
289
+ }
290
+ // triangles not expected
291
+ };
292
+ if (binaryFeatures.polygons && polygons.triangles) {
293
+ binaryFeatures.polygons.triangles = { value: new Uint32Array(polygons.triangles), size: 1 };
294
+ }
295
+ return binaryFeatures;
296
+ }
297
+ function fillNumericProperties(object, properties, index, length) {
298
+ for (const numericPropName in object.numericProps) {
299
+ if (numericPropName in properties) {
300
+ const value = properties[numericPropName];
301
+ object.numericProps[numericPropName].fill(value, index, index + length);
302
+ }
303
+ }
304
+ }
305
+ function keepStringProperties(properties, numericKeys) {
306
+ const props = {};
307
+ for (const key in properties) {
308
+ if (!numericKeys.includes(key)) {
309
+ props[key] = properties[key];
310
+ }
311
+ }
312
+ return props;
313
+ }
314
+ function deduceArrayType(x, constructor) {
315
+ if (constructor === Array || !Number.isFinite(x)) {
316
+ return Array;
317
+ }
318
+ return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
319
+ }
320
+
321
+ // src/lib/extract-geometry-info.ts
322
+ function extractGeometryInfo(features) {
323
+ let pointPositionsCount = 0;
324
+ let pointFeaturesCount = 0;
325
+ let linePositionsCount = 0;
326
+ let linePathsCount = 0;
327
+ let lineFeaturesCount = 0;
328
+ let polygonPositionsCount = 0;
329
+ let polygonObjectsCount = 0;
330
+ let polygonRingsCount = 0;
331
+ let polygonFeaturesCount = 0;
332
+ const coordLengths = /* @__PURE__ */ new Set();
333
+ for (const feature of features) {
334
+ const geometry = feature.geometry;
335
+ switch (geometry.type) {
336
+ case "Point":
337
+ pointFeaturesCount++;
338
+ pointPositionsCount++;
339
+ coordLengths.add(geometry.coordinates.length);
340
+ break;
341
+ case "MultiPoint":
342
+ pointFeaturesCount++;
343
+ pointPositionsCount += geometry.coordinates.length;
344
+ for (const point of geometry.coordinates) {
345
+ coordLengths.add(point.length);
346
+ }
347
+ break;
348
+ case "LineString":
349
+ lineFeaturesCount++;
350
+ linePositionsCount += geometry.coordinates.length;
351
+ linePathsCount++;
352
+ for (const coord of geometry.coordinates) {
353
+ coordLengths.add(coord.length);
354
+ }
355
+ break;
356
+ case "MultiLineString":
357
+ lineFeaturesCount++;
358
+ for (const line of geometry.coordinates) {
359
+ linePositionsCount += line.length;
360
+ linePathsCount++;
361
+ for (const coord of line) {
362
+ coordLengths.add(coord.length);
363
+ }
364
+ }
365
+ break;
366
+ case "Polygon":
367
+ polygonFeaturesCount++;
368
+ polygonObjectsCount++;
369
+ polygonRingsCount += geometry.coordinates.length;
370
+ const flattened = geometry.coordinates.flat();
371
+ polygonPositionsCount += flattened.length;
372
+ for (const coord of flattened) {
373
+ coordLengths.add(coord.length);
374
+ }
375
+ break;
376
+ case "MultiPolygon":
377
+ polygonFeaturesCount++;
378
+ for (const polygon of geometry.coordinates) {
379
+ polygonObjectsCount++;
380
+ polygonRingsCount += polygon.length;
381
+ const flattened2 = polygon.flat();
382
+ polygonPositionsCount += flattened2.length;
383
+ for (const coord of flattened2) {
384
+ coordLengths.add(coord.length);
385
+ }
386
+ }
387
+ break;
388
+ default:
389
+ throw new Error(`Unsupported geometry type: ${geometry.type}`);
390
+ }
391
+ }
392
+ return {
393
+ coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
394
+ pointPositionsCount,
395
+ pointFeaturesCount,
396
+ linePositionsCount,
397
+ linePathsCount,
398
+ lineFeaturesCount,
399
+ polygonPositionsCount,
400
+ polygonObjectsCount,
401
+ polygonRingsCount,
402
+ polygonFeaturesCount
403
+ };
404
+ }
405
+
406
+ // src/lib/geojson-to-flat-geojson.ts
407
+ var import_polygon2 = require("@math.gl/polygon");
408
+ function geojsonToFlatGeojson(features, options = { coordLength: 2, fixRingWinding: true }) {
409
+ return features.map((feature) => flattenFeature(feature, options));
410
+ }
411
+ function flattenPoint(coordinates, data, indices, options) {
412
+ indices.push(data.length);
413
+ data.push(...coordinates);
414
+ for (let i = coordinates.length; i < options.coordLength; i++) {
415
+ data.push(0);
416
+ }
417
+ }
418
+ function flattenLineString(coordinates, data, indices, options) {
419
+ indices.push(data.length);
420
+ for (const c of coordinates) {
421
+ data.push(...c);
422
+ for (let i = c.length; i < options.coordLength; i++) {
423
+ data.push(0);
424
+ }
425
+ }
426
+ }
427
+ function flattenPolygon(coordinates, data, indices, areas, options) {
428
+ let count = 0;
429
+ const ringAreas = [];
430
+ const polygons = [];
431
+ for (const lineString of coordinates) {
432
+ const lineString2d = lineString.map((p) => p.slice(0, 2));
433
+ let area = (0, import_polygon2.getPolygonSignedArea)(lineString2d.flat());
434
+ const ccw = area < 0;
435
+ if (options.fixRingWinding && (count === 0 && !ccw || count > 0 && ccw)) {
436
+ lineString.reverse();
437
+ area = -area;
438
+ }
439
+ ringAreas.push(area);
440
+ flattenLineString(lineString, data, polygons, options);
441
+ count++;
442
+ }
443
+ if (count > 0) {
444
+ areas.push(ringAreas);
445
+ indices.push(polygons);
446
+ }
447
+ }
448
+ function flattenFeature(feature, options) {
449
+ const { geometry } = feature;
450
+ if (geometry.type === "GeometryCollection") {
451
+ throw new Error("GeometryCollection type not supported");
452
+ }
453
+ const data = [];
454
+ const indices = [];
455
+ let areas;
456
+ let type;
457
+ switch (geometry.type) {
458
+ case "Point":
459
+ type = "Point";
460
+ flattenPoint(geometry.coordinates, data, indices, options);
461
+ break;
462
+ case "MultiPoint":
463
+ type = "Point";
464
+ geometry.coordinates.map((c) => flattenPoint(c, data, indices, options));
465
+ break;
466
+ case "LineString":
467
+ type = "LineString";
468
+ flattenLineString(geometry.coordinates, data, indices, options);
469
+ break;
470
+ case "MultiLineString":
471
+ type = "LineString";
472
+ geometry.coordinates.map((c) => flattenLineString(c, data, indices, options));
473
+ break;
474
+ case "Polygon":
475
+ type = "Polygon";
476
+ areas = [];
477
+ flattenPolygon(geometry.coordinates, data, indices, areas, options);
478
+ break;
479
+ case "MultiPolygon":
480
+ type = "Polygon";
481
+ areas = [];
482
+ geometry.coordinates.map((c) => flattenPolygon(c, data, indices, areas, options));
483
+ break;
484
+ default:
485
+ throw new Error(`Unknown type: ${type}`);
486
+ }
487
+ return { ...feature, geometry: { type, indices, data, areas } };
488
+ }
489
+
490
+ // src/lib/geojson-to-binary.ts
491
+ function geojsonToBinary(features, options = { fixRingWinding: true, triangulate: true }) {
492
+ const geometryInfo = extractGeometryInfo(features);
493
+ const coordLength = geometryInfo.coordLength;
494
+ const { fixRingWinding } = options;
495
+ const flatFeatures = geojsonToFlatGeojson(features, { coordLength, fixRingWinding });
496
+ return flatGeojsonToBinary(flatFeatures, geometryInfo, {
497
+ numericPropKeys: options.numericPropKeys,
498
+ PositionDataType: options.PositionDataType || Float32Array,
499
+ triangulate: options.triangulate
500
+ });
501
+ }
502
+
503
+ // src/lib/binary-to-geojson.ts
504
+ function binaryToGeojson(data, options) {
505
+ const globalFeatureId = options == null ? void 0 : options.globalFeatureId;
506
+ if (globalFeatureId !== void 0) {
507
+ return getSingleFeature(data, globalFeatureId);
508
+ }
509
+ return parseFeatures(data, options == null ? void 0 : options.type);
510
+ }
511
+ function getSingleFeature(data, globalFeatureId) {
512
+ const dataArray = normalizeInput(data);
513
+ for (const data2 of dataArray) {
514
+ let lastIndex = 0;
515
+ let lastValue = data2.featureIds.value[0];
516
+ for (let i = 0; i < data2.featureIds.value.length; i++) {
517
+ const currValue = data2.featureIds.value[i];
518
+ if (currValue === lastValue) {
519
+ continue;
520
+ }
521
+ if (globalFeatureId === data2.globalFeatureIds.value[lastIndex]) {
522
+ return parseFeature(data2, lastIndex, i);
523
+ }
524
+ lastIndex = i;
525
+ lastValue = currValue;
526
+ }
527
+ if (globalFeatureId === data2.globalFeatureIds.value[lastIndex]) {
528
+ return parseFeature(data2, lastIndex, data2.featureIds.value.length);
529
+ }
530
+ }
531
+ throw new Error(`featureId:${globalFeatureId} not found`);
532
+ }
533
+ function parseFeatures(data, type) {
534
+ const dataArray = normalizeInput(data, type);
535
+ return parseFeatureCollection(dataArray);
536
+ }
537
+ function binaryToGeometry(data, startIndex, endIndex) {
538
+ switch (data.type) {
539
+ case "Point":
540
+ return pointToGeoJson(data, startIndex, endIndex);
541
+ case "LineString":
542
+ return lineStringToGeoJson(data, startIndex, endIndex);
543
+ case "Polygon":
544
+ return polygonToGeoJson(data, startIndex, endIndex);
545
+ default:
546
+ const unexpectedInput = data;
547
+ throw new Error(`Unsupported geometry type: ${unexpectedInput == null ? void 0 : unexpectedInput.type}`);
548
+ }
549
+ }
550
+ function normalizeInput(data, type) {
551
+ const features = [];
552
+ if (data.points) {
553
+ data.points.type = "Point";
554
+ features.push(data.points);
555
+ }
556
+ if (data.lines) {
557
+ data.lines.type = "LineString";
558
+ features.push(data.lines);
559
+ }
560
+ if (data.polygons) {
561
+ data.polygons.type = "Polygon";
562
+ features.push(data.polygons);
563
+ }
564
+ return features;
565
+ }
566
+ function parseFeatureCollection(dataArray) {
567
+ const features = [];
568
+ for (const data of dataArray) {
569
+ if (data.featureIds.value.length === 0) {
570
+ continue;
571
+ }
572
+ let lastIndex = 0;
573
+ let lastValue = data.featureIds.value[0];
574
+ for (let i = 0; i < data.featureIds.value.length; i++) {
575
+ const currValue = data.featureIds.value[i];
576
+ if (currValue === lastValue) {
577
+ continue;
578
+ }
579
+ features.push(parseFeature(data, lastIndex, i));
580
+ lastIndex = i;
581
+ lastValue = currValue;
582
+ }
583
+ features.push(parseFeature(data, lastIndex, data.featureIds.value.length));
584
+ }
585
+ return features;
586
+ }
587
+ function parseFeature(data, startIndex, endIndex) {
588
+ const geometry = binaryToGeometry(data, startIndex, endIndex);
589
+ const properties = parseProperties(data, startIndex, endIndex);
590
+ const fields = parseFields(data, startIndex, endIndex);
591
+ return { type: "Feature", geometry, properties, ...fields };
592
+ }
593
+ function parseFields(data, startIndex = 0, endIndex) {
594
+ return data.fields && data.fields[data.featureIds.value[startIndex]];
595
+ }
596
+ function parseProperties(data, startIndex = 0, endIndex) {
597
+ const properties = Object.assign({}, data.properties[data.featureIds.value[startIndex]]);
598
+ for (const key in data.numericProps) {
599
+ properties[key] = data.numericProps[key].value[startIndex];
600
+ }
601
+ return properties;
602
+ }
603
+ function polygonToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
604
+ const { positions } = data;
605
+ const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
606
+ const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
607
+ (x) => x >= startIndex && x <= endIndex
608
+ );
609
+ const multi = polygonIndices.length > 2;
610
+ if (!multi) {
611
+ const coordinates2 = [];
612
+ for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
613
+ const startRingIndex = primitivePolygonIndices[i];
614
+ const endRingIndex = primitivePolygonIndices[i + 1];
615
+ const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
616
+ coordinates2.push(ringCoordinates);
617
+ }
618
+ return { type: "Polygon", coordinates: coordinates2 };
619
+ }
620
+ const coordinates = [];
621
+ for (let i = 0; i < polygonIndices.length - 1; i++) {
622
+ const startPolygonIndex = polygonIndices[i];
623
+ const endPolygonIndex = polygonIndices[i + 1];
624
+ const polygonCoordinates = polygonToGeoJson(
625
+ data,
626
+ startPolygonIndex,
627
+ endPolygonIndex
628
+ ).coordinates;
629
+ coordinates.push(polygonCoordinates);
630
+ }
631
+ return { type: "MultiPolygon", coordinates };
632
+ }
633
+ function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
634
+ const { positions } = data;
635
+ const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
636
+ const multi = pathIndices.length > 2;
637
+ if (!multi) {
638
+ const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
639
+ return { type: "LineString", coordinates: coordinates2 };
640
+ }
641
+ const coordinates = [];
642
+ for (let i = 0; i < pathIndices.length - 1; i++) {
643
+ const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
644
+ coordinates.push(ringCoordinates);
645
+ }
646
+ return { type: "MultiLineString", coordinates };
647
+ }
648
+ function pointToGeoJson(data, startIndex, endIndex) {
649
+ const { positions } = data;
650
+ const coordinates = ringToGeoJson(positions, startIndex, endIndex);
651
+ const multi = coordinates.length > 1;
652
+ if (multi) {
653
+ return { type: "MultiPoint", coordinates };
654
+ }
655
+ return { type: "Point", coordinates: coordinates[0] };
656
+ }
657
+ function ringToGeoJson(positions, startIndex, endIndex) {
658
+ startIndex = startIndex || 0;
659
+ endIndex = endIndex || positions.value.length / positions.size;
660
+ const ringCoordinates = [];
661
+ for (let j = startIndex; j < endIndex; j++) {
662
+ const coord = Array();
663
+ for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
664
+ coord.push(Number(positions.value[k]));
665
+ }
666
+ ringCoordinates.push(coord);
667
+ }
668
+ return ringCoordinates;
669
+ }
670
+
671
+ // src/lib/transform.ts
672
+ function transformBinaryCoords(binaryFeatures, transformCoordinate) {
673
+ if (binaryFeatures.points) {
674
+ transformBinaryGeometryPositions(binaryFeatures.points, transformCoordinate);
675
+ }
676
+ if (binaryFeatures.lines) {
677
+ transformBinaryGeometryPositions(binaryFeatures.lines, transformCoordinate);
678
+ }
679
+ if (binaryFeatures.polygons) {
680
+ transformBinaryGeometryPositions(binaryFeatures.polygons, transformCoordinate);
681
+ }
682
+ return binaryFeatures;
683
+ }
684
+ function transformBinaryGeometryPositions(binaryGeometry, fn) {
685
+ const { positions } = binaryGeometry;
686
+ for (let i = 0; i < positions.value.length; i += positions.size) {
687
+ const coord = Array.from(positions.value.subarray(i, i + positions.size));
688
+ const transformedCoord = fn(coord);
689
+ positions.value.set(transformedCoord, i);
690
+ }
691
+ }
692
+ function transformGeoJsonCoords(features, fn) {
693
+ for (const feature of features) {
694
+ feature.geometry.coordinates = coordMap(feature.geometry.coordinates, fn);
695
+ }
696
+ return features;
697
+ }
698
+ function coordMap(array, fn) {
699
+ if (isCoord(array)) {
700
+ return fn(array);
701
+ }
702
+ return array.map((item) => {
703
+ return coordMap(item, fn);
704
+ });
705
+ }
706
+ function isCoord(array) {
707
+ return Array.isArray(array) && Number.isFinite(array[0]) && Number.isFinite(array[1]);
708
+ }