mapshaper 0.6.61 → 0.6.62

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/www/mapshaper.js CHANGED
@@ -24550,6 +24550,9 @@ ${svg}
24550
24550
  DEFAULT: true,
24551
24551
  describe: 'JS expression to apply to each target feature'
24552
24552
  })
24553
+ .option('ids', { // undocumented, used by GUI
24554
+ type: 'numbers'
24555
+ })
24553
24556
  .option('where', whereOpt)
24554
24557
  .option('target', targetOpt);
24555
24558
 
@@ -24684,7 +24687,7 @@ ${svg}
24684
24687
  parser.command('graticule')
24685
24688
  .describe('create a graticule layer')
24686
24689
  .option('interval', {
24687
- describe: 'size of grid cells in degrees (options: 5 10 15 30 45, default is 10)',
24690
+ describe: 'size of grid cells in degrees (default is 10)',
24688
24691
  type: 'number'
24689
24692
  })
24690
24693
  .option('polygon', {
@@ -36955,128 +36958,6 @@ ${svg}
36955
36958
  }
36956
36959
  };
36957
36960
 
36958
- cmd.evaluateEachFeature = function(lyr, dataset, exp, opts) {
36959
- var n = getFeatureCount(lyr),
36960
- arcs = dataset.arcs,
36961
- compiled, filter;
36962
-
36963
- var exprOpts = {
36964
- no_return: true,
36965
- geojson_editor: expressionUsesGeoJSON(exp) ? getFeatureEditor(lyr, dataset) : null
36966
- };
36967
-
36968
- // TODO: consider not creating a data table -- not needed if expression only references geometry
36969
- if (n > 0 && !lyr.data) {
36970
- lyr.data = new DataTable(n);
36971
- }
36972
- if (opts && opts.where) {
36973
- filter = compileFeatureExpression(opts.where, lyr, arcs);
36974
- }
36975
- compiled = compileFeatureExpression(exp, lyr, arcs, exprOpts);
36976
- // call compiled expression with id of each record
36977
- for (var i=0; i<n; i++) {
36978
- if (!filter || filter(i)) {
36979
- compiled(i);
36980
- }
36981
- }
36982
-
36983
- var replacement = exprOpts.geojson_editor ? exprOpts.geojson_editor.done() : null;
36984
- if (replacement) {
36985
- replaceLayerContents(lyr, dataset, replacement);
36986
- }
36987
- };
36988
-
36989
- var externalCommands = {};
36990
-
36991
- cmd.registerCommand = function(name, params) {
36992
- var defn = {name: name, options: params.options || []};
36993
- // Add definitions of options common to all commands (TODO: remove duplication)
36994
- defn.options.push({name: 'target'});
36995
- utils.defaults(defn, params);
36996
- validateExternalCommand(defn);
36997
- externalCommands[name] = defn;
36998
- };
36999
-
37000
- function isValidExternalCommand(defn) {
37001
- try {
37002
- validateExternalCommand(defn);
37003
- return true;
37004
- } catch(e) {}
37005
- return false;
37006
- }
37007
-
37008
- function validateExternalCommand(defn) {
37009
- var targetTypes = ['layer', 'layers'];
37010
- if (typeof defn.command != 'function') {
37011
- stop('Expected "command" parameter function');
37012
- }
37013
- if (!defn.target) {
37014
- stop('Missing required "target" parameter');
37015
- }
37016
- if (!targetTypes.includes(defn.target)) {
37017
- stop('Unrecognized command target type:', defn.target);
37018
- }
37019
- }
37020
-
37021
- cmd.runExternalCommand = function(cmdOpts, catalog) {
37022
- var name = cmdOpts.name;
37023
- var cmdDefn = externalCommands[name];
37024
- if (!cmdDefn) {
37025
- stop('Unsupported command:', name);
37026
- }
37027
- var targetType = cmdDefn.target;
37028
- var opts = parseExternalCommand(name, cmdDefn, cmdOpts._);
37029
- var targets = catalog.findCommandTargets(opts.target || '*');
37030
- var target = targets[0];
37031
- var output;
37032
- if (!target) {
37033
- stop('Missing a target');
37034
- }
37035
- if (targetType == 'layer' && (target.layers.length != 1 || targets.length > 1)) {
37036
- stop('This command only supports targeting a single layer');
37037
- }
37038
- if (targets.length > 1) {
37039
- stop("Targetting layers from multiple datasets is not supported");
37040
- }
37041
- if (targetType == 'layer') {
37042
- output = cmdDefn.command(target.layers[0], target.dataset, opts.options);
37043
- } else if (targetType == 'layers') {
37044
- output = cmdDefn.command(target.layers, target.dataset, opts.options);
37045
- }
37046
- if (output) {
37047
- integrateOutput(output, target, catalog, opts);
37048
- }
37049
- };
37050
-
37051
- // TODO: remove restrictions on output data
37052
- function integrateOutput(output, input, catalog, opts) {
37053
- if (!output.dataset || !output.layers || output.layers.length > 0 === false) {
37054
- stop('Invalid command output');
37055
- }
37056
- if (output.dataset == input.dataset) {
37057
- stop('External commands are not currently allowed to modify input datasets');
37058
- }
37059
- if (output.dataset.layers.length != output.layers.length) {
37060
- stop('Currently not supported: targetting a subset of output layers');
37061
- }
37062
- if (!opts.no_replace) {
37063
- input.layers.forEach(function(lyr) {
37064
- catalog.deleteLayer(lyr, input.dataset);
37065
- });
37066
- }
37067
- catalog.addDataset(output.dataset);
37068
- }
37069
-
37070
- function parseExternalCommand(name, cmdDefn, tokens) {
37071
- var parser = new CommandParser();
37072
- var cmd = parser.command(name);
37073
- (cmdDefn.options || []).forEach(function(o) {
37074
- cmd.option(o.name, o);
37075
- });
37076
- var parsed = parser.parseArgv(['-' + name].concat(tokens));
37077
- return parsed[0];
37078
- }
37079
-
37080
36961
  cmd.filterGeom = function(lyr, arcs, opts) {
37081
36962
  if (!layerHasGeometry(lyr)) {
37082
36963
  stop("Layer is missing geometry");
@@ -37293,6 +37174,131 @@ ${svg}
37293
37174
  }) || a || b;
37294
37175
  }
37295
37176
 
37177
+ cmd.evaluateEachFeature = function(lyr, dataset, exp, opts) {
37178
+ var n = getFeatureCount(lyr),
37179
+ arcs = dataset.arcs,
37180
+ compiled, filter;
37181
+
37182
+ var exprOpts = {
37183
+ no_return: true,
37184
+ geojson_editor: expressionUsesGeoJSON(exp) ? getFeatureEditor(lyr, dataset) : null
37185
+ };
37186
+
37187
+ // TODO: consider not creating a data table -- not needed if expression only references geometry
37188
+ if (n > 0 && !lyr.data) {
37189
+ lyr.data = new DataTable(n);
37190
+ }
37191
+ if (opts && opts.where) {
37192
+ filter = compileFeatureExpression(opts.where, lyr, arcs);
37193
+ }
37194
+ if (opts && opts.ids) {
37195
+ filter = combineFilters(filter, getIdFilter(opts.ids));
37196
+ }
37197
+ compiled = compileFeatureExpression(exp, lyr, arcs, exprOpts);
37198
+ // call compiled expression with id of each record
37199
+ for (var i=0; i<n; i++) {
37200
+ if (!filter || filter(i)) {
37201
+ compiled(i);
37202
+ }
37203
+ }
37204
+
37205
+ var replacement = exprOpts.geojson_editor ? exprOpts.geojson_editor.done() : null;
37206
+ if (replacement) {
37207
+ replaceLayerContents(lyr, dataset, replacement);
37208
+ }
37209
+ };
37210
+
37211
+ var externalCommands = {};
37212
+
37213
+ cmd.registerCommand = function(name, params) {
37214
+ var defn = {name: name, options: params.options || []};
37215
+ // Add definitions of options common to all commands (TODO: remove duplication)
37216
+ defn.options.push({name: 'target'});
37217
+ utils.defaults(defn, params);
37218
+ validateExternalCommand(defn);
37219
+ externalCommands[name] = defn;
37220
+ };
37221
+
37222
+ function isValidExternalCommand(defn) {
37223
+ try {
37224
+ validateExternalCommand(defn);
37225
+ return true;
37226
+ } catch(e) {}
37227
+ return false;
37228
+ }
37229
+
37230
+ function validateExternalCommand(defn) {
37231
+ var targetTypes = ['layer', 'layers'];
37232
+ if (typeof defn.command != 'function') {
37233
+ stop('Expected "command" parameter function');
37234
+ }
37235
+ if (!defn.target) {
37236
+ stop('Missing required "target" parameter');
37237
+ }
37238
+ if (!targetTypes.includes(defn.target)) {
37239
+ stop('Unrecognized command target type:', defn.target);
37240
+ }
37241
+ }
37242
+
37243
+ cmd.runExternalCommand = function(cmdOpts, catalog) {
37244
+ var name = cmdOpts.name;
37245
+ var cmdDefn = externalCommands[name];
37246
+ if (!cmdDefn) {
37247
+ stop('Unsupported command:', name);
37248
+ }
37249
+ var targetType = cmdDefn.target;
37250
+ var opts = parseExternalCommand(name, cmdDefn, cmdOpts._);
37251
+ var targets = catalog.findCommandTargets(opts.target || '*');
37252
+ var target = targets[0];
37253
+ var output;
37254
+ if (!target) {
37255
+ stop('Missing a target');
37256
+ }
37257
+ if (targetType == 'layer' && (target.layers.length != 1 || targets.length > 1)) {
37258
+ stop('This command only supports targeting a single layer');
37259
+ }
37260
+ if (targets.length > 1) {
37261
+ stop("Targetting layers from multiple datasets is not supported");
37262
+ }
37263
+ if (targetType == 'layer') {
37264
+ output = cmdDefn.command(target.layers[0], target.dataset, opts.options);
37265
+ } else if (targetType == 'layers') {
37266
+ output = cmdDefn.command(target.layers, target.dataset, opts.options);
37267
+ }
37268
+ if (output) {
37269
+ integrateOutput(output, target, catalog, opts);
37270
+ }
37271
+ };
37272
+
37273
+ // TODO: remove restrictions on output data
37274
+ function integrateOutput(output, input, catalog, opts) {
37275
+ if (!output.dataset || !output.layers || output.layers.length > 0 === false) {
37276
+ stop('Invalid command output');
37277
+ }
37278
+ if (output.dataset == input.dataset) {
37279
+ stop('External commands are not currently allowed to modify input datasets');
37280
+ }
37281
+ if (output.dataset.layers.length != output.layers.length) {
37282
+ stop('Currently not supported: targetting a subset of output layers');
37283
+ }
37284
+ if (!opts.no_replace) {
37285
+ input.layers.forEach(function(lyr) {
37286
+ catalog.deleteLayer(lyr, input.dataset);
37287
+ });
37288
+ }
37289
+ catalog.addDataset(output.dataset);
37290
+ }
37291
+
37292
+ function parseExternalCommand(name, cmdDefn, tokens) {
37293
+ var parser = new CommandParser();
37294
+ var cmd = parser.command(name);
37295
+ (cmdDefn.options || []).forEach(function(o) {
37296
+ cmd.option(o.name, o);
37297
+ });
37298
+ var parsed = parser.parseArgv(['-' + name].concat(tokens));
37299
+ return parsed[0];
37300
+ }
37301
+
37296
37302
  cmd.filterIslands = function(lyr, dataset, optsArg) {
37297
37303
  var opts = utils.extend({sliver_control: 0}, optsArg); // no sliver control
37298
37304
  var arcs = dataset.arcs;
@@ -39228,7 +39234,9 @@ ${svg}
39228
39234
  //
39229
39235
  function createGraticule(P, outlined, opts) {
39230
39236
  var interval = opts.interval || 10;
39231
- if (![5,10,15,20,30,45].includes(interval)) stop('Invalid interval:', interval);
39237
+ if (Math.round(interval) != interval || interval > 0 === false) {
39238
+ stop('Invalid interval:', interval);
39239
+ }
39232
39240
  P.lam0 * 180 / Math.PI;
39233
39241
  var precision = interval > 10 ? 1 : 0.5; // degrees between each vertex
39234
39242
  var xstep = interval;
@@ -39269,6 +39277,7 @@ ${svg}
39269
39277
  return Math.abs(a - b) < interval / 5;
39270
39278
  }
39271
39279
 
39280
+ // extended: meridian extends to pole
39272
39281
  function createMeridian(x, extended) {
39273
39282
  var y0 = ystep <= 15 ? ystep : 0;
39274
39283
  createMeridianPart(x, -90 + y0, 90 - y0);
@@ -42016,24 +42025,23 @@ ${svg}
42016
42025
  // import { importGeoJSON } from '../geojson/geojson-import';
42017
42026
 
42018
42027
  function getTargetProxy(target) {
42019
- var lyr = target.layers[0];
42020
- var data = getLayerInfo(lyr, target.dataset); // layer_name, feature_count etc
42021
- data.layer = lyr;
42022
- data.dataset = target.dataset;
42023
- addGetters(data, {
42028
+ var proxy = getLayerInfo(target.layer, target.dataset); // layer_name, feature_count etc
42029
+ proxy.layer = target.layer;
42030
+ proxy.dataset = target.dataset;
42031
+ addGetters(proxy, {
42024
42032
  // export as an object, not a string or buffer
42025
42033
  geojson: getGeoJSON
42026
42034
  });
42027
42035
 
42028
42036
  function getGeoJSON() {
42029
- var features = exportLayerAsGeoJSON(lyr, target.dataset, {rfc7946: true}, true);
42037
+ var features = exportLayerAsGeoJSON(target.layer, target.dataset, {rfc7946: true}, true);
42030
42038
  return {
42031
42039
  type: 'FeatureCollection',
42032
42040
  features: features
42033
42041
  };
42034
42042
  }
42035
42043
 
42036
- return data;
42044
+ return proxy;
42037
42045
  }
42038
42046
 
42039
42047
  // Support for evaluating expressions embedded in curly-brace templates
@@ -42042,8 +42050,20 @@ ${svg}
42042
42050
  async function evalTemplateExpression(expression, targets, ctx) {
42043
42051
  ctx = ctx || getBaseContext();
42044
42052
  // TODO: throw an error if target is used when there are multiple targets
42045
- if (targets && targets.length == 1) {
42046
- Object.defineProperty(ctx, 'target', {value: getTargetProxy(targets[0])});
42053
+ if (targets) {
42054
+ var proxies = expandCommandTargets(targets).reduce(function(memo, target) {
42055
+ var proxy = getTargetProxy(target);
42056
+ memo.push(proxy);
42057
+ // index targets by layer name too
42058
+ if (target.layer.name) {
42059
+ memo[target.layer.name] = proxy;
42060
+ }
42061
+ return memo;
42062
+ }, []);
42063
+ Object.defineProperty(ctx, 'targets', {value: proxies});
42064
+ if (proxies.length == 1) {
42065
+ Object.defineProperty(ctx, 'target', {value: proxies[0]});
42066
+ }
42047
42067
  }
42048
42068
  // Add global functions and data to the expression context
42049
42069
  // (e.g. functions imported via the -require command)
@@ -44958,7 +44978,7 @@ ${svg}
44958
44978
  });
44959
44979
  }
44960
44980
 
44961
- var version = "0.6.61";
44981
+ var version = "0.6.62";
44962
44982
 
44963
44983
  // Parse command line args into commands and run them
44964
44984
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/www/page.css CHANGED
@@ -220,7 +220,7 @@ body {
220
220
  text-align: center;
221
221
  }
222
222
 
223
- .box-tool-options .box-coords {
223
+ .box-coords {
224
224
  margin-top: 7px;
225
225
  pointer-events: initial;
226
226
  }