mapshaper 0.5.86 → 0.5.91
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 +347 -87
- package/package.json +1 -1
- package/www/mapshaper-gui.js +568 -2300
- package/www/mapshaper.js +347 -87
- 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 -1291
package/bin/mapshaper-gui
CHANGED
|
@@ -9,6 +9,7 @@ var defaultPort = 5555,
|
|
|
9
9
|
.option('-s, --direct-save', 'save files outside the browser\'s download folder')
|
|
10
10
|
.option('-f, --force-save', 'allow overwriting input files with output files')
|
|
11
11
|
.option('-a, --display-all', 'turn on visibility of all layers')
|
|
12
|
+
.option('-n, --name <name(s)>', 'rename input layer or layers')
|
|
12
13
|
.option('-t, --target <name>', 'name of layer to select initially')
|
|
13
14
|
.helpOption('-h, --help', 'show this help message')
|
|
14
15
|
.version(require('../package.json').version)
|
|
@@ -29,7 +30,8 @@ var defaultPort = 5555,
|
|
|
29
30
|
validateFiles(dataFiles);
|
|
30
31
|
|
|
31
32
|
process.on('uncaughtException', function(err) {
|
|
32
|
-
|
|
33
|
+
// added 'code' for Node.js v16
|
|
34
|
+
if (err.errno === 'EADDRINUSE' || err.code === 'EADDRINUSE') {
|
|
33
35
|
// probe for an open port, unless user has specified a non-default port
|
|
34
36
|
if (port == defaultPort && probeCount < 10) {
|
|
35
37
|
probeCount++;
|
|
@@ -207,6 +209,7 @@ function getManifestJS(files, opts) {
|
|
|
207
209
|
if (opts.directSave) o.allow_saving = true;
|
|
208
210
|
if (opts.displayAll) o.display_all = true;
|
|
209
211
|
if (opts.quickView) o.quick_view = true;
|
|
212
|
+
if (opts.name) o.name = opts.name;
|
|
210
213
|
return "mapshaper.manifest = " + JSON.stringify(o) + ";\n";
|
|
211
214
|
}
|
|
212
215
|
|
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({
|
|
@@ -1240,7 +1240,8 @@
|
|
|
1240
1240
|
// print a message to stdout
|
|
1241
1241
|
function print() {
|
|
1242
1242
|
STDOUT = true; // tell logArgs() to print to stdout, not stderr
|
|
1243
|
-
message
|
|
1243
|
+
// calling message() adds the "[command name]" prefix
|
|
1244
|
+
_message(utils.toArray(arguments));
|
|
1244
1245
|
STDOUT = false;
|
|
1245
1246
|
}
|
|
1246
1247
|
|
|
@@ -4895,6 +4896,11 @@
|
|
|
4895
4896
|
};
|
|
4896
4897
|
}
|
|
4897
4898
|
|
|
4899
|
+
function MultiShapeIter(arcs) {
|
|
4900
|
+
var iter = new ShapeIter(arcs);
|
|
4901
|
+
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4898
4904
|
// Iterate along a path made up of one or more arcs.
|
|
4899
4905
|
//
|
|
4900
4906
|
function ShapeIter(arcs) {
|
|
@@ -4945,6 +4951,7 @@
|
|
|
4945
4951
|
PointIter: PointIter,
|
|
4946
4952
|
ArcIter: ArcIter,
|
|
4947
4953
|
FilteredArcIter: FilteredArcIter,
|
|
4954
|
+
MultiShapeIter: MultiShapeIter,
|
|
4948
4955
|
ShapeIter: ShapeIter
|
|
4949
4956
|
});
|
|
4950
4957
|
|
|
@@ -8222,10 +8229,21 @@
|
|
|
8222
8229
|
return +n.toPrecision(d);
|
|
8223
8230
|
}
|
|
8224
8231
|
|
|
8232
|
+
|
|
8225
8233
|
function roundToDigits(n, d) {
|
|
8226
8234
|
return +n.toFixed(d); // string conversion makes this slow
|
|
8227
8235
|
}
|
|
8228
8236
|
|
|
8237
|
+
// Used in mapshaper-expression-utils.js
|
|
8238
|
+
// TODO: choose between this and the above function
|
|
8239
|
+
function roundToDigits2(n, d) {
|
|
8240
|
+
var k = 1;
|
|
8241
|
+
if (!n && n !== 0) return n; // don't coerce null to 0
|
|
8242
|
+
d = d | 0;
|
|
8243
|
+
while (d-- > 0) k *= 10;
|
|
8244
|
+
return Math.round(n * k) / k;
|
|
8245
|
+
}
|
|
8246
|
+
|
|
8229
8247
|
function roundToTenths(n) {
|
|
8230
8248
|
return (Math.round(n * 10)) / 10;
|
|
8231
8249
|
}
|
|
@@ -8300,6 +8318,7 @@
|
|
|
8300
8318
|
__proto__: null,
|
|
8301
8319
|
roundToSignificantDigits: roundToSignificantDigits,
|
|
8302
8320
|
roundToDigits: roundToDigits,
|
|
8321
|
+
roundToDigits2: roundToDigits2,
|
|
8303
8322
|
roundToTenths: roundToTenths,
|
|
8304
8323
|
getRoundingFunction: getRoundingFunction,
|
|
8305
8324
|
getBoundsPrecisionForDisplay: getBoundsPrecisionForDisplay,
|
|
@@ -8938,15 +8957,15 @@
|
|
|
8938
8957
|
});
|
|
8939
8958
|
}
|
|
8940
8959
|
|
|
8941
|
-
function
|
|
8960
|
+
function cleanExpression(exp) {
|
|
8961
|
+
// workaround for problem in GNU Make v4: end-of-line backslashes inside
|
|
8962
|
+
// quoted strings are left in the string (other shell environments remove them)
|
|
8963
|
+
return exp.replace(/\\\n/g, ' ');
|
|
8964
|
+
}
|
|
8965
|
+
|
|
8966
|
+
function addFeatureExpressionUtils(env) {
|
|
8942
8967
|
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
|
-
},
|
|
8968
|
+
round: roundToDigits2,
|
|
8950
8969
|
int_median: interpolated_median,
|
|
8951
8970
|
sprintf: utils.format,
|
|
8952
8971
|
blend: blend
|
|
@@ -9325,6 +9344,47 @@
|
|
|
9325
9344
|
};
|
|
9326
9345
|
}
|
|
9327
9346
|
|
|
9347
|
+
// Returns an object representing a layer in a JS expression
|
|
9348
|
+
function getLayerProxy(lyr, arcs) {
|
|
9349
|
+
var obj = {};
|
|
9350
|
+
var records = lyr.data ? lyr.data.getRecords() : null;
|
|
9351
|
+
var getters = {
|
|
9352
|
+
name: lyr.name,
|
|
9353
|
+
data: records,
|
|
9354
|
+
type: lyr.geometry_type,
|
|
9355
|
+
size: getFeatureCount(lyr),
|
|
9356
|
+
empty: getFeatureCount(lyr) === 0
|
|
9357
|
+
};
|
|
9358
|
+
addGetters(obj, getters);
|
|
9359
|
+
addBBoxGetter(obj, lyr, arcs);
|
|
9360
|
+
obj.field_exists = function(name) {
|
|
9361
|
+
return lyr.data && lyr.data.fieldExists(name) ? true : false;
|
|
9362
|
+
};
|
|
9363
|
+
obj.field_type = function(name) {
|
|
9364
|
+
return lyr.data && getColumnType(name, lyr.data.getRecords()) || null;
|
|
9365
|
+
};
|
|
9366
|
+
obj.field_includes = function(name, val) {
|
|
9367
|
+
if (!lyr.data) return false;
|
|
9368
|
+
return lyr.data.getRecords().some(function(rec) {
|
|
9369
|
+
return rec && (rec[name] === val);
|
|
9370
|
+
});
|
|
9371
|
+
};
|
|
9372
|
+
return obj;
|
|
9373
|
+
}
|
|
9374
|
+
|
|
9375
|
+
function addLayerGetters(ctx, lyr, arcs) {
|
|
9376
|
+
var layerProxy;
|
|
9377
|
+
addGetters(ctx, {
|
|
9378
|
+
layer_name: lyr.name || '', // consider removing this
|
|
9379
|
+
layer: function() {
|
|
9380
|
+
// init on first access (to avoid overhead if not used)
|
|
9381
|
+
if (!layerProxy) layerProxy = getLayerProxy(lyr, arcs);
|
|
9382
|
+
return layerProxy;
|
|
9383
|
+
}
|
|
9384
|
+
});
|
|
9385
|
+
return ctx;
|
|
9386
|
+
}
|
|
9387
|
+
|
|
9328
9388
|
function addBBoxGetter(obj, lyr, arcs) {
|
|
9329
9389
|
var bbox;
|
|
9330
9390
|
addGetters(obj, {
|
|
@@ -9354,32 +9414,6 @@
|
|
|
9354
9414
|
return bbox;
|
|
9355
9415
|
}
|
|
9356
9416
|
|
|
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
9417
|
// Returns a function to return a feature proxy by id
|
|
9384
9418
|
// (the proxy appears as "this" or "$" in a feature expression)
|
|
9385
9419
|
function initFeatureProxy(lyr, arcs, optsArg) {
|
|
@@ -9576,11 +9610,6 @@
|
|
|
9576
9610
|
return compileFeatureExpression(exp, lyr, arcs, opts);
|
|
9577
9611
|
}
|
|
9578
9612
|
|
|
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
9613
|
|
|
9585
9614
|
function compileFeaturePairFilterExpression(exp, lyr, arcs) {
|
|
9586
9615
|
var func = compileFeaturePairExpression(exp, lyr, arcs);
|
|
@@ -9716,14 +9745,19 @@
|
|
|
9716
9745
|
|
|
9717
9746
|
function compileExpressionToFunction(exp, opts) {
|
|
9718
9747
|
// $$ added to avoid duplication with data field variables (an error condition)
|
|
9719
|
-
var functionBody
|
|
9720
|
-
|
|
9721
|
-
|
|
9748
|
+
var functionBody, func;
|
|
9749
|
+
if (opts.returns) {
|
|
9750
|
+
// functionBody = 'return ' + functionBody;
|
|
9751
|
+
functionBody = 'var $$retn = ' + exp + '; return $$retn;';
|
|
9752
|
+
} else {
|
|
9753
|
+
functionBody = exp;
|
|
9754
|
+
}
|
|
9755
|
+
functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
|
|
9722
9756
|
try {
|
|
9723
|
-
func = new Function(
|
|
9757
|
+
func = new Function('$$record,$$env', functionBody);
|
|
9724
9758
|
} catch(e) {
|
|
9725
9759
|
// if (opts.quiet) throw e;
|
|
9726
|
-
stop(e.name,
|
|
9760
|
+
stop(e.name, 'in expression [' + exp + ']');
|
|
9727
9761
|
}
|
|
9728
9762
|
return func;
|
|
9729
9763
|
}
|
|
@@ -9766,7 +9800,7 @@
|
|
|
9766
9800
|
var ctx = {};
|
|
9767
9801
|
var fields = lyr.data ? lyr.data.getFields() : [];
|
|
9768
9802
|
opts = opts || {};
|
|
9769
|
-
|
|
9803
|
+
addFeatureExpressionUtils(env); // mix in round(), sprintf(), etc.
|
|
9770
9804
|
if (fields.length > 0) {
|
|
9771
9805
|
// default to null values, so assignments to missing data properties
|
|
9772
9806
|
// are applied to the data record, not the global object
|
|
@@ -9821,7 +9855,6 @@
|
|
|
9821
9855
|
var Expressions = /*#__PURE__*/Object.freeze({
|
|
9822
9856
|
__proto__: null,
|
|
9823
9857
|
compileValueExpression: compileValueExpression,
|
|
9824
|
-
cleanExpression: cleanExpression,
|
|
9825
9858
|
compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
|
|
9826
9859
|
compileFeaturePairExpression: compileFeaturePairExpression,
|
|
9827
9860
|
compileFeatureExpression: compileFeatureExpression,
|
|
@@ -18564,6 +18597,13 @@ ${svg}
|
|
|
18564
18597
|
return this;
|
|
18565
18598
|
};
|
|
18566
18599
|
|
|
18600
|
+
this.options = function(o) {
|
|
18601
|
+
Object.keys(o).forEach(function(key) {
|
|
18602
|
+
this.option(key, o[key]);
|
|
18603
|
+
}, this);
|
|
18604
|
+
return this;
|
|
18605
|
+
};
|
|
18606
|
+
|
|
18567
18607
|
this.done = function() {
|
|
18568
18608
|
return _command;
|
|
18569
18609
|
};
|
|
@@ -19527,14 +19567,6 @@ ${svg}
|
|
|
19527
19567
|
.option('target', targetOpt)
|
|
19528
19568
|
.option('no-replace', noReplaceOpt);
|
|
19529
19569
|
|
|
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
19570
|
parser.command('include')
|
|
19539
19571
|
.describe('import JS data and functions for use in JS expressions')
|
|
19540
19572
|
.option('file', {
|
|
@@ -20093,33 +20125,22 @@ ${svg}
|
|
|
20093
20125
|
.option('target', targetOpt);
|
|
20094
20126
|
|
|
20095
20127
|
parser.command('symbols')
|
|
20096
|
-
|
|
20128
|
+
.describe('symbolize points as arrows, circles, stars, polygons, etc.')
|
|
20097
20129
|
.option('type', {
|
|
20098
|
-
describe: 'symbol type (e.g. star, polygon,
|
|
20130
|
+
describe: 'symbol type (e.g. arrow, circle, square, star, polygon, ring)'
|
|
20099
20131
|
})
|
|
20100
|
-
.option('
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
.option('pixel-scale', {
|
|
20105
|
-
describe: 'symbol scale in meters-per-pixel (see polygons option)',
|
|
20106
|
-
type: 'number',
|
|
20132
|
+
.option('stroke', {})
|
|
20133
|
+
.option('stroke-width', {})
|
|
20134
|
+
.option('fill', {
|
|
20135
|
+
describe: 'symbol fill color'
|
|
20107
20136
|
})
|
|
20108
20137
|
.option('polygons', {
|
|
20109
20138
|
describe: 'generate symbols as polygons instead of SVG objects',
|
|
20110
20139
|
type: 'flag'
|
|
20111
20140
|
})
|
|
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'
|
|
20141
|
+
.option('pixel-scale', {
|
|
20142
|
+
describe: 'set symbol scale in meters-per-pixel (for polygons option)',
|
|
20143
|
+
type: 'number',
|
|
20123
20144
|
})
|
|
20124
20145
|
// .option('flipped', {
|
|
20125
20146
|
// type: 'flag',
|
|
@@ -20127,11 +20148,23 @@ ${svg}
|
|
|
20127
20148
|
// })
|
|
20128
20149
|
.option('rotated', {
|
|
20129
20150
|
type: 'flag',
|
|
20130
|
-
describe: 'symbol is rotated to
|
|
20151
|
+
describe: 'symbol is rotated to an alternate orientation'
|
|
20131
20152
|
})
|
|
20132
20153
|
.option('rotation', {
|
|
20133
20154
|
describe: 'rotation of symbol in degrees'
|
|
20134
20155
|
})
|
|
20156
|
+
.option('scale', {
|
|
20157
|
+
describe: 'scale symbols by a multiplier',
|
|
20158
|
+
type: 'number'
|
|
20159
|
+
})
|
|
20160
|
+
.option('radius', {
|
|
20161
|
+
describe: 'distance from center to farthest point on the symbol',
|
|
20162
|
+
type: 'distance'
|
|
20163
|
+
})
|
|
20164
|
+
.option('sides', {
|
|
20165
|
+
describe: '(polygon) number of sides of a (regular) polygon symbol',
|
|
20166
|
+
type: 'number'
|
|
20167
|
+
})
|
|
20135
20168
|
.option('points', {
|
|
20136
20169
|
describe: '(star) number of points'
|
|
20137
20170
|
})
|
|
@@ -20149,7 +20182,7 @@ ${svg}
|
|
|
20149
20182
|
})
|
|
20150
20183
|
.option('direction', {
|
|
20151
20184
|
old_alias: 'arrow-direction',
|
|
20152
|
-
describe: '(arrow) angle off vertical (-90 = left-pointing)'
|
|
20185
|
+
describe: '(arrow) angle off of vertical (-90 = left-pointing)'
|
|
20153
20186
|
})
|
|
20154
20187
|
.option('head-angle', {
|
|
20155
20188
|
old_alias: 'arrow-head-angle',
|
|
@@ -20184,17 +20217,12 @@ ${svg}
|
|
|
20184
20217
|
})
|
|
20185
20218
|
.option('min-stem-ratio', {
|
|
20186
20219
|
old_alias: 'arrow-min-stem',
|
|
20187
|
-
describe: '(arrow)
|
|
20220
|
+
describe: '(arrow) minimum ratio of stem to total length',
|
|
20188
20221
|
type: 'number'
|
|
20189
20222
|
})
|
|
20190
20223
|
.option('anchor', {
|
|
20191
20224
|
describe: '(arrow) takes one of: start, middle, end (default is start)'
|
|
20192
20225
|
})
|
|
20193
|
-
.option('stroke', {})
|
|
20194
|
-
.option('stroke-width', {})
|
|
20195
|
-
.option('fill', {
|
|
20196
|
-
describe: 'symbol fill color'
|
|
20197
|
-
})
|
|
20198
20226
|
.option('effect', {})
|
|
20199
20227
|
// .option('where', whereOpt)
|
|
20200
20228
|
.option('name', nameOpt)
|
|
@@ -20497,6 +20525,49 @@ ${svg}
|
|
|
20497
20525
|
})
|
|
20498
20526
|
.option('target', targetOpt);
|
|
20499
20527
|
|
|
20528
|
+
parser.section('Control flow commands');
|
|
20529
|
+
|
|
20530
|
+
var ifOpts = {
|
|
20531
|
+
expression: {
|
|
20532
|
+
DEFAULT: true,
|
|
20533
|
+
describe: 'JS expression targeting a single layer'
|
|
20534
|
+
},
|
|
20535
|
+
empty: {
|
|
20536
|
+
describe: 'run if layer is empty',
|
|
20537
|
+
type: 'flag'
|
|
20538
|
+
},
|
|
20539
|
+
'not-empty': {
|
|
20540
|
+
describe: 'run if layer is not empty',
|
|
20541
|
+
type: 'flag'
|
|
20542
|
+
},
|
|
20543
|
+
layer: {
|
|
20544
|
+
describe: 'name or id of layer to test (default is current target)'
|
|
20545
|
+
},
|
|
20546
|
+
target: targetOpt
|
|
20547
|
+
};
|
|
20548
|
+
|
|
20549
|
+
parser.command('if')
|
|
20550
|
+
.describe('run the following commands if a condition is met')
|
|
20551
|
+
.options(ifOpts);
|
|
20552
|
+
|
|
20553
|
+
parser.command('elif')
|
|
20554
|
+
.describe('test an alternate condition; used after -if')
|
|
20555
|
+
.options(ifOpts);
|
|
20556
|
+
|
|
20557
|
+
parser.command('else')
|
|
20558
|
+
.describe('run commands if all preceding -if/-elif conditions are false');
|
|
20559
|
+
|
|
20560
|
+
parser.command('endif')
|
|
20561
|
+
.describe('mark the end of an -if sequence');
|
|
20562
|
+
|
|
20563
|
+
parser.command('ignore')
|
|
20564
|
+
// .describe('stop processing if a condition is met')
|
|
20565
|
+
.option('empty', {
|
|
20566
|
+
describe: 'ignore empty files',
|
|
20567
|
+
type: 'flag'
|
|
20568
|
+
})
|
|
20569
|
+
.option('target', targetOpt);
|
|
20570
|
+
|
|
20500
20571
|
parser.section('Informational commands');
|
|
20501
20572
|
|
|
20502
20573
|
parser.command('calc')
|
|
@@ -20540,6 +20611,10 @@ ${svg}
|
|
|
20540
20611
|
.option('target', targetOpt)
|
|
20541
20612
|
.validate(validateExpressionOpt);
|
|
20542
20613
|
|
|
20614
|
+
parser.command('print')
|
|
20615
|
+
.describe('print a message to stdout')
|
|
20616
|
+
.flag('multi_arg');
|
|
20617
|
+
|
|
20543
20618
|
parser.command('projections')
|
|
20544
20619
|
.describe('print list of supported projections');
|
|
20545
20620
|
|
|
@@ -34169,6 +34244,141 @@ ${svg}
|
|
|
34169
34244
|
};
|
|
34170
34245
|
}
|
|
34171
34246
|
|
|
34247
|
+
function resetControlFlow() {
|
|
34248
|
+
setStateVar('control', null);
|
|
34249
|
+
}
|
|
34250
|
+
|
|
34251
|
+
function inControlBlock() {
|
|
34252
|
+
var state = getState();
|
|
34253
|
+
return !!state.inControlBlock;
|
|
34254
|
+
}
|
|
34255
|
+
|
|
34256
|
+
function enterActiveBranch() {
|
|
34257
|
+
var state = getState();
|
|
34258
|
+
state.inControlBlock = true;
|
|
34259
|
+
state.active = true;
|
|
34260
|
+
state.complete = true;
|
|
34261
|
+
}
|
|
34262
|
+
|
|
34263
|
+
function enterInactiveBranch() {
|
|
34264
|
+
var state = getState();
|
|
34265
|
+
state.inControlBlock = true;
|
|
34266
|
+
state.active = false;
|
|
34267
|
+
}
|
|
34268
|
+
|
|
34269
|
+
function blockWasActive() {
|
|
34270
|
+
return !!getState().complete;
|
|
34271
|
+
}
|
|
34272
|
+
|
|
34273
|
+
function inActiveBranch() {
|
|
34274
|
+
return !!getState().active;
|
|
34275
|
+
}
|
|
34276
|
+
|
|
34277
|
+
function getState() {
|
|
34278
|
+
var o = getStateVar('control') || setStateVar('control', {}) || getStateVar('control');
|
|
34279
|
+
return o;
|
|
34280
|
+
}
|
|
34281
|
+
|
|
34282
|
+
function compileLayerExpression(expr, lyr, dataset, opts) {
|
|
34283
|
+
var proxy = getLayerProxy(lyr, dataset.arcs, opts);
|
|
34284
|
+
var exprOpts = Object.assign({returns: true}, opts);
|
|
34285
|
+
var func = compileExpressionToFunction(expr, exprOpts);
|
|
34286
|
+
var ctx = proxy;
|
|
34287
|
+
return function() {
|
|
34288
|
+
try {
|
|
34289
|
+
return func.call(proxy, {}, ctx);
|
|
34290
|
+
} catch(e) {
|
|
34291
|
+
// if (opts.quiet) throw e;
|
|
34292
|
+
stop(e.name, "in expression [" + expr + "]:", e.message);
|
|
34293
|
+
}
|
|
34294
|
+
};
|
|
34295
|
+
}
|
|
34296
|
+
|
|
34297
|
+
function skipCommand(cmdName) {
|
|
34298
|
+
// allow all control commands to run
|
|
34299
|
+
if (isControlFlowCommand(cmdName)) return false;
|
|
34300
|
+
return inControlBlock() && !inActiveBranch();
|
|
34301
|
+
}
|
|
34302
|
+
|
|
34303
|
+
cmd.if = function(catalog, opts) {
|
|
34304
|
+
if (inControlBlock()) {
|
|
34305
|
+
stop('Nested -if commands are not supported.');
|
|
34306
|
+
}
|
|
34307
|
+
evaluateIf(catalog, opts);
|
|
34308
|
+
};
|
|
34309
|
+
|
|
34310
|
+
cmd.elif = function(catalog, opts) {
|
|
34311
|
+
if (!inControlBlock()) {
|
|
34312
|
+
stop('-elif command must be preceded by an -if command.');
|
|
34313
|
+
}
|
|
34314
|
+
evaluateIf(catalog, opts);
|
|
34315
|
+
};
|
|
34316
|
+
|
|
34317
|
+
cmd.else = function() {
|
|
34318
|
+
if (!inControlBlock()) {
|
|
34319
|
+
stop('-else command must be preceded by an -if command.');
|
|
34320
|
+
}
|
|
34321
|
+
if (blockWasActive()) {
|
|
34322
|
+
enterInactiveBranch();
|
|
34323
|
+
} else {
|
|
34324
|
+
enterActiveBranch();
|
|
34325
|
+
}
|
|
34326
|
+
};
|
|
34327
|
+
|
|
34328
|
+
cmd.endif = function() {
|
|
34329
|
+
if (!inControlBlock()) {
|
|
34330
|
+
stop('-endif command must be preceded by an -if command.');
|
|
34331
|
+
}
|
|
34332
|
+
resetControlFlow();
|
|
34333
|
+
};
|
|
34334
|
+
|
|
34335
|
+
function isControlFlowCommand(cmd) {
|
|
34336
|
+
return ['if','elif','else','endif'].includes(cmd);
|
|
34337
|
+
}
|
|
34338
|
+
|
|
34339
|
+
function testLayer(catalog, opts) {
|
|
34340
|
+
var targ = getTargetLayer(catalog, opts);
|
|
34341
|
+
if (opts.expression) {
|
|
34342
|
+
return compileLayerExpression(opts.expression, targ.layer, targ.dataset, opts)();
|
|
34343
|
+
}
|
|
34344
|
+
if (opts.empty) {
|
|
34345
|
+
return layerIsEmpty(targ.layer);
|
|
34346
|
+
}
|
|
34347
|
+
if (opts.not_empty) {
|
|
34348
|
+
return !layerIsEmpty(targ.layer);
|
|
34349
|
+
}
|
|
34350
|
+
return true;
|
|
34351
|
+
}
|
|
34352
|
+
|
|
34353
|
+
function evaluateIf(catalog, opts) {
|
|
34354
|
+
if (!blockWasActive() && testLayer(catalog, opts)) {
|
|
34355
|
+
enterActiveBranch();
|
|
34356
|
+
} else {
|
|
34357
|
+
enterInactiveBranch();
|
|
34358
|
+
}
|
|
34359
|
+
}
|
|
34360
|
+
|
|
34361
|
+
// layerId: optional layer identifier
|
|
34362
|
+
//
|
|
34363
|
+
function getTargetLayer(catalog, opts) {
|
|
34364
|
+
var layerId = opts.layer || opts.target;
|
|
34365
|
+
var targets = catalog.findCommandTargets(layerId);
|
|
34366
|
+
if (targets.length === 0) {
|
|
34367
|
+
if (layerId) {
|
|
34368
|
+
stop('Layer not found:', layerId);
|
|
34369
|
+
} else {
|
|
34370
|
+
stop('Missing a target layer.');
|
|
34371
|
+
}
|
|
34372
|
+
}
|
|
34373
|
+
if (targets.length > 1 || targets[0].layers.length > 1) {
|
|
34374
|
+
stop('Command requires a single target layer.');
|
|
34375
|
+
}
|
|
34376
|
+
return {
|
|
34377
|
+
layer: targets[0].layers[0],
|
|
34378
|
+
dataset: targets[0].dataset
|
|
34379
|
+
};
|
|
34380
|
+
}
|
|
34381
|
+
|
|
34172
34382
|
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
34173
34383
|
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
34174
34384
|
interrupt('Layer is empty, stopping processing');
|
|
@@ -34715,6 +34925,28 @@ ${svg}
|
|
|
34715
34925
|
return findVertexIds(p2.x, p2.y, arcs);
|
|
34716
34926
|
}
|
|
34717
34927
|
|
|
34928
|
+
// Given a location @p (e.g. corresponding to the mouse pointer location),
|
|
34929
|
+
// find the midpoint of two vertices on @shp suitable for inserting a new vertex,
|
|
34930
|
+
// but only if:
|
|
34931
|
+
// 1. point @p is closer to the midpoint than either adjacent vertex
|
|
34932
|
+
// 2. the segment containing @p is longer than a minimum distance in pixels.
|
|
34933
|
+
//
|
|
34934
|
+
function findInsertionPoint(p, shp, arcs, pixelSize) {
|
|
34935
|
+
var p2 = findNearestVertex(p[0], p[1], shp, arcs);
|
|
34936
|
+
|
|
34937
|
+
}
|
|
34938
|
+
|
|
34939
|
+
function snapVerticesToPoint(ids, p, arcs, final) {
|
|
34940
|
+
ids.forEach(function(idx) {
|
|
34941
|
+
setVertexCoords(p[0], p[1], idx, arcs);
|
|
34942
|
+
});
|
|
34943
|
+
if (final) {
|
|
34944
|
+
// kludge to get dataset to recalculate internal bounding boxes
|
|
34945
|
+
arcs.transformPoints(function() {});
|
|
34946
|
+
}
|
|
34947
|
+
}
|
|
34948
|
+
|
|
34949
|
+
|
|
34718
34950
|
// p: point to snap
|
|
34719
34951
|
// ids: ids of nearby vertices, possibly including an arc endpoint
|
|
34720
34952
|
function snapPointToArcEndpoint(p, ids, arcs) {
|
|
@@ -34801,6 +35033,8 @@ ${svg}
|
|
|
34801
35033
|
var VertexUtils = /*#__PURE__*/Object.freeze({
|
|
34802
35034
|
__proto__: null,
|
|
34803
35035
|
findNearestVertices: findNearestVertices,
|
|
35036
|
+
findInsertionPoint: findInsertionPoint,
|
|
35037
|
+
snapVerticesToPoint: snapVerticesToPoint,
|
|
34804
35038
|
snapPointToArcEndpoint: snapPointToArcEndpoint,
|
|
34805
35039
|
findVertexIds: findVertexIds,
|
|
34806
35040
|
getVertexCoords: getVertexCoords,
|
|
@@ -36416,6 +36650,10 @@ ${svg}
|
|
|
36416
36650
|
};
|
|
36417
36651
|
}
|
|
36418
36652
|
|
|
36653
|
+
cmd.print = function(msgArg) {
|
|
36654
|
+
print(msgArg || '');
|
|
36655
|
+
};
|
|
36656
|
+
|
|
36419
36657
|
cmd.renameLayers = function(layers, names, catalog) {
|
|
36420
36658
|
if (names && names.join('').indexOf('=') > -1) {
|
|
36421
36659
|
renameByAssignment(names, catalog);
|
|
@@ -38088,7 +38326,8 @@ ${svg}
|
|
|
38088
38326
|
}
|
|
38089
38327
|
|
|
38090
38328
|
function calcArrowSize(d) {
|
|
38091
|
-
|
|
38329
|
+
// don't display arrows with negative length
|
|
38330
|
+
var totalLen = Math.max(d.radius || d.length || d.r || 0, 0),
|
|
38092
38331
|
scale = 1,
|
|
38093
38332
|
o = initArrowSize(d); // calc several parameters
|
|
38094
38333
|
|
|
@@ -38187,7 +38426,9 @@ ${svg}
|
|
|
38187
38426
|
if (d.anchor == 'end') {
|
|
38188
38427
|
scaleAndShiftCoords(coords, 1, [-dx, -dy - headLen]);
|
|
38189
38428
|
} else if (d.anchor == 'middle') {
|
|
38190
|
-
|
|
38429
|
+
// shift midpoint away from the head a bit for a more balanced placement
|
|
38430
|
+
// scaleAndShiftCoords(coords, 1, [-dx/2, (-dy - headLen)/2]);
|
|
38431
|
+
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - headLen * 0.25]);
|
|
38191
38432
|
}
|
|
38192
38433
|
|
|
38193
38434
|
rotateCoords(coords, direction);
|
|
@@ -38864,8 +39105,13 @@ ${svg}
|
|
|
38864
39105
|
targets,
|
|
38865
39106
|
targetDataset,
|
|
38866
39107
|
targetLayers,
|
|
39108
|
+
target,
|
|
38867
39109
|
arcs;
|
|
38868
39110
|
|
|
39111
|
+
if (skipCommand(name)) {
|
|
39112
|
+
return done(null);
|
|
39113
|
+
}
|
|
39114
|
+
|
|
38869
39115
|
try { // catch errors from synchronous functions
|
|
38870
39116
|
|
|
38871
39117
|
T$1.start();
|
|
@@ -38915,7 +39161,7 @@ ${svg}
|
|
|
38915
39161
|
}
|
|
38916
39162
|
if (!(name == 'graticule' || name == 'i' || name == 'help' ||
|
|
38917
39163
|
name == 'point-grid' || name == 'shape' || name == 'rectangle' ||
|
|
38918
|
-
name == 'include')) {
|
|
39164
|
+
name == 'include' || name == 'print')) {
|
|
38919
39165
|
throw new UserError("No data is available");
|
|
38920
39166
|
}
|
|
38921
39167
|
}
|
|
@@ -39032,6 +39278,14 @@ ${svg}
|
|
|
39032
39278
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
39033
39279
|
}
|
|
39034
39280
|
|
|
39281
|
+
} else if (name == 'if' || name == 'elif') {
|
|
39282
|
+
// target = findSingleTargetLayer(opts.layer, targets[0], catalog);
|
|
39283
|
+
// cmd[name](target.layer, target.dataset, opts);
|
|
39284
|
+
cmd[name](catalog, opts);
|
|
39285
|
+
|
|
39286
|
+
} else if (name == 'else' || name == 'endif') {
|
|
39287
|
+
cmd[name]();
|
|
39288
|
+
|
|
39035
39289
|
} else if (name == 'ignore') {
|
|
39036
39290
|
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
39037
39291
|
|
|
@@ -39092,6 +39346,9 @@ ${svg}
|
|
|
39092
39346
|
} else if (name == 'polygons') {
|
|
39093
39347
|
outputLayers = cmd.polygons(targetLayers, targetDataset, opts);
|
|
39094
39348
|
|
|
39349
|
+
} else if (name == 'print') {
|
|
39350
|
+
cmd.print(command._.join(' '));
|
|
39351
|
+
|
|
39095
39352
|
} else if (name == 'proj') {
|
|
39096
39353
|
initProjLibrary(opts, function() {
|
|
39097
39354
|
var err = null;
|
|
@@ -39264,6 +39521,7 @@ ${svg}
|
|
|
39264
39521
|
});
|
|
39265
39522
|
}
|
|
39266
39523
|
|
|
39524
|
+
|
|
39267
39525
|
// Apply a command to an array of target layers
|
|
39268
39526
|
function applyCommandToEachLayer(func, targetLayers) {
|
|
39269
39527
|
var args = utils.toArray(arguments).slice(2);
|
|
@@ -39522,6 +39780,8 @@ ${svg}
|
|
|
39522
39780
|
}
|
|
39523
39781
|
|
|
39524
39782
|
function runParsedCommands2(commands, catalog, cb) {
|
|
39783
|
+
// resetting closes any unterminated -if blocks from a previous command sequence
|
|
39784
|
+
resetControlFlow();
|
|
39525
39785
|
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
39526
39786
|
|
|
39527
39787
|
function nextCommand(catalog, cmd, next) {
|