mapshaper 0.7.45 → 0.7.46
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 +777 -367
- package/package.json +1 -1
- package/www/mapshaper-gui.js +147 -104
- package/www/mapshaper.js +777 -367
- package/www/page.css +33 -3
package/mapshaper.js
CHANGED
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
return obj === Object(obj); // via underscore
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
function clamp$
|
|
81
|
+
function clamp$4(val, min, max) {
|
|
82
82
|
return val < min ? min : (val > max ? max : val);
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -261,36 +261,6 @@
|
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
// Call @iter on each member of an array (similar to Array#reduce(iter))
|
|
265
|
-
// iter: function(memo, item, callback)
|
|
266
|
-
// Call @done when all members have been processed or if an error occurs
|
|
267
|
-
// done: function(err, memo)
|
|
268
|
-
// @memo: Initial value
|
|
269
|
-
//
|
|
270
|
-
function reduceAsync(arr, memo, iter, done) {
|
|
271
|
-
var call = typeof setImmediate == 'undefined' ? setTimeout : setImmediate;
|
|
272
|
-
var i=0;
|
|
273
|
-
next(null, memo);
|
|
274
|
-
|
|
275
|
-
function next(err, memo) {
|
|
276
|
-
// Detach next operation from call stack to prevent overflow
|
|
277
|
-
// Don't use setTimeout(, 0) if setImmediate is available
|
|
278
|
-
// (setTimeout() can introduce a long delay if previous operation was slow,
|
|
279
|
-
// as of Node 0.10.32 -- a bug?)
|
|
280
|
-
if (err) {
|
|
281
|
-
return done(err, null);
|
|
282
|
-
}
|
|
283
|
-
call(function() {
|
|
284
|
-
if (i < arr.length === false) {
|
|
285
|
-
done(null, memo);
|
|
286
|
-
} else {
|
|
287
|
-
iter(memo, arr[i++], next);
|
|
288
|
-
}
|
|
289
|
-
}, 0);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
|
|
294
264
|
// Append elements of @src array to @dest array
|
|
295
265
|
function merge$1(dest, src) {
|
|
296
266
|
if (!isArray(dest) || !isArray(src)) {
|
|
@@ -751,7 +721,7 @@
|
|
|
751
721
|
function findValueByRank(arr, rank) {
|
|
752
722
|
if (!arr.length || rank < 1 || rank > arr.length) error$1("[findValueByRank()] invalid input");
|
|
753
723
|
|
|
754
|
-
rank = clamp$
|
|
724
|
+
rank = clamp$4(rank | 0, 1, arr.length);
|
|
755
725
|
var k = rank - 1, // conv. rank to array index
|
|
756
726
|
n = arr.length,
|
|
757
727
|
l = 0,
|
|
@@ -1125,7 +1095,7 @@
|
|
|
1125
1095
|
// self-import and the resulting Rollup circular-dependency warning.
|
|
1126
1096
|
var utils = {
|
|
1127
1097
|
addThousandsSep, addslashes, arrayToIndex,
|
|
1128
|
-
clamp: clamp$
|
|
1098
|
+
clamp: clamp$4, cleanNumericString, contains, copyElements, countValues, createBuffer,
|
|
1129
1099
|
defaults, difference,
|
|
1130
1100
|
endsWith, every, expandoBuffer, extend: extend$1, extendBuffer,
|
|
1131
1101
|
find: find$1, findMedian, findQuantile, findRankByValue, findStringPrefix,
|
|
@@ -1145,7 +1115,7 @@
|
|
|
1145
1115
|
parseIntlNumber, parseNumber: parseNumber$1, parseString, pickOne, pluck,
|
|
1146
1116
|
pluralSuffix, promisify,
|
|
1147
1117
|
quicksort: quicksort$1, quicksortPartition,
|
|
1148
|
-
range,
|
|
1118
|
+
range, regexEscape, reorderArray: reorderArray$1, repeat, repeatString,
|
|
1149
1119
|
replaceArray, rpad, rtrim,
|
|
1150
1120
|
shuffle, some, sortArrayIndex, sortOn, splitLines, sum: sum$1,
|
|
1151
1121
|
toArray: toArray$1, toBuffer, trim, trimQuotes,
|
|
@@ -2083,12 +2053,12 @@
|
|
|
2083
2053
|
// TODO: remove this constant, use actual data from dataset CRS,
|
|
2084
2054
|
// also consider using ellipsoidal formulas where greater accuracy might be important.
|
|
2085
2055
|
var R$3 = WGS84.SEMIMAJOR_AXIS;
|
|
2086
|
-
var D2R$
|
|
2087
|
-
var R2D$
|
|
2056
|
+
var D2R$7 = Math.PI / 180;
|
|
2057
|
+
var R2D$6 = 180 / Math.PI;
|
|
2088
2058
|
|
|
2089
2059
|
// Equirectangular projection
|
|
2090
2060
|
function degreesToMeters(deg) {
|
|
2091
|
-
return deg * D2R$
|
|
2061
|
+
return deg * D2R$7 * R$3;
|
|
2092
2062
|
}
|
|
2093
2063
|
|
|
2094
2064
|
function distance3D(ax, ay, az, bx, by, bz) {
|
|
@@ -2235,16 +2205,16 @@
|
|
|
2235
2205
|
|
|
2236
2206
|
function xyzToLngLat(x, y, z, p) {
|
|
2237
2207
|
var d = distance3D(0, 0, 0, x, y, z); // normalize
|
|
2238
|
-
var lat = Math.asin(z / d) / D2R$
|
|
2239
|
-
var lng = Math.atan2(y / d, x / d) / D2R$
|
|
2208
|
+
var lat = Math.asin(z / d) / D2R$7;
|
|
2209
|
+
var lng = Math.atan2(y / d, x / d) / D2R$7;
|
|
2240
2210
|
p[0] = lng;
|
|
2241
2211
|
p[1] = lat;
|
|
2242
2212
|
}
|
|
2243
2213
|
|
|
2244
2214
|
function lngLatToXYZ(lng, lat, p) {
|
|
2245
2215
|
var cosLat;
|
|
2246
|
-
lng *= D2R$
|
|
2247
|
-
lat *= D2R$
|
|
2216
|
+
lng *= D2R$7;
|
|
2217
|
+
lat *= D2R$7;
|
|
2248
2218
|
cosLat = Math.cos(lat);
|
|
2249
2219
|
p[0] = Math.cos(lng) * cosLat * R$3;
|
|
2250
2220
|
p[1] = Math.sin(lng) * cosLat * R$3;
|
|
@@ -2364,9 +2334,9 @@
|
|
|
2364
2334
|
|
|
2365
2335
|
var Geom = /*#__PURE__*/Object.freeze({
|
|
2366
2336
|
__proto__: null,
|
|
2367
|
-
D2R: D2R$
|
|
2337
|
+
D2R: D2R$7,
|
|
2368
2338
|
R: R$3,
|
|
2369
|
-
R2D: R2D$
|
|
2339
|
+
R2D: R2D$6,
|
|
2370
2340
|
bearing: bearing,
|
|
2371
2341
|
bearing2D: bearing2D,
|
|
2372
2342
|
containsBounds: containsBounds,
|
|
@@ -6294,9 +6264,9 @@
|
|
|
6294
6264
|
* ISC License: https://github.com/d3/d3-geo-polygon/blob/main/LICENSE
|
|
6295
6265
|
*/
|
|
6296
6266
|
|
|
6297
|
-
var D2R$
|
|
6298
|
-
var R2D$
|
|
6299
|
-
var EPS$
|
|
6267
|
+
var D2R$6 = Math.PI / 180;
|
|
6268
|
+
var R2D$5 = 180 / Math.PI;
|
|
6269
|
+
var EPS$2 = 1e-12;
|
|
6300
6270
|
|
|
6301
6271
|
// Build a forward-only spherical polyhedral projection.
|
|
6302
6272
|
//
|
|
@@ -6334,10 +6304,10 @@
|
|
|
6334
6304
|
throw new Error('Invalid polyhedral face tree');
|
|
6335
6305
|
}
|
|
6336
6306
|
var childEdge = shared.map(function(p) {
|
|
6337
|
-
return face.project(p[0] * D2R$
|
|
6307
|
+
return face.project(p[0] * D2R$6, p[1] * D2R$6);
|
|
6338
6308
|
});
|
|
6339
6309
|
var parentEdge = shared.map(function(p) {
|
|
6340
|
-
return parent.project(p[0] * D2R$
|
|
6310
|
+
return parent.project(p[0] * D2R$6, p[1] * D2R$6);
|
|
6341
6311
|
});
|
|
6342
6312
|
face.transform = multiplyMatrices(
|
|
6343
6313
|
parent.transform,
|
|
@@ -6348,12 +6318,12 @@
|
|
|
6348
6318
|
|
|
6349
6319
|
var rootEdge = findLongestEdge(faces[0].coords);
|
|
6350
6320
|
var rootPlanarEdge = rootEdge.map(function(p) {
|
|
6351
|
-
return faces[0].project(p[0] * D2R$
|
|
6321
|
+
return faces[0].project(p[0] * D2R$6, p[1] * D2R$6);
|
|
6352
6322
|
});
|
|
6353
6323
|
var sphericalEdgeLength = angularDistance(rootEdge[0], rootEdge[1]);
|
|
6354
6324
|
var planarEdgeLength = distance2D(rootPlanarEdge[0], rootPlanarEdge[1]);
|
|
6355
6325
|
var scale = sphericalEdgeLength / planarEdgeLength;
|
|
6356
|
-
var planarAngle = (config.angle || 0) * D2R$
|
|
6326
|
+
var planarAngle = (config.angle || 0) * D2R$6;
|
|
6357
6327
|
var edgeIndex = indexEdges(faces, attachedPairs);
|
|
6358
6328
|
var outline = buildOutline(faces, attachedPairs).map(function(ring) {
|
|
6359
6329
|
return ring.map(transformOutputPoint);
|
|
@@ -6383,9 +6353,9 @@
|
|
|
6383
6353
|
var rotated = rotateRadians(
|
|
6384
6354
|
lam,
|
|
6385
6355
|
phi,
|
|
6386
|
-
config.rotation[0] * D2R$
|
|
6387
|
-
config.rotation[1] * D2R$
|
|
6388
|
-
config.rotation[2] * D2R$
|
|
6356
|
+
config.rotation[0] * D2R$6,
|
|
6357
|
+
config.rotation[1] * D2R$6,
|
|
6358
|
+
config.rotation[2] * D2R$6
|
|
6389
6359
|
);
|
|
6390
6360
|
var face = findFaceRotated(rotated[0], rotated[1]);
|
|
6391
6361
|
if (!face) return null;
|
|
@@ -6401,9 +6371,9 @@
|
|
|
6401
6371
|
var rotated = rotateRadians(
|
|
6402
6372
|
lam,
|
|
6403
6373
|
phi,
|
|
6404
|
-
config.rotation[0] * D2R$
|
|
6405
|
-
config.rotation[1] * D2R$
|
|
6406
|
-
config.rotation[2] * D2R$
|
|
6374
|
+
config.rotation[0] * D2R$6,
|
|
6375
|
+
config.rotation[1] * D2R$6,
|
|
6376
|
+
config.rotation[2] * D2R$6
|
|
6407
6377
|
);
|
|
6408
6378
|
var face = findFaceRotated(rotated[0], rotated[1]);
|
|
6409
6379
|
return face ? face.id : -1;
|
|
@@ -6413,9 +6383,9 @@
|
|
|
6413
6383
|
var rotated = rotateRadians(
|
|
6414
6384
|
lam,
|
|
6415
6385
|
phi,
|
|
6416
|
-
config.rotation[0] * D2R$
|
|
6417
|
-
config.rotation[1] * D2R$
|
|
6418
|
-
config.rotation[2] * D2R$
|
|
6386
|
+
config.rotation[0] * D2R$6,
|
|
6387
|
+
config.rotation[1] * D2R$6,
|
|
6388
|
+
config.rotation[2] * D2R$6
|
|
6419
6389
|
);
|
|
6420
6390
|
var face = findFaceRotated(rotated[0], rotated[1]);
|
|
6421
6391
|
var region;
|
|
@@ -6432,7 +6402,7 @@
|
|
|
6432
6402
|
faceId = config.findFace(lam, phi);
|
|
6433
6403
|
return faceId >= 0 ? faces[faceId] : null;
|
|
6434
6404
|
}
|
|
6435
|
-
var p = radiansToVector(lam, phi);
|
|
6405
|
+
var p = radiansToVector$1(lam, phi);
|
|
6436
6406
|
for (var i = 0; i < faces.length; i++) {
|
|
6437
6407
|
if (faceContainsVector(faces[i], p)) return faces[i];
|
|
6438
6408
|
}
|
|
@@ -6457,16 +6427,16 @@
|
|
|
6457
6427
|
var seams = edgeIndex.map(function(edge) {
|
|
6458
6428
|
var endpoints = edge.points.map(function(p) {
|
|
6459
6429
|
var q = rotateRadians(
|
|
6460
|
-
p[0] * D2R$
|
|
6461
|
-
p[1] * D2R$
|
|
6462
|
-
config.rotation[0] * D2R$
|
|
6463
|
-
config.rotation[1] * D2R$
|
|
6464
|
-
config.rotation[2] * D2R$
|
|
6430
|
+
p[0] * D2R$6,
|
|
6431
|
+
p[1] * D2R$6,
|
|
6432
|
+
config.rotation[0] * D2R$6,
|
|
6433
|
+
config.rotation[1] * D2R$6,
|
|
6434
|
+
config.rotation[2] * D2R$6,
|
|
6465
6435
|
true
|
|
6466
6436
|
);
|
|
6467
|
-
return [normalizeLongitude$
|
|
6437
|
+
return [normalizeLongitude$2(q[0] * R2D$5 + lon0), q[1] * R2D$5];
|
|
6468
6438
|
});
|
|
6469
|
-
var paths = splitPathAtAntimeridian$
|
|
6439
|
+
var paths = splitPathAtAntimeridian$2(
|
|
6470
6440
|
interpolateGreatCircle(endpoints[0], endpoints[1], 0.05)
|
|
6471
6441
|
);
|
|
6472
6442
|
paths.forEach(function(path) {
|
|
@@ -6491,12 +6461,12 @@
|
|
|
6491
6461
|
}),
|
|
6492
6462
|
seams: seams,
|
|
6493
6463
|
findRegion: function(lon, lat) {
|
|
6494
|
-
var lam = normalizeLongitude$
|
|
6495
|
-
return findFace(lam, lat * D2R$
|
|
6464
|
+
var lam = normalizeLongitude$2(lon - lon0) * D2R$6;
|
|
6465
|
+
return findFace(lam, lat * D2R$6);
|
|
6496
6466
|
},
|
|
6497
6467
|
findTransitionRegion: function(lon, lat) {
|
|
6498
|
-
var lam = normalizeLongitude$
|
|
6499
|
-
return findTransitionRegion(lam, lat * D2R$
|
|
6468
|
+
var lam = normalizeLongitude$2(lon - lon0) * D2R$6;
|
|
6469
|
+
return findTransitionRegion(lam, lat * D2R$6);
|
|
6500
6470
|
},
|
|
6501
6471
|
regionsAreAttached: function(a, b) {
|
|
6502
6472
|
return regionPairs.get(pairKey(a, b)) === true;
|
|
@@ -6514,9 +6484,9 @@
|
|
|
6514
6484
|
return rotateRadians(
|
|
6515
6485
|
lam,
|
|
6516
6486
|
phi,
|
|
6517
|
-
(rotation[0] || 0) * D2R$
|
|
6518
|
-
(rotation[1] || 0) * D2R$
|
|
6519
|
-
(rotation[2] || 0) * D2R$
|
|
6487
|
+
(rotation[0] || 0) * D2R$6,
|
|
6488
|
+
(rotation[1] || 0) * D2R$6,
|
|
6489
|
+
(rotation[2] || 0) * D2R$6,
|
|
6520
6490
|
invert
|
|
6521
6491
|
);
|
|
6522
6492
|
}
|
|
@@ -6525,7 +6495,7 @@
|
|
|
6525
6495
|
var vectors = coords.map(function(p) {
|
|
6526
6496
|
return degreesToVector$2(p[0], p[1]);
|
|
6527
6497
|
});
|
|
6528
|
-
var inside = normalizeVector$
|
|
6498
|
+
var inside = normalizeVector$2(vectors.reduce(function(sum, p) {
|
|
6529
6499
|
sum[0] += p[0];
|
|
6530
6500
|
sum[1] += p[1];
|
|
6531
6501
|
sum[2] += p[2];
|
|
@@ -6535,10 +6505,10 @@
|
|
|
6535
6505
|
for (var i = 0; i < vectors.length; i++) {
|
|
6536
6506
|
var a = vectors[i];
|
|
6537
6507
|
var b = vectors[(i + 1) % vectors.length];
|
|
6538
|
-
var normal = cross$
|
|
6508
|
+
var normal = cross$2(a, b);
|
|
6539
6509
|
edges.push({
|
|
6540
6510
|
normal: normal,
|
|
6541
|
-
sign: dot$
|
|
6511
|
+
sign: dot$2(normal, inside) < 0 ? -1 : 1
|
|
6542
6512
|
});
|
|
6543
6513
|
}
|
|
6544
6514
|
return {
|
|
@@ -6553,7 +6523,7 @@
|
|
|
6553
6523
|
function faceContainsVector(face, p) {
|
|
6554
6524
|
for (var i = 0; i < face.edges.length; i++) {
|
|
6555
6525
|
var edge = face.edges[i];
|
|
6556
|
-
if (dot$
|
|
6526
|
+
if (dot$2(edge.normal, p) * edge.sign < -EPS$2) return false;
|
|
6557
6527
|
}
|
|
6558
6528
|
return true;
|
|
6559
6529
|
}
|
|
@@ -6589,8 +6559,8 @@
|
|
|
6589
6559
|
var adjacent = findAdjacentFace(faces, face.id, a, b);
|
|
6590
6560
|
if (adjacent >= 0 && attachedPairs.has(pairKey(face.id, adjacent))) continue;
|
|
6591
6561
|
edges.push([
|
|
6592
|
-
applyMatrix(face.transform, face.project(a[0] * D2R$
|
|
6593
|
-
applyMatrix(face.transform, face.project(b[0] * D2R$
|
|
6562
|
+
applyMatrix(face.transform, face.project(a[0] * D2R$6, a[1] * D2R$6)),
|
|
6563
|
+
applyMatrix(face.transform, face.project(b[0] * D2R$6, b[1] * D2R$6))
|
|
6594
6564
|
]);
|
|
6595
6565
|
}
|
|
6596
6566
|
});
|
|
@@ -6717,9 +6687,9 @@
|
|
|
6717
6687
|
function rotateRadians(lam, phi, deltaLam, deltaPhi, deltaGamma, invert) {
|
|
6718
6688
|
if (invert) {
|
|
6719
6689
|
var inv = rotatePhiGamma$1(lam, phi, deltaPhi, deltaGamma, true);
|
|
6720
|
-
return [normalizeRadians$
|
|
6690
|
+
return [normalizeRadians$2(inv[0] - deltaLam), inv[1]];
|
|
6721
6691
|
}
|
|
6722
|
-
lam = normalizeRadians$
|
|
6692
|
+
lam = normalizeRadians$2(lam + deltaLam);
|
|
6723
6693
|
return rotatePhiGamma$1(lam, phi, deltaPhi, deltaGamma, false);
|
|
6724
6694
|
}
|
|
6725
6695
|
|
|
@@ -6739,28 +6709,28 @@
|
|
|
6739
6709
|
return [
|
|
6740
6710
|
Math.atan2(y * cosDeltaGamma + z * sinDeltaGamma,
|
|
6741
6711
|
x * cosDeltaPhi + k * sinDeltaPhi),
|
|
6742
|
-
Math.asin(clamp$
|
|
6712
|
+
Math.asin(clamp$3(k * cosDeltaPhi - x * sinDeltaPhi, -1, 1))
|
|
6743
6713
|
];
|
|
6744
6714
|
}
|
|
6745
6715
|
k = z * cosDeltaPhi + x * sinDeltaPhi;
|
|
6746
6716
|
return [
|
|
6747
6717
|
Math.atan2(y * cosDeltaGamma - k * sinDeltaGamma,
|
|
6748
6718
|
x * cosDeltaPhi - z * sinDeltaPhi),
|
|
6749
|
-
Math.asin(clamp$
|
|
6719
|
+
Math.asin(clamp$3(k * cosDeltaGamma + y * sinDeltaGamma, -1, 1))
|
|
6750
6720
|
];
|
|
6751
6721
|
}
|
|
6752
6722
|
|
|
6753
6723
|
function interpolateGreatCircle(a, b, interval) {
|
|
6754
6724
|
var av = degreesToVector$2(a[0], a[1]);
|
|
6755
6725
|
var bv = degreesToVector$2(b[0], b[1]);
|
|
6756
|
-
var angle = Math.acos(clamp$
|
|
6757
|
-
var n = Math.max(1, Math.ceil(angle * R2D$
|
|
6726
|
+
var angle = Math.acos(clamp$3(dot$2(av, bv), -1, 1));
|
|
6727
|
+
var n = Math.max(1, Math.ceil(angle * R2D$5 / interval));
|
|
6758
6728
|
var sinAngle = Math.sin(angle);
|
|
6759
6729
|
var points = [];
|
|
6760
6730
|
for (var i = 0; i <= n; i++) {
|
|
6761
6731
|
var t = i / n;
|
|
6762
6732
|
var p;
|
|
6763
|
-
if (sinAngle < EPS$
|
|
6733
|
+
if (sinAngle < EPS$2) {
|
|
6764
6734
|
p = av;
|
|
6765
6735
|
} else {
|
|
6766
6736
|
var ka = Math.sin((1 - t) * angle) / sinAngle;
|
|
@@ -6771,12 +6741,12 @@
|
|
|
6771
6741
|
av[2] * ka + bv[2] * kb
|
|
6772
6742
|
];
|
|
6773
6743
|
}
|
|
6774
|
-
points.push(vectorToDegrees$2(normalizeVector$
|
|
6744
|
+
points.push(vectorToDegrees$2(normalizeVector$2(p)));
|
|
6775
6745
|
}
|
|
6776
6746
|
return points;
|
|
6777
6747
|
}
|
|
6778
6748
|
|
|
6779
|
-
function splitPathAtAntimeridian$
|
|
6749
|
+
function splitPathAtAntimeridian$2(path) {
|
|
6780
6750
|
var paths = [];
|
|
6781
6751
|
var part = [path[0]];
|
|
6782
6752
|
for (var i = 1; i < path.length; i++) {
|
|
@@ -6812,32 +6782,32 @@
|
|
|
6812
6782
|
}
|
|
6813
6783
|
|
|
6814
6784
|
function angularDistance(a, b) {
|
|
6815
|
-
return Math.acos(clamp$
|
|
6785
|
+
return Math.acos(clamp$3(dot$2(degreesToVector$2(a[0], a[1]),
|
|
6816
6786
|
degreesToVector$2(b[0], b[1])), -1, 1));
|
|
6817
6787
|
}
|
|
6818
6788
|
|
|
6819
6789
|
function degreesToVector$2(lon, lat) {
|
|
6820
|
-
return radiansToVector(lon * D2R$
|
|
6790
|
+
return radiansToVector$1(lon * D2R$6, lat * D2R$6);
|
|
6821
6791
|
}
|
|
6822
6792
|
|
|
6823
|
-
function radiansToVector(lam, phi) {
|
|
6793
|
+
function radiansToVector$1(lam, phi) {
|
|
6824
6794
|
var cosPhi = Math.cos(phi);
|
|
6825
6795
|
return [Math.cos(lam) * cosPhi, Math.sin(lam) * cosPhi, Math.sin(phi)];
|
|
6826
6796
|
}
|
|
6827
6797
|
|
|
6828
6798
|
function vectorToDegrees$2(p) {
|
|
6829
6799
|
return [
|
|
6830
|
-
Math.atan2(p[1], p[0]) * R2D$
|
|
6831
|
-
Math.asin(clamp$
|
|
6800
|
+
Math.atan2(p[1], p[0]) * R2D$5,
|
|
6801
|
+
Math.asin(clamp$3(p[2], -1, 1)) * R2D$5
|
|
6832
6802
|
];
|
|
6833
6803
|
}
|
|
6834
6804
|
|
|
6835
|
-
function normalizeVector$
|
|
6836
|
-
var k = 1 / Math.sqrt(dot$
|
|
6805
|
+
function normalizeVector$2(p) {
|
|
6806
|
+
var k = 1 / Math.sqrt(dot$2(p, p));
|
|
6837
6807
|
return [p[0] * k, p[1] * k, p[2] * k];
|
|
6838
6808
|
}
|
|
6839
6809
|
|
|
6840
|
-
function cross$
|
|
6810
|
+
function cross$2(a, b) {
|
|
6841
6811
|
return [
|
|
6842
6812
|
a[1] * b[2] - a[2] * b[1],
|
|
6843
6813
|
a[2] * b[0] - a[0] * b[2],
|
|
@@ -6845,7 +6815,7 @@
|
|
|
6845
6815
|
];
|
|
6846
6816
|
}
|
|
6847
6817
|
|
|
6848
|
-
function dot$
|
|
6818
|
+
function dot$2(a, b) {
|
|
6849
6819
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
6850
6820
|
}
|
|
6851
6821
|
|
|
@@ -6856,7 +6826,7 @@
|
|
|
6856
6826
|
}
|
|
6857
6827
|
|
|
6858
6828
|
function sameSphericalPoint(a, b) {
|
|
6859
|
-
return Math.abs(a[0] - b[0]) < EPS$
|
|
6829
|
+
return Math.abs(a[0] - b[0]) < EPS$2 && Math.abs(a[1] - b[1]) < EPS$2;
|
|
6860
6830
|
}
|
|
6861
6831
|
|
|
6862
6832
|
function pointsAlmostEqual(a, b) {
|
|
@@ -6877,19 +6847,19 @@
|
|
|
6877
6847
|
return a < b ? a + '~' + b : b + '~' + a;
|
|
6878
6848
|
}
|
|
6879
6849
|
|
|
6880
|
-
function normalizeRadians$
|
|
6850
|
+
function normalizeRadians$2(lam) {
|
|
6881
6851
|
while (lam > Math.PI) lam -= Math.PI * 2;
|
|
6882
6852
|
while (lam < -Math.PI) lam += Math.PI * 2;
|
|
6883
6853
|
return lam;
|
|
6884
6854
|
}
|
|
6885
6855
|
|
|
6886
|
-
function normalizeLongitude$
|
|
6856
|
+
function normalizeLongitude$2(lon) {
|
|
6887
6857
|
while (lon > 180) lon -= 360;
|
|
6888
6858
|
while (lon < -180) lon += 360;
|
|
6889
6859
|
return lon;
|
|
6890
6860
|
}
|
|
6891
6861
|
|
|
6892
|
-
function clamp$
|
|
6862
|
+
function clamp$3(val, min, max) {
|
|
6893
6863
|
return Math.max(min, Math.min(max, val));
|
|
6894
6864
|
}
|
|
6895
6865
|
|
|
@@ -6905,9 +6875,9 @@
|
|
|
6905
6875
|
*/
|
|
6906
6876
|
|
|
6907
6877
|
|
|
6908
|
-
var D2R$
|
|
6909
|
-
var R2D$
|
|
6910
|
-
var SQRT3 = Math.sqrt(3);
|
|
6878
|
+
var D2R$5 = Math.PI / 180;
|
|
6879
|
+
var R2D$4 = 180 / Math.PI;
|
|
6880
|
+
var SQRT3$1 = Math.sqrt(3);
|
|
6911
6881
|
var GRAY_Z = Math.sqrt(5 + 2 * Math.sqrt(5)) / Math.sqrt(15);
|
|
6912
6882
|
var GRAY_EL = Math.sqrt(8) / Math.sqrt(5 + Math.sqrt(5));
|
|
6913
6883
|
var GRAY_DVE = Math.sqrt(3 + Math.sqrt(5)) / Math.sqrt(5 + Math.sqrt(5));
|
|
@@ -6919,7 +6889,7 @@
|
|
|
6919
6889
|
6, 8, 10, 17, 21,
|
|
6920
6890
|
16, 15, 19, 19
|
|
6921
6891
|
];
|
|
6922
|
-
var engines$
|
|
6892
|
+
var engines$2 = {};
|
|
6923
6893
|
|
|
6924
6894
|
function registerDymaxionProjections(mproj) {
|
|
6925
6895
|
// Some unit tests import source modules directly in an ESM context where
|
|
@@ -6938,9 +6908,9 @@
|
|
|
6938
6908
|
|
|
6939
6909
|
function getDymaxionEngine(method) {
|
|
6940
6910
|
method = method || 'fuller';
|
|
6941
|
-
if (!engines$
|
|
6911
|
+
if (!engines$2[method]) {
|
|
6942
6912
|
var data = createAiroceanFaces();
|
|
6943
|
-
engines$
|
|
6913
|
+
engines$2[method] = createPolyhedralProjection({
|
|
6944
6914
|
faces: data.faces,
|
|
6945
6915
|
faceSites: data.sites,
|
|
6946
6916
|
parents: PARENTS,
|
|
@@ -6951,7 +6921,7 @@
|
|
|
6951
6921
|
createGrayFullerFaceProjector
|
|
6952
6922
|
});
|
|
6953
6923
|
}
|
|
6954
|
-
return engines$
|
|
6924
|
+
return engines$2[method];
|
|
6955
6925
|
}
|
|
6956
6926
|
|
|
6957
6927
|
function initDymaxion(P, method) {
|
|
@@ -6967,12 +6937,12 @@
|
|
|
6967
6937
|
xy.y = p[1];
|
|
6968
6938
|
}
|
|
6969
6939
|
};
|
|
6970
|
-
P.__projection_topology = engine.getTopology(P.lam0 * R2D$
|
|
6940
|
+
P.__projection_topology = engine.getTopology(P.lam0 * R2D$4);
|
|
6971
6941
|
P.__projected_outline = engine.outline;
|
|
6972
6942
|
}
|
|
6973
6943
|
|
|
6974
6944
|
function createAiroceanFaces() {
|
|
6975
|
-
var theta = Math.atan(0.5) * R2D$
|
|
6945
|
+
var theta = Math.atan(0.5) * R2D$4;
|
|
6976
6946
|
var vertices = [[0, 90], [0, -90]];
|
|
6977
6947
|
var faces;
|
|
6978
6948
|
var sites;
|
|
@@ -7069,10 +7039,10 @@
|
|
|
7069
7039
|
var s = GRAY_Z / (cosPhi * Math.cos(lam));
|
|
7070
7040
|
var x = cosPhi * Math.sin(lam) * s;
|
|
7071
7041
|
var y = Math.sin(phi) * s;
|
|
7072
|
-
var a1p = Math.atan2(2 * y / SQRT3 + GRAY_EL / 3 - GRAY_EL / 2, GRAY_DVE);
|
|
7073
|
-
var a2p = Math.atan2(x - y / SQRT3 + GRAY_EL / 3 - GRAY_EL / 2, GRAY_DVE);
|
|
7074
|
-
var a3p = Math.atan2(GRAY_EL / 3 - x - y / SQRT3 - GRAY_EL / 2, GRAY_DVE);
|
|
7075
|
-
return [SQRT3 * (a2p - a3p), 2 * a1p - a2p - a3p];
|
|
7042
|
+
var a1p = Math.atan2(2 * y / SQRT3$1 + GRAY_EL / 3 - GRAY_EL / 2, GRAY_DVE);
|
|
7043
|
+
var a2p = Math.atan2(x - y / SQRT3$1 + GRAY_EL / 3 - GRAY_EL / 2, GRAY_DVE);
|
|
7044
|
+
var a3p = Math.atan2(GRAY_EL / 3 - x - y / SQRT3$1 - GRAY_EL / 2, GRAY_DVE);
|
|
7045
|
+
return [SQRT3$1 * (a2p - a3p), 2 * a1p - a2p - a3p];
|
|
7076
7046
|
}
|
|
7077
7047
|
|
|
7078
7048
|
function getSphericalCentroid(coords) {
|
|
@@ -7097,16 +7067,16 @@
|
|
|
7097
7067
|
}
|
|
7098
7068
|
|
|
7099
7069
|
function degreesToVector$1(p) {
|
|
7100
|
-
var lam = p[0] * D2R$
|
|
7101
|
-
var phi = p[1] * D2R$
|
|
7070
|
+
var lam = p[0] * D2R$5;
|
|
7071
|
+
var phi = p[1] * D2R$5;
|
|
7102
7072
|
var cosPhi = Math.cos(phi);
|
|
7103
7073
|
return [Math.cos(lam) * cosPhi, Math.sin(lam) * cosPhi, Math.sin(phi)];
|
|
7104
7074
|
}
|
|
7105
7075
|
|
|
7106
7076
|
function vectorToDegrees$1(p) {
|
|
7107
7077
|
return [
|
|
7108
|
-
Math.atan2(p[1], p[0]) * R2D$
|
|
7109
|
-
Math.asin(Math.max(-1, Math.min(1, p[2]))) * R2D$
|
|
7078
|
+
Math.atan2(p[1], p[0]) * R2D$4,
|
|
7079
|
+
Math.asin(Math.max(-1, Math.min(1, p[2]))) * R2D$4
|
|
7110
7080
|
];
|
|
7111
7081
|
}
|
|
7112
7082
|
|
|
@@ -7154,8 +7124,8 @@
|
|
|
7154
7124
|
* ISC License: https://github.com/d3/d3-geo-polygon/blob/main/LICENSE
|
|
7155
7125
|
*/
|
|
7156
7126
|
|
|
7157
|
-
var D2R$
|
|
7158
|
-
var R2D$
|
|
7127
|
+
var D2R$4 = Math.PI / 180;
|
|
7128
|
+
var R2D$3 = 180 / Math.PI;
|
|
7159
7129
|
|
|
7160
7130
|
function createCahillKeyesRaw(mg) {
|
|
7161
7131
|
return createCahillKeyesTransform(mg, false);
|
|
@@ -7167,12 +7137,12 @@
|
|
|
7167
7137
|
|
|
7168
7138
|
return function(lambda, phi) {
|
|
7169
7139
|
if (faceOnly) {
|
|
7170
|
-
var lon = lambda * R2D$
|
|
7140
|
+
var lon = lambda * R2D$3;
|
|
7171
7141
|
var side = lon < 0 ? -1 : lon > 0 ? 1 : 0;
|
|
7172
|
-
var local = mp2xy(Math.abs(lon), Math.abs(phi * R2D$
|
|
7142
|
+
var local = mp2xy(Math.abs(lon), Math.abs(phi * R2D$3));
|
|
7173
7143
|
return [local[0], side * local[1]];
|
|
7174
7144
|
}
|
|
7175
|
-
var res = ll2mp(lambda * R2D$
|
|
7145
|
+
var res = ll2mp(lambda * R2D$3, phi * R2D$3);
|
|
7176
7146
|
var xy = mp2xy(res[0], res[1]);
|
|
7177
7147
|
var p = [xy[0], res[2] * xy[1]];
|
|
7178
7148
|
return mj2g(p, res[3]);
|
|
@@ -7190,7 +7160,7 @@
|
|
|
7190
7160
|
CK.cos60 = 0.5;
|
|
7191
7161
|
CK.pointM = [0, 0];
|
|
7192
7162
|
CK.pointG = [CK.lengthMG, 0];
|
|
7193
|
-
pointN = [CK.lengthMG, CK.lengthMG * Math.tan(30 * D2R$
|
|
7163
|
+
pointN = [CK.lengthMG, CK.lengthMG * Math.tan(30 * D2R$4)];
|
|
7194
7164
|
CK.pointA = [CK.lengthMA, 0];
|
|
7195
7165
|
CK.pointB = lineIntersection(CK.pointM, 30, CK.pointA, 45);
|
|
7196
7166
|
CK.lengthAG = distance(CK.pointA, CK.pointG);
|
|
@@ -7201,8 +7171,8 @@
|
|
|
7201
7171
|
CK.pointD = interpolate(lengthMB, lengthMN, pointN, CK.pointM);
|
|
7202
7172
|
CK.pointF = [CK.lengthMG, lengthNG - lengthMB];
|
|
7203
7173
|
CK.pointE = [
|
|
7204
|
-
pointN[0] - CK.lengthMA * Math.sin(30 * D2R$
|
|
7205
|
-
pointN[1] - CK.lengthMA * Math.cos(30 * D2R$
|
|
7174
|
+
pointN[0] - CK.lengthMA * Math.sin(30 * D2R$4),
|
|
7175
|
+
pointN[1] - CK.lengthMA * Math.cos(30 * D2R$4)
|
|
7206
7176
|
];
|
|
7207
7177
|
CK.lengthGF = distance(CK.pointG, CK.pointF);
|
|
7208
7178
|
CK.lengthBD = distance(CK.pointB, CK.pointD);
|
|
@@ -7212,8 +7182,8 @@
|
|
|
7212
7182
|
CK.lengthAP73 = CK.lengthMG - CK.lengthMA -
|
|
7213
7183
|
CK.lengthParallel0to73At0 * 73;
|
|
7214
7184
|
pointU = [
|
|
7215
|
-
CK.pointA[0] + CK.lengthAP73 * Math.cos(30 * D2R$
|
|
7216
|
-
CK.pointA[1] + CK.lengthAP73 * Math.sin(30 * D2R$
|
|
7185
|
+
CK.pointA[0] + CK.lengthAP73 * Math.cos(30 * D2R$4),
|
|
7186
|
+
CK.pointA[1] + CK.lengthAP73 * Math.sin(30 * D2R$4)
|
|
7217
7187
|
];
|
|
7218
7188
|
CK.pointT = lineIntersection(pointU, -60, CK.pointB, 30);
|
|
7219
7189
|
|
|
@@ -7454,8 +7424,8 @@
|
|
|
7454
7424
|
|
|
7455
7425
|
function radialPoint(origin, length, angle) {
|
|
7456
7426
|
return [
|
|
7457
|
-
origin[0] + length * Math.cos(angle * D2R$
|
|
7458
|
-
origin[1] + length * Math.sin(angle * D2R$
|
|
7427
|
+
origin[0] + length * Math.cos(angle * D2R$4),
|
|
7428
|
+
origin[1] + length * Math.sin(angle * D2R$4)
|
|
7459
7429
|
];
|
|
7460
7430
|
}
|
|
7461
7431
|
|
|
@@ -7472,8 +7442,8 @@
|
|
|
7472
7442
|
-xy[0] * CK.sin60 - xy[1] * CK.cos60
|
|
7473
7443
|
];
|
|
7474
7444
|
}
|
|
7475
|
-
var cos = Math.cos(angle * D2R$
|
|
7476
|
-
var sin = Math.sin(angle * D2R$
|
|
7445
|
+
var cos = Math.cos(angle * D2R$4);
|
|
7446
|
+
var sin = Math.sin(angle * D2R$4);
|
|
7477
7447
|
return [xy[0] * cos - xy[1] * sin, xy[0] * sin + xy[1] * cos];
|
|
7478
7448
|
}
|
|
7479
7449
|
}
|
|
@@ -7494,8 +7464,8 @@
|
|
|
7494
7464
|
}
|
|
7495
7465
|
|
|
7496
7466
|
function lineIntersection(p1, slope1, p2, slope2) {
|
|
7497
|
-
var m1 = Math.tan(slope1 * D2R$
|
|
7498
|
-
var m2 = Math.tan(slope2 * D2R$
|
|
7467
|
+
var m1 = Math.tan(slope1 * D2R$4);
|
|
7468
|
+
var m2 = Math.tan(slope2 * D2R$4);
|
|
7499
7469
|
var x = (m1 * p1[0] - m2 * p2[0] - p1[1] + p2[1]) / (m1 - m2);
|
|
7500
7470
|
return [x, m1 * (x - p1[0]) + p1[1]];
|
|
7501
7471
|
}
|
|
@@ -7523,8 +7493,8 @@
|
|
|
7523
7493
|
return n > 0 ? Math.floor(n) : Math.ceil(n);
|
|
7524
7494
|
}
|
|
7525
7495
|
|
|
7526
|
-
var D2R$
|
|
7527
|
-
var EPS = 1e-12;
|
|
7496
|
+
var D2R$3 = Math.PI / 180;
|
|
7497
|
+
var EPS$1 = 1e-12;
|
|
7528
7498
|
|
|
7529
7499
|
// Create a smooth facet projection from any radial azimuthal projection.
|
|
7530
7500
|
// The azimuthal coordinates are warped back to the gnomonic polygon along
|
|
@@ -7534,7 +7504,7 @@
|
|
|
7534
7504
|
var center = options.planarCenter || getSphericalCenter(coords);
|
|
7535
7505
|
var gnomonic = createGnomonicProjector(center);
|
|
7536
7506
|
var planar = coords.map(function(p) {
|
|
7537
|
-
return gnomonic(p[0] * D2R$
|
|
7507
|
+
return gnomonic(p[0] * D2R$3, p[1] * D2R$3);
|
|
7538
7508
|
});
|
|
7539
7509
|
var edges = createNormalizedEdges(planar);
|
|
7540
7510
|
var radial = createRadialFunction(
|
|
@@ -7553,7 +7523,7 @@
|
|
|
7553
7523
|
function project(lam, phi) {
|
|
7554
7524
|
var p = gnomonic(lam, phi);
|
|
7555
7525
|
var r = Math.hypot(p[0], p[1]);
|
|
7556
|
-
if (r < EPS) return [0, 0];
|
|
7526
|
+
if (r < EPS$1) return [0, 0];
|
|
7557
7527
|
var c = Math.atan(r);
|
|
7558
7528
|
var azimuthalRadius = radial(c) * radialScale;
|
|
7559
7529
|
var boundaryWeight = getBoundaryWeight(p, edges, boundaryStrength);
|
|
@@ -7643,8 +7613,8 @@
|
|
|
7643
7613
|
|
|
7644
7614
|
function getSphericalCenter(coords) {
|
|
7645
7615
|
var sum = coords.reduce(function(memo, p) {
|
|
7646
|
-
var lam = p[0] * D2R$
|
|
7647
|
-
var phi = p[1] * D2R$
|
|
7616
|
+
var lam = p[0] * D2R$3;
|
|
7617
|
+
var phi = p[1] * D2R$3;
|
|
7648
7618
|
var cosPhi = Math.cos(phi);
|
|
7649
7619
|
memo[0] += Math.cos(lam) * cosPhi;
|
|
7650
7620
|
memo[1] += Math.sin(lam) * cosPhi;
|
|
@@ -7652,8 +7622,8 @@
|
|
|
7652
7622
|
return memo;
|
|
7653
7623
|
}, [0, 0, 0]);
|
|
7654
7624
|
return [
|
|
7655
|
-
Math.atan2(sum[1], sum[0]) / D2R$
|
|
7656
|
-
Math.atan2(sum[2], Math.hypot(sum[0], sum[1])) / D2R$
|
|
7625
|
+
Math.atan2(sum[1], sum[0]) / D2R$3,
|
|
7626
|
+
Math.atan2(sum[2], Math.hypot(sum[0], sum[1])) / D2R$3
|
|
7657
7627
|
];
|
|
7658
7628
|
}
|
|
7659
7629
|
|
|
@@ -7668,8 +7638,8 @@
|
|
|
7668
7638
|
*/
|
|
7669
7639
|
|
|
7670
7640
|
|
|
7671
|
-
var D2R$
|
|
7672
|
-
var R2D$
|
|
7641
|
+
var D2R$2 = Math.PI / 180;
|
|
7642
|
+
var R2D$2 = 180 / Math.PI;
|
|
7673
7643
|
var RADIAL_BOUNDARY_STRENGTH = 1;
|
|
7674
7644
|
var OCTAHEDRON = createOctahedron();
|
|
7675
7645
|
var BUTTERFLY_PARENTS = [-1, 0, 0, 1, 0, 1, 4, 5];
|
|
@@ -7678,7 +7648,7 @@
|
|
|
7678
7648
|
butterfly2: -20,
|
|
7679
7649
|
cahill_keyes: -20
|
|
7680
7650
|
};
|
|
7681
|
-
var engines = {};
|
|
7651
|
+
var engines$1 = {};
|
|
7682
7652
|
|
|
7683
7653
|
function registerButterflyProjections(mproj) {
|
|
7684
7654
|
if (!mproj) return;
|
|
@@ -7696,22 +7666,22 @@
|
|
|
7696
7666
|
|
|
7697
7667
|
function getButterflyEngine(method) {
|
|
7698
7668
|
var key = method == 'butterfly2' ? 'butterfly' : method;
|
|
7699
|
-
if (!engines[key]) {
|
|
7669
|
+
if (!engines$1[key]) {
|
|
7700
7670
|
if (key == 'cahill_keyes') {
|
|
7701
|
-
engines[key] = createCahillKeyesEngine();
|
|
7671
|
+
engines$1[key] = createCahillKeyesEngine();
|
|
7702
7672
|
} else if (key == 'butterfly') {
|
|
7703
|
-
engines[key] = createButterflyEngine();
|
|
7673
|
+
engines$1[key] = createButterflyEngine();
|
|
7704
7674
|
} else {
|
|
7705
7675
|
throw new Error('Unknown butterfly projection: ' + method);
|
|
7706
7676
|
}
|
|
7707
7677
|
}
|
|
7708
|
-
return engines[key];
|
|
7678
|
+
return engines$1[key];
|
|
7709
7679
|
}
|
|
7710
7680
|
|
|
7711
7681
|
function initButterfly(P, method) {
|
|
7712
7682
|
var engine = getButterflyEngine(method);
|
|
7713
7683
|
if (!P.params.lon_0) {
|
|
7714
|
-
P.lam0 = DEFAULT_LON0[method] * D2R$
|
|
7684
|
+
P.lam0 = DEFAULT_LON0[method] * D2R$2;
|
|
7715
7685
|
}
|
|
7716
7686
|
P.es = 0;
|
|
7717
7687
|
P.inv = null;
|
|
@@ -7724,7 +7694,7 @@
|
|
|
7724
7694
|
xy.y = p[1];
|
|
7725
7695
|
}
|
|
7726
7696
|
};
|
|
7727
|
-
P.__projection_topology = engine.getTopology(P.lam0 * R2D$
|
|
7697
|
+
P.__projection_topology = engine.getTopology(P.lam0 * R2D$2);
|
|
7728
7698
|
if (engine.removeOutlineExtremeConnectors) {
|
|
7729
7699
|
P.__remove_outline_extreme_connectors = true;
|
|
7730
7700
|
}
|
|
@@ -7738,8 +7708,8 @@
|
|
|
7738
7708
|
// Reuse the Cahill-Keyes polar incisions and 12-zone octant transform,
|
|
7739
7709
|
// then unfold the faces with the butterfly attachment tree.
|
|
7740
7710
|
var data = createTruncatedOctahedronFaces(
|
|
7741
|
-
Math.cos(17 * D2R$
|
|
7742
|
-
Math.sin(17 * D2R$
|
|
7711
|
+
Math.cos(17 * D2R$2),
|
|
7712
|
+
Math.sin(17 * D2R$2),
|
|
7743
7713
|
BUTTERFLY_PARENTS
|
|
7744
7714
|
);
|
|
7745
7715
|
var faceRaw = createCahillKeyesFaceRaw(10000);
|
|
@@ -7752,9 +7722,9 @@
|
|
|
7752
7722
|
findFace: createTruncatedFaceFinder(data.cornerNormals),
|
|
7753
7723
|
faceProjector: function(face) {
|
|
7754
7724
|
var baseId = face.id < 8 ? face.id : data.parents[face.id];
|
|
7755
|
-
var center = faceCenters[baseId] * D2R$
|
|
7725
|
+
var center = faceCenters[baseId] * D2R$2;
|
|
7756
7726
|
var raw = function(lam, phi) {
|
|
7757
|
-
return faceRaw(normalizeRadians(lam - center), phi);
|
|
7727
|
+
return faceRaw(normalizeRadians$1(lam - center), phi);
|
|
7758
7728
|
};
|
|
7759
7729
|
return createNormalizedFacetProjector(face.coords, raw);
|
|
7760
7730
|
}
|
|
@@ -7767,7 +7737,7 @@
|
|
|
7767
7737
|
// Remove the global placement and scale of a raw facet while preserving its
|
|
7768
7738
|
// internal shape. The polyhedral engine then controls how facets unfold.
|
|
7769
7739
|
var points = coords.map(function(p) {
|
|
7770
|
-
return raw(p[0] * D2R$
|
|
7740
|
+
return raw(p[0] * D2R$2, p[1] * D2R$2);
|
|
7771
7741
|
});
|
|
7772
7742
|
var edge = 0;
|
|
7773
7743
|
var maxLengthSq = -1;
|
|
@@ -7856,8 +7826,8 @@
|
|
|
7856
7826
|
|
|
7857
7827
|
function createCahillKeyesEngine() {
|
|
7858
7828
|
var data = createTruncatedOctahedronFaces(
|
|
7859
|
-
Math.cos(17 * D2R$
|
|
7860
|
-
Math.sin(17 * D2R$
|
|
7829
|
+
Math.cos(17 * D2R$2),
|
|
7830
|
+
Math.sin(17 * D2R$2),
|
|
7861
7831
|
[-1, 3, 0, 2, 0, 1, 4, 5]
|
|
7862
7832
|
);
|
|
7863
7833
|
var raw = createCahillKeyesRaw(10000);
|
|
@@ -7898,10 +7868,10 @@
|
|
|
7898
7868
|
var a = vectors[vectors.length - 1];
|
|
7899
7869
|
vectors.forEach(function(b) {
|
|
7900
7870
|
hexagon.push(
|
|
7901
|
-
vectorToDegrees(normalizeVector(addScaledVectors(
|
|
7871
|
+
vectorToDegrees(normalizeVector$1(addScaledVectors(
|
|
7902
7872
|
a, edgeWeight, b, vertexWeight
|
|
7903
7873
|
))),
|
|
7904
|
-
vectorToDegrees(normalizeVector(addScaledVectors(
|
|
7874
|
+
vectorToDegrees(normalizeVector$1(addScaledVectors(
|
|
7905
7875
|
b, edgeWeight, a, vertexWeight
|
|
7906
7876
|
)))
|
|
7907
7877
|
);
|
|
@@ -8002,7 +7972,7 @@
|
|
|
8002
7972
|
}
|
|
8003
7973
|
|
|
8004
7974
|
function planarAngle(p, project) {
|
|
8005
|
-
var q = project(p[0] * D2R$
|
|
7975
|
+
var q = project(p[0] * D2R$2, p[1] * D2R$2);
|
|
8006
7976
|
return Math.atan2(q[1], q[0]);
|
|
8007
7977
|
}
|
|
8008
7978
|
|
|
@@ -8036,16 +8006,16 @@
|
|
|
8036
8006
|
}
|
|
8037
8007
|
|
|
8038
8008
|
function degreesToVector(p) {
|
|
8039
|
-
var lam = p[0] * D2R$
|
|
8040
|
-
var phi = p[1] * D2R$
|
|
8009
|
+
var lam = p[0] * D2R$2;
|
|
8010
|
+
var phi = p[1] * D2R$2;
|
|
8041
8011
|
var cosPhi = Math.cos(phi);
|
|
8042
8012
|
return [Math.cos(lam) * cosPhi, Math.sin(lam) * cosPhi, Math.sin(phi)];
|
|
8043
8013
|
}
|
|
8044
8014
|
|
|
8045
8015
|
function vectorToDegrees(p) {
|
|
8046
8016
|
return [
|
|
8047
|
-
Math.atan2(p[1], p[0]) * R2D$
|
|
8048
|
-
Math.asin(Math.max(-1, Math.min(1, p[2]))) * R2D$
|
|
8017
|
+
Math.atan2(p[1], p[0]) * R2D$2,
|
|
8018
|
+
Math.asin(Math.max(-1, Math.min(1, p[2]))) * R2D$2
|
|
8049
8019
|
];
|
|
8050
8020
|
}
|
|
8051
8021
|
|
|
@@ -8069,12 +8039,12 @@
|
|
|
8069
8039
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
8070
8040
|
}
|
|
8071
8041
|
|
|
8072
|
-
function normalizeVector(p) {
|
|
8042
|
+
function normalizeVector$1(p) {
|
|
8073
8043
|
var k = 1 / Math.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
|
|
8074
8044
|
return [p[0] * k, p[1] * k, p[2] * k];
|
|
8075
8045
|
}
|
|
8076
8046
|
|
|
8077
|
-
function normalizeRadians(lam) {
|
|
8047
|
+
function normalizeRadians$1(lam) {
|
|
8078
8048
|
return (lam + Math.PI * 3) % (Math.PI * 2) - Math.PI;
|
|
8079
8049
|
}
|
|
8080
8050
|
|
|
@@ -8085,9 +8055,493 @@
|
|
|
8085
8055
|
registerButterflyProjections: registerButterflyProjections
|
|
8086
8056
|
});
|
|
8087
8057
|
|
|
8058
|
+
/*
|
|
8059
|
+
* Forward implementation of Hajime Narukawa's 2022 mathematical
|
|
8060
|
+
* approximation of the AuthaGraph construction.
|
|
8061
|
+
*
|
|
8062
|
+
* Facet formula:
|
|
8063
|
+
* H. Narukawa, "Formulation of AuthaGraph Map Projection" (2022)
|
|
8064
|
+
* https://www.jstage.jst.go.jp/article/jjca/60/1/60_1/_article/-char/en
|
|
8065
|
+
*
|
|
8066
|
+
* The rectangular facet routing follows the public Imago arrangement by
|
|
8067
|
+
* Justin Kunimune. The face transform itself uses Narukawa's published
|
|
8068
|
+
* equations, not Imago's power-law approximation.
|
|
8069
|
+
*/
|
|
8070
|
+
|
|
8071
|
+
var D2R$1 = Math.PI / 180;
|
|
8072
|
+
var R2D$1 = 180 / Math.PI;
|
|
8073
|
+
var HALF_PI = Math.PI / 2;
|
|
8074
|
+
var SQRT2 = Math.sqrt(2);
|
|
8075
|
+
var SQRT3 = Math.sqrt(3);
|
|
8076
|
+
var ASIN_ONE_THIRD = Math.asin(1 / 3);
|
|
8077
|
+
var EDGE_SCALE = Math.acos(-1 / 3) / 2;
|
|
8078
|
+
var XMIN = -2 * SQRT3;
|
|
8079
|
+
var XMAX = 2 * SQRT3;
|
|
8080
|
+
var YMIN = -1.5;
|
|
8081
|
+
var YMAX = 1.5;
|
|
8082
|
+
var BLOCK_HEIGHT = 2 * SQRT3;
|
|
8083
|
+
var LAYOUT_SHIFT = 1.16;
|
|
8084
|
+
var EPS = 1e-12;
|
|
8085
|
+
var engines = {};
|
|
8086
|
+
|
|
8087
|
+
// The four tetrahedron vertices published by Narukawa, in latitude-longitude
|
|
8088
|
+
// order. The extra precision preserves the regular tetrahedron to about 1e-9
|
|
8089
|
+
// in vector dot products.
|
|
8090
|
+
var GEOGRAPHIC_VERTICES = [
|
|
8091
|
+
[76.8810628, 149.4509913],
|
|
8092
|
+
[-27.9527772, 97.3570035],
|
|
8093
|
+
[-6.6370473, -18.8522325],
|
|
8094
|
+
[-22.9282364, -133.2827588]
|
|
8095
|
+
];
|
|
8096
|
+
|
|
8097
|
+
// D3 Imago's vertex-oriented tetrahedral block. Each entry contains the
|
|
8098
|
+
// spherical center, local meridian, planar rotation and planar center.
|
|
8099
|
+
var FACET_DEFS = [
|
|
8100
|
+
[0, SQRT3, HALF_PI, 0, 0, -HALF_PI],
|
|
8101
|
+
[0, -SQRT3, -ASIN_ONE_THIRD, 0, Math.PI, HALF_PI],
|
|
8102
|
+
[3, 0, -ASIN_ONE_THIRD, 2 * Math.PI / 3, Math.PI, 5 * Math.PI / 6],
|
|
8103
|
+
[-3, 0, -ASIN_ONE_THIRD, -2 * Math.PI / 3, Math.PI, Math.PI / 6]
|
|
8104
|
+
];
|
|
8105
|
+
|
|
8106
|
+
function registerNarukawa2022Projection(mproj) {
|
|
8107
|
+
if (!mproj || mproj.internal.pj_list.narukawa2022) return;
|
|
8108
|
+
mproj.pj_add(function(P) {
|
|
8109
|
+
initNarukawa2022(P);
|
|
8110
|
+
}, 'narukawa2022', 'Narukawa 2022 tetrahedral world map');
|
|
8111
|
+
}
|
|
8112
|
+
|
|
8113
|
+
function getNarukawa2022Engine() {
|
|
8114
|
+
if (!engines.default) {
|
|
8115
|
+
engines.default = createNarukawa2022Engine();
|
|
8116
|
+
}
|
|
8117
|
+
return engines.default;
|
|
8118
|
+
}
|
|
8119
|
+
|
|
8120
|
+
function initNarukawa2022(P) {
|
|
8121
|
+
var engine = getNarukawa2022Engine();
|
|
8122
|
+
P.es = 0;
|
|
8123
|
+
P.inv = null;
|
|
8124
|
+
P.fwd = function(lp, xy) {
|
|
8125
|
+
var p = engine.forward(lp.lam, lp.phi);
|
|
8126
|
+
xy.x = p[0];
|
|
8127
|
+
xy.y = p[1];
|
|
8128
|
+
};
|
|
8129
|
+
P.__projection_topology = engine.getTopology(P.lam0 * R2D$1);
|
|
8130
|
+
P.__projected_outline = engine.outline;
|
|
8131
|
+
}
|
|
8132
|
+
|
|
8133
|
+
function createNarukawa2022Engine() {
|
|
8134
|
+
var orientation = createPublishedOrientation();
|
|
8135
|
+
var facets = FACET_DEFS.map(function(def, i) {
|
|
8136
|
+
return {
|
|
8137
|
+
id: i,
|
|
8138
|
+
x: def[0],
|
|
8139
|
+
y: def[1],
|
|
8140
|
+
lat: def[2],
|
|
8141
|
+
lon: def[3],
|
|
8142
|
+
meridian: def[4],
|
|
8143
|
+
rotation: def[5]
|
|
8144
|
+
};
|
|
8145
|
+
});
|
|
8146
|
+
var outline = [[
|
|
8147
|
+
[XMIN * EDGE_SCALE, YMIN * EDGE_SCALE],
|
|
8148
|
+
[XMAX * EDGE_SCALE, YMIN * EDGE_SCALE],
|
|
8149
|
+
[XMAX * EDGE_SCALE, YMAX * EDGE_SCALE],
|
|
8150
|
+
[XMIN * EDGE_SCALE, YMAX * EDGE_SCALE],
|
|
8151
|
+
[XMIN * EDGE_SCALE, YMIN * EDGE_SCALE]
|
|
8152
|
+
]];
|
|
8153
|
+
|
|
8154
|
+
return {
|
|
8155
|
+
forward: forward,
|
|
8156
|
+
inverse: inverse,
|
|
8157
|
+
outline: outline,
|
|
8158
|
+
getTopology: getTopology
|
|
8159
|
+
};
|
|
8160
|
+
|
|
8161
|
+
function forward(lam, phi) {
|
|
8162
|
+
var state = projectState(lam, phi);
|
|
8163
|
+
return [state.x * EDGE_SCALE, state.y * EDGE_SCALE];
|
|
8164
|
+
}
|
|
8165
|
+
|
|
8166
|
+
// Internal inverse used only for tracing the geographic rectangular cut.
|
|
8167
|
+
// P.inv remains null because the full Mapshaper inverse path is unsupported.
|
|
8168
|
+
function inverse(x, y) {
|
|
8169
|
+
var p = invertLayout(x / EDGE_SCALE, y / EDGE_SCALE, facets);
|
|
8170
|
+
if (!p) return null;
|
|
8171
|
+
return fromCanonical(p[0], p[1], orientation);
|
|
8172
|
+
}
|
|
8173
|
+
|
|
8174
|
+
function projectState(lam, phi) {
|
|
8175
|
+
var p = toCanonical(lam, phi, orientation);
|
|
8176
|
+
var state = projectCanonical(p[0], p[1], facets);
|
|
8177
|
+
state.region = encodeRegion(state);
|
|
8178
|
+
return state;
|
|
8179
|
+
}
|
|
8180
|
+
|
|
8181
|
+
function getTopology(lon0) {
|
|
8182
|
+
var paths = createCutPaths(inverse, lon0);
|
|
8183
|
+
return {
|
|
8184
|
+
regions: createRegionIndex(),
|
|
8185
|
+
seams: [{
|
|
8186
|
+
type: 'cut',
|
|
8187
|
+
paths: paths
|
|
8188
|
+
}],
|
|
8189
|
+
findRegion: findRegion,
|
|
8190
|
+
findTransitionRegion: findRegion,
|
|
8191
|
+
outline: outline.map(function(ring) {
|
|
8192
|
+
return ring.map(function(p) {
|
|
8193
|
+
return p.concat();
|
|
8194
|
+
});
|
|
8195
|
+
})
|
|
8196
|
+
};
|
|
8197
|
+
|
|
8198
|
+
function findRegion(lon, lat) {
|
|
8199
|
+
var lam = normalizeRadians((lon - lon0) * D2R$1);
|
|
8200
|
+
return projectState(lam, lat * D2R$1).region;
|
|
8201
|
+
}
|
|
8202
|
+
}
|
|
8203
|
+
}
|
|
8204
|
+
|
|
8205
|
+
function projectCanonical(lam, phi, facets) {
|
|
8206
|
+
var facet = findForwardFacet(lam, phi, facets);
|
|
8207
|
+
var relative = obliquifySpherical(phi, lam, facet);
|
|
8208
|
+
var sector = Math.floor((relative[1] + Math.PI / 3) / (2 * Math.PI / 3));
|
|
8209
|
+
var base = sector * 2 * Math.PI / 3;
|
|
8210
|
+
var polar = narukawaFaceForward(relative[1] - base, relative[0]);
|
|
8211
|
+
var angle = polar[1] + facet.rotation + base / 2;
|
|
8212
|
+
var x = polar[0] * Math.cos(angle) + facet.x;
|
|
8213
|
+
var y = polar[0] * Math.sin(angle) + facet.y;
|
|
8214
|
+
var oob = 0;
|
|
8215
|
+
var folded = 0;
|
|
8216
|
+
var wrap = 0;
|
|
8217
|
+
|
|
8218
|
+
if (Math.abs(x) > 3 + EPS) {
|
|
8219
|
+
x = 2 * facet.x - x;
|
|
8220
|
+
y = -y;
|
|
8221
|
+
oob = 1;
|
|
8222
|
+
} else if (Math.abs(y) > SQRT3 + EPS) {
|
|
8223
|
+
x = -x;
|
|
8224
|
+
y = BLOCK_HEIGHT * Math.sign(y) - y;
|
|
8225
|
+
oob = 2;
|
|
8226
|
+
}
|
|
8227
|
+
|
|
8228
|
+
var qx = y;
|
|
8229
|
+
var qy = -x;
|
|
8230
|
+
if (qy > EPS) {
|
|
8231
|
+
qx = BLOCK_HEIGHT - qx;
|
|
8232
|
+
qy = -qy;
|
|
8233
|
+
folded = 1;
|
|
8234
|
+
}
|
|
8235
|
+
qx += LAYOUT_SHIFT;
|
|
8236
|
+
if (qx < 0) {
|
|
8237
|
+
qx += 2 * BLOCK_HEIGHT;
|
|
8238
|
+
wrap = 1;
|
|
8239
|
+
}
|
|
8240
|
+
x = qx - BLOCK_HEIGHT;
|
|
8241
|
+
y = qy + 1.5;
|
|
8242
|
+
x = clamp$2(x, XMIN, XMAX);
|
|
8243
|
+
y = clamp$2(y, YMIN, YMAX);
|
|
8244
|
+
return {
|
|
8245
|
+
x: x,
|
|
8246
|
+
y: y,
|
|
8247
|
+
facet: facet.id,
|
|
8248
|
+
sector: mod(sector, 3),
|
|
8249
|
+
oob: oob,
|
|
8250
|
+
folded: folded,
|
|
8251
|
+
wrap: wrap
|
|
8252
|
+
};
|
|
8253
|
+
}
|
|
8254
|
+
|
|
8255
|
+
function findForwardFacet(lam, phi, facets) {
|
|
8256
|
+
var best = null;
|
|
8257
|
+
var bestLat = -Infinity;
|
|
8258
|
+
for (var i = 0; i < 4; i++) {
|
|
8259
|
+
var facet = facets[i];
|
|
8260
|
+
var relative = obliquifySpherical(phi, lam, facet);
|
|
8261
|
+
if (relative[0] > bestLat) {
|
|
8262
|
+
bestLat = relative[0];
|
|
8263
|
+
best = facet;
|
|
8264
|
+
}
|
|
8265
|
+
}
|
|
8266
|
+
return best;
|
|
8267
|
+
}
|
|
8268
|
+
|
|
8269
|
+
function narukawaFaceForward(lam, phi) {
|
|
8270
|
+
var a = lam - Math.asin(Math.sin(lam) / SQRT3);
|
|
8271
|
+
var theta = Math.atan(2 * SQRT3 / Math.PI * a);
|
|
8272
|
+
var denominator = 2 + SQRT2 * Math.tan(phi);
|
|
8273
|
+
var q = denominator > 0 ? (2 + Math.cos(lam)) / denominator : 0;
|
|
8274
|
+
var r = q * SQRT3 / Math.cos(theta);
|
|
8275
|
+
return [r, theta];
|
|
8276
|
+
}
|
|
8277
|
+
|
|
8278
|
+
function narukawaFaceInverse(r, theta) {
|
|
8279
|
+
var target = Math.tan(theta) * Math.PI / (2 * SQRT3);
|
|
8280
|
+
var lo = -Math.PI / 3;
|
|
8281
|
+
var hi = Math.PI / 3;
|
|
8282
|
+
var lam;
|
|
8283
|
+
for (var i = 0; i < 55; i++) {
|
|
8284
|
+
lam = (lo + hi) / 2;
|
|
8285
|
+
var a = lam - Math.asin(Math.sin(lam) / SQRT3);
|
|
8286
|
+
if (a < target) lo = lam;
|
|
8287
|
+
else hi = lam;
|
|
8288
|
+
}
|
|
8289
|
+
lam = (lo + hi) / 2;
|
|
8290
|
+
var q = r * Math.cos(theta) / SQRT3;
|
|
8291
|
+
var phi = q < EPS ? HALF_PI :
|
|
8292
|
+
Math.atan(((2 + Math.cos(lam)) / q - 2) / SQRT2);
|
|
8293
|
+
return [phi, lam];
|
|
8294
|
+
}
|
|
8295
|
+
|
|
8296
|
+
function invertLayout(x, y, facets) {
|
|
8297
|
+
var qx = x + BLOCK_HEIGHT;
|
|
8298
|
+
var qy = y - 1.5;
|
|
8299
|
+
var normalizedX = (qx - LAYOUT_SHIFT) / BLOCK_HEIGHT;
|
|
8300
|
+
if (normalizedX > 1.5) normalizedX -= 2;
|
|
8301
|
+
if (normalizedX > 0.5) {
|
|
8302
|
+
normalizedX = 1 - normalizedX;
|
|
8303
|
+
qy *= -1;
|
|
8304
|
+
}
|
|
8305
|
+
x = -qy;
|
|
8306
|
+
y = normalizedX * BLOCK_HEIGHT;
|
|
8307
|
+
|
|
8308
|
+
var facet = findInverseFacet(x, y, facets);
|
|
8309
|
+
var dx = x - facet.x;
|
|
8310
|
+
var dy = y - facet.y;
|
|
8311
|
+
var r = Math.hypot(dx, dy);
|
|
8312
|
+
var theta = normalizeRadians(Math.atan2(dy, dx) - facet.rotation);
|
|
8313
|
+
var base = Math.floor((theta + Math.PI / 6) / (Math.PI / 3)) *
|
|
8314
|
+
Math.PI / 3;
|
|
8315
|
+
var relative = narukawaFaceInverse(r, theta - base);
|
|
8316
|
+
relative[1] += base * 2;
|
|
8317
|
+
var p = deobliquifySpherical(relative[0], relative[1], facet);
|
|
8318
|
+
return [p[1], p[0]];
|
|
8319
|
+
}
|
|
8320
|
+
|
|
8321
|
+
function findInverseFacet(x, y, facets) {
|
|
8322
|
+
var best = null;
|
|
8323
|
+
var minDistance = Infinity;
|
|
8324
|
+
facets.forEach(function(facet) {
|
|
8325
|
+
var d = Math.hypot(x - facet.x, y - facet.y);
|
|
8326
|
+
if (d < minDistance) {
|
|
8327
|
+
minDistance = d;
|
|
8328
|
+
best = facet;
|
|
8329
|
+
}
|
|
8330
|
+
});
|
|
8331
|
+
return best;
|
|
8332
|
+
}
|
|
8333
|
+
|
|
8334
|
+
function createPublishedOrientation() {
|
|
8335
|
+
// Match the D3 Imago arrangement: the third published vertex is the
|
|
8336
|
+
// canonical southern vertex at longitude zero.
|
|
8337
|
+
var north = latLonToVector(GEOGRAPHIC_VERTICES[0]);
|
|
8338
|
+
var south = latLonToVector(GEOGRAPHIC_VERTICES[2]);
|
|
8339
|
+
var tangent = normalizeVector(subtract(
|
|
8340
|
+
south,
|
|
8341
|
+
multiply(north, dot$1(south, north))
|
|
8342
|
+
));
|
|
8343
|
+
var x = tangent;
|
|
8344
|
+
var y = cross$1(north, tangent);
|
|
8345
|
+
return {x: x, y: y, z: north};
|
|
8346
|
+
}
|
|
8347
|
+
|
|
8348
|
+
function toCanonical(lam, phi, orientation) {
|
|
8349
|
+
var v = radiansToVector(lam, phi);
|
|
8350
|
+
return [
|
|
8351
|
+
Math.atan2(dot$1(v, orientation.y), dot$1(v, orientation.x)),
|
|
8352
|
+
Math.asin(clamp$2(dot$1(v, orientation.z), -1, 1))
|
|
8353
|
+
];
|
|
8354
|
+
}
|
|
8355
|
+
|
|
8356
|
+
function fromCanonical(lam, phi, orientation) {
|
|
8357
|
+
var v = radiansToVector(lam, phi);
|
|
8358
|
+
var p = [
|
|
8359
|
+
orientation.x[0] * v[0] + orientation.y[0] * v[1] + orientation.z[0] * v[2],
|
|
8360
|
+
orientation.x[1] * v[0] + orientation.y[1] * v[1] + orientation.z[1] * v[2],
|
|
8361
|
+
orientation.x[2] * v[0] + orientation.y[2] * v[1] + orientation.z[2] * v[2]
|
|
8362
|
+
];
|
|
8363
|
+
return [Math.atan2(p[1], p[0]), Math.asin(clamp$2(p[2], -1, 1))];
|
|
8364
|
+
}
|
|
8365
|
+
|
|
8366
|
+
// Adapted from Justin Kunimune's Imago implementation.
|
|
8367
|
+
function obliquifySpherical(lat, lon, pole) {
|
|
8368
|
+
var lat0 = pole.lat;
|
|
8369
|
+
var lon0 = pole.lon;
|
|
8370
|
+
var theta0 = pole.meridian;
|
|
8371
|
+
var lat1;
|
|
8372
|
+
var lon1;
|
|
8373
|
+
if (Math.abs(lat0 - HALF_PI) < EPS) {
|
|
8374
|
+
lat1 = lat;
|
|
8375
|
+
lon1 = lon - lon0;
|
|
8376
|
+
} else {
|
|
8377
|
+
lat1 = Math.asin(clamp$2(
|
|
8378
|
+
Math.sin(lat0) * Math.sin(lat) +
|
|
8379
|
+
Math.cos(lat0) * Math.cos(lat) * Math.cos(lon0 - lon),
|
|
8380
|
+
-1,
|
|
8381
|
+
1
|
|
8382
|
+
));
|
|
8383
|
+
var denominator = Math.cos(lat1);
|
|
8384
|
+
var value = denominator < EPS ? 1 :
|
|
8385
|
+
(Math.cos(lat0) * Math.sin(lat) -
|
|
8386
|
+
Math.sin(lat0) * Math.cos(lat) * Math.cos(lon0 - lon)) /
|
|
8387
|
+
denominator;
|
|
8388
|
+
lon1 = Math.acos(clamp$2(value, -1, 1)) - Math.PI;
|
|
8389
|
+
if (Math.sin(lon - lon0) > 0) lon1 = -lon1;
|
|
8390
|
+
}
|
|
8391
|
+
return [lat1, normalizeRadians(lon1 - theta0)];
|
|
8392
|
+
}
|
|
8393
|
+
|
|
8394
|
+
function deobliquifySpherical(lat, lon, pole) {
|
|
8395
|
+
var lat0 = pole.lat;
|
|
8396
|
+
var lon0 = pole.lon;
|
|
8397
|
+
lon += pole.meridian;
|
|
8398
|
+
var latOut = Math.asin(clamp$2(
|
|
8399
|
+
Math.sin(lat0) * Math.sin(lat) -
|
|
8400
|
+
Math.cos(lat0) * Math.cos(lon) * Math.cos(lat),
|
|
8401
|
+
-1,
|
|
8402
|
+
1
|
|
8403
|
+
));
|
|
8404
|
+
var lonOut;
|
|
8405
|
+
if (Math.abs(lat0 - HALF_PI) < EPS) {
|
|
8406
|
+
lonOut = lon + lon0;
|
|
8407
|
+
} else {
|
|
8408
|
+
var value = Math.sin(lat) / Math.cos(lat0) / Math.cos(latOut) -
|
|
8409
|
+
Math.tan(lat0) * Math.tan(latOut);
|
|
8410
|
+
if (Math.sin(lon) > 0) lonOut = lon0 + Math.acos(clamp$2(value, -1, 1));
|
|
8411
|
+
else lonOut = lon0 - Math.acos(clamp$2(value, -1, 1));
|
|
8412
|
+
}
|
|
8413
|
+
return [latOut, normalizeRadians(lonOut)];
|
|
8414
|
+
}
|
|
8415
|
+
|
|
8416
|
+
function createCutPaths(inverse, lon0) {
|
|
8417
|
+
// The rectangular edges become moderately curved geographic seams. Sampling
|
|
8418
|
+
// at about 0.03 degrees prevents straight mask chords from missing crossings.
|
|
8419
|
+
var n = 6000;
|
|
8420
|
+
var epsilon = 1e-8;
|
|
8421
|
+
var edges = [
|
|
8422
|
+
[[XMIN + epsilon, YMIN], [XMIN + epsilon, YMAX]],
|
|
8423
|
+
[[XMIN, YMAX - epsilon], [XMAX, YMAX - epsilon]],
|
|
8424
|
+
[[XMIN, YMIN + epsilon], [XMAX, YMIN + epsilon]]
|
|
8425
|
+
];
|
|
8426
|
+
var paths = edges.reduce(function(memo, edge) {
|
|
8427
|
+
var path = [];
|
|
8428
|
+
for (var i = 0; i <= n; i++) {
|
|
8429
|
+
var t = i / n;
|
|
8430
|
+
var x = edge[0][0] + (edge[1][0] - edge[0][0]) * t;
|
|
8431
|
+
var y = edge[0][1] + (edge[1][1] - edge[0][1]) * t;
|
|
8432
|
+
var p = inverse(x * EDGE_SCALE, y * EDGE_SCALE);
|
|
8433
|
+
path.push([
|
|
8434
|
+
normalizeLongitude$1(p[0] * R2D$1 + lon0),
|
|
8435
|
+
p[1] * R2D$1
|
|
8436
|
+
]);
|
|
8437
|
+
}
|
|
8438
|
+
return memo.concat(splitPathAtAntimeridian$1(path));
|
|
8439
|
+
}, []);
|
|
8440
|
+
return paths.map(function(part) {
|
|
8441
|
+
part.mask_width = 4e-5;
|
|
8442
|
+
return part;
|
|
8443
|
+
});
|
|
8444
|
+
}
|
|
8445
|
+
|
|
8446
|
+
function splitPathAtAntimeridian$1(path) {
|
|
8447
|
+
var paths = [];
|
|
8448
|
+
var part = [path[0]];
|
|
8449
|
+
for (var i = 1; i < path.length; i++) {
|
|
8450
|
+
var a = path[i - 1];
|
|
8451
|
+
var b = path[i];
|
|
8452
|
+
if (Math.abs(a[0] - b[0]) > 180) {
|
|
8453
|
+
var adjusted = b[0] + (b[0] < a[0] ? 360 : -360);
|
|
8454
|
+
var edge = a[0] < 0 ? -180 : 180;
|
|
8455
|
+
var t = (edge - a[0]) / (adjusted - a[0]);
|
|
8456
|
+
var lat = a[1] + (b[1] - a[1]) * t;
|
|
8457
|
+
part.push([edge, lat]);
|
|
8458
|
+
paths.push(part);
|
|
8459
|
+
part = [[-edge, lat], b];
|
|
8460
|
+
} else {
|
|
8461
|
+
part.push(b);
|
|
8462
|
+
}
|
|
8463
|
+
}
|
|
8464
|
+
if (part.length > 1) paths.push(part);
|
|
8465
|
+
return paths;
|
|
8466
|
+
}
|
|
8467
|
+
|
|
8468
|
+
function encodeRegion(state) {
|
|
8469
|
+
return ((((state.facet * 3 + state.sector) * 3 + state.oob) * 2 +
|
|
8470
|
+
state.folded) * 2 + state.wrap);
|
|
8471
|
+
}
|
|
8472
|
+
|
|
8473
|
+
function createRegionIndex() {
|
|
8474
|
+
var regions = [];
|
|
8475
|
+
for (var i = 0; i < 144; i++) {
|
|
8476
|
+
regions.push({id: i});
|
|
8477
|
+
}
|
|
8478
|
+
return regions;
|
|
8479
|
+
}
|
|
8480
|
+
|
|
8481
|
+
function latLonToVector(p) {
|
|
8482
|
+
return radiansToVector(p[1] * D2R$1, p[0] * D2R$1);
|
|
8483
|
+
}
|
|
8484
|
+
|
|
8485
|
+
function radiansToVector(lam, phi) {
|
|
8486
|
+
var cosPhi = Math.cos(phi);
|
|
8487
|
+
return [Math.cos(lam) * cosPhi, Math.sin(lam) * cosPhi, Math.sin(phi)];
|
|
8488
|
+
}
|
|
8489
|
+
|
|
8490
|
+
function subtract(a, b) {
|
|
8491
|
+
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
|
|
8492
|
+
}
|
|
8493
|
+
|
|
8494
|
+
function multiply(a, k) {
|
|
8495
|
+
return [a[0] * k, a[1] * k, a[2] * k];
|
|
8496
|
+
}
|
|
8497
|
+
|
|
8498
|
+
function normalizeVector(a) {
|
|
8499
|
+
var k = 1 / Math.hypot(a[0], a[1], a[2]);
|
|
8500
|
+
return multiply(a, k);
|
|
8501
|
+
}
|
|
8502
|
+
|
|
8503
|
+
function cross$1(a, b) {
|
|
8504
|
+
return [
|
|
8505
|
+
a[1] * b[2] - a[2] * b[1],
|
|
8506
|
+
a[2] * b[0] - a[0] * b[2],
|
|
8507
|
+
a[0] * b[1] - a[1] * b[0]
|
|
8508
|
+
];
|
|
8509
|
+
}
|
|
8510
|
+
|
|
8511
|
+
function dot$1(a, b) {
|
|
8512
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
8513
|
+
}
|
|
8514
|
+
|
|
8515
|
+
function mod(a, n) {
|
|
8516
|
+
return (a % n + n) % n;
|
|
8517
|
+
}
|
|
8518
|
+
|
|
8519
|
+
function normalizeRadians(lam) {
|
|
8520
|
+
while (lam > Math.PI) lam -= 2 * Math.PI;
|
|
8521
|
+
while (lam < -Math.PI) lam += 2 * Math.PI;
|
|
8522
|
+
return lam;
|
|
8523
|
+
}
|
|
8524
|
+
|
|
8525
|
+
function normalizeLongitude$1(lon) {
|
|
8526
|
+
while (lon > 180) lon -= 360;
|
|
8527
|
+
while (lon < -180) lon += 360;
|
|
8528
|
+
return lon;
|
|
8529
|
+
}
|
|
8530
|
+
|
|
8531
|
+
function clamp$2(value, min, max) {
|
|
8532
|
+
return Math.max(min, Math.min(max, value));
|
|
8533
|
+
}
|
|
8534
|
+
|
|
8535
|
+
var Narukawa2022 = /*#__PURE__*/Object.freeze({
|
|
8536
|
+
__proto__: null,
|
|
8537
|
+
getNarukawa2022Engine: getNarukawa2022Engine,
|
|
8538
|
+
registerNarukawa2022Projection: registerNarukawa2022Projection
|
|
8539
|
+
});
|
|
8540
|
+
|
|
8088
8541
|
var mproj$1 = require$1('mproj');
|
|
8089
8542
|
registerDymaxionProjections(mproj$1);
|
|
8090
8543
|
registerButterflyProjections(mproj$1);
|
|
8544
|
+
registerNarukawa2022Projection(mproj$1);
|
|
8091
8545
|
|
|
8092
8546
|
var asyncLoader = null;
|
|
8093
8547
|
|
|
@@ -11075,7 +11529,7 @@
|
|
|
11075
11529
|
function layerNameIsUnsafeFilename(name) {
|
|
11076
11530
|
name = String(name);
|
|
11077
11531
|
// path separators (directory traversal on any OS) or NUL
|
|
11078
|
-
if (/[
|
|
11532
|
+
if (/[/\\\0]/.test(name)) return true;
|
|
11079
11533
|
// Windows drive-relative prefix, e.g. "C:foo" can write to another drive
|
|
11080
11534
|
if (/^[A-Za-z]:/.test(name)) return true;
|
|
11081
11535
|
return false;
|
|
@@ -40970,7 +41424,9 @@ ${svg}
|
|
|
40970
41424
|
return finalizeImportedDataset(dataset, dataFmt, data, opts);
|
|
40971
41425
|
}
|
|
40972
41426
|
|
|
40973
|
-
|
|
41427
|
+
// Canonical content import interface. Always resolves to an array because some
|
|
41428
|
+
// formats (notably GeoPackage) may contain datasets that cannot be merged.
|
|
41429
|
+
async function importDatasetsFromContent(obj, opts) {
|
|
40974
41430
|
var dataset, dataFmt, data;
|
|
40975
41431
|
opts = opts || {};
|
|
40976
41432
|
if (obj.fgb) {
|
|
@@ -40994,14 +41450,16 @@ ${svg}
|
|
|
40994
41450
|
data = obj[dataFmt];
|
|
40995
41451
|
dataset = await importImageRaster(obj, opts);
|
|
40996
41452
|
} else {
|
|
40997
|
-
return importContent(obj, opts);
|
|
41453
|
+
return normalizeImportedDatasets$1(importContent(obj, opts));
|
|
40998
41454
|
}
|
|
40999
|
-
|
|
41000
|
-
return
|
|
41001
|
-
|
|
41002
|
-
|
|
41003
|
-
|
|
41004
|
-
|
|
41455
|
+
return normalizeImportedDatasets$1(dataset).map(function(ds) {
|
|
41456
|
+
return finalizeImportedDataset(ds, dataFmt, data, opts);
|
|
41457
|
+
});
|
|
41458
|
+
}
|
|
41459
|
+
|
|
41460
|
+
// Compatibility facade for callers that expect one dataset when possible.
|
|
41461
|
+
async function importContentAsync(obj, opts) {
|
|
41462
|
+
return denormalizeImportedDatasets$1(await importDatasetsFromContent(obj, opts));
|
|
41005
41463
|
}
|
|
41006
41464
|
|
|
41007
41465
|
// Deprecated (included for compatibility with older tests)
|
|
@@ -41012,6 +41470,14 @@ ${svg}
|
|
|
41012
41470
|
return importContent(input, opts);
|
|
41013
41471
|
}
|
|
41014
41472
|
|
|
41473
|
+
function normalizeImportedDatasets$1(datasetOrArray) {
|
|
41474
|
+
return Array.isArray(datasetOrArray) ? datasetOrArray : [datasetOrArray];
|
|
41475
|
+
}
|
|
41476
|
+
|
|
41477
|
+
function denormalizeImportedDatasets$1(datasets) {
|
|
41478
|
+
return datasets.length == 1 ? datasets[0] : datasets;
|
|
41479
|
+
}
|
|
41480
|
+
|
|
41015
41481
|
|
|
41016
41482
|
function importShapefile(obj, opts) {
|
|
41017
41483
|
var shpSrc = obj.shp.content || obj.shp.filename, // read from a file if (binary) content is missing
|
|
@@ -41094,6 +41560,7 @@ ${svg}
|
|
|
41094
41560
|
__proto__: null,
|
|
41095
41561
|
importContent: importContent,
|
|
41096
41562
|
importContentAsync: importContentAsync,
|
|
41563
|
+
importDatasetsFromContent: importDatasetsFromContent,
|
|
41097
41564
|
importFileContent: importFileContent
|
|
41098
41565
|
});
|
|
41099
41566
|
|
|
@@ -41262,8 +41729,7 @@ ${svg}
|
|
|
41262
41729
|
var dataset, datasets, target;
|
|
41263
41730
|
|
|
41264
41731
|
if (opts.stdin) {
|
|
41265
|
-
|
|
41266
|
-
datasets = normalizeImportedDatasets(dataset);
|
|
41732
|
+
datasets = await importDatasetsFromFile('/dev/stdin', opts);
|
|
41267
41733
|
catalog.addDatasets(datasets);
|
|
41268
41734
|
if (datasets.length > 1) {
|
|
41269
41735
|
catalog.setDefaultTargets(datasets.map(function(ds) {
|
|
@@ -41301,11 +41767,11 @@ ${svg}
|
|
|
41301
41767
|
}
|
|
41302
41768
|
|
|
41303
41769
|
if (files.length == 1) {
|
|
41304
|
-
|
|
41770
|
+
datasets = await importDatasetsFromFile(files[0], opts);
|
|
41305
41771
|
} else {
|
|
41306
41772
|
dataset = await importFilesTogetherAsync(files, opts);
|
|
41773
|
+
datasets = [dataset];
|
|
41307
41774
|
}
|
|
41308
|
-
datasets = normalizeImportedDatasets(dataset);
|
|
41309
41775
|
datasets = validateAndCleanGpkgSelection(datasets, opts);
|
|
41310
41776
|
|
|
41311
41777
|
if (opts.merge_files && files.length > 1) {
|
|
@@ -41422,9 +41888,12 @@ ${svg}
|
|
|
41422
41888
|
});
|
|
41423
41889
|
}
|
|
41424
41890
|
|
|
41425
|
-
// Let the web UI replace
|
|
41891
|
+
// Let the web UI replace path-based imports with a browser-friendly resolver.
|
|
41426
41892
|
function replaceImportFile(func) {
|
|
41427
41893
|
_importFile = func;
|
|
41894
|
+
_importDatasetsFromFile = async function(path, opts) {
|
|
41895
|
+
return normalizeImportedDatasets(await func(path, opts));
|
|
41896
|
+
};
|
|
41428
41897
|
}
|
|
41429
41898
|
|
|
41430
41899
|
function importFile(path, opts) {
|
|
@@ -41432,69 +41901,29 @@ ${svg}
|
|
|
41432
41901
|
}
|
|
41433
41902
|
|
|
41434
41903
|
async function importFileAsync(path, opts) {
|
|
41435
|
-
return
|
|
41904
|
+
return denormalizeImportedDatasets(await importDatasetsFromFile(path, opts));
|
|
41436
41905
|
}
|
|
41437
41906
|
|
|
41438
|
-
|
|
41439
|
-
|
|
41440
|
-
|
|
41441
|
-
|
|
41442
|
-
cache = opts && opts.input || null,
|
|
41443
|
-
cached = cache && (path in cache),
|
|
41444
|
-
content;
|
|
41445
|
-
|
|
41446
|
-
cli.checkFileExists(path, cache);
|
|
41447
|
-
|
|
41448
|
-
if ((fileType == 'shp' || fileType == 'json' || fileType == 'text' || fileType == 'dbf' ||
|
|
41449
|
-
fileType == 'gpkg') && !cached) {
|
|
41450
|
-
// these file types are read incrementally
|
|
41451
|
-
content = null;
|
|
41452
|
-
|
|
41453
|
-
} else if (fileType && isSupportedBinaryInputType(path)) {
|
|
41454
|
-
content = cli.readFile(path, null, cache);
|
|
41455
|
-
if (utils.isString(content)) {
|
|
41456
|
-
// Fix for issue #264 (applyCommands() input is file path instead of binary content)
|
|
41457
|
-
stop$1('Expected binary content, received a string');
|
|
41458
|
-
}
|
|
41459
|
-
|
|
41460
|
-
} else if (fileType) { // string type, e.g. kml, geojson
|
|
41461
|
-
content = cli.readFile(path, encoding || 'utf-8', cache);
|
|
41462
|
-
|
|
41463
|
-
} else if (getFileExtension(path) == 'gz') {
|
|
41464
|
-
var pathgz = path;
|
|
41465
|
-
path = pathgz.replace(/\.gz$/, '');
|
|
41466
|
-
fileType = guessInputFileType(path);
|
|
41467
|
-
if (!fileType) {
|
|
41468
|
-
stop$1('Unrecognized file type:', path);
|
|
41469
|
-
}
|
|
41470
|
-
content = gunzipSync(cli.readFile(pathgz, null, cache), path);
|
|
41471
|
-
|
|
41472
|
-
} else { // type can't be inferred from filename -- try reading as text
|
|
41473
|
-
content = cli.readFile(path, encoding || 'utf-8', cache);
|
|
41474
|
-
fileType = guessInputContentType(content);
|
|
41475
|
-
if (fileType == 'text' && content.indexOf('\ufffd') > -1) {
|
|
41476
|
-
// invalidate string data that contains the 'replacement character'
|
|
41477
|
-
fileType = null;
|
|
41478
|
-
}
|
|
41479
|
-
}
|
|
41907
|
+
// Canonical path import interface.
|
|
41908
|
+
async function importDatasetsFromFile(path, opts) {
|
|
41909
|
+
return _importDatasetsFromFile(path, opts);
|
|
41910
|
+
}
|
|
41480
41911
|
|
|
41481
|
-
|
|
41482
|
-
|
|
41483
|
-
}
|
|
41484
|
-
input[fileType] = {filename: path, content: content};
|
|
41485
|
-
content = null; // for g.c.
|
|
41486
|
-
if (fileType == 'shp' || fileType == 'dbf') {
|
|
41487
|
-
readShapefileAuxFiles(path, input, cache);
|
|
41488
|
-
} else if (isRasterImageInputType(fileType)) {
|
|
41489
|
-
readRasterImageAuxFiles(path, input, cache);
|
|
41490
|
-
}
|
|
41491
|
-
if (fileType == 'shp' && !input.dbf) {
|
|
41492
|
-
message(utils.format("[%s] .dbf file is missing - shapes imported without attribute data.", path));
|
|
41493
|
-
}
|
|
41912
|
+
var _importFile = function(path, opts) {
|
|
41913
|
+
var input = prepareImportFile(path, opts);
|
|
41494
41914
|
return importContent(input, opts);
|
|
41495
41915
|
};
|
|
41496
41916
|
|
|
41497
|
-
async function
|
|
41917
|
+
var _importDatasetsFromFile = async function(path, opts) {
|
|
41918
|
+
var input = prepareImportFile(path, opts);
|
|
41919
|
+
return importDatasetsFromContent(input, opts);
|
|
41920
|
+
};
|
|
41921
|
+
|
|
41922
|
+
// Read a file (or cache entry) and collect any sidecars into the normalized
|
|
41923
|
+
// content-group shape consumed by the content importers.
|
|
41924
|
+
// File acquisition is currently synchronous in both import paths; only some
|
|
41925
|
+
// format parsers require asynchronous work.
|
|
41926
|
+
function prepareImportFile(path, opts) {
|
|
41498
41927
|
var fileType = guessInputFileType(path),
|
|
41499
41928
|
input = {},
|
|
41500
41929
|
encoding = opts && opts.encoding || null,
|
|
@@ -41504,7 +41933,8 @@ ${svg}
|
|
|
41504
41933
|
|
|
41505
41934
|
cli.checkFileExists(path, cache);
|
|
41506
41935
|
|
|
41507
|
-
if ((fileType == 'shp' || fileType == 'json' || fileType == 'text' || fileType == 'dbf'
|
|
41936
|
+
if ((fileType == 'shp' || fileType == 'json' || fileType == 'text' || fileType == 'dbf' ||
|
|
41937
|
+
fileType == 'gpkg') && !cached) {
|
|
41508
41938
|
// these file types are read incrementally
|
|
41509
41939
|
content = null;
|
|
41510
41940
|
|
|
@@ -41547,37 +41977,10 @@ ${svg}
|
|
|
41547
41977
|
if (fileType == 'shp' && !input.dbf) {
|
|
41548
41978
|
message(utils.format("[%s] .dbf file is missing - shapes imported without attribute data.", path));
|
|
41549
41979
|
}
|
|
41550
|
-
return
|
|
41551
|
-
}
|
|
41552
|
-
|
|
41553
|
-
// Import multiple files to a single dataset
|
|
41554
|
-
function importFilesTogether(files, opts) {
|
|
41555
|
-
var unbuiltTopology = false;
|
|
41556
|
-
var datasets = files.reduce(function(memo, fname) {
|
|
41557
|
-
// import without topology or snapping
|
|
41558
|
-
var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
|
|
41559
|
-
var imported = normalizeImportedDatasets(importFile(fname, importOpts));
|
|
41560
|
-
// check if dataset contains non-topological paths
|
|
41561
|
-
// TODO: may also need to rebuild topology if multiple topojson files are merged
|
|
41562
|
-
imported.forEach(function(dataset) {
|
|
41563
|
-
if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
|
|
41564
|
-
unbuiltTopology = true;
|
|
41565
|
-
}
|
|
41566
|
-
memo.push(dataset);
|
|
41567
|
-
});
|
|
41568
|
-
return memo;
|
|
41569
|
-
}, []);
|
|
41570
|
-
var combined = mergeDatasets(datasets);
|
|
41571
|
-
// Build topology, if needed
|
|
41572
|
-
// TODO: consider updating topology of TopoJSON files instead of concatenating arcs
|
|
41573
|
-
// (but problem of mismatched coordinates due to quantization in input files.)
|
|
41574
|
-
if (unbuiltTopology && !opts.no_topology) {
|
|
41575
|
-
cleanPathsAfterImport(combined, opts);
|
|
41576
|
-
buildTopology(combined);
|
|
41577
|
-
}
|
|
41578
|
-
return combined;
|
|
41980
|
+
return input;
|
|
41579
41981
|
}
|
|
41580
41982
|
|
|
41983
|
+
// Import multiple files to a single dataset.
|
|
41581
41984
|
async function importFilesTogetherAsync(files, opts) {
|
|
41582
41985
|
var unbuiltTopology = false;
|
|
41583
41986
|
var datasets = [];
|
|
@@ -41585,7 +41988,7 @@ ${svg}
|
|
|
41585
41988
|
for (var fname of files) {
|
|
41586
41989
|
// import without topology or snapping
|
|
41587
41990
|
var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
|
|
41588
|
-
var imported =
|
|
41991
|
+
var imported = await importDatasetsFromFile(fname, importOpts);
|
|
41589
41992
|
imported.forEach(function(dataset) {
|
|
41590
41993
|
if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
|
|
41591
41994
|
unbuiltTopology = true;
|
|
@@ -41647,6 +42050,10 @@ ${svg}
|
|
|
41647
42050
|
return Array.isArray(datasetOrArray) ? datasetOrArray : [datasetOrArray];
|
|
41648
42051
|
}
|
|
41649
42052
|
|
|
42053
|
+
function denormalizeImportedDatasets(datasets) {
|
|
42054
|
+
return datasets.length == 1 ? datasets[0] : datasets;
|
|
42055
|
+
}
|
|
42056
|
+
|
|
41650
42057
|
function normalizeImportedTarget(datasets) {
|
|
41651
42058
|
if (datasets.length == 1) return datasets[0];
|
|
41652
42059
|
return {
|
|
@@ -41746,9 +42153,9 @@ ${svg}
|
|
|
41746
42153
|
|
|
41747
42154
|
var FileImport = /*#__PURE__*/Object.freeze({
|
|
41748
42155
|
__proto__: null,
|
|
42156
|
+
importDatasetsFromFile: importDatasetsFromFile,
|
|
41749
42157
|
importFile: importFile,
|
|
41750
42158
|
importFileAsync: importFileAsync,
|
|
41751
|
-
importFilesTogether: importFilesTogether,
|
|
41752
42159
|
importFilesTogetherAsync: importFilesTogetherAsync,
|
|
41753
42160
|
replaceImportFile: replaceImportFile
|
|
41754
42161
|
});
|
|
@@ -41778,31 +42185,37 @@ ${svg}
|
|
|
41778
42185
|
return /[$][{]/.test(name);
|
|
41779
42186
|
}
|
|
41780
42187
|
|
|
41781
|
-
function
|
|
42188
|
+
async function findCommandSourceAsync(sourceName, catalog, opts) {
|
|
41782
42189
|
var source = catalog.findSingleLayer(sourceName);
|
|
41783
|
-
var
|
|
42190
|
+
var sourceDatasets;
|
|
41784
42191
|
if (!source) {
|
|
41785
|
-
//
|
|
41786
|
-
|
|
41787
|
-
|
|
41788
|
-
// clip/erase -- topology is built later, when datasets are combined
|
|
41789
|
-
sourceDataset = importFile(sourceName, utils.defaults({no_topology: true}, opts));
|
|
41790
|
-
if (!sourceDataset) {
|
|
41791
|
-
stop$1(utils.format('Unable to find source [%s]', sourceName));
|
|
41792
|
-
} else if (sourceDataset.layers.length > 1) {
|
|
41793
|
-
stop$1('Multiple-layer sources are not supported');
|
|
41794
|
-
}
|
|
41795
|
-
// mark as disposable to indicate that data can be mutated
|
|
41796
|
-
source = {dataset: sourceDataset, layer: sourceDataset.layers[0], disposable: true};
|
|
42192
|
+
// Source-file topology is built later if it is needed by the command.
|
|
42193
|
+
sourceDatasets = await importDatasetsFromFile(sourceName, utils.defaults({no_topology: true}, opts));
|
|
42194
|
+
source = getImportedSource(sourceDatasets, sourceName);
|
|
41797
42195
|
}
|
|
41798
42196
|
return source;
|
|
41799
42197
|
}
|
|
41800
42198
|
|
|
42199
|
+
function getImportedSource(sourceDatasets, sourceName) {
|
|
42200
|
+
if (sourceDatasets.length != 1) {
|
|
42201
|
+
if (sourceDatasets.length > 1) {
|
|
42202
|
+
stop$1('Multiple-dataset sources are not supported');
|
|
42203
|
+
}
|
|
42204
|
+
stop$1(utils.format('Unable to find source [%s]', sourceName));
|
|
42205
|
+
}
|
|
42206
|
+
var sourceDataset = sourceDatasets[0];
|
|
42207
|
+
if (sourceDataset.layers.length > 1) {
|
|
42208
|
+
stop$1('Multiple-layer sources are not supported');
|
|
42209
|
+
}
|
|
42210
|
+
// mark as disposable to indicate that data can be mutated
|
|
42211
|
+
return {dataset: sourceDataset, layer: sourceDataset.layers[0], disposable: true};
|
|
42212
|
+
}
|
|
42213
|
+
|
|
41801
42214
|
var SourceUtils = /*#__PURE__*/Object.freeze({
|
|
41802
42215
|
__proto__: null,
|
|
41803
42216
|
convertInterpolatedName: convertInterpolatedName,
|
|
41804
42217
|
convertSourceName: convertSourceName,
|
|
41805
|
-
|
|
42218
|
+
findCommandSourceAsync: findCommandSourceAsync
|
|
41806
42219
|
});
|
|
41807
42220
|
|
|
41808
42221
|
// Catalog contains zero or more multi-layer datasets
|
|
@@ -43657,6 +44070,13 @@ ${svg}
|
|
|
43657
44070
|
return new GeographicLib.Geodesic.Geodesic(P.a, f);
|
|
43658
44071
|
}
|
|
43659
44072
|
|
|
44073
|
+
function getGeodesicDistanceFunction(P) {
|
|
44074
|
+
var geod = getGeodesic(P);
|
|
44075
|
+
return function(lng, lat, lng2, lat2) {
|
|
44076
|
+
return geod.Inverse(lat, lng, lat2, lng2).s12;
|
|
44077
|
+
};
|
|
44078
|
+
}
|
|
44079
|
+
|
|
43660
44080
|
function interpolatePoint2D(ax, ay, bx, by, k) {
|
|
43661
44081
|
var j = 1 - k;
|
|
43662
44082
|
return [ax * j + bx * k, ay * j + by * k];
|
|
@@ -43759,6 +44179,7 @@ ${svg}
|
|
|
43759
44179
|
bearingDegrees2D: bearingDegrees2D,
|
|
43760
44180
|
getBearingFunction: getBearingFunction,
|
|
43761
44181
|
getFastGeodeticSegmentFunction: getFastGeodeticSegmentFunction,
|
|
44182
|
+
getGeodesicDistanceFunction: getGeodesicDistanceFunction,
|
|
43762
44183
|
getGeodeticSegmentFunction: getGeodeticSegmentFunction,
|
|
43763
44184
|
getInterpolationFunction: getInterpolationFunction,
|
|
43764
44185
|
getPlanarSegmentEndpoint: getPlanarSegmentEndpoint,
|
|
@@ -45199,7 +45620,7 @@ ${svg}
|
|
|
45199
45620
|
|
|
45200
45621
|
function stopIfBufferReachesPole(shape, dist) {
|
|
45201
45622
|
var maxAbsLat = 0;
|
|
45202
|
-
var angularDist = dist / R$3 * R2D$
|
|
45623
|
+
var angularDist = dist / R$3 * R2D$6;
|
|
45203
45624
|
(shape || []).forEach(function(path) {
|
|
45204
45625
|
latLngPathIter.init(path);
|
|
45205
45626
|
while (latLngPathIter.hasNext()) {
|
|
@@ -47316,12 +47737,12 @@ ${svg}
|
|
|
47316
47737
|
}
|
|
47317
47738
|
|
|
47318
47739
|
function projectBufferPoint(x, y, spherical) {
|
|
47319
|
-
return spherical ? [x * D2R$
|
|
47740
|
+
return spherical ? [x * D2R$7 * R$3, Math.log(Math.tan(Math.PI / 4 + y * D2R$7 / 2)) * R$3] :
|
|
47320
47741
|
[x, y];
|
|
47321
47742
|
}
|
|
47322
47743
|
|
|
47323
47744
|
function unprojectBufferPoint(x, y, spherical) {
|
|
47324
|
-
return spherical ? [x / (D2R$
|
|
47745
|
+
return spherical ? [x / (D2R$7 * R$3), (2 * Math.atan(Math.exp(y / R$3)) - Math.PI / 2) / (D2R$7)] :
|
|
47325
47746
|
[x, y];
|
|
47326
47747
|
}
|
|
47327
47748
|
|
|
@@ -51992,7 +52413,7 @@ ${svg}
|
|
|
51992
52413
|
var maxAbsLat = Math.max(Math.abs(bounds.ymin), Math.abs(bounds.ymax));
|
|
51993
52414
|
var maxPositiveDistance = getMaxPositiveBufferDistance(lyr, dataset, opts);
|
|
51994
52415
|
if (!(maxPositiveDistance > 0)) return false;
|
|
51995
|
-
return maxAbsLat + maxPositiveDistance / R$3 * R2D$
|
|
52416
|
+
return maxAbsLat + maxPositiveDistance / R$3 * R2D$6 >= 90 - POLAR_BUFFER_MARGIN_DEGREES;
|
|
51996
52417
|
}
|
|
51997
52418
|
|
|
51998
52419
|
function getMaxPositiveBufferDistance(lyr, dataset, opts) {
|
|
@@ -53244,7 +53665,7 @@ ${svg}
|
|
|
53244
53665
|
}
|
|
53245
53666
|
|
|
53246
53667
|
function getCoordinateDistance(distance, arcs) {
|
|
53247
|
-
return arcs.isPlanar() ? distance : distance / R$3 * R2D$
|
|
53668
|
+
return arcs.isPlanar() ? distance : distance / R$3 * R2D$6;
|
|
53248
53669
|
}
|
|
53249
53670
|
|
|
53250
53671
|
// @shapeIndex: chunk-bounds index of the source shape (see buildShapeSegmentIndex)
|
|
@@ -53913,7 +54334,7 @@ ${svg}
|
|
|
53913
54334
|
// depending on parameters
|
|
53914
54335
|
if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
|
|
53915
54336
|
'ocea,omerc,tmerc,etmerc,nicol,dymaxion,dymaxion2,butterfly,butterfly2,' +
|
|
53916
|
-
'cahill_keyes')) {
|
|
54337
|
+
'cahill_keyes,narukawa2022')) {
|
|
53917
54338
|
return false;
|
|
53918
54339
|
}
|
|
53919
54340
|
if (isAzimuthal(P)) {
|
|
@@ -53965,16 +54386,16 @@ ${svg}
|
|
|
53965
54386
|
}
|
|
53966
54387
|
|
|
53967
54388
|
function getRotationFunction2(rotation, inv) {
|
|
53968
|
-
var a = (rotation[0] || 0) * D2R$
|
|
53969
|
-
b = (rotation[1] || 0) * D2R$
|
|
53970
|
-
c = (rotation[2] || 0) * D2R$
|
|
54389
|
+
var a = (rotation[0] || 0) * D2R$7,
|
|
54390
|
+
b = (rotation[1] || 0) * D2R$7,
|
|
54391
|
+
c = (rotation[2] || 0) * D2R$7;
|
|
53971
54392
|
return function(p) {
|
|
53972
|
-
p[0] *= D2R$
|
|
53973
|
-
p[1] *= D2R$
|
|
54393
|
+
p[0] *= D2R$7;
|
|
54394
|
+
p[1] *= D2R$7;
|
|
53974
54395
|
var rotate = inv ? rotatePointInv : rotatePoint;
|
|
53975
54396
|
rotate(p, a, b, c);
|
|
53976
|
-
p[0] *= R2D$
|
|
53977
|
-
p[1] *= R2D$
|
|
54397
|
+
p[0] *= R2D$6;
|
|
54398
|
+
p[1] *= R2D$6;
|
|
53978
54399
|
return p;
|
|
53979
54400
|
};
|
|
53980
54401
|
}
|
|
@@ -60312,7 +60733,7 @@ ${svg}
|
|
|
60312
60733
|
// Isometric ("Mercator-stretched") latitude in degrees-in; returns +/-Infinity at
|
|
60313
60734
|
// the poles.
|
|
60314
60735
|
function isometricLatitude(latDeg) {
|
|
60315
|
-
return Math.log(Math.tan(Math.PI / 4 + latDeg * D2R$
|
|
60736
|
+
return Math.log(Math.tan(Math.PI / 4 + latDeg * D2R$7 / 2));
|
|
60316
60737
|
}
|
|
60317
60738
|
|
|
60318
60739
|
// Rhumb-line (loxodrome) interpolation, fraction k of the way from A to B.
|
|
@@ -60337,9 +60758,9 @@ ${svg}
|
|
|
60337
60758
|
// Rhumb-line distance in meters, using the raw longitude delta (so a full-parallel
|
|
60338
60759
|
// sweep returns the parallel's length rather than 0).
|
|
60339
60760
|
function rhumbDistance(a, b) {
|
|
60340
|
-
var phi1 = a[1] * D2R$
|
|
60761
|
+
var phi1 = a[1] * D2R$7, phi2 = b[1] * D2R$7;
|
|
60341
60762
|
var dPhi = phi2 - phi1;
|
|
60342
|
-
var dLambda = (b[0] - a[0]) * D2R$
|
|
60763
|
+
var dLambda = (b[0] - a[0]) * D2R$7; // raw
|
|
60343
60764
|
var dPsi = Math.log(Math.tan(Math.PI / 4 + phi2 / 2) / Math.tan(Math.PI / 4 + phi1 / 2));
|
|
60344
60765
|
var q = Math.abs(dPsi) > 1e-12 ? dPhi / dPsi : Math.cos(phi1);
|
|
60345
60766
|
return Math.sqrt(dPhi * dPhi + q * q * dLambda * dLambda) * R$3;
|
|
@@ -67498,6 +67919,9 @@ ${svg}
|
|
|
67498
67919
|
var commands;
|
|
67499
67920
|
try {
|
|
67500
67921
|
commands = parseCommands(commandStr);
|
|
67922
|
+
if (opts && opts.validate_commands) {
|
|
67923
|
+
opts.validate_commands(commands);
|
|
67924
|
+
}
|
|
67501
67925
|
} catch(e) {
|
|
67502
67926
|
e.message = 'Error in command file ' + file + ': ' + e.message;
|
|
67503
67927
|
throw e;
|
|
@@ -67519,6 +67943,9 @@ ${svg}
|
|
|
67519
67943
|
}
|
|
67520
67944
|
if (c.name == 'run') {
|
|
67521
67945
|
c.options._run_depth = depth;
|
|
67946
|
+
if (opts && opts.validate_commands) {
|
|
67947
|
+
c.options.validate_commands = opts.validate_commands;
|
|
67948
|
+
}
|
|
67522
67949
|
}
|
|
67523
67950
|
});
|
|
67524
67951
|
|
|
@@ -67556,6 +67983,9 @@ ${svg}
|
|
|
67556
67983
|
ctx = getBaseContext();
|
|
67557
67984
|
// io proxy adds ability to add datasets dynamically in a required function
|
|
67558
67985
|
ctx.io = getIOProxy();
|
|
67986
|
+
if (opts.input) {
|
|
67987
|
+
Object.assign(ctx.io._cache, opts.input);
|
|
67988
|
+
}
|
|
67559
67989
|
tmp = await evalTemplateExpression(opts.expression, targets, ctx);
|
|
67560
67990
|
if (tmp && !utils.isString(tmp)) {
|
|
67561
67991
|
stop$1('Expected a string containing mapshaper commands; received:', tmp);
|
|
@@ -67564,6 +67994,9 @@ ${svg}
|
|
|
67564
67994
|
// truncate message (command might include a large GeoJSON string in an -i command)
|
|
67565
67995
|
message(`command: [${truncateString(tmp, 150)}]`);
|
|
67566
67996
|
commands = parseCommands(tmp);
|
|
67997
|
+
if (opts.validate_commands) {
|
|
67998
|
+
opts.validate_commands(commands);
|
|
67999
|
+
}
|
|
67567
68000
|
|
|
67568
68001
|
// TODO: remove duplication with mapshaper-run-commands.mjs
|
|
67569
68002
|
var outputArr = opts && opts.output || null;
|
|
@@ -67578,6 +68011,9 @@ ${svg}
|
|
|
67578
68011
|
cmd.name == 'info' && cmd.options.save_to)) {
|
|
67579
68012
|
cmd.options.output = outputArr;
|
|
67580
68013
|
}
|
|
68014
|
+
if (cmd.name == 'run' && opts.validate_commands) {
|
|
68015
|
+
cmd.options.validate_commands = opts.validate_commands;
|
|
68016
|
+
}
|
|
67581
68017
|
});
|
|
67582
68018
|
|
|
67583
68019
|
await utils.promisify(runParsedCommands)(commands, job);
|
|
@@ -70114,7 +70550,7 @@ ${svg}
|
|
|
70114
70550
|
if (Object.prototype.hasOwnProperty.call(command, '_sourceOverride')) {
|
|
70115
70551
|
source = command._sourceOverride;
|
|
70116
70552
|
} else if (opts.source) {
|
|
70117
|
-
source =
|
|
70553
|
+
source = await findCommandSourceAsync(convertSourceName(opts.source, targets), job.catalog, opts);
|
|
70118
70554
|
}
|
|
70119
70555
|
|
|
70120
70556
|
// identify command target/input (for postprocessing)
|
|
@@ -70520,7 +70956,7 @@ ${svg}
|
|
|
70520
70956
|
var disposableSourceTargetIndex = -1;
|
|
70521
70957
|
|
|
70522
70958
|
if (command.options.source && !sourceNameIsInterpolated(command.options.source)) {
|
|
70523
|
-
source = resolveSourceForTargets(command, job, targets);
|
|
70959
|
+
source = await resolveSourceForTargets(command, job, targets);
|
|
70524
70960
|
items = moveSourceTargetLast(items, source);
|
|
70525
70961
|
disposableSourceTargetIndex = findLastDisposableSourceTarget(
|
|
70526
70962
|
items,
|
|
@@ -70555,10 +70991,10 @@ ${svg}
|
|
|
70555
70991
|
return job;
|
|
70556
70992
|
}
|
|
70557
70993
|
|
|
70558
|
-
function resolveSourceForTargets(command, job, targets) {
|
|
70994
|
+
async function resolveSourceForTargets(command, job, targets) {
|
|
70559
70995
|
job.startCommand(command);
|
|
70560
70996
|
try {
|
|
70561
|
-
return
|
|
70997
|
+
return await findCommandSourceAsync(
|
|
70562
70998
|
convertSourceName(command.options.source, targets),
|
|
70563
70999
|
job.catalog,
|
|
70564
71000
|
command.options
|
|
@@ -70660,7 +71096,7 @@ ${svg}
|
|
|
70660
71096
|
return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
|
|
70661
71097
|
}
|
|
70662
71098
|
|
|
70663
|
-
var version = "0.7.
|
|
71099
|
+
var version = "0.7.46";
|
|
70664
71100
|
|
|
70665
71101
|
// Parse command line args into commands and run them
|
|
70666
71102
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -70690,7 +71126,6 @@ ${svg}
|
|
|
70690
71126
|
if (err) {
|
|
70691
71127
|
return callback(err);
|
|
70692
71128
|
}
|
|
70693
|
-
if (opts.legacy) return callback(null, toLegacyOutputFormat(outputArr));
|
|
70694
71129
|
return callback(null, toOutputFormat(outputArr));
|
|
70695
71130
|
});
|
|
70696
71131
|
if (opts.promise) return opts.promise;
|
|
@@ -70732,9 +71167,6 @@ ${svg}
|
|
|
70732
71167
|
opts.callback = arg1;
|
|
70733
71168
|
} else if (utils.isFunction(arg2)) {
|
|
70734
71169
|
opts.callback = arg2;
|
|
70735
|
-
// identify legacy input format (used by some tests)
|
|
70736
|
-
opts.legacy = arg1 && guessInputContentType(arg1) != null;
|
|
70737
|
-
opts.input = arg1;
|
|
70738
71170
|
} else {
|
|
70739
71171
|
// if no callback, create a promise and a callback for resolving the promise
|
|
70740
71172
|
opts.promise = new Promise(function(resolve, reject) {
|
|
@@ -70744,7 +71176,7 @@ ${svg}
|
|
|
70744
71176
|
};
|
|
70745
71177
|
});
|
|
70746
71178
|
}
|
|
70747
|
-
if (
|
|
71179
|
+
if (utils.isObject(arg1)) {
|
|
70748
71180
|
if (arg1.xl) {
|
|
70749
71181
|
// options for runCommandsXL()
|
|
70750
71182
|
opts.options = arg1;
|
|
@@ -70777,12 +71209,6 @@ ${svg}
|
|
|
70777
71209
|
return callback(e);
|
|
70778
71210
|
}
|
|
70779
71211
|
|
|
70780
|
-
if (opts.legacy) {
|
|
70781
|
-
message("Warning: deprecated input format");
|
|
70782
|
-
commands = convertLegacyCommands(commands, inputObj);
|
|
70783
|
-
inputObj = null;
|
|
70784
|
-
}
|
|
70785
|
-
|
|
70786
71212
|
if (commands.length === 0) {
|
|
70787
71213
|
return callback(new UserError("No commands to run"));
|
|
70788
71214
|
}
|
|
@@ -70819,13 +71245,22 @@ ${svg}
|
|
|
70819
71245
|
// (e.g. `mapshaper *.shp batch-mode -o out.json` writing all inputs to the
|
|
70820
71246
|
// same target on disk).
|
|
70821
71247
|
var sharedOutputs = [];
|
|
70822
|
-
|
|
71248
|
+
runBatches().then(function(job) {
|
|
71249
|
+
done(null, job);
|
|
71250
|
+
}, done);
|
|
70823
71251
|
|
|
70824
|
-
function
|
|
70825
|
-
|
|
70826
|
-
|
|
70827
|
-
|
|
70828
|
-
|
|
71252
|
+
async function runBatches() {
|
|
71253
|
+
var job;
|
|
71254
|
+
for (var batch of batches) {
|
|
71255
|
+
try {
|
|
71256
|
+
job = await runParsedCommands(batch, new Job(null, {output_files: sharedOutputs}));
|
|
71257
|
+
} catch (e) {
|
|
71258
|
+
var fatalError = handleNonFatalError(e);
|
|
71259
|
+
if (fatalError) throw fatalError;
|
|
71260
|
+
job = undefined;
|
|
71261
|
+
}
|
|
71262
|
+
}
|
|
71263
|
+
return job;
|
|
70829
71264
|
}
|
|
70830
71265
|
|
|
70831
71266
|
function done(err, job) {
|
|
@@ -70839,33 +71274,6 @@ ${svg}
|
|
|
70839
71274
|
}
|
|
70840
71275
|
|
|
70841
71276
|
|
|
70842
|
-
function toLegacyOutputFormat(arr) {
|
|
70843
|
-
if (arr.length > 1) {
|
|
70844
|
-
// Return an array if multiple files are output
|
|
70845
|
-
return utils.pluck(arr, 'content');
|
|
70846
|
-
}
|
|
70847
|
-
if (arr.length == 1) {
|
|
70848
|
-
// Return content if a single file is output
|
|
70849
|
-
return arr[0].content;
|
|
70850
|
-
}
|
|
70851
|
-
return null;
|
|
70852
|
-
}
|
|
70853
|
-
|
|
70854
|
-
function convertLegacyCommands(arr, inputObj) {
|
|
70855
|
-
var i = utils.find(arr, function(cmd) {return cmd.name == 'i';});
|
|
70856
|
-
var o = utils.find(arr, function(cmd) {return cmd.name == 'o';});
|
|
70857
|
-
if (!i) {
|
|
70858
|
-
i = {name: 'i', options: {}};
|
|
70859
|
-
arr.unshift(i);
|
|
70860
|
-
}
|
|
70861
|
-
i.options.files = ['__input__'];
|
|
70862
|
-
i.options.input = {__input__: inputObj};
|
|
70863
|
-
if (!o) {
|
|
70864
|
-
arr.push({name: 'o', options: {}});
|
|
70865
|
-
}
|
|
70866
|
-
return arr;
|
|
70867
|
-
}
|
|
70868
|
-
|
|
70869
71277
|
// TODO: rewrite tests and remove this function
|
|
70870
71278
|
function testCommands(argv, done) {
|
|
70871
71279
|
_runCommands(argv, {}, function(err, job) {
|
|
@@ -70883,9 +71291,20 @@ ${svg}
|
|
|
70883
71291
|
// Execute a sequence of parsed commands
|
|
70884
71292
|
// @commands Array of parsed commands
|
|
70885
71293
|
// @job: Job object containing previously imported data
|
|
70886
|
-
// @done: function([error], [job])
|
|
71294
|
+
// @done: optional function([error], [job]); returns a Promise if omitted
|
|
70887
71295
|
//
|
|
70888
71296
|
function runParsedCommands(commands, job, done) {
|
|
71297
|
+
var promise = runParsedCommandsAsync(commands, job);
|
|
71298
|
+
if (done) {
|
|
71299
|
+
promise.then(function(job) {
|
|
71300
|
+
done(null, job);
|
|
71301
|
+
}, done);
|
|
71302
|
+
return;
|
|
71303
|
+
}
|
|
71304
|
+
return promise;
|
|
71305
|
+
}
|
|
71306
|
+
|
|
71307
|
+
async function runParsedCommandsAsync(commands, job) {
|
|
70889
71308
|
if (!job) job = new Job();
|
|
70890
71309
|
commands = readAndRemoveSettings(job, commands);
|
|
70891
71310
|
if (!runningInBrowser()) {
|
|
@@ -70893,26 +71312,16 @@ ${svg}
|
|
|
70893
71312
|
}
|
|
70894
71313
|
commands = runAndRemoveInfoCommands(commands);
|
|
70895
71314
|
if (commands.length === 0) {
|
|
70896
|
-
return
|
|
71315
|
+
return;
|
|
70897
71316
|
}
|
|
70898
71317
|
// we're no longer using the same Job for all batches -- no reset needed
|
|
70899
71318
|
// // resetting closes any unterminated -if blocks from a previous command sequence
|
|
70900
71319
|
// resetControlFlow(job);
|
|
70901
|
-
|
|
70902
|
-
|
|
70903
|
-
|
|
70904
|
-
var resolved;
|
|
70905
|
-
try {
|
|
70906
|
-
resolved = maybeInterpolateCommand(cmd, job);
|
|
70907
|
-
} catch(e) {
|
|
70908
|
-
return next(e);
|
|
70909
|
-
}
|
|
70910
|
-
runCommand(resolved, job).then(function(result) {
|
|
70911
|
-
next(null, result);
|
|
70912
|
-
}).catch(function(e) {
|
|
70913
|
-
next(e);
|
|
70914
|
-
});
|
|
71320
|
+
for (var command of commands) {
|
|
71321
|
+
var resolved = maybeInterpolateCommand(command, job);
|
|
71322
|
+
job = await runCommand(resolved, job);
|
|
70915
71323
|
}
|
|
71324
|
+
return job;
|
|
70916
71325
|
}
|
|
70917
71326
|
|
|
70918
71327
|
// Late-binding interpolation: just before each command runs, replace any
|
|
@@ -72526,6 +72935,7 @@ ${svg}
|
|
|
72526
72935
|
CustomProjections,
|
|
72527
72936
|
Dymaxion,
|
|
72528
72937
|
ButterflyProjections,
|
|
72938
|
+
Narukawa2022,
|
|
72529
72939
|
DataAggregation,
|
|
72530
72940
|
DatasetUtils,
|
|
72531
72941
|
DataUtils,
|