mapshaper 0.6.54 → 0.6.56
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 +170 -145
- package/package.json +1 -1
- package/www/index.html +3 -2
- package/www/mapshaper-gui.js +40 -25
- package/www/mapshaper.js +170 -145
- package/www/page.css +2 -6
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.56";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1403,6 +1403,14 @@
|
|
|
1403
1403
|
else console.error(msg);
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
|
+
function truncateString(str, maxLen) {
|
|
1407
|
+
maxLen = maxLen || 80;
|
|
1408
|
+
if (str.length > maxLen) {
|
|
1409
|
+
str = str.substring(0, maxLen - 3).trimEnd() + '...';
|
|
1410
|
+
}
|
|
1411
|
+
return str;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1406
1414
|
var Logging = /*#__PURE__*/Object.freeze({
|
|
1407
1415
|
__proto__: null,
|
|
1408
1416
|
getLoggingSetter: getLoggingSetter,
|
|
@@ -1424,7 +1432,8 @@
|
|
|
1424
1432
|
formatColumns: formatColumns,
|
|
1425
1433
|
formatStringsAsGrid: formatStringsAsGrid,
|
|
1426
1434
|
formatLogArgs: formatLogArgs,
|
|
1427
|
-
logArgs: logArgs
|
|
1435
|
+
logArgs: logArgs,
|
|
1436
|
+
truncateString: truncateString
|
|
1428
1437
|
});
|
|
1429
1438
|
|
|
1430
1439
|
function Transform() {
|
|
@@ -14209,6 +14218,87 @@
|
|
|
14209
14218
|
};
|
|
14210
14219
|
}
|
|
14211
14220
|
|
|
14221
|
+
// Return array of variables on the left side of assignment operations
|
|
14222
|
+
// @hasDot (bool) Return property assignments via dot notation
|
|
14223
|
+
function getAssignedVars(exp, hasDot) {
|
|
14224
|
+
var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
|
|
14225
|
+
var matches = exp.match(rxp) || [];
|
|
14226
|
+
var f = function(s) {
|
|
14227
|
+
var i = s.indexOf('.');
|
|
14228
|
+
return hasDot ? i > -1 : i == -1;
|
|
14229
|
+
};
|
|
14230
|
+
var vars = utils.uniq(matches.filter(f));
|
|
14231
|
+
return vars;
|
|
14232
|
+
}
|
|
14233
|
+
|
|
14234
|
+
// Return array of objects with properties assigned via dot notation
|
|
14235
|
+
// e.g. 'd.value = 45' -> ['d']
|
|
14236
|
+
// export function getAssignmentObjects(exp) {
|
|
14237
|
+
// var matches = getAssignedVars(exp, true),
|
|
14238
|
+
// names = [];
|
|
14239
|
+
// matches.forEach(function(s) {
|
|
14240
|
+
// var match = /^([^.]+)\.[^.]+$/.exec(s);
|
|
14241
|
+
// var name = match ? match[1] : null;
|
|
14242
|
+
// if (name && name != 'this') {
|
|
14243
|
+
// names.push(name);
|
|
14244
|
+
// }
|
|
14245
|
+
// });
|
|
14246
|
+
// return utils.uniq(names);
|
|
14247
|
+
// }
|
|
14248
|
+
|
|
14249
|
+
function getExpressionFunction(exp, opts) {
|
|
14250
|
+
var func = compileExpressionToFunction(exp, opts);
|
|
14251
|
+
return function(rec, ctx) {
|
|
14252
|
+
var val;
|
|
14253
|
+
try {
|
|
14254
|
+
val = func.call(ctx.$, rec, ctx);
|
|
14255
|
+
} catch(e) {
|
|
14256
|
+
stop(e.name, "in expression [" + exp + "]:", e.message);
|
|
14257
|
+
}
|
|
14258
|
+
return val;
|
|
14259
|
+
};
|
|
14260
|
+
}
|
|
14261
|
+
|
|
14262
|
+
function compileExpressionToFunction(exp, opts) {
|
|
14263
|
+
// $$ added to avoid duplication with data field variables (an error condition)
|
|
14264
|
+
var functionBody, func;
|
|
14265
|
+
if (opts.returns) {
|
|
14266
|
+
// functionBody = 'return ' + functionBody;
|
|
14267
|
+
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
14268
|
+
} else {
|
|
14269
|
+
functionBody = exp;
|
|
14270
|
+
}
|
|
14271
|
+
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
14272
|
+
try {
|
|
14273
|
+
func = new Function('$$record,$$env', functionBody);
|
|
14274
|
+
} catch(e) {
|
|
14275
|
+
// if (opts.quiet) throw e;
|
|
14276
|
+
stop(e.name, 'in expression [' + exp + ']');
|
|
14277
|
+
}
|
|
14278
|
+
return func;
|
|
14279
|
+
}
|
|
14280
|
+
|
|
14281
|
+
function getBaseContext(ctx) {
|
|
14282
|
+
ctx = ctx || {};
|
|
14283
|
+
// Mask global properties (is this effective/worth doing?)
|
|
14284
|
+
ctx.globalThis = void 0; // some globals are not iterable
|
|
14285
|
+
(function() {
|
|
14286
|
+
for (var key in this) {
|
|
14287
|
+
ctx[key] = void 0;
|
|
14288
|
+
}
|
|
14289
|
+
}());
|
|
14290
|
+
ctx.console = console;
|
|
14291
|
+
return ctx;
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14294
|
+
var Expressions = /*#__PURE__*/Object.freeze({
|
|
14295
|
+
__proto__: null,
|
|
14296
|
+
getAssignedVars: getAssignedVars,
|
|
14297
|
+
getExpressionFunction: getExpressionFunction,
|
|
14298
|
+
compileExpressionToFunction: compileExpressionToFunction,
|
|
14299
|
+
getBaseContext: getBaseContext
|
|
14300
|
+
});
|
|
14301
|
+
|
|
14212
14302
|
// Compiled expression returns a value
|
|
14213
14303
|
function compileValueExpression(exp, lyr, arcs, opts) {
|
|
14214
14304
|
opts = opts || {};
|
|
@@ -14216,7 +14306,6 @@
|
|
|
14216
14306
|
return compileFeatureExpression(exp, lyr, arcs, opts);
|
|
14217
14307
|
}
|
|
14218
14308
|
|
|
14219
|
-
|
|
14220
14309
|
function compileFeaturePairFilterExpression(exp, lyr, arcs) {
|
|
14221
14310
|
var func = compileFeaturePairExpression(exp, lyr, arcs);
|
|
14222
14311
|
return function(idA, idB) {
|
|
@@ -14232,13 +14321,16 @@
|
|
|
14232
14321
|
var exp = cleanExpression(rawExp);
|
|
14233
14322
|
// don't add layer data to the context
|
|
14234
14323
|
// (fields are not added to the pair expression context)
|
|
14235
|
-
var ctx =
|
|
14324
|
+
var ctx = getFeatureExpressionContext({});
|
|
14236
14325
|
var getA = getProxyFactory(lyr, arcs);
|
|
14237
14326
|
var getB = getProxyFactory(lyr, arcs);
|
|
14238
14327
|
var vars = getAssignedVars(exp);
|
|
14239
14328
|
var functionBody = "with($$env){with($$record){return " + exp + "}}";
|
|
14240
14329
|
var func;
|
|
14241
14330
|
|
|
14331
|
+
// protect global object from assigned values
|
|
14332
|
+
nullifyUnsetProperties(vars, ctx);
|
|
14333
|
+
|
|
14242
14334
|
try {
|
|
14243
14335
|
func = new Function("$$record,$$env", functionBody);
|
|
14244
14336
|
} catch(e) {
|
|
@@ -14246,9 +14338,6 @@
|
|
|
14246
14338
|
stop(e.name, "in expression [" + exp + "]");
|
|
14247
14339
|
}
|
|
14248
14340
|
|
|
14249
|
-
// protect global object from assigned values
|
|
14250
|
-
nullifyUnsetProperties(vars, ctx);
|
|
14251
|
-
|
|
14252
14341
|
function getProxyFactory(lyr, arcs) {
|
|
14253
14342
|
var records = lyr.data ? lyr.data.getRecords() : [];
|
|
14254
14343
|
var getFeatureById = initFeatureProxy(lyr, arcs);
|
|
@@ -14284,12 +14373,12 @@
|
|
|
14284
14373
|
};
|
|
14285
14374
|
}
|
|
14286
14375
|
|
|
14287
|
-
function compileFeatureExpression(rawExp, lyr, arcs,
|
|
14288
|
-
var opts =
|
|
14376
|
+
function compileFeatureExpression(rawExp, lyr, arcs, optsArg) {
|
|
14377
|
+
var opts = optsArg || {},
|
|
14378
|
+
ctx = opts.context || {},
|
|
14289
14379
|
exp = cleanExpression(rawExp || ''),
|
|
14290
14380
|
mutable = !opts.no_assign, // block assignment expressions
|
|
14291
|
-
vars = getAssignedVars(exp)
|
|
14292
|
-
func, records;
|
|
14381
|
+
vars = getAssignedVars(exp);
|
|
14293
14382
|
|
|
14294
14383
|
if (mutable && vars.length > 0 && !lyr.data) {
|
|
14295
14384
|
initDataTable(lyr);
|
|
@@ -14297,110 +14386,45 @@
|
|
|
14297
14386
|
|
|
14298
14387
|
if (!mutable) {
|
|
14299
14388
|
// protect global object from assigned values
|
|
14300
|
-
|
|
14301
|
-
nullifyUnsetProperties(vars, opts.context);
|
|
14389
|
+
nullifyUnsetProperties(vars, ctx);
|
|
14302
14390
|
}
|
|
14303
14391
|
|
|
14304
|
-
records = lyr.data ? lyr.data.getRecords() : [];
|
|
14305
|
-
|
|
14392
|
+
var records = lyr.data ? lyr.data.getRecords() : [];
|
|
14393
|
+
var getFeatureById = initFeatureProxy(lyr, arcs, opts);
|
|
14394
|
+
var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
|
|
14395
|
+
var func = getExpressionFunction(exp, opts);
|
|
14396
|
+
ctx = getFeatureExpressionContext(lyr, ctx, opts);
|
|
14306
14397
|
|
|
14307
|
-
//
|
|
14398
|
+
// recId: index of a data record in the records array.
|
|
14399
|
+
// destRec: (optional argument, used by -calc) an object used to capture assignments
|
|
14400
|
+
// By default, assignments are captured by records[recId]
|
|
14401
|
+
//
|
|
14308
14402
|
return function(recId, destRec) {
|
|
14309
|
-
var
|
|
14403
|
+
var rec;
|
|
14310
14404
|
if (destRec) {
|
|
14311
|
-
|
|
14405
|
+
rec = destRec;
|
|
14312
14406
|
} else {
|
|
14313
|
-
|
|
14314
|
-
}
|
|
14407
|
+
rec = records[recId] || (records[recId] = {});
|
|
14408
|
+
}
|
|
14409
|
+
// Assigning feature/layer proxy to '$' ... ctx.$ is also exposed as 'this'
|
|
14410
|
+
// in the expression context.
|
|
14411
|
+
ctx.$ = recId >= 0 ? getFeatureById(recId) : layerOnlyProxy;
|
|
14412
|
+
// "_" is used as an alias for the expression context, so functions can still
|
|
14413
|
+
// be used when masked by variables of the same name.
|
|
14414
|
+
ctx._ = ctx;
|
|
14415
|
+
// Expose data properties using "d", like d3 does. (data propertries are
|
|
14416
|
+
// also available as "this.properties")
|
|
14417
|
+
ctx.d = rec || null;
|
|
14315
14418
|
|
|
14316
|
-
// initialize new fields to null so assignments work
|
|
14317
14419
|
if (mutable) {
|
|
14318
|
-
|
|
14319
|
-
|
|
14320
|
-
return func(record, recId);
|
|
14321
|
-
};
|
|
14322
|
-
}
|
|
14323
|
-
|
|
14324
|
-
// Return array of variables on the left side of assignment operations
|
|
14325
|
-
// @hasDot (bool) Return property assignments via dot notation
|
|
14326
|
-
function getAssignedVars(exp, hasDot) {
|
|
14327
|
-
var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
|
|
14328
|
-
var matches = exp.match(rxp) || [];
|
|
14329
|
-
var f = function(s) {
|
|
14330
|
-
var i = s.indexOf('.');
|
|
14331
|
-
return hasDot ? i > -1 : i == -1;
|
|
14332
|
-
};
|
|
14333
|
-
var vars = utils.uniq(matches.filter(f));
|
|
14334
|
-
return vars;
|
|
14335
|
-
}
|
|
14336
|
-
|
|
14337
|
-
// Return array of objects with properties assigned via dot notation
|
|
14338
|
-
// e.g. 'd.value = 45' -> ['d']
|
|
14339
|
-
function getAssignmentObjects(exp) {
|
|
14340
|
-
var matches = getAssignedVars(exp, true),
|
|
14341
|
-
names = [];
|
|
14342
|
-
matches.forEach(function(s) {
|
|
14343
|
-
var match = /^([^.]+)\.[^.]+$/.exec(s);
|
|
14344
|
-
var name = match ? match[1] : null;
|
|
14345
|
-
if (name && name != 'this') {
|
|
14346
|
-
names.push(name);
|
|
14347
|
-
}
|
|
14348
|
-
});
|
|
14349
|
-
return utils.uniq(names);
|
|
14350
|
-
}
|
|
14351
|
-
|
|
14352
|
-
function compileExpressionToFunction(exp, opts) {
|
|
14353
|
-
// $$ added to avoid duplication with data field variables (an error condition)
|
|
14354
|
-
var functionBody, func;
|
|
14355
|
-
if (opts.returns) {
|
|
14356
|
-
// functionBody = 'return ' + functionBody;
|
|
14357
|
-
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
14358
|
-
} else {
|
|
14359
|
-
functionBody = exp;
|
|
14360
|
-
}
|
|
14361
|
-
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
14362
|
-
try {
|
|
14363
|
-
func = new Function('$$record,$$env', functionBody);
|
|
14364
|
-
} catch(e) {
|
|
14365
|
-
// if (opts.quiet) throw e;
|
|
14366
|
-
stop(e.name, 'in expression [' + exp + ']');
|
|
14367
|
-
}
|
|
14368
|
-
return func;
|
|
14369
|
-
}
|
|
14370
|
-
|
|
14371
|
-
function getExpressionFunction(exp, lyr, arcs, opts) {
|
|
14372
|
-
var getFeatureById = initFeatureProxy(lyr, arcs, opts);
|
|
14373
|
-
var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
|
|
14374
|
-
var ctx = getExpressionContext(lyr, opts.context, opts);
|
|
14375
|
-
var func = compileExpressionToFunction(exp, opts);
|
|
14376
|
-
return function(rec, i) {
|
|
14377
|
-
var val;
|
|
14378
|
-
// Assigning feature/layer proxy to '$' -- maybe this should be removed,
|
|
14379
|
-
// since it is also exposed as "this".
|
|
14380
|
-
// (kludge) i is undefined in calc expressions ... we still
|
|
14381
|
-
// may need layer data (but not single-feature data)
|
|
14382
|
-
ctx.$ = i >= 0 ? getFeatureById(i) : layerOnlyProxy;
|
|
14383
|
-
ctx._ = ctx; // provide access to functions when masked by variable names
|
|
14384
|
-
ctx.d = rec || null; // expose data properties a la d3 (also exposed as this.properties)
|
|
14385
|
-
try {
|
|
14386
|
-
val = func.call(ctx.$, rec, ctx);
|
|
14387
|
-
} catch(e) {
|
|
14388
|
-
// if (opts.quiet) throw e;
|
|
14389
|
-
stop(e.name, "in expression [" + exp + "]:", e.message);
|
|
14420
|
+
// initialize assigned variables to rec.null so rec can capture them
|
|
14421
|
+
nullifyUnsetProperties(vars, rec);
|
|
14390
14422
|
}
|
|
14391
|
-
return
|
|
14423
|
+
return func(rec, ctx);
|
|
14392
14424
|
};
|
|
14393
14425
|
}
|
|
14394
14426
|
|
|
14395
|
-
function
|
|
14396
|
-
for (var i=0; i<vars.length; i++) {
|
|
14397
|
-
if (vars[i] in obj === false) {
|
|
14398
|
-
obj[vars[i]] = null;
|
|
14399
|
-
}
|
|
14400
|
-
}
|
|
14401
|
-
}
|
|
14402
|
-
|
|
14403
|
-
function getExpressionContext(lyr, mixins, opts) {
|
|
14427
|
+
function getFeatureExpressionContext(lyr, mixins, opts) {
|
|
14404
14428
|
var defs = getStashedVar('defs');
|
|
14405
14429
|
var env = getBaseContext();
|
|
14406
14430
|
var ctx = {};
|
|
@@ -14446,29 +14470,20 @@
|
|
|
14446
14470
|
}, ctx);
|
|
14447
14471
|
}
|
|
14448
14472
|
|
|
14449
|
-
function
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
(function() {
|
|
14454
|
-
for (var key in this) {
|
|
14455
|
-
ctx[key] = void 0;
|
|
14473
|
+
function nullifyUnsetProperties(vars, obj) {
|
|
14474
|
+
for (var i=0; i<vars.length; i++) {
|
|
14475
|
+
if (vars[i] in obj === false) {
|
|
14476
|
+
obj[vars[i]] = null;
|
|
14456
14477
|
}
|
|
14457
|
-
}
|
|
14458
|
-
ctx.console = console;
|
|
14459
|
-
return ctx;
|
|
14478
|
+
}
|
|
14460
14479
|
}
|
|
14461
14480
|
|
|
14462
|
-
var
|
|
14481
|
+
var FeatureExpressions = /*#__PURE__*/Object.freeze({
|
|
14463
14482
|
__proto__: null,
|
|
14464
14483
|
compileValueExpression: compileValueExpression,
|
|
14465
14484
|
compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
|
|
14466
14485
|
compileFeaturePairExpression: compileFeaturePairExpression,
|
|
14467
|
-
compileFeatureExpression: compileFeatureExpression
|
|
14468
|
-
getAssignedVars: getAssignedVars,
|
|
14469
|
-
getAssignmentObjects: getAssignmentObjects,
|
|
14470
|
-
compileExpressionToFunction: compileExpressionToFunction,
|
|
14471
|
-
getBaseContext: getBaseContext
|
|
14486
|
+
compileFeatureExpression: compileFeatureExpression
|
|
14472
14487
|
});
|
|
14473
14488
|
|
|
14474
14489
|
function getMode(values) {
|
|
@@ -25221,11 +25236,12 @@ ${svg}
|
|
|
25221
25236
|
describe: 'use field values to calculate data island weights'
|
|
25222
25237
|
});
|
|
25223
25238
|
|
|
25224
|
-
|
|
25225
|
-
|
|
25226
|
-
|
|
25227
|
-
|
|
25228
|
-
|
|
25239
|
+
// replaced by -require
|
|
25240
|
+
// parser.command('external')
|
|
25241
|
+
// .option('module', {
|
|
25242
|
+
// DEFAULT: true,
|
|
25243
|
+
// describe: 'name of Node module containing the command'
|
|
25244
|
+
// });
|
|
25229
25245
|
|
|
25230
25246
|
parser.command('filter-points')
|
|
25231
25247
|
// .describe('remove points that are not part of a group')
|
|
@@ -25311,17 +25327,17 @@ ${svg}
|
|
|
25311
25327
|
.option('no-replace', noReplaceOpt);
|
|
25312
25328
|
|
|
25313
25329
|
parser.command('require')
|
|
25314
|
-
.describe('require a Node module
|
|
25330
|
+
.describe('require a Node module or ES module to use in JS expressions')
|
|
25315
25331
|
.option('module', {
|
|
25316
25332
|
DEFAULT: true,
|
|
25317
|
-
describe: 'name of
|
|
25333
|
+
describe: 'name of installed module or path to module file'
|
|
25318
25334
|
})
|
|
25319
25335
|
.option('alias', {
|
|
25320
25336
|
describe: 'Set the module name to an alias'
|
|
25321
|
-
})
|
|
25322
|
-
.option('init', {
|
|
25323
|
-
describe: 'JS expression to run after the module loads'
|
|
25324
25337
|
});
|
|
25338
|
+
// .option('init', {
|
|
25339
|
+
// describe: 'JS expression to run after the module loads'
|
|
25340
|
+
// });
|
|
25325
25341
|
|
|
25326
25342
|
parser.command('rotate')
|
|
25327
25343
|
// .describe('apply d3-style 3-axis rotation to a lat-long dataset')
|
|
@@ -35318,7 +35334,6 @@ ${svg}
|
|
|
35318
35334
|
if (targets.length === 0 && targetId) {
|
|
35319
35335
|
stop('Layer not found:', targetId);
|
|
35320
35336
|
}
|
|
35321
|
-
// var vars = getAssignedVars(exp);
|
|
35322
35337
|
var defs = getStashedVar('defs') || {};
|
|
35323
35338
|
|
|
35324
35339
|
var ctx;
|
|
@@ -41983,8 +41998,8 @@ ${svg}
|
|
|
41983
41998
|
return true;
|
|
41984
41999
|
}
|
|
41985
42000
|
|
|
41986
|
-
cmd.require = async function(
|
|
41987
|
-
var
|
|
42001
|
+
cmd.require = async function(opts) {
|
|
42002
|
+
var globals = getStashedVar('defs');
|
|
41988
42003
|
var moduleFile, moduleName, mod;
|
|
41989
42004
|
if (!opts.module) {
|
|
41990
42005
|
stop("Missing module name or path to module");
|
|
@@ -42000,25 +42015,33 @@ ${svg}
|
|
|
42000
42015
|
moduleFile = require$1('path').join(process.cwd(), moduleFile);
|
|
42001
42016
|
}
|
|
42002
42017
|
try {
|
|
42003
|
-
|
|
42018
|
+
// import CJS and ES modules
|
|
42019
|
+
mod = await import(moduleFile || moduleName);
|
|
42020
|
+
if (mod.default) {
|
|
42021
|
+
mod = mod.default;
|
|
42022
|
+
}
|
|
42004
42023
|
if (typeof mod == 'function') {
|
|
42005
|
-
//
|
|
42024
|
+
// assuming that functions are mapshpaper command generators...
|
|
42025
|
+
// this MUST be changed asap.
|
|
42006
42026
|
var retn = mod(api);
|
|
42007
42027
|
if (retn && isValidExternalCommand(retn)) {
|
|
42008
42028
|
cmd.registerCommand(retn.name, retn);
|
|
42009
42029
|
}
|
|
42010
42030
|
}
|
|
42011
42031
|
} catch(e) {
|
|
42012
|
-
|
|
42032
|
+
if (!mod) {
|
|
42033
|
+
stop('Unable to load external module:', e.message, getErrorDetail(e));
|
|
42034
|
+
}
|
|
42013
42035
|
}
|
|
42014
42036
|
if (moduleName || opts.alias) {
|
|
42015
|
-
|
|
42037
|
+
globals[opts.alias || moduleName] = mod;
|
|
42016
42038
|
} else {
|
|
42017
|
-
Object.assign(
|
|
42018
|
-
}
|
|
42019
|
-
if (opts.init) {
|
|
42020
|
-
await evalTemplateExpression(opts.init, targets);
|
|
42039
|
+
Object.assign(globals, mod);
|
|
42021
42040
|
}
|
|
42041
|
+
// instead of an init expression, you could use -run <expression>
|
|
42042
|
+
// if (opts.init) {
|
|
42043
|
+
// await evalTemplateExpression(opts.init, targets);
|
|
42044
|
+
// }
|
|
42022
42045
|
};
|
|
42023
42046
|
|
|
42024
42047
|
// Parse an array or a string of command line tokens into an array of
|
|
@@ -42123,7 +42146,8 @@ ${svg}
|
|
|
42123
42146
|
stop('Expected a string containing mapshaper commands; received:', tmp);
|
|
42124
42147
|
}
|
|
42125
42148
|
if (tmp) {
|
|
42126
|
-
message(
|
|
42149
|
+
// truncate message (command might include a large GeoJSON string in an -i command)
|
|
42150
|
+
message(`command: [${truncateString(tmp, 150)}]`);
|
|
42127
42151
|
commands = parseCommands(tmp);
|
|
42128
42152
|
|
|
42129
42153
|
// TODO: remove duplication with mapshaper-run-commands.mjs
|
|
@@ -44473,9 +44497,9 @@ ${svg}
|
|
|
44473
44497
|
} else if (name == 'explode') {
|
|
44474
44498
|
outputLayers = applyCommandToEachLayer(cmd.explodeFeatures, targetLayers, arcs, opts);
|
|
44475
44499
|
|
|
44476
|
-
|
|
44477
|
-
|
|
44478
|
-
|
|
44500
|
+
// -require now incorporates functionality of -external
|
|
44501
|
+
// } else if (name == 'external') {
|
|
44502
|
+
// cmd.require(targets, opts);
|
|
44479
44503
|
|
|
44480
44504
|
} else if (name == 'filter') {
|
|
44481
44505
|
outputLayers = applyCommandToEachLayer(cmd.filterFeatures, targetLayers, arcs, opts);
|
|
@@ -44617,7 +44641,7 @@ ${svg}
|
|
|
44617
44641
|
cmd.renameLayers(targetLayers, opts.names, job.catalog);
|
|
44618
44642
|
|
|
44619
44643
|
} else if (name == 'require') {
|
|
44620
|
-
cmd.require(
|
|
44644
|
+
await cmd.require(opts);
|
|
44621
44645
|
|
|
44622
44646
|
} else if (name == 'rotate') {
|
|
44623
44647
|
targets.forEach(function(targ) {
|
|
@@ -45445,6 +45469,7 @@ ${svg}
|
|
|
45445
45469
|
Explode,
|
|
45446
45470
|
Export,
|
|
45447
45471
|
Expressions,
|
|
45472
|
+
FeatureExpressions,
|
|
45448
45473
|
FileExport,
|
|
45449
45474
|
FileImport,
|
|
45450
45475
|
FilenameUtils,
|
package/package.json
CHANGED
package/www/index.html
CHANGED
|
@@ -308,9 +308,10 @@ encoding=big5</span>. Click to see all options.</div></div></div></div>
|
|
|
308
308
|
<div class="mshp-main-map main-area map-area">
|
|
309
309
|
<div class="coordinate-info colored-text selectable"></div>
|
|
310
310
|
<div class="intersection-display">
|
|
311
|
-
<
|
|
312
|
-
<
|
|
311
|
+
<span class="intersection-check text-btn colored-text">Check line intersections</span><span class="intersection-count">0 line intersections</span>
|
|
312
|
+
<img class="close-btn" draggable="false" src="images/close.png">
|
|
313
313
|
<div class="repair-btn text-btn colored-text">Repair</div>
|
|
314
|
+
|
|
314
315
|
</div>
|
|
315
316
|
<div class="map-layers"></div>
|
|
316
317
|
<div class="basemap-container"><div class="basemap"></div></div>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -654,8 +654,9 @@
|
|
|
654
654
|
},
|
|
655
655
|
|
|
656
656
|
show: function(css) {
|
|
657
|
+
var tag = this.el && this.el.tagName;
|
|
657
658
|
if (!this.visible()) {
|
|
658
|
-
this.css('display:block
|
|
659
|
+
this.css('display', tag == 'SPAN' ? 'inline-block' : 'block');
|
|
659
660
|
this._hidden = false;
|
|
660
661
|
}
|
|
661
662
|
return this;
|
|
@@ -3561,7 +3562,10 @@
|
|
|
3561
3562
|
repairBtn = el.findChild(".repair-btn"),
|
|
3562
3563
|
_simplifiedXX, // saved simplified intersections, for repair
|
|
3563
3564
|
_unsimplifiedXX, // saved unsimplified intersection data, for performance
|
|
3564
|
-
_disabled = false
|
|
3565
|
+
_disabled = false,
|
|
3566
|
+
_on = false;
|
|
3567
|
+
|
|
3568
|
+
el.findChild('.close-btn').on('click', dismissForever);
|
|
3565
3569
|
|
|
3566
3570
|
gui.on('simplify_drag_start', function() {
|
|
3567
3571
|
if (intersectionsAreOn()) {
|
|
@@ -3570,19 +3574,20 @@
|
|
|
3570
3574
|
});
|
|
3571
3575
|
|
|
3572
3576
|
gui.on('simplify_drag_end', function() {
|
|
3573
|
-
|
|
3577
|
+
updateSync('simplify_drag_end');
|
|
3574
3578
|
});
|
|
3575
3579
|
|
|
3576
3580
|
checkBtn.on('click', function() {
|
|
3577
3581
|
checkBtn.hide();
|
|
3578
|
-
|
|
3582
|
+
_on = true;
|
|
3583
|
+
updateSync();
|
|
3579
3584
|
});
|
|
3580
3585
|
|
|
3581
3586
|
repairBtn.on('click', function() {
|
|
3582
3587
|
var e = model.getActiveLayer();
|
|
3583
3588
|
if (!_simplifiedXX || !e.dataset.arcs) return;
|
|
3584
|
-
|
|
3585
|
-
showIntersections(
|
|
3589
|
+
_simplifiedXX = internal.repairIntersections(e.dataset.arcs, _simplifiedXX);
|
|
3590
|
+
showIntersections(_simplifiedXX, e.layer, e.dataset.arcs);
|
|
3586
3591
|
repairBtn.hide();
|
|
3587
3592
|
model.updated({repair: true});
|
|
3588
3593
|
gui.session.simplificationRepair();
|
|
@@ -3593,7 +3598,8 @@
|
|
|
3593
3598
|
reset(); // need this?
|
|
3594
3599
|
return;
|
|
3595
3600
|
}
|
|
3596
|
-
var needRefresh = e.flags.simplify_method || e.flags.simplify ||
|
|
3601
|
+
var needRefresh = e.flags.simplify_method || e.flags.simplify ||
|
|
3602
|
+
e.flags.repair || e.flags.clean;
|
|
3597
3603
|
if (needRefresh) {
|
|
3598
3604
|
updateAsync();
|
|
3599
3605
|
} else if (e.flags.simplify_amount) {
|
|
@@ -3608,17 +3614,18 @@
|
|
|
3608
3614
|
});
|
|
3609
3615
|
|
|
3610
3616
|
function intersectionsAreOn() {
|
|
3611
|
-
return
|
|
3617
|
+
return _on && !_disabled;
|
|
3612
3618
|
}
|
|
3613
3619
|
|
|
3614
|
-
function
|
|
3620
|
+
function turnOff() {
|
|
3621
|
+
hide();
|
|
3622
|
+
_on = false;
|
|
3615
3623
|
_simplifiedXX = null;
|
|
3616
3624
|
_unsimplifiedXX = null;
|
|
3617
3625
|
}
|
|
3618
3626
|
|
|
3619
3627
|
function reset() {
|
|
3620
|
-
|
|
3621
|
-
hide();
|
|
3628
|
+
turnOff();
|
|
3622
3629
|
if (_disabled) {
|
|
3623
3630
|
return;
|
|
3624
3631
|
}
|
|
@@ -3633,8 +3640,7 @@
|
|
|
3633
3640
|
|
|
3634
3641
|
function dismissForever() {
|
|
3635
3642
|
_disabled = true;
|
|
3636
|
-
|
|
3637
|
-
hide();
|
|
3643
|
+
turnOff();
|
|
3638
3644
|
}
|
|
3639
3645
|
|
|
3640
3646
|
function hide() {
|
|
@@ -3645,12 +3651,11 @@
|
|
|
3645
3651
|
// Update intersection display, after a short delay so map can redraw after previous
|
|
3646
3652
|
// operation (e.g. simplification change)
|
|
3647
3653
|
function updateAsync() {
|
|
3648
|
-
|
|
3649
|
-
setTimeout(refreshSync, 10);
|
|
3650
|
-
}
|
|
3654
|
+
setTimeout(updateSync, 10);
|
|
3651
3655
|
}
|
|
3652
3656
|
|
|
3653
|
-
function
|
|
3657
|
+
function updateSync(action) {
|
|
3658
|
+
if (!intersectionsAreOn()) return;
|
|
3654
3659
|
var e = model.getActiveLayer();
|
|
3655
3660
|
var arcs = e.dataset && e.dataset.arcs;
|
|
3656
3661
|
var intersectionOpts = {
|
|
@@ -3661,13 +3666,14 @@
|
|
|
3661
3666
|
return;
|
|
3662
3667
|
}
|
|
3663
3668
|
if (arcs.getRetainedInterval() > 0) {
|
|
3669
|
+
// simplification
|
|
3664
3670
|
_simplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
|
|
3665
3671
|
} else {
|
|
3666
3672
|
// no simplification
|
|
3667
|
-
_simplifiedXX = null; // clear old simplified XX
|
|
3668
|
-
if (
|
|
3669
|
-
//
|
|
3670
|
-
|
|
3673
|
+
_simplifiedXX = null; // clear any old simplified XX
|
|
3674
|
+
if (_unsimplifiedXX && action == 'simplify_drag_end') {
|
|
3675
|
+
// re-use previously generated intersection data (optimization)
|
|
3676
|
+
} else {
|
|
3671
3677
|
_unsimplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
|
|
3672
3678
|
}
|
|
3673
3679
|
}
|
|
@@ -3675,7 +3681,7 @@
|
|
|
3675
3681
|
}
|
|
3676
3682
|
|
|
3677
3683
|
function showIntersections(xx, lyr, arcs) {
|
|
3678
|
-
var pointLyr, count = 0;
|
|
3684
|
+
var pointLyr, count = 0, html;
|
|
3679
3685
|
el.show();
|
|
3680
3686
|
readout.show();
|
|
3681
3687
|
checkBtn.hide();
|
|
@@ -3685,12 +3691,13 @@
|
|
|
3685
3691
|
}
|
|
3686
3692
|
if (count == 0) {
|
|
3687
3693
|
map.setIntersectionLayer(null);
|
|
3688
|
-
|
|
3694
|
+
html = '<span class="icon black"></span>No self-intersections';
|
|
3689
3695
|
} else {
|
|
3690
3696
|
map.setIntersectionLayer(pointLyr, {layers:[pointLyr]});
|
|
3691
|
-
|
|
3692
|
-
readout.findChild('.close-btn').on('click', dismissForever);
|
|
3697
|
+
html = utils$1.format('<span class="icon"></span>%s line intersection%s', count, utils$1.pluralSuffix(count));
|
|
3693
3698
|
}
|
|
3699
|
+
readout.html(html);
|
|
3700
|
+
|
|
3694
3701
|
if (_simplifiedXX && count > 0) {
|
|
3695
3702
|
repairBtn.show();
|
|
3696
3703
|
} else {
|
|
@@ -5367,6 +5374,14 @@
|
|
|
5367
5374
|
else console.error(msg);
|
|
5368
5375
|
}
|
|
5369
5376
|
|
|
5377
|
+
function truncateString(str, maxLen) {
|
|
5378
|
+
maxLen = maxLen || 80;
|
|
5379
|
+
if (str.length > maxLen) {
|
|
5380
|
+
str = str.substring(0, maxLen - 3).trimEnd() + '...';
|
|
5381
|
+
}
|
|
5382
|
+
return str;
|
|
5383
|
+
}
|
|
5384
|
+
|
|
5370
5385
|
var uniqCount = 0;
|
|
5371
5386
|
function getUniqueName(prefix) {
|
|
5372
5387
|
return (prefix || "__id_") + (++uniqCount);
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.56";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1403,6 +1403,14 @@
|
|
|
1403
1403
|
else console.error(msg);
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
|
+
function truncateString(str, maxLen) {
|
|
1407
|
+
maxLen = maxLen || 80;
|
|
1408
|
+
if (str.length > maxLen) {
|
|
1409
|
+
str = str.substring(0, maxLen - 3).trimEnd() + '...';
|
|
1410
|
+
}
|
|
1411
|
+
return str;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1406
1414
|
var Logging = /*#__PURE__*/Object.freeze({
|
|
1407
1415
|
__proto__: null,
|
|
1408
1416
|
getLoggingSetter: getLoggingSetter,
|
|
@@ -1424,7 +1432,8 @@
|
|
|
1424
1432
|
formatColumns: formatColumns,
|
|
1425
1433
|
formatStringsAsGrid: formatStringsAsGrid,
|
|
1426
1434
|
formatLogArgs: formatLogArgs,
|
|
1427
|
-
logArgs: logArgs
|
|
1435
|
+
logArgs: logArgs,
|
|
1436
|
+
truncateString: truncateString
|
|
1428
1437
|
});
|
|
1429
1438
|
|
|
1430
1439
|
function Transform() {
|
|
@@ -14209,6 +14218,87 @@
|
|
|
14209
14218
|
};
|
|
14210
14219
|
}
|
|
14211
14220
|
|
|
14221
|
+
// Return array of variables on the left side of assignment operations
|
|
14222
|
+
// @hasDot (bool) Return property assignments via dot notation
|
|
14223
|
+
function getAssignedVars(exp, hasDot) {
|
|
14224
|
+
var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
|
|
14225
|
+
var matches = exp.match(rxp) || [];
|
|
14226
|
+
var f = function(s) {
|
|
14227
|
+
var i = s.indexOf('.');
|
|
14228
|
+
return hasDot ? i > -1 : i == -1;
|
|
14229
|
+
};
|
|
14230
|
+
var vars = utils.uniq(matches.filter(f));
|
|
14231
|
+
return vars;
|
|
14232
|
+
}
|
|
14233
|
+
|
|
14234
|
+
// Return array of objects with properties assigned via dot notation
|
|
14235
|
+
// e.g. 'd.value = 45' -> ['d']
|
|
14236
|
+
// export function getAssignmentObjects(exp) {
|
|
14237
|
+
// var matches = getAssignedVars(exp, true),
|
|
14238
|
+
// names = [];
|
|
14239
|
+
// matches.forEach(function(s) {
|
|
14240
|
+
// var match = /^([^.]+)\.[^.]+$/.exec(s);
|
|
14241
|
+
// var name = match ? match[1] : null;
|
|
14242
|
+
// if (name && name != 'this') {
|
|
14243
|
+
// names.push(name);
|
|
14244
|
+
// }
|
|
14245
|
+
// });
|
|
14246
|
+
// return utils.uniq(names);
|
|
14247
|
+
// }
|
|
14248
|
+
|
|
14249
|
+
function getExpressionFunction(exp, opts) {
|
|
14250
|
+
var func = compileExpressionToFunction(exp, opts);
|
|
14251
|
+
return function(rec, ctx) {
|
|
14252
|
+
var val;
|
|
14253
|
+
try {
|
|
14254
|
+
val = func.call(ctx.$, rec, ctx);
|
|
14255
|
+
} catch(e) {
|
|
14256
|
+
stop(e.name, "in expression [" + exp + "]:", e.message);
|
|
14257
|
+
}
|
|
14258
|
+
return val;
|
|
14259
|
+
};
|
|
14260
|
+
}
|
|
14261
|
+
|
|
14262
|
+
function compileExpressionToFunction(exp, opts) {
|
|
14263
|
+
// $$ added to avoid duplication with data field variables (an error condition)
|
|
14264
|
+
var functionBody, func;
|
|
14265
|
+
if (opts.returns) {
|
|
14266
|
+
// functionBody = 'return ' + functionBody;
|
|
14267
|
+
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
14268
|
+
} else {
|
|
14269
|
+
functionBody = exp;
|
|
14270
|
+
}
|
|
14271
|
+
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
14272
|
+
try {
|
|
14273
|
+
func = new Function('$$record,$$env', functionBody);
|
|
14274
|
+
} catch(e) {
|
|
14275
|
+
// if (opts.quiet) throw e;
|
|
14276
|
+
stop(e.name, 'in expression [' + exp + ']');
|
|
14277
|
+
}
|
|
14278
|
+
return func;
|
|
14279
|
+
}
|
|
14280
|
+
|
|
14281
|
+
function getBaseContext(ctx) {
|
|
14282
|
+
ctx = ctx || {};
|
|
14283
|
+
// Mask global properties (is this effective/worth doing?)
|
|
14284
|
+
ctx.globalThis = void 0; // some globals are not iterable
|
|
14285
|
+
(function() {
|
|
14286
|
+
for (var key in this) {
|
|
14287
|
+
ctx[key] = void 0;
|
|
14288
|
+
}
|
|
14289
|
+
}());
|
|
14290
|
+
ctx.console = console;
|
|
14291
|
+
return ctx;
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14294
|
+
var Expressions = /*#__PURE__*/Object.freeze({
|
|
14295
|
+
__proto__: null,
|
|
14296
|
+
getAssignedVars: getAssignedVars,
|
|
14297
|
+
getExpressionFunction: getExpressionFunction,
|
|
14298
|
+
compileExpressionToFunction: compileExpressionToFunction,
|
|
14299
|
+
getBaseContext: getBaseContext
|
|
14300
|
+
});
|
|
14301
|
+
|
|
14212
14302
|
// Compiled expression returns a value
|
|
14213
14303
|
function compileValueExpression(exp, lyr, arcs, opts) {
|
|
14214
14304
|
opts = opts || {};
|
|
@@ -14216,7 +14306,6 @@
|
|
|
14216
14306
|
return compileFeatureExpression(exp, lyr, arcs, opts);
|
|
14217
14307
|
}
|
|
14218
14308
|
|
|
14219
|
-
|
|
14220
14309
|
function compileFeaturePairFilterExpression(exp, lyr, arcs) {
|
|
14221
14310
|
var func = compileFeaturePairExpression(exp, lyr, arcs);
|
|
14222
14311
|
return function(idA, idB) {
|
|
@@ -14232,13 +14321,16 @@
|
|
|
14232
14321
|
var exp = cleanExpression(rawExp);
|
|
14233
14322
|
// don't add layer data to the context
|
|
14234
14323
|
// (fields are not added to the pair expression context)
|
|
14235
|
-
var ctx =
|
|
14324
|
+
var ctx = getFeatureExpressionContext({});
|
|
14236
14325
|
var getA = getProxyFactory(lyr, arcs);
|
|
14237
14326
|
var getB = getProxyFactory(lyr, arcs);
|
|
14238
14327
|
var vars = getAssignedVars(exp);
|
|
14239
14328
|
var functionBody = "with($$env){with($$record){return " + exp + "}}";
|
|
14240
14329
|
var func;
|
|
14241
14330
|
|
|
14331
|
+
// protect global object from assigned values
|
|
14332
|
+
nullifyUnsetProperties(vars, ctx);
|
|
14333
|
+
|
|
14242
14334
|
try {
|
|
14243
14335
|
func = new Function("$$record,$$env", functionBody);
|
|
14244
14336
|
} catch(e) {
|
|
@@ -14246,9 +14338,6 @@
|
|
|
14246
14338
|
stop(e.name, "in expression [" + exp + "]");
|
|
14247
14339
|
}
|
|
14248
14340
|
|
|
14249
|
-
// protect global object from assigned values
|
|
14250
|
-
nullifyUnsetProperties(vars, ctx);
|
|
14251
|
-
|
|
14252
14341
|
function getProxyFactory(lyr, arcs) {
|
|
14253
14342
|
var records = lyr.data ? lyr.data.getRecords() : [];
|
|
14254
14343
|
var getFeatureById = initFeatureProxy(lyr, arcs);
|
|
@@ -14284,12 +14373,12 @@
|
|
|
14284
14373
|
};
|
|
14285
14374
|
}
|
|
14286
14375
|
|
|
14287
|
-
function compileFeatureExpression(rawExp, lyr, arcs,
|
|
14288
|
-
var opts =
|
|
14376
|
+
function compileFeatureExpression(rawExp, lyr, arcs, optsArg) {
|
|
14377
|
+
var opts = optsArg || {},
|
|
14378
|
+
ctx = opts.context || {},
|
|
14289
14379
|
exp = cleanExpression(rawExp || ''),
|
|
14290
14380
|
mutable = !opts.no_assign, // block assignment expressions
|
|
14291
|
-
vars = getAssignedVars(exp)
|
|
14292
|
-
func, records;
|
|
14381
|
+
vars = getAssignedVars(exp);
|
|
14293
14382
|
|
|
14294
14383
|
if (mutable && vars.length > 0 && !lyr.data) {
|
|
14295
14384
|
initDataTable(lyr);
|
|
@@ -14297,110 +14386,45 @@
|
|
|
14297
14386
|
|
|
14298
14387
|
if (!mutable) {
|
|
14299
14388
|
// protect global object from assigned values
|
|
14300
|
-
|
|
14301
|
-
nullifyUnsetProperties(vars, opts.context);
|
|
14389
|
+
nullifyUnsetProperties(vars, ctx);
|
|
14302
14390
|
}
|
|
14303
14391
|
|
|
14304
|
-
records = lyr.data ? lyr.data.getRecords() : [];
|
|
14305
|
-
|
|
14392
|
+
var records = lyr.data ? lyr.data.getRecords() : [];
|
|
14393
|
+
var getFeatureById = initFeatureProxy(lyr, arcs, opts);
|
|
14394
|
+
var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
|
|
14395
|
+
var func = getExpressionFunction(exp, opts);
|
|
14396
|
+
ctx = getFeatureExpressionContext(lyr, ctx, opts);
|
|
14306
14397
|
|
|
14307
|
-
//
|
|
14398
|
+
// recId: index of a data record in the records array.
|
|
14399
|
+
// destRec: (optional argument, used by -calc) an object used to capture assignments
|
|
14400
|
+
// By default, assignments are captured by records[recId]
|
|
14401
|
+
//
|
|
14308
14402
|
return function(recId, destRec) {
|
|
14309
|
-
var
|
|
14403
|
+
var rec;
|
|
14310
14404
|
if (destRec) {
|
|
14311
|
-
|
|
14405
|
+
rec = destRec;
|
|
14312
14406
|
} else {
|
|
14313
|
-
|
|
14314
|
-
}
|
|
14407
|
+
rec = records[recId] || (records[recId] = {});
|
|
14408
|
+
}
|
|
14409
|
+
// Assigning feature/layer proxy to '$' ... ctx.$ is also exposed as 'this'
|
|
14410
|
+
// in the expression context.
|
|
14411
|
+
ctx.$ = recId >= 0 ? getFeatureById(recId) : layerOnlyProxy;
|
|
14412
|
+
// "_" is used as an alias for the expression context, so functions can still
|
|
14413
|
+
// be used when masked by variables of the same name.
|
|
14414
|
+
ctx._ = ctx;
|
|
14415
|
+
// Expose data properties using "d", like d3 does. (data propertries are
|
|
14416
|
+
// also available as "this.properties")
|
|
14417
|
+
ctx.d = rec || null;
|
|
14315
14418
|
|
|
14316
|
-
// initialize new fields to null so assignments work
|
|
14317
14419
|
if (mutable) {
|
|
14318
|
-
|
|
14319
|
-
|
|
14320
|
-
return func(record, recId);
|
|
14321
|
-
};
|
|
14322
|
-
}
|
|
14323
|
-
|
|
14324
|
-
// Return array of variables on the left side of assignment operations
|
|
14325
|
-
// @hasDot (bool) Return property assignments via dot notation
|
|
14326
|
-
function getAssignedVars(exp, hasDot) {
|
|
14327
|
-
var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
|
|
14328
|
-
var matches = exp.match(rxp) || [];
|
|
14329
|
-
var f = function(s) {
|
|
14330
|
-
var i = s.indexOf('.');
|
|
14331
|
-
return hasDot ? i > -1 : i == -1;
|
|
14332
|
-
};
|
|
14333
|
-
var vars = utils.uniq(matches.filter(f));
|
|
14334
|
-
return vars;
|
|
14335
|
-
}
|
|
14336
|
-
|
|
14337
|
-
// Return array of objects with properties assigned via dot notation
|
|
14338
|
-
// e.g. 'd.value = 45' -> ['d']
|
|
14339
|
-
function getAssignmentObjects(exp) {
|
|
14340
|
-
var matches = getAssignedVars(exp, true),
|
|
14341
|
-
names = [];
|
|
14342
|
-
matches.forEach(function(s) {
|
|
14343
|
-
var match = /^([^.]+)\.[^.]+$/.exec(s);
|
|
14344
|
-
var name = match ? match[1] : null;
|
|
14345
|
-
if (name && name != 'this') {
|
|
14346
|
-
names.push(name);
|
|
14347
|
-
}
|
|
14348
|
-
});
|
|
14349
|
-
return utils.uniq(names);
|
|
14350
|
-
}
|
|
14351
|
-
|
|
14352
|
-
function compileExpressionToFunction(exp, opts) {
|
|
14353
|
-
// $$ added to avoid duplication with data field variables (an error condition)
|
|
14354
|
-
var functionBody, func;
|
|
14355
|
-
if (opts.returns) {
|
|
14356
|
-
// functionBody = 'return ' + functionBody;
|
|
14357
|
-
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
14358
|
-
} else {
|
|
14359
|
-
functionBody = exp;
|
|
14360
|
-
}
|
|
14361
|
-
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
14362
|
-
try {
|
|
14363
|
-
func = new Function('$$record,$$env', functionBody);
|
|
14364
|
-
} catch(e) {
|
|
14365
|
-
// if (opts.quiet) throw e;
|
|
14366
|
-
stop(e.name, 'in expression [' + exp + ']');
|
|
14367
|
-
}
|
|
14368
|
-
return func;
|
|
14369
|
-
}
|
|
14370
|
-
|
|
14371
|
-
function getExpressionFunction(exp, lyr, arcs, opts) {
|
|
14372
|
-
var getFeatureById = initFeatureProxy(lyr, arcs, opts);
|
|
14373
|
-
var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
|
|
14374
|
-
var ctx = getExpressionContext(lyr, opts.context, opts);
|
|
14375
|
-
var func = compileExpressionToFunction(exp, opts);
|
|
14376
|
-
return function(rec, i) {
|
|
14377
|
-
var val;
|
|
14378
|
-
// Assigning feature/layer proxy to '$' -- maybe this should be removed,
|
|
14379
|
-
// since it is also exposed as "this".
|
|
14380
|
-
// (kludge) i is undefined in calc expressions ... we still
|
|
14381
|
-
// may need layer data (but not single-feature data)
|
|
14382
|
-
ctx.$ = i >= 0 ? getFeatureById(i) : layerOnlyProxy;
|
|
14383
|
-
ctx._ = ctx; // provide access to functions when masked by variable names
|
|
14384
|
-
ctx.d = rec || null; // expose data properties a la d3 (also exposed as this.properties)
|
|
14385
|
-
try {
|
|
14386
|
-
val = func.call(ctx.$, rec, ctx);
|
|
14387
|
-
} catch(e) {
|
|
14388
|
-
// if (opts.quiet) throw e;
|
|
14389
|
-
stop(e.name, "in expression [" + exp + "]:", e.message);
|
|
14420
|
+
// initialize assigned variables to rec.null so rec can capture them
|
|
14421
|
+
nullifyUnsetProperties(vars, rec);
|
|
14390
14422
|
}
|
|
14391
|
-
return
|
|
14423
|
+
return func(rec, ctx);
|
|
14392
14424
|
};
|
|
14393
14425
|
}
|
|
14394
14426
|
|
|
14395
|
-
function
|
|
14396
|
-
for (var i=0; i<vars.length; i++) {
|
|
14397
|
-
if (vars[i] in obj === false) {
|
|
14398
|
-
obj[vars[i]] = null;
|
|
14399
|
-
}
|
|
14400
|
-
}
|
|
14401
|
-
}
|
|
14402
|
-
|
|
14403
|
-
function getExpressionContext(lyr, mixins, opts) {
|
|
14427
|
+
function getFeatureExpressionContext(lyr, mixins, opts) {
|
|
14404
14428
|
var defs = getStashedVar('defs');
|
|
14405
14429
|
var env = getBaseContext();
|
|
14406
14430
|
var ctx = {};
|
|
@@ -14446,29 +14470,20 @@
|
|
|
14446
14470
|
}, ctx);
|
|
14447
14471
|
}
|
|
14448
14472
|
|
|
14449
|
-
function
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
(function() {
|
|
14454
|
-
for (var key in this) {
|
|
14455
|
-
ctx[key] = void 0;
|
|
14473
|
+
function nullifyUnsetProperties(vars, obj) {
|
|
14474
|
+
for (var i=0; i<vars.length; i++) {
|
|
14475
|
+
if (vars[i] in obj === false) {
|
|
14476
|
+
obj[vars[i]] = null;
|
|
14456
14477
|
}
|
|
14457
|
-
}
|
|
14458
|
-
ctx.console = console;
|
|
14459
|
-
return ctx;
|
|
14478
|
+
}
|
|
14460
14479
|
}
|
|
14461
14480
|
|
|
14462
|
-
var
|
|
14481
|
+
var FeatureExpressions = /*#__PURE__*/Object.freeze({
|
|
14463
14482
|
__proto__: null,
|
|
14464
14483
|
compileValueExpression: compileValueExpression,
|
|
14465
14484
|
compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
|
|
14466
14485
|
compileFeaturePairExpression: compileFeaturePairExpression,
|
|
14467
|
-
compileFeatureExpression: compileFeatureExpression
|
|
14468
|
-
getAssignedVars: getAssignedVars,
|
|
14469
|
-
getAssignmentObjects: getAssignmentObjects,
|
|
14470
|
-
compileExpressionToFunction: compileExpressionToFunction,
|
|
14471
|
-
getBaseContext: getBaseContext
|
|
14486
|
+
compileFeatureExpression: compileFeatureExpression
|
|
14472
14487
|
});
|
|
14473
14488
|
|
|
14474
14489
|
function getMode(values) {
|
|
@@ -25221,11 +25236,12 @@ ${svg}
|
|
|
25221
25236
|
describe: 'use field values to calculate data island weights'
|
|
25222
25237
|
});
|
|
25223
25238
|
|
|
25224
|
-
|
|
25225
|
-
|
|
25226
|
-
|
|
25227
|
-
|
|
25228
|
-
|
|
25239
|
+
// replaced by -require
|
|
25240
|
+
// parser.command('external')
|
|
25241
|
+
// .option('module', {
|
|
25242
|
+
// DEFAULT: true,
|
|
25243
|
+
// describe: 'name of Node module containing the command'
|
|
25244
|
+
// });
|
|
25229
25245
|
|
|
25230
25246
|
parser.command('filter-points')
|
|
25231
25247
|
// .describe('remove points that are not part of a group')
|
|
@@ -25311,17 +25327,17 @@ ${svg}
|
|
|
25311
25327
|
.option('no-replace', noReplaceOpt);
|
|
25312
25328
|
|
|
25313
25329
|
parser.command('require')
|
|
25314
|
-
.describe('require a Node module
|
|
25330
|
+
.describe('require a Node module or ES module to use in JS expressions')
|
|
25315
25331
|
.option('module', {
|
|
25316
25332
|
DEFAULT: true,
|
|
25317
|
-
describe: 'name of
|
|
25333
|
+
describe: 'name of installed module or path to module file'
|
|
25318
25334
|
})
|
|
25319
25335
|
.option('alias', {
|
|
25320
25336
|
describe: 'Set the module name to an alias'
|
|
25321
|
-
})
|
|
25322
|
-
.option('init', {
|
|
25323
|
-
describe: 'JS expression to run after the module loads'
|
|
25324
25337
|
});
|
|
25338
|
+
// .option('init', {
|
|
25339
|
+
// describe: 'JS expression to run after the module loads'
|
|
25340
|
+
// });
|
|
25325
25341
|
|
|
25326
25342
|
parser.command('rotate')
|
|
25327
25343
|
// .describe('apply d3-style 3-axis rotation to a lat-long dataset')
|
|
@@ -35318,7 +35334,6 @@ ${svg}
|
|
|
35318
35334
|
if (targets.length === 0 && targetId) {
|
|
35319
35335
|
stop('Layer not found:', targetId);
|
|
35320
35336
|
}
|
|
35321
|
-
// var vars = getAssignedVars(exp);
|
|
35322
35337
|
var defs = getStashedVar('defs') || {};
|
|
35323
35338
|
|
|
35324
35339
|
var ctx;
|
|
@@ -41983,8 +41998,8 @@ ${svg}
|
|
|
41983
41998
|
return true;
|
|
41984
41999
|
}
|
|
41985
42000
|
|
|
41986
|
-
cmd.require = async function(
|
|
41987
|
-
var
|
|
42001
|
+
cmd.require = async function(opts) {
|
|
42002
|
+
var globals = getStashedVar('defs');
|
|
41988
42003
|
var moduleFile, moduleName, mod;
|
|
41989
42004
|
if (!opts.module) {
|
|
41990
42005
|
stop("Missing module name or path to module");
|
|
@@ -42000,25 +42015,33 @@ ${svg}
|
|
|
42000
42015
|
moduleFile = require$1('path').join(process.cwd(), moduleFile);
|
|
42001
42016
|
}
|
|
42002
42017
|
try {
|
|
42003
|
-
|
|
42018
|
+
// import CJS and ES modules
|
|
42019
|
+
mod = await import(moduleFile || moduleName);
|
|
42020
|
+
if (mod.default) {
|
|
42021
|
+
mod = mod.default;
|
|
42022
|
+
}
|
|
42004
42023
|
if (typeof mod == 'function') {
|
|
42005
|
-
//
|
|
42024
|
+
// assuming that functions are mapshpaper command generators...
|
|
42025
|
+
// this MUST be changed asap.
|
|
42006
42026
|
var retn = mod(api);
|
|
42007
42027
|
if (retn && isValidExternalCommand(retn)) {
|
|
42008
42028
|
cmd.registerCommand(retn.name, retn);
|
|
42009
42029
|
}
|
|
42010
42030
|
}
|
|
42011
42031
|
} catch(e) {
|
|
42012
|
-
|
|
42032
|
+
if (!mod) {
|
|
42033
|
+
stop('Unable to load external module:', e.message, getErrorDetail(e));
|
|
42034
|
+
}
|
|
42013
42035
|
}
|
|
42014
42036
|
if (moduleName || opts.alias) {
|
|
42015
|
-
|
|
42037
|
+
globals[opts.alias || moduleName] = mod;
|
|
42016
42038
|
} else {
|
|
42017
|
-
Object.assign(
|
|
42018
|
-
}
|
|
42019
|
-
if (opts.init) {
|
|
42020
|
-
await evalTemplateExpression(opts.init, targets);
|
|
42039
|
+
Object.assign(globals, mod);
|
|
42021
42040
|
}
|
|
42041
|
+
// instead of an init expression, you could use -run <expression>
|
|
42042
|
+
// if (opts.init) {
|
|
42043
|
+
// await evalTemplateExpression(opts.init, targets);
|
|
42044
|
+
// }
|
|
42022
42045
|
};
|
|
42023
42046
|
|
|
42024
42047
|
// Parse an array or a string of command line tokens into an array of
|
|
@@ -42123,7 +42146,8 @@ ${svg}
|
|
|
42123
42146
|
stop('Expected a string containing mapshaper commands; received:', tmp);
|
|
42124
42147
|
}
|
|
42125
42148
|
if (tmp) {
|
|
42126
|
-
message(
|
|
42149
|
+
// truncate message (command might include a large GeoJSON string in an -i command)
|
|
42150
|
+
message(`command: [${truncateString(tmp, 150)}]`);
|
|
42127
42151
|
commands = parseCommands(tmp);
|
|
42128
42152
|
|
|
42129
42153
|
// TODO: remove duplication with mapshaper-run-commands.mjs
|
|
@@ -44473,9 +44497,9 @@ ${svg}
|
|
|
44473
44497
|
} else if (name == 'explode') {
|
|
44474
44498
|
outputLayers = applyCommandToEachLayer(cmd.explodeFeatures, targetLayers, arcs, opts);
|
|
44475
44499
|
|
|
44476
|
-
|
|
44477
|
-
|
|
44478
|
-
|
|
44500
|
+
// -require now incorporates functionality of -external
|
|
44501
|
+
// } else if (name == 'external') {
|
|
44502
|
+
// cmd.require(targets, opts);
|
|
44479
44503
|
|
|
44480
44504
|
} else if (name == 'filter') {
|
|
44481
44505
|
outputLayers = applyCommandToEachLayer(cmd.filterFeatures, targetLayers, arcs, opts);
|
|
@@ -44617,7 +44641,7 @@ ${svg}
|
|
|
44617
44641
|
cmd.renameLayers(targetLayers, opts.names, job.catalog);
|
|
44618
44642
|
|
|
44619
44643
|
} else if (name == 'require') {
|
|
44620
|
-
cmd.require(
|
|
44644
|
+
await cmd.require(opts);
|
|
44621
44645
|
|
|
44622
44646
|
} else if (name == 'rotate') {
|
|
44623
44647
|
targets.forEach(function(targ) {
|
|
@@ -45445,6 +45469,7 @@ ${svg}
|
|
|
45445
45469
|
Explode,
|
|
45446
45470
|
Export,
|
|
45447
45471
|
Expressions,
|
|
45472
|
+
FeatureExpressions,
|
|
45448
45473
|
FileExport,
|
|
45449
45474
|
FileImport,
|
|
45450
45475
|
FilenameUtils,
|
package/www/page.css
CHANGED
|
@@ -959,10 +959,6 @@ img.close-btn:hover,
|
|
|
959
959
|
left: 13px;
|
|
960
960
|
}
|
|
961
961
|
|
|
962
|
-
.intersection-count {
|
|
963
|
-
vertical-align: middle;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
962
|
.intersection-check {
|
|
967
963
|
display: none;
|
|
968
964
|
}
|
|
@@ -979,13 +975,13 @@ img.close-btn:hover,
|
|
|
979
975
|
background-color: black;
|
|
980
976
|
}
|
|
981
977
|
|
|
982
|
-
.intersection-
|
|
978
|
+
.intersection-display .close-btn {
|
|
983
979
|
width: 16px;
|
|
984
980
|
height: 16px;
|
|
985
981
|
cursor: pointer;
|
|
986
982
|
position: relative;
|
|
987
983
|
top: 4px;
|
|
988
|
-
margin-left:
|
|
984
|
+
margin-left: 1px;
|
|
989
985
|
}
|
|
990
986
|
|
|
991
987
|
/*.intersection-display .text-btn.disabled {
|