mapshaper 0.6.67 → 0.6.69
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/mapshaper.js +341 -150
- package/package.json +2 -2
- package/www/mapshaper-gui.js +243 -161
- package/www/mapshaper.js +341 -150
package/www/mapshaper.js
CHANGED
|
@@ -7415,6 +7415,8 @@
|
|
|
7415
7415
|
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
|
|
7416
7416
|
})
|
|
7417
7417
|
}
|
|
7418
|
+
if (!source.buffer && source.constructor === ArrayBuffer)
|
|
7419
|
+
source = typeof Buffer !== 'undefined' ? Buffer.from(source) : new Uint8Array(source);
|
|
7418
7420
|
if (typeof options === 'object') {
|
|
7419
7421
|
srcEnd = options.end || source.length;
|
|
7420
7422
|
position$1 = options.start || 0;
|
|
@@ -7460,10 +7462,10 @@
|
|
|
7460
7462
|
let size = source.length;
|
|
7461
7463
|
let value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
|
|
7462
7464
|
if (forEach) {
|
|
7463
|
-
if (forEach(value) === false) return;
|
|
7465
|
+
if (forEach(value, lastPosition, position$1) === false) return;
|
|
7464
7466
|
while(position$1 < size) {
|
|
7465
7467
|
lastPosition = position$1;
|
|
7466
|
-
if (forEach(checkedRead()) === false) {
|
|
7468
|
+
if (forEach(checkedRead(), lastPosition, position$1) === false) {
|
|
7467
7469
|
return
|
|
7468
7470
|
}
|
|
7469
7471
|
}
|
|
@@ -7511,8 +7513,8 @@
|
|
|
7511
7513
|
}
|
|
7512
7514
|
return this.structures = loadedStructures
|
|
7513
7515
|
}
|
|
7514
|
-
decode(source,
|
|
7515
|
-
return this.unpack(source,
|
|
7516
|
+
decode(source, options) {
|
|
7517
|
+
return this.unpack(source, options)
|
|
7516
7518
|
}
|
|
7517
7519
|
}
|
|
7518
7520
|
function checkedRead(options) {
|
|
@@ -7535,6 +7537,10 @@
|
|
|
7535
7537
|
position$1 = bundledStrings$1.postBundlePosition;
|
|
7536
7538
|
bundledStrings$1 = null;
|
|
7537
7539
|
}
|
|
7540
|
+
if (sequentialMode)
|
|
7541
|
+
// we only need to restore the structures if there was an error, but if we completed a read,
|
|
7542
|
+
// we can clear this out and keep the structures we read
|
|
7543
|
+
currentStructures.restoreStructures = null;
|
|
7538
7544
|
|
|
7539
7545
|
if (position$1 == srcEnd) {
|
|
7540
7546
|
// finished reading this source, cleanup references
|
|
@@ -7548,7 +7554,13 @@
|
|
|
7548
7554
|
// over read
|
|
7549
7555
|
throw new Error('Unexpected end of MessagePack data')
|
|
7550
7556
|
} else if (!sequentialMode) {
|
|
7551
|
-
|
|
7557
|
+
let jsonView;
|
|
7558
|
+
try {
|
|
7559
|
+
jsonView = JSON.stringify(result, (_, value) => typeof value === "bigint" ? `${value}n` : value).slice(0, 100);
|
|
7560
|
+
} catch(error) {
|
|
7561
|
+
jsonView = '(JSON view not available ' + error + ')';
|
|
7562
|
+
}
|
|
7563
|
+
throw new Error('Data read, but end of buffer not reached ' + jsonView)
|
|
7552
7564
|
}
|
|
7553
7565
|
// else more to read, but we are reading sequentially, so don't clear source yet
|
|
7554
7566
|
return result
|
|
@@ -7704,6 +7716,9 @@
|
|
|
7704
7716
|
value += dataView.getUint32(position$1 + 4);
|
|
7705
7717
|
} else if (currentUnpackr.int64AsType === 'string') {
|
|
7706
7718
|
value = dataView.getBigUint64(position$1).toString();
|
|
7719
|
+
} else if (currentUnpackr.int64AsType === 'auto') {
|
|
7720
|
+
value = dataView.getBigUint64(position$1);
|
|
7721
|
+
if (value<=BigInt(2)<<BigInt(52)) value=Number(value);
|
|
7707
7722
|
} else
|
|
7708
7723
|
value = dataView.getBigUint64(position$1);
|
|
7709
7724
|
position$1 += 8;
|
|
@@ -7726,6 +7741,9 @@
|
|
|
7726
7741
|
value += dataView.getUint32(position$1 + 4);
|
|
7727
7742
|
} else if (currentUnpackr.int64AsType === 'string') {
|
|
7728
7743
|
value = dataView.getBigInt64(position$1).toString();
|
|
7744
|
+
} else if (currentUnpackr.int64AsType === 'auto') {
|
|
7745
|
+
value = dataView.getBigInt64(position$1);
|
|
7746
|
+
if (value>=BigInt(-2)<<BigInt(52)&&value<=BigInt(2)<<BigInt(52)) value=Number(value);
|
|
7729
7747
|
} else
|
|
7730
7748
|
value = dataView.getBigInt64(position$1);
|
|
7731
7749
|
position$1 += 8;
|
|
@@ -8183,7 +8201,7 @@
|
|
|
8183
8201
|
return readFixedString(length)
|
|
8184
8202
|
} else { // not cacheable, go back and do a standard read
|
|
8185
8203
|
position$1--;
|
|
8186
|
-
return read()
|
|
8204
|
+
return asSafeString(read())
|
|
8187
8205
|
}
|
|
8188
8206
|
let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position$1) : length > 0 ? src[position$1] : 0)) & 0xfff;
|
|
8189
8207
|
let entry = keyCache[key];
|
|
@@ -8235,16 +8253,25 @@
|
|
|
8235
8253
|
return entry.string = readFixedString(length)
|
|
8236
8254
|
}
|
|
8237
8255
|
|
|
8256
|
+
function asSafeString(property) {
|
|
8257
|
+
if (typeof property === 'string') return property;
|
|
8258
|
+
if (typeof property === 'number') return property.toString();
|
|
8259
|
+
throw new Error('Invalid property type for record', typeof property);
|
|
8260
|
+
}
|
|
8238
8261
|
// the registration of the record definition extension (as "r")
|
|
8239
8262
|
const recordDefinition = (id, highByte) => {
|
|
8240
|
-
let structure = read().map(
|
|
8263
|
+
let structure = read().map(asSafeString); // ensure that all keys are strings and
|
|
8264
|
+
// that the array is mutable
|
|
8241
8265
|
let firstByte = id;
|
|
8242
8266
|
if (highByte !== undefined) {
|
|
8243
8267
|
id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
|
|
8244
8268
|
structure.highByte = highByte;
|
|
8245
8269
|
}
|
|
8246
8270
|
let existingStructure = currentStructures[id];
|
|
8247
|
-
|
|
8271
|
+
// If it is a shared structure, we need to restore any changes after reading.
|
|
8272
|
+
// Also in sequential mode, we may get incomplete reads and thus errors, and we need to restore
|
|
8273
|
+
// to the state prior to an incomplete read in order to properly resume.
|
|
8274
|
+
if (existingStructure && (existingStructure.isShared || sequentialMode)) {
|
|
8248
8275
|
(currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
|
|
8249
8276
|
}
|
|
8250
8277
|
currentStructures[id] = structure;
|
|
@@ -8254,13 +8281,26 @@
|
|
|
8254
8281
|
currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
8255
8282
|
currentExtensions[0].noBuffer = true;
|
|
8256
8283
|
|
|
8284
|
+
currentExtensions[0x42] = (data) => {
|
|
8285
|
+
// decode bigint
|
|
8286
|
+
let length = data.length;
|
|
8287
|
+
let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
|
|
8288
|
+
for (let i = 1; i < length; i++) {
|
|
8289
|
+
value <<= 8n;
|
|
8290
|
+
value += BigInt(data[i]);
|
|
8291
|
+
}
|
|
8292
|
+
return value;
|
|
8293
|
+
};
|
|
8294
|
+
|
|
8295
|
+
let errors = { Error, TypeError, ReferenceError };
|
|
8257
8296
|
currentExtensions[0x65] = () => {
|
|
8258
8297
|
let data = read();
|
|
8259
|
-
return (
|
|
8298
|
+
return (errors[data[0]] || Error)(data[1])
|
|
8260
8299
|
};
|
|
8261
8300
|
|
|
8262
8301
|
currentExtensions[0x69] = (data) => {
|
|
8263
8302
|
// id extension (for structured clones)
|
|
8303
|
+
if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
|
|
8264
8304
|
let id = dataView.getUint32(position$1 - 4);
|
|
8265
8305
|
if (!referenceMap)
|
|
8266
8306
|
referenceMap = new Map();
|
|
@@ -8284,6 +8324,7 @@
|
|
|
8284
8324
|
|
|
8285
8325
|
currentExtensions[0x70] = (data) => {
|
|
8286
8326
|
// pointer extension (for structured clones)
|
|
8327
|
+
if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
|
|
8287
8328
|
let id = dataView.getUint32(position$1 - 4);
|
|
8288
8329
|
let refEntry = referenceMap.get(id);
|
|
8289
8330
|
refEntry.used = true;
|
|
@@ -8294,13 +8335,14 @@
|
|
|
8294
8335
|
|
|
8295
8336
|
const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
|
|
8296
8337
|
|
|
8338
|
+
let glbl = typeof globalThis === 'object' ? globalThis : window;
|
|
8297
8339
|
currentExtensions[0x74] = (data) => {
|
|
8298
8340
|
let typeCode = data[0];
|
|
8299
8341
|
let typedArrayName = typedArrays[typeCode];
|
|
8300
8342
|
if (!typedArrayName)
|
|
8301
8343
|
throw new Error('Could not find typed array for code ' + typeCode)
|
|
8302
8344
|
// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
|
|
8303
|
-
return new
|
|
8345
|
+
return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
|
|
8304
8346
|
};
|
|
8305
8347
|
currentExtensions[0x78] = () => {
|
|
8306
8348
|
let data = read();
|
|
@@ -8465,6 +8507,7 @@
|
|
|
8465
8507
|
} else
|
|
8466
8508
|
position = (position + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
8467
8509
|
start = position;
|
|
8510
|
+
if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff);
|
|
8468
8511
|
referenceMap = packr.structuredClone ? new Map() : null;
|
|
8469
8512
|
if (packr.bundleStrings && typeof value !== 'string') {
|
|
8470
8513
|
bundledStrings = [];
|
|
@@ -8506,8 +8549,9 @@
|
|
|
8506
8549
|
}
|
|
8507
8550
|
if (hasSharedUpdate)
|
|
8508
8551
|
hasSharedUpdate = false;
|
|
8552
|
+
let encodingError;
|
|
8509
8553
|
try {
|
|
8510
|
-
if (packr.randomAccessStructure && value.constructor && value.constructor === Object)
|
|
8554
|
+
if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
|
|
8511
8555
|
writeStruct(value);
|
|
8512
8556
|
else
|
|
8513
8557
|
pack(value);
|
|
@@ -8556,42 +8600,51 @@
|
|
|
8556
8600
|
return target
|
|
8557
8601
|
}
|
|
8558
8602
|
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
8603
|
+
} catch(error) {
|
|
8604
|
+
encodingError = error;
|
|
8605
|
+
throw error;
|
|
8559
8606
|
} finally {
|
|
8560
8607
|
if (structures) {
|
|
8561
|
-
|
|
8562
|
-
serializationsSinceTransitionRebuild++;
|
|
8563
|
-
let sharedLength = structures.sharedLength || 0;
|
|
8564
|
-
if (structures.length > sharedLength)
|
|
8565
|
-
structures.length = sharedLength;
|
|
8566
|
-
if (transitionsCount > 10000) {
|
|
8567
|
-
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
8568
|
-
structures.transitions = null;
|
|
8569
|
-
serializationsSinceTransitionRebuild = 0;
|
|
8570
|
-
transitionsCount = 0;
|
|
8571
|
-
if (recordIdsToRemove.length > 0)
|
|
8572
|
-
recordIdsToRemove = [];
|
|
8573
|
-
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
8574
|
-
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
8575
|
-
recordIdsToRemove[i][RECORD_SYMBOL] = 0;
|
|
8576
|
-
}
|
|
8577
|
-
recordIdsToRemove = [];
|
|
8578
|
-
}
|
|
8608
|
+
resetStructures();
|
|
8579
8609
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
8610
|
+
let sharedLength = structures.sharedLength || 0;
|
|
8580
8611
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
8581
8612
|
let returnBuffer = target.subarray(start, position);
|
|
8582
8613
|
let newSharedData = prepareStructures(structures, packr);
|
|
8583
|
-
if (
|
|
8584
|
-
|
|
8585
|
-
|
|
8614
|
+
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
|
|
8615
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
8616
|
+
// get updated structures and try again if the update failed
|
|
8617
|
+
return packr.pack(value, encodeOptions)
|
|
8618
|
+
}
|
|
8619
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
8620
|
+
return returnBuffer
|
|
8586
8621
|
}
|
|
8587
|
-
packr.lastNamedStructuresLength = sharedLength;
|
|
8588
|
-
return returnBuffer
|
|
8589
8622
|
}
|
|
8590
8623
|
}
|
|
8591
8624
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
8592
8625
|
position = start;
|
|
8593
8626
|
}
|
|
8594
8627
|
};
|
|
8628
|
+
const resetStructures = () => {
|
|
8629
|
+
if (serializationsSinceTransitionRebuild < 10)
|
|
8630
|
+
serializationsSinceTransitionRebuild++;
|
|
8631
|
+
let sharedLength = structures.sharedLength || 0;
|
|
8632
|
+
if (structures.length > sharedLength && !isSequential)
|
|
8633
|
+
structures.length = sharedLength;
|
|
8634
|
+
if (transitionsCount > 10000) {
|
|
8635
|
+
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
8636
|
+
structures.transitions = null;
|
|
8637
|
+
serializationsSinceTransitionRebuild = 0;
|
|
8638
|
+
transitionsCount = 0;
|
|
8639
|
+
if (recordIdsToRemove.length > 0)
|
|
8640
|
+
recordIdsToRemove = [];
|
|
8641
|
+
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
8642
|
+
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
8643
|
+
recordIdsToRemove[i][RECORD_SYMBOL] = 0;
|
|
8644
|
+
}
|
|
8645
|
+
recordIdsToRemove = [];
|
|
8646
|
+
}
|
|
8647
|
+
};
|
|
8595
8648
|
const packArray = (value) => {
|
|
8596
8649
|
var length = value.length;
|
|
8597
8650
|
if (length < 0x10) {
|
|
@@ -8769,7 +8822,7 @@
|
|
|
8769
8822
|
targetView.setFloat64(position, value);
|
|
8770
8823
|
position += 8;
|
|
8771
8824
|
}
|
|
8772
|
-
} else if (type === 'object') {
|
|
8825
|
+
} else if (type === 'object' || type === 'function') {
|
|
8773
8826
|
if (!value)
|
|
8774
8827
|
target[position++] = 0xc0;
|
|
8775
8828
|
else {
|
|
@@ -8794,21 +8847,24 @@
|
|
|
8794
8847
|
} else if (constructor === Array) {
|
|
8795
8848
|
packArray(value);
|
|
8796
8849
|
} else if (constructor === Map) {
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8850
|
+
if (this.mapAsEmptyObject) target[position++] = 0x80;
|
|
8851
|
+
else {
|
|
8852
|
+
length = value.size;
|
|
8853
|
+
if (length < 0x10) {
|
|
8854
|
+
target[position++] = 0x80 | length;
|
|
8855
|
+
} else if (length < 0x10000) {
|
|
8856
|
+
target[position++] = 0xde;
|
|
8857
|
+
target[position++] = length >> 8;
|
|
8858
|
+
target[position++] = length & 0xff;
|
|
8859
|
+
} else {
|
|
8860
|
+
target[position++] = 0xdf;
|
|
8861
|
+
targetView.setUint32(position, length);
|
|
8862
|
+
position += 4;
|
|
8863
|
+
}
|
|
8864
|
+
for (let [key, entryValue] of value) {
|
|
8865
|
+
pack(key);
|
|
8866
|
+
pack(entryValue);
|
|
8867
|
+
}
|
|
8812
8868
|
}
|
|
8813
8869
|
} else {
|
|
8814
8870
|
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
@@ -8871,6 +8927,18 @@
|
|
|
8871
8927
|
if (Array.isArray(value)) {
|
|
8872
8928
|
packArray(value);
|
|
8873
8929
|
} else {
|
|
8930
|
+
// use this as an alternate mechanism for expressing how to serialize
|
|
8931
|
+
if (value.toJSON) {
|
|
8932
|
+
const json = value.toJSON();
|
|
8933
|
+
// if for some reason value.toJSON returns itself it'll loop forever
|
|
8934
|
+
if (json !== value)
|
|
8935
|
+
return pack(json)
|
|
8936
|
+
}
|
|
8937
|
+
|
|
8938
|
+
// if there is a writeFunction, use it, otherwise just encode as undefined
|
|
8939
|
+
if (type === 'function')
|
|
8940
|
+
return pack(this.writeFunction && this.writeFunction(value));
|
|
8941
|
+
|
|
8874
8942
|
// no extension found, write as object
|
|
8875
8943
|
writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
|
|
8876
8944
|
}
|
|
@@ -8892,8 +8960,26 @@
|
|
|
8892
8960
|
if (this.largeBigIntToFloat) {
|
|
8893
8961
|
target[position++] = 0xcb;
|
|
8894
8962
|
targetView.setFloat64(position, Number(value));
|
|
8963
|
+
} else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
|
|
8964
|
+
target[position++] = 0xc7;
|
|
8965
|
+
position++;
|
|
8966
|
+
target[position++] = 0x42; // "B" for BigInt
|
|
8967
|
+
let bytes = [];
|
|
8968
|
+
let alignedSign;
|
|
8969
|
+
do {
|
|
8970
|
+
let byte = value & 0xffn;
|
|
8971
|
+
alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
|
|
8972
|
+
bytes.push(byte);
|
|
8973
|
+
value >>= 8n;
|
|
8974
|
+
} while (!((value === 0n || value === -1n) && alignedSign));
|
|
8975
|
+
target[position-2] = bytes.length;
|
|
8976
|
+
for (let i = bytes.length; i > 0;) {
|
|
8977
|
+
target[position++] = Number(bytes[--i]);
|
|
8978
|
+
}
|
|
8979
|
+
return
|
|
8895
8980
|
} else {
|
|
8896
|
-
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format,
|
|
8981
|
+
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
8982
|
+
' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
|
|
8897
8983
|
}
|
|
8898
8984
|
}
|
|
8899
8985
|
position += 8;
|
|
@@ -8905,14 +8991,12 @@
|
|
|
8905
8991
|
target[position++] = 0;
|
|
8906
8992
|
target[position++] = 0;
|
|
8907
8993
|
}
|
|
8908
|
-
} else if (type === 'function') {
|
|
8909
|
-
pack(this.writeFunction && this.writeFunction()); // if there is a writeFunction, use it, otherwise just encode as undefined
|
|
8910
8994
|
} else {
|
|
8911
8995
|
throw new Error('Unknown type: ' + type)
|
|
8912
8996
|
}
|
|
8913
8997
|
};
|
|
8914
8998
|
|
|
8915
|
-
const
|
|
8999
|
+
const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber) ? (object) => {
|
|
8916
9000
|
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
8917
9001
|
let keys = Object.keys(object);
|
|
8918
9002
|
let length = keys.length;
|
|
@@ -8928,9 +9012,19 @@
|
|
|
8928
9012
|
position += 4;
|
|
8929
9013
|
}
|
|
8930
9014
|
let key;
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
9015
|
+
if (this.coercibleKeyAsNumber) {
|
|
9016
|
+
for (let i = 0; i < length; i++) {
|
|
9017
|
+
key = keys[i];
|
|
9018
|
+
let num = Number(key);
|
|
9019
|
+
pack(isNaN(num) ? key : num);
|
|
9020
|
+
pack(object[key]);
|
|
9021
|
+
}
|
|
9022
|
+
|
|
9023
|
+
} else {
|
|
9024
|
+
for (let i = 0; i < length; i++) {
|
|
9025
|
+
pack(key = keys[i]);
|
|
9026
|
+
pack(object[key]);
|
|
9027
|
+
}
|
|
8934
9028
|
}
|
|
8935
9029
|
} :
|
|
8936
9030
|
(object, safePrototype) => {
|
|
@@ -8947,7 +9041,9 @@
|
|
|
8947
9041
|
}
|
|
8948
9042
|
target[objectOffset++ + start] = size >> 8;
|
|
8949
9043
|
target[objectOffset + start] = size & 0xff;
|
|
8950
|
-
}
|
|
9044
|
+
};
|
|
9045
|
+
|
|
9046
|
+
const writeRecord = this.useRecords === false ? writePlainObject :
|
|
8951
9047
|
(options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
|
|
8952
9048
|
(object, safePrototype) => {
|
|
8953
9049
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
@@ -9016,9 +9112,18 @@
|
|
|
9016
9112
|
}
|
|
9017
9113
|
// now write the values
|
|
9018
9114
|
for (let key in object)
|
|
9019
|
-
if (safePrototype || object.hasOwnProperty(key))
|
|
9115
|
+
if (safePrototype || object.hasOwnProperty(key)) {
|
|
9020
9116
|
pack(object[key]);
|
|
9117
|
+
}
|
|
9021
9118
|
};
|
|
9119
|
+
|
|
9120
|
+
// craete reference to useRecords if useRecords is a function
|
|
9121
|
+
const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
|
|
9122
|
+
|
|
9123
|
+
const writeObject = checkUseRecords ? (object, safePrototype) => {
|
|
9124
|
+
checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
|
|
9125
|
+
} : writeRecord;
|
|
9126
|
+
|
|
9022
9127
|
const makeRoom = (end) => {
|
|
9023
9128
|
let newSize;
|
|
9024
9129
|
if (end > 0x1000000) {
|
|
@@ -9122,12 +9227,13 @@
|
|
|
9122
9227
|
}
|
|
9123
9228
|
};
|
|
9124
9229
|
const writeStruct = (object, safePrototype) => {
|
|
9125
|
-
let newPosition = writeStructSlots(object, target, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
9230
|
+
let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
9126
9231
|
if (notifySharedUpdate)
|
|
9127
9232
|
return hasSharedUpdate = true;
|
|
9128
9233
|
position = newPosition;
|
|
9129
9234
|
let startTarget = target;
|
|
9130
9235
|
pack(value);
|
|
9236
|
+
resetStructures();
|
|
9131
9237
|
if (startTarget !== target) {
|
|
9132
9238
|
return { position, targetView, target }; // indicate the buffer was re-allocated
|
|
9133
9239
|
}
|
|
@@ -9191,6 +9297,10 @@
|
|
|
9191
9297
|
}
|
|
9192
9298
|
}, {
|
|
9193
9299
|
pack(set, allocateForWrite, pack) {
|
|
9300
|
+
if (this.setAsEmptyObject) {
|
|
9301
|
+
allocateForWrite(0);
|
|
9302
|
+
return pack({})
|
|
9303
|
+
}
|
|
9194
9304
|
let array = Array.from(set);
|
|
9195
9305
|
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
|
|
9196
9306
|
if (this.moreTypes) {
|
|
@@ -9371,6 +9481,7 @@
|
|
|
9371
9481
|
defaultPackr.pack;
|
|
9372
9482
|
const REUSE_BUFFER_MODE = 512;
|
|
9373
9483
|
const RESET_BUFFER_MODE = 1024;
|
|
9484
|
+
const RESERVE_START_SPACE = 2048;
|
|
9374
9485
|
|
|
9375
9486
|
// DEFLATE is a complex format; to read this code, you should probably check the RFC first:
|
|
9376
9487
|
// https://tools.ietf.org/html/rfc1951
|
|
@@ -14726,6 +14837,9 @@
|
|
|
14726
14837
|
bounds: function() {
|
|
14727
14838
|
return shapeBounds().toArray();
|
|
14728
14839
|
},
|
|
14840
|
+
bbox: function() {
|
|
14841
|
+
return shapeBounds().toArray();
|
|
14842
|
+
},
|
|
14729
14843
|
height: function() {
|
|
14730
14844
|
return shapeBounds().height();
|
|
14731
14845
|
},
|
|
@@ -17323,9 +17437,10 @@
|
|
|
17323
17437
|
}
|
|
17324
17438
|
|
|
17325
17439
|
function getGapRemovalMessage(removed, retained, areaLabel) {
|
|
17440
|
+
var tot = removed + retained;
|
|
17326
17441
|
if (removed > 0 === false) return '';
|
|
17327
|
-
return utils.format('Removed %,d
|
|
17328
|
-
removed,
|
|
17442
|
+
return utils.format('Removed %,d of %,d sliver%s using %s',
|
|
17443
|
+
removed, tot, utils.pluralSuffix(tot), areaLabel);
|
|
17329
17444
|
}
|
|
17330
17445
|
|
|
17331
17446
|
function dissolvePolygonGroups2(groups, lyr, dataset, opts) {
|
|
@@ -19274,12 +19389,12 @@
|
|
|
19274
19389
|
// Kludge for applying fill and other styles to a <text> element
|
|
19275
19390
|
// (for rendering labels in the GUI with the dot in Canvas, not SVG)
|
|
19276
19391
|
function renderStyledLabel(rec) {
|
|
19277
|
-
var o = renderLabel(rec);
|
|
19392
|
+
var o = renderLabel$1(rec);
|
|
19278
19393
|
applyStyleAttributes(o, 'label', rec);
|
|
19279
19394
|
return o;
|
|
19280
19395
|
}
|
|
19281
19396
|
|
|
19282
|
-
function renderLabel(rec) {
|
|
19397
|
+
function renderLabel$1(rec) {
|
|
19283
19398
|
var line = toLabelString(rec['label-text']);
|
|
19284
19399
|
var morelines, obj;
|
|
19285
19400
|
// Accepting \n (two chars) as an alternative to the newline character
|
|
@@ -19324,7 +19439,7 @@
|
|
|
19324
19439
|
var SvgLabels = /*#__PURE__*/Object.freeze({
|
|
19325
19440
|
__proto__: null,
|
|
19326
19441
|
renderStyledLabel: renderStyledLabel,
|
|
19327
|
-
renderLabel: renderLabel
|
|
19442
|
+
renderLabel: renderLabel$1
|
|
19328
19443
|
});
|
|
19329
19444
|
|
|
19330
19445
|
// convert data records (properties like svg-symbol, label-text, fill, r) to svg symbols
|
|
@@ -19536,13 +19651,64 @@
|
|
|
19536
19651
|
};
|
|
19537
19652
|
}
|
|
19538
19653
|
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19654
|
+
function renderScalebar(d, frame) {
|
|
19655
|
+
if (!frame.crs) {
|
|
19656
|
+
message('Unable to render scalebar: unknown CRS.');
|
|
19657
|
+
return [];
|
|
19658
|
+
}
|
|
19659
|
+
if (frame.width > 0 === false) {
|
|
19660
|
+
return [];
|
|
19661
|
+
}
|
|
19662
|
+
|
|
19663
|
+
var opts = getScalebarOpts(d);
|
|
19664
|
+
var metersPerPx = getMapFrameMetersPerPixel(frame);
|
|
19665
|
+
var frameWidthPx = frame.width;
|
|
19666
|
+
var labels = d.label ? d.label.split(',') : null;
|
|
19667
|
+
var label1 = labels && labels[0] || null;
|
|
19668
|
+
var props1 = parseScalebarLabel(label1 || getAutoScalebarLabel(frameWidthPx, metersPerPx, 'mile'));
|
|
19669
|
+
var label2 = opts.style == 'b' && labels && labels[1] || null;
|
|
19670
|
+
var props2, length2;
|
|
19671
|
+
|
|
19672
|
+
if (props1.km > 0 === false) {
|
|
19673
|
+
message('Unusable scalebar label:', label1);
|
|
19674
|
+
return [];
|
|
19675
|
+
}
|
|
19676
|
+
|
|
19677
|
+
var length1 = Math.round(props1.km / metersPerPx * 1000);
|
|
19678
|
+
if (length1 > 0 === false) {
|
|
19679
|
+
stop("Null scalebar length");
|
|
19680
|
+
}
|
|
19681
|
+
|
|
19682
|
+
if (label2) {
|
|
19683
|
+
props2 = parseScalebarLabel(label2);
|
|
19684
|
+
length2 = Math.round(props2.km / metersPerPx * 1000);
|
|
19685
|
+
if (length2 > length1) {
|
|
19686
|
+
stop("First part of a dual-unit scalebar must be longer than the second part.");
|
|
19687
|
+
}
|
|
19688
|
+
}
|
|
19689
|
+
|
|
19690
|
+
var barPos = getScalebarPosition(opts);
|
|
19691
|
+
var labelPos = getLabelPosition(opts);
|
|
19692
|
+
var dx = barPos.xpos == 'right' ? frameWidthPx - length1 - opts.margin : opts.margin;
|
|
19693
|
+
var dy = barPos.ypos == 'bottom' ? frame.height - opts.margin : opts.margin;
|
|
19694
|
+
|
|
19695
|
+
// vshift to adjust for height above or below the baseline
|
|
19696
|
+
var labelHeight = Math.round(opts.label_offset + opts.tic_length + opts.font_size * 0.8 + opts.bar_width / 2);
|
|
19697
|
+
var bareHeight = Math.round(opts.bar_width / 2);
|
|
19698
|
+
var topHeight = labelPos.ypos == 'top' || label2 ? labelHeight : bareHeight;
|
|
19699
|
+
var bottomHeight = labelPos.ypos == 'bottom' || label2 ? labelHeight : bareHeight;
|
|
19700
|
+
if (barPos.ypos == 'top') {
|
|
19701
|
+
dy += topHeight;
|
|
19702
|
+
} else {
|
|
19703
|
+
dy -= bottomHeight;
|
|
19704
|
+
}
|
|
19705
|
+
|
|
19706
|
+
var g = renderAsSvg(length1, label1, length2, label2, opts);
|
|
19707
|
+
g.properties = {
|
|
19708
|
+
transform: 'translate(' + dx + ' ' + dy + ')'
|
|
19545
19709
|
};
|
|
19710
|
+
|
|
19711
|
+
return [g];
|
|
19546
19712
|
}
|
|
19547
19713
|
|
|
19548
19714
|
var styleOpts = {
|
|
@@ -19569,105 +19735,112 @@
|
|
|
19569
19735
|
return Object.assign({}, defaultOpts, styleOpts[style], d, {style: style});
|
|
19570
19736
|
}
|
|
19571
19737
|
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19738
|
+
function renderAsSvg(length, text, length2, text2, opts) {
|
|
19739
|
+
var labelPart = renderLabel(text, length, opts);
|
|
19740
|
+
var zeroLabelPart = renderLabel('0', length, Object.assign({flipx: true}, opts));
|
|
19741
|
+
var barPart = renderBar(length, length2, opts);
|
|
19742
|
+
var parts = opts.style == 'b' ? [zeroLabelPart, labelPart, barPart] : [labelPart, barPart];
|
|
19743
|
+
if (text2) {
|
|
19744
|
+
parts.push(renderLabel(text2, length2, Object.assign({flipy: true}, opts)));
|
|
19745
|
+
parts.push(renderLabel('0', length2, Object.assign({flipx: true, flipy: true}, opts)));
|
|
19746
|
+
}
|
|
19747
|
+
return {
|
|
19748
|
+
tag: 'g',
|
|
19749
|
+
children: parts
|
|
19750
|
+
};
|
|
19576
19751
|
}
|
|
19577
19752
|
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
var
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19753
|
+
// TODO: generalize to other kinds of furniture as they are developed
|
|
19754
|
+
function getScalebarPosition(opts) {
|
|
19755
|
+
var pos = opts.position || 'top-left';
|
|
19756
|
+
return {
|
|
19757
|
+
ypos: pos.includes('top') ? 'top' : 'bottom',
|
|
19758
|
+
xpos: pos.includes('left') ? 'left' : 'right'
|
|
19759
|
+
};
|
|
19760
|
+
}
|
|
19761
|
+
|
|
19762
|
+
function renderLabel(text, length, opts) {
|
|
19763
|
+
var labelPos = getLabelPosition(opts);
|
|
19764
|
+
var anchorX = length * labelPos.kx + labelPos.dx;
|
|
19765
|
+
var bottomLabelY = opts.bar_width + opts.tic_length + opts.label_offset;
|
|
19766
|
+
var topLabelY = -opts.label_offset - opts.tic_length;
|
|
19767
|
+
var anchorY = labelPos.ypos == 'top' ? topLabelY : bottomLabelY;
|
|
19587
19768
|
var labelOpts = {
|
|
19588
19769
|
'label-text': text,
|
|
19589
19770
|
'font-size': opts.font_size,
|
|
19590
|
-
'text-anchor':
|
|
19591
|
-
'dominant-baseline':
|
|
19771
|
+
'text-anchor': labelPos.anchor,
|
|
19772
|
+
'dominant-baseline': labelPos.ypos == 'top' ? 'auto' : 'hanging'
|
|
19592
19773
|
//// 'dominant-baseline': labelPos == 'top' ? 'text-after-edge' : 'text-before-edge'
|
|
19593
19774
|
// 'text-after-edge' is buggy in Safari and unsupported by Illustrator,
|
|
19594
19775
|
// so I'm using 'hanging' and 'auto', which seem to be well supported.
|
|
19595
19776
|
// downside: requires a kludgy multiplier to calculate scalebar height (see above)
|
|
19596
19777
|
};
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
var zeroLabel = symbolRenderers.label(zeroOpts, -xOff, anchorY);
|
|
19778
|
+
return symbolRenderers.label(labelOpts, anchorX, anchorY);
|
|
19779
|
+
}
|
|
19600
19780
|
|
|
19601
|
-
|
|
19602
|
-
var
|
|
19603
|
-
var
|
|
19604
|
-
var
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
if (opts.tic_length > 0) {
|
|
19609
|
-
coords = [[0, y2], [0, y], [length, y], [length, y2]];
|
|
19781
|
+
function getLabelPosition(opts) {
|
|
19782
|
+
var pos = opts.label_position;
|
|
19783
|
+
var ypos = pos.includes('bottom') && 'bottom' || 'top';
|
|
19784
|
+
var dx = 0;
|
|
19785
|
+
var xpos;
|
|
19786
|
+
if (opts.style == 'a') {
|
|
19787
|
+
xpos = pos.includes('center') && 'center' || pos.includes('right') && 'right' || 'left';
|
|
19610
19788
|
} else {
|
|
19611
|
-
|
|
19789
|
+
xpos = 'right'; // style b
|
|
19790
|
+
}
|
|
19791
|
+
if (opts.flipx) {
|
|
19792
|
+
xpos = xpos == 'left' && 'right' || xpos == 'right' && 'left' || xpos;
|
|
19793
|
+
}
|
|
19794
|
+
if (opts.flipy) {
|
|
19795
|
+
ypos = ypos == 'top' && 'bottom' || ypos == 'bottom' && 'top' || ypos;
|
|
19796
|
+
}
|
|
19797
|
+
if (opts.style == 'b') {
|
|
19798
|
+
dx = xpos == 'left' && -opts.font_size / 4 || xpos == 'right' && opts.font_size / 4 || 0;
|
|
19612
19799
|
}
|
|
19613
|
-
var barPart = importLineString(coords);
|
|
19614
|
-
Object.assign(barPart.properties, {
|
|
19615
|
-
stroke: 'black',
|
|
19616
|
-
fill: 'none',
|
|
19617
|
-
'stroke-width': opts.bar_width,
|
|
19618
|
-
'stroke-linecap': 'butt',
|
|
19619
|
-
'stroke-linejoin': 'miter'
|
|
19620
|
-
});
|
|
19621
|
-
var parts = opts.style == 'b' ? [zeroLabel, labelPart, barPart] : [labelPart, barPart];
|
|
19622
19800
|
return {
|
|
19623
|
-
|
|
19624
|
-
|
|
19801
|
+
xpos,
|
|
19802
|
+
ypos,
|
|
19803
|
+
dx,
|
|
19804
|
+
kx: xpos == 'right' && 1 || xpos == 'center' && 0.5 || 0,
|
|
19805
|
+
anchor: xpos == 'center' && 'middle' || xpos == 'left' && 'start' || 'end'
|
|
19625
19806
|
};
|
|
19626
19807
|
}
|
|
19627
19808
|
|
|
19628
|
-
|
|
19629
|
-
|
|
19630
|
-
|
|
19631
|
-
|
|
19632
|
-
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
var opts = getScalebarOpts(d);
|
|
19638
|
-
var metersPerPx = getMapFrameMetersPerPixel(frame);
|
|
19639
|
-
var frameWidthPx = frame.width;
|
|
19640
|
-
var unit = d.label ? parseScalebarUnits(d.label) : 'mile';
|
|
19641
|
-
var number = d.label ? parseScalebarNumber(d.label) : null;
|
|
19642
|
-
var label = number && unit ? d.label : getAutoScalebarLabel(frameWidthPx, metersPerPx, unit);
|
|
19643
|
-
|
|
19644
|
-
var scalebarKm = parseScalebarLabelToKm(label);
|
|
19645
|
-
if (scalebarKm > 0 === false) {
|
|
19646
|
-
message('Unusable scalebar label:', label);
|
|
19647
|
-
return [];
|
|
19809
|
+
// length1: length of main bar
|
|
19810
|
+
// length2: length of optional second distance (assumes that length2 <= length1)
|
|
19811
|
+
function getStyleBCoords(length1, length2, opts) {
|
|
19812
|
+
var coords = [];
|
|
19813
|
+
var labelPos = getLabelPosition(opts);
|
|
19814
|
+
var y = opts.tic_length + opts.bar_width / 2;
|
|
19815
|
+
if (labelPos.ypos == "top") {
|
|
19816
|
+
y = -y;
|
|
19648
19817
|
}
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
|
|
19818
|
+
coords.push([[0, y], [0, 0], [length1, 0], [length1, y]]);
|
|
19819
|
+
if (length2 > 0) {
|
|
19820
|
+
coords.push([[0, 0], [0, -y]]);
|
|
19821
|
+
coords.push([[length2, 0], [length2, -y]]);
|
|
19653
19822
|
}
|
|
19823
|
+
return coords;
|
|
19824
|
+
}
|
|
19654
19825
|
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
var
|
|
19659
|
-
if (opts.
|
|
19660
|
-
|
|
19826
|
+
// length: length of scale bar in px
|
|
19827
|
+
// length2: length of optional dual-units portion of the scalebar
|
|
19828
|
+
function renderBar(length, length2, opts) {
|
|
19829
|
+
var coords;
|
|
19830
|
+
if (opts.style == 'b') {
|
|
19831
|
+
coords = getStyleBCoords(length, length2, opts);
|
|
19661
19832
|
} else {
|
|
19662
|
-
|
|
19833
|
+
coords = [[[0, 0], [length, 0]]];
|
|
19663
19834
|
}
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19668
|
-
|
|
19669
|
-
|
|
19670
|
-
|
|
19835
|
+
var bar = importMultiLineString(coords);
|
|
19836
|
+
Object.assign(bar.properties, {
|
|
19837
|
+
stroke: 'black',
|
|
19838
|
+
fill: 'none',
|
|
19839
|
+
'stroke-width': opts.bar_width,
|
|
19840
|
+
'stroke-linecap': 'butt',
|
|
19841
|
+
'stroke-linejoin': 'miter'
|
|
19842
|
+
});
|
|
19843
|
+
return bar;
|
|
19671
19844
|
}
|
|
19672
19845
|
|
|
19673
19846
|
// unit: 'km' || 'mile'
|
|
@@ -19701,6 +19874,20 @@
|
|
|
19701
19874
|
return units == 'mile' ? value * 1.60934 : value;
|
|
19702
19875
|
}
|
|
19703
19876
|
|
|
19877
|
+
function parseScalebarLabel(label) {
|
|
19878
|
+
var num = label ? parseScalebarNumber(label) : null;
|
|
19879
|
+
var units = label ? parseScalebarUnits(label) : 'mile';
|
|
19880
|
+
var km = NaN;
|
|
19881
|
+
if (units && num) {
|
|
19882
|
+
km = units == 'mile' ? num * 1.60934 : num;
|
|
19883
|
+
}
|
|
19884
|
+
return {
|
|
19885
|
+
number: num,
|
|
19886
|
+
units: units,
|
|
19887
|
+
km: km
|
|
19888
|
+
};
|
|
19889
|
+
}
|
|
19890
|
+
|
|
19704
19891
|
function parseScalebarUnits(str) {
|
|
19705
19892
|
var isMiles = /miles?$/.test(str.toLowerCase());
|
|
19706
19893
|
var isKm = /(k\.m\.|km|kilometers?|kilometres?)$/.test(str.toLowerCase());
|
|
@@ -25821,7 +26008,11 @@ ${svg}
|
|
|
25821
26008
|
describe: 'e.g. bottom-right (default is top-left)'
|
|
25822
26009
|
})
|
|
25823
26010
|
.option('label-position', {
|
|
25824
|
-
describe: 'top
|
|
26011
|
+
describe: 'top, bottom, top-center (style a), etc'
|
|
26012
|
+
})
|
|
26013
|
+
.option('dual-units', {
|
|
26014
|
+
// describe: 'display both metric and imperial units',
|
|
26015
|
+
type: 'flag'
|
|
25825
26016
|
})
|
|
25826
26017
|
.option('margin', {
|
|
25827
26018
|
describe: 'offset in pixels from edge of map',
|
|
@@ -45224,7 +45415,7 @@ ${svg}
|
|
|
45224
45415
|
});
|
|
45225
45416
|
}
|
|
45226
45417
|
|
|
45227
|
-
var version = "0.6.
|
|
45418
|
+
var version = "0.6.69";
|
|
45228
45419
|
|
|
45229
45420
|
// Parse command line args into commands and run them
|
|
45230
45421
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|