mapshaper 0.5.84 → 0.5.88
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 +420 -128
- package/package.json +1 -1
- package/www/mapshaper-gui.js +274 -140
- package/www/mapshaper.js +420 -128
- package/www/nacis/Makefile +22 -0
- package/www/nacis/Makefile.txt +22 -0
- package/www/nacis/images/close.png +0 -0
- package/www/nacis/images/eye.png +0 -0
- package/www/nacis/images/eye2.png +0 -0
- package/www/nacis/index.html +262 -0
- package/www/nacis/manifest.js +27 -0
- package/www/nacis/map.svg +12308 -0
- package/CHANGELOG.md +0 -1285
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.87";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -4895,6 +4895,11 @@
|
|
|
4895
4895
|
};
|
|
4896
4896
|
}
|
|
4897
4897
|
|
|
4898
|
+
function MultiShapeIter(arcs) {
|
|
4899
|
+
var iter = new ShapeIter(arcs);
|
|
4900
|
+
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4898
4903
|
// Iterate along a path made up of one or more arcs.
|
|
4899
4904
|
//
|
|
4900
4905
|
function ShapeIter(arcs) {
|
|
@@ -4945,6 +4950,7 @@
|
|
|
4945
4950
|
PointIter: PointIter,
|
|
4946
4951
|
ArcIter: ArcIter,
|
|
4947
4952
|
FilteredArcIter: FilteredArcIter,
|
|
4953
|
+
MultiShapeIter: MultiShapeIter,
|
|
4948
4954
|
ShapeIter: ShapeIter
|
|
4949
4955
|
});
|
|
4950
4956
|
|
|
@@ -8222,10 +8228,21 @@
|
|
|
8222
8228
|
return +n.toPrecision(d);
|
|
8223
8229
|
}
|
|
8224
8230
|
|
|
8231
|
+
|
|
8225
8232
|
function roundToDigits(n, d) {
|
|
8226
8233
|
return +n.toFixed(d); // string conversion makes this slow
|
|
8227
8234
|
}
|
|
8228
8235
|
|
|
8236
|
+
// Used in mapshaper-expression-utils.js
|
|
8237
|
+
// TODO: choose between this and the above function
|
|
8238
|
+
function roundToDigits2(n, d) {
|
|
8239
|
+
var k = 1;
|
|
8240
|
+
if (!n && n !== 0) return n; // don't coerce null to 0
|
|
8241
|
+
d = d | 0;
|
|
8242
|
+
while (d-- > 0) k *= 10;
|
|
8243
|
+
return Math.round(n * k) / k;
|
|
8244
|
+
}
|
|
8245
|
+
|
|
8229
8246
|
function roundToTenths(n) {
|
|
8230
8247
|
return (Math.round(n * 10)) / 10;
|
|
8231
8248
|
}
|
|
@@ -8300,6 +8317,7 @@
|
|
|
8300
8317
|
__proto__: null,
|
|
8301
8318
|
roundToSignificantDigits: roundToSignificantDigits,
|
|
8302
8319
|
roundToDigits: roundToDigits,
|
|
8320
|
+
roundToDigits2: roundToDigits2,
|
|
8303
8321
|
roundToTenths: roundToTenths,
|
|
8304
8322
|
getRoundingFunction: getRoundingFunction,
|
|
8305
8323
|
getBoundsPrecisionForDisplay: getBoundsPrecisionForDisplay,
|
|
@@ -8938,15 +8956,15 @@
|
|
|
8938
8956
|
});
|
|
8939
8957
|
}
|
|
8940
8958
|
|
|
8941
|
-
function
|
|
8959
|
+
function cleanExpression(exp) {
|
|
8960
|
+
// workaround for problem in GNU Make v4: end-of-line backslashes inside
|
|
8961
|
+
// quoted strings are left in the string (other shell environments remove them)
|
|
8962
|
+
return exp.replace(/\\\n/g, ' ');
|
|
8963
|
+
}
|
|
8964
|
+
|
|
8965
|
+
function addFeatureExpressionUtils(env) {
|
|
8942
8966
|
Object.assign(env, {
|
|
8943
|
-
round:
|
|
8944
|
-
var k = 1;
|
|
8945
|
-
if (!val && val !== 0) return val; // don't coerce null to 0
|
|
8946
|
-
dig = dig | 0;
|
|
8947
|
-
while(dig-- > 0) k *= 10;
|
|
8948
|
-
return Math.round(val * k) / k;
|
|
8949
|
-
},
|
|
8967
|
+
round: roundToDigits2,
|
|
8950
8968
|
int_median: interpolated_median,
|
|
8951
8969
|
sprintf: utils.format,
|
|
8952
8970
|
blend: blend
|
|
@@ -9325,6 +9343,39 @@
|
|
|
9325
9343
|
};
|
|
9326
9344
|
}
|
|
9327
9345
|
|
|
9346
|
+
// Returns an object representing a layer in a JS expression
|
|
9347
|
+
function getLayerProxy(lyr, arcs) {
|
|
9348
|
+
var obj = {};
|
|
9349
|
+
var records = lyr.data ? lyr.data.getRecords() : null;
|
|
9350
|
+
var getters = {
|
|
9351
|
+
name: lyr.name,
|
|
9352
|
+
data: records,
|
|
9353
|
+
type: lyr.geometry_type
|
|
9354
|
+
};
|
|
9355
|
+
addGetters(obj, getters);
|
|
9356
|
+
addBBoxGetter(obj, lyr, arcs);
|
|
9357
|
+
obj.empty = function() {
|
|
9358
|
+
return getFeatureCount(lyr) === 0;
|
|
9359
|
+
};
|
|
9360
|
+
obj.size = function() {
|
|
9361
|
+
return getFeatureCount(lyr);
|
|
9362
|
+
};
|
|
9363
|
+
return obj;
|
|
9364
|
+
}
|
|
9365
|
+
|
|
9366
|
+
function addLayerGetters(ctx, lyr, arcs) {
|
|
9367
|
+
var layerProxy;
|
|
9368
|
+
addGetters(ctx, {
|
|
9369
|
+
layer_name: lyr.name || '', // consider removing this
|
|
9370
|
+
layer: function() {
|
|
9371
|
+
// init on first access (to avoid overhead if not used)
|
|
9372
|
+
if (!layerProxy) layerProxy = getLayerProxy(lyr, arcs);
|
|
9373
|
+
return layerProxy;
|
|
9374
|
+
}
|
|
9375
|
+
});
|
|
9376
|
+
return ctx;
|
|
9377
|
+
}
|
|
9378
|
+
|
|
9328
9379
|
function addBBoxGetter(obj, lyr, arcs) {
|
|
9329
9380
|
var bbox;
|
|
9330
9381
|
addGetters(obj, {
|
|
@@ -9354,32 +9405,6 @@
|
|
|
9354
9405
|
return bbox;
|
|
9355
9406
|
}
|
|
9356
9407
|
|
|
9357
|
-
// Returns an object representing a layer in a JS expression
|
|
9358
|
-
function getLayerProxy(lyr, arcs) {
|
|
9359
|
-
var obj = {};
|
|
9360
|
-
var records = lyr.data ? lyr.data.getRecords() : null;
|
|
9361
|
-
var getters = {
|
|
9362
|
-
name: lyr.name,
|
|
9363
|
-
data: records
|
|
9364
|
-
};
|
|
9365
|
-
addGetters(obj, getters);
|
|
9366
|
-
addBBoxGetter(obj, lyr, arcs);
|
|
9367
|
-
return obj;
|
|
9368
|
-
}
|
|
9369
|
-
|
|
9370
|
-
function addLayerGetters(ctx, lyr, arcs) {
|
|
9371
|
-
var layerProxy;
|
|
9372
|
-
addGetters(ctx, {
|
|
9373
|
-
layer_name: lyr.name || '', // consider removing this
|
|
9374
|
-
layer: function() {
|
|
9375
|
-
// init on first access (to avoid overhead if not used)
|
|
9376
|
-
if (!layerProxy) layerProxy = getLayerProxy(lyr, arcs);
|
|
9377
|
-
return layerProxy;
|
|
9378
|
-
}
|
|
9379
|
-
});
|
|
9380
|
-
return ctx;
|
|
9381
|
-
}
|
|
9382
|
-
|
|
9383
9408
|
// Returns a function to return a feature proxy by id
|
|
9384
9409
|
// (the proxy appears as "this" or "$" in a feature expression)
|
|
9385
9410
|
function initFeatureProxy(lyr, arcs, optsArg) {
|
|
@@ -9576,11 +9601,6 @@
|
|
|
9576
9601
|
return compileFeatureExpression(exp, lyr, arcs, opts);
|
|
9577
9602
|
}
|
|
9578
9603
|
|
|
9579
|
-
function cleanExpression(exp) {
|
|
9580
|
-
// workaround for problem in GNU Make v4: end-of-line backslashes inside
|
|
9581
|
-
// quoted strings are left in the string (other shell environments remove them)
|
|
9582
|
-
return exp.replace(/\\\n/g, ' ');
|
|
9583
|
-
}
|
|
9584
9604
|
|
|
9585
9605
|
function compileFeaturePairFilterExpression(exp, lyr, arcs) {
|
|
9586
9606
|
var func = compileFeaturePairExpression(exp, lyr, arcs);
|
|
@@ -9716,14 +9736,19 @@
|
|
|
9716
9736
|
|
|
9717
9737
|
function compileExpressionToFunction(exp, opts) {
|
|
9718
9738
|
// $$ added to avoid duplication with data field variables (an error condition)
|
|
9719
|
-
var functionBody
|
|
9720
|
-
|
|
9721
|
-
|
|
9739
|
+
var functionBody, func;
|
|
9740
|
+
if (opts.returns) {
|
|
9741
|
+
// functionBody = 'return ' + functionBody;
|
|
9742
|
+
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
9743
|
+
} else {
|
|
9744
|
+
functionBody = exp;
|
|
9745
|
+
}
|
|
9746
|
+
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
9722
9747
|
try {
|
|
9723
|
-
func = new Function(
|
|
9748
|
+
func = new Function('$$record,$$env', functionBody);
|
|
9724
9749
|
} catch(e) {
|
|
9725
9750
|
// if (opts.quiet) throw e;
|
|
9726
|
-
stop(e.name,
|
|
9751
|
+
stop(e.name, 'in expression [' + exp + ']');
|
|
9727
9752
|
}
|
|
9728
9753
|
return func;
|
|
9729
9754
|
}
|
|
@@ -9766,7 +9791,7 @@
|
|
|
9766
9791
|
var ctx = {};
|
|
9767
9792
|
var fields = lyr.data ? lyr.data.getFields() : [];
|
|
9768
9793
|
opts = opts || {};
|
|
9769
|
-
|
|
9794
|
+
addFeatureExpressionUtils(env); // mix in round(), sprintf(), etc.
|
|
9770
9795
|
if (fields.length > 0) {
|
|
9771
9796
|
// default to null values, so assignments to missing data properties
|
|
9772
9797
|
// are applied to the data record, not the global object
|
|
@@ -9821,7 +9846,6 @@
|
|
|
9821
9846
|
var Expressions = /*#__PURE__*/Object.freeze({
|
|
9822
9847
|
__proto__: null,
|
|
9823
9848
|
compileValueExpression: compileValueExpression,
|
|
9824
|
-
cleanExpression: cleanExpression,
|
|
9825
9849
|
compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
|
|
9826
9850
|
compileFeaturePairExpression: compileFeaturePairExpression,
|
|
9827
9851
|
compileFeatureExpression: compileFeatureExpression,
|
|
@@ -13712,6 +13736,9 @@
|
|
|
13712
13736
|
flipped: 'boolean',
|
|
13713
13737
|
rotated: 'boolean',
|
|
13714
13738
|
direction: 'number',
|
|
13739
|
+
sides: 'number', // polygons and stars
|
|
13740
|
+
points: 'number', // polygons and stars
|
|
13741
|
+
anchor: null, // arrows; takes start, middle, end
|
|
13715
13742
|
'head-angle': 'number',
|
|
13716
13743
|
'head-width': 'number',
|
|
13717
13744
|
'head-length': 'number',
|
|
@@ -18561,6 +18588,13 @@ ${svg}
|
|
|
18561
18588
|
return this;
|
|
18562
18589
|
};
|
|
18563
18590
|
|
|
18591
|
+
this.options = function(o) {
|
|
18592
|
+
Object.keys(o).forEach(function(key) {
|
|
18593
|
+
this.option(key, o[key]);
|
|
18594
|
+
}, this);
|
|
18595
|
+
return this;
|
|
18596
|
+
};
|
|
18597
|
+
|
|
18564
18598
|
this.done = function() {
|
|
18565
18599
|
return _command;
|
|
18566
18600
|
};
|
|
@@ -19524,14 +19558,6 @@ ${svg}
|
|
|
19524
19558
|
.option('target', targetOpt)
|
|
19525
19559
|
.option('no-replace', noReplaceOpt);
|
|
19526
19560
|
|
|
19527
|
-
parser.command('ignore')
|
|
19528
|
-
// .describe('stop processing if a condition is met')
|
|
19529
|
-
.option('empty', {
|
|
19530
|
-
describe: 'ignore empty files',
|
|
19531
|
-
type: 'flag'
|
|
19532
|
-
})
|
|
19533
|
-
.option('target', targetOpt);
|
|
19534
|
-
|
|
19535
19561
|
parser.command('include')
|
|
19536
19562
|
.describe('import JS data and functions for use in JS expressions')
|
|
19537
19563
|
.option('file', {
|
|
@@ -20111,16 +20137,17 @@ ${svg}
|
|
|
20111
20137
|
type: 'distance'
|
|
20112
20138
|
})
|
|
20113
20139
|
.option('sides', {
|
|
20114
|
-
describe: 'sides of a polygon
|
|
20140
|
+
describe: 'number of sides of a polygon symbol',
|
|
20115
20141
|
type: 'number'
|
|
20116
20142
|
})
|
|
20117
20143
|
.option('orientation', {
|
|
20144
|
+
// TODO: removed (replaced by flipped and rotated)
|
|
20118
20145
|
// describe: 'use orientation=b for a rotated or flipped orientation'
|
|
20119
20146
|
})
|
|
20120
|
-
.option('flipped', {
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
})
|
|
20147
|
+
// .option('flipped', {
|
|
20148
|
+
// type: 'flag',
|
|
20149
|
+
// describe: 'symbol is vertically flipped'
|
|
20150
|
+
// })
|
|
20124
20151
|
.option('rotated', {
|
|
20125
20152
|
type: 'flag',
|
|
20126
20153
|
describe: 'symbol is rotated to a different orientation'
|
|
@@ -20128,8 +20155,8 @@ ${svg}
|
|
|
20128
20155
|
.option('rotation', {
|
|
20129
20156
|
describe: 'rotation of symbol in degrees'
|
|
20130
20157
|
})
|
|
20131
|
-
.option('
|
|
20132
|
-
|
|
20158
|
+
.option('points', {
|
|
20159
|
+
describe: '(star) number of points'
|
|
20133
20160
|
})
|
|
20134
20161
|
.option('point-ratio', {
|
|
20135
20162
|
old_alias: 'star-ratio',
|
|
@@ -20183,6 +20210,9 @@ ${svg}
|
|
|
20183
20210
|
describe: '(arrow) min ratio of stem to total length',
|
|
20184
20211
|
type: 'number'
|
|
20185
20212
|
})
|
|
20213
|
+
.option('anchor', {
|
|
20214
|
+
describe: '(arrow) takes one of: start, middle, end (default is start)'
|
|
20215
|
+
})
|
|
20186
20216
|
.option('stroke', {})
|
|
20187
20217
|
.option('stroke-width', {})
|
|
20188
20218
|
.option('fill', {
|
|
@@ -20490,6 +20520,49 @@ ${svg}
|
|
|
20490
20520
|
})
|
|
20491
20521
|
.option('target', targetOpt);
|
|
20492
20522
|
|
|
20523
|
+
parser.section('Control flow commands');
|
|
20524
|
+
|
|
20525
|
+
var ifOpts = {
|
|
20526
|
+
expression: {
|
|
20527
|
+
DEFAULT: true,
|
|
20528
|
+
describe: 'JS expression targeting a single layer'
|
|
20529
|
+
},
|
|
20530
|
+
empty: {
|
|
20531
|
+
describe: 'run if layer is empty',
|
|
20532
|
+
type: 'flag'
|
|
20533
|
+
},
|
|
20534
|
+
'not-empty': {
|
|
20535
|
+
describe: 'run if layer is not empty',
|
|
20536
|
+
type: 'flag'
|
|
20537
|
+
},
|
|
20538
|
+
layer: {
|
|
20539
|
+
describe: 'name or id of layer to test (default is current target)'
|
|
20540
|
+
},
|
|
20541
|
+
target: targetOpt
|
|
20542
|
+
};
|
|
20543
|
+
|
|
20544
|
+
parser.command('if')
|
|
20545
|
+
.describe('run the following commands if a condition is met')
|
|
20546
|
+
.options(ifOpts);
|
|
20547
|
+
|
|
20548
|
+
parser.command('elif')
|
|
20549
|
+
.describe('test an alternate condition; used after -if')
|
|
20550
|
+
.options(ifOpts);
|
|
20551
|
+
|
|
20552
|
+
parser.command('else')
|
|
20553
|
+
.describe('run commands if all preceding -if/-elif conditions are false');
|
|
20554
|
+
|
|
20555
|
+
parser.command('endif')
|
|
20556
|
+
.describe('mark the end of an -if sequence');
|
|
20557
|
+
|
|
20558
|
+
parser.command('ignore')
|
|
20559
|
+
// .describe('stop processing if a condition is met')
|
|
20560
|
+
.option('empty', {
|
|
20561
|
+
describe: 'ignore empty files',
|
|
20562
|
+
type: 'flag'
|
|
20563
|
+
})
|
|
20564
|
+
.option('target', targetOpt);
|
|
20565
|
+
|
|
20493
20566
|
parser.section('Informational commands');
|
|
20494
20567
|
|
|
20495
20568
|
parser.command('calc')
|
|
@@ -34162,6 +34235,141 @@ ${svg}
|
|
|
34162
34235
|
};
|
|
34163
34236
|
}
|
|
34164
34237
|
|
|
34238
|
+
function resetControlFlow() {
|
|
34239
|
+
setStateVar('control', null);
|
|
34240
|
+
}
|
|
34241
|
+
|
|
34242
|
+
function inControlBlock() {
|
|
34243
|
+
var state = getState();
|
|
34244
|
+
return !!state.inControlBlock;
|
|
34245
|
+
}
|
|
34246
|
+
|
|
34247
|
+
function enterActiveBranch() {
|
|
34248
|
+
var state = getState();
|
|
34249
|
+
state.inControlBlock = true;
|
|
34250
|
+
state.active = true;
|
|
34251
|
+
state.complete = true;
|
|
34252
|
+
}
|
|
34253
|
+
|
|
34254
|
+
function enterInactiveBranch() {
|
|
34255
|
+
var state = getState();
|
|
34256
|
+
state.inControlBlock = true;
|
|
34257
|
+
state.active = false;
|
|
34258
|
+
}
|
|
34259
|
+
|
|
34260
|
+
function blockWasActive() {
|
|
34261
|
+
return !!getState().complete;
|
|
34262
|
+
}
|
|
34263
|
+
|
|
34264
|
+
function inActiveBranch() {
|
|
34265
|
+
return !!getState().active;
|
|
34266
|
+
}
|
|
34267
|
+
|
|
34268
|
+
function getState() {
|
|
34269
|
+
var o = getStateVar('control') || setStateVar('control', {}) || getStateVar('control');
|
|
34270
|
+
return o;
|
|
34271
|
+
}
|
|
34272
|
+
|
|
34273
|
+
function compileLayerExpression(expr, lyr, dataset, opts) {
|
|
34274
|
+
var proxy = getLayerProxy(lyr, dataset.arcs, opts);
|
|
34275
|
+
var exprOpts = Object.assign({returns: true}, opts);
|
|
34276
|
+
var func = compileExpressionToFunction(expr, exprOpts);
|
|
34277
|
+
var ctx = proxy;
|
|
34278
|
+
return function() {
|
|
34279
|
+
try {
|
|
34280
|
+
return func.call(proxy, {}, ctx);
|
|
34281
|
+
} catch(e) {
|
|
34282
|
+
// if (opts.quiet) throw e;
|
|
34283
|
+
stop(e.name, "in expression [" + expr + "]:", e.message);
|
|
34284
|
+
}
|
|
34285
|
+
};
|
|
34286
|
+
}
|
|
34287
|
+
|
|
34288
|
+
function skipCommand(cmdName) {
|
|
34289
|
+
// allow all control commands to run
|
|
34290
|
+
if (isControlFlowCommand(cmdName)) return false;
|
|
34291
|
+
return inControlBlock() && !inActiveBranch();
|
|
34292
|
+
}
|
|
34293
|
+
|
|
34294
|
+
cmd.if = function(catalog, opts) {
|
|
34295
|
+
if (inControlBlock()) {
|
|
34296
|
+
stop('Nested -if commands are not supported.');
|
|
34297
|
+
}
|
|
34298
|
+
evaluateIf(catalog, opts);
|
|
34299
|
+
};
|
|
34300
|
+
|
|
34301
|
+
cmd.elif = function(catalog, opts) {
|
|
34302
|
+
if (!inControlBlock()) {
|
|
34303
|
+
stop('-elif command must be preceded by an -if command.');
|
|
34304
|
+
}
|
|
34305
|
+
evaluateIf(catalog, opts);
|
|
34306
|
+
};
|
|
34307
|
+
|
|
34308
|
+
cmd.else = function() {
|
|
34309
|
+
if (!inControlBlock()) {
|
|
34310
|
+
stop('-else command must be preceded by an -if command.');
|
|
34311
|
+
}
|
|
34312
|
+
if (blockWasActive()) {
|
|
34313
|
+
enterInactiveBranch();
|
|
34314
|
+
} else {
|
|
34315
|
+
enterActiveBranch();
|
|
34316
|
+
}
|
|
34317
|
+
};
|
|
34318
|
+
|
|
34319
|
+
cmd.endif = function() {
|
|
34320
|
+
if (!inControlBlock()) {
|
|
34321
|
+
stop('-endif command must be preceded by an -if command.');
|
|
34322
|
+
}
|
|
34323
|
+
resetControlFlow();
|
|
34324
|
+
};
|
|
34325
|
+
|
|
34326
|
+
function isControlFlowCommand(cmd) {
|
|
34327
|
+
return ['if','elif','else','endif'].includes(cmd);
|
|
34328
|
+
}
|
|
34329
|
+
|
|
34330
|
+
function testLayer(catalog, opts) {
|
|
34331
|
+
var targ = getTargetLayer(catalog, opts);
|
|
34332
|
+
if (opts.expression) {
|
|
34333
|
+
return compileLayerExpression(opts.expression, targ.layer, targ.dataset, opts)();
|
|
34334
|
+
}
|
|
34335
|
+
if (opts.empty) {
|
|
34336
|
+
return layerIsEmpty(targ.layer);
|
|
34337
|
+
}
|
|
34338
|
+
if (opts.not_empty) {
|
|
34339
|
+
return !layerIsEmpty(targ.layer);
|
|
34340
|
+
}
|
|
34341
|
+
return true;
|
|
34342
|
+
}
|
|
34343
|
+
|
|
34344
|
+
function evaluateIf(catalog, opts) {
|
|
34345
|
+
if (!blockWasActive() && testLayer(catalog, opts)) {
|
|
34346
|
+
enterActiveBranch();
|
|
34347
|
+
} else {
|
|
34348
|
+
enterInactiveBranch();
|
|
34349
|
+
}
|
|
34350
|
+
}
|
|
34351
|
+
|
|
34352
|
+
// layerId: optional layer identifier
|
|
34353
|
+
//
|
|
34354
|
+
function getTargetLayer(catalog, opts) {
|
|
34355
|
+
var layerId = opts.layer || opts.target;
|
|
34356
|
+
var targets = catalog.findCommandTargets(layerId);
|
|
34357
|
+
if (targets.length === 0) {
|
|
34358
|
+
if (layerId) {
|
|
34359
|
+
stop('Layer not found:', layerId);
|
|
34360
|
+
} else {
|
|
34361
|
+
stop('Missing a target layer.');
|
|
34362
|
+
}
|
|
34363
|
+
}
|
|
34364
|
+
if (targets.length > 1 || targets[0].layers.length > 1) {
|
|
34365
|
+
stop('Command requires a single target layer.');
|
|
34366
|
+
}
|
|
34367
|
+
return {
|
|
34368
|
+
layer: targets[0].layers[0],
|
|
34369
|
+
dataset: targets[0].dataset
|
|
34370
|
+
};
|
|
34371
|
+
}
|
|
34372
|
+
|
|
34165
34373
|
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
34166
34374
|
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
34167
34375
|
interrupt('Layer is empty, stopping processing');
|
|
@@ -34708,6 +34916,28 @@ ${svg}
|
|
|
34708
34916
|
return findVertexIds(p2.x, p2.y, arcs);
|
|
34709
34917
|
}
|
|
34710
34918
|
|
|
34919
|
+
// Given a location @p (e.g. corresponding to the mouse pointer location),
|
|
34920
|
+
// find the midpoint of two vertices on @shp suitable for inserting a new vertex,
|
|
34921
|
+
// but only if:
|
|
34922
|
+
// 1. point @p is closer to the midpoint than either adjacent vertex
|
|
34923
|
+
// 2. the segment containing @p is longer than a minimum distance in pixels.
|
|
34924
|
+
//
|
|
34925
|
+
function findInsertionPoint(p, shp, arcs, pixelSize) {
|
|
34926
|
+
var p2 = findNearestVertex(p[0], p[1], shp, arcs);
|
|
34927
|
+
|
|
34928
|
+
}
|
|
34929
|
+
|
|
34930
|
+
function snapVerticesToPoint(ids, p, arcs, final) {
|
|
34931
|
+
ids.forEach(function(idx) {
|
|
34932
|
+
setVertexCoords(p[0], p[1], idx, arcs);
|
|
34933
|
+
});
|
|
34934
|
+
if (final) {
|
|
34935
|
+
// kludge to get dataset to recalculate internal bounding boxes
|
|
34936
|
+
arcs.transformPoints(function() {});
|
|
34937
|
+
}
|
|
34938
|
+
}
|
|
34939
|
+
|
|
34940
|
+
|
|
34711
34941
|
// p: point to snap
|
|
34712
34942
|
// ids: ids of nearby vertices, possibly including an arc endpoint
|
|
34713
34943
|
function snapPointToArcEndpoint(p, ids, arcs) {
|
|
@@ -34794,6 +35024,8 @@ ${svg}
|
|
|
34794
35024
|
var VertexUtils = /*#__PURE__*/Object.freeze({
|
|
34795
35025
|
__proto__: null,
|
|
34796
35026
|
findNearestVertices: findNearestVertices,
|
|
35027
|
+
findInsertionPoint: findInsertionPoint,
|
|
35028
|
+
snapVerticesToPoint: snapVerticesToPoint,
|
|
34797
35029
|
snapPointToArcEndpoint: snapPointToArcEndpoint,
|
|
34798
35030
|
findVertexIds: findVertexIds,
|
|
34799
35031
|
getVertexCoords: getVertexCoords,
|
|
@@ -38075,40 +38307,14 @@ ${svg}
|
|
|
38075
38307
|
// return [a[0] + b[0], a[1] + b[1]];
|
|
38076
38308
|
// }
|
|
38077
38309
|
|
|
38078
|
-
function getFilledArrowCoords(d) {
|
|
38079
|
-
var direction = d.rotation || d.direction || 0,
|
|
38080
|
-
stemTaper = d['stem-taper'] || 0,
|
|
38081
|
-
stemCurve = d['stem-curve'] || 0,
|
|
38082
|
-
size = calcArrowSize(d);
|
|
38083
|
-
|
|
38084
|
-
if (!size) return null;
|
|
38085
|
-
|
|
38086
|
-
var headDx = size.headWidth / 2,
|
|
38087
|
-
stemDx = size.stemWidth / 2,
|
|
38088
|
-
baseDx = stemDx * (1 - stemTaper),
|
|
38089
|
-
coords;
|
|
38090
|
-
|
|
38091
|
-
if (!stemCurve || Math.abs(stemCurve) > 90) {
|
|
38092
|
-
coords = calcStraightArrowCoords(size.stemLen, size.headLen, stemDx, headDx, baseDx);
|
|
38093
|
-
} else {
|
|
38094
|
-
if (direction > 0) stemCurve = -stemCurve;
|
|
38095
|
-
coords = getCurvedArrowCoords(size.stemLen, size.headLen, stemCurve, stemDx, headDx, baseDx);
|
|
38096
|
-
}
|
|
38097
|
-
|
|
38098
|
-
rotateCoords(coords, direction);
|
|
38099
|
-
if (d.flipped) {
|
|
38100
|
-
flipY(coords);
|
|
38101
|
-
}
|
|
38102
|
-
return [coords];
|
|
38103
|
-
}
|
|
38104
|
-
|
|
38105
38310
|
function calcStraightArrowCoords(stemLen, headLen, stemDx, headDx, baseDx) {
|
|
38106
38311
|
return [[baseDx, 0], [stemDx, stemLen], [headDx, stemLen], [0, stemLen + headLen],
|
|
38107
38312
|
[-headDx, stemLen], [-stemDx, stemLen], [-baseDx, 0], [baseDx, 0]];
|
|
38108
38313
|
}
|
|
38109
38314
|
|
|
38110
38315
|
function calcArrowSize(d) {
|
|
38111
|
-
|
|
38316
|
+
// don't display arrows with negative length
|
|
38317
|
+
var totalLen = Math.max(d.radius || d.length || d.r || 0, 0),
|
|
38112
38318
|
scale = 1,
|
|
38113
38319
|
o = initArrowSize(d); // calc several parameters
|
|
38114
38320
|
|
|
@@ -38168,21 +38374,55 @@ ${svg}
|
|
|
38168
38374
|
return 1 / Math.tan(Math.PI * headAngle / 180 / 2) / 2;
|
|
38169
38375
|
}
|
|
38170
38376
|
|
|
38171
|
-
function
|
|
38377
|
+
function getFilledArrowCoords(d) {
|
|
38378
|
+
var direction = d.rotation || d.direction || 0,
|
|
38379
|
+
stemTaper = d['stem-taper'] || 0,
|
|
38380
|
+
curvature = d['stem-curve'] || 0,
|
|
38381
|
+
size = calcArrowSize(d);
|
|
38382
|
+
if (!size) return null;
|
|
38383
|
+
var stemLen = size.stemLen,
|
|
38384
|
+
headLen = size.headLen,
|
|
38385
|
+
headDx = size.headWidth / 2,
|
|
38386
|
+
stemDx = size.stemWidth / 2,
|
|
38387
|
+
baseDx = stemDx * (1 - stemTaper),
|
|
38388
|
+
head, stem, coords, dx, dy;
|
|
38389
|
+
|
|
38390
|
+
if (curvature) {
|
|
38391
|
+
if (direction > 0) curvature = -curvature;
|
|
38392
|
+
var theta = Math.abs(curvature) / 180 * Math.PI;
|
|
38393
|
+
var sign = curvature > 0 ? 1 : -1;
|
|
38394
|
+
var ax = baseDx * Math.cos(theta); // rotate arrow base
|
|
38395
|
+
var ay = baseDx * Math.sin(theta) * -sign;
|
|
38396
|
+
dx = stemLen * Math.sin(theta / 2) * sign;
|
|
38397
|
+
dy = stemLen * Math.cos(theta / 2);
|
|
38398
|
+
var leftStem = getCurvedStemCoords(-ax, -ay, -stemDx + dx, dy, theta);
|
|
38399
|
+
var rightStem = getCurvedStemCoords(ax, ay, stemDx + dx, dy, theta);
|
|
38400
|
+
stem = leftStem.concat(rightStem.reverse());
|
|
38401
|
+
|
|
38402
|
+
} else {
|
|
38403
|
+
dx = 0;
|
|
38404
|
+
dy = stemLen;
|
|
38405
|
+
stem = [[-baseDx, 0], [baseDx, 0], [baseDx, 0]];
|
|
38406
|
+
}
|
|
38407
|
+
|
|
38172
38408
|
// coordinates go counter clockwise, starting from the leftmost head coordinate
|
|
38173
|
-
|
|
38174
|
-
|
|
38175
|
-
|
|
38176
|
-
|
|
38177
|
-
|
|
38178
|
-
|
|
38179
|
-
|
|
38180
|
-
|
|
38181
|
-
|
|
38182
|
-
|
|
38183
|
-
|
|
38184
|
-
|
|
38185
|
-
|
|
38409
|
+
head = [[stemDx + dx, dy], [headDx + dx, dy],
|
|
38410
|
+
[dx, headLen + dy], [-headDx + dx, dy], [-stemDx + dx, dy]];
|
|
38411
|
+
|
|
38412
|
+
coords = stem.concat(head);
|
|
38413
|
+
if (d.anchor == 'end') {
|
|
38414
|
+
scaleAndShiftCoords(coords, 1, [-dx, -dy - headLen]);
|
|
38415
|
+
} else if (d.anchor == 'middle') {
|
|
38416
|
+
// shift midpoint away from the head a bit for a more balanced placement
|
|
38417
|
+
// scaleAndShiftCoords(coords, 1, [-dx/2, (-dy - headLen)/2]);
|
|
38418
|
+
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - headLen * 0.25]);
|
|
38419
|
+
}
|
|
38420
|
+
|
|
38421
|
+
rotateCoords(coords, direction);
|
|
38422
|
+
if (d.flipped) {
|
|
38423
|
+
flipY(coords);
|
|
38424
|
+
}
|
|
38425
|
+
return [coords];
|
|
38186
38426
|
}
|
|
38187
38427
|
|
|
38188
38428
|
// ax, ay: point on the base
|
|
@@ -38219,43 +38459,31 @@ ${svg}
|
|
|
38219
38459
|
return coords;
|
|
38220
38460
|
}
|
|
38221
38461
|
|
|
38222
|
-
// sides: e.g. 5-pointed star has 10 sides
|
|
38223
|
-
// radius: distance from center to point
|
|
38224
|
-
//
|
|
38225
38462
|
function getPolygonCoords(d) {
|
|
38226
|
-
var radius = d.radius || d.length || d.r
|
|
38463
|
+
var radius = d.radius || d.length || d.r,
|
|
38464
|
+
sides = +d.sides || getSidesByType(d.type),
|
|
38465
|
+
rotated = sides % 2 == 1,
|
|
38466
|
+
coords = [],
|
|
38467
|
+
angle, b;
|
|
38468
|
+
|
|
38227
38469
|
if (radius > 0 === false) return null;
|
|
38228
|
-
|
|
38229
|
-
var sides = +d.sides || getDefaultSides(type);
|
|
38230
|
-
var isStar = type == 'star';
|
|
38231
|
-
if (isStar && (sides < 6 || sides % 2 !== 0)) {
|
|
38232
|
-
stop(`Invalid number of sides for a star (${sides})`);
|
|
38233
|
-
} else if (sides >= 3 === false) {
|
|
38470
|
+
if (sides >= 3 === false) {
|
|
38234
38471
|
stop(`Invalid number of sides (${sides})`);
|
|
38235
38472
|
}
|
|
38236
|
-
var coords = [],
|
|
38237
|
-
angle = 360 / sides,
|
|
38238
|
-
b = isStar ? 1 : 0.5,
|
|
38239
|
-
theta, even, len;
|
|
38240
38473
|
if (d.orientation == 'b' || d.flipped || d.rotated) {
|
|
38241
|
-
|
|
38474
|
+
rotated = !rotated;
|
|
38242
38475
|
}
|
|
38476
|
+
b = rotated ? 0 : 0.5;
|
|
38243
38477
|
for (var i=0; i<sides; i++) {
|
|
38244
|
-
|
|
38245
|
-
|
|
38246
|
-
if (isStar && even) {
|
|
38247
|
-
len *= (d.star_ratio || 0.5);
|
|
38248
|
-
}
|
|
38249
|
-
theta = (i + b) * angle % 360;
|
|
38250
|
-
coords.push(getPlanarSegmentEndpoint(0, 0, theta, len));
|
|
38478
|
+
angle = (i + b) / sides * 360;
|
|
38479
|
+
coords.push(getPlanarSegmentEndpoint(0, 0, angle, radius));
|
|
38251
38480
|
}
|
|
38252
38481
|
coords.push(coords[0].concat());
|
|
38253
38482
|
return [coords];
|
|
38254
38483
|
}
|
|
38255
38484
|
|
|
38256
|
-
function
|
|
38485
|
+
function getSidesByType(type) {
|
|
38257
38486
|
return {
|
|
38258
|
-
star: 10,
|
|
38259
38487
|
circle: 72,
|
|
38260
38488
|
triangle: 3,
|
|
38261
38489
|
square: 4,
|
|
@@ -38268,6 +38496,52 @@ ${svg}
|
|
|
38268
38496
|
}[type] || 4;
|
|
38269
38497
|
}
|
|
38270
38498
|
|
|
38499
|
+
function getStarCoords(d) {
|
|
38500
|
+
var radius = d.radius || d.length || d.r,
|
|
38501
|
+
points = d.points || d.sides && d.sides / 2 || 5,
|
|
38502
|
+
sides = points * 2,
|
|
38503
|
+
minorRadius = getMinorRadius(points) * radius,
|
|
38504
|
+
b = d.orientation == 'b' || d.flipped || d.rotated ? 0 : 1,
|
|
38505
|
+
coords = [],
|
|
38506
|
+
angle, len;
|
|
38507
|
+
|
|
38508
|
+
if (radius > 0 === false) return null;
|
|
38509
|
+
if (points < 5) {
|
|
38510
|
+
stop(`Invalid number of points for a star (${points})`);
|
|
38511
|
+
}
|
|
38512
|
+
for (var i=0; i<sides; i++) {
|
|
38513
|
+
len = i % 2 == 0 ? minorRadius : radius;
|
|
38514
|
+
angle = (i + b) / sides * 360;
|
|
38515
|
+
coords.push(getPlanarSegmentEndpoint(0, 0, angle, len));
|
|
38516
|
+
}
|
|
38517
|
+
coords.push(coords[0].concat());
|
|
38518
|
+
return [coords];
|
|
38519
|
+
}
|
|
38520
|
+
|
|
38521
|
+
function getMinorRadius(points) {
|
|
38522
|
+
var innerAngle = 360 / points;
|
|
38523
|
+
var pointAngle = getDefaultPointAngle(points);
|
|
38524
|
+
var thetaA = Math.PI / 180 * innerAngle / 2;
|
|
38525
|
+
var thetaB = Math.PI / 180 * pointAngle / 2;
|
|
38526
|
+
var a = Math.tan(thetaB) / (Math.tan(thetaB) + Math.tan(thetaA));
|
|
38527
|
+
var c = a / Math.cos(thetaA);
|
|
38528
|
+
return c;
|
|
38529
|
+
}
|
|
38530
|
+
|
|
38531
|
+
function getDefaultPointAngle(points) {
|
|
38532
|
+
var minSkip = 1;
|
|
38533
|
+
var maxSkip = Math.ceil(points / 2) - 2;
|
|
38534
|
+
var skip = Math.floor((maxSkip + minSkip) / 2);
|
|
38535
|
+
return getPointAngle(points, skip);
|
|
38536
|
+
}
|
|
38537
|
+
|
|
38538
|
+
// skip: number of adjacent points to skip when drawing a segment
|
|
38539
|
+
function getPointAngle(points, skip) {
|
|
38540
|
+
var unitAngle = 360 / points;
|
|
38541
|
+
var centerAngle = unitAngle * (skip + 1);
|
|
38542
|
+
return 180 - centerAngle;
|
|
38543
|
+
}
|
|
38544
|
+
|
|
38271
38545
|
// Returns GeoJSON MultiPolygon coords
|
|
38272
38546
|
function getRingCoords(d) {
|
|
38273
38547
|
var radii = parseRings(d.radii || '2');
|
|
@@ -38322,6 +38596,8 @@ ${svg}
|
|
|
38322
38596
|
} else if (d.type == 'ring') {
|
|
38323
38597
|
coords = getRingCoords(d);
|
|
38324
38598
|
geojsonType = 'MultiPolygon';
|
|
38599
|
+
} else if (d.type == 'star') {
|
|
38600
|
+
coords = getStarCoords(d);
|
|
38325
38601
|
} else {
|
|
38326
38602
|
coords = getPolygonCoords(d);
|
|
38327
38603
|
}
|
|
@@ -38816,8 +39092,13 @@ ${svg}
|
|
|
38816
39092
|
targets,
|
|
38817
39093
|
targetDataset,
|
|
38818
39094
|
targetLayers,
|
|
39095
|
+
target,
|
|
38819
39096
|
arcs;
|
|
38820
39097
|
|
|
39098
|
+
if (skipCommand(name)) {
|
|
39099
|
+
return done(null);
|
|
39100
|
+
}
|
|
39101
|
+
|
|
38821
39102
|
try { // catch errors from synchronous functions
|
|
38822
39103
|
|
|
38823
39104
|
T$1.start();
|
|
@@ -38984,6 +39265,14 @@ ${svg}
|
|
|
38984
39265
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
38985
39266
|
}
|
|
38986
39267
|
|
|
39268
|
+
} else if (name == 'if' || name == 'elif') {
|
|
39269
|
+
// target = findSingleTargetLayer(opts.layer, targets[0], catalog);
|
|
39270
|
+
// cmd[name](target.layer, target.dataset, opts);
|
|
39271
|
+
cmd[name](catalog, opts);
|
|
39272
|
+
|
|
39273
|
+
} else if (name == 'else' || name == 'endif') {
|
|
39274
|
+
cmd[name]();
|
|
39275
|
+
|
|
38987
39276
|
} else if (name == 'ignore') {
|
|
38988
39277
|
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
38989
39278
|
|
|
@@ -39216,6 +39505,7 @@ ${svg}
|
|
|
39216
39505
|
});
|
|
39217
39506
|
}
|
|
39218
39507
|
|
|
39508
|
+
|
|
39219
39509
|
// Apply a command to an array of target layers
|
|
39220
39510
|
function applyCommandToEachLayer(func, targetLayers) {
|
|
39221
39511
|
var args = utils.toArray(arguments).slice(2);
|
|
@@ -39474,6 +39764,8 @@ ${svg}
|
|
|
39474
39764
|
}
|
|
39475
39765
|
|
|
39476
39766
|
function runParsedCommands2(commands, catalog, cb) {
|
|
39767
|
+
// resetting closes any unterminated -if blocks from a previous command sequence
|
|
39768
|
+
resetControlFlow();
|
|
39477
39769
|
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
39478
39770
|
|
|
39479
39771
|
function nextCommand(catalog, cmd, next) {
|