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/mapshaper.js CHANGED
@@ -78,7 +78,7 @@
78
78
  return obj === Object(obj); // via underscore
79
79
  }
80
80
 
81
- function clamp$1(val, min, max) {
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$1(rank | 0, 1, arr.length);
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$1, cleanNumericString, contains, copyElements, countValues, createBuffer,
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 (crsAreEqual(crsFrom, crsTo)) return xy.concat();
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
- message('Use the target= option to specify multiple layers for merging');
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
- if (usingPathClip) {
45276
- nodes = addIntersectionCuts(mergedDataset, opts);
45277
- noteDatasetWillChange(targetDataset, {operation: type, unit: 'arcs'});
45278
- targetDataset.arcs = mergedDataset.arcs;
45279
- markDatasetChanged(targetDataset, {operation: type, unit: 'arcs'});
45280
- profileStart('clipDissolvePolygonLayer2');
45281
- clipLyr = utils.defaults({data: null}, clipLyr);
45282
- clipLyr = dissolvePolygonLayer2(clipLyr, mergedDataset, {quiet: true, silent: true});
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, catalog) {
55008
+ cmd.renameLayers = function(layers, names) {
54976
55009
  if (names && names.join('').indexOf('=') > -1) {
54977
- renameByAssignment(names, catalog);
55010
+ renameByAssignment(names, layers);
54978
55011
  } else {
54979
55012
  renameTargetLayers(names, layers);
54980
55013
  }
54981
55014
  };
54982
55015
 
54983
- function renameByAssignment(names, catalog) {
55016
+ function renameByAssignment(names, layers) {
54984
55017
  var index = mapLayerNames(names);
54985
- catalog.forEachLayer(function(lyr) {
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
- var name = '';
54997
- var suffix = '';
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 = name + suffix;
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
- // default target is all layers
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, job.catalog);
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 == 'clip' || name == 'erase' || name == 'rectangle' ||
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
- var version = "0.7.19";
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.19",
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.2",
76
+ "mproj": "0.1.3",
77
77
  "msgpackr": "^1.10.1",
78
78
  "open": "^11.0.0",
79
79
  "pngjs": "^7.0.0",