mapshaper 0.7.18 → 0.7.20

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,
@@ -19880,7 +19891,7 @@
19880
19891
  function exportSVG(dataset, opts) {
19881
19892
  var namespace = 'xmlns="http://www.w3.org/2000/svg"';
19882
19893
  var defs = [];
19883
- var frame, svg, layers, metadataJSON;
19894
+ var frame, svg, layers, metadataJSON, files, svgFile;
19884
19895
  var style = '';
19885
19896
 
19886
19897
  // kludge for map keys
@@ -19901,6 +19912,8 @@
19901
19912
  // use invert_y: 0 setting for screen coordinates and geojson polygon generation
19902
19913
  // use 1px default margin so typical strokes don't get cut off on the sides
19903
19914
  opts = Object.assign({invert_y: true, margin: "1"}, opts);
19915
+ opts.svg_image_files = [];
19916
+ opts.svg_file_base = getSvgFileBase(dataset, opts);
19904
19917
  frame = getFrameData(dataset, opts);
19905
19918
  fitDatasetToFrame(dataset, frame);
19906
19919
  setCoordinatePrecision(dataset, opts.precision || 0.01);
@@ -19953,10 +19966,17 @@
19953
19966
  ${svg}
19954
19967
  </svg>`;
19955
19968
  svg = utils.format(template, frame.width, frame.height, 0, 0, frame.width, frame.height);
19956
- return [{
19969
+ svgFile = {
19957
19970
  content: svg,
19958
19971
  filename: opts.file || getOutputFileBase(dataset) + '.svg'
19959
- }];
19972
+ };
19973
+ files = [svgFile].concat(opts.svg_image_files);
19974
+ return files;
19975
+ }
19976
+
19977
+ function getSvgFileBase(dataset, opts) {
19978
+ var file = opts.file || getOutputFileBase(dataset) + '.svg';
19979
+ return file.replace(/\.svg$/i, '');
19960
19980
  }
19961
19981
 
19962
19982
  function getMetadataBlock(metadataJSON, viewBox) {
@@ -20047,7 +20067,9 @@ ${svg}
20047
20067
  layerObj.children = [];
20048
20068
  return layerObj;
20049
20069
  }
20050
- href = encodeRasterPreview(rendered.preview, opts);
20070
+ href = opts.linked_images ?
20071
+ exportLinkedRasterPreview(rendered.preview, opts) :
20072
+ encodeRasterPreview(rendered.preview, opts);
20051
20073
  layerObj.children = [{
20052
20074
  tag: 'image',
20053
20075
  properties: {
@@ -20121,6 +20143,30 @@ ${svg}
20121
20143
  return 'data:image/' + format + ';base64,' + data;
20122
20144
  }
20123
20145
 
20146
+ function exportLinkedRasterPreview(preview, opts) {
20147
+ var format = getSvgRasterFormat(preview, opts);
20148
+ var data = format == 'png' ? encodePng(preview) : encodeJpeg(preview, opts);
20149
+ var ext = format == 'jpeg' ? 'jpg' : format;
20150
+ var filename = opts.svg_file_base + '-image-' + (opts.svg_image_files.length + 1) + '.' + ext;
20151
+ opts.svg_image_files.push({
20152
+ filename: filename,
20153
+ content: base64ToBytes(data)
20154
+ });
20155
+ return filename;
20156
+ }
20157
+
20158
+ function base64ToBytes(str) {
20159
+ if (typeof Buffer != 'undefined') {
20160
+ return Buffer.from(str, 'base64');
20161
+ }
20162
+ var bin = atob(str);
20163
+ var bytes = new Uint8Array(bin.length);
20164
+ for (var i = 0; i < bin.length; i++) {
20165
+ bytes[i] = bin.charCodeAt(i);
20166
+ }
20167
+ return bytes;
20168
+ }
20169
+
20124
20170
  function getSvgRasterFormat(preview, opts) {
20125
20171
  var fmt = opts.svg_raster_format || opts.raster_format || null;
20126
20172
  if (fmt) return fmt == 'jpg' ? 'jpeg' : fmt;
@@ -20136,11 +20182,11 @@ ${svg}
20136
20182
  }
20137
20183
 
20138
20184
  function encodeJpeg(preview, opts) {
20185
+ var quality = getJpegQuality(opts);
20139
20186
  if (runningInBrowser() && typeof document != 'undefined') {
20140
- return encodeWithCanvas(preview, 'image/jpeg', opts.svg_raster_quality || 0.85);
20187
+ return encodeWithCanvas(preview, 'image/jpeg', quality / 100);
20141
20188
  }
20142
20189
  var jpeg = require$1('jpeg-js');
20143
- var quality = Math.round((opts.svg_raster_quality || 0.85) * 100);
20144
20190
  return Buffer.from(jpeg.encode({
20145
20191
  data: Buffer.from(preview.pixels),
20146
20192
  width: preview.width,
@@ -20148,6 +20194,14 @@ ${svg}
20148
20194
  }, quality).data).toString('base64');
20149
20195
  }
20150
20196
 
20197
+ function getJpegQuality(opts) {
20198
+ var quality = opts.jpeg_quality == null ? 85 : opts.jpeg_quality;
20199
+ if ((quality >= 1 && quality <= 100) === false) {
20200
+ stop$1('jpeg-quality= option should be a number from 1 to 100');
20201
+ }
20202
+ return Math.round(quality);
20203
+ }
20204
+
20151
20205
  function encodePng(preview) {
20152
20206
  if (runningInBrowser() && typeof document != 'undefined') {
20153
20207
  return encodeWithCanvas(preview, 'image/png');
@@ -29002,6 +29056,10 @@ ${svg}
29002
29056
  if ('topojson_precision' in o && o.topojson_precision > 0 === false) {
29003
29057
  error('topojson-precision= option should be a positive number');
29004
29058
  }
29059
+
29060
+ if ('jpeg_quality' in o && (o.jpeg_quality >= 1 && o.jpeg_quality <= 100) === false) {
29061
+ error('jpeg-quality= option should be a number from 1 to 100');
29062
+ }
29005
29063
  }
29006
29064
 
29007
29065
  var assignmentRxp = /^([a-z0-9_+-]+)=(?!=)(.*)$/i; // exclude ==
@@ -30408,6 +30466,14 @@ ${svg}
30408
30466
  describe: '[SVG] raster pixels per SVG pixel (default is 1)',
30409
30467
  type: 'number'
30410
30468
  })
30469
+ .option('linked-images', {
30470
+ describe: '[SVG] link raster images as external files',
30471
+ type: 'flag'
30472
+ })
30473
+ .option('jpeg-quality', {
30474
+ describe: '[SVG] JPEG quality for raster images, 1-100 (default is 85)',
30475
+ type: 'number'
30476
+ })
30411
30477
  .option('fit-extent', {
30412
30478
  describe: '[SVG] layer to use for the map extent'
30413
30479
  })
@@ -30546,6 +30612,13 @@ ${svg}
30546
30612
  .option('target', targetOpt)
30547
30613
  .option('no-replace', noReplaceOpt);
30548
30614
 
30615
+ parser.command('blur')
30616
+ // .describe('apply a Gaussian-like blur to projected raster layers')
30617
+ .option('radius', {
30618
+ describe: '[raster] blur amount in pixels, corresponding to 2 * sigma (e.g. 10 or 10px)'
30619
+ })
30620
+ .option('target', targetOpt);
30621
+
30549
30622
  parser.command('classify')
30550
30623
  // .describe('apply sequential or categorical classification')
30551
30624
  .describe('assign colors or values using one of several methods')
@@ -31432,6 +31505,10 @@ ${svg}
31432
31505
  .option('nodata-color', {
31433
31506
  describe: '[raster] color for uncovered pixels after reprojection'
31434
31507
  })
31508
+ .option('background', {
31509
+ describe: '[raster] alias for nodata-color',
31510
+ alias_to: 'nodata-color'
31511
+ })
31435
31512
  .option('resampling', {
31436
31513
  describe: '[raster] nearest or bilinear (default is bilinear)'
31437
31514
  })
@@ -51110,7 +51187,7 @@ ${svg}
51110
51187
  bbox = opts.output_bbox || opts.outputBbox || getProjectedMeshBBox(mesh);
51111
51188
  if (!bbox) stop$1('Unable to project raster layer');
51112
51189
  outSize = getOutputGridSize(grid, bbox, opts);
51113
- outGrid = createProjectedRasterGrid(grid, bbox, outSize.width, outSize.height, opts);
51190
+ outGrid = createProjectedRasterGrid(grid, raster, bbox, outSize.width, outSize.height, opts);
51114
51191
  timeStart(timing, 'rasterize');
51115
51192
  rasterizeProjectedMesh(grid, outGrid, mesh, getRasterProjectionSampleMethod(raster, opts));
51116
51193
  timeEnd(timing, 'rasterize');
@@ -51379,13 +51456,13 @@ ${svg}
51379
51456
  return xmin < Infinity && xmax > xmin && ymax > ymin ? [xmin, ymin, xmax, ymax] : null;
51380
51457
  }
51381
51458
 
51382
- function createProjectedRasterGrid(grid, bbox, widthArg, heightArg, opts) {
51459
+ function createProjectedRasterGrid(grid, raster, bbox, widthArg, heightArg, opts) {
51383
51460
  var width = widthArg || grid.width;
51384
51461
  var height = heightArg || grid.height;
51385
- var bands = getOutputBandCount(grid, opts);
51462
+ var bands = getOutputBandCount(grid, raster, opts);
51386
51463
  var samples = new grid.samples.constructor(width * height * bands);
51387
51464
  var coverage = new Uint8Array(width * height);
51388
- fillProjectedRasterSamples(samples, bands, grid, opts || {});
51465
+ fillProjectedRasterSamples(samples, bands, grid, raster, opts || {});
51389
51466
  return Object.assign({}, grid, {
51390
51467
  width: width,
51391
51468
  height: height,
@@ -51422,13 +51499,13 @@ ${svg}
51422
51499
  return {width: width, height: height};
51423
51500
  }
51424
51501
 
51425
- function getOutputBandCount(grid, opts) {
51426
- var color = getNoDataColor(opts);
51502
+ function getOutputBandCount(grid, raster, opts) {
51503
+ var color = getNoDataColor(raster, opts);
51427
51504
  return color && color.a === 0 && grid.bands > 1 && grid.bands < 4 ? 4 : grid.bands;
51428
51505
  }
51429
51506
 
51430
- function fillProjectedRasterSamples(samples, bands, grid, opts) {
51431
- var color = getNoDataColor(opts);
51507
+ function fillProjectedRasterSamples(samples, bands, grid, raster, opts) {
51508
+ var color = getNoDataColor(raster, opts);
51432
51509
  var noData = grid.nodata;
51433
51510
  if (color) {
51434
51511
  fillProjectedRasterColor(samples, bands, color);
@@ -51438,10 +51515,12 @@ ${svg}
51438
51515
  samples.fill(noData);
51439
51516
  }
51440
51517
 
51441
- function getNoDataColor(opts) {
51518
+ function getNoDataColor(raster, opts) {
51442
51519
  var arg = opts.nodata_color || opts.nodataColor;
51443
51520
  var color;
51444
- if (arg == null || arg === '') return null;
51521
+ if (arg == null || arg === '') {
51522
+ return rasterAppearsCategorical(raster) ? null : {r: 255, g: 255, b: 255, a: 1};
51523
+ }
51445
51524
  if (String(arg).toLowerCase() == 'transparent') {
51446
51525
  return {r: 0, g: 0, b: 0, a: 0};
51447
51526
  }
@@ -51508,10 +51587,10 @@ ${svg}
51508
51587
 
51509
51588
  function getTrianglePixelBounds(grid, p1, p2, p3) {
51510
51589
  return [
51511
- clamp(Math.floor(Math.min(p1.x, p2.x, p3.x)), 0, grid.width - 1),
51512
- clamp(Math.floor(Math.min(p1.y, p2.y, p3.y)), 0, grid.height - 1),
51513
- clamp(Math.ceil(Math.max(p1.x, p2.x, p3.x)), 0, grid.width - 1),
51514
- clamp(Math.ceil(Math.max(p1.y, p2.y, p3.y)), 0, grid.height - 1)
51590
+ clamp$1(Math.floor(Math.min(p1.x, p2.x, p3.x)), 0, grid.width - 1),
51591
+ clamp$1(Math.floor(Math.min(p1.y, p2.y, p3.y)), 0, grid.height - 1),
51592
+ clamp$1(Math.ceil(Math.max(p1.x, p2.x, p3.x)), 0, grid.width - 1),
51593
+ clamp$1(Math.ceil(Math.max(p1.y, p2.y, p3.y)), 0, grid.height - 1)
51515
51594
  ];
51516
51595
  }
51517
51596
 
@@ -51532,8 +51611,8 @@ ${svg}
51532
51611
  }
51533
51612
 
51534
51613
  function copyNearestRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
51535
- var srcX = clamp(Math.floor(sx), 0, srcGrid.width - 1);
51536
- var srcY = clamp(Math.floor(sy), 0, srcGrid.height - 1);
51614
+ var srcX = clamp$1(Math.floor(sx), 0, srcGrid.width - 1);
51615
+ var srcY = clamp$1(Math.floor(sy), 0, srcGrid.height - 1);
51537
51616
  var src = (srcY * srcGrid.width + srcX) * srcGrid.bands;
51538
51617
  var dest = (dy * destGrid.width + dx) * destGrid.bands;
51539
51618
  if (!rasterSourcePixelIsCovered(srcGrid, srcX, srcY)) return;
@@ -51545,12 +51624,12 @@ ${svg}
51545
51624
  }
51546
51625
 
51547
51626
  function copyBilinearRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
51548
- var srcX = clamp(Math.floor(sx - 0.5), 0, srcGrid.width - 1);
51549
- var srcY = clamp(Math.floor(sy - 0.5), 0, srcGrid.height - 1);
51550
- var srcX2 = clamp(srcX + 1, 0, srcGrid.width - 1);
51551
- var srcY2 = clamp(srcY + 1, 0, srcGrid.height - 1);
51552
- var tx = clamp(sx - 0.5 - srcX, 0, 1);
51553
- var ty = clamp(sy - 0.5 - srcY, 0, 1);
51627
+ var srcX = clamp$1(Math.floor(sx - 0.5), 0, srcGrid.width - 1);
51628
+ var srcY = clamp$1(Math.floor(sy - 0.5), 0, srcGrid.height - 1);
51629
+ var srcX2 = clamp$1(srcX + 1, 0, srcGrid.width - 1);
51630
+ var srcY2 = clamp$1(srcY + 1, 0, srcGrid.height - 1);
51631
+ var tx = clamp$1(sx - 0.5 - srcX, 0, 1);
51632
+ var ty = clamp$1(sy - 0.5 - srcY, 0, 1);
51554
51633
  var src00 = (srcY * srcGrid.width + srcX) * srcGrid.bands;
51555
51634
  var src10 = (srcY * srcGrid.width + srcX2) * srcGrid.bands;
51556
51635
  var src01 = (srcY2 * srcGrid.width + srcX) * srcGrid.bands;
@@ -51655,7 +51734,7 @@ ${svg}
51655
51734
  return (x - a.x) * (b.y - a.y) - (y - a.y) * (b.x - a.x);
51656
51735
  }
51657
51736
 
51658
- function clamp(val, min, max) {
51737
+ function clamp$1(val, min, max) {
51659
51738
  return val < min ? min : val > max ? max : val;
51660
51739
  }
51661
51740
 
@@ -54911,17 +54990,17 @@ ${svg}
54911
54990
  print(msgArg || '');
54912
54991
  };
54913
54992
 
54914
- cmd.renameLayers = function(layers, names, catalog) {
54993
+ cmd.renameLayers = function(layers, names) {
54915
54994
  if (names && names.join('').indexOf('=') > -1) {
54916
- renameByAssignment(names, catalog);
54995
+ renameByAssignment(names, layers);
54917
54996
  } else {
54918
54997
  renameTargetLayers(names, layers);
54919
54998
  }
54920
54999
  };
54921
55000
 
54922
- function renameByAssignment(names, catalog) {
55001
+ function renameByAssignment(names, layers) {
54923
55002
  var index = mapLayerNames(names);
54924
- catalog.forEachLayer(function(lyr) {
55003
+ layers.forEach(function(lyr) {
54925
55004
  if (index[lyr.name]) {
54926
55005
  noteLayerMetadataWillChange(lyr, {operation: 'rename-layers'});
54927
55006
  lyr.name = index[lyr.name];
@@ -54932,17 +55011,14 @@ ${svg}
54932
55011
 
54933
55012
  function renameTargetLayers(names, layers) {
54934
55013
  var nameCount = names && names.length || 0;
54935
- var name = '';
54936
- var suffix = '';
55014
+ if (nameCount != layers.length) {
55015
+ stop$1("Expected one name for each target layer; received " + nameCount +
55016
+ " name" + (nameCount == 1 ? "" : "s") + " for " + layers.length +
55017
+ " target layer" + (layers.length == 1 ? "" : "s"));
55018
+ }
54937
55019
  layers.forEach(function(lyr, i) {
54938
- if (i < nameCount) {
54939
- name = names[i];
54940
- }
54941
- if (name && nameCount < layers.length && (i >= nameCount - 1)) {
54942
- suffix = (suffix || 0) + 1;
54943
- }
54944
55020
  noteLayerMetadataWillChange(lyr, {operation: 'rename-layers'});
54945
- lyr.name = name + suffix;
55021
+ lyr.name = names[i];
54946
55022
  markLayerMetadataChanged(lyr, {operation: 'rename-layers'});
54947
55023
  });
54948
55024
  }
@@ -57798,7 +57874,7 @@ ${svg}
57798
57874
  name == 'require' || name == 'drop' || name == 'target' ||
57799
57875
  name == 'if' || name == 'elif' || name == 'else' || name == 'endif' ||
57800
57876
  name == 'run' || name == 'i' || name == 'snap' || name == 'frame' ||
57801
- name == 'comment';
57877
+ name == 'comment' || name == 'rename-layers';
57802
57878
  }
57803
57879
 
57804
57880
  function commandAcceptsEmptyTarget(name) {
@@ -57839,8 +57915,7 @@ ${svg}
57839
57915
  T$1.start();
57840
57916
 
57841
57917
  if (name == 'rename-layers') {
57842
- // default target is all layers
57843
- targets = job.catalog.findCommandTargets(opts.target || '*');
57918
+ targets = job.catalog.findCommandTargets(opts.target);
57844
57919
  targetLayers = targets.reduce(function(memo, obj) {
57845
57920
  return memo.concat(obj.layers);
57846
57921
  }, []);
@@ -57909,6 +57984,9 @@ ${svg}
57909
57984
  outputLayers = applyCommandToEachLayer(cmd.buffer, targetLayers, targetDataset, opts);
57910
57985
  // outputLayers = cmd.buffer(targetLayers, targetDataset, opts);
57911
57986
 
57987
+ } else if (name == 'blur') {
57988
+ cmd.blur(targetLayers, targetDataset, opts);
57989
+
57912
57990
  } else if (name == 'data-fill') {
57913
57991
  applyCommandToEachLayer(cmd.dataFill, targetLayers, arcs, opts);
57914
57992
 
@@ -58115,7 +58193,7 @@ ${svg}
58115
58193
  applyCommandToEachLayer(cmd.renameFields, targetLayers, opts.fields);
58116
58194
 
58117
58195
  } else if (name == 'rename-layers') {
58118
- cmd.renameLayers(targetLayers, opts.names, job.catalog);
58196
+ cmd.renameLayers(targetLayers, opts.names);
58119
58197
 
58120
58198
  } else if (name == 'require') {
58121
58199
  await cmd.require(opts);
@@ -58269,7 +58347,7 @@ ${svg}
58269
58347
  });
58270
58348
  }
58271
58349
 
58272
- var version = "0.7.18";
58350
+ var version = "0.7.20";
58273
58351
 
58274
58352
  // Parse command line args into commands and run them
58275
58353
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
@@ -58958,6 +59036,291 @@ ${svg}
58958
59036
  return false;
58959
59037
  }
58960
59038
 
59039
+ var BOX_BLUR_PASSES = 3;
59040
+
59041
+ function blurRasterGrid(raster, optsArg) {
59042
+ var opts = optsArg || {};
59043
+ var grid = getRasterGrid(raster);
59044
+ var radius = getBlurRadius(opts);
59045
+ var sigma = radius / 2;
59046
+ var boxes = getGaussianBoxWidths(sigma, BOX_BLUR_PASSES);
59047
+ var samples = new grid.samples.constructor(grid.samples.length);
59048
+ var tmp = new Float32Array(grid.width * grid.height);
59049
+ var channel = new Float32Array(grid.width * grid.height);
59050
+ var weights = getRasterBlurWeights(grid);
59051
+ validateBlurGrid(grid);
59052
+ if (grid.bands == 4) {
59053
+ blurRgbaGrid(grid, samples, channel, tmp, weights, boxes);
59054
+ return Object.assign({}, grid, {
59055
+ samples: samples
59056
+ });
59057
+ }
59058
+ for (var band = 0; band < grid.bands; band++) {
59059
+ copyBandToChannel(grid, band, channel);
59060
+ blurChannel(channel, tmp, weights, grid.width, grid.height, boxes);
59061
+ copyChannelToBand(channel, samples, grid, band);
59062
+ }
59063
+ return Object.assign({}, grid, {
59064
+ samples: samples
59065
+ });
59066
+ }
59067
+
59068
+ function getBlurRadius(opts) {
59069
+ var arg = opts.radius;
59070
+ var radius;
59071
+ if (arg == null || arg === '') stop$1('Missing blur radius');
59072
+ if (typeof arg == 'string') {
59073
+ arg = arg.trim().replace(/px$/i, '');
59074
+ }
59075
+ radius = Number(arg);
59076
+ if (!(radius > 0 && isFinite(radius))) {
59077
+ stop$1('Expected radius= to be a positive pixel value');
59078
+ }
59079
+ return radius;
59080
+ }
59081
+
59082
+ function validateBlurGrid(grid) {
59083
+ if (!grid || !grid.samples || !grid.width || !grid.height || !grid.bands) {
59084
+ stop$1('Expected a raster grid');
59085
+ }
59086
+ }
59087
+
59088
+ // Convert a Gaussian sigma to box widths using the method described by
59089
+ // Ivan Kutskir / Peter Kovesi. Three box passes are a close, fast approximation.
59090
+ function getGaussianBoxWidths(sigma, n) {
59091
+ var ideal = Math.sqrt((12 * sigma * sigma / n) + 1);
59092
+ var wl = Math.floor(ideal);
59093
+ if (wl % 2 === 0) wl--;
59094
+ var wu = wl + 2;
59095
+ var m = Math.round((12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4));
59096
+ var boxes = [];
59097
+ for (var i = 0; i < n; i++) {
59098
+ boxes.push(i < m ? wl : wu);
59099
+ }
59100
+ return boxes;
59101
+ }
59102
+
59103
+ function blurRgbaGrid(grid, samples, channel, tmp, weights, boxes) {
59104
+ var alpha = new Float32Array(grid.width * grid.height);
59105
+ copyBandToChannel(grid, 3, alpha);
59106
+ blurChannel(alpha, tmp, weights, grid.width, grid.height, boxes);
59107
+ for (var band = 0; band < grid.bands; band++) {
59108
+ if (band < 3) {
59109
+ copyPremultipliedBandToChannel(grid, band, channel);
59110
+ blurChannel(channel, tmp, weights, grid.width, grid.height, boxes);
59111
+ copyUnpremultipliedChannelToBand(channel, alpha, samples, grid, band);
59112
+ } else {
59113
+ copyChannelToBand(alpha, samples, grid, 3);
59114
+ }
59115
+ }
59116
+ }
59117
+
59118
+ function blurChannel(channel, tmp, weights, width, height, boxes) {
59119
+ boxes.forEach(function(widthPx) {
59120
+ var radius = Math.floor((widthPx - 1) / 2);
59121
+ if (radius < 1) return;
59122
+ if (weights) {
59123
+ boxBlurWeighted(channel, tmp, weights, width, height, radius);
59124
+ } else {
59125
+ boxBlur(channel, tmp, width, height, radius);
59126
+ }
59127
+ });
59128
+ }
59129
+
59130
+ function boxBlur(src, tmp, width, height, radius) {
59131
+ boxBlurHorizontal(src, tmp, width, height, radius);
59132
+ boxBlurVertical(tmp, src, width, height, radius);
59133
+ }
59134
+
59135
+ function boxBlurHorizontal(src, dest, width, height, radius) {
59136
+ var size = radius * 2 + 1;
59137
+ var x, y, row, sum;
59138
+ for (y = 0; y < height; y++) {
59139
+ row = y * width;
59140
+ sum = src[row] * (radius + 1);
59141
+ for (x = 1; x <= radius; x++) sum += src[row + Math.min(width - 1, x)];
59142
+ for (x = 0; x < width; x++) {
59143
+ dest[row + x] = sum / size;
59144
+ sum += src[row + Math.min(width - 1, x + radius + 1)] - src[row + Math.max(0, x - radius)];
59145
+ }
59146
+ }
59147
+ }
59148
+
59149
+ function boxBlurVertical(src, dest, width, height, radius) {
59150
+ var size = radius * 2 + 1;
59151
+ var x, y, sum;
59152
+ for (x = 0; x < width; x++) {
59153
+ sum = src[x] * (radius + 1);
59154
+ for (y = 1; y <= radius; y++) sum += src[Math.min(height - 1, y) * width + x];
59155
+ for (y = 0; y < height; y++) {
59156
+ dest[y * width + x] = sum / size;
59157
+ sum += src[Math.min(height - 1, y + radius + 1) * width + x] - src[Math.max(0, y - radius) * width + x];
59158
+ }
59159
+ }
59160
+ }
59161
+
59162
+ function boxBlurWeighted(src, tmp, weights, width, height, radius) {
59163
+ boxBlurHorizontalWeighted(src, tmp, weights, width, height, radius);
59164
+ boxBlurVerticalWeighted(tmp, src, weights, width, height, radius);
59165
+ }
59166
+
59167
+ function boxBlurHorizontalWeighted(src, dest, weights, width, height, radius) {
59168
+ var x, y, row, id, addId, subId, sum, weightSum;
59169
+ for (y = 0; y < height; y++) {
59170
+ row = y * width;
59171
+ sum = src[row] * weights[row] * (radius + 1);
59172
+ weightSum = weights[row] * (radius + 1);
59173
+ for (x = 1; x <= radius; x++) {
59174
+ id = row + Math.min(width - 1, x);
59175
+ sum += src[id] * weights[id];
59176
+ weightSum += weights[id];
59177
+ }
59178
+ for (x = 0; x < width; x++) {
59179
+ id = row + x;
59180
+ dest[id] = weightSum > 0 ? sum / weightSum : src[id];
59181
+ addId = row + Math.min(width - 1, x + radius + 1);
59182
+ subId = row + Math.max(0, x - radius);
59183
+ sum += src[addId] * weights[addId] - src[subId] * weights[subId];
59184
+ weightSum += weights[addId] - weights[subId];
59185
+ }
59186
+ }
59187
+ }
59188
+
59189
+ function boxBlurVerticalWeighted(src, dest, weights, width, height, radius) {
59190
+ var x, y, id, addId, subId, sum, weightSum;
59191
+ for (x = 0; x < width; x++) {
59192
+ sum = src[x] * weights[x] * (radius + 1);
59193
+ weightSum = weights[x] * (radius + 1);
59194
+ for (y = 1; y <= radius; y++) {
59195
+ id = Math.min(height - 1, y) * width + x;
59196
+ sum += src[id] * weights[id];
59197
+ weightSum += weights[id];
59198
+ }
59199
+ for (y = 0; y < height; y++) {
59200
+ id = y * width + x;
59201
+ dest[id] = weightSum > 0 ? sum / weightSum : src[id];
59202
+ addId = Math.min(height - 1, y + radius + 1) * width + x;
59203
+ subId = Math.max(0, y - radius) * width + x;
59204
+ sum += src[addId] * weights[addId] - src[subId] * weights[subId];
59205
+ weightSum += weights[addId] - weights[subId];
59206
+ }
59207
+ }
59208
+ }
59209
+
59210
+ function copyBandToChannel(grid, band, channel) {
59211
+ var samples = grid.samples;
59212
+ var bands = grid.bands;
59213
+ for (var i = 0, j = band; i < channel.length; i++, j += bands) {
59214
+ channel[i] = samples[j];
59215
+ }
59216
+ }
59217
+
59218
+ function copyPremultipliedBandToChannel(grid, band, channel) {
59219
+ var samples = grid.samples;
59220
+ var bands = grid.bands;
59221
+ var alphaOffset = 3 - band;
59222
+ var maxAlpha = getAlphaMaxValue(samples);
59223
+ for (var i = 0, j = band; i < channel.length; i++, j += bands) {
59224
+ channel[i] = samples[j] * samples[j + alphaOffset] / maxAlpha;
59225
+ }
59226
+ }
59227
+
59228
+ function copyUnpremultipliedChannelToBand(channel, alpha, samples, grid, band) {
59229
+ var bands = grid.bands;
59230
+ var isFloat = samples instanceof Float32Array || samples instanceof Float64Array;
59231
+ var range = isFloat ? null : getTypedArrayRange(samples);
59232
+ var maxAlpha = getAlphaMaxValue(samples);
59233
+ var val, a;
59234
+ for (var i = 0, j = band; i < channel.length; i++, j += bands) {
59235
+ a = alpha[i];
59236
+ val = a > 0 ? channel[i] * maxAlpha / a : 0;
59237
+ samples[j] = isFloat ? val : clamp(Math.round(val), range.min, range.max);
59238
+ }
59239
+ }
59240
+
59241
+ function copyChannelToBand(channel, samples, grid, band) {
59242
+ var bands = grid.bands;
59243
+ var isFloat = samples instanceof Float32Array || samples instanceof Float64Array;
59244
+ var range = isFloat ? null : getTypedArrayRange(samples);
59245
+ var val;
59246
+ for (var i = 0, j = band; i < channel.length; i++, j += bands) {
59247
+ val = channel[i];
59248
+ samples[j] = isFloat ? val : clamp(Math.round(val), range.min, range.max);
59249
+ }
59250
+ }
59251
+
59252
+ function getRasterBlurWeights(grid) {
59253
+ if (!grid.coverage && grid.nodata == null) return null;
59254
+ var weights = new Float32Array(grid.width * grid.height);
59255
+ for (var i = 0; i < weights.length; i++) {
59256
+ weights[i] = rasterBlurPixelIsValid(grid, i) ? 1 : 0;
59257
+ }
59258
+ return weights;
59259
+ }
59260
+
59261
+ function rasterBlurPixelIsValid(grid, pixelId) {
59262
+ var off, n;
59263
+ if (grid.coverage && grid.coverage[pixelId] === 0) return false;
59264
+ if (grid.nodata == null) return true;
59265
+ off = pixelId * grid.bands;
59266
+ n = Math.min(grid.bands, 3);
59267
+ for (var i = 0; i < n; i++) {
59268
+ if (grid.samples[off + i] != grid.nodata) return true;
59269
+ }
59270
+ return false;
59271
+ }
59272
+
59273
+ function getAlphaMaxValue(samples) {
59274
+ if (samples instanceof Float32Array || samples instanceof Float64Array) return 1;
59275
+ return getTypedArrayRange(samples).max;
59276
+ }
59277
+
59278
+ function getTypedArrayRange(arr) {
59279
+ if (arr instanceof Uint8Array || arr instanceof Uint8ClampedArray) return {min: 0, max: 255};
59280
+ if (arr instanceof Int8Array) return {min: -128, max: 127};
59281
+ if (arr instanceof Uint16Array) return {min: 0, max: 65535};
59282
+ if (arr instanceof Int16Array) return {min: -32768, max: 32767};
59283
+ if (arr instanceof Uint32Array) return {min: 0, max: 4294967295};
59284
+ if (arr instanceof Int32Array) return {min: -2147483648, max: 2147483647};
59285
+ return {min: -Infinity, max: Infinity};
59286
+ }
59287
+
59288
+ function clamp(val, min, max) {
59289
+ return val < min ? min : val > max ? max : val;
59290
+ }
59291
+
59292
+ cmd.blur = blurRasterLayers;
59293
+
59294
+ function blurRasterLayers(layers, dataset, optsArg) {
59295
+ var opts = optsArg || {};
59296
+ requireProjectedDataset(dataset);
59297
+ layers.forEach(function(lyr) {
59298
+ if (!layerHasRaster(lyr)) {
59299
+ stop$1('Command requires a raster layer');
59300
+ }
59301
+ blurRasterLayer(lyr, opts);
59302
+ });
59303
+ }
59304
+
59305
+ function blurRasterLayer(lyr, opts) {
59306
+ var raster = lyr.raster;
59307
+ noteLayerWillChange(lyr, {operation: 'blurRasterLayer', unit: 'raster'});
59308
+ raster.grid = blurRasterGrid(raster, opts);
59309
+ raster.view = raster.view || {};
59310
+ delete raster.view.scalingStats;
59311
+ if (runningInBrowser()) {
59312
+ raster.view.preview = createRasterPreview(raster, opts);
59313
+ } else {
59314
+ delete raster.view.preview;
59315
+ }
59316
+ markLayerChanged(lyr, {operation: 'blurRasterLayer', unit: 'raster'});
59317
+ }
59318
+
59319
+ var Blur = /*#__PURE__*/Object.freeze({
59320
+ __proto__: null,
59321
+ blurRasterLayers: blurRasterLayers
59322
+ });
59323
+
58961
59324
  function UndoTransaction(label) {
58962
59325
  this.label = label || '';
58963
59326
  this.units = [];
@@ -59748,6 +60111,7 @@ ${svg}
59748
60111
  ArcUtils,
59749
60112
  Bbox2Clipping,
59750
60113
  BinArray$1,
60114
+ Blur,
59751
60115
  // BufferCommon,
59752
60116
  Calc,
59753
60117
  CalcUtils,