mapshaper 0.6.37 → 0.6.39
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 +185 -48
- package/package.json +1 -1
- package/www/mapshaper-gui.js +18 -41
- package/www/mapshaper.js +185 -48
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.39";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
get rtrim () { return rtrim; },
|
|
66
66
|
get addThousandsSep () { return addThousandsSep; },
|
|
67
67
|
get numToStr () { return numToStr; },
|
|
68
|
-
get formatNumber () { return formatNumber; },
|
|
68
|
+
get formatNumber () { return formatNumber$1; },
|
|
69
69
|
get formatIntlNumber () { return formatIntlNumber; },
|
|
70
70
|
get formatNumberForDisplay () { return formatNumberForDisplay; },
|
|
71
71
|
get shuffle () { return shuffle; },
|
|
@@ -649,12 +649,12 @@
|
|
|
649
649
|
return decimals >= 0 ? num.toFixed(decimals) : String(num);
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
-
function formatNumber(val) {
|
|
652
|
+
function formatNumber$1(val) {
|
|
653
653
|
return val + '';
|
|
654
654
|
}
|
|
655
655
|
|
|
656
656
|
function formatIntlNumber(val) {
|
|
657
|
-
var str = formatNumber(val);
|
|
657
|
+
var str = formatNumber$1(val);
|
|
658
658
|
return '"' + str.replace('.', ',') + '"'; // need to quote if comma-delimited
|
|
659
659
|
}
|
|
660
660
|
|
|
@@ -1247,7 +1247,8 @@
|
|
|
1247
1247
|
|
|
1248
1248
|
// Handle an error caused by invalid input or misuse of API
|
|
1249
1249
|
function stop() {
|
|
1250
|
-
_stop.apply(null, utils.toArray(arguments));
|
|
1250
|
+
// _stop.apply(null, utils.toArray(arguments));
|
|
1251
|
+
_stop.apply(null, messageArgs(arguments));
|
|
1251
1252
|
}
|
|
1252
1253
|
|
|
1253
1254
|
function interrupt() {
|
|
@@ -4670,12 +4671,11 @@
|
|
|
4670
4671
|
albersusa: AlbersUSA
|
|
4671
4672
|
};
|
|
4672
4673
|
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
if (!asyncLoader) return done();
|
|
4676
|
-
asyncLoader(opts, done);
|
|
4674
|
+
async function initProjLibrary(opts) {
|
|
4675
|
+
if (asyncLoader) await asyncLoader(opts);
|
|
4677
4676
|
}
|
|
4678
4677
|
|
|
4678
|
+
// used by web UI to support loading projection assets asyncronously
|
|
4679
4679
|
function setProjectionLoader(loader) {
|
|
4680
4680
|
asyncLoader = loader;
|
|
4681
4681
|
}
|
|
@@ -13115,6 +13115,105 @@
|
|
|
13115
13115
|
});
|
|
13116
13116
|
}
|
|
13117
13117
|
|
|
13118
|
+
// Parse a formatted value in DMS DM or D to a numeric value. Returns NaN if unparsable.
|
|
13119
|
+
// Delimiters: degrees: D|d|°; minutes: '; seconds: "
|
|
13120
|
+
function parseDMS(str, fmt) {
|
|
13121
|
+
var defaultRxp = /^(?<prefix>[nsew+-]?)(?<d>[0-9.]+)[d°]? ?(?<m>[0-9.]*)['′]? ?(?<s>[0-9.]*)["″]? ?(?<suffix>[nsew]?)$/i;
|
|
13122
|
+
var rxp = fmt ? getParseRxp(fmt) : defaultRxp;
|
|
13123
|
+
var match = rxp.exec(str.trim());
|
|
13124
|
+
var d = NaN;
|
|
13125
|
+
var deg, min, sec;
|
|
13126
|
+
if (match) {
|
|
13127
|
+
deg = match.groups.d || '0';
|
|
13128
|
+
min = match.groups.m || '0';
|
|
13129
|
+
sec = match.groups.s || '0';
|
|
13130
|
+
d = (+deg) + (+min) / 60 + (+sec) / 3600;
|
|
13131
|
+
if (/[sw-]/i.test(match.groups.prefix || '') || /[sw]/i.test(match.groups.suffix || '')) {
|
|
13132
|
+
d = -d;
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
return d;
|
|
13136
|
+
}
|
|
13137
|
+
|
|
13138
|
+
var cache$1 = {};
|
|
13139
|
+
|
|
13140
|
+
function getParseRxp(fmt) {
|
|
13141
|
+
if (fmt in cache$1) return cache$1[fmt];
|
|
13142
|
+
var rxp = fmt;
|
|
13143
|
+
rxp = rxp.replace('[-]', '(?<prefix>-)?'); // optional -
|
|
13144
|
+
rxp = rxp.replace(/\[[NSEW, +-]{2,}\]/, '(?<prefix>$&)');
|
|
13145
|
+
rxp = rxp.replace(/(MM?)(\.M+)?/, (m, g1, g2) => {
|
|
13146
|
+
var s = g1.length == 1 ? '[0-9]+' : '[0-9][0-9]';
|
|
13147
|
+
if (g2) s += `\\.[0-9]+`;
|
|
13148
|
+
return `(?<m>${s})`;
|
|
13149
|
+
});
|
|
13150
|
+
rxp = rxp.replace(/(SS?)(\.S+)?/, (m, g1, g2) => {
|
|
13151
|
+
var s = g1.length == 1 ? '[0-9]+' : '[0-9][0-9]';
|
|
13152
|
+
if (g2) s += `\\.[0-9]+`;
|
|
13153
|
+
return `(?<s>${s})`;
|
|
13154
|
+
});
|
|
13155
|
+
rxp = rxp.replace(/D+/, '(?<d>[0-9]+)');
|
|
13156
|
+
rxp = '^' + rxp + '$';
|
|
13157
|
+
try {
|
|
13158
|
+
// TODO: make sure all DMS codes have been matched
|
|
13159
|
+
cache$1[fmt] = new RegExp(rxp);
|
|
13160
|
+
} catch(e) {
|
|
13161
|
+
stop('Invalid DMS format string:', fmt);
|
|
13162
|
+
}
|
|
13163
|
+
return cache$1[fmt];
|
|
13164
|
+
}
|
|
13165
|
+
|
|
13166
|
+
function formatNumber(val, integers, decimals) {
|
|
13167
|
+
var str = val.toFixed(decimals);
|
|
13168
|
+
var parts = str.split('.');
|
|
13169
|
+
if (parts.length > 0) {
|
|
13170
|
+
parts[0] = parts[0].padStart(integers, '0');
|
|
13171
|
+
str = parts.join('.');
|
|
13172
|
+
}
|
|
13173
|
+
return str;
|
|
13174
|
+
}
|
|
13175
|
+
|
|
13176
|
+
function getDecimals(fmt) {
|
|
13177
|
+
var match = /S\.(S+)/.exec(fmt) || /M\.(M+)/.exec(fmt) || null;
|
|
13178
|
+
return match ? match[1].length : 0;
|
|
13179
|
+
}
|
|
13180
|
+
|
|
13181
|
+
// TODO: support DD.DDDDD
|
|
13182
|
+
function formatDMS(coord, fmt) {
|
|
13183
|
+
if (!fmt) fmt = '[-]D°M\'S.SSS';
|
|
13184
|
+
var str = fmt;
|
|
13185
|
+
var dstr, mstr, sstr;
|
|
13186
|
+
var match = /(D+)[^M]*(M+)[^S[\]]*(S+)?/.exec(fmt);
|
|
13187
|
+
if (!match) {
|
|
13188
|
+
stop('Invalid DMS format string:', fmt);
|
|
13189
|
+
}
|
|
13190
|
+
var gotSeconds = !!match[3];
|
|
13191
|
+
var decimals = getDecimals(fmt);
|
|
13192
|
+
var integers = gotSeconds ? match[3].length : match[2].length;
|
|
13193
|
+
var RES = Math.pow(10, decimals);
|
|
13194
|
+
var CONV = gotSeconds ? 3600 * RES : 60 * RES;
|
|
13195
|
+
var r = Math.floor(Math.abs(coord) * CONV + 0.5);
|
|
13196
|
+
var lastPart = formatNumber((r / RES) % 60, integers, decimals);
|
|
13197
|
+
if (gotSeconds) {
|
|
13198
|
+
r = Math.floor(r / (RES * 60));
|
|
13199
|
+
sstr = lastPart;
|
|
13200
|
+
mstr = String(r % 60).padStart(match[2].length, '0');
|
|
13201
|
+
} else {
|
|
13202
|
+
r = Math.floor(r / RES);
|
|
13203
|
+
mstr = lastPart;
|
|
13204
|
+
sstr = '';
|
|
13205
|
+
}
|
|
13206
|
+
dstr = String(Math.floor(r / 60)).padStart(match[1].length, '0');
|
|
13207
|
+
str = str.replace(/\[-\]/, s => coord < 0 ? '-' : '');
|
|
13208
|
+
str = str.replace(/\[[+-]+\]/, s => coord < 0 ? '-' : '+');
|
|
13209
|
+
str = str.replace(/\[[NS, ]+\]/, s => coord < 0 ? 'S' : 'N');
|
|
13210
|
+
str = str.replace(/\[[EW, ]+\]/, s => coord < 0 ? 'W' : 'E');
|
|
13211
|
+
str = str.replace(/D+/, dstr);
|
|
13212
|
+
str = str.replace(/M+(\.M+)?/, mstr);
|
|
13213
|
+
if (gotSeconds) str = str.replace(/S+(\.S+)?/, sstr);
|
|
13214
|
+
return str;
|
|
13215
|
+
}
|
|
13216
|
+
|
|
13118
13217
|
function cleanExpression(exp) {
|
|
13119
13218
|
// workaround for problem in GNU Make v4: end-of-line backslashes inside
|
|
13120
13219
|
// quoted strings are left in the string (other shell environments remove them)
|
|
@@ -13126,7 +13225,9 @@
|
|
|
13126
13225
|
round: roundToDigits2,
|
|
13127
13226
|
int_median: interpolated_median,
|
|
13128
13227
|
sprintf: utils.format,
|
|
13129
|
-
blend: blend
|
|
13228
|
+
blend: blend,
|
|
13229
|
+
format_dms: formatDMS,
|
|
13230
|
+
parse_dms: parseDMS
|
|
13130
13231
|
});
|
|
13131
13232
|
}
|
|
13132
13233
|
|
|
@@ -22791,7 +22892,6 @@ ${svg}
|
|
|
22791
22892
|
|
|
22792
22893
|
this.getHelpMessage = function(cmdName) {
|
|
22793
22894
|
var helpCommands, singleCommand, lines;
|
|
22794
|
-
|
|
22795
22895
|
if (cmdName) {
|
|
22796
22896
|
singleCommand = findCommandDefn(cmdName, getCommands());
|
|
22797
22897
|
if (!singleCommand) {
|
|
@@ -22910,10 +23010,6 @@ ${svg}
|
|
|
22910
23010
|
}
|
|
22911
23011
|
};
|
|
22912
23012
|
|
|
22913
|
-
this.printHelp = function(command) {
|
|
22914
|
-
print(this.getHelpMessage(command));
|
|
22915
|
-
};
|
|
22916
|
-
|
|
22917
23013
|
function getCommands() {
|
|
22918
23014
|
return _commands.map(function(cmd) {
|
|
22919
23015
|
return cmd.done();
|
|
@@ -23633,7 +23729,7 @@ ${svg}
|
|
|
23633
23729
|
type: 'flag'
|
|
23634
23730
|
})
|
|
23635
23731
|
.option('other', {
|
|
23636
|
-
describe: 'default color for categorical scheme (
|
|
23732
|
+
describe: 'default color for categorical scheme (default is nodata color)'
|
|
23637
23733
|
})
|
|
23638
23734
|
.option('nodata', {
|
|
23639
23735
|
describe: 'color to use for invalid or missing data (default is white)'
|
|
@@ -24561,7 +24657,7 @@ ${svg}
|
|
|
24561
24657
|
parser.command('symbols')
|
|
24562
24658
|
.describe('symbolize points as arrows, circles, stars, polygons, etc.')
|
|
24563
24659
|
.option('type', {
|
|
24564
|
-
describe: '
|
|
24660
|
+
describe: 'types: arrow, circle, square, star, polygon, ring'
|
|
24565
24661
|
})
|
|
24566
24662
|
.option('stroke', {})
|
|
24567
24663
|
.option('stroke-width', {})
|
|
@@ -24574,6 +24670,9 @@ ${svg}
|
|
|
24574
24670
|
.option('stroke-width', {
|
|
24575
24671
|
describe: 'symbol line width (linear symbols only)'
|
|
24576
24672
|
})
|
|
24673
|
+
.option('opacity', {
|
|
24674
|
+
describe: 'symbol opacity'
|
|
24675
|
+
})
|
|
24577
24676
|
.option('geographic', {
|
|
24578
24677
|
old_alias: 'polygons',
|
|
24579
24678
|
describe: 'make geographic shapes instead of SVG objects',
|
|
@@ -24674,7 +24773,6 @@ ${svg}
|
|
|
24674
24773
|
.option('no-replace', noReplaceOpt);
|
|
24675
24774
|
// .option('name', nameOpt);
|
|
24676
24775
|
|
|
24677
|
-
|
|
24678
24776
|
parser.command('target')
|
|
24679
24777
|
.describe('set active layer (or layers)')
|
|
24680
24778
|
.option('target', {
|
|
@@ -24684,6 +24782,14 @@ ${svg}
|
|
|
24684
24782
|
.option('type', {
|
|
24685
24783
|
describe: 'type of layer to target (polygon|polyline|point)'
|
|
24686
24784
|
})
|
|
24785
|
+
// .option('combine', {
|
|
24786
|
+
// type: 'flag',
|
|
24787
|
+
// describe: 'place all targeted layers in one dataset together with any associated layers'
|
|
24788
|
+
// })
|
|
24789
|
+
// .option('isolate', {
|
|
24790
|
+
// type: 'flag',
|
|
24791
|
+
// describe: 'place all targeted layers in one dataset exclusive of associated layers'
|
|
24792
|
+
// })
|
|
24687
24793
|
.option('name', {
|
|
24688
24794
|
describe: 'rename the target layer'
|
|
24689
24795
|
});
|
|
@@ -38516,6 +38622,11 @@ ${svg}
|
|
|
38516
38622
|
};
|
|
38517
38623
|
}
|
|
38518
38624
|
|
|
38625
|
+
cmd.printHelp = function(opts) {
|
|
38626
|
+
var str = getOptionParser().getHelpMessage(opts.command);
|
|
38627
|
+
print(str);
|
|
38628
|
+
};
|
|
38629
|
+
|
|
38519
38630
|
function resetControlFlow(job) {
|
|
38520
38631
|
job.control = null;
|
|
38521
38632
|
}
|
|
@@ -39155,25 +39266,6 @@ ${svg}
|
|
|
39155
39266
|
};
|
|
39156
39267
|
}
|
|
39157
39268
|
|
|
39158
|
-
// Parse a formatted value in DMS DM or D to a numeric value. Returns NaN if unparsable.
|
|
39159
|
-
// Delimiters: degrees: D|d|°; minutes: '; seconds: "
|
|
39160
|
-
function parseDMS(str) {
|
|
39161
|
-
var rxp = /^([nsew+-]?)([0-9.]+)[d°]? ?([0-9.]*)['′]? ?([0-9.]*)["″]? ?([nsew]?)$/i;
|
|
39162
|
-
var match = rxp.exec(str.trim());
|
|
39163
|
-
var d = NaN;
|
|
39164
|
-
var deg, min, sec;
|
|
39165
|
-
if (match) {
|
|
39166
|
-
deg = match[2] || '0';
|
|
39167
|
-
min = match[3] || '0';
|
|
39168
|
-
sec = match[4] || '0';
|
|
39169
|
-
d = (+deg) + (+min) / 60 + (+sec) / 3600;
|
|
39170
|
-
if (/[sw-]/i.test(match[1]) || /[sw]/i.test(match[5])) {
|
|
39171
|
-
d = -d;
|
|
39172
|
-
}
|
|
39173
|
-
}
|
|
39174
|
-
return d;
|
|
39175
|
-
}
|
|
39176
|
-
|
|
39177
39269
|
function findNearestVertices(p, shp, arcs) {
|
|
39178
39270
|
var p2 = findNearestVertex(p[0], p[1], shp, arcs);
|
|
39179
39271
|
return findVertexIds(p2.x, p2.y, arcs);
|
|
@@ -42281,6 +42373,18 @@ ${svg}
|
|
|
42281
42373
|
return d.stroke || d.fill || 'magenta';
|
|
42282
42374
|
}
|
|
42283
42375
|
|
|
42376
|
+
function applySymbolStyles(sym, d) {
|
|
42377
|
+
if (sym.type == 'polyline') {
|
|
42378
|
+
sym.stroke = getSymbolStrokeColor(d);
|
|
42379
|
+
} else {
|
|
42380
|
+
sym.fill = getSymbolFillColor(d);
|
|
42381
|
+
}
|
|
42382
|
+
if (d.opacity) {
|
|
42383
|
+
sym.opacity = d.opacity;
|
|
42384
|
+
}
|
|
42385
|
+
return sym;
|
|
42386
|
+
}
|
|
42387
|
+
|
|
42284
42388
|
function getSymbolRadius(d) {
|
|
42285
42389
|
if (d.radius === 0 || d.length === 0 || d.r === 0) return 0;
|
|
42286
42390
|
return d.radius || d.length || d.r || 5; // use a default value
|
|
@@ -42518,11 +42622,8 @@ ${svg}
|
|
|
42518
42622
|
var radius = getSymbolRadius(d);
|
|
42519
42623
|
// TODO: remove duplication with svg-symbols.js
|
|
42520
42624
|
if (+opts.scale) radius *= +opts.scale;
|
|
42521
|
-
|
|
42522
|
-
|
|
42523
|
-
fill: getSymbolFillColor(d),
|
|
42524
|
-
r: radius
|
|
42525
|
-
};
|
|
42625
|
+
var sym = { type: 'circle', r: radius };
|
|
42626
|
+
return applySymbolStyles(sym, d);
|
|
42526
42627
|
}
|
|
42527
42628
|
|
|
42528
42629
|
function getPolygonCoords(d) {
|
|
@@ -42614,11 +42715,13 @@ ${svg}
|
|
|
42614
42715
|
var radii = parseRings(d.radii || '2').map(function(r) { return r * scale; });
|
|
42615
42716
|
var solidCenter = utils.isOdd(radii.length);
|
|
42616
42717
|
var color = getSymbolFillColor(d);
|
|
42718
|
+
var opacity = opts.opacity || undefined;
|
|
42617
42719
|
var parts = [];
|
|
42618
42720
|
if (solidCenter) {
|
|
42619
42721
|
parts.push({
|
|
42620
42722
|
type: 'circle',
|
|
42621
42723
|
fill: color,
|
|
42724
|
+
opacity: opacity,
|
|
42622
42725
|
r: radii.shift()
|
|
42623
42726
|
});
|
|
42624
42727
|
}
|
|
@@ -42627,6 +42730,7 @@ ${svg}
|
|
|
42627
42730
|
type: 'circle',
|
|
42628
42731
|
fill: 'none', // TODO remove default black fill so this is not needed
|
|
42629
42732
|
stroke: color,
|
|
42733
|
+
opacity: opacity,
|
|
42630
42734
|
'stroke-width': roundToTenths(radii[i+1] - radii[i]),
|
|
42631
42735
|
r: roundToTenths(radii[i+1] * 0.5 + radii[i] * 0.5)
|
|
42632
42736
|
});
|
|
@@ -42674,19 +42778,18 @@ ${svg}
|
|
|
42674
42778
|
if (geojsonType == 'MultiPolygon' || geojsonType == 'Polygon') {
|
|
42675
42779
|
sym = {
|
|
42676
42780
|
type: 'polygon',
|
|
42677
|
-
fill: getSymbolFillColor(properties),
|
|
42678
42781
|
coordinates: geojsonType == 'Polygon' ? coords : flattenMultiPolygonCoords(coords)
|
|
42679
42782
|
};
|
|
42680
42783
|
} else if (geojsonType == 'LineString' || geojsonType == 'MultiLineString') {
|
|
42681
42784
|
sym = {
|
|
42682
42785
|
type: 'polyline',
|
|
42683
|
-
stroke: getSymbolStrokeColor(properties),
|
|
42684
42786
|
'stroke-width': properties['stroke-width'] || 2,
|
|
42685
42787
|
coordinates: geojsonType == 'LineString' ? [coords] : coords
|
|
42686
42788
|
};
|
|
42687
42789
|
} else {
|
|
42688
42790
|
error('Unsupported type:', geojsonType);
|
|
42689
42791
|
}
|
|
42792
|
+
applySymbolStyles(sym, properties);
|
|
42690
42793
|
roundCoordsForSVG(sym.coordinates);
|
|
42691
42794
|
return sym;
|
|
42692
42795
|
}
|
|
@@ -42746,6 +42849,7 @@ ${svg}
|
|
|
42746
42849
|
scaleAndShiftCoords(coords, metersPerPx, shp[0]);
|
|
42747
42850
|
if (d.fill) rec.fill = d.fill;
|
|
42748
42851
|
if (d.stroke) rec.stroke = d.stroke;
|
|
42852
|
+
if (d.opacity) rec.opacity = d.opacity;
|
|
42749
42853
|
return createGeometry(coords, geojsonType);
|
|
42750
42854
|
} else {
|
|
42751
42855
|
rec['svg-symbol'] = makePathSymbol(coords, d, geojsonType);
|
|
@@ -42811,9 +42915,41 @@ ${svg}
|
|
|
42811
42915
|
// TODO: improve this
|
|
42812
42916
|
targets[0].layers[0].name = opts.name;
|
|
42813
42917
|
}
|
|
42918
|
+
if (opts.combine) {
|
|
42919
|
+
targets = combineTargets(targets, catalog);
|
|
42920
|
+
} else if (opts.isolate) {
|
|
42921
|
+
targets = isolateTargets(targets, catalog);
|
|
42922
|
+
}
|
|
42814
42923
|
catalog.setDefaultTargets(targets);
|
|
42815
42924
|
};
|
|
42816
42925
|
|
|
42926
|
+
function combineTargets(targets, catalog) {
|
|
42927
|
+
var datasets = [];
|
|
42928
|
+
var layers = [];
|
|
42929
|
+
targets.forEach(function(o) {
|
|
42930
|
+
datasets.push(o.dataset);
|
|
42931
|
+
catalog.removeDataset(o.dataset);
|
|
42932
|
+
layers = layers.concat(o.layers);
|
|
42933
|
+
});
|
|
42934
|
+
var combined = mergeDatasets(datasets);
|
|
42935
|
+
catalog.addDataset(combined);
|
|
42936
|
+
return [{
|
|
42937
|
+
dataset: combined,
|
|
42938
|
+
layers: layers
|
|
42939
|
+
}];
|
|
42940
|
+
}
|
|
42941
|
+
|
|
42942
|
+
function isolateTargets(targets, catalog) {
|
|
42943
|
+
var datasets = [];
|
|
42944
|
+
targets.forEach(function(o) {
|
|
42945
|
+
datasets.push(o.dataset);
|
|
42946
|
+
o.layers.forEach(function(lyr) {
|
|
42947
|
+
catalog.removeLayer(lyr, o.dataset);
|
|
42948
|
+
|
|
42949
|
+
});
|
|
42950
|
+
});
|
|
42951
|
+
}
|
|
42952
|
+
|
|
42817
42953
|
cmd.union = function(targetLayers, targetDataset, opts) {
|
|
42818
42954
|
if (targetLayers.length < 2) {
|
|
42819
42955
|
stop('Command requires at least two target layers');
|
|
@@ -43198,7 +43334,7 @@ ${svg}
|
|
|
43198
43334
|
function commandAcceptsMultipleTargetDatasets(name) {
|
|
43199
43335
|
return name == 'rotate' || name == 'info' || name == 'proj' ||
|
|
43200
43336
|
name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
|
|
43201
|
-
name == 'else' || name == 'endif' || name == 'run';
|
|
43337
|
+
name == 'else' || name == 'endif' || name == 'run' || name == 'i';
|
|
43202
43338
|
}
|
|
43203
43339
|
|
|
43204
43340
|
function commandAcceptsEmptyTarget(name) {
|
|
@@ -43387,8 +43523,8 @@ ${svg}
|
|
|
43387
43523
|
job.catalog.addDataset(cmd.graticule(targetDataset, opts));
|
|
43388
43524
|
|
|
43389
43525
|
} else if (name == 'help') {
|
|
43390
|
-
// placing
|
|
43391
|
-
|
|
43526
|
+
// placing help command here to handle errors from invalid command names
|
|
43527
|
+
cmd.printHelp(command.options);
|
|
43392
43528
|
|
|
43393
43529
|
} else if (name == 'i') {
|
|
43394
43530
|
if (opts.replace) job.catalog = new Catalog(); // is this what we want?
|
|
@@ -43470,7 +43606,7 @@ ${svg}
|
|
|
43470
43606
|
cmd.print(command._.join(' '));
|
|
43471
43607
|
|
|
43472
43608
|
} else if (name == 'proj') {
|
|
43473
|
-
await
|
|
43609
|
+
await initProjLibrary(opts);
|
|
43474
43610
|
job.resumeCommand();
|
|
43475
43611
|
targets.forEach(function(targ) {
|
|
43476
43612
|
cmd.proj(targ.dataset, job.catalog, opts);
|
|
@@ -44305,6 +44441,7 @@ ${svg}
|
|
|
44305
44441
|
Heap,
|
|
44306
44442
|
NodeCollection,
|
|
44307
44443
|
parseDMS,
|
|
44444
|
+
formatDMS,
|
|
44308
44445
|
PathIndex,
|
|
44309
44446
|
PolygonIndex,
|
|
44310
44447
|
ShpReader,
|
package/package.json
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -2479,42 +2479,18 @@
|
|
|
2479
2479
|
});
|
|
2480
2480
|
}
|
|
2481
2481
|
|
|
2482
|
+
internal.setProjectionLoader(loadProjLibs);
|
|
2483
|
+
|
|
2482
2484
|
// load Proj.4 CRS definition files dynamically
|
|
2483
2485
|
//
|
|
2484
|
-
|
|
2486
|
+
async function loadProjLibs(opts) {
|
|
2485
2487
|
var mproj = require('mproj');
|
|
2486
2488
|
var libs = internal.findProjLibs([opts.init || '', opts.match || '', opts.crs || ''].join(' '));
|
|
2487
|
-
// skip loaded libs
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
function loadProjLibs(libs, done) {
|
|
2493
|
-
var mproj = require('mproj');
|
|
2494
|
-
var i = 0;
|
|
2495
|
-
next();
|
|
2496
|
-
|
|
2497
|
-
function next() {
|
|
2498
|
-
var libName = libs[i];
|
|
2499
|
-
var content, req;
|
|
2500
|
-
if (!libName) return done();
|
|
2501
|
-
req = new XMLHttpRequest();
|
|
2502
|
-
req.addEventListener('load', function(e) {
|
|
2503
|
-
if (req.status == 200) {
|
|
2504
|
-
content = req.response;
|
|
2505
|
-
}
|
|
2506
|
-
});
|
|
2507
|
-
req.addEventListener('loadend', function() {
|
|
2508
|
-
if (content) {
|
|
2509
|
-
mproj.internal.mproj_insert_libcache(libName, content);
|
|
2510
|
-
}
|
|
2511
|
-
// TODO: consider stopping with an error message if no content was loaded
|
|
2512
|
-
// (currently, a less specific error will occur when mapshaper tries to use the library)
|
|
2513
|
-
next();
|
|
2514
|
-
});
|
|
2515
|
-
req.open('GET', 'assets/' + libName);
|
|
2516
|
-
req.send();
|
|
2517
|
-
i++;
|
|
2489
|
+
libs = libs.filter(function(name) {return !mproj.internal.mproj_search_libcache(name);}); // skip loaded libs
|
|
2490
|
+
for (var libName of libs) {
|
|
2491
|
+
var content = await fetch('assets/' + libName).then(resp => resp.ok ? resp.text() : null);
|
|
2492
|
+
if (!content) stop$1(`Unable to load projection resource [${libName}]`);
|
|
2493
|
+
mproj.internal.mproj_insert_libcache(libName, content);
|
|
2518
2494
|
}
|
|
2519
2495
|
}
|
|
2520
2496
|
|
|
@@ -3371,7 +3347,10 @@
|
|
|
3371
3347
|
setDisplayProjection(gui, cmd);
|
|
3372
3348
|
} else {
|
|
3373
3349
|
line.hide(); // hide cursor while command is being run
|
|
3374
|
-
runMapshaperCommands(cmd, function(err) {
|
|
3350
|
+
runMapshaperCommands(cmd, function(err, flags) {
|
|
3351
|
+
if (flags) {
|
|
3352
|
+
gui.clearMode();
|
|
3353
|
+
}
|
|
3375
3354
|
if (err) {
|
|
3376
3355
|
onError(err);
|
|
3377
3356
|
}
|
|
@@ -3404,14 +3383,9 @@
|
|
|
3404
3383
|
}
|
|
3405
3384
|
}
|
|
3406
3385
|
if (flags) {
|
|
3407
|
-
// if the command may have changed data, and a tool with an edit mode is being used,
|
|
3408
|
-
// close the tool. (we may need a better way to allow the console and other tools
|
|
3409
|
-
// to be used at the same time).
|
|
3410
|
-
gui.clearMode();
|
|
3411
|
-
|
|
3412
3386
|
model.updated(flags); // info commands do not return flags
|
|
3413
3387
|
}
|
|
3414
|
-
done(err);
|
|
3388
|
+
done(err, flags);
|
|
3415
3389
|
});
|
|
3416
3390
|
}
|
|
3417
3391
|
|
|
@@ -5068,7 +5042,8 @@
|
|
|
5068
5042
|
|
|
5069
5043
|
// Handle an error caused by invalid input or misuse of API
|
|
5070
5044
|
function stop() {
|
|
5071
|
-
_stop.apply(null, utils.toArray(arguments));
|
|
5045
|
+
// _stop.apply(null, utils.toArray(arguments));
|
|
5046
|
+
_stop.apply(null, messageArgs(arguments));
|
|
5072
5047
|
}
|
|
5073
5048
|
|
|
5074
5049
|
function interrupt() {
|
|
@@ -7976,10 +7951,11 @@
|
|
|
7976
7951
|
hit.clearSelection();
|
|
7977
7952
|
});
|
|
7978
7953
|
|
|
7979
|
-
function runCommand(cmd) {
|
|
7954
|
+
function runCommand(cmd, turnOff) {
|
|
7980
7955
|
popup.hide();
|
|
7981
7956
|
if (gui.console) gui.console.runMapshaperCommands(cmd, function(err) {
|
|
7982
7957
|
reset();
|
|
7958
|
+
if (turnOff) gui.clearMode();
|
|
7983
7959
|
});
|
|
7984
7960
|
}
|
|
7985
7961
|
}
|
|
@@ -10311,6 +10287,7 @@
|
|
|
10311
10287
|
if (gui.console) {
|
|
10312
10288
|
gui.console.runMapshaperCommands(cmd, function(err) {
|
|
10313
10289
|
reset();
|
|
10290
|
+
gui.clearMode();
|
|
10314
10291
|
});
|
|
10315
10292
|
}
|
|
10316
10293
|
// reset(); // TODO: exit interactive mode
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.39";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
get rtrim () { return rtrim; },
|
|
66
66
|
get addThousandsSep () { return addThousandsSep; },
|
|
67
67
|
get numToStr () { return numToStr; },
|
|
68
|
-
get formatNumber () { return formatNumber; },
|
|
68
|
+
get formatNumber () { return formatNumber$1; },
|
|
69
69
|
get formatIntlNumber () { return formatIntlNumber; },
|
|
70
70
|
get formatNumberForDisplay () { return formatNumberForDisplay; },
|
|
71
71
|
get shuffle () { return shuffle; },
|
|
@@ -649,12 +649,12 @@
|
|
|
649
649
|
return decimals >= 0 ? num.toFixed(decimals) : String(num);
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
-
function formatNumber(val) {
|
|
652
|
+
function formatNumber$1(val) {
|
|
653
653
|
return val + '';
|
|
654
654
|
}
|
|
655
655
|
|
|
656
656
|
function formatIntlNumber(val) {
|
|
657
|
-
var str = formatNumber(val);
|
|
657
|
+
var str = formatNumber$1(val);
|
|
658
658
|
return '"' + str.replace('.', ',') + '"'; // need to quote if comma-delimited
|
|
659
659
|
}
|
|
660
660
|
|
|
@@ -1247,7 +1247,8 @@
|
|
|
1247
1247
|
|
|
1248
1248
|
// Handle an error caused by invalid input or misuse of API
|
|
1249
1249
|
function stop() {
|
|
1250
|
-
_stop.apply(null, utils.toArray(arguments));
|
|
1250
|
+
// _stop.apply(null, utils.toArray(arguments));
|
|
1251
|
+
_stop.apply(null, messageArgs(arguments));
|
|
1251
1252
|
}
|
|
1252
1253
|
|
|
1253
1254
|
function interrupt() {
|
|
@@ -4670,12 +4671,11 @@
|
|
|
4670
4671
|
albersusa: AlbersUSA
|
|
4671
4672
|
};
|
|
4672
4673
|
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
if (!asyncLoader) return done();
|
|
4676
|
-
asyncLoader(opts, done);
|
|
4674
|
+
async function initProjLibrary(opts) {
|
|
4675
|
+
if (asyncLoader) await asyncLoader(opts);
|
|
4677
4676
|
}
|
|
4678
4677
|
|
|
4678
|
+
// used by web UI to support loading projection assets asyncronously
|
|
4679
4679
|
function setProjectionLoader(loader) {
|
|
4680
4680
|
asyncLoader = loader;
|
|
4681
4681
|
}
|
|
@@ -13115,6 +13115,105 @@
|
|
|
13115
13115
|
});
|
|
13116
13116
|
}
|
|
13117
13117
|
|
|
13118
|
+
// Parse a formatted value in DMS DM or D to a numeric value. Returns NaN if unparsable.
|
|
13119
|
+
// Delimiters: degrees: D|d|°; minutes: '; seconds: "
|
|
13120
|
+
function parseDMS(str, fmt) {
|
|
13121
|
+
var defaultRxp = /^(?<prefix>[nsew+-]?)(?<d>[0-9.]+)[d°]? ?(?<m>[0-9.]*)['′]? ?(?<s>[0-9.]*)["″]? ?(?<suffix>[nsew]?)$/i;
|
|
13122
|
+
var rxp = fmt ? getParseRxp(fmt) : defaultRxp;
|
|
13123
|
+
var match = rxp.exec(str.trim());
|
|
13124
|
+
var d = NaN;
|
|
13125
|
+
var deg, min, sec;
|
|
13126
|
+
if (match) {
|
|
13127
|
+
deg = match.groups.d || '0';
|
|
13128
|
+
min = match.groups.m || '0';
|
|
13129
|
+
sec = match.groups.s || '0';
|
|
13130
|
+
d = (+deg) + (+min) / 60 + (+sec) / 3600;
|
|
13131
|
+
if (/[sw-]/i.test(match.groups.prefix || '') || /[sw]/i.test(match.groups.suffix || '')) {
|
|
13132
|
+
d = -d;
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
return d;
|
|
13136
|
+
}
|
|
13137
|
+
|
|
13138
|
+
var cache$1 = {};
|
|
13139
|
+
|
|
13140
|
+
function getParseRxp(fmt) {
|
|
13141
|
+
if (fmt in cache$1) return cache$1[fmt];
|
|
13142
|
+
var rxp = fmt;
|
|
13143
|
+
rxp = rxp.replace('[-]', '(?<prefix>-)?'); // optional -
|
|
13144
|
+
rxp = rxp.replace(/\[[NSEW, +-]{2,}\]/, '(?<prefix>$&)');
|
|
13145
|
+
rxp = rxp.replace(/(MM?)(\.M+)?/, (m, g1, g2) => {
|
|
13146
|
+
var s = g1.length == 1 ? '[0-9]+' : '[0-9][0-9]';
|
|
13147
|
+
if (g2) s += `\\.[0-9]+`;
|
|
13148
|
+
return `(?<m>${s})`;
|
|
13149
|
+
});
|
|
13150
|
+
rxp = rxp.replace(/(SS?)(\.S+)?/, (m, g1, g2) => {
|
|
13151
|
+
var s = g1.length == 1 ? '[0-9]+' : '[0-9][0-9]';
|
|
13152
|
+
if (g2) s += `\\.[0-9]+`;
|
|
13153
|
+
return `(?<s>${s})`;
|
|
13154
|
+
});
|
|
13155
|
+
rxp = rxp.replace(/D+/, '(?<d>[0-9]+)');
|
|
13156
|
+
rxp = '^' + rxp + '$';
|
|
13157
|
+
try {
|
|
13158
|
+
// TODO: make sure all DMS codes have been matched
|
|
13159
|
+
cache$1[fmt] = new RegExp(rxp);
|
|
13160
|
+
} catch(e) {
|
|
13161
|
+
stop('Invalid DMS format string:', fmt);
|
|
13162
|
+
}
|
|
13163
|
+
return cache$1[fmt];
|
|
13164
|
+
}
|
|
13165
|
+
|
|
13166
|
+
function formatNumber(val, integers, decimals) {
|
|
13167
|
+
var str = val.toFixed(decimals);
|
|
13168
|
+
var parts = str.split('.');
|
|
13169
|
+
if (parts.length > 0) {
|
|
13170
|
+
parts[0] = parts[0].padStart(integers, '0');
|
|
13171
|
+
str = parts.join('.');
|
|
13172
|
+
}
|
|
13173
|
+
return str;
|
|
13174
|
+
}
|
|
13175
|
+
|
|
13176
|
+
function getDecimals(fmt) {
|
|
13177
|
+
var match = /S\.(S+)/.exec(fmt) || /M\.(M+)/.exec(fmt) || null;
|
|
13178
|
+
return match ? match[1].length : 0;
|
|
13179
|
+
}
|
|
13180
|
+
|
|
13181
|
+
// TODO: support DD.DDDDD
|
|
13182
|
+
function formatDMS(coord, fmt) {
|
|
13183
|
+
if (!fmt) fmt = '[-]D°M\'S.SSS';
|
|
13184
|
+
var str = fmt;
|
|
13185
|
+
var dstr, mstr, sstr;
|
|
13186
|
+
var match = /(D+)[^M]*(M+)[^S[\]]*(S+)?/.exec(fmt);
|
|
13187
|
+
if (!match) {
|
|
13188
|
+
stop('Invalid DMS format string:', fmt);
|
|
13189
|
+
}
|
|
13190
|
+
var gotSeconds = !!match[3];
|
|
13191
|
+
var decimals = getDecimals(fmt);
|
|
13192
|
+
var integers = gotSeconds ? match[3].length : match[2].length;
|
|
13193
|
+
var RES = Math.pow(10, decimals);
|
|
13194
|
+
var CONV = gotSeconds ? 3600 * RES : 60 * RES;
|
|
13195
|
+
var r = Math.floor(Math.abs(coord) * CONV + 0.5);
|
|
13196
|
+
var lastPart = formatNumber((r / RES) % 60, integers, decimals);
|
|
13197
|
+
if (gotSeconds) {
|
|
13198
|
+
r = Math.floor(r / (RES * 60));
|
|
13199
|
+
sstr = lastPart;
|
|
13200
|
+
mstr = String(r % 60).padStart(match[2].length, '0');
|
|
13201
|
+
} else {
|
|
13202
|
+
r = Math.floor(r / RES);
|
|
13203
|
+
mstr = lastPart;
|
|
13204
|
+
sstr = '';
|
|
13205
|
+
}
|
|
13206
|
+
dstr = String(Math.floor(r / 60)).padStart(match[1].length, '0');
|
|
13207
|
+
str = str.replace(/\[-\]/, s => coord < 0 ? '-' : '');
|
|
13208
|
+
str = str.replace(/\[[+-]+\]/, s => coord < 0 ? '-' : '+');
|
|
13209
|
+
str = str.replace(/\[[NS, ]+\]/, s => coord < 0 ? 'S' : 'N');
|
|
13210
|
+
str = str.replace(/\[[EW, ]+\]/, s => coord < 0 ? 'W' : 'E');
|
|
13211
|
+
str = str.replace(/D+/, dstr);
|
|
13212
|
+
str = str.replace(/M+(\.M+)?/, mstr);
|
|
13213
|
+
if (gotSeconds) str = str.replace(/S+(\.S+)?/, sstr);
|
|
13214
|
+
return str;
|
|
13215
|
+
}
|
|
13216
|
+
|
|
13118
13217
|
function cleanExpression(exp) {
|
|
13119
13218
|
// workaround for problem in GNU Make v4: end-of-line backslashes inside
|
|
13120
13219
|
// quoted strings are left in the string (other shell environments remove them)
|
|
@@ -13126,7 +13225,9 @@
|
|
|
13126
13225
|
round: roundToDigits2,
|
|
13127
13226
|
int_median: interpolated_median,
|
|
13128
13227
|
sprintf: utils.format,
|
|
13129
|
-
blend: blend
|
|
13228
|
+
blend: blend,
|
|
13229
|
+
format_dms: formatDMS,
|
|
13230
|
+
parse_dms: parseDMS
|
|
13130
13231
|
});
|
|
13131
13232
|
}
|
|
13132
13233
|
|
|
@@ -22791,7 +22892,6 @@ ${svg}
|
|
|
22791
22892
|
|
|
22792
22893
|
this.getHelpMessage = function(cmdName) {
|
|
22793
22894
|
var helpCommands, singleCommand, lines;
|
|
22794
|
-
|
|
22795
22895
|
if (cmdName) {
|
|
22796
22896
|
singleCommand = findCommandDefn(cmdName, getCommands());
|
|
22797
22897
|
if (!singleCommand) {
|
|
@@ -22910,10 +23010,6 @@ ${svg}
|
|
|
22910
23010
|
}
|
|
22911
23011
|
};
|
|
22912
23012
|
|
|
22913
|
-
this.printHelp = function(command) {
|
|
22914
|
-
print(this.getHelpMessage(command));
|
|
22915
|
-
};
|
|
22916
|
-
|
|
22917
23013
|
function getCommands() {
|
|
22918
23014
|
return _commands.map(function(cmd) {
|
|
22919
23015
|
return cmd.done();
|
|
@@ -23633,7 +23729,7 @@ ${svg}
|
|
|
23633
23729
|
type: 'flag'
|
|
23634
23730
|
})
|
|
23635
23731
|
.option('other', {
|
|
23636
|
-
describe: 'default color for categorical scheme (
|
|
23732
|
+
describe: 'default color for categorical scheme (default is nodata color)'
|
|
23637
23733
|
})
|
|
23638
23734
|
.option('nodata', {
|
|
23639
23735
|
describe: 'color to use for invalid or missing data (default is white)'
|
|
@@ -24561,7 +24657,7 @@ ${svg}
|
|
|
24561
24657
|
parser.command('symbols')
|
|
24562
24658
|
.describe('symbolize points as arrows, circles, stars, polygons, etc.')
|
|
24563
24659
|
.option('type', {
|
|
24564
|
-
describe: '
|
|
24660
|
+
describe: 'types: arrow, circle, square, star, polygon, ring'
|
|
24565
24661
|
})
|
|
24566
24662
|
.option('stroke', {})
|
|
24567
24663
|
.option('stroke-width', {})
|
|
@@ -24574,6 +24670,9 @@ ${svg}
|
|
|
24574
24670
|
.option('stroke-width', {
|
|
24575
24671
|
describe: 'symbol line width (linear symbols only)'
|
|
24576
24672
|
})
|
|
24673
|
+
.option('opacity', {
|
|
24674
|
+
describe: 'symbol opacity'
|
|
24675
|
+
})
|
|
24577
24676
|
.option('geographic', {
|
|
24578
24677
|
old_alias: 'polygons',
|
|
24579
24678
|
describe: 'make geographic shapes instead of SVG objects',
|
|
@@ -24674,7 +24773,6 @@ ${svg}
|
|
|
24674
24773
|
.option('no-replace', noReplaceOpt);
|
|
24675
24774
|
// .option('name', nameOpt);
|
|
24676
24775
|
|
|
24677
|
-
|
|
24678
24776
|
parser.command('target')
|
|
24679
24777
|
.describe('set active layer (or layers)')
|
|
24680
24778
|
.option('target', {
|
|
@@ -24684,6 +24782,14 @@ ${svg}
|
|
|
24684
24782
|
.option('type', {
|
|
24685
24783
|
describe: 'type of layer to target (polygon|polyline|point)'
|
|
24686
24784
|
})
|
|
24785
|
+
// .option('combine', {
|
|
24786
|
+
// type: 'flag',
|
|
24787
|
+
// describe: 'place all targeted layers in one dataset together with any associated layers'
|
|
24788
|
+
// })
|
|
24789
|
+
// .option('isolate', {
|
|
24790
|
+
// type: 'flag',
|
|
24791
|
+
// describe: 'place all targeted layers in one dataset exclusive of associated layers'
|
|
24792
|
+
// })
|
|
24687
24793
|
.option('name', {
|
|
24688
24794
|
describe: 'rename the target layer'
|
|
24689
24795
|
});
|
|
@@ -38516,6 +38622,11 @@ ${svg}
|
|
|
38516
38622
|
};
|
|
38517
38623
|
}
|
|
38518
38624
|
|
|
38625
|
+
cmd.printHelp = function(opts) {
|
|
38626
|
+
var str = getOptionParser().getHelpMessage(opts.command);
|
|
38627
|
+
print(str);
|
|
38628
|
+
};
|
|
38629
|
+
|
|
38519
38630
|
function resetControlFlow(job) {
|
|
38520
38631
|
job.control = null;
|
|
38521
38632
|
}
|
|
@@ -39155,25 +39266,6 @@ ${svg}
|
|
|
39155
39266
|
};
|
|
39156
39267
|
}
|
|
39157
39268
|
|
|
39158
|
-
// Parse a formatted value in DMS DM or D to a numeric value. Returns NaN if unparsable.
|
|
39159
|
-
// Delimiters: degrees: D|d|°; minutes: '; seconds: "
|
|
39160
|
-
function parseDMS(str) {
|
|
39161
|
-
var rxp = /^([nsew+-]?)([0-9.]+)[d°]? ?([0-9.]*)['′]? ?([0-9.]*)["″]? ?([nsew]?)$/i;
|
|
39162
|
-
var match = rxp.exec(str.trim());
|
|
39163
|
-
var d = NaN;
|
|
39164
|
-
var deg, min, sec;
|
|
39165
|
-
if (match) {
|
|
39166
|
-
deg = match[2] || '0';
|
|
39167
|
-
min = match[3] || '0';
|
|
39168
|
-
sec = match[4] || '0';
|
|
39169
|
-
d = (+deg) + (+min) / 60 + (+sec) / 3600;
|
|
39170
|
-
if (/[sw-]/i.test(match[1]) || /[sw]/i.test(match[5])) {
|
|
39171
|
-
d = -d;
|
|
39172
|
-
}
|
|
39173
|
-
}
|
|
39174
|
-
return d;
|
|
39175
|
-
}
|
|
39176
|
-
|
|
39177
39269
|
function findNearestVertices(p, shp, arcs) {
|
|
39178
39270
|
var p2 = findNearestVertex(p[0], p[1], shp, arcs);
|
|
39179
39271
|
return findVertexIds(p2.x, p2.y, arcs);
|
|
@@ -42281,6 +42373,18 @@ ${svg}
|
|
|
42281
42373
|
return d.stroke || d.fill || 'magenta';
|
|
42282
42374
|
}
|
|
42283
42375
|
|
|
42376
|
+
function applySymbolStyles(sym, d) {
|
|
42377
|
+
if (sym.type == 'polyline') {
|
|
42378
|
+
sym.stroke = getSymbolStrokeColor(d);
|
|
42379
|
+
} else {
|
|
42380
|
+
sym.fill = getSymbolFillColor(d);
|
|
42381
|
+
}
|
|
42382
|
+
if (d.opacity) {
|
|
42383
|
+
sym.opacity = d.opacity;
|
|
42384
|
+
}
|
|
42385
|
+
return sym;
|
|
42386
|
+
}
|
|
42387
|
+
|
|
42284
42388
|
function getSymbolRadius(d) {
|
|
42285
42389
|
if (d.radius === 0 || d.length === 0 || d.r === 0) return 0;
|
|
42286
42390
|
return d.radius || d.length || d.r || 5; // use a default value
|
|
@@ -42518,11 +42622,8 @@ ${svg}
|
|
|
42518
42622
|
var radius = getSymbolRadius(d);
|
|
42519
42623
|
// TODO: remove duplication with svg-symbols.js
|
|
42520
42624
|
if (+opts.scale) radius *= +opts.scale;
|
|
42521
|
-
|
|
42522
|
-
|
|
42523
|
-
fill: getSymbolFillColor(d),
|
|
42524
|
-
r: radius
|
|
42525
|
-
};
|
|
42625
|
+
var sym = { type: 'circle', r: radius };
|
|
42626
|
+
return applySymbolStyles(sym, d);
|
|
42526
42627
|
}
|
|
42527
42628
|
|
|
42528
42629
|
function getPolygonCoords(d) {
|
|
@@ -42614,11 +42715,13 @@ ${svg}
|
|
|
42614
42715
|
var radii = parseRings(d.radii || '2').map(function(r) { return r * scale; });
|
|
42615
42716
|
var solidCenter = utils.isOdd(radii.length);
|
|
42616
42717
|
var color = getSymbolFillColor(d);
|
|
42718
|
+
var opacity = opts.opacity || undefined;
|
|
42617
42719
|
var parts = [];
|
|
42618
42720
|
if (solidCenter) {
|
|
42619
42721
|
parts.push({
|
|
42620
42722
|
type: 'circle',
|
|
42621
42723
|
fill: color,
|
|
42724
|
+
opacity: opacity,
|
|
42622
42725
|
r: radii.shift()
|
|
42623
42726
|
});
|
|
42624
42727
|
}
|
|
@@ -42627,6 +42730,7 @@ ${svg}
|
|
|
42627
42730
|
type: 'circle',
|
|
42628
42731
|
fill: 'none', // TODO remove default black fill so this is not needed
|
|
42629
42732
|
stroke: color,
|
|
42733
|
+
opacity: opacity,
|
|
42630
42734
|
'stroke-width': roundToTenths(radii[i+1] - radii[i]),
|
|
42631
42735
|
r: roundToTenths(radii[i+1] * 0.5 + radii[i] * 0.5)
|
|
42632
42736
|
});
|
|
@@ -42674,19 +42778,18 @@ ${svg}
|
|
|
42674
42778
|
if (geojsonType == 'MultiPolygon' || geojsonType == 'Polygon') {
|
|
42675
42779
|
sym = {
|
|
42676
42780
|
type: 'polygon',
|
|
42677
|
-
fill: getSymbolFillColor(properties),
|
|
42678
42781
|
coordinates: geojsonType == 'Polygon' ? coords : flattenMultiPolygonCoords(coords)
|
|
42679
42782
|
};
|
|
42680
42783
|
} else if (geojsonType == 'LineString' || geojsonType == 'MultiLineString') {
|
|
42681
42784
|
sym = {
|
|
42682
42785
|
type: 'polyline',
|
|
42683
|
-
stroke: getSymbolStrokeColor(properties),
|
|
42684
42786
|
'stroke-width': properties['stroke-width'] || 2,
|
|
42685
42787
|
coordinates: geojsonType == 'LineString' ? [coords] : coords
|
|
42686
42788
|
};
|
|
42687
42789
|
} else {
|
|
42688
42790
|
error('Unsupported type:', geojsonType);
|
|
42689
42791
|
}
|
|
42792
|
+
applySymbolStyles(sym, properties);
|
|
42690
42793
|
roundCoordsForSVG(sym.coordinates);
|
|
42691
42794
|
return sym;
|
|
42692
42795
|
}
|
|
@@ -42746,6 +42849,7 @@ ${svg}
|
|
|
42746
42849
|
scaleAndShiftCoords(coords, metersPerPx, shp[0]);
|
|
42747
42850
|
if (d.fill) rec.fill = d.fill;
|
|
42748
42851
|
if (d.stroke) rec.stroke = d.stroke;
|
|
42852
|
+
if (d.opacity) rec.opacity = d.opacity;
|
|
42749
42853
|
return createGeometry(coords, geojsonType);
|
|
42750
42854
|
} else {
|
|
42751
42855
|
rec['svg-symbol'] = makePathSymbol(coords, d, geojsonType);
|
|
@@ -42811,9 +42915,41 @@ ${svg}
|
|
|
42811
42915
|
// TODO: improve this
|
|
42812
42916
|
targets[0].layers[0].name = opts.name;
|
|
42813
42917
|
}
|
|
42918
|
+
if (opts.combine) {
|
|
42919
|
+
targets = combineTargets(targets, catalog);
|
|
42920
|
+
} else if (opts.isolate) {
|
|
42921
|
+
targets = isolateTargets(targets, catalog);
|
|
42922
|
+
}
|
|
42814
42923
|
catalog.setDefaultTargets(targets);
|
|
42815
42924
|
};
|
|
42816
42925
|
|
|
42926
|
+
function combineTargets(targets, catalog) {
|
|
42927
|
+
var datasets = [];
|
|
42928
|
+
var layers = [];
|
|
42929
|
+
targets.forEach(function(o) {
|
|
42930
|
+
datasets.push(o.dataset);
|
|
42931
|
+
catalog.removeDataset(o.dataset);
|
|
42932
|
+
layers = layers.concat(o.layers);
|
|
42933
|
+
});
|
|
42934
|
+
var combined = mergeDatasets(datasets);
|
|
42935
|
+
catalog.addDataset(combined);
|
|
42936
|
+
return [{
|
|
42937
|
+
dataset: combined,
|
|
42938
|
+
layers: layers
|
|
42939
|
+
}];
|
|
42940
|
+
}
|
|
42941
|
+
|
|
42942
|
+
function isolateTargets(targets, catalog) {
|
|
42943
|
+
var datasets = [];
|
|
42944
|
+
targets.forEach(function(o) {
|
|
42945
|
+
datasets.push(o.dataset);
|
|
42946
|
+
o.layers.forEach(function(lyr) {
|
|
42947
|
+
catalog.removeLayer(lyr, o.dataset);
|
|
42948
|
+
|
|
42949
|
+
});
|
|
42950
|
+
});
|
|
42951
|
+
}
|
|
42952
|
+
|
|
42817
42953
|
cmd.union = function(targetLayers, targetDataset, opts) {
|
|
42818
42954
|
if (targetLayers.length < 2) {
|
|
42819
42955
|
stop('Command requires at least two target layers');
|
|
@@ -43198,7 +43334,7 @@ ${svg}
|
|
|
43198
43334
|
function commandAcceptsMultipleTargetDatasets(name) {
|
|
43199
43335
|
return name == 'rotate' || name == 'info' || name == 'proj' ||
|
|
43200
43336
|
name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
|
|
43201
|
-
name == 'else' || name == 'endif' || name == 'run';
|
|
43337
|
+
name == 'else' || name == 'endif' || name == 'run' || name == 'i';
|
|
43202
43338
|
}
|
|
43203
43339
|
|
|
43204
43340
|
function commandAcceptsEmptyTarget(name) {
|
|
@@ -43387,8 +43523,8 @@ ${svg}
|
|
|
43387
43523
|
job.catalog.addDataset(cmd.graticule(targetDataset, opts));
|
|
43388
43524
|
|
|
43389
43525
|
} else if (name == 'help') {
|
|
43390
|
-
// placing
|
|
43391
|
-
|
|
43526
|
+
// placing help command here to handle errors from invalid command names
|
|
43527
|
+
cmd.printHelp(command.options);
|
|
43392
43528
|
|
|
43393
43529
|
} else if (name == 'i') {
|
|
43394
43530
|
if (opts.replace) job.catalog = new Catalog(); // is this what we want?
|
|
@@ -43470,7 +43606,7 @@ ${svg}
|
|
|
43470
43606
|
cmd.print(command._.join(' '));
|
|
43471
43607
|
|
|
43472
43608
|
} else if (name == 'proj') {
|
|
43473
|
-
await
|
|
43609
|
+
await initProjLibrary(opts);
|
|
43474
43610
|
job.resumeCommand();
|
|
43475
43611
|
targets.forEach(function(targ) {
|
|
43476
43612
|
cmd.proj(targ.dataset, job.catalog, opts);
|
|
@@ -44305,6 +44441,7 @@ ${svg}
|
|
|
44305
44441
|
Heap,
|
|
44306
44442
|
NodeCollection,
|
|
44307
44443
|
parseDMS,
|
|
44444
|
+
formatDMS,
|
|
44308
44445
|
PathIndex,
|
|
44309
44446
|
PolygonIndex,
|
|
44310
44447
|
ShpReader,
|