mapshaper 0.6.40 → 0.6.42

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 CHANGED
@@ -9,7 +9,7 @@ var defaultPort = 5555,
9
9
  .option('-q, --quick-view', 'load files with default options, bypassing import dialog')
10
10
  .option('-s, --direct-save', 'save files outside the browser\'s download folder')
11
11
  .option('-f, --force-save', 'allow overwriting input files with output files')
12
- .option('-a, --display-all', 'turn on visibility of all layers')
12
+ .option('-a, --display-all', 'turn on initial visibility of all layers')
13
13
  .option('-n, --name <name(s)>', 'rename input layer or layers')
14
14
  .option('-c, --commands <string>', 'console commands to run initially')
15
15
  .option('-t, --target <name>', 'name of layer to select initially')
package/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.40";
3
+ var VERSION = "0.6.42";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -1267,6 +1267,26 @@
1267
1267
  _stop = stop;
1268
1268
  }
1269
1269
 
1270
+ // get detailed error information from error stack (if available)
1271
+ // Example stack string (Node.js):
1272
+ /*
1273
+ /Users/someuser/somescript.js:226
1274
+ opacity: Math.round(weight * 5 / 5 // 0.2 0.4 0.6 etc
1275
+ ^
1276
+
1277
+ SyntaxError: missing ) after argument list
1278
+ at internalCompileFunction (node:internal/vm:73:18)
1279
+ at wrapSafe (node:internal/modules/cjs/loader:1149:20)
1280
+ at Module._compile (node:internal/modules/cjs/loader:1190:27)
1281
+ ...
1282
+ */
1283
+ function getErrorDetail(e) {
1284
+ var parts = (typeof e.stack == 'string') ? e.stack.split(/\n\s*\n/) : [];
1285
+ if (parts.length > 1 || true) {
1286
+ return '\nError details:\n' + parts[0];
1287
+ }
1288
+ return '';
1289
+ }
1270
1290
 
1271
1291
  // print a message to stdout
1272
1292
  function print() {
@@ -1389,6 +1409,7 @@
1389
1409
  interrupt: interrupt,
1390
1410
  message: message,
1391
1411
  setLoggingFunctions: setLoggingFunctions,
1412
+ getErrorDetail: getErrorDetail,
1392
1413
  print: print,
1393
1414
  verbose: verbose,
1394
1415
  debug: debug,
@@ -6359,9 +6380,10 @@
6359
6380
  function mergeDatasets(arr) {
6360
6381
  var arcSources = [],
6361
6382
  arcCount = 0,
6362
- mergedLayers = [],
6363
- mergedInfo = {},
6364
- mergedArcs;
6383
+ merged = {
6384
+ info: {},
6385
+ layers: []
6386
+ };
6365
6387
 
6366
6388
  // Error if incompatible CRS
6367
6389
  requireDatasetsHaveCompatibleCRS(arr);
@@ -6372,38 +6394,35 @@
6372
6394
  arcSources.push(dataset.arcs);
6373
6395
  }
6374
6396
 
6375
- mergeDatasetInfo(mergedInfo, dataset);
6397
+ mergeDatasetInfo$1(merged, dataset);
6376
6398
  dataset.layers.forEach(function(lyr) {
6377
6399
  if (lyr.geometry_type == 'polygon' || lyr.geometry_type == 'polyline') {
6378
6400
  forEachArcId(lyr.shapes, function(id) {
6379
6401
  return id < 0 ? id - arcCount : id + arcCount;
6380
6402
  });
6381
6403
  }
6382
- mergedLayers.push(lyr);
6404
+ merged.layers.push(lyr);
6383
6405
  });
6384
6406
  arcCount += n;
6385
6407
  });
6386
6408
 
6387
6409
  if (arcSources.length > 0) {
6388
- mergedArcs = mergeArcs(arcSources);
6389
- if (mergedArcs.size() != arcCount) {
6410
+ merged.arcs = mergeArcs(arcSources);
6411
+ if (merged.arcs.size() != arcCount) {
6390
6412
  error("[mergeDatasets()] Arc indexing error");
6391
6413
  }
6392
6414
  }
6393
6415
 
6394
- return {
6395
- info: mergedInfo,
6396
- arcs: mergedArcs,
6397
- layers: mergedLayers
6398
- };
6416
+ return merged;
6399
6417
  }
6400
6418
 
6401
- function mergeDatasetInfo(merged, dataset) {
6402
- var info = dataset.info || {};
6403
- merged.input_files = utils.uniq((merged.input_files || []).concat(info.input_files || []));
6404
- merged.input_formats = utils.uniq((merged.input_formats || []).concat(info.input_formats || []));
6419
+ function mergeDatasetInfo$1(merged, dataset) {
6420
+ var src = dataset.info || {};
6421
+ var dest = merged.info || (merged.info = {});
6422
+ dest.input_files = utils.uniq((dest.input_files || []).concat(src.input_files || []));
6423
+ dest.input_formats = utils.uniq((dest.input_formats || []).concat(src.input_formats || []));
6405
6424
  // merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
6406
- utils.defaults(merged, info);
6425
+ utils.defaults(dest, src);
6407
6426
  }
6408
6427
 
6409
6428
  function mergeArcs(arr) {
@@ -6450,6 +6469,7 @@
6450
6469
  mergeDatasetsForExport: mergeDatasetsForExport,
6451
6470
  mergeCommandTargets: mergeCommandTargets,
6452
6471
  mergeDatasets: mergeDatasets,
6472
+ mergeDatasetInfo: mergeDatasetInfo$1,
6453
6473
  mergeArcs: mergeArcs
6454
6474
  });
6455
6475
 
@@ -6900,6 +6920,18 @@
6900
6920
  });
6901
6921
  }
6902
6922
 
6923
+ // dest: destination dataset
6924
+ // src: source dataset
6925
+ function mergeDatasetInfo(dest, src) {
6926
+ var srcInfo = src.info || {};
6927
+ var destInfo = dest.info || (dest.info = {});
6928
+ destInfo.input_files = utils.uniq((destInfo.input_files || []).concat(srcInfo.input_files || []));
6929
+ destInfo.input_formats = utils.uniq((destInfo.input_formats || []).concat(srcInfo.input_formats || []));
6930
+ // merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
6931
+ utils.defaults(destInfo, srcInfo);
6932
+ }
6933
+
6934
+
6903
6935
  function splitApartLayers(dataset, layers) {
6904
6936
  var datasets = [];
6905
6937
  dataset.layers = dataset.layers.filter(function(lyr) {
@@ -7064,6 +7096,7 @@
7064
7096
  var DatasetUtils = /*#__PURE__*/Object.freeze({
7065
7097
  __proto__: null,
7066
7098
  splitDataset: splitDataset,
7099
+ mergeDatasetInfo: mergeDatasetInfo,
7067
7100
  splitApartLayers: splitApartLayers,
7068
7101
  copyDataset: copyDataset,
7069
7102
  copyDatasetForExport: copyDatasetForExport,
@@ -10877,7 +10910,8 @@
10877
10910
  pack: pack,
10878
10911
  exportDatasetsToPack: exportDatasetsToPack,
10879
10912
  applyCompression: applyCompression,
10880
- exportDataset: exportDataset
10913
+ exportDataset: exportDataset,
10914
+ exportInfo: exportInfo
10881
10915
  });
10882
10916
 
10883
10917
  // Guess the type of a data file from file extension, or return null if not sure
@@ -11204,20 +11238,43 @@
11204
11238
  return dest;
11205
11239
  };
11206
11240
 
11241
+ // Receives a directory path, in which the final subdirectory may include the
11242
+ // "*" wildcard, e.g. '.' 'data' '*' 'data/*' '2023-*'
11243
+ // Returns an array of expanded directory names
11244
+ // TODO: add support for wildcards in other subdirectories
11245
+ cli.expandDirectoryName = function(name) {
11246
+ var info = parseLocalPath(name);
11247
+ // final directory name is parsed as info.filename
11248
+ if (!info.filename.includes('*')) {
11249
+ return [name];
11250
+ }
11251
+ var rxp = utils.wildcardToRegExp(info.filename);
11252
+ var dirs = [];
11253
+ require$1('fs').readdirSync(info.directory || '.').forEach(function(item) {
11254
+ var path = info.directory ? require$1('path').join(info.directory, item) : item;
11255
+ if (rxp.test(item) && cli.isDirectory(path)) {
11256
+ dirs.push(path);
11257
+ }
11258
+ });
11259
+ return dirs;
11260
+ };
11261
+
11207
11262
  // Expand any "*" wild cards in file name
11208
11263
  // (For the Windows command line; unix shells do this automatically)
11209
11264
  cli.expandFileName = function(name) {
11210
11265
  var info = parseLocalPath(name),
11211
11266
  rxp = utils.wildcardToRegExp(info.filename),
11212
- dir = info.directory || '.',
11267
+ dirs = cli.expandDirectoryName(info.directory || '.'),
11213
11268
  files = [];
11214
11269
 
11215
11270
  try {
11216
- require$1('fs').readdirSync(dir).forEach(function(item) {
11217
- var path = require$1('path').join(dir, item);
11218
- if (rxp.test(item) && cli.isFile(path)) {
11219
- files.push(path);
11220
- }
11271
+ dirs.forEach(function(dir) {
11272
+ require$1('fs').readdirSync(dir).forEach(function(item) {
11273
+ var path = require$1('path').join(dir, item);
11274
+ if (rxp.test(item) && cli.isFile(path)) {
11275
+ files.push(path);
11276
+ }
11277
+ });
11221
11278
  });
11222
11279
  } catch(e) {}
11223
11280
 
@@ -23386,6 +23443,10 @@ ${svg}
23386
23443
  describe: '[TopoJSON] export coordinates without quantization',
23387
23444
  type: 'flag'
23388
23445
  })
23446
+ .option('metadata', {
23447
+ // describe: '[TopoJSON] Add a metadata object containing CRS information',
23448
+ type: 'flag'
23449
+ })
23389
23450
  .option('no-point-quantization', {
23390
23451
  // describe: '[TopoJSON] export point coordinates without quantization',
23391
23452
  type: 'flag'
@@ -27562,6 +27623,7 @@ ${svg}
27562
27623
  var separator = path.indexOf('/') > 0 ? '/' : '.';
27563
27624
  var parts = path.split(separator);
27564
27625
  var subpath, array, match;
27626
+
27565
27627
  while (parts.length > 0) {
27566
27628
  subpath = parts.shift();
27567
27629
  match = arrayRxp.exec(subpath);
@@ -28233,20 +28295,23 @@ ${svg}
28233
28295
  };
28234
28296
 
28235
28297
  this.setDefaultTarget = function(layers, dataset) {
28236
- if (datasets.indexOf(dataset) == -1) {
28237
- datasets.push(dataset);
28238
- }
28239
- defaultTargets = [{
28298
+ this.setDefaultTargets([{
28240
28299
  // Copy layers array, in case layers is a reference to dataset.layers.
28241
28300
  // This prevents layers that are added to the dataset inside a command from
28242
28301
  // being added to the next command's target, e.g. debugging layers added
28243
28302
  // by '-join unmatched unjoined'.
28244
28303
  layers: layers.concat(),
28245
28304
  dataset: dataset
28246
- }];
28305
+ }]);
28247
28306
  };
28248
28307
 
28308
+ // arr: array of target objects {layers:[], dataset:{}}
28249
28309
  this.setDefaultTargets = function(arr) {
28310
+ arr.forEach(function(target) {
28311
+ if (datasets.indexOf(target.dataset) == -1) {
28312
+ datasets.push(target.dataset);
28313
+ }
28314
+ });
28250
28315
  defaultTargets = arr;
28251
28316
  };
28252
28317
 
@@ -28339,6 +28404,30 @@ ${svg}
28339
28404
  stashVar('input_files', job.input_files);
28340
28405
  }
28341
28406
 
28407
+ // Apply a command to an array of target layers
28408
+ function applyCommandToEachLayer(func, targetLayers) {
28409
+ var args = utils.toArray(arguments).slice(2);
28410
+ return targetLayers.reduce(function(memo, lyr) {
28411
+ var result = func.apply(null, [lyr].concat(args));
28412
+ if (utils.isArray(result)) { // some commands return an array of layers
28413
+ memo = memo.concat(result);
28414
+ } else if (result) { // assuming result is a layer
28415
+ memo.push(result);
28416
+ }
28417
+ return memo;
28418
+ }, []);
28419
+ }
28420
+
28421
+ function applyCommandToEachTarget(func, targets) {
28422
+ var args = utils.toArray(arguments).slice(2);
28423
+ targets.forEach(function(target) {
28424
+ var result = func.apply(null, [target].concat(args));
28425
+ if (result) {
28426
+ error('Unexpected output from command');
28427
+ }
28428
+ });
28429
+ }
28430
+
28342
28431
  cmd.addShape = addShape;
28343
28432
 
28344
28433
  function addShape(targetLayers, targetDataset, opts) {
@@ -36244,31 +36333,6 @@ ${svg}
36244
36333
 
36245
36334
  var externalCommands = {};
36246
36335
 
36247
- cmd.external = function(opts) {
36248
- // TODO: remove duplication with -require command
36249
- var _module, moduleFile, moduleName;
36250
- if (!opts.module) {
36251
- stop('Missing required "module" parameter');
36252
- }
36253
- if (cli.isFile(opts.module)) {
36254
- moduleFile = opts.module;
36255
- } else if (cli.isFile(opts.module + '.js')) {
36256
- moduleFile = opts.module + '.js';
36257
- } else {
36258
- moduleName = opts.module;
36259
- }
36260
- if (moduleFile) {
36261
- moduleFile = require$1('path').join(process.cwd(), moduleFile);
36262
- }
36263
- try {
36264
- _module = require$1(moduleFile || moduleName);
36265
- _module(coreAPI);
36266
- } catch(e) {
36267
- // stop(e);
36268
- stop('Unable to load external module:', e.message);
36269
- }
36270
- };
36271
-
36272
36336
  cmd.registerCommand = function(name, params) {
36273
36337
  var defn = {name: name, options: params.options || []};
36274
36338
  // Add definitions of options common to all commands (TODO: remove duplication)
@@ -36278,13 +36342,25 @@ ${svg}
36278
36342
  externalCommands[name] = defn;
36279
36343
  };
36280
36344
 
36345
+ function isValidExternalCommand(defn) {
36346
+ try {
36347
+ validateExternalCommand(defn);
36348
+ return true;
36349
+ } catch(e) {}
36350
+ return false;
36351
+ }
36352
+
36281
36353
  function validateExternalCommand(defn) {
36354
+ var targetTypes = ['layer', 'layers'];
36282
36355
  if (typeof defn.command != 'function') {
36283
36356
  stop('Expected "command" parameter function');
36284
36357
  }
36285
36358
  if (!defn.target) {
36286
36359
  stop('Missing required "target" parameter');
36287
36360
  }
36361
+ if (!targetTypes.includes(defn.target)) {
36362
+ stop('Unrecognized command target type:', defn.target);
36363
+ }
36288
36364
  }
36289
36365
 
36290
36366
  cmd.runExternalCommand = function(cmdOpts, catalog) {
@@ -36297,6 +36373,7 @@ ${svg}
36297
36373
  var opts = parseExternalCommand(name, cmdDefn, cmdOpts._);
36298
36374
  var targets = catalog.findCommandTargets(opts.target || '*');
36299
36375
  var target = targets[0];
36376
+ var output;
36300
36377
  if (!target) {
36301
36378
  stop('Missing a target');
36302
36379
  }
@@ -36307,12 +36384,34 @@ ${svg}
36307
36384
  stop("Targetting layers from multiple datasets is not supported");
36308
36385
  }
36309
36386
  if (targetType == 'layer') {
36310
- cmdDefn.command(target.layers[0], target.dataset, opts.options);
36387
+ output = cmdDefn.command(target.layers[0], target.dataset, opts.options);
36311
36388
  } else if (targetType == 'layers') {
36312
- cmdDefn.command(target.layers, target.dataset, opts.options);
36389
+ output = cmdDefn.command(target.layers, target.dataset, opts.options);
36390
+ }
36391
+ if (output) {
36392
+ integrateOutput(output, target, catalog, opts);
36313
36393
  }
36314
36394
  };
36315
36395
 
36396
+ // TODO: remove restrictions on output data
36397
+ function integrateOutput(output, input, catalog, opts) {
36398
+ if (!output.dataset || !output.layers || output.layers.length > 0 === false) {
36399
+ stop('Invalid command output');
36400
+ }
36401
+ if (output.dataset == input.dataset) {
36402
+ stop('External commands are not currently allowed to modify input datasets');
36403
+ }
36404
+ if (output.dataset.layers.length != output.layers.length) {
36405
+ stop('Currently not supported: targetting a subset of output layers');
36406
+ }
36407
+ if (!opts.no_replace) {
36408
+ input.layers.forEach(function(lyr) {
36409
+ catalog.deleteLayer(lyr, input.dataset);
36410
+ });
36411
+ }
36412
+ catalog.addDataset(output.dataset);
36413
+ }
36414
+
36316
36415
  function parseExternalCommand(name, cmdDefn, tokens) {
36317
36416
  var parser = new CommandParser();
36318
36417
  var cmd = parser.command(name);
@@ -40624,6 +40723,7 @@ ${svg}
40624
40723
  return outputLayers;
40625
40724
  };
40626
40725
 
40726
+
40627
40727
  function getPolygonDataset(pointLyr, gridBBox, opts) {
40628
40728
  var points = getPointsInLayer(pointLyr);
40629
40729
  var cellSize = opts.interval;
@@ -40726,21 +40826,27 @@ ${svg}
40726
40826
  function makeCircleCoords(center, opts) {
40727
40827
  var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
40728
40828
  var radius = opts.interval / 2 * (1 - margin);
40729
- return getPointBufferCoordinates(center, radius, 20, getPlanarSegmentEndpoint);
40829
+ var vertices = opts.vertices || 20;
40830
+ return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
40730
40831
  }
40731
40832
 
40833
+ // Returns a function that receives a cell index and returns indices of points
40834
+ // within a given distance of the cell.
40732
40835
  function getPointIndex(points, grid, radius) {
40733
40836
  var Flatbush = require$1('flatbush');
40734
40837
  var gridIndex = new IdTestIndex(grid.cells());
40735
40838
  var bboxIndex = new Flatbush(points.length);
40736
40839
  var empty = [];
40737
40840
  points.forEach(function(p) {
40841
+ var bbox = getPointBounds(p, radius);
40738
40842
  addPointToGridIndex(p, gridIndex, grid);
40739
- bboxIndex.add.apply(bboxIndex, getPointBounds(p, radius));
40843
+ bboxIndex.add.apply(bboxIndex, bbox);
40740
40844
  });
40741
40845
  bboxIndex.finish();
40742
40846
  return function(i) {
40743
- if (!gridIndex.hasId(i)) return empty;
40847
+ if (!gridIndex.hasId(i)) {
40848
+ return empty;
40849
+ }
40744
40850
  var bbox = grid.idxToBBox(i);
40745
40851
  var indices = bboxIndex.search.apply(bboxIndex, bbox);
40746
40852
  return indices;
@@ -40860,12 +40966,27 @@ ${svg}
40860
40966
  xmin + (c + 1) * interval, ymin + (r + 1) * interval
40861
40967
  ];
40862
40968
  }
40969
+
40863
40970
  return {
40864
40971
  size, cells, pointToCol, pointToRow, colRowToIdx, pointToIdx,
40865
40972
  idxToCol, idxToRow, idxToBBox, idxToPoint
40866
40973
  };
40867
40974
  }
40868
40975
 
40976
+ var PointToGrid = /*#__PURE__*/Object.freeze({
40977
+ __proto__: null,
40978
+ getPointCircleRadius: getPointCircleRadius,
40979
+ calcCellProperties: calcCellProperties,
40980
+ calcWeights: calcWeights,
40981
+ twoCircleIntersection: twoCircleIntersection,
40982
+ makeCellPolygon: makeCellPolygon,
40983
+ makeCircleCoords: makeCircleCoords,
40984
+ getPointIndex: getPointIndex,
40985
+ getAlignedGridBounds: getAlignedGridBounds,
40986
+ getCenteredGridBounds: getCenteredGridBounds,
40987
+ getGridData: getGridData
40988
+ });
40989
+
40869
40990
  function closeUndershoots(lyr, dataset, opts) {
40870
40991
  var maxGapLen = opts.gap_tolerance ? convertIntervalParam(opts.gap_tolerance, getDatasetCRS(dataset)) : 0;
40871
40992
  var arcs = dataset.arcs;
@@ -41180,8 +41301,15 @@ ${svg}
41180
41301
  }
41181
41302
  try {
41182
41303
  mod = require$1(moduleFile || moduleName);
41304
+ if (typeof mod == 'function') {
41305
+ // -require now includes the functionality of the old -external command
41306
+ var retn = mod(api);
41307
+ if (retn && isValidExternalCommand(retn)) {
41308
+ cmd.registerCommand(retn.name, retn);
41309
+ }
41310
+ }
41183
41311
  } catch(e) {
41184
- stop(e);
41312
+ stop('Unable to load external module:', e.message, getErrorDetail(e));
41185
41313
  }
41186
41314
  if (moduleName || opts.alias) {
41187
41315
  defs[opts.alias || moduleName] = mod;
@@ -42212,9 +42340,10 @@ ${svg}
42212
42340
  }
42213
42341
  };
42214
42342
 
42215
- cmd.snap = function(dataset, opts) {
42343
+ cmd.snap = function(target, opts) {
42216
42344
  var interval = 0;
42217
42345
  var snapCount = 0;
42346
+ var dataset = target.dataset;
42218
42347
  var arcs = dataset.arcs;
42219
42348
  var arcBounds = arcs && arcs.getBounds();
42220
42349
  if (!arcBounds || !arcBounds.hasBounds()) {
@@ -43347,9 +43476,9 @@ ${svg}
43347
43476
  }
43348
43477
 
43349
43478
  function commandAcceptsMultipleTargetDatasets(name) {
43350
- return name == 'rotate' || name == 'info' || name == 'proj' ||
43479
+ return name == 'rotate' || name == 'info' || name == 'proj' || name == 'require' ||
43351
43480
  name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
43352
- name == 'else' || name == 'endif' || name == 'run' || name == 'i';
43481
+ name == 'else' || name == 'endif' || name == 'run' || name == 'i' || name == 'snap';
43353
43482
  }
43354
43483
 
43355
43484
  function commandAcceptsEmptyTarget(name) {
@@ -43431,6 +43560,10 @@ ${svg}
43431
43560
  source = findCommandSource(convertSourceName(opts.source, targets), job.catalog, opts);
43432
43561
  }
43433
43562
 
43563
+ // identify command target/input (for postprocessing)
43564
+ // TODO: support commands with multiple target datasets
43565
+ // target = name == 'i' ? null : targets[0];
43566
+
43434
43567
  if (name == 'add-shape') {
43435
43568
  if (!targetDataset) {
43436
43569
  targetDataset = {info: {}, layers: []};
@@ -43505,7 +43638,8 @@ ${svg}
43505
43638
  outputLayers = applyCommandToEachLayer(cmd.explodeFeatures, targetLayers, arcs, opts);
43506
43639
 
43507
43640
  } else if (name == 'external') {
43508
- cmd.external(opts);
43641
+ // -require now incorporates -external
43642
+ cmd.require(targets, opts);
43509
43643
 
43510
43644
  } else if (name == 'filter') {
43511
43645
  outputLayers = applyCommandToEachLayer(cmd.filterFeatures, targetLayers, arcs, opts);
@@ -43537,6 +43671,9 @@ ${svg}
43537
43671
  } else if (name == 'graticule') {
43538
43672
  job.catalog.addDataset(cmd.graticule(targetDataset, opts));
43539
43673
 
43674
+ } else if (name == 'grid') {
43675
+ outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
43676
+
43540
43677
  } else if (name == 'help') {
43541
43678
  // placing help command here to handle errors from invalid command names
43542
43679
  cmd.printHelp(command.options);
@@ -43608,9 +43745,6 @@ ${svg}
43608
43745
  } else if (name == 'point-to-grid') {
43609
43746
  outputLayers = cmd.pointToGrid(targetLayers, targetDataset, opts);
43610
43747
 
43611
- } else if (name == 'grid') {
43612
- outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
43613
-
43614
43748
  } else if (name == 'points') {
43615
43749
  outputLayers = applyCommandToEachLayer(cmd.createPointLayer, targetLayers, targetDataset, opts);
43616
43750
 
@@ -43674,7 +43808,8 @@ ${svg}
43674
43808
  outputLayers = cmd.sliceLayers(targetLayers, source, targetDataset, opts);
43675
43809
 
43676
43810
  } else if (name == 'snap') {
43677
- cmd.snap(targetDataset, opts);
43811
+ // cmd.snap(targetDataset, opts);
43812
+ applyCommandToEachTarget(targets, opts);
43678
43813
 
43679
43814
  } else if (name == 'sort') {
43680
43815
  applyCommandToEachLayer(cmd.sortFeatures, targetLayers, arcs, opts);
@@ -43765,9 +43900,12 @@ ${svg}
43765
43900
 
43766
43901
  // delete arcs if no longer needed (e.g. after -points command)
43767
43902
  // (after output layers have been integrated)
43903
+ // TODO: be more selective (e.g. -i command doesn't need cleanup)
43904
+ // or: detect if arcs have been changed
43768
43905
  if (targetDataset) {
43769
43906
  cleanupArcs(targetDataset);
43770
43907
  }
43908
+
43771
43909
  } catch(e) {
43772
43910
  return done(e);
43773
43911
  }
@@ -43789,20 +43927,6 @@ ${svg}
43789
43927
  });
43790
43928
  }
43791
43929
 
43792
- // Apply a command to an array of target layers
43793
- function applyCommandToEachLayer(func, targetLayers) {
43794
- var args = utils.toArray(arguments).slice(2);
43795
- return targetLayers.reduce(function(memo, lyr) {
43796
- var result = func.apply(null, [lyr].concat(args));
43797
- if (utils.isArray(result)) { // some commands return an array of layers
43798
- memo = memo.concat(result);
43799
- } else if (result) { // assuming result is a layer
43800
- memo.push(result);
43801
- }
43802
- return memo;
43803
- }, []);
43804
- }
43805
-
43806
43930
  // Parse command line args into commands and run them
43807
43931
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
43808
43932
  // function(argv[, input], callback)
@@ -44130,14 +44254,6 @@ ${svg}
44130
44254
  runAndRemoveInfoCommands: runAndRemoveInfoCommands
44131
44255
  });
44132
44256
 
44133
- // the mapshaper public api only has 4 functions
44134
- var coreAPI = {
44135
- runCommands,
44136
- applyCommands,
44137
- runCommandsXL,
44138
- enableLogging
44139
- };
44140
-
44141
44257
  // Return an array containing points from a path iterator, clipped to a bounding box
44142
44258
  // Currently using this function for clipping styled polygons in the GUI to speed up layer rendering.
44143
44259
  // Artifacts along the edges make this unsuitable for clipping datasets
@@ -44454,6 +44570,7 @@ ${svg}
44454
44570
  editArcs,
44455
44571
  GeoJSONReader,
44456
44572
  Heap,
44573
+ IdLookupIndex,
44457
44574
  NodeCollection,
44458
44575
  parseDMS,
44459
44576
  formatDMS,
@@ -44534,6 +44651,7 @@ ${svg}
44534
44651
  PixelTransform,
44535
44652
  PointPolygonJoin,
44536
44653
  Points,
44654
+ PointToGrid,
44537
44655
  PointUtils,
44538
44656
  PolygonDissolve,
44539
44657
  PolygonDissolve2,
@@ -44581,16 +44699,26 @@ ${svg}
44581
44699
  Zip
44582
44700
  );
44583
44701
 
44584
- // The entry point for the core mapshaper module
44702
+ // the mapshaper public api only has 4 functions
44703
+ var api = {
44704
+ runCommands,
44705
+ applyCommands,
44706
+ runCommandsXL,
44707
+ enableLogging
44708
+ };
44585
44709
 
44586
- var moduleAPI = Object.assign({
44710
+ // Add some namespaces, for easier testability and
44711
+ // to expose internal functions to the web UI
44712
+ Object.assign(api, {
44587
44713
  cli, cmd, geom, utils, internal,
44588
- }, coreAPI);
44714
+ });
44715
+
44716
+ // The entry point for the core mapshaper module
44589
44717
 
44590
44718
  if (typeof module === "object" && module.exports) {
44591
- module.exports = moduleAPI;
44719
+ module.exports = api;
44592
44720
  } else if (typeof window === "object" && window) {
44593
- window.mapshaper = moduleAPI;
44721
+ window.mapshaper = api;
44594
44722
  }
44595
44723
 
44596
44724
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.40",
3
+ "version": "0.6.42",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/index.html CHANGED
@@ -172,7 +172,7 @@ precision=0.001. Click to see all options.</div></div></div></a>
172
172
 
173
173
  <!-- <div class="cancel-btn btn dialog-btn">Cancel</div> -->
174
174
  <div class="save-btn btn dialog-btn">Export</div>
175
- <span id="save-preference"><input type="checkbox"/>choose directory</span>
175
+ <span id="save-preference" class="inline-checkbox" style="display: none;"><input type="checkbox"/>choose directory</span>
176
176
 
177
177
  </div>
178
178
  </div>