mapshaper 0.7.19 → 0.7.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mapshaper-gui +47 -3
- package/mapshaper.js +377 -52
- package/package.json +2 -2
- package/www/mapshaper-gui.js +121 -52
- package/www/mapshaper.js +377 -52
- package/www/modules.js +71 -0
- package/www/page.css +2 -0
- package/www/sponsor.html +3 -5
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$2(val, min, max) {
|
|
82
82
|
return val < min ? min : (val > max ? max : val);
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -751,7 +751,7 @@
|
|
|
751
751
|
function findValueByRank(arr, rank) {
|
|
752
752
|
if (!arr.length || rank < 1 || rank > arr.length) error$1("[findValueByRank()] invalid input");
|
|
753
753
|
|
|
754
|
-
rank = clamp$
|
|
754
|
+
rank = clamp$2(rank | 0, 1, arr.length);
|
|
755
755
|
var k = rank - 1, // conv. rank to array index
|
|
756
756
|
n = arr.length,
|
|
757
757
|
l = 0,
|
|
@@ -1125,7 +1125,7 @@
|
|
|
1125
1125
|
// self-import and the resulting Rollup circular-dependency warning.
|
|
1126
1126
|
var utils = {
|
|
1127
1127
|
addThousandsSep, addslashes, arrayToIndex,
|
|
1128
|
-
clamp: clamp$
|
|
1128
|
+
clamp: clamp$2, cleanNumericString, contains, copyElements, countValues, createBuffer,
|
|
1129
1129
|
defaults, difference,
|
|
1130
1130
|
endsWith, every, expandoBuffer, extend: extend$1, extendBuffer,
|
|
1131
1131
|
find: find$1, findMedian, findQuantile, findRankByValue, findStringPrefix,
|
|
@@ -6373,7 +6373,7 @@
|
|
|
6373
6373
|
}
|
|
6374
6374
|
|
|
6375
6375
|
function projectPoint(xy, crsFrom, crsTo) {
|
|
6376
|
-
if (
|
|
6376
|
+
if (crsHaveSameTransform(crsFrom, crsTo)) return xy.concat();
|
|
6377
6377
|
var proj = getProjTransform2(crsFrom, crsTo);
|
|
6378
6378
|
return proj(xy[0], xy[1]);
|
|
6379
6379
|
}
|
|
@@ -6418,6 +6418,16 @@
|
|
|
6418
6418
|
return !!str && str == crsToProj4(b);
|
|
6419
6419
|
}
|
|
6420
6420
|
|
|
6421
|
+
function crsHaveSameTransform(a, b) {
|
|
6422
|
+
var str = crsToNormalizedProj4(a);
|
|
6423
|
+
return !!str && str == crsToNormalizedProj4(b);
|
|
6424
|
+
}
|
|
6425
|
+
|
|
6426
|
+
function crsToNormalizedProj4(P) {
|
|
6427
|
+
var normalizer = mproj$1.internal && mproj$1.internal.get_normalized_proj_defn;
|
|
6428
|
+
return P && normalizer ? normalizer(P) : null;
|
|
6429
|
+
}
|
|
6430
|
+
|
|
6421
6431
|
function isProjAlias(str) {
|
|
6422
6432
|
return str in projectionAliases;
|
|
6423
6433
|
}
|
|
@@ -6690,6 +6700,7 @@
|
|
|
6690
6700
|
var Projections = /*#__PURE__*/Object.freeze({
|
|
6691
6701
|
__proto__: null,
|
|
6692
6702
|
crsAreEqual: crsAreEqual,
|
|
6703
|
+
crsHaveSameTransform: crsHaveSameTransform,
|
|
6693
6704
|
crsToPrj: crsToPrj,
|
|
6694
6705
|
crsToProj4: crsToProj4,
|
|
6695
6706
|
crsToWkt2: crsToWkt2,
|
|
@@ -7406,7 +7417,7 @@
|
|
|
7406
7417
|
i = fw ? arcId : ~arcId,
|
|
7407
7418
|
iter = _zz && _zlimit ? _filteredArcIter : _arcIter;
|
|
7408
7419
|
if (i >= _nn.length) {
|
|
7409
|
-
error("#getArcId() out-of-range arc id:", arcId);
|
|
7420
|
+
error("#getArcId() out-of-range arc id:", arcId, `(max id: ${_nn.length - 1})`);
|
|
7410
7421
|
}
|
|
7411
7422
|
return iter.init(_ii[i], _nn[i], fw, _zlimit);
|
|
7412
7423
|
};
|
|
@@ -17435,9 +17446,14 @@
|
|
|
17435
17446
|
var layers = layersArg.filter(getFeatureCount); // ignore empty layers
|
|
17436
17447
|
var merged = {};
|
|
17437
17448
|
opts = opts || {};
|
|
17449
|
+
if (!layers.length && layersArg.length > 1) {
|
|
17450
|
+
layers = layersArg; // merge all-empty layer sets
|
|
17451
|
+
}
|
|
17438
17452
|
if (!layers.length) return null;
|
|
17439
17453
|
if (layers.length == 1) {
|
|
17440
|
-
|
|
17454
|
+
if (layersArg.length == 1) {
|
|
17455
|
+
message('Use the target= option to specify multiple layers for merging');
|
|
17456
|
+
}
|
|
17441
17457
|
return layers.concat();
|
|
17442
17458
|
}
|
|
17443
17459
|
merged.data = mergeDataFromLayers(layers, opts);
|
|
@@ -30601,6 +30617,13 @@ ${svg}
|
|
|
30601
30617
|
.option('target', targetOpt)
|
|
30602
30618
|
.option('no-replace', noReplaceOpt);
|
|
30603
30619
|
|
|
30620
|
+
parser.command('blur')
|
|
30621
|
+
// .describe('apply a Gaussian-like blur to projected raster layers')
|
|
30622
|
+
.option('radius', {
|
|
30623
|
+
describe: '[raster] blur amount in pixels, corresponding to 2 * sigma (e.g. 10 or 10px)'
|
|
30624
|
+
})
|
|
30625
|
+
.option('target', targetOpt);
|
|
30626
|
+
|
|
30604
30627
|
parser.command('classify')
|
|
30605
30628
|
// .describe('apply sequential or categorical classification')
|
|
30606
30629
|
.describe('assign colors or values using one of several methods')
|
|
@@ -45268,23 +45291,23 @@ ${svg}
|
|
|
45268
45291
|
profileEnd('clipLayers');
|
|
45269
45292
|
return result;
|
|
45270
45293
|
}
|
|
45294
|
+
if (!usingPathClip) {
|
|
45295
|
+
result = clipLayersByClipDataset(targetLayers, clipDataset, type, opts);
|
|
45296
|
+
profileEnd('clipLayers');
|
|
45297
|
+
return result;
|
|
45298
|
+
}
|
|
45271
45299
|
profileStart('mergeLayersForOverlay');
|
|
45272
45300
|
mergedDataset = mergeLayersForOverlay2(targetLayers, targetDataset, clipDataset);
|
|
45273
45301
|
profileEnd('mergeLayersForOverlay');
|
|
45274
45302
|
clipLyr = mergedDataset.layers[mergedDataset.layers.length-1];
|
|
45275
|
-
|
|
45276
|
-
|
|
45277
|
-
|
|
45278
|
-
|
|
45279
|
-
|
|
45280
|
-
|
|
45281
|
-
|
|
45282
|
-
|
|
45283
|
-
profileEnd('clipDissolvePolygonLayer2');
|
|
45284
|
-
|
|
45285
|
-
} else {
|
|
45286
|
-
nodes = new NodeCollection(mergedDataset.arcs);
|
|
45287
|
-
}
|
|
45303
|
+
nodes = addIntersectionCuts(mergedDataset, opts);
|
|
45304
|
+
noteDatasetWillChange(targetDataset, {operation: type, unit: 'arcs'});
|
|
45305
|
+
targetDataset.arcs = mergedDataset.arcs;
|
|
45306
|
+
markDatasetChanged(targetDataset, {operation: type, unit: 'arcs'});
|
|
45307
|
+
profileStart('clipDissolvePolygonLayer2');
|
|
45308
|
+
clipLyr = utils.defaults({data: null}, clipLyr);
|
|
45309
|
+
clipLyr = dissolvePolygonLayer2(clipLyr, mergedDataset, {quiet: true, silent: true});
|
|
45310
|
+
profileEnd('clipDissolvePolygonLayer2');
|
|
45288
45311
|
|
|
45289
45312
|
profileStart('clipLayersByLayer');
|
|
45290
45313
|
result = clipLayersByLayer(targetLayers, clipLyr, nodes, type, opts);
|
|
@@ -45293,6 +45316,16 @@ ${svg}
|
|
|
45293
45316
|
return result;
|
|
45294
45317
|
}
|
|
45295
45318
|
|
|
45319
|
+
function clipLayersByClipDataset(targetLayers, clipDataset, type, opts) {
|
|
45320
|
+
var clipLyr = clipDataset.layers[0];
|
|
45321
|
+
var nodes = new NodeCollection(clipDataset.arcs);
|
|
45322
|
+
var result;
|
|
45323
|
+
profileStart('clipLayersByLayer');
|
|
45324
|
+
result = clipLayersByLayer(targetLayers, clipLyr, nodes, type, opts);
|
|
45325
|
+
profileEnd('clipLayersByLayer');
|
|
45326
|
+
return result;
|
|
45327
|
+
}
|
|
45328
|
+
|
|
45296
45329
|
function clipRasterLayers(targetLayers, clipSrc, targetDataset, type, opts) {
|
|
45297
45330
|
var clipDataset, clipBounds, bbox;
|
|
45298
45331
|
if (type != 'clip') {
|
|
@@ -51569,10 +51602,10 @@ ${svg}
|
|
|
51569
51602
|
|
|
51570
51603
|
function getTrianglePixelBounds(grid, p1, p2, p3) {
|
|
51571
51604
|
return [
|
|
51572
|
-
clamp(Math.floor(Math.min(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51573
|
-
clamp(Math.floor(Math.min(p1.y, p2.y, p3.y)), 0, grid.height - 1),
|
|
51574
|
-
clamp(Math.ceil(Math.max(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51575
|
-
clamp(Math.ceil(Math.max(p1.y, p2.y, p3.y)), 0, grid.height - 1)
|
|
51605
|
+
clamp$1(Math.floor(Math.min(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51606
|
+
clamp$1(Math.floor(Math.min(p1.y, p2.y, p3.y)), 0, grid.height - 1),
|
|
51607
|
+
clamp$1(Math.ceil(Math.max(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51608
|
+
clamp$1(Math.ceil(Math.max(p1.y, p2.y, p3.y)), 0, grid.height - 1)
|
|
51576
51609
|
];
|
|
51577
51610
|
}
|
|
51578
51611
|
|
|
@@ -51593,8 +51626,8 @@ ${svg}
|
|
|
51593
51626
|
}
|
|
51594
51627
|
|
|
51595
51628
|
function copyNearestRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
|
|
51596
|
-
var srcX = clamp(Math.floor(sx), 0, srcGrid.width - 1);
|
|
51597
|
-
var srcY = clamp(Math.floor(sy), 0, srcGrid.height - 1);
|
|
51629
|
+
var srcX = clamp$1(Math.floor(sx), 0, srcGrid.width - 1);
|
|
51630
|
+
var srcY = clamp$1(Math.floor(sy), 0, srcGrid.height - 1);
|
|
51598
51631
|
var src = (srcY * srcGrid.width + srcX) * srcGrid.bands;
|
|
51599
51632
|
var dest = (dy * destGrid.width + dx) * destGrid.bands;
|
|
51600
51633
|
if (!rasterSourcePixelIsCovered(srcGrid, srcX, srcY)) return;
|
|
@@ -51606,12 +51639,12 @@ ${svg}
|
|
|
51606
51639
|
}
|
|
51607
51640
|
|
|
51608
51641
|
function copyBilinearRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
|
|
51609
|
-
var srcX = clamp(Math.floor(sx - 0.5), 0, srcGrid.width - 1);
|
|
51610
|
-
var srcY = clamp(Math.floor(sy - 0.5), 0, srcGrid.height - 1);
|
|
51611
|
-
var srcX2 = clamp(srcX + 1, 0, srcGrid.width - 1);
|
|
51612
|
-
var srcY2 = clamp(srcY + 1, 0, srcGrid.height - 1);
|
|
51613
|
-
var tx = clamp(sx - 0.5 - srcX, 0, 1);
|
|
51614
|
-
var ty = clamp(sy - 0.5 - srcY, 0, 1);
|
|
51642
|
+
var srcX = clamp$1(Math.floor(sx - 0.5), 0, srcGrid.width - 1);
|
|
51643
|
+
var srcY = clamp$1(Math.floor(sy - 0.5), 0, srcGrid.height - 1);
|
|
51644
|
+
var srcX2 = clamp$1(srcX + 1, 0, srcGrid.width - 1);
|
|
51645
|
+
var srcY2 = clamp$1(srcY + 1, 0, srcGrid.height - 1);
|
|
51646
|
+
var tx = clamp$1(sx - 0.5 - srcX, 0, 1);
|
|
51647
|
+
var ty = clamp$1(sy - 0.5 - srcY, 0, 1);
|
|
51615
51648
|
var src00 = (srcY * srcGrid.width + srcX) * srcGrid.bands;
|
|
51616
51649
|
var src10 = (srcY * srcGrid.width + srcX2) * srcGrid.bands;
|
|
51617
51650
|
var src01 = (srcY2 * srcGrid.width + srcX) * srcGrid.bands;
|
|
@@ -51716,7 +51749,7 @@ ${svg}
|
|
|
51716
51749
|
return (x - a.x) * (b.y - a.y) - (y - a.y) * (b.x - a.x);
|
|
51717
51750
|
}
|
|
51718
51751
|
|
|
51719
|
-
function clamp(val, min, max) {
|
|
51752
|
+
function clamp$1(val, min, max) {
|
|
51720
51753
|
return val < min ? min : val > max ? max : val;
|
|
51721
51754
|
}
|
|
51722
51755
|
|
|
@@ -54972,17 +55005,17 @@ ${svg}
|
|
|
54972
55005
|
print(msgArg || '');
|
|
54973
55006
|
};
|
|
54974
55007
|
|
|
54975
|
-
cmd.renameLayers = function(layers, names
|
|
55008
|
+
cmd.renameLayers = function(layers, names) {
|
|
54976
55009
|
if (names && names.join('').indexOf('=') > -1) {
|
|
54977
|
-
renameByAssignment(names,
|
|
55010
|
+
renameByAssignment(names, layers);
|
|
54978
55011
|
} else {
|
|
54979
55012
|
renameTargetLayers(names, layers);
|
|
54980
55013
|
}
|
|
54981
55014
|
};
|
|
54982
55015
|
|
|
54983
|
-
function renameByAssignment(names,
|
|
55016
|
+
function renameByAssignment(names, layers) {
|
|
54984
55017
|
var index = mapLayerNames(names);
|
|
54985
|
-
|
|
55018
|
+
layers.forEach(function(lyr) {
|
|
54986
55019
|
if (index[lyr.name]) {
|
|
54987
55020
|
noteLayerMetadataWillChange(lyr, {operation: 'rename-layers'});
|
|
54988
55021
|
lyr.name = index[lyr.name];
|
|
@@ -54993,17 +55026,14 @@ ${svg}
|
|
|
54993
55026
|
|
|
54994
55027
|
function renameTargetLayers(names, layers) {
|
|
54995
55028
|
var nameCount = names && names.length || 0;
|
|
54996
|
-
|
|
54997
|
-
|
|
55029
|
+
if (nameCount != layers.length) {
|
|
55030
|
+
stop$1("Expected one name for each target layer; received " + nameCount +
|
|
55031
|
+
" name" + (nameCount == 1 ? "" : "s") + " for " + layers.length +
|
|
55032
|
+
" target layer" + (layers.length == 1 ? "" : "s"));
|
|
55033
|
+
}
|
|
54998
55034
|
layers.forEach(function(lyr, i) {
|
|
54999
|
-
if (i < nameCount) {
|
|
55000
|
-
name = names[i];
|
|
55001
|
-
}
|
|
55002
|
-
if (name && nameCount < layers.length && (i >= nameCount - 1)) {
|
|
55003
|
-
suffix = (suffix || 0) + 1;
|
|
55004
|
-
}
|
|
55005
55035
|
noteLayerMetadataWillChange(lyr, {operation: 'rename-layers'});
|
|
55006
|
-
lyr.name =
|
|
55036
|
+
lyr.name = names[i];
|
|
55007
55037
|
markLayerMetadataChanged(lyr, {operation: 'rename-layers'});
|
|
55008
55038
|
});
|
|
55009
55039
|
}
|
|
@@ -57859,7 +57889,7 @@ ${svg}
|
|
|
57859
57889
|
name == 'require' || name == 'drop' || name == 'target' ||
|
|
57860
57890
|
name == 'if' || name == 'elif' || name == 'else' || name == 'endif' ||
|
|
57861
57891
|
name == 'run' || name == 'i' || name == 'snap' || name == 'frame' ||
|
|
57862
|
-
name == 'comment';
|
|
57892
|
+
name == 'comment' || name == 'rename-layers';
|
|
57863
57893
|
}
|
|
57864
57894
|
|
|
57865
57895
|
function commandAcceptsEmptyTarget(name) {
|
|
@@ -57900,8 +57930,7 @@ ${svg}
|
|
|
57900
57930
|
T$1.start();
|
|
57901
57931
|
|
|
57902
57932
|
if (name == 'rename-layers') {
|
|
57903
|
-
|
|
57904
|
-
targets = job.catalog.findCommandTargets(opts.target || '*');
|
|
57933
|
+
targets = job.catalog.findCommandTargets(opts.target);
|
|
57905
57934
|
targetLayers = targets.reduce(function(memo, obj) {
|
|
57906
57935
|
return memo.concat(obj.layers);
|
|
57907
57936
|
}, []);
|
|
@@ -57970,6 +57999,9 @@ ${svg}
|
|
|
57970
57999
|
outputLayers = applyCommandToEachLayer(cmd.buffer, targetLayers, targetDataset, opts);
|
|
57971
58000
|
// outputLayers = cmd.buffer(targetLayers, targetDataset, opts);
|
|
57972
58001
|
|
|
58002
|
+
} else if (name == 'blur') {
|
|
58003
|
+
cmd.blur(targetLayers, targetDataset, opts);
|
|
58004
|
+
|
|
57973
58005
|
} else if (name == 'data-fill') {
|
|
57974
58006
|
applyCommandToEachLayer(cmd.dataFill, targetLayers, arcs, opts);
|
|
57975
58007
|
|
|
@@ -58176,7 +58208,7 @@ ${svg}
|
|
|
58176
58208
|
applyCommandToEachLayer(cmd.renameFields, targetLayers, opts.fields);
|
|
58177
58209
|
|
|
58178
58210
|
} else if (name == 'rename-layers') {
|
|
58179
|
-
cmd.renameLayers(targetLayers, opts.names
|
|
58211
|
+
cmd.renameLayers(targetLayers, opts.names);
|
|
58180
58212
|
|
|
58181
58213
|
} else if (name == 'require') {
|
|
58182
58214
|
await cmd.require(opts);
|
|
@@ -58282,8 +58314,7 @@ ${svg}
|
|
|
58282
58314
|
// TODO: consider replacing old layers as they are generated, for gc
|
|
58283
58315
|
replaceLayers(targetDataset, targetLayers, outputLayers);
|
|
58284
58316
|
// some operations leave unreferenced arcs that should be cleaned up
|
|
58285
|
-
if ((name
|
|
58286
|
-
name == 'rectangles' || name == 'filter' && opts.cleanup) && !opts.no_cleanup) {
|
|
58317
|
+
if (commandNeedsArcDissolve(name, targetLayers, opts)) {
|
|
58287
58318
|
dissolveArcs(targetDataset);
|
|
58288
58319
|
}
|
|
58289
58320
|
}
|
|
@@ -58330,7 +58361,15 @@ ${svg}
|
|
|
58330
58361
|
});
|
|
58331
58362
|
}
|
|
58332
58363
|
|
|
58333
|
-
|
|
58364
|
+
function commandNeedsArcDissolve(name, targetLayers, opts) {
|
|
58365
|
+
if (opts.no_cleanup) return false;
|
|
58366
|
+
if (name == 'clip' || name == 'erase') {
|
|
58367
|
+
return utils.some(targetLayers || [], layerHasPaths);
|
|
58368
|
+
}
|
|
58369
|
+
return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
|
|
58370
|
+
}
|
|
58371
|
+
|
|
58372
|
+
var version = "0.7.21";
|
|
58334
58373
|
|
|
58335
58374
|
// Parse command line args into commands and run them
|
|
58336
58375
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -59019,6 +59058,291 @@ ${svg}
|
|
|
59019
59058
|
return false;
|
|
59020
59059
|
}
|
|
59021
59060
|
|
|
59061
|
+
var BOX_BLUR_PASSES = 3;
|
|
59062
|
+
|
|
59063
|
+
function blurRasterGrid(raster, optsArg) {
|
|
59064
|
+
var opts = optsArg || {};
|
|
59065
|
+
var grid = getRasterGrid(raster);
|
|
59066
|
+
var radius = getBlurRadius(opts);
|
|
59067
|
+
var sigma = radius / 2;
|
|
59068
|
+
var boxes = getGaussianBoxWidths(sigma, BOX_BLUR_PASSES);
|
|
59069
|
+
var samples = new grid.samples.constructor(grid.samples.length);
|
|
59070
|
+
var tmp = new Float32Array(grid.width * grid.height);
|
|
59071
|
+
var channel = new Float32Array(grid.width * grid.height);
|
|
59072
|
+
var weights = getRasterBlurWeights(grid);
|
|
59073
|
+
validateBlurGrid(grid);
|
|
59074
|
+
if (grid.bands == 4) {
|
|
59075
|
+
blurRgbaGrid(grid, samples, channel, tmp, weights, boxes);
|
|
59076
|
+
return Object.assign({}, grid, {
|
|
59077
|
+
samples: samples
|
|
59078
|
+
});
|
|
59079
|
+
}
|
|
59080
|
+
for (var band = 0; band < grid.bands; band++) {
|
|
59081
|
+
copyBandToChannel(grid, band, channel);
|
|
59082
|
+
blurChannel(channel, tmp, weights, grid.width, grid.height, boxes);
|
|
59083
|
+
copyChannelToBand(channel, samples, grid, band);
|
|
59084
|
+
}
|
|
59085
|
+
return Object.assign({}, grid, {
|
|
59086
|
+
samples: samples
|
|
59087
|
+
});
|
|
59088
|
+
}
|
|
59089
|
+
|
|
59090
|
+
function getBlurRadius(opts) {
|
|
59091
|
+
var arg = opts.radius;
|
|
59092
|
+
var radius;
|
|
59093
|
+
if (arg == null || arg === '') stop$1('Missing blur radius');
|
|
59094
|
+
if (typeof arg == 'string') {
|
|
59095
|
+
arg = arg.trim().replace(/px$/i, '');
|
|
59096
|
+
}
|
|
59097
|
+
radius = Number(arg);
|
|
59098
|
+
if (!(radius > 0 && isFinite(radius))) {
|
|
59099
|
+
stop$1('Expected radius= to be a positive pixel value');
|
|
59100
|
+
}
|
|
59101
|
+
return radius;
|
|
59102
|
+
}
|
|
59103
|
+
|
|
59104
|
+
function validateBlurGrid(grid) {
|
|
59105
|
+
if (!grid || !grid.samples || !grid.width || !grid.height || !grid.bands) {
|
|
59106
|
+
stop$1('Expected a raster grid');
|
|
59107
|
+
}
|
|
59108
|
+
}
|
|
59109
|
+
|
|
59110
|
+
// Convert a Gaussian sigma to box widths using the method described by
|
|
59111
|
+
// Ivan Kutskir / Peter Kovesi. Three box passes are a close, fast approximation.
|
|
59112
|
+
function getGaussianBoxWidths(sigma, n) {
|
|
59113
|
+
var ideal = Math.sqrt((12 * sigma * sigma / n) + 1);
|
|
59114
|
+
var wl = Math.floor(ideal);
|
|
59115
|
+
if (wl % 2 === 0) wl--;
|
|
59116
|
+
var wu = wl + 2;
|
|
59117
|
+
var m = Math.round((12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4));
|
|
59118
|
+
var boxes = [];
|
|
59119
|
+
for (var i = 0; i < n; i++) {
|
|
59120
|
+
boxes.push(i < m ? wl : wu);
|
|
59121
|
+
}
|
|
59122
|
+
return boxes;
|
|
59123
|
+
}
|
|
59124
|
+
|
|
59125
|
+
function blurRgbaGrid(grid, samples, channel, tmp, weights, boxes) {
|
|
59126
|
+
var alpha = new Float32Array(grid.width * grid.height);
|
|
59127
|
+
copyBandToChannel(grid, 3, alpha);
|
|
59128
|
+
blurChannel(alpha, tmp, weights, grid.width, grid.height, boxes);
|
|
59129
|
+
for (var band = 0; band < grid.bands; band++) {
|
|
59130
|
+
if (band < 3) {
|
|
59131
|
+
copyPremultipliedBandToChannel(grid, band, channel);
|
|
59132
|
+
blurChannel(channel, tmp, weights, grid.width, grid.height, boxes);
|
|
59133
|
+
copyUnpremultipliedChannelToBand(channel, alpha, samples, grid, band);
|
|
59134
|
+
} else {
|
|
59135
|
+
copyChannelToBand(alpha, samples, grid, 3);
|
|
59136
|
+
}
|
|
59137
|
+
}
|
|
59138
|
+
}
|
|
59139
|
+
|
|
59140
|
+
function blurChannel(channel, tmp, weights, width, height, boxes) {
|
|
59141
|
+
boxes.forEach(function(widthPx) {
|
|
59142
|
+
var radius = Math.floor((widthPx - 1) / 2);
|
|
59143
|
+
if (radius < 1) return;
|
|
59144
|
+
if (weights) {
|
|
59145
|
+
boxBlurWeighted(channel, tmp, weights, width, height, radius);
|
|
59146
|
+
} else {
|
|
59147
|
+
boxBlur(channel, tmp, width, height, radius);
|
|
59148
|
+
}
|
|
59149
|
+
});
|
|
59150
|
+
}
|
|
59151
|
+
|
|
59152
|
+
function boxBlur(src, tmp, width, height, radius) {
|
|
59153
|
+
boxBlurHorizontal(src, tmp, width, height, radius);
|
|
59154
|
+
boxBlurVertical(tmp, src, width, height, radius);
|
|
59155
|
+
}
|
|
59156
|
+
|
|
59157
|
+
function boxBlurHorizontal(src, dest, width, height, radius) {
|
|
59158
|
+
var size = radius * 2 + 1;
|
|
59159
|
+
var x, y, row, sum;
|
|
59160
|
+
for (y = 0; y < height; y++) {
|
|
59161
|
+
row = y * width;
|
|
59162
|
+
sum = src[row] * (radius + 1);
|
|
59163
|
+
for (x = 1; x <= radius; x++) sum += src[row + Math.min(width - 1, x)];
|
|
59164
|
+
for (x = 0; x < width; x++) {
|
|
59165
|
+
dest[row + x] = sum / size;
|
|
59166
|
+
sum += src[row + Math.min(width - 1, x + radius + 1)] - src[row + Math.max(0, x - radius)];
|
|
59167
|
+
}
|
|
59168
|
+
}
|
|
59169
|
+
}
|
|
59170
|
+
|
|
59171
|
+
function boxBlurVertical(src, dest, width, height, radius) {
|
|
59172
|
+
var size = radius * 2 + 1;
|
|
59173
|
+
var x, y, sum;
|
|
59174
|
+
for (x = 0; x < width; x++) {
|
|
59175
|
+
sum = src[x] * (radius + 1);
|
|
59176
|
+
for (y = 1; y <= radius; y++) sum += src[Math.min(height - 1, y) * width + x];
|
|
59177
|
+
for (y = 0; y < height; y++) {
|
|
59178
|
+
dest[y * width + x] = sum / size;
|
|
59179
|
+
sum += src[Math.min(height - 1, y + radius + 1) * width + x] - src[Math.max(0, y - radius) * width + x];
|
|
59180
|
+
}
|
|
59181
|
+
}
|
|
59182
|
+
}
|
|
59183
|
+
|
|
59184
|
+
function boxBlurWeighted(src, tmp, weights, width, height, radius) {
|
|
59185
|
+
boxBlurHorizontalWeighted(src, tmp, weights, width, height, radius);
|
|
59186
|
+
boxBlurVerticalWeighted(tmp, src, weights, width, height, radius);
|
|
59187
|
+
}
|
|
59188
|
+
|
|
59189
|
+
function boxBlurHorizontalWeighted(src, dest, weights, width, height, radius) {
|
|
59190
|
+
var x, y, row, id, addId, subId, sum, weightSum;
|
|
59191
|
+
for (y = 0; y < height; y++) {
|
|
59192
|
+
row = y * width;
|
|
59193
|
+
sum = src[row] * weights[row] * (radius + 1);
|
|
59194
|
+
weightSum = weights[row] * (radius + 1);
|
|
59195
|
+
for (x = 1; x <= radius; x++) {
|
|
59196
|
+
id = row + Math.min(width - 1, x);
|
|
59197
|
+
sum += src[id] * weights[id];
|
|
59198
|
+
weightSum += weights[id];
|
|
59199
|
+
}
|
|
59200
|
+
for (x = 0; x < width; x++) {
|
|
59201
|
+
id = row + x;
|
|
59202
|
+
dest[id] = weightSum > 0 ? sum / weightSum : src[id];
|
|
59203
|
+
addId = row + Math.min(width - 1, x + radius + 1);
|
|
59204
|
+
subId = row + Math.max(0, x - radius);
|
|
59205
|
+
sum += src[addId] * weights[addId] - src[subId] * weights[subId];
|
|
59206
|
+
weightSum += weights[addId] - weights[subId];
|
|
59207
|
+
}
|
|
59208
|
+
}
|
|
59209
|
+
}
|
|
59210
|
+
|
|
59211
|
+
function boxBlurVerticalWeighted(src, dest, weights, width, height, radius) {
|
|
59212
|
+
var x, y, id, addId, subId, sum, weightSum;
|
|
59213
|
+
for (x = 0; x < width; x++) {
|
|
59214
|
+
sum = src[x] * weights[x] * (radius + 1);
|
|
59215
|
+
weightSum = weights[x] * (radius + 1);
|
|
59216
|
+
for (y = 1; y <= radius; y++) {
|
|
59217
|
+
id = Math.min(height - 1, y) * width + x;
|
|
59218
|
+
sum += src[id] * weights[id];
|
|
59219
|
+
weightSum += weights[id];
|
|
59220
|
+
}
|
|
59221
|
+
for (y = 0; y < height; y++) {
|
|
59222
|
+
id = y * width + x;
|
|
59223
|
+
dest[id] = weightSum > 0 ? sum / weightSum : src[id];
|
|
59224
|
+
addId = Math.min(height - 1, y + radius + 1) * width + x;
|
|
59225
|
+
subId = Math.max(0, y - radius) * width + x;
|
|
59226
|
+
sum += src[addId] * weights[addId] - src[subId] * weights[subId];
|
|
59227
|
+
weightSum += weights[addId] - weights[subId];
|
|
59228
|
+
}
|
|
59229
|
+
}
|
|
59230
|
+
}
|
|
59231
|
+
|
|
59232
|
+
function copyBandToChannel(grid, band, channel) {
|
|
59233
|
+
var samples = grid.samples;
|
|
59234
|
+
var bands = grid.bands;
|
|
59235
|
+
for (var i = 0, j = band; i < channel.length; i++, j += bands) {
|
|
59236
|
+
channel[i] = samples[j];
|
|
59237
|
+
}
|
|
59238
|
+
}
|
|
59239
|
+
|
|
59240
|
+
function copyPremultipliedBandToChannel(grid, band, channel) {
|
|
59241
|
+
var samples = grid.samples;
|
|
59242
|
+
var bands = grid.bands;
|
|
59243
|
+
var alphaOffset = 3 - band;
|
|
59244
|
+
var maxAlpha = getAlphaMaxValue(samples);
|
|
59245
|
+
for (var i = 0, j = band; i < channel.length; i++, j += bands) {
|
|
59246
|
+
channel[i] = samples[j] * samples[j + alphaOffset] / maxAlpha;
|
|
59247
|
+
}
|
|
59248
|
+
}
|
|
59249
|
+
|
|
59250
|
+
function copyUnpremultipliedChannelToBand(channel, alpha, samples, grid, band) {
|
|
59251
|
+
var bands = grid.bands;
|
|
59252
|
+
var isFloat = samples instanceof Float32Array || samples instanceof Float64Array;
|
|
59253
|
+
var range = isFloat ? null : getTypedArrayRange(samples);
|
|
59254
|
+
var maxAlpha = getAlphaMaxValue(samples);
|
|
59255
|
+
var val, a;
|
|
59256
|
+
for (var i = 0, j = band; i < channel.length; i++, j += bands) {
|
|
59257
|
+
a = alpha[i];
|
|
59258
|
+
val = a > 0 ? channel[i] * maxAlpha / a : 0;
|
|
59259
|
+
samples[j] = isFloat ? val : clamp(Math.round(val), range.min, range.max);
|
|
59260
|
+
}
|
|
59261
|
+
}
|
|
59262
|
+
|
|
59263
|
+
function copyChannelToBand(channel, samples, grid, band) {
|
|
59264
|
+
var bands = grid.bands;
|
|
59265
|
+
var isFloat = samples instanceof Float32Array || samples instanceof Float64Array;
|
|
59266
|
+
var range = isFloat ? null : getTypedArrayRange(samples);
|
|
59267
|
+
var val;
|
|
59268
|
+
for (var i = 0, j = band; i < channel.length; i++, j += bands) {
|
|
59269
|
+
val = channel[i];
|
|
59270
|
+
samples[j] = isFloat ? val : clamp(Math.round(val), range.min, range.max);
|
|
59271
|
+
}
|
|
59272
|
+
}
|
|
59273
|
+
|
|
59274
|
+
function getRasterBlurWeights(grid) {
|
|
59275
|
+
if (!grid.coverage && grid.nodata == null) return null;
|
|
59276
|
+
var weights = new Float32Array(grid.width * grid.height);
|
|
59277
|
+
for (var i = 0; i < weights.length; i++) {
|
|
59278
|
+
weights[i] = rasterBlurPixelIsValid(grid, i) ? 1 : 0;
|
|
59279
|
+
}
|
|
59280
|
+
return weights;
|
|
59281
|
+
}
|
|
59282
|
+
|
|
59283
|
+
function rasterBlurPixelIsValid(grid, pixelId) {
|
|
59284
|
+
var off, n;
|
|
59285
|
+
if (grid.coverage && grid.coverage[pixelId] === 0) return false;
|
|
59286
|
+
if (grid.nodata == null) return true;
|
|
59287
|
+
off = pixelId * grid.bands;
|
|
59288
|
+
n = Math.min(grid.bands, 3);
|
|
59289
|
+
for (var i = 0; i < n; i++) {
|
|
59290
|
+
if (grid.samples[off + i] != grid.nodata) return true;
|
|
59291
|
+
}
|
|
59292
|
+
return false;
|
|
59293
|
+
}
|
|
59294
|
+
|
|
59295
|
+
function getAlphaMaxValue(samples) {
|
|
59296
|
+
if (samples instanceof Float32Array || samples instanceof Float64Array) return 1;
|
|
59297
|
+
return getTypedArrayRange(samples).max;
|
|
59298
|
+
}
|
|
59299
|
+
|
|
59300
|
+
function getTypedArrayRange(arr) {
|
|
59301
|
+
if (arr instanceof Uint8Array || arr instanceof Uint8ClampedArray) return {min: 0, max: 255};
|
|
59302
|
+
if (arr instanceof Int8Array) return {min: -128, max: 127};
|
|
59303
|
+
if (arr instanceof Uint16Array) return {min: 0, max: 65535};
|
|
59304
|
+
if (arr instanceof Int16Array) return {min: -32768, max: 32767};
|
|
59305
|
+
if (arr instanceof Uint32Array) return {min: 0, max: 4294967295};
|
|
59306
|
+
if (arr instanceof Int32Array) return {min: -2147483648, max: 2147483647};
|
|
59307
|
+
return {min: -Infinity, max: Infinity};
|
|
59308
|
+
}
|
|
59309
|
+
|
|
59310
|
+
function clamp(val, min, max) {
|
|
59311
|
+
return val < min ? min : val > max ? max : val;
|
|
59312
|
+
}
|
|
59313
|
+
|
|
59314
|
+
cmd.blur = blurRasterLayers;
|
|
59315
|
+
|
|
59316
|
+
function blurRasterLayers(layers, dataset, optsArg) {
|
|
59317
|
+
var opts = optsArg || {};
|
|
59318
|
+
requireProjectedDataset(dataset);
|
|
59319
|
+
layers.forEach(function(lyr) {
|
|
59320
|
+
if (!layerHasRaster(lyr)) {
|
|
59321
|
+
stop$1('Command requires a raster layer');
|
|
59322
|
+
}
|
|
59323
|
+
blurRasterLayer(lyr, opts);
|
|
59324
|
+
});
|
|
59325
|
+
}
|
|
59326
|
+
|
|
59327
|
+
function blurRasterLayer(lyr, opts) {
|
|
59328
|
+
var raster = lyr.raster;
|
|
59329
|
+
noteLayerWillChange(lyr, {operation: 'blurRasterLayer', unit: 'raster'});
|
|
59330
|
+
raster.grid = blurRasterGrid(raster, opts);
|
|
59331
|
+
raster.view = raster.view || {};
|
|
59332
|
+
delete raster.view.scalingStats;
|
|
59333
|
+
if (runningInBrowser()) {
|
|
59334
|
+
raster.view.preview = createRasterPreview(raster, opts);
|
|
59335
|
+
} else {
|
|
59336
|
+
delete raster.view.preview;
|
|
59337
|
+
}
|
|
59338
|
+
markLayerChanged(lyr, {operation: 'blurRasterLayer', unit: 'raster'});
|
|
59339
|
+
}
|
|
59340
|
+
|
|
59341
|
+
var Blur = /*#__PURE__*/Object.freeze({
|
|
59342
|
+
__proto__: null,
|
|
59343
|
+
blurRasterLayers: blurRasterLayers
|
|
59344
|
+
});
|
|
59345
|
+
|
|
59022
59346
|
function UndoTransaction(label) {
|
|
59023
59347
|
this.label = label || '';
|
|
59024
59348
|
this.units = [];
|
|
@@ -59809,6 +60133,7 @@ ${svg}
|
|
|
59809
60133
|
ArcUtils,
|
|
59810
60134
|
Bbox2Clipping,
|
|
59811
60135
|
BinArray$1,
|
|
60136
|
+
Blur,
|
|
59812
60137
|
// BufferCommon,
|
|
59813
60138
|
Calc,
|
|
59814
60139
|
CalcUtils,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.21",
|
|
4
4
|
"description": "A tool for editing geospatial data for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"idb-keyval": "^6.2.0",
|
|
74
74
|
"jpeg-js": "^0.4.4",
|
|
75
75
|
"kdbush": "^3.0.0",
|
|
76
|
-
"mproj": "0.1.
|
|
76
|
+
"mproj": "0.1.3",
|
|
77
77
|
"msgpackr": "^1.10.1",
|
|
78
78
|
"open": "^11.0.0",
|
|
79
79
|
"pngjs": "^7.0.0",
|