@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.
- package/dist/dist.dev.js +4 -4
- package/dist/geojson-worker.js +1254 -1254
- package/package.json +5 -5
package/dist/geojson-worker.js
CHANGED
|
@@ -253,1356 +253,1356 @@
|
|
|
253
253
|
return obj;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
//
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
312
|
-
|
|
280
|
+
this.rows = this.rows || new Array(DEFAULT_ROW_COUNT);
|
|
281
|
+
this.rows[this.length] = row;
|
|
282
|
+
this.length++;
|
|
313
283
|
}
|
|
314
|
-
|
|
315
|
-
|
|
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
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
329
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
|
336
|
+
return arrayRow;
|
|
342
337
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
|
|
451
|
-
|
|
452
|
-
return false;
|
|
453
|
-
p = p.prevZ;
|
|
421
|
+
rowCount() {
|
|
422
|
+
return this.length;
|
|
454
423
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
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
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
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
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
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
|
-
|
|
577
|
+
} else if (this.options.batchSize > this.aggregator.rowCount()) {
|
|
578
|
+
return false;
|
|
628
579
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
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
|
-
//
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
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
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
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
|
-
|
|
683
|
+
earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
|
|
684
|
+
return triangles;
|
|
797
685
|
}
|
|
798
|
-
function
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
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
|
-
|
|
898
|
-
|
|
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
|
|
905
|
-
|
|
906
|
-
const
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
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
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
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
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
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
|
-
|
|
971
|
-
|
|
972
|
-
}
|
|
863
|
+
a = a.next;
|
|
864
|
+
} while (a !== start);
|
|
973
865
|
}
|
|
974
|
-
function
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
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
|
-
|
|
983
|
-
|
|
984
|
-
|
|
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
|
|
993
|
-
|
|
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
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1002
|
-
|
|
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
|
-
|
|
895
|
+
const bridgeReverse = splitPolygon(bridge, hole);
|
|
896
|
+
filterPoints(bridgeReverse, bridgeReverse.next);
|
|
897
|
+
return filterPoints(bridge, bridge.next);
|
|
1032
898
|
}
|
|
1033
|
-
function
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
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
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
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
|
-
|
|
933
|
+
p = p.next;
|
|
934
|
+
} while (p !== stop);
|
|
935
|
+
return m;
|
|
1049
936
|
}
|
|
1050
|
-
function
|
|
1051
|
-
|
|
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
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
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
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
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
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
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
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
|
1154
|
-
|
|
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
|
|
1163
|
-
|
|
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
|
|
1184
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
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
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
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
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
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
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
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
|
-
// ../
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
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
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
if (
|
|
1425
|
-
for (const
|
|
1426
|
-
const
|
|
1427
|
-
|
|
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
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
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
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
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
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
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
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
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
|
-
|
|
1339
|
+
const endPosition = indexMap.polygonPosition;
|
|
1340
|
+
triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
|
|
1500
1341
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
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
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
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
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
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
|
-
|
|
1537
|
-
|
|
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
|
-
|
|
1542
|
-
|
|
1417
|
+
return props;
|
|
1418
|
+
}
|
|
1419
|
+
function deduceArrayType(x, constructor) {
|
|
1420
|
+
if (constructor === Array || !Number.isFinite(x)) {
|
|
1421
|
+
return Array;
|
|
1543
1422
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
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
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
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
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
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
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
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
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
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
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
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.
|
|
2420
|
+
var VERSION = true ? "4.0.1" : "latest";
|
|
2421
2421
|
var GeoJSONWorkerLoader = {
|
|
2422
2422
|
name: "GeoJSON",
|
|
2423
2423
|
id: "geojson",
|