mapshaper 0.5.85 → 0.5.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mapshaper-gui +4 -1
- package/mapshaper.js +385 -141
- package/package.json +1 -1
- package/www/mapshaper-gui.js +476 -376
- package/www/mapshaper.js +385 -141
- 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 -1288
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.88";
|
|
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,35 @@
|
|
|
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
|
+
size: getFeatureCount(lyr),
|
|
9355
|
+
empty: getFeatureCount(lyr) === 0
|
|
9356
|
+
};
|
|
9357
|
+
addGetters(obj, getters);
|
|
9358
|
+
addBBoxGetter(obj, lyr, arcs);
|
|
9359
|
+
return obj;
|
|
9360
|
+
}
|
|
9361
|
+
|
|
9362
|
+
function addLayerGetters(ctx, lyr, arcs) {
|
|
9363
|
+
var layerProxy;
|
|
9364
|
+
addGetters(ctx, {
|
|
9365
|
+
layer_name: lyr.name || '', // consider removing this
|
|
9366
|
+
layer: function() {
|
|
9367
|
+
// init on first access (to avoid overhead if not used)
|
|
9368
|
+
if (!layerProxy) layerProxy = getLayerProxy(lyr, arcs);
|
|
9369
|
+
return layerProxy;
|
|
9370
|
+
}
|
|
9371
|
+
});
|
|
9372
|
+
return ctx;
|
|
9373
|
+
}
|
|
9374
|
+
|
|
9328
9375
|
function addBBoxGetter(obj, lyr, arcs) {
|
|
9329
9376
|
var bbox;
|
|
9330
9377
|
addGetters(obj, {
|
|
@@ -9354,32 +9401,6 @@
|
|
|
9354
9401
|
return bbox;
|
|
9355
9402
|
}
|
|
9356
9403
|
|
|
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
9404
|
// Returns a function to return a feature proxy by id
|
|
9384
9405
|
// (the proxy appears as "this" or "$" in a feature expression)
|
|
9385
9406
|
function initFeatureProxy(lyr, arcs, optsArg) {
|
|
@@ -9576,11 +9597,6 @@
|
|
|
9576
9597
|
return compileFeatureExpression(exp, lyr, arcs, opts);
|
|
9577
9598
|
}
|
|
9578
9599
|
|
|
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
9600
|
|
|
9585
9601
|
function compileFeaturePairFilterExpression(exp, lyr, arcs) {
|
|
9586
9602
|
var func = compileFeaturePairExpression(exp, lyr, arcs);
|
|
@@ -9716,14 +9732,19 @@
|
|
|
9716
9732
|
|
|
9717
9733
|
function compileExpressionToFunction(exp, opts) {
|
|
9718
9734
|
// $$ added to avoid duplication with data field variables (an error condition)
|
|
9719
|
-
var functionBody
|
|
9720
|
-
|
|
9721
|
-
|
|
9735
|
+
var functionBody, func;
|
|
9736
|
+
if (opts.returns) {
|
|
9737
|
+
// functionBody = 'return ' + functionBody;
|
|
9738
|
+
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
9739
|
+
} else {
|
|
9740
|
+
functionBody = exp;
|
|
9741
|
+
}
|
|
9742
|
+
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
9722
9743
|
try {
|
|
9723
|
-
func = new Function(
|
|
9744
|
+
func = new Function('$$record,$$env', functionBody);
|
|
9724
9745
|
} catch(e) {
|
|
9725
9746
|
// if (opts.quiet) throw e;
|
|
9726
|
-
stop(e.name,
|
|
9747
|
+
stop(e.name, 'in expression [' + exp + ']');
|
|
9727
9748
|
}
|
|
9728
9749
|
return func;
|
|
9729
9750
|
}
|
|
@@ -9766,7 +9787,7 @@
|
|
|
9766
9787
|
var ctx = {};
|
|
9767
9788
|
var fields = lyr.data ? lyr.data.getFields() : [];
|
|
9768
9789
|
opts = opts || {};
|
|
9769
|
-
|
|
9790
|
+
addFeatureExpressionUtils(env); // mix in round(), sprintf(), etc.
|
|
9770
9791
|
if (fields.length > 0) {
|
|
9771
9792
|
// default to null values, so assignments to missing data properties
|
|
9772
9793
|
// are applied to the data record, not the global object
|
|
@@ -9821,7 +9842,6 @@
|
|
|
9821
9842
|
var Expressions = /*#__PURE__*/Object.freeze({
|
|
9822
9843
|
__proto__: null,
|
|
9823
9844
|
compileValueExpression: compileValueExpression,
|
|
9824
|
-
cleanExpression: cleanExpression,
|
|
9825
9845
|
compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
|
|
9826
9846
|
compileFeaturePairExpression: compileFeaturePairExpression,
|
|
9827
9847
|
compileFeatureExpression: compileFeatureExpression,
|
|
@@ -18564,6 +18584,13 @@ ${svg}
|
|
|
18564
18584
|
return this;
|
|
18565
18585
|
};
|
|
18566
18586
|
|
|
18587
|
+
this.options = function(o) {
|
|
18588
|
+
Object.keys(o).forEach(function(key) {
|
|
18589
|
+
this.option(key, o[key]);
|
|
18590
|
+
}, this);
|
|
18591
|
+
return this;
|
|
18592
|
+
};
|
|
18593
|
+
|
|
18567
18594
|
this.done = function() {
|
|
18568
18595
|
return _command;
|
|
18569
18596
|
};
|
|
@@ -19527,14 +19554,6 @@ ${svg}
|
|
|
19527
19554
|
.option('target', targetOpt)
|
|
19528
19555
|
.option('no-replace', noReplaceOpt);
|
|
19529
19556
|
|
|
19530
|
-
parser.command('ignore')
|
|
19531
|
-
// .describe('stop processing if a condition is met')
|
|
19532
|
-
.option('empty', {
|
|
19533
|
-
describe: 'ignore empty files',
|
|
19534
|
-
type: 'flag'
|
|
19535
|
-
})
|
|
19536
|
-
.option('target', targetOpt);
|
|
19537
|
-
|
|
19538
19557
|
parser.command('include')
|
|
19539
19558
|
.describe('import JS data and functions for use in JS expressions')
|
|
19540
19559
|
.option('file', {
|
|
@@ -20093,45 +20112,46 @@ ${svg}
|
|
|
20093
20112
|
.option('target', targetOpt);
|
|
20094
20113
|
|
|
20095
20114
|
parser.command('symbols')
|
|
20096
|
-
|
|
20115
|
+
.describe('symbolize points as arrows, circles, stars, polygons, etc.')
|
|
20097
20116
|
.option('type', {
|
|
20098
|
-
describe: 'symbol type (e.g. star, polygon,
|
|
20117
|
+
describe: 'symbol type (e.g. arrow, circle, square, star, polygon, ring)'
|
|
20099
20118
|
})
|
|
20100
|
-
.option('
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
.option('pixel-scale', {
|
|
20105
|
-
describe: 'symbol scale in meters-per-pixel (see polygons option)',
|
|
20106
|
-
type: 'number',
|
|
20119
|
+
.option('stroke', {})
|
|
20120
|
+
.option('stroke-width', {})
|
|
20121
|
+
.option('fill', {
|
|
20122
|
+
describe: 'symbol fill color'
|
|
20107
20123
|
})
|
|
20108
20124
|
.option('polygons', {
|
|
20109
20125
|
describe: 'generate symbols as polygons instead of SVG objects',
|
|
20110
20126
|
type: 'flag'
|
|
20111
20127
|
})
|
|
20112
|
-
.option('
|
|
20113
|
-
describe: '
|
|
20114
|
-
type: '
|
|
20115
|
-
})
|
|
20116
|
-
.option('sides', {
|
|
20117
|
-
describe: 'number of sides of a polygon symbol',
|
|
20118
|
-
type: 'number'
|
|
20119
|
-
})
|
|
20120
|
-
.option('orientation', {
|
|
20121
|
-
// TODO: removed (replaced by flipped and rotated)
|
|
20122
|
-
// describe: 'use orientation=b for a rotated or flipped orientation'
|
|
20123
|
-
})
|
|
20124
|
-
.option('flipped', {
|
|
20125
|
-
type: 'flag',
|
|
20126
|
-
describe: 'symbol is vertically flipped'
|
|
20128
|
+
.option('pixel-scale', {
|
|
20129
|
+
describe: 'set symbol scale in meters-per-pixel (for polygons option)',
|
|
20130
|
+
type: 'number',
|
|
20127
20131
|
})
|
|
20132
|
+
// .option('flipped', {
|
|
20133
|
+
// type: 'flag',
|
|
20134
|
+
// describe: 'symbol is vertically flipped'
|
|
20135
|
+
// })
|
|
20128
20136
|
.option('rotated', {
|
|
20129
20137
|
type: 'flag',
|
|
20130
|
-
describe: 'symbol is rotated to
|
|
20138
|
+
describe: 'symbol is rotated to an alternate orientation'
|
|
20131
20139
|
})
|
|
20132
20140
|
.option('rotation', {
|
|
20133
20141
|
describe: 'rotation of symbol in degrees'
|
|
20134
20142
|
})
|
|
20143
|
+
.option('scale', {
|
|
20144
|
+
describe: 'scale symbols by a multiplier',
|
|
20145
|
+
type: 'number'
|
|
20146
|
+
})
|
|
20147
|
+
.option('radius', {
|
|
20148
|
+
describe: 'distance from center to farthest point on the symbol',
|
|
20149
|
+
type: 'distance'
|
|
20150
|
+
})
|
|
20151
|
+
.option('sides', {
|
|
20152
|
+
describe: '(polygon) number of sides of a (regular) polygon symbol',
|
|
20153
|
+
type: 'number'
|
|
20154
|
+
})
|
|
20135
20155
|
.option('points', {
|
|
20136
20156
|
describe: '(star) number of points'
|
|
20137
20157
|
})
|
|
@@ -20149,7 +20169,7 @@ ${svg}
|
|
|
20149
20169
|
})
|
|
20150
20170
|
.option('direction', {
|
|
20151
20171
|
old_alias: 'arrow-direction',
|
|
20152
|
-
describe: '(arrow) angle off vertical (-90 = left-pointing)'
|
|
20172
|
+
describe: '(arrow) angle off of vertical (-90 = left-pointing)'
|
|
20153
20173
|
})
|
|
20154
20174
|
.option('head-angle', {
|
|
20155
20175
|
old_alias: 'arrow-head-angle',
|
|
@@ -20184,17 +20204,12 @@ ${svg}
|
|
|
20184
20204
|
})
|
|
20185
20205
|
.option('min-stem-ratio', {
|
|
20186
20206
|
old_alias: 'arrow-min-stem',
|
|
20187
|
-
describe: '(arrow)
|
|
20207
|
+
describe: '(arrow) minimum ratio of stem to total length',
|
|
20188
20208
|
type: 'number'
|
|
20189
20209
|
})
|
|
20190
20210
|
.option('anchor', {
|
|
20191
20211
|
describe: '(arrow) takes one of: start, middle, end (default is start)'
|
|
20192
20212
|
})
|
|
20193
|
-
.option('stroke', {})
|
|
20194
|
-
.option('stroke-width', {})
|
|
20195
|
-
.option('fill', {
|
|
20196
|
-
describe: 'symbol fill color'
|
|
20197
|
-
})
|
|
20198
20213
|
.option('effect', {})
|
|
20199
20214
|
// .option('where', whereOpt)
|
|
20200
20215
|
.option('name', nameOpt)
|
|
@@ -20497,6 +20512,49 @@ ${svg}
|
|
|
20497
20512
|
})
|
|
20498
20513
|
.option('target', targetOpt);
|
|
20499
20514
|
|
|
20515
|
+
parser.section('Control flow commands');
|
|
20516
|
+
|
|
20517
|
+
var ifOpts = {
|
|
20518
|
+
expression: {
|
|
20519
|
+
DEFAULT: true,
|
|
20520
|
+
describe: 'JS expression targeting a single layer'
|
|
20521
|
+
},
|
|
20522
|
+
empty: {
|
|
20523
|
+
describe: 'run if layer is empty',
|
|
20524
|
+
type: 'flag'
|
|
20525
|
+
},
|
|
20526
|
+
'not-empty': {
|
|
20527
|
+
describe: 'run if layer is not empty',
|
|
20528
|
+
type: 'flag'
|
|
20529
|
+
},
|
|
20530
|
+
layer: {
|
|
20531
|
+
describe: 'name or id of layer to test (default is current target)'
|
|
20532
|
+
},
|
|
20533
|
+
target: targetOpt
|
|
20534
|
+
};
|
|
20535
|
+
|
|
20536
|
+
parser.command('if')
|
|
20537
|
+
.describe('run the following commands if a condition is met')
|
|
20538
|
+
.options(ifOpts);
|
|
20539
|
+
|
|
20540
|
+
parser.command('elif')
|
|
20541
|
+
.describe('test an alternate condition; used after -if')
|
|
20542
|
+
.options(ifOpts);
|
|
20543
|
+
|
|
20544
|
+
parser.command('else')
|
|
20545
|
+
.describe('run commands if all preceding -if/-elif conditions are false');
|
|
20546
|
+
|
|
20547
|
+
parser.command('endif')
|
|
20548
|
+
.describe('mark the end of an -if sequence');
|
|
20549
|
+
|
|
20550
|
+
parser.command('ignore')
|
|
20551
|
+
// .describe('stop processing if a condition is met')
|
|
20552
|
+
.option('empty', {
|
|
20553
|
+
describe: 'ignore empty files',
|
|
20554
|
+
type: 'flag'
|
|
20555
|
+
})
|
|
20556
|
+
.option('target', targetOpt);
|
|
20557
|
+
|
|
20500
20558
|
parser.section('Informational commands');
|
|
20501
20559
|
|
|
20502
20560
|
parser.command('calc')
|
|
@@ -34169,6 +34227,141 @@ ${svg}
|
|
|
34169
34227
|
};
|
|
34170
34228
|
}
|
|
34171
34229
|
|
|
34230
|
+
function resetControlFlow() {
|
|
34231
|
+
setStateVar('control', null);
|
|
34232
|
+
}
|
|
34233
|
+
|
|
34234
|
+
function inControlBlock() {
|
|
34235
|
+
var state = getState();
|
|
34236
|
+
return !!state.inControlBlock;
|
|
34237
|
+
}
|
|
34238
|
+
|
|
34239
|
+
function enterActiveBranch() {
|
|
34240
|
+
var state = getState();
|
|
34241
|
+
state.inControlBlock = true;
|
|
34242
|
+
state.active = true;
|
|
34243
|
+
state.complete = true;
|
|
34244
|
+
}
|
|
34245
|
+
|
|
34246
|
+
function enterInactiveBranch() {
|
|
34247
|
+
var state = getState();
|
|
34248
|
+
state.inControlBlock = true;
|
|
34249
|
+
state.active = false;
|
|
34250
|
+
}
|
|
34251
|
+
|
|
34252
|
+
function blockWasActive() {
|
|
34253
|
+
return !!getState().complete;
|
|
34254
|
+
}
|
|
34255
|
+
|
|
34256
|
+
function inActiveBranch() {
|
|
34257
|
+
return !!getState().active;
|
|
34258
|
+
}
|
|
34259
|
+
|
|
34260
|
+
function getState() {
|
|
34261
|
+
var o = getStateVar('control') || setStateVar('control', {}) || getStateVar('control');
|
|
34262
|
+
return o;
|
|
34263
|
+
}
|
|
34264
|
+
|
|
34265
|
+
function compileLayerExpression(expr, lyr, dataset, opts) {
|
|
34266
|
+
var proxy = getLayerProxy(lyr, dataset.arcs, opts);
|
|
34267
|
+
var exprOpts = Object.assign({returns: true}, opts);
|
|
34268
|
+
var func = compileExpressionToFunction(expr, exprOpts);
|
|
34269
|
+
var ctx = proxy;
|
|
34270
|
+
return function() {
|
|
34271
|
+
try {
|
|
34272
|
+
return func.call(proxy, {}, ctx);
|
|
34273
|
+
} catch(e) {
|
|
34274
|
+
// if (opts.quiet) throw e;
|
|
34275
|
+
stop(e.name, "in expression [" + expr + "]:", e.message);
|
|
34276
|
+
}
|
|
34277
|
+
};
|
|
34278
|
+
}
|
|
34279
|
+
|
|
34280
|
+
function skipCommand(cmdName) {
|
|
34281
|
+
// allow all control commands to run
|
|
34282
|
+
if (isControlFlowCommand(cmdName)) return false;
|
|
34283
|
+
return inControlBlock() && !inActiveBranch();
|
|
34284
|
+
}
|
|
34285
|
+
|
|
34286
|
+
cmd.if = function(catalog, opts) {
|
|
34287
|
+
if (inControlBlock()) {
|
|
34288
|
+
stop('Nested -if commands are not supported.');
|
|
34289
|
+
}
|
|
34290
|
+
evaluateIf(catalog, opts);
|
|
34291
|
+
};
|
|
34292
|
+
|
|
34293
|
+
cmd.elif = function(catalog, opts) {
|
|
34294
|
+
if (!inControlBlock()) {
|
|
34295
|
+
stop('-elif command must be preceded by an -if command.');
|
|
34296
|
+
}
|
|
34297
|
+
evaluateIf(catalog, opts);
|
|
34298
|
+
};
|
|
34299
|
+
|
|
34300
|
+
cmd.else = function() {
|
|
34301
|
+
if (!inControlBlock()) {
|
|
34302
|
+
stop('-else command must be preceded by an -if command.');
|
|
34303
|
+
}
|
|
34304
|
+
if (blockWasActive()) {
|
|
34305
|
+
enterInactiveBranch();
|
|
34306
|
+
} else {
|
|
34307
|
+
enterActiveBranch();
|
|
34308
|
+
}
|
|
34309
|
+
};
|
|
34310
|
+
|
|
34311
|
+
cmd.endif = function() {
|
|
34312
|
+
if (!inControlBlock()) {
|
|
34313
|
+
stop('-endif command must be preceded by an -if command.');
|
|
34314
|
+
}
|
|
34315
|
+
resetControlFlow();
|
|
34316
|
+
};
|
|
34317
|
+
|
|
34318
|
+
function isControlFlowCommand(cmd) {
|
|
34319
|
+
return ['if','elif','else','endif'].includes(cmd);
|
|
34320
|
+
}
|
|
34321
|
+
|
|
34322
|
+
function testLayer(catalog, opts) {
|
|
34323
|
+
var targ = getTargetLayer(catalog, opts);
|
|
34324
|
+
if (opts.expression) {
|
|
34325
|
+
return compileLayerExpression(opts.expression, targ.layer, targ.dataset, opts)();
|
|
34326
|
+
}
|
|
34327
|
+
if (opts.empty) {
|
|
34328
|
+
return layerIsEmpty(targ.layer);
|
|
34329
|
+
}
|
|
34330
|
+
if (opts.not_empty) {
|
|
34331
|
+
return !layerIsEmpty(targ.layer);
|
|
34332
|
+
}
|
|
34333
|
+
return true;
|
|
34334
|
+
}
|
|
34335
|
+
|
|
34336
|
+
function evaluateIf(catalog, opts) {
|
|
34337
|
+
if (!blockWasActive() && testLayer(catalog, opts)) {
|
|
34338
|
+
enterActiveBranch();
|
|
34339
|
+
} else {
|
|
34340
|
+
enterInactiveBranch();
|
|
34341
|
+
}
|
|
34342
|
+
}
|
|
34343
|
+
|
|
34344
|
+
// layerId: optional layer identifier
|
|
34345
|
+
//
|
|
34346
|
+
function getTargetLayer(catalog, opts) {
|
|
34347
|
+
var layerId = opts.layer || opts.target;
|
|
34348
|
+
var targets = catalog.findCommandTargets(layerId);
|
|
34349
|
+
if (targets.length === 0) {
|
|
34350
|
+
if (layerId) {
|
|
34351
|
+
stop('Layer not found:', layerId);
|
|
34352
|
+
} else {
|
|
34353
|
+
stop('Missing a target layer.');
|
|
34354
|
+
}
|
|
34355
|
+
}
|
|
34356
|
+
if (targets.length > 1 || targets[0].layers.length > 1) {
|
|
34357
|
+
stop('Command requires a single target layer.');
|
|
34358
|
+
}
|
|
34359
|
+
return {
|
|
34360
|
+
layer: targets[0].layers[0],
|
|
34361
|
+
dataset: targets[0].dataset
|
|
34362
|
+
};
|
|
34363
|
+
}
|
|
34364
|
+
|
|
34172
34365
|
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
34173
34366
|
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
34174
34367
|
interrupt('Layer is empty, stopping processing');
|
|
@@ -34715,6 +34908,28 @@ ${svg}
|
|
|
34715
34908
|
return findVertexIds(p2.x, p2.y, arcs);
|
|
34716
34909
|
}
|
|
34717
34910
|
|
|
34911
|
+
// Given a location @p (e.g. corresponding to the mouse pointer location),
|
|
34912
|
+
// find the midpoint of two vertices on @shp suitable for inserting a new vertex,
|
|
34913
|
+
// but only if:
|
|
34914
|
+
// 1. point @p is closer to the midpoint than either adjacent vertex
|
|
34915
|
+
// 2. the segment containing @p is longer than a minimum distance in pixels.
|
|
34916
|
+
//
|
|
34917
|
+
function findInsertionPoint(p, shp, arcs, pixelSize) {
|
|
34918
|
+
var p2 = findNearestVertex(p[0], p[1], shp, arcs);
|
|
34919
|
+
|
|
34920
|
+
}
|
|
34921
|
+
|
|
34922
|
+
function snapVerticesToPoint(ids, p, arcs, final) {
|
|
34923
|
+
ids.forEach(function(idx) {
|
|
34924
|
+
setVertexCoords(p[0], p[1], idx, arcs);
|
|
34925
|
+
});
|
|
34926
|
+
if (final) {
|
|
34927
|
+
// kludge to get dataset to recalculate internal bounding boxes
|
|
34928
|
+
arcs.transformPoints(function() {});
|
|
34929
|
+
}
|
|
34930
|
+
}
|
|
34931
|
+
|
|
34932
|
+
|
|
34718
34933
|
// p: point to snap
|
|
34719
34934
|
// ids: ids of nearby vertices, possibly including an arc endpoint
|
|
34720
34935
|
function snapPointToArcEndpoint(p, ids, arcs) {
|
|
@@ -34801,6 +35016,8 @@ ${svg}
|
|
|
34801
35016
|
var VertexUtils = /*#__PURE__*/Object.freeze({
|
|
34802
35017
|
__proto__: null,
|
|
34803
35018
|
findNearestVertices: findNearestVertices,
|
|
35019
|
+
findInsertionPoint: findInsertionPoint,
|
|
35020
|
+
snapVerticesToPoint: snapVerticesToPoint,
|
|
34804
35021
|
snapPointToArcEndpoint: snapPointToArcEndpoint,
|
|
34805
35022
|
findVertexIds: findVertexIds,
|
|
34806
35023
|
getVertexCoords: getVertexCoords,
|
|
@@ -38088,7 +38305,8 @@ ${svg}
|
|
|
38088
38305
|
}
|
|
38089
38306
|
|
|
38090
38307
|
function calcArrowSize(d) {
|
|
38091
|
-
|
|
38308
|
+
// don't display arrows with negative length
|
|
38309
|
+
var totalLen = Math.max(d.radius || d.length || d.r || 0, 0),
|
|
38092
38310
|
scale = 1,
|
|
38093
38311
|
o = initArrowSize(d); // calc several parameters
|
|
38094
38312
|
|
|
@@ -38187,7 +38405,9 @@ ${svg}
|
|
|
38187
38405
|
if (d.anchor == 'end') {
|
|
38188
38406
|
scaleAndShiftCoords(coords, 1, [-dx, -dy - headLen]);
|
|
38189
38407
|
} else if (d.anchor == 'middle') {
|
|
38190
|
-
|
|
38408
|
+
// shift midpoint away from the head a bit for a more balanced placement
|
|
38409
|
+
// scaleAndShiftCoords(coords, 1, [-dx/2, (-dy - headLen)/2]);
|
|
38410
|
+
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - headLen * 0.25]);
|
|
38191
38411
|
}
|
|
38192
38412
|
|
|
38193
38413
|
rotateCoords(coords, direction);
|
|
@@ -38231,71 +38451,31 @@ ${svg}
|
|
|
38231
38451
|
return coords;
|
|
38232
38452
|
}
|
|
38233
38453
|
|
|
38234
|
-
function getMinorRadius(points) {
|
|
38235
|
-
var innerAngle = 360 / points;
|
|
38236
|
-
var pointAngle = getDefaultPointAngle(points);
|
|
38237
|
-
var thetaA = Math.PI / 180 * innerAngle / 2;
|
|
38238
|
-
var thetaB = Math.PI / 180 * pointAngle / 2;
|
|
38239
|
-
var a = Math.tan(thetaB) / (Math.tan(thetaB) + Math.tan(thetaA));
|
|
38240
|
-
var c = a / Math.cos(thetaA);
|
|
38241
|
-
return c;
|
|
38242
|
-
}
|
|
38243
|
-
|
|
38244
|
-
|
|
38245
|
-
function getPointAngle(points, skip) {
|
|
38246
|
-
var unitAngle = 360 / points;
|
|
38247
|
-
var centerAngle = unitAngle * (skip + 1);
|
|
38248
|
-
return 180 - centerAngle;
|
|
38249
|
-
}
|
|
38250
|
-
|
|
38251
|
-
function getDefaultPointAngle(points) {
|
|
38252
|
-
var minSkip = 1;
|
|
38253
|
-
var maxSkip = Math.ceil(points / 2) - 2;
|
|
38254
|
-
var skip = Math.floor((maxSkip + minSkip) / 2);
|
|
38255
|
-
return getPointAngle(points, skip);
|
|
38256
|
-
}
|
|
38257
|
-
|
|
38258
|
-
// sides: e.g. 5-pointed star has 10 sides
|
|
38259
|
-
// radius: distance from center to point
|
|
38260
|
-
//
|
|
38261
38454
|
function getPolygonCoords(d) {
|
|
38262
|
-
var radius = d.radius || d.length || d.r
|
|
38455
|
+
var radius = d.radius || d.length || d.r,
|
|
38456
|
+
sides = +d.sides || getSidesByType(d.type),
|
|
38457
|
+
rotated = sides % 2 == 1,
|
|
38458
|
+
coords = [],
|
|
38459
|
+
angle, b;
|
|
38460
|
+
|
|
38263
38461
|
if (radius > 0 === false) return null;
|
|
38264
|
-
|
|
38265
|
-
var sides = +d.sides || getDefaultSides(type);
|
|
38266
|
-
var isStar = type == 'star';
|
|
38267
|
-
if (isStar && d.points > 0) {
|
|
38268
|
-
sides = d.points * 2;
|
|
38269
|
-
}
|
|
38270
|
-
var starRatio = isStar ? d.star_ratio || getMinorRadius(sides / 2) : 0;
|
|
38271
|
-
if (isStar && (sides < 10 || sides % 2 !== 0)) {
|
|
38272
|
-
stop(`Invalid number of points for a star (${sides / 2})`);
|
|
38273
|
-
} else if (sides >= 3 === false) {
|
|
38462
|
+
if (sides >= 3 === false) {
|
|
38274
38463
|
stop(`Invalid number of sides (${sides})`);
|
|
38275
38464
|
}
|
|
38276
|
-
var coords = [],
|
|
38277
|
-
angle = 360 / sides,
|
|
38278
|
-
b = isStar ? 1 : 0.5,
|
|
38279
|
-
theta, even, len;
|
|
38280
38465
|
if (d.orientation == 'b' || d.flipped || d.rotated) {
|
|
38281
|
-
|
|
38466
|
+
rotated = !rotated;
|
|
38282
38467
|
}
|
|
38468
|
+
b = rotated ? 0 : 0.5;
|
|
38283
38469
|
for (var i=0; i<sides; i++) {
|
|
38284
|
-
|
|
38285
|
-
|
|
38286
|
-
if (isStar && even) {
|
|
38287
|
-
len *= starRatio;
|
|
38288
|
-
}
|
|
38289
|
-
theta = (i + b) * angle % 360;
|
|
38290
|
-
coords.push(getPlanarSegmentEndpoint(0, 0, theta, len));
|
|
38470
|
+
angle = (i + b) / sides * 360;
|
|
38471
|
+
coords.push(getPlanarSegmentEndpoint(0, 0, angle, radius));
|
|
38291
38472
|
}
|
|
38292
38473
|
coords.push(coords[0].concat());
|
|
38293
38474
|
return [coords];
|
|
38294
38475
|
}
|
|
38295
38476
|
|
|
38296
|
-
function
|
|
38477
|
+
function getSidesByType(type) {
|
|
38297
38478
|
return {
|
|
38298
|
-
star: 10,
|
|
38299
38479
|
circle: 72,
|
|
38300
38480
|
triangle: 3,
|
|
38301
38481
|
square: 4,
|
|
@@ -38308,6 +38488,52 @@ ${svg}
|
|
|
38308
38488
|
}[type] || 4;
|
|
38309
38489
|
}
|
|
38310
38490
|
|
|
38491
|
+
function getStarCoords(d) {
|
|
38492
|
+
var radius = d.radius || d.length || d.r,
|
|
38493
|
+
points = d.points || d.sides && d.sides / 2 || 5,
|
|
38494
|
+
sides = points * 2,
|
|
38495
|
+
minorRadius = getMinorRadius(points) * radius,
|
|
38496
|
+
b = d.orientation == 'b' || d.flipped || d.rotated ? 0 : 1,
|
|
38497
|
+
coords = [],
|
|
38498
|
+
angle, len;
|
|
38499
|
+
|
|
38500
|
+
if (radius > 0 === false) return null;
|
|
38501
|
+
if (points < 5) {
|
|
38502
|
+
stop(`Invalid number of points for a star (${points})`);
|
|
38503
|
+
}
|
|
38504
|
+
for (var i=0; i<sides; i++) {
|
|
38505
|
+
len = i % 2 == 0 ? minorRadius : radius;
|
|
38506
|
+
angle = (i + b) / sides * 360;
|
|
38507
|
+
coords.push(getPlanarSegmentEndpoint(0, 0, angle, len));
|
|
38508
|
+
}
|
|
38509
|
+
coords.push(coords[0].concat());
|
|
38510
|
+
return [coords];
|
|
38511
|
+
}
|
|
38512
|
+
|
|
38513
|
+
function getMinorRadius(points) {
|
|
38514
|
+
var innerAngle = 360 / points;
|
|
38515
|
+
var pointAngle = getDefaultPointAngle(points);
|
|
38516
|
+
var thetaA = Math.PI / 180 * innerAngle / 2;
|
|
38517
|
+
var thetaB = Math.PI / 180 * pointAngle / 2;
|
|
38518
|
+
var a = Math.tan(thetaB) / (Math.tan(thetaB) + Math.tan(thetaA));
|
|
38519
|
+
var c = a / Math.cos(thetaA);
|
|
38520
|
+
return c;
|
|
38521
|
+
}
|
|
38522
|
+
|
|
38523
|
+
function getDefaultPointAngle(points) {
|
|
38524
|
+
var minSkip = 1;
|
|
38525
|
+
var maxSkip = Math.ceil(points / 2) - 2;
|
|
38526
|
+
var skip = Math.floor((maxSkip + minSkip) / 2);
|
|
38527
|
+
return getPointAngle(points, skip);
|
|
38528
|
+
}
|
|
38529
|
+
|
|
38530
|
+
// skip: number of adjacent points to skip when drawing a segment
|
|
38531
|
+
function getPointAngle(points, skip) {
|
|
38532
|
+
var unitAngle = 360 / points;
|
|
38533
|
+
var centerAngle = unitAngle * (skip + 1);
|
|
38534
|
+
return 180 - centerAngle;
|
|
38535
|
+
}
|
|
38536
|
+
|
|
38311
38537
|
// Returns GeoJSON MultiPolygon coords
|
|
38312
38538
|
function getRingCoords(d) {
|
|
38313
38539
|
var radii = parseRings(d.radii || '2');
|
|
@@ -38362,6 +38588,8 @@ ${svg}
|
|
|
38362
38588
|
} else if (d.type == 'ring') {
|
|
38363
38589
|
coords = getRingCoords(d);
|
|
38364
38590
|
geojsonType = 'MultiPolygon';
|
|
38591
|
+
} else if (d.type == 'star') {
|
|
38592
|
+
coords = getStarCoords(d);
|
|
38365
38593
|
} else {
|
|
38366
38594
|
coords = getPolygonCoords(d);
|
|
38367
38595
|
}
|
|
@@ -38856,8 +39084,13 @@ ${svg}
|
|
|
38856
39084
|
targets,
|
|
38857
39085
|
targetDataset,
|
|
38858
39086
|
targetLayers,
|
|
39087
|
+
target,
|
|
38859
39088
|
arcs;
|
|
38860
39089
|
|
|
39090
|
+
if (skipCommand(name)) {
|
|
39091
|
+
return done(null);
|
|
39092
|
+
}
|
|
39093
|
+
|
|
38861
39094
|
try { // catch errors from synchronous functions
|
|
38862
39095
|
|
|
38863
39096
|
T$1.start();
|
|
@@ -39024,6 +39257,14 @@ ${svg}
|
|
|
39024
39257
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
39025
39258
|
}
|
|
39026
39259
|
|
|
39260
|
+
} else if (name == 'if' || name == 'elif') {
|
|
39261
|
+
// target = findSingleTargetLayer(opts.layer, targets[0], catalog);
|
|
39262
|
+
// cmd[name](target.layer, target.dataset, opts);
|
|
39263
|
+
cmd[name](catalog, opts);
|
|
39264
|
+
|
|
39265
|
+
} else if (name == 'else' || name == 'endif') {
|
|
39266
|
+
cmd[name]();
|
|
39267
|
+
|
|
39027
39268
|
} else if (name == 'ignore') {
|
|
39028
39269
|
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
39029
39270
|
|
|
@@ -39256,6 +39497,7 @@ ${svg}
|
|
|
39256
39497
|
});
|
|
39257
39498
|
}
|
|
39258
39499
|
|
|
39500
|
+
|
|
39259
39501
|
// Apply a command to an array of target layers
|
|
39260
39502
|
function applyCommandToEachLayer(func, targetLayers) {
|
|
39261
39503
|
var args = utils.toArray(arguments).slice(2);
|
|
@@ -39514,6 +39756,8 @@ ${svg}
|
|
|
39514
39756
|
}
|
|
39515
39757
|
|
|
39516
39758
|
function runParsedCommands2(commands, catalog, cb) {
|
|
39759
|
+
// resetting closes any unterminated -if blocks from a previous command sequence
|
|
39760
|
+
resetControlFlow();
|
|
39517
39761
|
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
39518
39762
|
|
|
39519
39763
|
function nextCommand(catalog, cmd, next) {
|