@loaders.gl/json 4.0.0-beta.8 → 4.0.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.
@@ -253,1356 +253,1356 @@
253
253
  return obj;
254
254
  }
255
255
 
256
- // ../../node_modules/@math.gl/polygon/dist/polygon-utils.js
257
- var DimIndex = {
258
- x: 0,
259
- y: 1,
260
- z: 2
261
- };
262
- function getPolygonSignedArea(points, options = {}) {
263
- const {
264
- start = 0,
265
- end = points.length,
266
- plane = "xy"
267
- } = options;
268
- const dim = options.size || 2;
269
- let area2 = 0;
270
- const i0 = DimIndex[plane[0]];
271
- const i1 = DimIndex[plane[1]];
272
- for (let i = start, j = end - dim; i < end; i += dim) {
273
- area2 += (points[i + i0] - points[j + i0]) * (points[i + i1] + points[j + i1]);
274
- j = i;
256
+ // ../schema/src/lib/table/batches/base-table-batch-aggregator.ts
257
+ var DEFAULT_ROW_COUNT = 100;
258
+ var BaseTableBatchAggregator = class {
259
+ constructor(schema, options) {
260
+ this.length = 0;
261
+ this.rows = null;
262
+ this.cursor = 0;
263
+ this._headers = [];
264
+ this.options = options;
265
+ this.schema = schema;
266
+ if (!Array.isArray(schema)) {
267
+ this._headers = [];
268
+ for (const key in schema) {
269
+ this._headers[schema[key].index] = schema[key].name;
270
+ }
271
+ }
275
272
  }
276
- return area2 / 2;
277
- }
278
-
279
- // ../../node_modules/@math.gl/polygon/dist/earcut.js
280
- function earcut(positions, holeIndices, dim = 2, areas, plane = "xy") {
281
- const hasHoles = holeIndices && holeIndices.length;
282
- const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
283
- let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0], plane);
284
- const triangles = [];
285
- if (!outerNode || outerNode.next === outerNode.prev)
286
- return triangles;
287
- let invSize;
288
- let maxX;
289
- let maxY;
290
- let minX;
291
- let minY;
292
- let x;
293
- let y;
294
- if (hasHoles)
295
- outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas, plane);
296
- if (positions.length > 80 * dim) {
297
- minX = maxX = positions[0];
298
- minY = maxY = positions[1];
299
- for (let i = dim; i < outerLen; i += dim) {
300
- x = positions[i];
301
- y = positions[i + 1];
302
- if (x < minX)
303
- minX = x;
304
- if (y < minY)
305
- minY = y;
306
- if (x > maxX)
307
- maxX = x;
308
- if (y > maxY)
309
- maxY = y;
273
+ rowCount() {
274
+ return this.length;
275
+ }
276
+ addArrayRow(row, cursor) {
277
+ if (Number.isFinite(cursor)) {
278
+ this.cursor = cursor;
310
279
  }
311
- invSize = Math.max(maxX - minX, maxY - minY);
312
- invSize = invSize !== 0 ? 32767 / invSize : 0;
280
+ this.rows = this.rows || new Array(DEFAULT_ROW_COUNT);
281
+ this.rows[this.length] = row;
282
+ this.length++;
313
283
  }
314
- earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
315
- return triangles;
284
+ addObjectRow(row, cursor) {
285
+ if (Number.isFinite(cursor)) {
286
+ this.cursor = cursor;
287
+ }
288
+ this.rows = this.rows || new Array(DEFAULT_ROW_COUNT);
289
+ this.rows[this.length] = row;
290
+ this.length++;
291
+ }
292
+ getBatch() {
293
+ let rows = this.rows;
294
+ if (!rows) {
295
+ return null;
296
+ }
297
+ rows = rows.slice(0, this.length);
298
+ this.rows = null;
299
+ const batch = {
300
+ shape: this.options.shape,
301
+ batchType: "data",
302
+ data: rows,
303
+ length: this.length,
304
+ schema: this.schema,
305
+ cursor: this.cursor
306
+ };
307
+ return batch;
308
+ }
309
+ };
310
+
311
+ // ../schema/src/lib/table/simple-table/row-utils.ts
312
+ function convertToObjectRow(arrayRow, headers) {
313
+ if (!arrayRow) {
314
+ throw new Error("null row");
315
+ }
316
+ if (!headers) {
317
+ throw new Error("no headers");
318
+ }
319
+ const objectRow = {};
320
+ for (let i = 0; i < headers.length; i++) {
321
+ objectRow[headers[i]] = arrayRow[i];
322
+ }
323
+ return objectRow;
316
324
  }
317
- function linkedList(data, start, end, dim, clockwise, area2, plane) {
318
- let i;
319
- let last;
320
- if (area2 === void 0) {
321
- area2 = getPolygonSignedArea(data, {
322
- start,
323
- end,
324
- size: dim,
325
- plane
326
- });
325
+ function convertToArrayRow(objectRow, headers) {
326
+ if (!objectRow) {
327
+ throw new Error("null row");
327
328
  }
328
- let i0 = DimIndex[plane[0]];
329
- let i1 = DimIndex[plane[1]];
330
- if (clockwise === area2 < 0) {
331
- for (i = start; i < end; i += dim)
332
- last = insertNode(i, data[i + i0], data[i + i1], last);
333
- } else {
334
- for (i = end - dim; i >= start; i -= dim)
335
- last = insertNode(i, data[i + i0], data[i + i1], last);
329
+ if (!headers) {
330
+ throw new Error("no headers");
336
331
  }
337
- if (last && equals(last, last.next)) {
338
- removeNode(last);
339
- last = last.next;
332
+ const arrayRow = new Array(headers.length);
333
+ for (let i = 0; i < headers.length; i++) {
334
+ arrayRow[i] = objectRow[headers[i]];
340
335
  }
341
- return last;
336
+ return arrayRow;
342
337
  }
343
- function filterPoints(start, end) {
344
- if (!start)
345
- return start;
346
- if (!end)
347
- end = start;
348
- let p = start;
349
- let again;
350
- do {
351
- again = false;
352
- if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
353
- removeNode(p);
354
- p = end = p.prev;
355
- if (p === p.next)
338
+
339
+ // ../schema/src/lib/table/batches/row-table-batch-aggregator.ts
340
+ var DEFAULT_ROW_COUNT2 = 100;
341
+ var RowTableBatchAggregator = class {
342
+ constructor(schema, options) {
343
+ this.length = 0;
344
+ this.objectRows = null;
345
+ this.arrayRows = null;
346
+ this.cursor = 0;
347
+ this._headers = [];
348
+ this.options = options;
349
+ this.schema = schema;
350
+ if (!Array.isArray(schema)) {
351
+ this._headers = [];
352
+ for (const key in schema) {
353
+ this._headers[schema[key].index] = schema[key].name;
354
+ }
355
+ }
356
+ }
357
+ rowCount() {
358
+ return this.length;
359
+ }
360
+ addArrayRow(row, cursor) {
361
+ if (Number.isFinite(cursor)) {
362
+ this.cursor = cursor;
363
+ }
364
+ switch (this.options.shape) {
365
+ case "object-row-table":
366
+ const rowObject = convertToObjectRow(row, this._headers);
367
+ this.addObjectRow(rowObject, cursor);
368
+ break;
369
+ case "array-row-table":
370
+ this.arrayRows = this.arrayRows || new Array(DEFAULT_ROW_COUNT2);
371
+ this.arrayRows[this.length] = row;
372
+ this.length++;
356
373
  break;
357
- again = true;
358
- } else {
359
- p = p.next;
360
374
  }
361
- } while (again || p !== end);
362
- return end;
363
- }
364
- function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
365
- if (!ear)
366
- return;
367
- if (!pass && invSize)
368
- indexCurve(ear, minX, minY, invSize);
369
- let stop = ear;
370
- let prev;
371
- let next;
372
- while (ear.prev !== ear.next) {
373
- prev = ear.prev;
374
- next = ear.next;
375
- if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
376
- triangles.push(prev.i / dim | 0);
377
- triangles.push(ear.i / dim | 0);
378
- triangles.push(next.i / dim | 0);
379
- removeNode(ear);
380
- ear = next.next;
381
- stop = next.next;
382
- continue;
375
+ }
376
+ addObjectRow(row, cursor) {
377
+ if (Number.isFinite(cursor)) {
378
+ this.cursor = cursor;
383
379
  }
384
- ear = next;
385
- if (ear === stop) {
386
- if (!pass) {
387
- earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
388
- } else if (pass === 1) {
389
- ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
390
- earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
391
- } else if (pass === 2) {
392
- splitEarcut(ear, triangles, dim, minX, minY, invSize);
393
- }
394
- break;
380
+ switch (this.options.shape) {
381
+ case "array-row-table":
382
+ const rowArray = convertToArrayRow(row, this._headers);
383
+ this.addArrayRow(rowArray, cursor);
384
+ break;
385
+ case "object-row-table":
386
+ this.objectRows = this.objectRows || new Array(DEFAULT_ROW_COUNT2);
387
+ this.objectRows[this.length] = row;
388
+ this.length++;
389
+ break;
395
390
  }
396
391
  }
397
- }
398
- function isEar(ear) {
399
- const a = ear.prev;
400
- const b = ear;
401
- const c = ear.next;
402
- if (area(a, b, c) >= 0)
403
- return false;
404
- const ax = a.x;
405
- const bx = b.x;
406
- const cx = c.x;
407
- const ay = a.y;
408
- const by = b.y;
409
- const cy = c.y;
410
- const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
411
- const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
412
- const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
413
- const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
414
- let p = c.next;
415
- while (p !== a) {
416
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
417
- return false;
418
- p = p.next;
392
+ getBatch() {
393
+ let rows = this.arrayRows || this.objectRows;
394
+ if (!rows) {
395
+ return null;
396
+ }
397
+ rows = rows.slice(0, this.length);
398
+ this.arrayRows = null;
399
+ this.objectRows = null;
400
+ return {
401
+ shape: this.options.shape,
402
+ batchType: "data",
403
+ data: rows,
404
+ length: this.length,
405
+ schema: this.schema,
406
+ cursor: this.cursor
407
+ };
419
408
  }
420
- return true;
421
- }
422
- function isEarHashed(ear, minX, minY, invSize) {
423
- const a = ear.prev;
424
- const b = ear;
425
- const c = ear.next;
426
- if (area(a, b, c) >= 0)
427
- return false;
428
- const ax = a.x;
429
- const bx = b.x;
430
- const cx = c.x;
431
- const ay = a.y;
432
- const by = b.y;
433
- const cy = c.y;
434
- const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
435
- const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
436
- const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
437
- const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
438
- const minZ = zOrder(x0, y0, minX, minY, invSize);
439
- const maxZ = zOrder(x1, y1, minX, minY, invSize);
440
- let p = ear.prevZ;
441
- let n = ear.nextZ;
442
- while (p && p.z >= minZ && n && n.z <= maxZ) {
443
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
444
- return false;
445
- p = p.prevZ;
446
- if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
447
- return false;
448
- n = n.nextZ;
409
+ };
410
+
411
+ // ../schema/src/lib/table/batches/columnar-table-batch-aggregator.ts
412
+ var DEFAULT_ROW_COUNT3 = 100;
413
+ var ColumnarTableBatchAggregator = class {
414
+ constructor(schema, options) {
415
+ this.length = 0;
416
+ this.allocated = 0;
417
+ this.columns = {};
418
+ this.schema = schema;
419
+ this._reallocateColumns();
449
420
  }
450
- while (p && p.z >= minZ) {
451
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
452
- return false;
453
- p = p.prevZ;
421
+ rowCount() {
422
+ return this.length;
454
423
  }
455
- while (n && n.z <= maxZ) {
456
- if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
457
- return false;
458
- n = n.nextZ;
424
+ addArrayRow(row) {
425
+ this._reallocateColumns();
426
+ let i = 0;
427
+ for (const fieldName in this.columns) {
428
+ this.columns[fieldName][this.length] = row[i++];
429
+ }
430
+ this.length++;
459
431
  }
460
- return true;
461
- }
462
- function cureLocalIntersections(start, triangles, dim) {
463
- let p = start;
464
- do {
465
- const a = p.prev;
466
- const b = p.next.next;
467
- if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
468
- triangles.push(a.i / dim | 0);
469
- triangles.push(p.i / dim | 0);
470
- triangles.push(b.i / dim | 0);
471
- removeNode(p);
472
- removeNode(p.next);
473
- p = start = b;
432
+ addObjectRow(row) {
433
+ this._reallocateColumns();
434
+ for (const fieldName in row) {
435
+ this.columns[fieldName][this.length] = row[fieldName];
474
436
  }
475
- p = p.next;
476
- } while (p !== start);
477
- return filterPoints(p);
478
- }
479
- function splitEarcut(start, triangles, dim, minX, minY, invSize) {
480
- let a = start;
481
- do {
482
- let b = a.next.next;
483
- while (b !== a.prev) {
484
- if (a.i !== b.i && isValidDiagonal(a, b)) {
485
- let c = splitPolygon(a, b);
486
- a = filterPoints(a, a.next);
487
- c = filterPoints(c, c.next);
488
- earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
489
- earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
490
- return;
437
+ this.length++;
438
+ }
439
+ getBatch() {
440
+ this._pruneColumns();
441
+ const columns = Array.isArray(this.schema) ? this.columns : {};
442
+ if (!Array.isArray(this.schema)) {
443
+ for (const fieldName in this.schema) {
444
+ const field = this.schema[fieldName];
445
+ columns[field.name] = this.columns[field.index];
491
446
  }
492
- b = b.next;
493
447
  }
494
- a = a.next;
495
- } while (a !== start);
496
- }
497
- function eliminateHoles(data, holeIndices, outerNode, dim, areas, plane) {
498
- const queue = [];
499
- let i;
500
- let len;
501
- let start;
502
- let end;
503
- let list;
504
- for (i = 0, len = holeIndices.length; i < len; i++) {
505
- start = holeIndices[i] * dim;
506
- end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
507
- list = linkedList(data, start, end, dim, false, areas && areas[i + 1], plane);
508
- if (list === list.next)
509
- list.steiner = true;
510
- queue.push(getLeftmost(list));
511
- }
512
- queue.sort(compareX);
513
- for (i = 0; i < queue.length; i++) {
514
- outerNode = eliminateHole(queue[i], outerNode);
515
- }
516
- return outerNode;
517
- }
518
- function compareX(a, b) {
519
- return a.x - b.x;
520
- }
521
- function eliminateHole(hole, outerNode) {
522
- const bridge = findHoleBridge(hole, outerNode);
523
- if (!bridge) {
524
- return outerNode;
448
+ this.columns = {};
449
+ const batch = {
450
+ shape: "columnar-table",
451
+ batchType: "data",
452
+ data: columns,
453
+ schema: this.schema,
454
+ length: this.length
455
+ };
456
+ return batch;
525
457
  }
526
- const bridgeReverse = splitPolygon(bridge, hole);
527
- filterPoints(bridgeReverse, bridgeReverse.next);
528
- return filterPoints(bridge, bridge.next);
529
- }
530
- function findHoleBridge(hole, outerNode) {
531
- let p = outerNode;
532
- const hx = hole.x;
533
- const hy = hole.y;
534
- let qx = -Infinity;
535
- let m;
536
- do {
537
- if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
538
- const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
539
- if (x <= hx && x > qx) {
540
- qx = x;
541
- m = p.x < p.next.x ? p : p.next;
542
- if (x === hx)
543
- return m;
544
- }
458
+ // HELPERS
459
+ _reallocateColumns() {
460
+ if (this.length < this.allocated) {
461
+ return;
545
462
  }
546
- p = p.next;
547
- } while (p !== outerNode);
548
- if (!m)
549
- return null;
550
- const stop = m;
551
- const mx = m.x;
552
- const my = m.y;
553
- let tanMin = Infinity;
554
- let tan;
555
- p = m;
556
- do {
557
- if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
558
- tan = Math.abs(hy - p.y) / (hx - p.x);
559
- if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
560
- m = p;
561
- tanMin = tan;
463
+ this.allocated = this.allocated > 0 ? this.allocated *= 2 : DEFAULT_ROW_COUNT3;
464
+ this.columns = {};
465
+ for (const fieldName in this.schema) {
466
+ const field = this.schema[fieldName];
467
+ const ArrayType = field.type || Float32Array;
468
+ const oldColumn = this.columns[field.index];
469
+ if (oldColumn && ArrayBuffer.isView(oldColumn)) {
470
+ const typedArray = new ArrayType(this.allocated);
471
+ typedArray.set(oldColumn);
472
+ this.columns[field.index] = typedArray;
473
+ } else if (oldColumn) {
474
+ oldColumn.length = this.allocated;
475
+ this.columns[field.index] = oldColumn;
476
+ } else {
477
+ this.columns[field.index] = new ArrayType(this.allocated);
562
478
  }
563
479
  }
564
- p = p.next;
565
- } while (p !== stop);
566
- return m;
567
- }
568
- function sectorContainsSector(m, p) {
569
- return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
570
- }
571
- function indexCurve(start, minX, minY, invSize) {
572
- let p = start;
573
- do {
574
- if (p.z === 0)
575
- p.z = zOrder(p.x, p.y, minX, minY, invSize);
576
- p.prevZ = p.prev;
577
- p.nextZ = p.next;
578
- p = p.next;
579
- } while (p !== start);
580
- p.prevZ.nextZ = null;
581
- p.prevZ = null;
582
- sortLinked(p);
583
- }
584
- function sortLinked(list) {
585
- let e;
586
- let i;
587
- let inSize = 1;
588
- let numMerges;
589
- let p;
590
- let pSize;
591
- let q;
592
- let qSize;
593
- let tail;
594
- do {
595
- p = list;
596
- list = null;
597
- tail = null;
598
- numMerges = 0;
599
- while (p) {
600
- numMerges++;
601
- q = p;
602
- pSize = 0;
603
- for (i = 0; i < inSize; i++) {
604
- pSize++;
605
- q = q.nextZ;
606
- if (!q)
607
- break;
608
- }
609
- qSize = inSize;
610
- while (pSize > 0 || qSize > 0 && q) {
611
- if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
612
- e = p;
613
- p = p.nextZ;
614
- pSize--;
615
- } else {
616
- e = q;
617
- q = q.nextZ;
618
- qSize--;
619
- }
620
- if (tail)
621
- tail.nextZ = e;
622
- else
623
- list = e;
624
- e.prevZ = tail;
625
- tail = e;
480
+ }
481
+ _pruneColumns() {
482
+ for (const [columnName, column] of Object.entries(this.columns)) {
483
+ this.columns[columnName] = column.slice(0, this.length);
484
+ }
485
+ }
486
+ };
487
+
488
+ // ../schema/src/lib/table/batches/table-batch-builder.ts
489
+ var DEFAULT_OPTIONS = {
490
+ shape: "array-row-table",
491
+ batchSize: "auto",
492
+ batchDebounceMs: 0,
493
+ limit: 0,
494
+ _limitMB: 0
495
+ };
496
+ var ERR_MESSAGE = "TableBatchBuilder";
497
+ var TableBatchBuilder = class {
498
+ constructor(schema, options) {
499
+ this.aggregator = null;
500
+ this.batchCount = 0;
501
+ this.bytesUsed = 0;
502
+ this.isChunkComplete = false;
503
+ this.lastBatchEmittedMs = Date.now();
504
+ this.totalLength = 0;
505
+ this.totalBytes = 0;
506
+ this.rowBytes = 0;
507
+ this.schema = schema;
508
+ this.options = { ...DEFAULT_OPTIONS, ...options };
509
+ }
510
+ limitReached() {
511
+ if (Boolean(this.options?.limit) && this.totalLength >= this.options.limit) {
512
+ return true;
513
+ }
514
+ if (Boolean(this.options?._limitMB) && this.totalBytes / 1e6 >= this.options._limitMB) {
515
+ return true;
516
+ }
517
+ return false;
518
+ }
519
+ /** @deprecated Use addArrayRow or addObjectRow */
520
+ addRow(row) {
521
+ if (this.limitReached()) {
522
+ return;
523
+ }
524
+ this.totalLength++;
525
+ this.rowBytes = this.rowBytes || this._estimateRowMB(row);
526
+ this.totalBytes += this.rowBytes;
527
+ if (Array.isArray(row)) {
528
+ this.addArrayRow(row);
529
+ } else {
530
+ this.addObjectRow(row);
531
+ }
532
+ }
533
+ /** Add one row to the batch */
534
+ addArrayRow(row) {
535
+ if (!this.aggregator) {
536
+ const TableBatchType = this._getTableBatchType();
537
+ this.aggregator = new TableBatchType(this.schema, this.options);
538
+ }
539
+ this.aggregator.addArrayRow(row);
540
+ }
541
+ /** Add one row to the batch */
542
+ addObjectRow(row) {
543
+ if (!this.aggregator) {
544
+ const TableBatchType = this._getTableBatchType();
545
+ this.aggregator = new TableBatchType(this.schema, this.options);
546
+ }
547
+ this.aggregator.addObjectRow(row);
548
+ }
549
+ /** Mark an incoming raw memory chunk has completed */
550
+ chunkComplete(chunk) {
551
+ if (chunk instanceof ArrayBuffer) {
552
+ this.bytesUsed += chunk.byteLength;
553
+ }
554
+ if (typeof chunk === "string") {
555
+ this.bytesUsed += chunk.length;
556
+ }
557
+ this.isChunkComplete = true;
558
+ }
559
+ getFullBatch(options) {
560
+ return this._isFull() ? this._getBatch(options) : null;
561
+ }
562
+ getFinalBatch(options) {
563
+ return this._getBatch(options);
564
+ }
565
+ // INTERNAL
566
+ _estimateRowMB(row) {
567
+ return Array.isArray(row) ? row.length * 8 : Object.keys(row).length * 8;
568
+ }
569
+ _isFull() {
570
+ if (!this.aggregator || this.aggregator.rowCount() === 0) {
571
+ return false;
572
+ }
573
+ if (this.options.batchSize === "auto") {
574
+ if (!this.isChunkComplete) {
575
+ return false;
626
576
  }
627
- p = q;
577
+ } else if (this.options.batchSize > this.aggregator.rowCount()) {
578
+ return false;
628
579
  }
629
- tail.nextZ = null;
630
- inSize *= 2;
631
- } while (numMerges > 1);
632
- return list;
633
- }
634
- function zOrder(x, y, minX, minY, invSize) {
635
- x = (x - minX) * invSize | 0;
636
- y = (y - minY) * invSize | 0;
637
- x = (x | x << 8) & 16711935;
638
- x = (x | x << 4) & 252645135;
639
- x = (x | x << 2) & 858993459;
640
- x = (x | x << 1) & 1431655765;
641
- y = (y | y << 8) & 16711935;
642
- y = (y | y << 4) & 252645135;
643
- y = (y | y << 2) & 858993459;
644
- y = (y | y << 1) & 1431655765;
645
- return x | y << 1;
646
- }
647
- function getLeftmost(start) {
648
- let p = start;
649
- let leftmost = start;
650
- do {
651
- if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
652
- leftmost = p;
653
- p = p.next;
654
- } while (p !== start);
655
- return leftmost;
656
- }
657
- function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
658
- return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
659
- }
660
- function isValidDiagonal(a, b) {
661
- return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && (area(a.prev, a, b.prev) || area(a, b.prev, b)) || equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
662
- }
663
- function area(p, q, r) {
664
- return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
665
- }
666
- function equals(p1, p2) {
667
- return p1.x === p2.x && p1.y === p2.y;
668
- }
669
- function intersects(p1, q1, p2, q2) {
670
- const o1 = sign(area(p1, q1, p2));
671
- const o2 = sign(area(p1, q1, q2));
672
- const o3 = sign(area(p2, q2, p1));
673
- const o4 = sign(area(p2, q2, q1));
674
- if (o1 !== o2 && o3 !== o4)
675
- return true;
676
- if (o1 === 0 && onSegment(p1, p2, q1))
677
- return true;
678
- if (o2 === 0 && onSegment(p1, q2, q1))
679
- return true;
680
- if (o3 === 0 && onSegment(p2, p1, q2))
681
- return true;
682
- if (o4 === 0 && onSegment(p2, q1, q2))
580
+ if (this.options.batchDebounceMs > Date.now() - this.lastBatchEmittedMs) {
581
+ return false;
582
+ }
583
+ this.isChunkComplete = false;
584
+ this.lastBatchEmittedMs = Date.now();
683
585
  return true;
684
- return false;
685
- }
686
- function onSegment(p, q, r) {
687
- return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
688
- }
689
- function sign(num) {
690
- return num > 0 ? 1 : num < 0 ? -1 : 0;
691
- }
692
- function intersectsPolygon(a, b) {
693
- let p = a;
694
- do {
695
- if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
696
- return true;
697
- p = p.next;
698
- } while (p !== a);
699
- return false;
700
- }
701
- function locallyInside(a, b) {
702
- return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
703
- }
704
- function middleInside(a, b) {
705
- let p = a;
706
- let inside = false;
707
- const px = (a.x + b.x) / 2;
708
- const py = (a.y + b.y) / 2;
709
- do {
710
- if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
711
- inside = !inside;
712
- p = p.next;
713
- } while (p !== a);
714
- return inside;
715
- }
716
- function splitPolygon(a, b) {
717
- const a2 = new Vertex(a.i, a.x, a.y);
718
- const b2 = new Vertex(b.i, b.x, b.y);
719
- const an = a.next;
720
- const bp = b.prev;
721
- a.next = b;
722
- b.prev = a;
723
- a2.next = an;
724
- an.prev = a2;
725
- b2.next = a2;
726
- a2.prev = b2;
727
- bp.next = b2;
728
- b2.prev = bp;
729
- return b2;
730
- }
731
- function insertNode(i, x, y, last) {
732
- const p = new Vertex(i, x, y);
733
- if (!last) {
734
- p.prev = p;
735
- p.next = p;
736
- } else {
737
- p.next = last.next;
738
- p.prev = last;
739
- last.next.prev = p;
740
- last.next = p;
741
586
  }
742
- return p;
743
- }
744
- function removeNode(p) {
745
- p.next.prev = p.prev;
746
- p.prev.next = p.next;
747
- if (p.prevZ)
748
- p.prevZ.nextZ = p.nextZ;
749
- if (p.nextZ)
750
- p.nextZ.prevZ = p.prevZ;
751
- }
752
- var Vertex = class {
753
- constructor(i, x, y) {
754
- _defineProperty(this, "i", void 0);
755
- _defineProperty(this, "x", void 0);
756
- _defineProperty(this, "y", void 0);
757
- _defineProperty(this, "prev", null);
758
- _defineProperty(this, "next", null);
759
- _defineProperty(this, "z", 0);
760
- _defineProperty(this, "prevZ", null);
761
- _defineProperty(this, "nextZ", null);
762
- _defineProperty(this, "steiner", false);
763
- this.i = i;
764
- this.x = x;
765
- this.y = y;
587
+ /**
588
+ * bytesUsed can be set via chunkComplete or via getBatch*
589
+ */
590
+ _getBatch(options) {
591
+ if (!this.aggregator) {
592
+ return null;
593
+ }
594
+ if (options?.bytesUsed) {
595
+ this.bytesUsed = options.bytesUsed;
596
+ }
597
+ const normalizedBatch = this.aggregator.getBatch();
598
+ normalizedBatch.count = this.batchCount;
599
+ normalizedBatch.bytesUsed = this.bytesUsed;
600
+ Object.assign(normalizedBatch, options);
601
+ this.batchCount++;
602
+ this.aggregator = null;
603
+ return normalizedBatch;
604
+ }
605
+ _getTableBatchType() {
606
+ switch (this.options.shape) {
607
+ case "row-table":
608
+ return BaseTableBatchAggregator;
609
+ case "array-row-table":
610
+ case "object-row-table":
611
+ return RowTableBatchAggregator;
612
+ case "columnar-table":
613
+ return ColumnarTableBatchAggregator;
614
+ case "arrow-table":
615
+ if (!TableBatchBuilder.ArrowBatch) {
616
+ throw new Error(ERR_MESSAGE);
617
+ }
618
+ return TableBatchBuilder.ArrowBatch;
619
+ default:
620
+ throw new Error(ERR_MESSAGE);
621
+ }
766
622
  }
767
623
  };
768
624
 
769
- // ../gis/src/lib/flat-geojson-to-binary.ts
770
- function flatGeojsonToBinary(features, geometryInfo, options) {
771
- const propArrayTypes = extractNumericPropTypes(features);
772
- const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
773
- return fillArrays(
774
- features,
775
- {
776
- propArrayTypes,
777
- ...geometryInfo
778
- },
779
- {
780
- numericPropKeys: options && options.numericPropKeys || numericPropKeys,
781
- PositionDataType: options ? options.PositionDataType : Float32Array,
782
- triangulate: options ? options.triangulate : true
783
- }
784
- );
625
+ // ../../node_modules/@math.gl/polygon/dist/polygon-utils.js
626
+ var DimIndex = {
627
+ x: 0,
628
+ y: 1,
629
+ z: 2
630
+ };
631
+ function getPolygonSignedArea(points, options = {}) {
632
+ const {
633
+ start = 0,
634
+ end = points.length,
635
+ plane = "xy"
636
+ } = options;
637
+ const dim = options.size || 2;
638
+ let area2 = 0;
639
+ const i0 = DimIndex[plane[0]];
640
+ const i1 = DimIndex[plane[1]];
641
+ for (let i = start, j = end - dim; i < end; i += dim) {
642
+ area2 += (points[i + i0] - points[j + i0]) * (points[i + i1] + points[j + i1]);
643
+ j = i;
644
+ }
645
+ return area2 / 2;
785
646
  }
786
- function extractNumericPropTypes(features) {
787
- const propArrayTypes = {};
788
- for (const feature of features) {
789
- if (feature.properties) {
790
- for (const key in feature.properties) {
791
- const val = feature.properties[key];
792
- propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
793
- }
647
+
648
+ // ../../node_modules/@math.gl/polygon/dist/earcut.js
649
+ function earcut(positions, holeIndices, dim = 2, areas, plane = "xy") {
650
+ const hasHoles = holeIndices && holeIndices.length;
651
+ const outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
652
+ let outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0], plane);
653
+ const triangles = [];
654
+ if (!outerNode || outerNode.next === outerNode.prev)
655
+ return triangles;
656
+ let invSize;
657
+ let maxX;
658
+ let maxY;
659
+ let minX;
660
+ let minY;
661
+ let x;
662
+ let y;
663
+ if (hasHoles)
664
+ outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas, plane);
665
+ if (positions.length > 80 * dim) {
666
+ minX = maxX = positions[0];
667
+ minY = maxY = positions[1];
668
+ for (let i = dim; i < outerLen; i += dim) {
669
+ x = positions[i];
670
+ y = positions[i + 1];
671
+ if (x < minX)
672
+ minX = x;
673
+ if (y < minY)
674
+ minY = y;
675
+ if (x > maxX)
676
+ maxX = x;
677
+ if (y > maxY)
678
+ maxY = y;
794
679
  }
680
+ invSize = Math.max(maxX - minX, maxY - minY);
681
+ invSize = invSize !== 0 ? 32767 / invSize : 0;
795
682
  }
796
- return propArrayTypes;
683
+ earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
684
+ return triangles;
797
685
  }
798
- function fillArrays(features, geometryInfo, options) {
799
- const {
800
- pointPositionsCount,
801
- pointFeaturesCount,
802
- linePositionsCount,
803
- linePathsCount,
804
- lineFeaturesCount,
805
- polygonPositionsCount,
806
- polygonObjectsCount,
807
- polygonRingsCount,
808
- polygonFeaturesCount,
809
- propArrayTypes,
810
- coordLength
811
- } = geometryInfo;
812
- const { numericPropKeys = [], PositionDataType = Float32Array, triangulate = true } = options;
813
- const hasGlobalId = features[0] && "id" in features[0];
814
- const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
815
- const points = {
816
- type: "Point",
817
- positions: new PositionDataType(pointPositionsCount * coordLength),
818
- globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
819
- featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount),
820
- numericProps: {},
821
- properties: [],
822
- fields: []
823
- };
824
- const lines = {
825
- type: "LineString",
826
- pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1),
827
- positions: new PositionDataType(linePositionsCount * coordLength),
828
- globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
829
- featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount),
830
- numericProps: {},
831
- properties: [],
832
- fields: []
833
- };
834
- const polygons = {
835
- type: "Polygon",
836
- polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1),
837
- primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1),
838
- positions: new PositionDataType(polygonPositionsCount * coordLength),
839
- globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
840
- featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount),
841
- numericProps: {},
842
- properties: [],
843
- fields: []
844
- };
845
- if (triangulate) {
846
- polygons.triangles = [];
686
+ function linkedList(data, start, end, dim, clockwise, area2, plane) {
687
+ let i;
688
+ let last;
689
+ if (area2 === void 0) {
690
+ area2 = getPolygonSignedArea(data, {
691
+ start,
692
+ end,
693
+ size: dim,
694
+ plane
695
+ });
696
+ }
697
+ let i0 = DimIndex[plane[0]];
698
+ let i1 = DimIndex[plane[1]];
699
+ if (clockwise === area2 < 0) {
700
+ for (i = start; i < end; i += dim)
701
+ last = insertNode(i, data[i + i0], data[i + i1], last);
702
+ } else {
703
+ for (i = end - dim; i >= start; i -= dim)
704
+ last = insertNode(i, data[i + i0], data[i + i1], last);
847
705
  }
848
- for (const object of [points, lines, polygons]) {
849
- for (const propName of numericPropKeys) {
850
- const T = propArrayTypes[propName];
851
- object.numericProps[propName] = new T(object.positions.length / coordLength);
852
- }
706
+ if (last && equals(last, last.next)) {
707
+ removeNode(last);
708
+ last = last.next;
853
709
  }
854
- lines.pathIndices[linePathsCount] = linePositionsCount;
855
- polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount;
856
- polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount;
857
- const indexMap = {
858
- pointPosition: 0,
859
- pointFeature: 0,
860
- linePosition: 0,
861
- linePath: 0,
862
- lineFeature: 0,
863
- polygonPosition: 0,
864
- polygonObject: 0,
865
- polygonRing: 0,
866
- polygonFeature: 0,
867
- feature: 0
868
- };
869
- for (const feature of features) {
870
- const geometry = feature.geometry;
871
- const properties = feature.properties || {};
872
- switch (geometry.type) {
873
- case "Point":
874
- handlePoint(geometry, points, indexMap, coordLength, properties);
875
- points.properties.push(keepStringProperties(properties, numericPropKeys));
876
- if (hasGlobalId) {
877
- points.fields.push({ id: feature.id });
878
- }
879
- indexMap.pointFeature++;
880
- break;
881
- case "LineString":
882
- handleLineString(geometry, lines, indexMap, coordLength, properties);
883
- lines.properties.push(keepStringProperties(properties, numericPropKeys));
884
- if (hasGlobalId) {
885
- lines.fields.push({ id: feature.id });
886
- }
887
- indexMap.lineFeature++;
888
- break;
889
- case "Polygon":
890
- handlePolygon(geometry, polygons, indexMap, coordLength, properties);
891
- polygons.properties.push(keepStringProperties(properties, numericPropKeys));
892
- if (hasGlobalId) {
893
- polygons.fields.push({ id: feature.id });
894
- }
895
- indexMap.polygonFeature++;
710
+ return last;
711
+ }
712
+ function filterPoints(start, end) {
713
+ if (!start)
714
+ return start;
715
+ if (!end)
716
+ end = start;
717
+ let p = start;
718
+ let again;
719
+ do {
720
+ again = false;
721
+ if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
722
+ removeNode(p);
723
+ p = end = p.prev;
724
+ if (p === p.next)
896
725
  break;
897
- default:
898
- throw new Error("Invalid geometry type");
726
+ again = true;
727
+ } else {
728
+ p = p.next;
729
+ }
730
+ } while (again || p !== end);
731
+ return end;
732
+ }
733
+ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
734
+ if (!ear)
735
+ return;
736
+ if (!pass && invSize)
737
+ indexCurve(ear, minX, minY, invSize);
738
+ let stop = ear;
739
+ let prev;
740
+ let next;
741
+ while (ear.prev !== ear.next) {
742
+ prev = ear.prev;
743
+ next = ear.next;
744
+ if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
745
+ triangles.push(prev.i / dim | 0);
746
+ triangles.push(ear.i / dim | 0);
747
+ triangles.push(next.i / dim | 0);
748
+ removeNode(ear);
749
+ ear = next.next;
750
+ stop = next.next;
751
+ continue;
752
+ }
753
+ ear = next;
754
+ if (ear === stop) {
755
+ if (!pass) {
756
+ earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
757
+ } else if (pass === 1) {
758
+ ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
759
+ earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
760
+ } else if (pass === 2) {
761
+ splitEarcut(ear, triangles, dim, minX, minY, invSize);
762
+ }
763
+ break;
899
764
  }
900
- indexMap.feature++;
901
765
  }
902
- return makeAccessorObjects(points, lines, polygons, coordLength);
903
766
  }
904
- function handlePoint(geometry, points, indexMap, coordLength, properties) {
905
- points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
906
- const nPositions = geometry.data.length / coordLength;
907
- fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
908
- points.globalFeatureIds.fill(
909
- indexMap.feature,
910
- indexMap.pointPosition,
911
- indexMap.pointPosition + nPositions
912
- );
913
- points.featureIds.fill(
914
- indexMap.pointFeature,
915
- indexMap.pointPosition,
916
- indexMap.pointPosition + nPositions
917
- );
918
- indexMap.pointPosition += nPositions;
767
+ function isEar(ear) {
768
+ const a = ear.prev;
769
+ const b = ear;
770
+ const c = ear.next;
771
+ if (area(a, b, c) >= 0)
772
+ return false;
773
+ const ax = a.x;
774
+ const bx = b.x;
775
+ const cx = c.x;
776
+ const ay = a.y;
777
+ const by = b.y;
778
+ const cy = c.y;
779
+ const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
780
+ const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
781
+ const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
782
+ const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
783
+ let p = c.next;
784
+ while (p !== a) {
785
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
786
+ return false;
787
+ p = p.next;
788
+ }
789
+ return true;
919
790
  }
920
- function handleLineString(geometry, lines, indexMap, coordLength, properties) {
921
- lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
922
- const nPositions = geometry.data.length / coordLength;
923
- fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
924
- lines.globalFeatureIds.fill(
925
- indexMap.feature,
926
- indexMap.linePosition,
927
- indexMap.linePosition + nPositions
928
- );
929
- lines.featureIds.fill(
930
- indexMap.lineFeature,
931
- indexMap.linePosition,
932
- indexMap.linePosition + nPositions
933
- );
934
- for (let i = 0, il = geometry.indices.length; i < il; ++i) {
935
- const start = geometry.indices[i];
936
- const end = i === il - 1 ? geometry.data.length : geometry.indices[i + 1];
937
- lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
938
- indexMap.linePosition += (end - start) / coordLength;
791
+ function isEarHashed(ear, minX, minY, invSize) {
792
+ const a = ear.prev;
793
+ const b = ear;
794
+ const c = ear.next;
795
+ if (area(a, b, c) >= 0)
796
+ return false;
797
+ const ax = a.x;
798
+ const bx = b.x;
799
+ const cx = c.x;
800
+ const ay = a.y;
801
+ const by = b.y;
802
+ const cy = c.y;
803
+ const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx;
804
+ const y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy;
805
+ const x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx;
806
+ const y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
807
+ const minZ = zOrder(x0, y0, minX, minY, invSize);
808
+ const maxZ = zOrder(x1, y1, minX, minY, invSize);
809
+ let p = ear.prevZ;
810
+ let n = ear.nextZ;
811
+ while (p && p.z >= minZ && n && n.z <= maxZ) {
812
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
813
+ return false;
814
+ p = p.prevZ;
815
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
816
+ return false;
817
+ n = n.nextZ;
818
+ }
819
+ while (p && p.z >= minZ) {
820
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
821
+ return false;
822
+ p = p.prevZ;
823
+ }
824
+ while (n && n.z <= maxZ) {
825
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
826
+ return false;
827
+ n = n.nextZ;
939
828
  }
829
+ return true;
940
830
  }
941
- function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
942
- polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
943
- const nPositions = geometry.data.length / coordLength;
944
- fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
945
- polygons.globalFeatureIds.fill(
946
- indexMap.feature,
947
- indexMap.polygonPosition,
948
- indexMap.polygonPosition + nPositions
949
- );
950
- polygons.featureIds.fill(
951
- indexMap.polygonFeature,
952
- indexMap.polygonPosition,
953
- indexMap.polygonPosition + nPositions
954
- );
955
- for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
956
- const startPosition = indexMap.polygonPosition;
957
- polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
958
- const areas = geometry.areas[l];
959
- const indices = geometry.indices[l];
960
- const nextIndices = geometry.indices[l + 1];
961
- for (let i = 0, il = indices.length; i < il; ++i) {
962
- const start = indices[i];
963
- const end = i === il - 1 ? (
964
- // last line, so either read to:
965
- nextIndices === void 0 ? geometry.data.length : nextIndices[0]
966
- ) : indices[i + 1];
967
- polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
968
- indexMap.polygonPosition += (end - start) / coordLength;
831
+ function cureLocalIntersections(start, triangles, dim) {
832
+ let p = start;
833
+ do {
834
+ const a = p.prev;
835
+ const b = p.next.next;
836
+ if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
837
+ triangles.push(a.i / dim | 0);
838
+ triangles.push(p.i / dim | 0);
839
+ triangles.push(b.i / dim | 0);
840
+ removeNode(p);
841
+ removeNode(p.next);
842
+ p = start = b;
843
+ }
844
+ p = p.next;
845
+ } while (p !== start);
846
+ return filterPoints(p);
847
+ }
848
+ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
849
+ let a = start;
850
+ do {
851
+ let b = a.next.next;
852
+ while (b !== a.prev) {
853
+ if (a.i !== b.i && isValidDiagonal(a, b)) {
854
+ let c = splitPolygon(a, b);
855
+ a = filterPoints(a, a.next);
856
+ c = filterPoints(c, c.next);
857
+ earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
858
+ earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
859
+ return;
860
+ }
861
+ b = b.next;
969
862
  }
970
- const endPosition = indexMap.polygonPosition;
971
- triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
972
- }
863
+ a = a.next;
864
+ } while (a !== start);
973
865
  }
974
- function triangulatePolygon(polygons, areas, indices, {
975
- startPosition,
976
- endPosition,
977
- coordLength
978
- }) {
979
- if (!polygons.triangles) {
980
- return;
866
+ function eliminateHoles(data, holeIndices, outerNode, dim, areas, plane) {
867
+ const queue = [];
868
+ let i;
869
+ let len;
870
+ let start;
871
+ let end;
872
+ let list;
873
+ for (i = 0, len = holeIndices.length; i < len; i++) {
874
+ start = holeIndices[i] * dim;
875
+ end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
876
+ list = linkedList(data, start, end, dim, false, areas && areas[i + 1], plane);
877
+ if (list === list.next)
878
+ list.steiner = true;
879
+ queue.push(getLeftmost(list));
981
880
  }
982
- const start = startPosition * coordLength;
983
- const end = endPosition * coordLength;
984
- const polygonPositions = polygons.positions.subarray(start, end);
985
- const offset = indices[0];
986
- const holes = indices.slice(1).map((n) => (n - offset) / coordLength);
987
- const triangles = earcut(polygonPositions, holes, coordLength, areas);
988
- for (let t = 0, tl = triangles.length; t < tl; ++t) {
989
- polygons.triangles.push(startPosition + triangles[t]);
881
+ queue.sort(compareX);
882
+ for (i = 0; i < queue.length; i++) {
883
+ outerNode = eliminateHole(queue[i], outerNode);
990
884
  }
885
+ return outerNode;
991
886
  }
992
- function wrapProps(obj, size) {
993
- const returnObj = {};
994
- for (const key in obj) {
995
- returnObj[key] = { value: obj[key], size };
996
- }
997
- return returnObj;
887
+ function compareX(a, b) {
888
+ return a.x - b.x;
998
889
  }
999
- function makeAccessorObjects(points, lines, polygons, coordLength) {
1000
- const binaryFeatures = {
1001
- shape: "binary-feature-collection",
1002
- points: {
1003
- ...points,
1004
- positions: { value: points.positions, size: coordLength },
1005
- globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
1006
- featureIds: { value: points.featureIds, size: 1 },
1007
- numericProps: wrapProps(points.numericProps, 1)
1008
- },
1009
- lines: {
1010
- ...lines,
1011
- positions: { value: lines.positions, size: coordLength },
1012
- pathIndices: { value: lines.pathIndices, size: 1 },
1013
- globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
1014
- featureIds: { value: lines.featureIds, size: 1 },
1015
- numericProps: wrapProps(lines.numericProps, 1)
1016
- },
1017
- polygons: {
1018
- ...polygons,
1019
- positions: { value: polygons.positions, size: coordLength },
1020
- polygonIndices: { value: polygons.polygonIndices, size: 1 },
1021
- primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
1022
- globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
1023
- featureIds: { value: polygons.featureIds, size: 1 },
1024
- numericProps: wrapProps(polygons.numericProps, 1)
1025
- }
1026
- // triangles not expected
1027
- };
1028
- if (binaryFeatures.polygons && polygons.triangles) {
1029
- binaryFeatures.polygons.triangles = { value: new Uint32Array(polygons.triangles), size: 1 };
890
+ function eliminateHole(hole, outerNode) {
891
+ const bridge = findHoleBridge(hole, outerNode);
892
+ if (!bridge) {
893
+ return outerNode;
1030
894
  }
1031
- return binaryFeatures;
895
+ const bridgeReverse = splitPolygon(bridge, hole);
896
+ filterPoints(bridgeReverse, bridgeReverse.next);
897
+ return filterPoints(bridge, bridge.next);
1032
898
  }
1033
- function fillNumericProperties(object, properties, index, length) {
1034
- for (const numericPropName in object.numericProps) {
1035
- if (numericPropName in properties) {
1036
- const value = properties[numericPropName];
1037
- object.numericProps[numericPropName].fill(value, index, index + length);
899
+ function findHoleBridge(hole, outerNode) {
900
+ let p = outerNode;
901
+ const hx = hole.x;
902
+ const hy = hole.y;
903
+ let qx = -Infinity;
904
+ let m;
905
+ do {
906
+ if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
907
+ const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
908
+ if (x <= hx && x > qx) {
909
+ qx = x;
910
+ m = p.x < p.next.x ? p : p.next;
911
+ if (x === hx)
912
+ return m;
913
+ }
1038
914
  }
1039
- }
1040
- }
1041
- function keepStringProperties(properties, numericKeys) {
1042
- const props = {};
1043
- for (const key in properties) {
1044
- if (!numericKeys.includes(key)) {
1045
- props[key] = properties[key];
915
+ p = p.next;
916
+ } while (p !== outerNode);
917
+ if (!m)
918
+ return null;
919
+ const stop = m;
920
+ const mx = m.x;
921
+ const my = m.y;
922
+ let tanMin = Infinity;
923
+ let tan;
924
+ p = m;
925
+ do {
926
+ if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
927
+ tan = Math.abs(hy - p.y) / (hx - p.x);
928
+ if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
929
+ m = p;
930
+ tanMin = tan;
931
+ }
1046
932
  }
1047
- }
1048
- return props;
933
+ p = p.next;
934
+ } while (p !== stop);
935
+ return m;
1049
936
  }
1050
- function deduceArrayType(x, constructor) {
1051
- if (constructor === Array || !Number.isFinite(x)) {
1052
- return Array;
1053
- }
1054
- return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
937
+ function sectorContainsSector(m, p) {
938
+ return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
1055
939
  }
1056
-
1057
- // ../gis/src/lib/extract-geometry-info.ts
1058
- function extractGeometryInfo(features) {
1059
- let pointPositionsCount = 0;
1060
- let pointFeaturesCount = 0;
1061
- let linePositionsCount = 0;
1062
- let linePathsCount = 0;
1063
- let lineFeaturesCount = 0;
1064
- let polygonPositionsCount = 0;
1065
- let polygonObjectsCount = 0;
1066
- let polygonRingsCount = 0;
1067
- let polygonFeaturesCount = 0;
1068
- const coordLengths = /* @__PURE__ */ new Set();
1069
- for (const feature of features) {
1070
- const geometry = feature.geometry;
1071
- switch (geometry.type) {
1072
- case "Point":
1073
- pointFeaturesCount++;
1074
- pointPositionsCount++;
1075
- coordLengths.add(geometry.coordinates.length);
1076
- break;
1077
- case "MultiPoint":
1078
- pointFeaturesCount++;
1079
- pointPositionsCount += geometry.coordinates.length;
1080
- for (const point of geometry.coordinates) {
1081
- coordLengths.add(point.length);
1082
- }
1083
- break;
1084
- case "LineString":
1085
- lineFeaturesCount++;
1086
- linePositionsCount += geometry.coordinates.length;
1087
- linePathsCount++;
1088
- for (const coord of geometry.coordinates) {
1089
- coordLengths.add(coord.length);
1090
- }
1091
- break;
1092
- case "MultiLineString":
1093
- lineFeaturesCount++;
1094
- for (const line of geometry.coordinates) {
1095
- linePositionsCount += line.length;
1096
- linePathsCount++;
1097
- for (const coord of line) {
1098
- coordLengths.add(coord.length);
1099
- }
1100
- }
1101
- break;
1102
- case "Polygon":
1103
- polygonFeaturesCount++;
1104
- polygonObjectsCount++;
1105
- polygonRingsCount += geometry.coordinates.length;
1106
- const flattened = geometry.coordinates.flat();
1107
- polygonPositionsCount += flattened.length;
1108
- for (const coord of flattened) {
1109
- coordLengths.add(coord.length);
1110
- }
1111
- break;
1112
- case "MultiPolygon":
1113
- polygonFeaturesCount++;
1114
- for (const polygon of geometry.coordinates) {
1115
- polygonObjectsCount++;
1116
- polygonRingsCount += polygon.length;
1117
- const flattened2 = polygon.flat();
1118
- polygonPositionsCount += flattened2.length;
1119
- for (const coord of flattened2) {
1120
- coordLengths.add(coord.length);
1121
- }
940
+ function indexCurve(start, minX, minY, invSize) {
941
+ let p = start;
942
+ do {
943
+ if (p.z === 0)
944
+ p.z = zOrder(p.x, p.y, minX, minY, invSize);
945
+ p.prevZ = p.prev;
946
+ p.nextZ = p.next;
947
+ p = p.next;
948
+ } while (p !== start);
949
+ p.prevZ.nextZ = null;
950
+ p.prevZ = null;
951
+ sortLinked(p);
952
+ }
953
+ function sortLinked(list) {
954
+ let e;
955
+ let i;
956
+ let inSize = 1;
957
+ let numMerges;
958
+ let p;
959
+ let pSize;
960
+ let q;
961
+ let qSize;
962
+ let tail;
963
+ do {
964
+ p = list;
965
+ list = null;
966
+ tail = null;
967
+ numMerges = 0;
968
+ while (p) {
969
+ numMerges++;
970
+ q = p;
971
+ pSize = 0;
972
+ for (i = 0; i < inSize; i++) {
973
+ pSize++;
974
+ q = q.nextZ;
975
+ if (!q)
976
+ break;
977
+ }
978
+ qSize = inSize;
979
+ while (pSize > 0 || qSize > 0 && q) {
980
+ if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
981
+ e = p;
982
+ p = p.nextZ;
983
+ pSize--;
984
+ } else {
985
+ e = q;
986
+ q = q.nextZ;
987
+ qSize--;
1122
988
  }
1123
- break;
1124
- default:
1125
- throw new Error(`Unsupported geometry type: ${geometry.type}`);
989
+ if (tail)
990
+ tail.nextZ = e;
991
+ else
992
+ list = e;
993
+ e.prevZ = tail;
994
+ tail = e;
995
+ }
996
+ p = q;
1126
997
  }
1127
- }
1128
- return {
1129
- coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
1130
- pointPositionsCount,
1131
- pointFeaturesCount,
1132
- linePositionsCount,
1133
- linePathsCount,
1134
- lineFeaturesCount,
1135
- polygonPositionsCount,
1136
- polygonObjectsCount,
1137
- polygonRingsCount,
1138
- polygonFeaturesCount
1139
- };
998
+ tail.nextZ = null;
999
+ inSize *= 2;
1000
+ } while (numMerges > 1);
1001
+ return list;
1140
1002
  }
1141
-
1142
- // ../gis/src/lib/geojson-to-flat-geojson.ts
1143
- function geojsonToFlatGeojson(features, options = { coordLength: 2, fixRingWinding: true }) {
1144
- return features.map((feature) => flattenFeature(feature, options));
1003
+ function zOrder(x, y, minX, minY, invSize) {
1004
+ x = (x - minX) * invSize | 0;
1005
+ y = (y - minY) * invSize | 0;
1006
+ x = (x | x << 8) & 16711935;
1007
+ x = (x | x << 4) & 252645135;
1008
+ x = (x | x << 2) & 858993459;
1009
+ x = (x | x << 1) & 1431655765;
1010
+ y = (y | y << 8) & 16711935;
1011
+ y = (y | y << 4) & 252645135;
1012
+ y = (y | y << 2) & 858993459;
1013
+ y = (y | y << 1) & 1431655765;
1014
+ return x | y << 1;
1145
1015
  }
1146
- function flattenPoint(coordinates, data, indices, options) {
1147
- indices.push(data.length);
1148
- data.push(...coordinates);
1149
- for (let i = coordinates.length; i < options.coordLength; i++) {
1150
- data.push(0);
1151
- }
1016
+ function getLeftmost(start) {
1017
+ let p = start;
1018
+ let leftmost = start;
1019
+ do {
1020
+ if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
1021
+ leftmost = p;
1022
+ p = p.next;
1023
+ } while (p !== start);
1024
+ return leftmost;
1152
1025
  }
1153
- function flattenLineString(coordinates, data, indices, options) {
1154
- indices.push(data.length);
1155
- for (const c of coordinates) {
1156
- data.push(...c);
1157
- for (let i = c.length; i < options.coordLength; i++) {
1158
- data.push(0);
1159
- }
1160
- }
1026
+ function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
1027
+ return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
1161
1028
  }
1162
- function flattenPolygon(coordinates, data, indices, areas, options) {
1163
- let count = 0;
1164
- const ringAreas = [];
1165
- const polygons = [];
1166
- for (const lineString of coordinates) {
1167
- const lineString2d = lineString.map((p) => p.slice(0, 2));
1168
- let area2 = getPolygonSignedArea(lineString2d.flat());
1169
- const ccw = area2 < 0;
1170
- if (options.fixRingWinding && (count === 0 && !ccw || count > 0 && ccw)) {
1171
- lineString.reverse();
1172
- area2 = -area2;
1173
- }
1174
- ringAreas.push(area2);
1175
- flattenLineString(lineString, data, polygons, options);
1176
- count++;
1177
- }
1178
- if (count > 0) {
1179
- areas.push(ringAreas);
1180
- indices.push(polygons);
1181
- }
1029
+ function isValidDiagonal(a, b) {
1030
+ return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && (area(a.prev, a, b.prev) || area(a, b.prev, b)) || equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
1182
1031
  }
1183
- function flattenFeature(feature, options) {
1184
- const { geometry } = feature;
1185
- if (geometry.type === "GeometryCollection") {
1186
- throw new Error("GeometryCollection type not supported");
1187
- }
1188
- const data = [];
1189
- const indices = [];
1190
- let areas;
1191
- let type;
1192
- switch (geometry.type) {
1193
- case "Point":
1194
- type = "Point";
1195
- flattenPoint(geometry.coordinates, data, indices, options);
1196
- break;
1197
- case "MultiPoint":
1198
- type = "Point";
1199
- geometry.coordinates.map((c) => flattenPoint(c, data, indices, options));
1200
- break;
1201
- case "LineString":
1202
- type = "LineString";
1203
- flattenLineString(geometry.coordinates, data, indices, options);
1204
- break;
1205
- case "MultiLineString":
1206
- type = "LineString";
1207
- geometry.coordinates.map((c) => flattenLineString(c, data, indices, options));
1208
- break;
1209
- case "Polygon":
1210
- type = "Polygon";
1211
- areas = [];
1212
- flattenPolygon(geometry.coordinates, data, indices, areas, options);
1213
- break;
1214
- case "MultiPolygon":
1215
- type = "Polygon";
1216
- areas = [];
1217
- geometry.coordinates.map((c) => flattenPolygon(c, data, indices, areas, options));
1218
- break;
1219
- default:
1220
- throw new Error(`Unknown type: ${type}`);
1221
- }
1222
- return { ...feature, geometry: { type, indices, data, areas } };
1032
+ function area(p, q, r) {
1033
+ return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
1223
1034
  }
1224
-
1225
- // ../gis/src/lib/geojson-to-binary.ts
1226
- function geojsonToBinary(features, options = { fixRingWinding: true, triangulate: true }) {
1227
- const geometryInfo = extractGeometryInfo(features);
1228
- const coordLength = geometryInfo.coordLength;
1229
- const { fixRingWinding } = options;
1230
- const flatFeatures = geojsonToFlatGeojson(features, { coordLength, fixRingWinding });
1231
- return flatGeojsonToBinary(flatFeatures, geometryInfo, {
1232
- numericPropKeys: options.numericPropKeys,
1233
- PositionDataType: options.PositionDataType || Float32Array,
1234
- triangulate: options.triangulate
1235
- });
1035
+ function equals(p1, p2) {
1036
+ return p1.x === p2.x && p1.y === p2.y;
1236
1037
  }
1237
-
1238
- // ../schema/src/lib/table/batches/base-table-batch-aggregator.ts
1239
- var DEFAULT_ROW_COUNT = 100;
1240
- var BaseTableBatchAggregator = class {
1241
- constructor(schema, options) {
1242
- this.length = 0;
1243
- this.rows = null;
1244
- this.cursor = 0;
1245
- this._headers = [];
1246
- this.options = options;
1247
- this.schema = schema;
1248
- if (!Array.isArray(schema)) {
1249
- this._headers = [];
1250
- for (const key in schema) {
1251
- this._headers[schema[key].index] = schema[key].name;
1252
- }
1253
- }
1254
- }
1255
- rowCount() {
1256
- return this.length;
1257
- }
1258
- addArrayRow(row, cursor) {
1259
- if (Number.isFinite(cursor)) {
1260
- this.cursor = cursor;
1261
- }
1262
- this.rows = this.rows || new Array(DEFAULT_ROW_COUNT);
1263
- this.rows[this.length] = row;
1264
- this.length++;
1265
- }
1266
- addObjectRow(row, cursor) {
1267
- if (Number.isFinite(cursor)) {
1268
- this.cursor = cursor;
1269
- }
1270
- this.rows = this.rows || new Array(DEFAULT_ROW_COUNT);
1271
- this.rows[this.length] = row;
1272
- this.length++;
1273
- }
1274
- getBatch() {
1275
- let rows = this.rows;
1276
- if (!rows) {
1277
- return null;
1278
- }
1279
- rows = rows.slice(0, this.length);
1280
- this.rows = null;
1281
- const batch = {
1282
- shape: this.options.shape,
1283
- batchType: "data",
1284
- data: rows,
1285
- length: this.length,
1286
- schema: this.schema,
1287
- cursor: this.cursor
1288
- };
1289
- return batch;
1290
- }
1291
- };
1292
-
1293
- // ../schema/src/lib/table/simple-table/row-utils.ts
1294
- function convertToObjectRow(arrayRow, headers) {
1295
- if (!arrayRow) {
1296
- throw new Error("null row");
1297
- }
1298
- if (!headers) {
1299
- throw new Error("no headers");
1300
- }
1301
- const objectRow = {};
1302
- for (let i = 0; i < headers.length; i++) {
1303
- objectRow[headers[i]] = arrayRow[i];
1304
- }
1305
- return objectRow;
1038
+ function intersects(p1, q1, p2, q2) {
1039
+ const o1 = sign(area(p1, q1, p2));
1040
+ const o2 = sign(area(p1, q1, q2));
1041
+ const o3 = sign(area(p2, q2, p1));
1042
+ const o4 = sign(area(p2, q2, q1));
1043
+ if (o1 !== o2 && o3 !== o4)
1044
+ return true;
1045
+ if (o1 === 0 && onSegment(p1, p2, q1))
1046
+ return true;
1047
+ if (o2 === 0 && onSegment(p1, q2, q1))
1048
+ return true;
1049
+ if (o3 === 0 && onSegment(p2, p1, q2))
1050
+ return true;
1051
+ if (o4 === 0 && onSegment(p2, q1, q2))
1052
+ return true;
1053
+ return false;
1054
+ }
1055
+ function onSegment(p, q, r) {
1056
+ return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
1057
+ }
1058
+ function sign(num) {
1059
+ return num > 0 ? 1 : num < 0 ? -1 : 0;
1060
+ }
1061
+ function intersectsPolygon(a, b) {
1062
+ let p = a;
1063
+ do {
1064
+ if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
1065
+ return true;
1066
+ p = p.next;
1067
+ } while (p !== a);
1068
+ return false;
1069
+ }
1070
+ function locallyInside(a, b) {
1071
+ return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
1306
1072
  }
1307
- function convertToArrayRow(objectRow, headers) {
1308
- if (!objectRow) {
1309
- throw new Error("null row");
1310
- }
1311
- if (!headers) {
1312
- throw new Error("no headers");
1313
- }
1314
- const arrayRow = new Array(headers.length);
1315
- for (let i = 0; i < headers.length; i++) {
1316
- arrayRow[i] = objectRow[headers[i]];
1317
- }
1318
- return arrayRow;
1073
+ function middleInside(a, b) {
1074
+ let p = a;
1075
+ let inside = false;
1076
+ const px = (a.x + b.x) / 2;
1077
+ const py = (a.y + b.y) / 2;
1078
+ do {
1079
+ if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
1080
+ inside = !inside;
1081
+ p = p.next;
1082
+ } while (p !== a);
1083
+ return inside;
1319
1084
  }
1320
-
1321
- // ../schema/src/lib/table/batches/row-table-batch-aggregator.ts
1322
- var DEFAULT_ROW_COUNT2 = 100;
1323
- var RowTableBatchAggregator = class {
1324
- constructor(schema, options) {
1325
- this.length = 0;
1326
- this.objectRows = null;
1327
- this.arrayRows = null;
1328
- this.cursor = 0;
1329
- this._headers = [];
1330
- this.options = options;
1331
- this.schema = schema;
1332
- if (!Array.isArray(schema)) {
1333
- this._headers = [];
1334
- for (const key in schema) {
1335
- this._headers[schema[key].index] = schema[key].name;
1336
- }
1337
- }
1338
- }
1339
- rowCount() {
1340
- return this.length;
1341
- }
1342
- addArrayRow(row, cursor) {
1343
- if (Number.isFinite(cursor)) {
1344
- this.cursor = cursor;
1345
- }
1346
- switch (this.options.shape) {
1347
- case "object-row-table":
1348
- const rowObject = convertToObjectRow(row, this._headers);
1349
- this.addObjectRow(rowObject, cursor);
1350
- break;
1351
- case "array-row-table":
1352
- this.arrayRows = this.arrayRows || new Array(DEFAULT_ROW_COUNT2);
1353
- this.arrayRows[this.length] = row;
1354
- this.length++;
1355
- break;
1356
- }
1357
- }
1358
- addObjectRow(row, cursor) {
1359
- if (Number.isFinite(cursor)) {
1360
- this.cursor = cursor;
1361
- }
1362
- switch (this.options.shape) {
1363
- case "array-row-table":
1364
- const rowArray = convertToArrayRow(row, this._headers);
1365
- this.addArrayRow(rowArray, cursor);
1366
- break;
1367
- case "object-row-table":
1368
- this.objectRows = this.objectRows || new Array(DEFAULT_ROW_COUNT2);
1369
- this.objectRows[this.length] = row;
1370
- this.length++;
1371
- break;
1372
- }
1085
+ function splitPolygon(a, b) {
1086
+ const a2 = new Vertex(a.i, a.x, a.y);
1087
+ const b2 = new Vertex(b.i, b.x, b.y);
1088
+ const an = a.next;
1089
+ const bp = b.prev;
1090
+ a.next = b;
1091
+ b.prev = a;
1092
+ a2.next = an;
1093
+ an.prev = a2;
1094
+ b2.next = a2;
1095
+ a2.prev = b2;
1096
+ bp.next = b2;
1097
+ b2.prev = bp;
1098
+ return b2;
1099
+ }
1100
+ function insertNode(i, x, y, last) {
1101
+ const p = new Vertex(i, x, y);
1102
+ if (!last) {
1103
+ p.prev = p;
1104
+ p.next = p;
1105
+ } else {
1106
+ p.next = last.next;
1107
+ p.prev = last;
1108
+ last.next.prev = p;
1109
+ last.next = p;
1373
1110
  }
1374
- getBatch() {
1375
- let rows = this.arrayRows || this.objectRows;
1376
- if (!rows) {
1377
- return null;
1378
- }
1379
- rows = rows.slice(0, this.length);
1380
- this.arrayRows = null;
1381
- this.objectRows = null;
1382
- return {
1383
- shape: this.options.shape,
1384
- batchType: "data",
1385
- data: rows,
1386
- length: this.length,
1387
- schema: this.schema,
1388
- cursor: this.cursor
1389
- };
1111
+ return p;
1112
+ }
1113
+ function removeNode(p) {
1114
+ p.next.prev = p.prev;
1115
+ p.prev.next = p.next;
1116
+ if (p.prevZ)
1117
+ p.prevZ.nextZ = p.nextZ;
1118
+ if (p.nextZ)
1119
+ p.nextZ.prevZ = p.prevZ;
1120
+ }
1121
+ var Vertex = class {
1122
+ constructor(i, x, y) {
1123
+ _defineProperty(this, "i", void 0);
1124
+ _defineProperty(this, "x", void 0);
1125
+ _defineProperty(this, "y", void 0);
1126
+ _defineProperty(this, "prev", null);
1127
+ _defineProperty(this, "next", null);
1128
+ _defineProperty(this, "z", 0);
1129
+ _defineProperty(this, "prevZ", null);
1130
+ _defineProperty(this, "nextZ", null);
1131
+ _defineProperty(this, "steiner", false);
1132
+ this.i = i;
1133
+ this.x = x;
1134
+ this.y = y;
1390
1135
  }
1391
1136
  };
1392
1137
 
1393
- // ../schema/src/lib/table/batches/columnar-table-batch-aggregator.ts
1394
- var DEFAULT_ROW_COUNT3 = 100;
1395
- var ColumnarTableBatchAggregator = class {
1396
- constructor(schema, options) {
1397
- this.length = 0;
1398
- this.allocated = 0;
1399
- this.columns = {};
1400
- this.schema = schema;
1401
- this._reallocateColumns();
1402
- }
1403
- rowCount() {
1404
- return this.length;
1405
- }
1406
- addArrayRow(row) {
1407
- this._reallocateColumns();
1408
- let i = 0;
1409
- for (const fieldName in this.columns) {
1410
- this.columns[fieldName][this.length] = row[i++];
1411
- }
1412
- this.length++;
1413
- }
1414
- addObjectRow(row) {
1415
- this._reallocateColumns();
1416
- for (const fieldName in row) {
1417
- this.columns[fieldName][this.length] = row[fieldName];
1138
+ // ../gis/src/lib/binary-features/flat-geojson-to-binary.ts
1139
+ function flatGeojsonToBinary(features, geometryInfo, options) {
1140
+ const propArrayTypes = extractNumericPropTypes(features);
1141
+ const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
1142
+ return fillArrays(
1143
+ features,
1144
+ {
1145
+ propArrayTypes,
1146
+ ...geometryInfo
1147
+ },
1148
+ {
1149
+ numericPropKeys: options && options.numericPropKeys || numericPropKeys,
1150
+ PositionDataType: options ? options.PositionDataType : Float32Array,
1151
+ triangulate: options ? options.triangulate : true
1418
1152
  }
1419
- this.length++;
1420
- }
1421
- getBatch() {
1422
- this._pruneColumns();
1423
- const columns = Array.isArray(this.schema) ? this.columns : {};
1424
- if (!Array.isArray(this.schema)) {
1425
- for (const fieldName in this.schema) {
1426
- const field = this.schema[fieldName];
1427
- columns[field.name] = this.columns[field.index];
1153
+ );
1154
+ }
1155
+ function extractNumericPropTypes(features) {
1156
+ const propArrayTypes = {};
1157
+ for (const feature of features) {
1158
+ if (feature.properties) {
1159
+ for (const key in feature.properties) {
1160
+ const val = feature.properties[key];
1161
+ propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
1428
1162
  }
1429
1163
  }
1430
- this.columns = {};
1431
- const batch = {
1432
- shape: "columnar-table",
1433
- batchType: "data",
1434
- data: columns,
1435
- schema: this.schema,
1436
- length: this.length
1437
- };
1438
- return batch;
1439
1164
  }
1440
- // HELPERS
1441
- _reallocateColumns() {
1442
- if (this.length < this.allocated) {
1443
- return;
1444
- }
1445
- this.allocated = this.allocated > 0 ? this.allocated *= 2 : DEFAULT_ROW_COUNT3;
1446
- this.columns = {};
1447
- for (const fieldName in this.schema) {
1448
- const field = this.schema[fieldName];
1449
- const ArrayType = field.type || Float32Array;
1450
- const oldColumn = this.columns[field.index];
1451
- if (oldColumn && ArrayBuffer.isView(oldColumn)) {
1452
- const typedArray = new ArrayType(this.allocated);
1453
- typedArray.set(oldColumn);
1454
- this.columns[field.index] = typedArray;
1455
- } else if (oldColumn) {
1456
- oldColumn.length = this.allocated;
1457
- this.columns[field.index] = oldColumn;
1458
- } else {
1459
- this.columns[field.index] = new ArrayType(this.allocated);
1460
- }
1165
+ return propArrayTypes;
1166
+ }
1167
+ function fillArrays(features, geometryInfo, options) {
1168
+ const {
1169
+ pointPositionsCount,
1170
+ pointFeaturesCount,
1171
+ linePositionsCount,
1172
+ linePathsCount,
1173
+ lineFeaturesCount,
1174
+ polygonPositionsCount,
1175
+ polygonObjectsCount,
1176
+ polygonRingsCount,
1177
+ polygonFeaturesCount,
1178
+ propArrayTypes,
1179
+ coordLength
1180
+ } = geometryInfo;
1181
+ const { numericPropKeys = [], PositionDataType = Float32Array, triangulate = true } = options;
1182
+ const hasGlobalId = features[0] && "id" in features[0];
1183
+ const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
1184
+ const points = {
1185
+ type: "Point",
1186
+ positions: new PositionDataType(pointPositionsCount * coordLength),
1187
+ globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
1188
+ featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount),
1189
+ numericProps: {},
1190
+ properties: [],
1191
+ fields: []
1192
+ };
1193
+ const lines = {
1194
+ type: "LineString",
1195
+ pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1),
1196
+ positions: new PositionDataType(linePositionsCount * coordLength),
1197
+ globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
1198
+ featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount),
1199
+ numericProps: {},
1200
+ properties: [],
1201
+ fields: []
1202
+ };
1203
+ const polygons = {
1204
+ type: "Polygon",
1205
+ polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1),
1206
+ primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1),
1207
+ positions: new PositionDataType(polygonPositionsCount * coordLength),
1208
+ globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
1209
+ featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount),
1210
+ numericProps: {},
1211
+ properties: [],
1212
+ fields: []
1213
+ };
1214
+ if (triangulate) {
1215
+ polygons.triangles = [];
1216
+ }
1217
+ for (const object of [points, lines, polygons]) {
1218
+ for (const propName of numericPropKeys) {
1219
+ const T = propArrayTypes[propName];
1220
+ object.numericProps[propName] = new T(object.positions.length / coordLength);
1461
1221
  }
1462
1222
  }
1463
- _pruneColumns() {
1464
- for (const [columnName, column] of Object.entries(this.columns)) {
1465
- this.columns[columnName] = column.slice(0, this.length);
1223
+ lines.pathIndices[linePathsCount] = linePositionsCount;
1224
+ polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount;
1225
+ polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount;
1226
+ const indexMap = {
1227
+ pointPosition: 0,
1228
+ pointFeature: 0,
1229
+ linePosition: 0,
1230
+ linePath: 0,
1231
+ lineFeature: 0,
1232
+ polygonPosition: 0,
1233
+ polygonObject: 0,
1234
+ polygonRing: 0,
1235
+ polygonFeature: 0,
1236
+ feature: 0
1237
+ };
1238
+ for (const feature of features) {
1239
+ const geometry = feature.geometry;
1240
+ const properties = feature.properties || {};
1241
+ switch (geometry.type) {
1242
+ case "Point":
1243
+ handlePoint(geometry, points, indexMap, coordLength, properties);
1244
+ points.properties.push(keepStringProperties(properties, numericPropKeys));
1245
+ if (hasGlobalId) {
1246
+ points.fields.push({ id: feature.id });
1247
+ }
1248
+ indexMap.pointFeature++;
1249
+ break;
1250
+ case "LineString":
1251
+ handleLineString(geometry, lines, indexMap, coordLength, properties);
1252
+ lines.properties.push(keepStringProperties(properties, numericPropKeys));
1253
+ if (hasGlobalId) {
1254
+ lines.fields.push({ id: feature.id });
1255
+ }
1256
+ indexMap.lineFeature++;
1257
+ break;
1258
+ case "Polygon":
1259
+ handlePolygon(geometry, polygons, indexMap, coordLength, properties);
1260
+ polygons.properties.push(keepStringProperties(properties, numericPropKeys));
1261
+ if (hasGlobalId) {
1262
+ polygons.fields.push({ id: feature.id });
1263
+ }
1264
+ indexMap.polygonFeature++;
1265
+ break;
1266
+ default:
1267
+ throw new Error("Invalid geometry type");
1466
1268
  }
1269
+ indexMap.feature++;
1467
1270
  }
1468
- };
1469
-
1470
- // ../schema/src/lib/table/batches/table-batch-builder.ts
1471
- var DEFAULT_OPTIONS = {
1472
- shape: "array-row-table",
1473
- batchSize: "auto",
1474
- batchDebounceMs: 0,
1475
- limit: 0,
1476
- _limitMB: 0
1477
- };
1478
- var ERR_MESSAGE = "TableBatchBuilder";
1479
- var TableBatchBuilder = class {
1480
- constructor(schema, options) {
1481
- this.aggregator = null;
1482
- this.batchCount = 0;
1483
- this.bytesUsed = 0;
1484
- this.isChunkComplete = false;
1485
- this.lastBatchEmittedMs = Date.now();
1486
- this.totalLength = 0;
1487
- this.totalBytes = 0;
1488
- this.rowBytes = 0;
1489
- this.schema = schema;
1490
- this.options = { ...DEFAULT_OPTIONS, ...options };
1271
+ return makeAccessorObjects(points, lines, polygons, coordLength);
1272
+ }
1273
+ function handlePoint(geometry, points, indexMap, coordLength, properties) {
1274
+ points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
1275
+ const nPositions = geometry.data.length / coordLength;
1276
+ fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
1277
+ points.globalFeatureIds.fill(
1278
+ indexMap.feature,
1279
+ indexMap.pointPosition,
1280
+ indexMap.pointPosition + nPositions
1281
+ );
1282
+ points.featureIds.fill(
1283
+ indexMap.pointFeature,
1284
+ indexMap.pointPosition,
1285
+ indexMap.pointPosition + nPositions
1286
+ );
1287
+ indexMap.pointPosition += nPositions;
1288
+ }
1289
+ function handleLineString(geometry, lines, indexMap, coordLength, properties) {
1290
+ lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
1291
+ const nPositions = geometry.data.length / coordLength;
1292
+ fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
1293
+ lines.globalFeatureIds.fill(
1294
+ indexMap.feature,
1295
+ indexMap.linePosition,
1296
+ indexMap.linePosition + nPositions
1297
+ );
1298
+ lines.featureIds.fill(
1299
+ indexMap.lineFeature,
1300
+ indexMap.linePosition,
1301
+ indexMap.linePosition + nPositions
1302
+ );
1303
+ for (let i = 0, il = geometry.indices.length; i < il; ++i) {
1304
+ const start = geometry.indices[i];
1305
+ const end = i === il - 1 ? geometry.data.length : geometry.indices[i + 1];
1306
+ lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
1307
+ indexMap.linePosition += (end - start) / coordLength;
1491
1308
  }
1492
- limitReached() {
1493
- if (Boolean(this.options?.limit) && this.totalLength >= this.options.limit) {
1494
- return true;
1495
- }
1496
- if (Boolean(this.options?._limitMB) && this.totalBytes / 1e6 >= this.options._limitMB) {
1497
- return true;
1309
+ }
1310
+ function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
1311
+ polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
1312
+ const nPositions = geometry.data.length / coordLength;
1313
+ fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
1314
+ polygons.globalFeatureIds.fill(
1315
+ indexMap.feature,
1316
+ indexMap.polygonPosition,
1317
+ indexMap.polygonPosition + nPositions
1318
+ );
1319
+ polygons.featureIds.fill(
1320
+ indexMap.polygonFeature,
1321
+ indexMap.polygonPosition,
1322
+ indexMap.polygonPosition + nPositions
1323
+ );
1324
+ for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
1325
+ const startPosition = indexMap.polygonPosition;
1326
+ polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
1327
+ const areas = geometry.areas[l];
1328
+ const indices = geometry.indices[l];
1329
+ const nextIndices = geometry.indices[l + 1];
1330
+ for (let i = 0, il = indices.length; i < il; ++i) {
1331
+ const start = indices[i];
1332
+ const end = i === il - 1 ? (
1333
+ // last line, so either read to:
1334
+ nextIndices === void 0 ? geometry.data.length : nextIndices[0]
1335
+ ) : indices[i + 1];
1336
+ polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
1337
+ indexMap.polygonPosition += (end - start) / coordLength;
1498
1338
  }
1499
- return false;
1339
+ const endPosition = indexMap.polygonPosition;
1340
+ triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
1500
1341
  }
1501
- /** @deprecated Use addArrayRow or addObjectRow */
1502
- addRow(row) {
1503
- if (this.limitReached()) {
1504
- return;
1505
- }
1506
- this.totalLength++;
1507
- this.rowBytes = this.rowBytes || this._estimateRowMB(row);
1508
- this.totalBytes += this.rowBytes;
1509
- if (Array.isArray(row)) {
1510
- this.addArrayRow(row);
1511
- } else {
1512
- this.addObjectRow(row);
1513
- }
1342
+ }
1343
+ function triangulatePolygon(polygons, areas, indices, {
1344
+ startPosition,
1345
+ endPosition,
1346
+ coordLength
1347
+ }) {
1348
+ if (!polygons.triangles) {
1349
+ return;
1514
1350
  }
1515
- /** Add one row to the batch */
1516
- addArrayRow(row) {
1517
- if (!this.aggregator) {
1518
- const TableBatchType = this._getTableBatchType();
1519
- this.aggregator = new TableBatchType(this.schema, this.options);
1520
- }
1521
- this.aggregator.addArrayRow(row);
1351
+ const start = startPosition * coordLength;
1352
+ const end = endPosition * coordLength;
1353
+ const polygonPositions = polygons.positions.subarray(start, end);
1354
+ const offset = indices[0];
1355
+ const holes = indices.slice(1).map((n) => (n - offset) / coordLength);
1356
+ const triangles = earcut(polygonPositions, holes, coordLength, areas);
1357
+ for (let t = 0, tl = triangles.length; t < tl; ++t) {
1358
+ polygons.triangles.push(startPosition + triangles[t]);
1522
1359
  }
1523
- /** Add one row to the batch */
1524
- addObjectRow(row) {
1525
- if (!this.aggregator) {
1526
- const TableBatchType = this._getTableBatchType();
1527
- this.aggregator = new TableBatchType(this.schema, this.options);
1360
+ }
1361
+ function wrapProps(obj, size) {
1362
+ const returnObj = {};
1363
+ for (const key in obj) {
1364
+ returnObj[key] = { value: obj[key], size };
1365
+ }
1366
+ return returnObj;
1367
+ }
1368
+ function makeAccessorObjects(points, lines, polygons, coordLength) {
1369
+ const binaryFeatures = {
1370
+ shape: "binary-feature-collection",
1371
+ points: {
1372
+ ...points,
1373
+ positions: { value: points.positions, size: coordLength },
1374
+ globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
1375
+ featureIds: { value: points.featureIds, size: 1 },
1376
+ numericProps: wrapProps(points.numericProps, 1)
1377
+ },
1378
+ lines: {
1379
+ ...lines,
1380
+ positions: { value: lines.positions, size: coordLength },
1381
+ pathIndices: { value: lines.pathIndices, size: 1 },
1382
+ globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
1383
+ featureIds: { value: lines.featureIds, size: 1 },
1384
+ numericProps: wrapProps(lines.numericProps, 1)
1385
+ },
1386
+ polygons: {
1387
+ ...polygons,
1388
+ positions: { value: polygons.positions, size: coordLength },
1389
+ polygonIndices: { value: polygons.polygonIndices, size: 1 },
1390
+ primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
1391
+ globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
1392
+ featureIds: { value: polygons.featureIds, size: 1 },
1393
+ numericProps: wrapProps(polygons.numericProps, 1)
1528
1394
  }
1529
- this.aggregator.addObjectRow(row);
1395
+ // triangles not expected
1396
+ };
1397
+ if (binaryFeatures.polygons && polygons.triangles) {
1398
+ binaryFeatures.polygons.triangles = { value: new Uint32Array(polygons.triangles), size: 1 };
1530
1399
  }
1531
- /** Mark an incoming raw memory chunk has completed */
1532
- chunkComplete(chunk) {
1533
- if (chunk instanceof ArrayBuffer) {
1534
- this.bytesUsed += chunk.byteLength;
1400
+ return binaryFeatures;
1401
+ }
1402
+ function fillNumericProperties(object, properties, index, length) {
1403
+ for (const numericPropName in object.numericProps) {
1404
+ if (numericPropName in properties) {
1405
+ const value = properties[numericPropName];
1406
+ object.numericProps[numericPropName].fill(value, index, index + length);
1535
1407
  }
1536
- if (typeof chunk === "string") {
1537
- this.bytesUsed += chunk.length;
1408
+ }
1409
+ }
1410
+ function keepStringProperties(properties, numericKeys) {
1411
+ const props = {};
1412
+ for (const key in properties) {
1413
+ if (!numericKeys.includes(key)) {
1414
+ props[key] = properties[key];
1538
1415
  }
1539
- this.isChunkComplete = true;
1540
1416
  }
1541
- getFullBatch(options) {
1542
- return this._isFull() ? this._getBatch(options) : null;
1417
+ return props;
1418
+ }
1419
+ function deduceArrayType(x, constructor) {
1420
+ if (constructor === Array || !Number.isFinite(x)) {
1421
+ return Array;
1543
1422
  }
1544
- getFinalBatch(options) {
1545
- return this._getBatch(options);
1423
+ return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
1424
+ }
1425
+
1426
+ // ../gis/src/lib/binary-features/extract-geometry-info.ts
1427
+ function extractGeometryInfo(features) {
1428
+ let pointPositionsCount = 0;
1429
+ let pointFeaturesCount = 0;
1430
+ let linePositionsCount = 0;
1431
+ let linePathsCount = 0;
1432
+ let lineFeaturesCount = 0;
1433
+ let polygonPositionsCount = 0;
1434
+ let polygonObjectsCount = 0;
1435
+ let polygonRingsCount = 0;
1436
+ let polygonFeaturesCount = 0;
1437
+ const coordLengths = /* @__PURE__ */ new Set();
1438
+ for (const feature of features) {
1439
+ const geometry = feature.geometry;
1440
+ switch (geometry.type) {
1441
+ case "Point":
1442
+ pointFeaturesCount++;
1443
+ pointPositionsCount++;
1444
+ coordLengths.add(geometry.coordinates.length);
1445
+ break;
1446
+ case "MultiPoint":
1447
+ pointFeaturesCount++;
1448
+ pointPositionsCount += geometry.coordinates.length;
1449
+ for (const point of geometry.coordinates) {
1450
+ coordLengths.add(point.length);
1451
+ }
1452
+ break;
1453
+ case "LineString":
1454
+ lineFeaturesCount++;
1455
+ linePositionsCount += geometry.coordinates.length;
1456
+ linePathsCount++;
1457
+ for (const coord of geometry.coordinates) {
1458
+ coordLengths.add(coord.length);
1459
+ }
1460
+ break;
1461
+ case "MultiLineString":
1462
+ lineFeaturesCount++;
1463
+ for (const line of geometry.coordinates) {
1464
+ linePositionsCount += line.length;
1465
+ linePathsCount++;
1466
+ for (const coord of line) {
1467
+ coordLengths.add(coord.length);
1468
+ }
1469
+ }
1470
+ break;
1471
+ case "Polygon":
1472
+ polygonFeaturesCount++;
1473
+ polygonObjectsCount++;
1474
+ polygonRingsCount += geometry.coordinates.length;
1475
+ const flattened = geometry.coordinates.flat();
1476
+ polygonPositionsCount += flattened.length;
1477
+ for (const coord of flattened) {
1478
+ coordLengths.add(coord.length);
1479
+ }
1480
+ break;
1481
+ case "MultiPolygon":
1482
+ polygonFeaturesCount++;
1483
+ for (const polygon of geometry.coordinates) {
1484
+ polygonObjectsCount++;
1485
+ polygonRingsCount += polygon.length;
1486
+ const flattened2 = polygon.flat();
1487
+ polygonPositionsCount += flattened2.length;
1488
+ for (const coord of flattened2) {
1489
+ coordLengths.add(coord.length);
1490
+ }
1491
+ }
1492
+ break;
1493
+ default:
1494
+ throw new Error(`Unsupported geometry type: ${geometry.type}`);
1495
+ }
1546
1496
  }
1547
- // INTERNAL
1548
- _estimateRowMB(row) {
1549
- return Array.isArray(row) ? row.length * 8 : Object.keys(row).length * 8;
1497
+ return {
1498
+ coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
1499
+ pointPositionsCount,
1500
+ pointFeaturesCount,
1501
+ linePositionsCount,
1502
+ linePathsCount,
1503
+ lineFeaturesCount,
1504
+ polygonPositionsCount,
1505
+ polygonObjectsCount,
1506
+ polygonRingsCount,
1507
+ polygonFeaturesCount
1508
+ };
1509
+ }
1510
+
1511
+ // ../gis/src/lib/binary-features/geojson-to-flat-geojson.ts
1512
+ function geojsonToFlatGeojson(features, options = { coordLength: 2, fixRingWinding: true }) {
1513
+ return features.map((feature) => flattenFeature(feature, options));
1514
+ }
1515
+ function flattenPoint(coordinates, data, indices, options) {
1516
+ indices.push(data.length);
1517
+ data.push(...coordinates);
1518
+ for (let i = coordinates.length; i < options.coordLength; i++) {
1519
+ data.push(0);
1550
1520
  }
1551
- _isFull() {
1552
- if (!this.aggregator || this.aggregator.rowCount() === 0) {
1553
- return false;
1554
- }
1555
- if (this.options.batchSize === "auto") {
1556
- if (!this.isChunkComplete) {
1557
- return false;
1558
- }
1559
- } else if (this.options.batchSize > this.aggregator.rowCount()) {
1560
- return false;
1561
- }
1562
- if (this.options.batchDebounceMs > Date.now() - this.lastBatchEmittedMs) {
1563
- return false;
1521
+ }
1522
+ function flattenLineString(coordinates, data, indices, options) {
1523
+ indices.push(data.length);
1524
+ for (const c of coordinates) {
1525
+ data.push(...c);
1526
+ for (let i = c.length; i < options.coordLength; i++) {
1527
+ data.push(0);
1564
1528
  }
1565
- this.isChunkComplete = false;
1566
- this.lastBatchEmittedMs = Date.now();
1567
- return true;
1568
1529
  }
1569
- /**
1570
- * bytesUsed can be set via chunkComplete or via getBatch*
1571
- */
1572
- _getBatch(options) {
1573
- if (!this.aggregator) {
1574
- return null;
1575
- }
1576
- if (options?.bytesUsed) {
1577
- this.bytesUsed = options.bytesUsed;
1530
+ }
1531
+ function flattenPolygon(coordinates, data, indices, areas, options) {
1532
+ let count = 0;
1533
+ const ringAreas = [];
1534
+ const polygons = [];
1535
+ for (const lineString of coordinates) {
1536
+ const lineString2d = lineString.map((p) => p.slice(0, 2));
1537
+ let area2 = getPolygonSignedArea(lineString2d.flat());
1538
+ const ccw = area2 < 0;
1539
+ if (options.fixRingWinding && (count === 0 && !ccw || count > 0 && ccw)) {
1540
+ lineString.reverse();
1541
+ area2 = -area2;
1578
1542
  }
1579
- const normalizedBatch = this.aggregator.getBatch();
1580
- normalizedBatch.count = this.batchCount;
1581
- normalizedBatch.bytesUsed = this.bytesUsed;
1582
- Object.assign(normalizedBatch, options);
1583
- this.batchCount++;
1584
- this.aggregator = null;
1585
- return normalizedBatch;
1543
+ ringAreas.push(area2);
1544
+ flattenLineString(lineString, data, polygons, options);
1545
+ count++;
1586
1546
  }
1587
- _getTableBatchType() {
1588
- switch (this.options.shape) {
1589
- case "row-table":
1590
- return BaseTableBatchAggregator;
1591
- case "array-row-table":
1592
- case "object-row-table":
1593
- return RowTableBatchAggregator;
1594
- case "columnar-table":
1595
- return ColumnarTableBatchAggregator;
1596
- case "arrow-table":
1597
- if (!TableBatchBuilder.ArrowBatch) {
1598
- throw new Error(ERR_MESSAGE);
1599
- }
1600
- return TableBatchBuilder.ArrowBatch;
1601
- default:
1602
- throw new Error(ERR_MESSAGE);
1603
- }
1547
+ if (count > 0) {
1548
+ areas.push(ringAreas);
1549
+ indices.push(polygons);
1604
1550
  }
1605
- };
1551
+ }
1552
+ function flattenFeature(feature, options) {
1553
+ const { geometry } = feature;
1554
+ if (geometry.type === "GeometryCollection") {
1555
+ throw new Error("GeometryCollection type not supported");
1556
+ }
1557
+ const data = [];
1558
+ const indices = [];
1559
+ let areas;
1560
+ let type;
1561
+ switch (geometry.type) {
1562
+ case "Point":
1563
+ type = "Point";
1564
+ flattenPoint(geometry.coordinates, data, indices, options);
1565
+ break;
1566
+ case "MultiPoint":
1567
+ type = "Point";
1568
+ geometry.coordinates.map((c) => flattenPoint(c, data, indices, options));
1569
+ break;
1570
+ case "LineString":
1571
+ type = "LineString";
1572
+ flattenLineString(geometry.coordinates, data, indices, options);
1573
+ break;
1574
+ case "MultiLineString":
1575
+ type = "LineString";
1576
+ geometry.coordinates.map((c) => flattenLineString(c, data, indices, options));
1577
+ break;
1578
+ case "Polygon":
1579
+ type = "Polygon";
1580
+ areas = [];
1581
+ flattenPolygon(geometry.coordinates, data, indices, areas, options);
1582
+ break;
1583
+ case "MultiPolygon":
1584
+ type = "Polygon";
1585
+ areas = [];
1586
+ geometry.coordinates.map((c) => flattenPolygon(c, data, indices, areas, options));
1587
+ break;
1588
+ default:
1589
+ throw new Error(`Unknown type: ${type}`);
1590
+ }
1591
+ return { ...feature, geometry: { type, indices, data, areas } };
1592
+ }
1593
+
1594
+ // ../gis/src/lib/binary-features/geojson-to-binary.ts
1595
+ function geojsonToBinary(features, options = { fixRingWinding: true, triangulate: true }) {
1596
+ const geometryInfo = extractGeometryInfo(features);
1597
+ const coordLength = geometryInfo.coordLength;
1598
+ const { fixRingWinding } = options;
1599
+ const flatFeatures = geojsonToFlatGeojson(features, { coordLength, fixRingWinding });
1600
+ return flatGeojsonToBinary(flatFeatures, geometryInfo, {
1601
+ numericPropKeys: options.numericPropKeys,
1602
+ PositionDataType: options.PositionDataType || Float32Array,
1603
+ triangulate: options.triangulate
1604
+ });
1605
+ }
1606
1606
 
1607
1607
  // src/lib/clarinet/clarinet.ts
1608
1608
  var MAX_BUFFER_LENGTH = Number.MAX_SAFE_INTEGER;
@@ -2417,7 +2417,7 @@ Char: ${this.c}`;
2417
2417
  }
2418
2418
 
2419
2419
  // src/geojson-loader.ts
2420
- var VERSION = true ? "4.0.0-beta.8" : "latest";
2420
+ var VERSION = true ? "4.0.1" : "latest";
2421
2421
  var GeoJSONWorkerLoader = {
2422
2422
  name: "GeoJSON",
2423
2423
  id: "geojson",