mapshaper 0.7.22 → 0.7.24
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/bin/mapshaper-gui +3 -5
- package/mapshaper.js +5305 -1766
- package/package.json +9 -6
- package/www/geopackage.js +4 -1
- package/www/index.html +21 -19
- package/www/mapshaper-gui.js +74 -27
- package/www/mapshaper.js +5305 -1766
- package/www/modules.js +8 -455
- package/www/page.css +60 -1
- package/www/sponsor.html +1 -0
package/www/modules.js
CHANGED
|
@@ -973,7 +973,7 @@
|
|
|
973
973
|
// Buffer instances.
|
|
974
974
|
Buffer.prototype._isBuffer = true;
|
|
975
975
|
|
|
976
|
-
function swap$
|
|
976
|
+
function swap$1 (b, n, m) {
|
|
977
977
|
var i = b[n];
|
|
978
978
|
b[n] = b[m];
|
|
979
979
|
b[m] = i;
|
|
@@ -985,7 +985,7 @@
|
|
|
985
985
|
throw new RangeError('Buffer size must be a multiple of 16-bits')
|
|
986
986
|
}
|
|
987
987
|
for (var i = 0; i < len; i += 2) {
|
|
988
|
-
swap$
|
|
988
|
+
swap$1(this, i, i + 1);
|
|
989
989
|
}
|
|
990
990
|
return this
|
|
991
991
|
};
|
|
@@ -996,8 +996,8 @@
|
|
|
996
996
|
throw new RangeError('Buffer size must be a multiple of 32-bits')
|
|
997
997
|
}
|
|
998
998
|
for (var i = 0; i < len; i += 4) {
|
|
999
|
-
swap$
|
|
1000
|
-
swap$
|
|
999
|
+
swap$1(this, i, i + 3);
|
|
1000
|
+
swap$1(this, i + 1, i + 2);
|
|
1001
1001
|
}
|
|
1002
1002
|
return this
|
|
1003
1003
|
};
|
|
@@ -1008,10 +1008,10 @@
|
|
|
1008
1008
|
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
|
1009
1009
|
}
|
|
1010
1010
|
for (var i = 0; i < len; i += 8) {
|
|
1011
|
-
swap$
|
|
1012
|
-
swap$
|
|
1013
|
-
swap$
|
|
1014
|
-
swap$
|
|
1011
|
+
swap$1(this, i, i + 7);
|
|
1012
|
+
swap$1(this, i + 1, i + 6);
|
|
1013
|
+
swap$1(this, i + 2, i + 5);
|
|
1014
|
+
swap$1(this, i + 3, i + 4);
|
|
1015
1015
|
}
|
|
1016
1016
|
return this
|
|
1017
1017
|
};
|
|
@@ -33430,452 +33430,6 @@
|
|
|
33430
33430
|
return pj_init(defn);
|
|
33431
33431
|
}
|
|
33432
33432
|
|
|
33433
|
-
class FlatQueue {
|
|
33434
|
-
|
|
33435
|
-
constructor() {
|
|
33436
|
-
this.ids = [];
|
|
33437
|
-
this.values = [];
|
|
33438
|
-
this.length = 0;
|
|
33439
|
-
}
|
|
33440
|
-
|
|
33441
|
-
clear() {
|
|
33442
|
-
this.length = 0;
|
|
33443
|
-
}
|
|
33444
|
-
|
|
33445
|
-
push(id, value) {
|
|
33446
|
-
let pos = this.length++;
|
|
33447
|
-
this.ids[pos] = id;
|
|
33448
|
-
this.values[pos] = value;
|
|
33449
|
-
|
|
33450
|
-
while (pos > 0) {
|
|
33451
|
-
const parent = (pos - 1) >> 1;
|
|
33452
|
-
const parentValue = this.values[parent];
|
|
33453
|
-
if (value >= parentValue) break;
|
|
33454
|
-
this.ids[pos] = this.ids[parent];
|
|
33455
|
-
this.values[pos] = parentValue;
|
|
33456
|
-
pos = parent;
|
|
33457
|
-
}
|
|
33458
|
-
|
|
33459
|
-
this.ids[pos] = id;
|
|
33460
|
-
this.values[pos] = value;
|
|
33461
|
-
}
|
|
33462
|
-
|
|
33463
|
-
pop() {
|
|
33464
|
-
if (this.length === 0) return undefined;
|
|
33465
|
-
|
|
33466
|
-
const top = this.ids[0];
|
|
33467
|
-
this.length--;
|
|
33468
|
-
|
|
33469
|
-
if (this.length > 0) {
|
|
33470
|
-
const id = this.ids[0] = this.ids[this.length];
|
|
33471
|
-
const value = this.values[0] = this.values[this.length];
|
|
33472
|
-
const halfLength = this.length >> 1;
|
|
33473
|
-
let pos = 0;
|
|
33474
|
-
|
|
33475
|
-
while (pos < halfLength) {
|
|
33476
|
-
let left = (pos << 1) + 1;
|
|
33477
|
-
const right = left + 1;
|
|
33478
|
-
let bestIndex = this.ids[left];
|
|
33479
|
-
let bestValue = this.values[left];
|
|
33480
|
-
const rightValue = this.values[right];
|
|
33481
|
-
|
|
33482
|
-
if (right < this.length && rightValue < bestValue) {
|
|
33483
|
-
left = right;
|
|
33484
|
-
bestIndex = this.ids[right];
|
|
33485
|
-
bestValue = rightValue;
|
|
33486
|
-
}
|
|
33487
|
-
if (bestValue >= value) break;
|
|
33488
|
-
|
|
33489
|
-
this.ids[pos] = bestIndex;
|
|
33490
|
-
this.values[pos] = bestValue;
|
|
33491
|
-
pos = left;
|
|
33492
|
-
}
|
|
33493
|
-
|
|
33494
|
-
this.ids[pos] = id;
|
|
33495
|
-
this.values[pos] = value;
|
|
33496
|
-
}
|
|
33497
|
-
|
|
33498
|
-
return top;
|
|
33499
|
-
}
|
|
33500
|
-
|
|
33501
|
-
peek() {
|
|
33502
|
-
return this.ids[0];
|
|
33503
|
-
}
|
|
33504
|
-
|
|
33505
|
-
peekValue() {
|
|
33506
|
-
return this.values[0];
|
|
33507
|
-
}
|
|
33508
|
-
}
|
|
33509
|
-
|
|
33510
|
-
const ARRAY_TYPES = [
|
|
33511
|
-
Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,
|
|
33512
|
-
Int32Array, Uint32Array, Float32Array, Float64Array
|
|
33513
|
-
];
|
|
33514
|
-
|
|
33515
|
-
const VERSION = 3; // serialized format version
|
|
33516
|
-
|
|
33517
|
-
class Flatbush {
|
|
33518
|
-
|
|
33519
|
-
static from(data) {
|
|
33520
|
-
if (!(data instanceof ArrayBuffer)) {
|
|
33521
|
-
throw new Error('Data must be an instance of ArrayBuffer.');
|
|
33522
|
-
}
|
|
33523
|
-
const [magic, versionAndType] = new Uint8Array(data, 0, 2);
|
|
33524
|
-
if (magic !== 0xfb) {
|
|
33525
|
-
throw new Error('Data does not appear to be in a Flatbush format.');
|
|
33526
|
-
}
|
|
33527
|
-
if (versionAndType >> 4 !== VERSION) {
|
|
33528
|
-
throw new Error(`Got v${versionAndType >> 4} data when expected v${VERSION}.`);
|
|
33529
|
-
}
|
|
33530
|
-
const [nodeSize] = new Uint16Array(data, 2, 1);
|
|
33531
|
-
const [numItems] = new Uint32Array(data, 4, 1);
|
|
33532
|
-
|
|
33533
|
-
return new Flatbush(numItems, nodeSize, ARRAY_TYPES[versionAndType & 0x0f], data);
|
|
33534
|
-
}
|
|
33535
|
-
|
|
33536
|
-
constructor(numItems, nodeSize = 16, ArrayType = Float64Array, data) {
|
|
33537
|
-
if (numItems === undefined) throw new Error('Missing required argument: numItems.');
|
|
33538
|
-
if (isNaN(numItems) || numItems <= 0) throw new Error(`Unpexpected numItems value: ${numItems}.`);
|
|
33539
|
-
|
|
33540
|
-
this.numItems = +numItems;
|
|
33541
|
-
this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);
|
|
33542
|
-
|
|
33543
|
-
// calculate the total number of nodes in the R-tree to allocate space for
|
|
33544
|
-
// and the index of each tree level (used in search later)
|
|
33545
|
-
let n = numItems;
|
|
33546
|
-
let numNodes = n;
|
|
33547
|
-
this._levelBounds = [n * 4];
|
|
33548
|
-
do {
|
|
33549
|
-
n = Math.ceil(n / this.nodeSize);
|
|
33550
|
-
numNodes += n;
|
|
33551
|
-
this._levelBounds.push(numNodes * 4);
|
|
33552
|
-
} while (n !== 1);
|
|
33553
|
-
|
|
33554
|
-
this.ArrayType = ArrayType || Float64Array;
|
|
33555
|
-
this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;
|
|
33556
|
-
|
|
33557
|
-
const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);
|
|
33558
|
-
const nodesByteSize = numNodes * 4 * this.ArrayType.BYTES_PER_ELEMENT;
|
|
33559
|
-
|
|
33560
|
-
if (arrayTypeIndex < 0) {
|
|
33561
|
-
throw new Error(`Unexpected typed array class: ${ArrayType}.`);
|
|
33562
|
-
}
|
|
33563
|
-
|
|
33564
|
-
if (data && (data instanceof ArrayBuffer)) {
|
|
33565
|
-
this.data = data;
|
|
33566
|
-
this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
|
|
33567
|
-
this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
|
|
33568
|
-
|
|
33569
|
-
this._pos = numNodes * 4;
|
|
33570
|
-
this.minX = this._boxes[this._pos - 4];
|
|
33571
|
-
this.minY = this._boxes[this._pos - 3];
|
|
33572
|
-
this.maxX = this._boxes[this._pos - 2];
|
|
33573
|
-
this.maxY = this._boxes[this._pos - 1];
|
|
33574
|
-
|
|
33575
|
-
} else {
|
|
33576
|
-
this.data = new ArrayBuffer(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);
|
|
33577
|
-
this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
|
|
33578
|
-
this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
|
|
33579
|
-
this._pos = 0;
|
|
33580
|
-
this.minX = Infinity;
|
|
33581
|
-
this.minY = Infinity;
|
|
33582
|
-
this.maxX = -Infinity;
|
|
33583
|
-
this.maxY = -Infinity;
|
|
33584
|
-
|
|
33585
|
-
new Uint8Array(this.data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);
|
|
33586
|
-
new Uint16Array(this.data, 2, 1)[0] = nodeSize;
|
|
33587
|
-
new Uint32Array(this.data, 4, 1)[0] = numItems;
|
|
33588
|
-
}
|
|
33589
|
-
|
|
33590
|
-
// a priority queue for k-nearest-neighbors queries
|
|
33591
|
-
this._queue = new FlatQueue();
|
|
33592
|
-
}
|
|
33593
|
-
|
|
33594
|
-
add(minX, minY, maxX, maxY) {
|
|
33595
|
-
const index = this._pos >> 2;
|
|
33596
|
-
this._indices[index] = index;
|
|
33597
|
-
this._boxes[this._pos++] = minX;
|
|
33598
|
-
this._boxes[this._pos++] = minY;
|
|
33599
|
-
this._boxes[this._pos++] = maxX;
|
|
33600
|
-
this._boxes[this._pos++] = maxY;
|
|
33601
|
-
|
|
33602
|
-
if (minX < this.minX) this.minX = minX;
|
|
33603
|
-
if (minY < this.minY) this.minY = minY;
|
|
33604
|
-
if (maxX > this.maxX) this.maxX = maxX;
|
|
33605
|
-
if (maxY > this.maxY) this.maxY = maxY;
|
|
33606
|
-
|
|
33607
|
-
return index;
|
|
33608
|
-
}
|
|
33609
|
-
|
|
33610
|
-
finish() {
|
|
33611
|
-
if (this._pos >> 2 !== this.numItems) {
|
|
33612
|
-
throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`);
|
|
33613
|
-
}
|
|
33614
|
-
|
|
33615
|
-
const width = this.maxX - this.minX;
|
|
33616
|
-
const height = this.maxY - this.minY;
|
|
33617
|
-
const hilbertValues = new Uint32Array(this.numItems);
|
|
33618
|
-
const hilbertMax = (1 << 16) - 1;
|
|
33619
|
-
|
|
33620
|
-
// map item centers into Hilbert coordinate space and calculate Hilbert values
|
|
33621
|
-
for (let i = 0; i < this.numItems; i++) {
|
|
33622
|
-
let pos = 4 * i;
|
|
33623
|
-
const minX = this._boxes[pos++];
|
|
33624
|
-
const minY = this._boxes[pos++];
|
|
33625
|
-
const maxX = this._boxes[pos++];
|
|
33626
|
-
const maxY = this._boxes[pos++];
|
|
33627
|
-
const x = Math.floor(hilbertMax * ((minX + maxX) / 2 - this.minX) / width);
|
|
33628
|
-
const y = Math.floor(hilbertMax * ((minY + maxY) / 2 - this.minY) / height);
|
|
33629
|
-
hilbertValues[i] = hilbert(x, y);
|
|
33630
|
-
}
|
|
33631
|
-
|
|
33632
|
-
// sort items by their Hilbert value (for packing later)
|
|
33633
|
-
sort(hilbertValues, this._boxes, this._indices, 0, this.numItems - 1);
|
|
33634
|
-
|
|
33635
|
-
// generate nodes at each tree level, bottom-up
|
|
33636
|
-
for (let i = 0, pos = 0; i < this._levelBounds.length - 1; i++) {
|
|
33637
|
-
const end = this._levelBounds[i];
|
|
33638
|
-
|
|
33639
|
-
// generate a parent node for each block of consecutive <nodeSize> nodes
|
|
33640
|
-
while (pos < end) {
|
|
33641
|
-
let nodeMinX = Infinity;
|
|
33642
|
-
let nodeMinY = Infinity;
|
|
33643
|
-
let nodeMaxX = -Infinity;
|
|
33644
|
-
let nodeMaxY = -Infinity;
|
|
33645
|
-
const nodeIndex = pos;
|
|
33646
|
-
|
|
33647
|
-
// calculate bbox for the new node
|
|
33648
|
-
for (let i = 0; i < this.nodeSize && pos < end; i++) {
|
|
33649
|
-
const minX = this._boxes[pos++];
|
|
33650
|
-
const minY = this._boxes[pos++];
|
|
33651
|
-
const maxX = this._boxes[pos++];
|
|
33652
|
-
const maxY = this._boxes[pos++];
|
|
33653
|
-
if (minX < nodeMinX) nodeMinX = minX;
|
|
33654
|
-
if (minY < nodeMinY) nodeMinY = minY;
|
|
33655
|
-
if (maxX > nodeMaxX) nodeMaxX = maxX;
|
|
33656
|
-
if (maxY > nodeMaxY) nodeMaxY = maxY;
|
|
33657
|
-
}
|
|
33658
|
-
|
|
33659
|
-
// add the new node to the tree data
|
|
33660
|
-
this._indices[this._pos >> 2] = nodeIndex;
|
|
33661
|
-
this._boxes[this._pos++] = nodeMinX;
|
|
33662
|
-
this._boxes[this._pos++] = nodeMinY;
|
|
33663
|
-
this._boxes[this._pos++] = nodeMaxX;
|
|
33664
|
-
this._boxes[this._pos++] = nodeMaxY;
|
|
33665
|
-
}
|
|
33666
|
-
}
|
|
33667
|
-
}
|
|
33668
|
-
|
|
33669
|
-
search(minX, minY, maxX, maxY, filterFn) {
|
|
33670
|
-
if (this._pos !== this._boxes.length) {
|
|
33671
|
-
throw new Error('Data not yet indexed - call index.finish().');
|
|
33672
|
-
}
|
|
33673
|
-
|
|
33674
|
-
let nodeIndex = this._boxes.length - 4;
|
|
33675
|
-
let level = this._levelBounds.length - 1;
|
|
33676
|
-
const queue = [];
|
|
33677
|
-
const results = [];
|
|
33678
|
-
|
|
33679
|
-
while (nodeIndex !== undefined) {
|
|
33680
|
-
// find the end index of the node
|
|
33681
|
-
const end = Math.min(nodeIndex + this.nodeSize * 4, this._levelBounds[level]);
|
|
33682
|
-
|
|
33683
|
-
// search through child nodes
|
|
33684
|
-
for (let pos = nodeIndex; pos < end; pos += 4) {
|
|
33685
|
-
const index = this._indices[pos >> 2] | 0;
|
|
33686
|
-
|
|
33687
|
-
// check if node bbox intersects with query bbox
|
|
33688
|
-
if (maxX < this._boxes[pos]) continue; // maxX < nodeMinX
|
|
33689
|
-
if (maxY < this._boxes[pos + 1]) continue; // maxY < nodeMinY
|
|
33690
|
-
if (minX > this._boxes[pos + 2]) continue; // minX > nodeMaxX
|
|
33691
|
-
if (minY > this._boxes[pos + 3]) continue; // minY > nodeMaxY
|
|
33692
|
-
|
|
33693
|
-
if (nodeIndex < this.numItems * 4) {
|
|
33694
|
-
if (filterFn === undefined || filterFn(index)) {
|
|
33695
|
-
results.push(index); // leaf item
|
|
33696
|
-
}
|
|
33697
|
-
|
|
33698
|
-
} else {
|
|
33699
|
-
queue.push(index); // node; add it to the search queue
|
|
33700
|
-
queue.push(level - 1);
|
|
33701
|
-
}
|
|
33702
|
-
}
|
|
33703
|
-
|
|
33704
|
-
level = queue.pop();
|
|
33705
|
-
nodeIndex = queue.pop();
|
|
33706
|
-
}
|
|
33707
|
-
|
|
33708
|
-
return results;
|
|
33709
|
-
}
|
|
33710
|
-
|
|
33711
|
-
neighbors(x, y, maxResults = Infinity, maxDistance = Infinity, filterFn) {
|
|
33712
|
-
if (this._pos !== this._boxes.length) {
|
|
33713
|
-
throw new Error('Data not yet indexed - call index.finish().');
|
|
33714
|
-
}
|
|
33715
|
-
|
|
33716
|
-
let nodeIndex = this._boxes.length - 4;
|
|
33717
|
-
const q = this._queue;
|
|
33718
|
-
const results = [];
|
|
33719
|
-
const maxDistSquared = maxDistance * maxDistance;
|
|
33720
|
-
|
|
33721
|
-
while (nodeIndex !== undefined) {
|
|
33722
|
-
// find the end index of the node
|
|
33723
|
-
const end = Math.min(nodeIndex + this.nodeSize * 4, upperBound(nodeIndex, this._levelBounds));
|
|
33724
|
-
|
|
33725
|
-
// add child nodes to the queue
|
|
33726
|
-
for (let pos = nodeIndex; pos < end; pos += 4) {
|
|
33727
|
-
const index = this._indices[pos >> 2] | 0;
|
|
33728
|
-
|
|
33729
|
-
const dx = axisDist(x, this._boxes[pos], this._boxes[pos + 2]);
|
|
33730
|
-
const dy = axisDist(y, this._boxes[pos + 1], this._boxes[pos + 3]);
|
|
33731
|
-
const dist = dx * dx + dy * dy;
|
|
33732
|
-
|
|
33733
|
-
if (nodeIndex < this.numItems * 4) { // leaf node
|
|
33734
|
-
if (filterFn === undefined || filterFn(index)) {
|
|
33735
|
-
// put a negative index if it's an item rather than a node, to recognize later
|
|
33736
|
-
q.push(-index - 1, dist);
|
|
33737
|
-
}
|
|
33738
|
-
} else {
|
|
33739
|
-
q.push(index, dist);
|
|
33740
|
-
}
|
|
33741
|
-
}
|
|
33742
|
-
|
|
33743
|
-
// pop items from the queue
|
|
33744
|
-
while (q.length && q.peek() < 0) {
|
|
33745
|
-
const dist = q.peekValue();
|
|
33746
|
-
if (dist > maxDistSquared) {
|
|
33747
|
-
q.clear();
|
|
33748
|
-
return results;
|
|
33749
|
-
}
|
|
33750
|
-
results.push(-q.pop() - 1);
|
|
33751
|
-
|
|
33752
|
-
if (results.length === maxResults) {
|
|
33753
|
-
q.clear();
|
|
33754
|
-
return results;
|
|
33755
|
-
}
|
|
33756
|
-
}
|
|
33757
|
-
|
|
33758
|
-
nodeIndex = q.pop();
|
|
33759
|
-
}
|
|
33760
|
-
|
|
33761
|
-
q.clear();
|
|
33762
|
-
return results;
|
|
33763
|
-
}
|
|
33764
|
-
}
|
|
33765
|
-
|
|
33766
|
-
function axisDist(k, min, max) {
|
|
33767
|
-
return k < min ? min - k : k <= max ? 0 : k - max;
|
|
33768
|
-
}
|
|
33769
|
-
|
|
33770
|
-
// binary search for the first value in the array bigger than the given
|
|
33771
|
-
function upperBound(value, arr) {
|
|
33772
|
-
let i = 0;
|
|
33773
|
-
let j = arr.length - 1;
|
|
33774
|
-
while (i < j) {
|
|
33775
|
-
const m = (i + j) >> 1;
|
|
33776
|
-
if (arr[m] > value) {
|
|
33777
|
-
j = m;
|
|
33778
|
-
} else {
|
|
33779
|
-
i = m + 1;
|
|
33780
|
-
}
|
|
33781
|
-
}
|
|
33782
|
-
return arr[i];
|
|
33783
|
-
}
|
|
33784
|
-
|
|
33785
|
-
// custom quicksort that sorts bbox data alongside the hilbert values
|
|
33786
|
-
function sort(values, boxes, indices, left, right) {
|
|
33787
|
-
if (left >= right) return;
|
|
33788
|
-
|
|
33789
|
-
const pivot = values[(left + right) >> 1];
|
|
33790
|
-
let i = left - 1;
|
|
33791
|
-
let j = right + 1;
|
|
33792
|
-
|
|
33793
|
-
while (true) {
|
|
33794
|
-
do i++; while (values[i] < pivot);
|
|
33795
|
-
do j--; while (values[j] > pivot);
|
|
33796
|
-
if (i >= j) break;
|
|
33797
|
-
swap$1(values, boxes, indices, i, j);
|
|
33798
|
-
}
|
|
33799
|
-
|
|
33800
|
-
sort(values, boxes, indices, left, j);
|
|
33801
|
-
sort(values, boxes, indices, j + 1, right);
|
|
33802
|
-
}
|
|
33803
|
-
|
|
33804
|
-
// swap two values and two corresponding boxes
|
|
33805
|
-
function swap$1(values, boxes, indices, i, j) {
|
|
33806
|
-
const temp = values[i];
|
|
33807
|
-
values[i] = values[j];
|
|
33808
|
-
values[j] = temp;
|
|
33809
|
-
|
|
33810
|
-
const k = 4 * i;
|
|
33811
|
-
const m = 4 * j;
|
|
33812
|
-
|
|
33813
|
-
const a = boxes[k];
|
|
33814
|
-
const b = boxes[k + 1];
|
|
33815
|
-
const c = boxes[k + 2];
|
|
33816
|
-
const d = boxes[k + 3];
|
|
33817
|
-
boxes[k] = boxes[m];
|
|
33818
|
-
boxes[k + 1] = boxes[m + 1];
|
|
33819
|
-
boxes[k + 2] = boxes[m + 2];
|
|
33820
|
-
boxes[k + 3] = boxes[m + 3];
|
|
33821
|
-
boxes[m] = a;
|
|
33822
|
-
boxes[m + 1] = b;
|
|
33823
|
-
boxes[m + 2] = c;
|
|
33824
|
-
boxes[m + 3] = d;
|
|
33825
|
-
|
|
33826
|
-
const e = indices[i];
|
|
33827
|
-
indices[i] = indices[j];
|
|
33828
|
-
indices[j] = e;
|
|
33829
|
-
}
|
|
33830
|
-
|
|
33831
|
-
// Fast Hilbert curve algorithm by http://threadlocalmutex.com/
|
|
33832
|
-
// Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)
|
|
33833
|
-
function hilbert(x, y) {
|
|
33834
|
-
let a = x ^ y;
|
|
33835
|
-
let b = 0xFFFF ^ a;
|
|
33836
|
-
let c = 0xFFFF ^ (x | y);
|
|
33837
|
-
let d = x & (y ^ 0xFFFF);
|
|
33838
|
-
|
|
33839
|
-
let A = a | (b >> 1);
|
|
33840
|
-
let B = (a >> 1) ^ a;
|
|
33841
|
-
let C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
|
|
33842
|
-
let D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
|
|
33843
|
-
|
|
33844
|
-
a = A; b = B; c = C; d = D;
|
|
33845
|
-
A = ((a & (a >> 2)) ^ (b & (b >> 2)));
|
|
33846
|
-
B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));
|
|
33847
|
-
C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));
|
|
33848
|
-
D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));
|
|
33849
|
-
|
|
33850
|
-
a = A; b = B; c = C; d = D;
|
|
33851
|
-
A = ((a & (a >> 4)) ^ (b & (b >> 4)));
|
|
33852
|
-
B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));
|
|
33853
|
-
C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));
|
|
33854
|
-
D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));
|
|
33855
|
-
|
|
33856
|
-
a = A; b = B; c = C; d = D;
|
|
33857
|
-
C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));
|
|
33858
|
-
D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));
|
|
33859
|
-
|
|
33860
|
-
a = C ^ (C >> 1);
|
|
33861
|
-
b = D ^ (D >> 1);
|
|
33862
|
-
|
|
33863
|
-
let i0 = x ^ y;
|
|
33864
|
-
let i1 = b | (0xFFFF ^ (i0 | a));
|
|
33865
|
-
|
|
33866
|
-
i0 = (i0 | (i0 << 8)) & 0x00FF00FF;
|
|
33867
|
-
i0 = (i0 | (i0 << 4)) & 0x0F0F0F0F;
|
|
33868
|
-
i0 = (i0 | (i0 << 2)) & 0x33333333;
|
|
33869
|
-
i0 = (i0 | (i0 << 1)) & 0x55555555;
|
|
33870
|
-
|
|
33871
|
-
i1 = (i1 | (i1 << 8)) & 0x00FF00FF;
|
|
33872
|
-
i1 = (i1 | (i1 << 4)) & 0x0F0F0F0F;
|
|
33873
|
-
i1 = (i1 | (i1 << 2)) & 0x33333333;
|
|
33874
|
-
i1 = (i1 | (i1 << 1)) & 0x55555555;
|
|
33875
|
-
|
|
33876
|
-
return ((i1 << 1) | i0) >>> 0;
|
|
33877
|
-
}
|
|
33878
|
-
|
|
33879
33433
|
function sortKD(ids, coords, nodeSize, left, right, depth) {
|
|
33880
33434
|
if (right - left <= nodeSize) return;
|
|
33881
33435
|
|
|
@@ -34213,7 +33767,6 @@
|
|
|
34213
33767
|
'@tmcw/togeojson': togeojson,
|
|
34214
33768
|
'geographiclib-geodesic': GeographicLib,
|
|
34215
33769
|
mproj: api,
|
|
34216
|
-
flatbush: Flatbush,
|
|
34217
33770
|
kdbush: KDBush,
|
|
34218
33771
|
buffer
|
|
34219
33772
|
};
|
package/www/page.css
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
--colored-text: #10699b;
|
|
24
24
|
--normal-text: #333;
|
|
25
25
|
--left-sidebar-width: 420px;
|
|
26
|
+
--sidebar-panels-separator-position: 50%;
|
|
26
27
|
--sidebar-resize-col: #f2c65a; /* #d6a51d; */
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -788,7 +789,7 @@ input[type="checkbox"]
|
|
|
788
789
|
|
|
789
790
|
/* --- Sidebar panels ------------ */
|
|
790
791
|
|
|
791
|
-
.sidebar-
|
|
792
|
+
.sidebar-panels {
|
|
792
793
|
right: auto;
|
|
793
794
|
width: var(--left-sidebar-width);
|
|
794
795
|
max-width: 100%;
|
|
@@ -800,6 +801,31 @@ input[type="checkbox"]
|
|
|
800
801
|
display: none;
|
|
801
802
|
}
|
|
802
803
|
|
|
804
|
+
.sidebar-panel {
|
|
805
|
+
position: relative;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
.sidebar-panel:first-child {
|
|
809
|
+
height: var(--sidebar-panels-separator-position);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.sidebar-panel:last-child {
|
|
813
|
+
height: calc(100% - var(--sidebar-panels-separator-position));
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.sidebar-panels:not(:has(> .sidebar-panel.open ~ .sidebar-panel.open)) > .sidebar-panel.open {
|
|
817
|
+
height: 100%;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.sidebar-panels:not(:has(> .sidebar-panel.open ~ .sidebar-panel.open)) .sidebar-panels-resize-handle {
|
|
821
|
+
display: none;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
body.sidebar-open .sidebar-panels {
|
|
825
|
+
display: flex;
|
|
826
|
+
flex-direction: column;
|
|
827
|
+
}
|
|
828
|
+
|
|
803
829
|
.console-area {
|
|
804
830
|
font-size: 12px;
|
|
805
831
|
}
|
|
@@ -845,6 +871,39 @@ body.sidebar-resizing .sidebar-resize-handle::before,
|
|
|
845
871
|
background-color: var(--sidebar-resize-col);
|
|
846
872
|
}
|
|
847
873
|
|
|
874
|
+
.sidebar-panels-resize-handle {
|
|
875
|
+
display: block;
|
|
876
|
+
position: absolute;
|
|
877
|
+
left: 0;
|
|
878
|
+
right: 0;
|
|
879
|
+
top: -4px;
|
|
880
|
+
height: 8px;
|
|
881
|
+
z-index: 35;
|
|
882
|
+
cursor: ns-resize;
|
|
883
|
+
pointer-events: auto;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.sidebar-panels-resize-handle::before {
|
|
887
|
+
content: "";
|
|
888
|
+
position: absolute;
|
|
889
|
+
left: 0;
|
|
890
|
+
right: 0;
|
|
891
|
+
top: 3px;
|
|
892
|
+
height: 2px;
|
|
893
|
+
background-color: transparent;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
body.sidebar-panels-resizing,
|
|
897
|
+
body.sidebar-panels-resizing * {
|
|
898
|
+
cursor: ns-resize !important;
|
|
899
|
+
user-select: none;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
body.sidebar-panels-resizing .sidebar-panels-resize-handle::before,
|
|
903
|
+
.sidebar-panels-resize-handle:hover::before {
|
|
904
|
+
background-color: var(--sidebar-resize-col);
|
|
905
|
+
}
|
|
906
|
+
|
|
848
907
|
/* Give the console a little more line length on wide screens. */
|
|
849
908
|
@media screen and (max-width: 525px) {
|
|
850
909
|
body.sidebar-open .map-area {
|
package/www/sponsor.html
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
<h2>Recent work</h2>
|
|
38
38
|
<ul class="support-list">
|
|
39
|
+
<li><strong>Buffer command</strong> — Geodesic and planar buffering for points, lines and polygons</li>
|
|
39
40
|
<li><strong>Raster importing</strong> — GeoTIFF + georeferenced JPEG and PNG</li>
|
|
40
41
|
<li><strong>Undo/redo</strong> in the browser — the most requested feature</li>
|
|
41
42
|
<li><strong>New vector formats</strong> — GeoParquet, GeoPackage and FlatGeobuf</li>
|