mapshaper 0.6.34 → 0.6.36

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
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.34";
3
+ var VERSION = "0.6.36";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -5829,11 +5829,11 @@
5829
5829
  };
5830
5830
 
5831
5831
  // TODO: move this and similar methods out of ArcCollection
5832
- this.getMultiShapeBounds = function(shapeIds, bounds) {
5832
+ this.getMultiShapeBounds = function(shp, bounds) {
5833
5833
  bounds = bounds || new Bounds();
5834
- if (shapeIds) { // handle null shapes
5835
- for (var i=0, n=shapeIds.length; i<n; i++) {
5836
- this.getSimpleShapeBounds(shapeIds[i], bounds);
5834
+ if (shp) { // handle null shapes
5835
+ for (var i=0, n=shp.length; i<n; i++) {
5836
+ this.getSimpleShapeBounds(shp[i], bounds);
5837
5837
  }
5838
5838
  }
5839
5839
  return bounds;
@@ -12719,7 +12719,7 @@
12719
12719
  }
12720
12720
  var sliverControl = opts.sliver_control >= 0 ? opts.sliver_control : 0; // 0 is default
12721
12721
  var crs = getDatasetCRS(dataset);
12722
- var threshold = areaArg ?
12722
+ var threshold = areaArg && areaArg != 'auto' ?
12723
12723
  convertAreaParam(areaArg, crs) :
12724
12724
  getDefaultSliverThreshold(lyr, dataset.arcs);
12725
12725
  var filter = sliverControl > 0 ?
@@ -16653,7 +16653,8 @@
16653
16653
  overlap_rule: opts.overlap_rule
16654
16654
  };
16655
16655
  var mosaicIndex = new MosaicIndex(lyr, nodes, mosaicOpts);
16656
- var fillGaps = !opts.allow_overlaps; // gap fill doesn't work yet with overlapping shapes
16656
+ // gap fill doesn't work yet with overlapping shapes
16657
+ var fillGaps = !opts.allow_overlaps && (opts.sliver_control || opts.gap_fill_area);
16657
16658
  var cleanupData, filterData;
16658
16659
  if (fillGaps) {
16659
16660
  var sliverOpts = utils.extend({sliver_control: 1}, opts);
@@ -16935,6 +16936,7 @@
16935
16936
 
16936
16937
  function cleanPolygonLayerGeometry(lyr, dataset, opts) {
16937
16938
  // clean polygons by apply the 'dissolve2' function to each feature
16939
+ opts = Object.assign({gap_fill_area: 'auto'}, opts);
16938
16940
  var groups = lyr.shapes.map(function(shp, i) {
16939
16941
  return [i];
16940
16942
  });
@@ -19130,6 +19132,47 @@
19130
19132
  return str1;
19131
19133
  }
19132
19134
 
19135
+ function getSphereEffectParams() {
19136
+ return {
19137
+ cx: 0.5,
19138
+ cy: 0.5,
19139
+ r: 0.57,
19140
+ fx: 0.35,
19141
+ fy: 0.35,
19142
+ stops: [
19143
+ {offset: 0.3, opacity: 0},
19144
+ {offset: 0.6, opacity: 0.1},
19145
+ {offset: 0.78, opacity: 0.25},
19146
+ {offset: 0.87, opacity: 0.45},
19147
+ {offset: 0.95, opacity: 1}]
19148
+ };
19149
+ }
19150
+
19151
+ function convertFillEffect(obj, defs) {
19152
+ if (obj['fill-effect'] != 'sphere') return; // only "sphere" is supported
19153
+ var id = 'mapshaper_sphere_effect';
19154
+ var href = `url(#${ id })`;
19155
+ var params = getSphereEffectParams();
19156
+ var stops = params.stops.map(function(stop) {
19157
+ return `<stop offset="${stop.offset}" stop-opacity="${stop.opacity}"/>`;
19158
+ });
19159
+ var svg =
19160
+ `<radialGradient id="${id}" cx="${params.cx}" cy="${params.cy}" r="${params.r}" fx="${params.fx}" fy="${params.fy}">${stops.join('')}</radialGradient>` ;
19161
+ if (!utils.find(defs, function(o) { return o.id == id; })) {
19162
+ defs.push({svg, id, href});
19163
+ }
19164
+ obj.fill = href;
19165
+ if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
19166
+ obj['fill-opacity'] = 0.35;
19167
+ }
19168
+ }
19169
+
19170
+ var SvgEffect = /*#__PURE__*/Object.freeze({
19171
+ __proto__: null,
19172
+ getSphereEffectParams: getSphereEffectParams,
19173
+ convertFillEffect: convertFillEffect
19174
+ });
19175
+
19133
19176
  var cache = {};
19134
19177
  function fetchFileSync(url) {
19135
19178
  if (url in cache) return cache[url];
@@ -19147,8 +19190,8 @@
19147
19190
  if (obj.tag == 'path' && obj.properties['fill-pattern']) {
19148
19191
  convertFillPattern(obj.properties, defs);
19149
19192
  }
19150
- if (obj.tag == 'path' && obj.properties['fill-effect'] == 'sphere') {
19151
- convertSphereEffect(obj.properties, defs);
19193
+ if (obj.tag == 'path' && obj.properties['fill-effect']) {
19194
+ convertFillEffect(obj.properties, defs);
19152
19195
  }
19153
19196
  if (obj.tag == 'image') {
19154
19197
  if (/\.svg/.test(obj.properties.href || '')) {
@@ -19160,25 +19203,6 @@
19160
19203
  }
19161
19204
  }
19162
19205
 
19163
- function convertSphereEffect(obj, defs) {
19164
- var id = 'mapshaper_sphere_effect';
19165
- var href = `url(#${ id })`;
19166
- var svg =
19167
- `<radialGradient id="${id}" cx="0.5" cy="0.5" r=".56" fx="0.4" fy="0.35">
19168
- <stop offset=".35" stop-opacity="0"/>
19169
- <stop offset=".65" stop-opacity="0.1" />
19170
- <stop offset=".85" stop-opacity="0.45" />
19171
- <stop offset=".95" stop-opacity="1" />
19172
- </radialGradient>` ;
19173
- if (!utils.find(defs, function(o) { return o.id == id; })) {
19174
- defs.push({svg, id, href});
19175
- }
19176
- obj.fill = href;
19177
- if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
19178
- obj['fill-opacity'] = 0.35;
19179
- }
19180
- }
19181
-
19182
19206
  function convertSvgImage(obj, defs) {
19183
19207
  // Same-origin policy prevents embedding images in the web UI
19184
19208
  var href = obj.properties.href;
@@ -23698,7 +23722,10 @@ ${svg}
23698
23722
  .option('calc', calcOpt)
23699
23723
  .option('sum-fields', sumFieldsOpt)
23700
23724
  .option('copy-fields', copyFieldsOpt)
23701
- .option('gap-fill-area', minGapAreaOpt)
23725
+ .option('gap-fill-area', {
23726
+ describe: 'threshold for filling gaps, e.g. 1.5km2',
23727
+ type: 'area'
23728
+ })
23702
23729
  .option('sliver-control', sliverControlOpt)
23703
23730
  .option('allow-overlaps', {
23704
23731
  describe: 'allow dissolved polygons to overlap (disables gap fill)',
@@ -40133,6 +40160,7 @@ ${svg}
40133
40160
  };
40134
40161
 
40135
40162
  if (opts.calc) {
40163
+ if (!lyr.data) initDataTable(lyr);
40136
40164
  records2 = recombineDataRecords(lyr.data.getRecords(), mosaicIndex.getSourceIdsByTileId, mosaicShapes.length, opts);
40137
40165
  lyr2.data = new DataTable(records2);
40138
40166
  }
@@ -43164,7 +43192,7 @@ ${svg}
43164
43192
  function commandAcceptsMultipleTargetDatasets(name) {
43165
43193
  return name == 'rotate' || name == 'info' || name == 'proj' ||
43166
43194
  name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
43167
- name == 'else' || name == 'endif';
43195
+ name == 'else' || name == 'endif' || name == 'run';
43168
43196
  }
43169
43197
 
43170
43198
  function commandAcceptsEmptyTarget(name) {
@@ -44390,6 +44418,7 @@ ${svg}
44390
44418
  Topology,
44391
44419
  Units,
44392
44420
  SvgHatch,
44421
+ SvgEffect,
44393
44422
  VertexUtils,
44394
44423
  Zip
44395
44424
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.34",
3
+ "version": "0.6.36",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -9045,6 +9045,7 @@
9045
9045
  r: 'radius',
9046
9046
  'fill': 'fillColor',
9047
9047
  'fill-pattern': 'fillPattern',
9048
+ 'fill-effect': 'fillEffect',
9048
9049
  'fill-opacity': 'fillOpacity',
9049
9050
  'stroke': 'strokeColor',
9050
9051
  'stroke-width': 'strokeWidth',
@@ -9359,6 +9360,117 @@
9359
9360
 
9360
9361
  utils$1.inherit(MapExtent, EventDispatcher);
9361
9362
 
9363
+ var hatches = {}; // cached patterns
9364
+
9365
+ function getCanvasFillEffect(ctx, shp, arcs, ext, style) {
9366
+ var bounds = arcs.getMultiShapeBounds(shp);
9367
+ if (!bounds.hasBounds() || style.fillEffect != 'sphere') {
9368
+ return null;
9369
+ }
9370
+ bounds.transform(ext.getTransform(GUI.getPixelRatio()));
9371
+ bounds.fillOut(1); // convert to square
9372
+ var o = convertSvgSphereParams(bounds);
9373
+ var fill = ctx.createRadialGradient(o.x0, o.y0, o.r0, o.x1, o.y1, o.r1);
9374
+ o.stops.forEach(function(stop) {
9375
+ fill.addColorStop(stop.offset, stop.color);
9376
+ });
9377
+ return fill;
9378
+ }
9379
+
9380
+ function convertSvgSphereParams(bounds) {
9381
+ var bbox = bounds.toArray(),
9382
+ d = Math.max(bounds.width(), bounds.height()),
9383
+ cx = bounds.centerX(),
9384
+ cy = bounds.centerY(),
9385
+ o = internal.getSphereEffectParams();
9386
+ return {
9387
+ x0: bbox[0] + d * o.fx,
9388
+ y0: bbox[1] + d * o.fy,
9389
+ r0: 0,
9390
+ x1: bbox[0] + d * o.cx,
9391
+ y1: bbox[1] + d * o.cy,
9392
+ r1: d * o.r,
9393
+ stops: o.stops.map(function(stop) {
9394
+ return {offset: stop.offset, color: `rgba(0,0,0,${stop.opacity})`};
9395
+ })
9396
+ };
9397
+ }
9398
+
9399
+
9400
+ function getCanvasFillPattern(style) {
9401
+ var fill = hatches[style.fillPattern];
9402
+ if (fill === undefined) {
9403
+ fill = makePatternFill(style);
9404
+ hatches[style.fillPattern] = fill;
9405
+ }
9406
+ return fill || style.fill || '#000'; // use fill if hatches are invalid
9407
+ }
9408
+
9409
+ function makePatternFill(style) {
9410
+ var o = internal.parsePattern(style.fillPattern);
9411
+ if (!o) return null;
9412
+ var canv = document.createElement('canvas');
9413
+ var ctx = canv.getContext('2d');
9414
+ var res = GUI.getPixelRatio();
9415
+ var w = o.tileSize[0] * res;
9416
+ var h = o.tileSize[1] * res;
9417
+ canv.setAttribute('width', w);
9418
+ canv.setAttribute('height', h);
9419
+ if (o.background) {
9420
+ ctx.fillStyle = o.background;
9421
+ ctx.fillRect(0, 0, w, h);
9422
+ }
9423
+ if (o.type == 'dots' || o.type == 'squares') makeDotFill(o, ctx, res);
9424
+ if (o.type == 'dashes') makeDashFill(o, ctx, res);
9425
+ if (o.type == 'hatches') makeHatchFill(o, ctx, res);
9426
+ var pattern = ctx.createPattern(canv, 'repeat');
9427
+ if (o.rotation) {
9428
+ pattern.setTransform(new DOMMatrix('rotate(' + o.rotation + 'deg)'));
9429
+ }
9430
+ return pattern;
9431
+ }
9432
+
9433
+ function makeDashFill(o, ctx, res) {
9434
+ var x = 0;
9435
+ for (var i=0; i<o.colors.length; i++) {
9436
+ ctx.fillStyle = o.colors[i];
9437
+ ctx.fillRect(x, 0, o.width * res, o.dashes[0] * res);
9438
+ x += res * (o.spacing + o.width);
9439
+ }
9440
+ }
9441
+
9442
+ function makeDotFill(o, ctx, res) {
9443
+ var dotSize = o.size * res;
9444
+ var r = dotSize / 2;
9445
+ var n = o.colors.length;
9446
+ var dist = dotSize + o.spacing * res;
9447
+ var dots = n * n;
9448
+ var x = 0, y = 0;
9449
+ for (var i=0; i<dots; i++) {
9450
+ if (o.type == 'dots') ctx.beginPath();
9451
+ ctx.fillStyle = o.colors[(i + Math.floor(i / n)) % n];
9452
+ if (o.type == 'dots') {
9453
+ ctx.arc(x + r, y + r, r, 0, Math.PI * 2);
9454
+ } else {
9455
+ ctx.fillRect(x, y, dotSize, dotSize);
9456
+ }
9457
+ if (o.type == 'dots') ctx.fill();
9458
+ x = ((i + 1) % n) * dist;
9459
+ if (x == 0) y += dist;
9460
+ }
9461
+ }
9462
+
9463
+ function makeHatchFill(o, ctx, res) {
9464
+ var h = o.tileSize[1] * res;
9465
+ var w;
9466
+ for (var i=0, x=0; i<o.widths.length; i++) {
9467
+ w = o.widths[i] * res;
9468
+ ctx.fillStyle = o.colors[i];
9469
+ ctx.fillRect(x, 0, x + w, h);
9470
+ x += w;
9471
+ }
9472
+ }
9473
+
9362
9474
  // TODO: consider moving this upstream
9363
9475
  function getArcsForRendering(obj, ext) {
9364
9476
  var dataset = obj.source.dataset;
@@ -9549,7 +9661,7 @@
9549
9661
  shp = shapes[i];
9550
9662
  if (!shp || filter && !filter(shp)) continue;
9551
9663
  if (styler) styler(style, i);
9552
- if (style.overlay || style.opacity < 1 || style.fillOpacity < 1 || style.strokeOpacity < 1) {
9664
+ if (style.overlay || style.opacity < 1 || style.fillOpacity < 1 || style.strokeOpacity < 1 || style.fillEffect) {
9553
9665
  // don't batch shapes with opacity, in case they overlap
9554
9666
  drawPaths([shp], startPath, draw, style);
9555
9667
  continue;
@@ -9574,10 +9686,10 @@
9574
9686
  });
9575
9687
  };
9576
9688
 
9577
- function drawPaths(shapes, begin, draw, style) {
9578
- begin(_ctx, style);
9689
+ function drawPaths(shapes, beginPath, drawShape, style) {
9690
+ beginPath(_ctx, style);
9579
9691
  for (var i=0, n=shapes.length; i<n; i++) {
9580
- draw(shapes[i], _ctx);
9692
+ drawShape(shapes[i], _ctx, style);
9581
9693
  }
9582
9694
  endPath(_ctx, style);
9583
9695
  }
@@ -9863,7 +9975,10 @@
9863
9975
  function getShapePencil(arcs, ext) {
9864
9976
  var t = getScaledTransform(ext);
9865
9977
  var iter = new internal.ShapeIter(arcs);
9866
- return function(shp, ctx) {
9978
+ return function(shp, ctx, style) {
9979
+ if (style.fillEffect) {
9980
+ ctx.fillStyle = getCanvasFillEffect(ctx, shp, arcs, ext, style);
9981
+ }
9867
9982
  for (var i=0, n=shp ? shp.length : 0; i<n; i++) {
9868
9983
  iter.init(shp[i]);
9869
9984
  // 0.2 trades visible seams for performance
@@ -9930,8 +10045,12 @@
9930
10045
  var fo = style.opacity >= 0 ? style.opacity : 1,
9931
10046
  so = fo;
9932
10047
  if (style.strokeOpacity >= 0) so *= style.strokeOpacity;
9933
- if (style.fillOpacity >= 0) fo *= style.fillOpacity;
9934
- if (style.fillColor || style.fillPattern) {
10048
+ if (style.fillColor || style.fillPattern || style.fillEffect) {
10049
+ if (style.fillOpacity >= 0) {
10050
+ fo *= style.fillOpacity;
10051
+ } else if (style.fillEffect && style.opacity >= 0 === false) {
10052
+ fo = 0.35; // kludge: default opacity of sphere effect
10053
+ }
9935
10054
  ctx.globalAlpha = fo;
9936
10055
  ctx.fill();
9937
10056
  }
@@ -9947,82 +10066,6 @@
9947
10066
  ctx.closePath();
9948
10067
  }
9949
10068
 
9950
- var hatches = {};
9951
-
9952
- function getCanvasFillPattern(style) {
9953
- var fill = hatches[style.fillPattern];
9954
- if (fill === undefined) {
9955
- fill = makePatternFill(style);
9956
- hatches[style.fillPattern] = fill;
9957
- }
9958
- return fill || style.fill || '#000'; // use fill if hatches are invalid
9959
- }
9960
-
9961
- function makePatternFill(style) {
9962
- var o = internal.parsePattern(style.fillPattern);
9963
- if (!o) return null;
9964
- var canv = document.createElement('canvas');
9965
- var ctx = canv.getContext('2d');
9966
- var res = GUI.getPixelRatio();
9967
- var w = o.tileSize[0] * res;
9968
- var h = o.tileSize[1] * res;
9969
- canv.setAttribute('width', w);
9970
- canv.setAttribute('height', h);
9971
- if (o.background) {
9972
- ctx.fillStyle = o.background;
9973
- ctx.fillRect(0, 0, w, h);
9974
- }
9975
- if (o.type == 'dots' || o.type == 'squares') makeDotFill(o, ctx, res);
9976
- if (o.type == 'dashes') makeDashFill(o, ctx, res);
9977
- if (o.type == 'hatches') makeHatchFill(o, ctx, res);
9978
- var pattern = ctx.createPattern(canv, 'repeat');
9979
- if (o.rotation) {
9980
- pattern.setTransform(new DOMMatrix('rotate(' + o.rotation + 'deg)'));
9981
- }
9982
- return pattern;
9983
- }
9984
-
9985
- function makeDashFill(o, ctx, res) {
9986
- var x = 0;
9987
- for (var i=0; i<o.colors.length; i++) {
9988
- ctx.fillStyle = o.colors[i];
9989
- ctx.fillRect(x, 0, o.width * res, o.dashes[0] * res);
9990
- x += res * (o.spacing + o.width);
9991
- }
9992
- }
9993
-
9994
- function makeDotFill(o, ctx, res) {
9995
- var dotSize = o.size * res;
9996
- var r = dotSize / 2;
9997
- var n = o.colors.length;
9998
- var dist = dotSize + o.spacing * res;
9999
- var dots = n * n;
10000
- var x = 0, y = 0;
10001
- for (var i=0; i<dots; i++) {
10002
- if (o.type == 'dots') ctx.beginPath();
10003
- ctx.fillStyle = o.colors[(i + Math.floor(i / n)) % n];
10004
- if (o.type == 'dots') {
10005
- ctx.arc(x + r, y + r, r, 0, Math.PI * 2);
10006
- } else {
10007
- ctx.fillRect(x, y, dotSize, dotSize);
10008
- }
10009
- if (o.type == 'dots') ctx.fill();
10010
- x = ((i + 1) % n) * dist;
10011
- if (x == 0) y += dist;
10012
- }
10013
- }
10014
-
10015
- function makeHatchFill(o, ctx, res) {
10016
- var h = o.tileSize[1] * res;
10017
- var w;
10018
- for (var i=0, x=0; i<o.widths.length; i++) {
10019
- w = o.widths[i] * res;
10020
- ctx.fillStyle = o.colors[i];
10021
- ctx.fillRect(x, 0, x + w, h);
10022
- x += w;
10023
- }
10024
- }
10025
-
10026
10069
  function getSvgFurnitureTransform(ext) {
10027
10070
  var scale = ext.getSymbolScale();
10028
10071
  var frame = ext.getFrame();
package/www/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.34";
3
+ var VERSION = "0.6.36";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -5829,11 +5829,11 @@
5829
5829
  };
5830
5830
 
5831
5831
  // TODO: move this and similar methods out of ArcCollection
5832
- this.getMultiShapeBounds = function(shapeIds, bounds) {
5832
+ this.getMultiShapeBounds = function(shp, bounds) {
5833
5833
  bounds = bounds || new Bounds();
5834
- if (shapeIds) { // handle null shapes
5835
- for (var i=0, n=shapeIds.length; i<n; i++) {
5836
- this.getSimpleShapeBounds(shapeIds[i], bounds);
5834
+ if (shp) { // handle null shapes
5835
+ for (var i=0, n=shp.length; i<n; i++) {
5836
+ this.getSimpleShapeBounds(shp[i], bounds);
5837
5837
  }
5838
5838
  }
5839
5839
  return bounds;
@@ -12719,7 +12719,7 @@
12719
12719
  }
12720
12720
  var sliverControl = opts.sliver_control >= 0 ? opts.sliver_control : 0; // 0 is default
12721
12721
  var crs = getDatasetCRS(dataset);
12722
- var threshold = areaArg ?
12722
+ var threshold = areaArg && areaArg != 'auto' ?
12723
12723
  convertAreaParam(areaArg, crs) :
12724
12724
  getDefaultSliverThreshold(lyr, dataset.arcs);
12725
12725
  var filter = sliverControl > 0 ?
@@ -16653,7 +16653,8 @@
16653
16653
  overlap_rule: opts.overlap_rule
16654
16654
  };
16655
16655
  var mosaicIndex = new MosaicIndex(lyr, nodes, mosaicOpts);
16656
- var fillGaps = !opts.allow_overlaps; // gap fill doesn't work yet with overlapping shapes
16656
+ // gap fill doesn't work yet with overlapping shapes
16657
+ var fillGaps = !opts.allow_overlaps && (opts.sliver_control || opts.gap_fill_area);
16657
16658
  var cleanupData, filterData;
16658
16659
  if (fillGaps) {
16659
16660
  var sliverOpts = utils.extend({sliver_control: 1}, opts);
@@ -16935,6 +16936,7 @@
16935
16936
 
16936
16937
  function cleanPolygonLayerGeometry(lyr, dataset, opts) {
16937
16938
  // clean polygons by apply the 'dissolve2' function to each feature
16939
+ opts = Object.assign({gap_fill_area: 'auto'}, opts);
16938
16940
  var groups = lyr.shapes.map(function(shp, i) {
16939
16941
  return [i];
16940
16942
  });
@@ -19130,6 +19132,47 @@
19130
19132
  return str1;
19131
19133
  }
19132
19134
 
19135
+ function getSphereEffectParams() {
19136
+ return {
19137
+ cx: 0.5,
19138
+ cy: 0.5,
19139
+ r: 0.57,
19140
+ fx: 0.35,
19141
+ fy: 0.35,
19142
+ stops: [
19143
+ {offset: 0.3, opacity: 0},
19144
+ {offset: 0.6, opacity: 0.1},
19145
+ {offset: 0.78, opacity: 0.25},
19146
+ {offset: 0.87, opacity: 0.45},
19147
+ {offset: 0.95, opacity: 1}]
19148
+ };
19149
+ }
19150
+
19151
+ function convertFillEffect(obj, defs) {
19152
+ if (obj['fill-effect'] != 'sphere') return; // only "sphere" is supported
19153
+ var id = 'mapshaper_sphere_effect';
19154
+ var href = `url(#${ id })`;
19155
+ var params = getSphereEffectParams();
19156
+ var stops = params.stops.map(function(stop) {
19157
+ return `<stop offset="${stop.offset}" stop-opacity="${stop.opacity}"/>`;
19158
+ });
19159
+ var svg =
19160
+ `<radialGradient id="${id}" cx="${params.cx}" cy="${params.cy}" r="${params.r}" fx="${params.fx}" fy="${params.fy}">${stops.join('')}</radialGradient>` ;
19161
+ if (!utils.find(defs, function(o) { return o.id == id; })) {
19162
+ defs.push({svg, id, href});
19163
+ }
19164
+ obj.fill = href;
19165
+ if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
19166
+ obj['fill-opacity'] = 0.35;
19167
+ }
19168
+ }
19169
+
19170
+ var SvgEffect = /*#__PURE__*/Object.freeze({
19171
+ __proto__: null,
19172
+ getSphereEffectParams: getSphereEffectParams,
19173
+ convertFillEffect: convertFillEffect
19174
+ });
19175
+
19133
19176
  var cache = {};
19134
19177
  function fetchFileSync(url) {
19135
19178
  if (url in cache) return cache[url];
@@ -19147,8 +19190,8 @@
19147
19190
  if (obj.tag == 'path' && obj.properties['fill-pattern']) {
19148
19191
  convertFillPattern(obj.properties, defs);
19149
19192
  }
19150
- if (obj.tag == 'path' && obj.properties['fill-effect'] == 'sphere') {
19151
- convertSphereEffect(obj.properties, defs);
19193
+ if (obj.tag == 'path' && obj.properties['fill-effect']) {
19194
+ convertFillEffect(obj.properties, defs);
19152
19195
  }
19153
19196
  if (obj.tag == 'image') {
19154
19197
  if (/\.svg/.test(obj.properties.href || '')) {
@@ -19160,25 +19203,6 @@
19160
19203
  }
19161
19204
  }
19162
19205
 
19163
- function convertSphereEffect(obj, defs) {
19164
- var id = 'mapshaper_sphere_effect';
19165
- var href = `url(#${ id })`;
19166
- var svg =
19167
- `<radialGradient id="${id}" cx="0.5" cy="0.5" r=".56" fx="0.4" fy="0.35">
19168
- <stop offset=".35" stop-opacity="0"/>
19169
- <stop offset=".65" stop-opacity="0.1" />
19170
- <stop offset=".85" stop-opacity="0.45" />
19171
- <stop offset=".95" stop-opacity="1" />
19172
- </radialGradient>` ;
19173
- if (!utils.find(defs, function(o) { return o.id == id; })) {
19174
- defs.push({svg, id, href});
19175
- }
19176
- obj.fill = href;
19177
- if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
19178
- obj['fill-opacity'] = 0.35;
19179
- }
19180
- }
19181
-
19182
19206
  function convertSvgImage(obj, defs) {
19183
19207
  // Same-origin policy prevents embedding images in the web UI
19184
19208
  var href = obj.properties.href;
@@ -23698,7 +23722,10 @@ ${svg}
23698
23722
  .option('calc', calcOpt)
23699
23723
  .option('sum-fields', sumFieldsOpt)
23700
23724
  .option('copy-fields', copyFieldsOpt)
23701
- .option('gap-fill-area', minGapAreaOpt)
23725
+ .option('gap-fill-area', {
23726
+ describe: 'threshold for filling gaps, e.g. 1.5km2',
23727
+ type: 'area'
23728
+ })
23702
23729
  .option('sliver-control', sliverControlOpt)
23703
23730
  .option('allow-overlaps', {
23704
23731
  describe: 'allow dissolved polygons to overlap (disables gap fill)',
@@ -40133,6 +40160,7 @@ ${svg}
40133
40160
  };
40134
40161
 
40135
40162
  if (opts.calc) {
40163
+ if (!lyr.data) initDataTable(lyr);
40136
40164
  records2 = recombineDataRecords(lyr.data.getRecords(), mosaicIndex.getSourceIdsByTileId, mosaicShapes.length, opts);
40137
40165
  lyr2.data = new DataTable(records2);
40138
40166
  }
@@ -43164,7 +43192,7 @@ ${svg}
43164
43192
  function commandAcceptsMultipleTargetDatasets(name) {
43165
43193
  return name == 'rotate' || name == 'info' || name == 'proj' ||
43166
43194
  name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
43167
- name == 'else' || name == 'endif';
43195
+ name == 'else' || name == 'endif' || name == 'run';
43168
43196
  }
43169
43197
 
43170
43198
  function commandAcceptsEmptyTarget(name) {
@@ -44390,6 +44418,7 @@ ${svg}
44390
44418
  Topology,
44391
44419
  Units,
44392
44420
  SvgHatch,
44421
+ SvgEffect,
44393
44422
  VertexUtils,
44394
44423
  Zip
44395
44424
  );