mapshaper 0.6.41 → 0.6.42
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 +162 -56
- package/package.json +1 -1
- package/www/index.html +1 -1
- package/www/mapshaper-gui.js +97 -28
- package/www/mapshaper.js +162 -56
- package/www/page.css +33 -18
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.42";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1267,6 +1267,26 @@
|
|
|
1267
1267
|
_stop = stop;
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
|
+
// get detailed error information from error stack (if available)
|
|
1271
|
+
// Example stack string (Node.js):
|
|
1272
|
+
/*
|
|
1273
|
+
/Users/someuser/somescript.js:226
|
|
1274
|
+
opacity: Math.round(weight * 5 / 5 // 0.2 0.4 0.6 etc
|
|
1275
|
+
^
|
|
1276
|
+
|
|
1277
|
+
SyntaxError: missing ) after argument list
|
|
1278
|
+
at internalCompileFunction (node:internal/vm:73:18)
|
|
1279
|
+
at wrapSafe (node:internal/modules/cjs/loader:1149:20)
|
|
1280
|
+
at Module._compile (node:internal/modules/cjs/loader:1190:27)
|
|
1281
|
+
...
|
|
1282
|
+
*/
|
|
1283
|
+
function getErrorDetail(e) {
|
|
1284
|
+
var parts = (typeof e.stack == 'string') ? e.stack.split(/\n\s*\n/) : [];
|
|
1285
|
+
if (parts.length > 1 || true) {
|
|
1286
|
+
return '\nError details:\n' + parts[0];
|
|
1287
|
+
}
|
|
1288
|
+
return '';
|
|
1289
|
+
}
|
|
1270
1290
|
|
|
1271
1291
|
// print a message to stdout
|
|
1272
1292
|
function print() {
|
|
@@ -1389,6 +1409,7 @@
|
|
|
1389
1409
|
interrupt: interrupt,
|
|
1390
1410
|
message: message,
|
|
1391
1411
|
setLoggingFunctions: setLoggingFunctions,
|
|
1412
|
+
getErrorDetail: getErrorDetail,
|
|
1392
1413
|
print: print,
|
|
1393
1414
|
verbose: verbose,
|
|
1394
1415
|
debug: debug,
|
|
@@ -6359,9 +6380,10 @@
|
|
|
6359
6380
|
function mergeDatasets(arr) {
|
|
6360
6381
|
var arcSources = [],
|
|
6361
6382
|
arcCount = 0,
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6383
|
+
merged = {
|
|
6384
|
+
info: {},
|
|
6385
|
+
layers: []
|
|
6386
|
+
};
|
|
6365
6387
|
|
|
6366
6388
|
// Error if incompatible CRS
|
|
6367
6389
|
requireDatasetsHaveCompatibleCRS(arr);
|
|
@@ -6372,38 +6394,35 @@
|
|
|
6372
6394
|
arcSources.push(dataset.arcs);
|
|
6373
6395
|
}
|
|
6374
6396
|
|
|
6375
|
-
mergeDatasetInfo(
|
|
6397
|
+
mergeDatasetInfo$1(merged, dataset);
|
|
6376
6398
|
dataset.layers.forEach(function(lyr) {
|
|
6377
6399
|
if (lyr.geometry_type == 'polygon' || lyr.geometry_type == 'polyline') {
|
|
6378
6400
|
forEachArcId(lyr.shapes, function(id) {
|
|
6379
6401
|
return id < 0 ? id - arcCount : id + arcCount;
|
|
6380
6402
|
});
|
|
6381
6403
|
}
|
|
6382
|
-
|
|
6404
|
+
merged.layers.push(lyr);
|
|
6383
6405
|
});
|
|
6384
6406
|
arcCount += n;
|
|
6385
6407
|
});
|
|
6386
6408
|
|
|
6387
6409
|
if (arcSources.length > 0) {
|
|
6388
|
-
|
|
6389
|
-
if (
|
|
6410
|
+
merged.arcs = mergeArcs(arcSources);
|
|
6411
|
+
if (merged.arcs.size() != arcCount) {
|
|
6390
6412
|
error("[mergeDatasets()] Arc indexing error");
|
|
6391
6413
|
}
|
|
6392
6414
|
}
|
|
6393
6415
|
|
|
6394
|
-
return
|
|
6395
|
-
info: mergedInfo,
|
|
6396
|
-
arcs: mergedArcs,
|
|
6397
|
-
layers: mergedLayers
|
|
6398
|
-
};
|
|
6416
|
+
return merged;
|
|
6399
6417
|
}
|
|
6400
6418
|
|
|
6401
|
-
function mergeDatasetInfo(merged, dataset) {
|
|
6402
|
-
var
|
|
6403
|
-
|
|
6404
|
-
|
|
6419
|
+
function mergeDatasetInfo$1(merged, dataset) {
|
|
6420
|
+
var src = dataset.info || {};
|
|
6421
|
+
var dest = merged.info || (merged.info = {});
|
|
6422
|
+
dest.input_files = utils.uniq((dest.input_files || []).concat(src.input_files || []));
|
|
6423
|
+
dest.input_formats = utils.uniq((dest.input_formats || []).concat(src.input_formats || []));
|
|
6405
6424
|
// merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
|
|
6406
|
-
utils.defaults(
|
|
6425
|
+
utils.defaults(dest, src);
|
|
6407
6426
|
}
|
|
6408
6427
|
|
|
6409
6428
|
function mergeArcs(arr) {
|
|
@@ -6450,6 +6469,7 @@
|
|
|
6450
6469
|
mergeDatasetsForExport: mergeDatasetsForExport,
|
|
6451
6470
|
mergeCommandTargets: mergeCommandTargets,
|
|
6452
6471
|
mergeDatasets: mergeDatasets,
|
|
6472
|
+
mergeDatasetInfo: mergeDatasetInfo$1,
|
|
6453
6473
|
mergeArcs: mergeArcs
|
|
6454
6474
|
});
|
|
6455
6475
|
|
|
@@ -6900,6 +6920,18 @@
|
|
|
6900
6920
|
});
|
|
6901
6921
|
}
|
|
6902
6922
|
|
|
6923
|
+
// dest: destination dataset
|
|
6924
|
+
// src: source dataset
|
|
6925
|
+
function mergeDatasetInfo(dest, src) {
|
|
6926
|
+
var srcInfo = src.info || {};
|
|
6927
|
+
var destInfo = dest.info || (dest.info = {});
|
|
6928
|
+
destInfo.input_files = utils.uniq((destInfo.input_files || []).concat(srcInfo.input_files || []));
|
|
6929
|
+
destInfo.input_formats = utils.uniq((destInfo.input_formats || []).concat(srcInfo.input_formats || []));
|
|
6930
|
+
// merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
|
|
6931
|
+
utils.defaults(destInfo, srcInfo);
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
|
|
6903
6935
|
function splitApartLayers(dataset, layers) {
|
|
6904
6936
|
var datasets = [];
|
|
6905
6937
|
dataset.layers = dataset.layers.filter(function(lyr) {
|
|
@@ -7064,6 +7096,7 @@
|
|
|
7064
7096
|
var DatasetUtils = /*#__PURE__*/Object.freeze({
|
|
7065
7097
|
__proto__: null,
|
|
7066
7098
|
splitDataset: splitDataset,
|
|
7099
|
+
mergeDatasetInfo: mergeDatasetInfo,
|
|
7067
7100
|
splitApartLayers: splitApartLayers,
|
|
7068
7101
|
copyDataset: copyDataset,
|
|
7069
7102
|
copyDatasetForExport: copyDatasetForExport,
|
|
@@ -11205,20 +11238,43 @@
|
|
|
11205
11238
|
return dest;
|
|
11206
11239
|
};
|
|
11207
11240
|
|
|
11241
|
+
// Receives a directory path, in which the final subdirectory may include the
|
|
11242
|
+
// "*" wildcard, e.g. '.' 'data' '*' 'data/*' '2023-*'
|
|
11243
|
+
// Returns an array of expanded directory names
|
|
11244
|
+
// TODO: add support for wildcards in other subdirectories
|
|
11245
|
+
cli.expandDirectoryName = function(name) {
|
|
11246
|
+
var info = parseLocalPath(name);
|
|
11247
|
+
// final directory name is parsed as info.filename
|
|
11248
|
+
if (!info.filename.includes('*')) {
|
|
11249
|
+
return [name];
|
|
11250
|
+
}
|
|
11251
|
+
var rxp = utils.wildcardToRegExp(info.filename);
|
|
11252
|
+
var dirs = [];
|
|
11253
|
+
require$1('fs').readdirSync(info.directory || '.').forEach(function(item) {
|
|
11254
|
+
var path = info.directory ? require$1('path').join(info.directory, item) : item;
|
|
11255
|
+
if (rxp.test(item) && cli.isDirectory(path)) {
|
|
11256
|
+
dirs.push(path);
|
|
11257
|
+
}
|
|
11258
|
+
});
|
|
11259
|
+
return dirs;
|
|
11260
|
+
};
|
|
11261
|
+
|
|
11208
11262
|
// Expand any "*" wild cards in file name
|
|
11209
11263
|
// (For the Windows command line; unix shells do this automatically)
|
|
11210
11264
|
cli.expandFileName = function(name) {
|
|
11211
11265
|
var info = parseLocalPath(name),
|
|
11212
11266
|
rxp = utils.wildcardToRegExp(info.filename),
|
|
11213
|
-
|
|
11267
|
+
dirs = cli.expandDirectoryName(info.directory || '.'),
|
|
11214
11268
|
files = [];
|
|
11215
11269
|
|
|
11216
11270
|
try {
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11271
|
+
dirs.forEach(function(dir) {
|
|
11272
|
+
require$1('fs').readdirSync(dir).forEach(function(item) {
|
|
11273
|
+
var path = require$1('path').join(dir, item);
|
|
11274
|
+
if (rxp.test(item) && cli.isFile(path)) {
|
|
11275
|
+
files.push(path);
|
|
11276
|
+
}
|
|
11277
|
+
});
|
|
11222
11278
|
});
|
|
11223
11279
|
} catch(e) {}
|
|
11224
11280
|
|
|
@@ -28239,20 +28295,23 @@ ${svg}
|
|
|
28239
28295
|
};
|
|
28240
28296
|
|
|
28241
28297
|
this.setDefaultTarget = function(layers, dataset) {
|
|
28242
|
-
|
|
28243
|
-
datasets.push(dataset);
|
|
28244
|
-
}
|
|
28245
|
-
defaultTargets = [{
|
|
28298
|
+
this.setDefaultTargets([{
|
|
28246
28299
|
// Copy layers array, in case layers is a reference to dataset.layers.
|
|
28247
28300
|
// This prevents layers that are added to the dataset inside a command from
|
|
28248
28301
|
// being added to the next command's target, e.g. debugging layers added
|
|
28249
28302
|
// by '-join unmatched unjoined'.
|
|
28250
28303
|
layers: layers.concat(),
|
|
28251
28304
|
dataset: dataset
|
|
28252
|
-
}];
|
|
28305
|
+
}]);
|
|
28253
28306
|
};
|
|
28254
28307
|
|
|
28308
|
+
// arr: array of target objects {layers:[], dataset:{}}
|
|
28255
28309
|
this.setDefaultTargets = function(arr) {
|
|
28310
|
+
arr.forEach(function(target) {
|
|
28311
|
+
if (datasets.indexOf(target.dataset) == -1) {
|
|
28312
|
+
datasets.push(target.dataset);
|
|
28313
|
+
}
|
|
28314
|
+
});
|
|
28256
28315
|
defaultTargets = arr;
|
|
28257
28316
|
};
|
|
28258
28317
|
|
|
@@ -28345,6 +28404,30 @@ ${svg}
|
|
|
28345
28404
|
stashVar('input_files', job.input_files);
|
|
28346
28405
|
}
|
|
28347
28406
|
|
|
28407
|
+
// Apply a command to an array of target layers
|
|
28408
|
+
function applyCommandToEachLayer(func, targetLayers) {
|
|
28409
|
+
var args = utils.toArray(arguments).slice(2);
|
|
28410
|
+
return targetLayers.reduce(function(memo, lyr) {
|
|
28411
|
+
var result = func.apply(null, [lyr].concat(args));
|
|
28412
|
+
if (utils.isArray(result)) { // some commands return an array of layers
|
|
28413
|
+
memo = memo.concat(result);
|
|
28414
|
+
} else if (result) { // assuming result is a layer
|
|
28415
|
+
memo.push(result);
|
|
28416
|
+
}
|
|
28417
|
+
return memo;
|
|
28418
|
+
}, []);
|
|
28419
|
+
}
|
|
28420
|
+
|
|
28421
|
+
function applyCommandToEachTarget(func, targets) {
|
|
28422
|
+
var args = utils.toArray(arguments).slice(2);
|
|
28423
|
+
targets.forEach(function(target) {
|
|
28424
|
+
var result = func.apply(null, [target].concat(args));
|
|
28425
|
+
if (result) {
|
|
28426
|
+
error('Unexpected output from command');
|
|
28427
|
+
}
|
|
28428
|
+
});
|
|
28429
|
+
}
|
|
28430
|
+
|
|
28348
28431
|
cmd.addShape = addShape;
|
|
28349
28432
|
|
|
28350
28433
|
function addShape(targetLayers, targetDataset, opts) {
|
|
@@ -36290,6 +36373,7 @@ ${svg}
|
|
|
36290
36373
|
var opts = parseExternalCommand(name, cmdDefn, cmdOpts._);
|
|
36291
36374
|
var targets = catalog.findCommandTargets(opts.target || '*');
|
|
36292
36375
|
var target = targets[0];
|
|
36376
|
+
var output;
|
|
36293
36377
|
if (!target) {
|
|
36294
36378
|
stop('Missing a target');
|
|
36295
36379
|
}
|
|
@@ -36300,12 +36384,34 @@ ${svg}
|
|
|
36300
36384
|
stop("Targetting layers from multiple datasets is not supported");
|
|
36301
36385
|
}
|
|
36302
36386
|
if (targetType == 'layer') {
|
|
36303
|
-
cmdDefn.command(target.layers[0], target.dataset, opts.options);
|
|
36387
|
+
output = cmdDefn.command(target.layers[0], target.dataset, opts.options);
|
|
36304
36388
|
} else if (targetType == 'layers') {
|
|
36305
|
-
cmdDefn.command(target.layers, target.dataset, opts.options);
|
|
36389
|
+
output = cmdDefn.command(target.layers, target.dataset, opts.options);
|
|
36390
|
+
}
|
|
36391
|
+
if (output) {
|
|
36392
|
+
integrateOutput(output, target, catalog, opts);
|
|
36306
36393
|
}
|
|
36307
36394
|
};
|
|
36308
36395
|
|
|
36396
|
+
// TODO: remove restrictions on output data
|
|
36397
|
+
function integrateOutput(output, input, catalog, opts) {
|
|
36398
|
+
if (!output.dataset || !output.layers || output.layers.length > 0 === false) {
|
|
36399
|
+
stop('Invalid command output');
|
|
36400
|
+
}
|
|
36401
|
+
if (output.dataset == input.dataset) {
|
|
36402
|
+
stop('External commands are not currently allowed to modify input datasets');
|
|
36403
|
+
}
|
|
36404
|
+
if (output.dataset.layers.length != output.layers.length) {
|
|
36405
|
+
stop('Currently not supported: targetting a subset of output layers');
|
|
36406
|
+
}
|
|
36407
|
+
if (!opts.no_replace) {
|
|
36408
|
+
input.layers.forEach(function(lyr) {
|
|
36409
|
+
catalog.deleteLayer(lyr, input.dataset);
|
|
36410
|
+
});
|
|
36411
|
+
}
|
|
36412
|
+
catalog.addDataset(output.dataset);
|
|
36413
|
+
}
|
|
36414
|
+
|
|
36309
36415
|
function parseExternalCommand(name, cmdDefn, tokens) {
|
|
36310
36416
|
var parser = new CommandParser();
|
|
36311
36417
|
var cmd = parser.command(name);
|
|
@@ -40720,7 +40826,8 @@ ${svg}
|
|
|
40720
40826
|
function makeCircleCoords(center, opts) {
|
|
40721
40827
|
var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
|
|
40722
40828
|
var radius = opts.interval / 2 * (1 - margin);
|
|
40723
|
-
|
|
40829
|
+
var vertices = opts.vertices || 20;
|
|
40830
|
+
return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
|
|
40724
40831
|
}
|
|
40725
40832
|
|
|
40726
40833
|
// Returns a function that receives a cell index and returns indices of points
|
|
@@ -40731,12 +40838,15 @@ ${svg}
|
|
|
40731
40838
|
var bboxIndex = new Flatbush(points.length);
|
|
40732
40839
|
var empty = [];
|
|
40733
40840
|
points.forEach(function(p) {
|
|
40841
|
+
var bbox = getPointBounds(p, radius);
|
|
40734
40842
|
addPointToGridIndex(p, gridIndex, grid);
|
|
40735
|
-
bboxIndex.add.apply(bboxIndex,
|
|
40843
|
+
bboxIndex.add.apply(bboxIndex, bbox);
|
|
40736
40844
|
});
|
|
40737
40845
|
bboxIndex.finish();
|
|
40738
40846
|
return function(i) {
|
|
40739
|
-
if (!gridIndex.hasId(i))
|
|
40847
|
+
if (!gridIndex.hasId(i)) {
|
|
40848
|
+
return empty;
|
|
40849
|
+
}
|
|
40740
40850
|
var bbox = grid.idxToBBox(i);
|
|
40741
40851
|
var indices = bboxIndex.search.apply(bboxIndex, bbox);
|
|
40742
40852
|
return indices;
|
|
@@ -40870,6 +40980,7 @@ ${svg}
|
|
|
40870
40980
|
calcWeights: calcWeights,
|
|
40871
40981
|
twoCircleIntersection: twoCircleIntersection,
|
|
40872
40982
|
makeCellPolygon: makeCellPolygon,
|
|
40983
|
+
makeCircleCoords: makeCircleCoords,
|
|
40873
40984
|
getPointIndex: getPointIndex,
|
|
40874
40985
|
getAlignedGridBounds: getAlignedGridBounds,
|
|
40875
40986
|
getCenteredGridBounds: getCenteredGridBounds,
|
|
@@ -41198,8 +41309,7 @@ ${svg}
|
|
|
41198
41309
|
}
|
|
41199
41310
|
}
|
|
41200
41311
|
} catch(e) {
|
|
41201
|
-
|
|
41202
|
-
stop('Unable to load external module:', e.message);
|
|
41312
|
+
stop('Unable to load external module:', e.message, getErrorDetail(e));
|
|
41203
41313
|
}
|
|
41204
41314
|
if (moduleName || opts.alias) {
|
|
41205
41315
|
defs[opts.alias || moduleName] = mod;
|
|
@@ -42230,9 +42340,10 @@ ${svg}
|
|
|
42230
42340
|
}
|
|
42231
42341
|
};
|
|
42232
42342
|
|
|
42233
|
-
cmd.snap = function(
|
|
42343
|
+
cmd.snap = function(target, opts) {
|
|
42234
42344
|
var interval = 0;
|
|
42235
42345
|
var snapCount = 0;
|
|
42346
|
+
var dataset = target.dataset;
|
|
42236
42347
|
var arcs = dataset.arcs;
|
|
42237
42348
|
var arcBounds = arcs && arcs.getBounds();
|
|
42238
42349
|
if (!arcBounds || !arcBounds.hasBounds()) {
|
|
@@ -43367,7 +43478,7 @@ ${svg}
|
|
|
43367
43478
|
function commandAcceptsMultipleTargetDatasets(name) {
|
|
43368
43479
|
return name == 'rotate' || name == 'info' || name == 'proj' || name == 'require' ||
|
|
43369
43480
|
name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
|
|
43370
|
-
name == 'else' || name == 'endif' || name == 'run' || name == 'i';
|
|
43481
|
+
name == 'else' || name == 'endif' || name == 'run' || name == 'i' || name == 'snap';
|
|
43371
43482
|
}
|
|
43372
43483
|
|
|
43373
43484
|
function commandAcceptsEmptyTarget(name) {
|
|
@@ -43449,6 +43560,10 @@ ${svg}
|
|
|
43449
43560
|
source = findCommandSource(convertSourceName(opts.source, targets), job.catalog, opts);
|
|
43450
43561
|
}
|
|
43451
43562
|
|
|
43563
|
+
// identify command target/input (for postprocessing)
|
|
43564
|
+
// TODO: support commands with multiple target datasets
|
|
43565
|
+
// target = name == 'i' ? null : targets[0];
|
|
43566
|
+
|
|
43452
43567
|
if (name == 'add-shape') {
|
|
43453
43568
|
if (!targetDataset) {
|
|
43454
43569
|
targetDataset = {info: {}, layers: []};
|
|
@@ -43556,6 +43671,9 @@ ${svg}
|
|
|
43556
43671
|
} else if (name == 'graticule') {
|
|
43557
43672
|
job.catalog.addDataset(cmd.graticule(targetDataset, opts));
|
|
43558
43673
|
|
|
43674
|
+
} else if (name == 'grid') {
|
|
43675
|
+
outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
|
|
43676
|
+
|
|
43559
43677
|
} else if (name == 'help') {
|
|
43560
43678
|
// placing help command here to handle errors from invalid command names
|
|
43561
43679
|
cmd.printHelp(command.options);
|
|
@@ -43627,9 +43745,6 @@ ${svg}
|
|
|
43627
43745
|
} else if (name == 'point-to-grid') {
|
|
43628
43746
|
outputLayers = cmd.pointToGrid(targetLayers, targetDataset, opts);
|
|
43629
43747
|
|
|
43630
|
-
} else if (name == 'grid') {
|
|
43631
|
-
outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
|
|
43632
|
-
|
|
43633
43748
|
} else if (name == 'points') {
|
|
43634
43749
|
outputLayers = applyCommandToEachLayer(cmd.createPointLayer, targetLayers, targetDataset, opts);
|
|
43635
43750
|
|
|
@@ -43693,7 +43808,8 @@ ${svg}
|
|
|
43693
43808
|
outputLayers = cmd.sliceLayers(targetLayers, source, targetDataset, opts);
|
|
43694
43809
|
|
|
43695
43810
|
} else if (name == 'snap') {
|
|
43696
|
-
cmd.snap(targetDataset, opts);
|
|
43811
|
+
// cmd.snap(targetDataset, opts);
|
|
43812
|
+
applyCommandToEachTarget(targets, opts);
|
|
43697
43813
|
|
|
43698
43814
|
} else if (name == 'sort') {
|
|
43699
43815
|
applyCommandToEachLayer(cmd.sortFeatures, targetLayers, arcs, opts);
|
|
@@ -43784,9 +43900,12 @@ ${svg}
|
|
|
43784
43900
|
|
|
43785
43901
|
// delete arcs if no longer needed (e.g. after -points command)
|
|
43786
43902
|
// (after output layers have been integrated)
|
|
43903
|
+
// TODO: be more selective (e.g. -i command doesn't need cleanup)
|
|
43904
|
+
// or: detect if arcs have been changed
|
|
43787
43905
|
if (targetDataset) {
|
|
43788
43906
|
cleanupArcs(targetDataset);
|
|
43789
43907
|
}
|
|
43908
|
+
|
|
43790
43909
|
} catch(e) {
|
|
43791
43910
|
return done(e);
|
|
43792
43911
|
}
|
|
@@ -43808,20 +43927,6 @@ ${svg}
|
|
|
43808
43927
|
});
|
|
43809
43928
|
}
|
|
43810
43929
|
|
|
43811
|
-
// Apply a command to an array of target layers
|
|
43812
|
-
function applyCommandToEachLayer(func, targetLayers) {
|
|
43813
|
-
var args = utils.toArray(arguments).slice(2);
|
|
43814
|
-
return targetLayers.reduce(function(memo, lyr) {
|
|
43815
|
-
var result = func.apply(null, [lyr].concat(args));
|
|
43816
|
-
if (utils.isArray(result)) { // some commands return an array of layers
|
|
43817
|
-
memo = memo.concat(result);
|
|
43818
|
-
} else if (result) { // assuming result is a layer
|
|
43819
|
-
memo.push(result);
|
|
43820
|
-
}
|
|
43821
|
-
return memo;
|
|
43822
|
-
}, []);
|
|
43823
|
-
}
|
|
43824
|
-
|
|
43825
43930
|
// Parse command line args into commands and run them
|
|
43826
43931
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
43827
43932
|
// function(argv[, input], callback)
|
|
@@ -44465,6 +44570,7 @@ ${svg}
|
|
|
44465
44570
|
editArcs,
|
|
44466
44571
|
GeoJSONReader,
|
|
44467
44572
|
Heap,
|
|
44573
|
+
IdLookupIndex,
|
|
44468
44574
|
NodeCollection,
|
|
44469
44575
|
parseDMS,
|
|
44470
44576
|
formatDMS,
|
package/package.json
CHANGED
package/www/index.html
CHANGED
|
@@ -172,7 +172,7 @@ precision=0.001. Click to see all options.</div></div></div></a>
|
|
|
172
172
|
|
|
173
173
|
<!-- <div class="cancel-btn btn dialog-btn">Cancel</div> -->
|
|
174
174
|
<div class="save-btn btn dialog-btn">Export</div>
|
|
175
|
-
<span id="save-preference"><input type="checkbox"/>choose directory</span>
|
|
175
|
+
<span id="save-preference" class="inline-checkbox" style="display: none;"><input type="checkbox"/>choose directory</span>
|
|
176
176
|
|
|
177
177
|
</div>
|
|
178
178
|
</div>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -1125,21 +1125,26 @@
|
|
|
1125
1125
|
var self = {}, html = '';
|
|
1126
1126
|
var _cancel, _close;
|
|
1127
1127
|
var warningRxp = /^Warning: /;
|
|
1128
|
-
var el = El('div').appendTo('body').addClass('
|
|
1129
|
-
var infoBox = El('div').appendTo(el).addClass('
|
|
1128
|
+
var el = El('div').appendTo('body').addClass('alert-wrapper');
|
|
1129
|
+
var infoBox = El('div').appendTo(el).addClass('alert-box info-box selectable');
|
|
1130
|
+
El('div').appendTo(infoBox).addClass('close2-btn').on('click', function() {
|
|
1131
|
+
if (_cancel) _cancel();
|
|
1132
|
+
self.close();
|
|
1133
|
+
});
|
|
1134
|
+
var container = El('div').appendTo(infoBox);
|
|
1130
1135
|
if (!title && warningRxp.test(msg)) {
|
|
1131
1136
|
title = 'Warning';
|
|
1132
1137
|
msg = msg.replace(warningRxp, '');
|
|
1133
1138
|
}
|
|
1134
1139
|
if (title) {
|
|
1135
|
-
|
|
1140
|
+
El('div').addClass('alert-title').text(title).appendTo(container);
|
|
1136
1141
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1142
|
+
var content = El('div').appendTo(infoBox);
|
|
1143
|
+
if (msg) {
|
|
1144
|
+
content.html(`<p class="error-message">${msg}</p>`);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
self.container = function() { return content; };
|
|
1143
1148
|
|
|
1144
1149
|
self.onCancel = function(cb) {
|
|
1145
1150
|
_cancel = cb;
|
|
@@ -4023,10 +4028,10 @@
|
|
|
4023
4028
|
|
|
4024
4029
|
function render() {
|
|
4025
4030
|
renderLayerList();
|
|
4026
|
-
|
|
4031
|
+
renderSourceFileList();
|
|
4027
4032
|
}
|
|
4028
4033
|
|
|
4029
|
-
function
|
|
4034
|
+
function renderSourceFileList() {
|
|
4030
4035
|
var list = el.findChild('.file-list');
|
|
4031
4036
|
var files = [];
|
|
4032
4037
|
list.empty();
|
|
@@ -5064,6 +5069,26 @@
|
|
|
5064
5069
|
_stop = stop;
|
|
5065
5070
|
}
|
|
5066
5071
|
|
|
5072
|
+
// get detailed error information from error stack (if available)
|
|
5073
|
+
// Example stack string (Node.js):
|
|
5074
|
+
/*
|
|
5075
|
+
/Users/someuser/somescript.js:226
|
|
5076
|
+
opacity: Math.round(weight * 5 / 5 // 0.2 0.4 0.6 etc
|
|
5077
|
+
^
|
|
5078
|
+
|
|
5079
|
+
SyntaxError: missing ) after argument list
|
|
5080
|
+
at internalCompileFunction (node:internal/vm:73:18)
|
|
5081
|
+
at wrapSafe (node:internal/modules/cjs/loader:1149:20)
|
|
5082
|
+
at Module._compile (node:internal/modules/cjs/loader:1190:27)
|
|
5083
|
+
...
|
|
5084
|
+
*/
|
|
5085
|
+
function getErrorDetail(e) {
|
|
5086
|
+
var parts = (typeof e.stack == 'string') ? e.stack.split(/\n\s*\n/) : [];
|
|
5087
|
+
if (parts.length > 1 || true) {
|
|
5088
|
+
return '\nError details:\n' + parts[0];
|
|
5089
|
+
}
|
|
5090
|
+
return '';
|
|
5091
|
+
}
|
|
5067
5092
|
|
|
5068
5093
|
// print a message to stdout
|
|
5069
5094
|
function print() {
|
|
@@ -7993,8 +8018,7 @@
|
|
|
7993
8018
|
// stash a function for refreshing the current popup when data changes
|
|
7994
8019
|
// while the popup is being displayed (e.g. while dragging a label)
|
|
7995
8020
|
refresh = function() {
|
|
7996
|
-
|
|
7997
|
-
render(content, rec, table, editable);
|
|
8021
|
+
render(content, id, table, editable);
|
|
7998
8022
|
};
|
|
7999
8023
|
refresh();
|
|
8000
8024
|
if (ids && ids.length > 1) {
|
|
@@ -8033,7 +8057,8 @@
|
|
|
8033
8057
|
tab.show();
|
|
8034
8058
|
}
|
|
8035
8059
|
|
|
8036
|
-
function render(el,
|
|
8060
|
+
function render(el, recId, table, editable) {
|
|
8061
|
+
var rec = table && (editable ? table.getRecordAt(recId) : table.getReadOnlyRecordAt(recId)) || {};
|
|
8037
8062
|
var tableEl = El('table').addClass('selectable'),
|
|
8038
8063
|
rows = 0;
|
|
8039
8064
|
// self.hide(); // clean up if panel is already open
|
|
@@ -8048,11 +8073,6 @@
|
|
|
8048
8073
|
}
|
|
8049
8074
|
});
|
|
8050
8075
|
|
|
8051
|
-
// add new field form
|
|
8052
|
-
if (editable) {
|
|
8053
|
-
renderNewRow(tableEl, rec, table);
|
|
8054
|
-
}
|
|
8055
|
-
|
|
8056
8076
|
tableEl.appendTo(el);
|
|
8057
8077
|
if (rows > 0) {
|
|
8058
8078
|
// tableEl.appendTo(el);
|
|
@@ -8077,15 +8097,58 @@
|
|
|
8077
8097
|
}
|
|
8078
8098
|
|
|
8079
8099
|
if (editable) {
|
|
8100
|
+
// render "add field" button
|
|
8080
8101
|
var line = El('div').appendTo(el);
|
|
8081
8102
|
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
8103
|
+
// show "add field" dialog
|
|
8104
|
+
renderAddFieldPopup(recId, table);
|
|
8105
|
+
}).text('+ add field');
|
|
8106
|
+
}
|
|
8107
|
+
}
|
|
8108
|
+
|
|
8109
|
+
function renderAddFieldPopup(recId, table) {
|
|
8110
|
+
var popup = showPopupAlert('', 'Add field');
|
|
8111
|
+
var el = popup.container();
|
|
8112
|
+
el.addClass('option-menu');
|
|
8113
|
+
var html = `<input type="text" class="field-name text-input" placeholder="field name"><br>
|
|
8114
|
+
<input type="text" class="field-value text-input" placeholder="value"><br>
|
|
8115
|
+
<div class="btn dialog-btn">Apply</div> <span class="inline-checkbox"><input type="checkbox" class="all" />assign value to all records</span>`;
|
|
8116
|
+
el.html(html);
|
|
8117
|
+
|
|
8118
|
+
var name = el.findChild('.field-name');
|
|
8119
|
+
name.node().focus();
|
|
8120
|
+
var val = el.findChild('.field-value');
|
|
8121
|
+
var box = el.findChild('.all');
|
|
8122
|
+
var btn = el.findChild('.btn').on('click', function() {
|
|
8123
|
+
var all = box.node().checked;
|
|
8124
|
+
var nameStr = name.node().value.trim();
|
|
8125
|
+
if (!nameStr) return;
|
|
8126
|
+
if (table.fieldExists(nameStr)) {
|
|
8127
|
+
name.node().value = '';
|
|
8128
|
+
return;
|
|
8129
|
+
}
|
|
8130
|
+
var valStr = val.node().value.trim();
|
|
8131
|
+
var value = parseUnknownType(valStr);
|
|
8132
|
+
// table.addField(nameStr, function(d) {
|
|
8133
|
+
// // parse each time to avoid multiple references to objects
|
|
8134
|
+
// return (all || d == rec) ? parseUnknownType(valStr) : null;
|
|
8135
|
+
// });
|
|
8082
8136
|
|
|
8083
|
-
}
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8137
|
+
var cmdStr = `-each "d['${nameStr}'] = `;
|
|
8138
|
+
if (!all) {
|
|
8139
|
+
cmdStr += `this.id != ${recId} ? null : `;
|
|
8140
|
+
}
|
|
8141
|
+
valStr = JSON.stringify(JSON.stringify(value));
|
|
8142
|
+
cmdStr = valStr.replace('"', cmdStr);
|
|
8088
8143
|
|
|
8144
|
+
gui.console.runMapshaperCommands(cmdStr, function(err) {
|
|
8145
|
+
if (!err) {
|
|
8146
|
+
popup.close();
|
|
8147
|
+
} else {
|
|
8148
|
+
console.error(err);
|
|
8149
|
+
}
|
|
8150
|
+
});
|
|
8151
|
+
});
|
|
8089
8152
|
}
|
|
8090
8153
|
|
|
8091
8154
|
function renderRow(table, rec, key, type, editable) {
|
|
@@ -8121,12 +8184,10 @@
|
|
|
8121
8184
|
input.on('change', function(e) {
|
|
8122
8185
|
var val2 = parser(input.value()),
|
|
8123
8186
|
strval2 = formatInspectorValue(val2, type);
|
|
8124
|
-
if (
|
|
8125
|
-
// contents unchanged
|
|
8126
|
-
} else if (val2 === null && type != 'object') { // allow null objects
|
|
8187
|
+
if (val2 === null && type != 'object') { // allow null objects
|
|
8127
8188
|
// invalid value; revert to previous value
|
|
8128
8189
|
input.value(strval);
|
|
8129
|
-
} else {
|
|
8190
|
+
} else if (strval != strval2) {
|
|
8130
8191
|
// field content has changed
|
|
8131
8192
|
strval = strval2;
|
|
8132
8193
|
gui.dispatchEvent('data_preupdate', {FID: currId}); // for undo/redo
|
|
@@ -8191,6 +8252,14 @@
|
|
|
8191
8252
|
}
|
|
8192
8253
|
};
|
|
8193
8254
|
|
|
8255
|
+
function parseUnknownType(str) {
|
|
8256
|
+
var val = inputParsers.number(str);
|
|
8257
|
+
if (val !== null) return val;
|
|
8258
|
+
val = inputParsers.object(str);
|
|
8259
|
+
if (val !== null) return val;
|
|
8260
|
+
return str;
|
|
8261
|
+
}
|
|
8262
|
+
|
|
8194
8263
|
function getInputParser(type) {
|
|
8195
8264
|
return inputParsers[type || 'multiple'];
|
|
8196
8265
|
}
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.42";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1267,6 +1267,26 @@
|
|
|
1267
1267
|
_stop = stop;
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
|
+
// get detailed error information from error stack (if available)
|
|
1271
|
+
// Example stack string (Node.js):
|
|
1272
|
+
/*
|
|
1273
|
+
/Users/someuser/somescript.js:226
|
|
1274
|
+
opacity: Math.round(weight * 5 / 5 // 0.2 0.4 0.6 etc
|
|
1275
|
+
^
|
|
1276
|
+
|
|
1277
|
+
SyntaxError: missing ) after argument list
|
|
1278
|
+
at internalCompileFunction (node:internal/vm:73:18)
|
|
1279
|
+
at wrapSafe (node:internal/modules/cjs/loader:1149:20)
|
|
1280
|
+
at Module._compile (node:internal/modules/cjs/loader:1190:27)
|
|
1281
|
+
...
|
|
1282
|
+
*/
|
|
1283
|
+
function getErrorDetail(e) {
|
|
1284
|
+
var parts = (typeof e.stack == 'string') ? e.stack.split(/\n\s*\n/) : [];
|
|
1285
|
+
if (parts.length > 1 || true) {
|
|
1286
|
+
return '\nError details:\n' + parts[0];
|
|
1287
|
+
}
|
|
1288
|
+
return '';
|
|
1289
|
+
}
|
|
1270
1290
|
|
|
1271
1291
|
// print a message to stdout
|
|
1272
1292
|
function print() {
|
|
@@ -1389,6 +1409,7 @@
|
|
|
1389
1409
|
interrupt: interrupt,
|
|
1390
1410
|
message: message,
|
|
1391
1411
|
setLoggingFunctions: setLoggingFunctions,
|
|
1412
|
+
getErrorDetail: getErrorDetail,
|
|
1392
1413
|
print: print,
|
|
1393
1414
|
verbose: verbose,
|
|
1394
1415
|
debug: debug,
|
|
@@ -6359,9 +6380,10 @@
|
|
|
6359
6380
|
function mergeDatasets(arr) {
|
|
6360
6381
|
var arcSources = [],
|
|
6361
6382
|
arcCount = 0,
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6383
|
+
merged = {
|
|
6384
|
+
info: {},
|
|
6385
|
+
layers: []
|
|
6386
|
+
};
|
|
6365
6387
|
|
|
6366
6388
|
// Error if incompatible CRS
|
|
6367
6389
|
requireDatasetsHaveCompatibleCRS(arr);
|
|
@@ -6372,38 +6394,35 @@
|
|
|
6372
6394
|
arcSources.push(dataset.arcs);
|
|
6373
6395
|
}
|
|
6374
6396
|
|
|
6375
|
-
mergeDatasetInfo(
|
|
6397
|
+
mergeDatasetInfo$1(merged, dataset);
|
|
6376
6398
|
dataset.layers.forEach(function(lyr) {
|
|
6377
6399
|
if (lyr.geometry_type == 'polygon' || lyr.geometry_type == 'polyline') {
|
|
6378
6400
|
forEachArcId(lyr.shapes, function(id) {
|
|
6379
6401
|
return id < 0 ? id - arcCount : id + arcCount;
|
|
6380
6402
|
});
|
|
6381
6403
|
}
|
|
6382
|
-
|
|
6404
|
+
merged.layers.push(lyr);
|
|
6383
6405
|
});
|
|
6384
6406
|
arcCount += n;
|
|
6385
6407
|
});
|
|
6386
6408
|
|
|
6387
6409
|
if (arcSources.length > 0) {
|
|
6388
|
-
|
|
6389
|
-
if (
|
|
6410
|
+
merged.arcs = mergeArcs(arcSources);
|
|
6411
|
+
if (merged.arcs.size() != arcCount) {
|
|
6390
6412
|
error("[mergeDatasets()] Arc indexing error");
|
|
6391
6413
|
}
|
|
6392
6414
|
}
|
|
6393
6415
|
|
|
6394
|
-
return
|
|
6395
|
-
info: mergedInfo,
|
|
6396
|
-
arcs: mergedArcs,
|
|
6397
|
-
layers: mergedLayers
|
|
6398
|
-
};
|
|
6416
|
+
return merged;
|
|
6399
6417
|
}
|
|
6400
6418
|
|
|
6401
|
-
function mergeDatasetInfo(merged, dataset) {
|
|
6402
|
-
var
|
|
6403
|
-
|
|
6404
|
-
|
|
6419
|
+
function mergeDatasetInfo$1(merged, dataset) {
|
|
6420
|
+
var src = dataset.info || {};
|
|
6421
|
+
var dest = merged.info || (merged.info = {});
|
|
6422
|
+
dest.input_files = utils.uniq((dest.input_files || []).concat(src.input_files || []));
|
|
6423
|
+
dest.input_formats = utils.uniq((dest.input_formats || []).concat(src.input_formats || []));
|
|
6405
6424
|
// merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
|
|
6406
|
-
utils.defaults(
|
|
6425
|
+
utils.defaults(dest, src);
|
|
6407
6426
|
}
|
|
6408
6427
|
|
|
6409
6428
|
function mergeArcs(arr) {
|
|
@@ -6450,6 +6469,7 @@
|
|
|
6450
6469
|
mergeDatasetsForExport: mergeDatasetsForExport,
|
|
6451
6470
|
mergeCommandTargets: mergeCommandTargets,
|
|
6452
6471
|
mergeDatasets: mergeDatasets,
|
|
6472
|
+
mergeDatasetInfo: mergeDatasetInfo$1,
|
|
6453
6473
|
mergeArcs: mergeArcs
|
|
6454
6474
|
});
|
|
6455
6475
|
|
|
@@ -6900,6 +6920,18 @@
|
|
|
6900
6920
|
});
|
|
6901
6921
|
}
|
|
6902
6922
|
|
|
6923
|
+
// dest: destination dataset
|
|
6924
|
+
// src: source dataset
|
|
6925
|
+
function mergeDatasetInfo(dest, src) {
|
|
6926
|
+
var srcInfo = src.info || {};
|
|
6927
|
+
var destInfo = dest.info || (dest.info = {});
|
|
6928
|
+
destInfo.input_files = utils.uniq((destInfo.input_files || []).concat(srcInfo.input_files || []));
|
|
6929
|
+
destInfo.input_formats = utils.uniq((destInfo.input_formats || []).concat(srcInfo.input_formats || []));
|
|
6930
|
+
// merge other info properties (e.g. input_geojson_crs, input_delimiter, prj, crs)
|
|
6931
|
+
utils.defaults(destInfo, srcInfo);
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
|
|
6903
6935
|
function splitApartLayers(dataset, layers) {
|
|
6904
6936
|
var datasets = [];
|
|
6905
6937
|
dataset.layers = dataset.layers.filter(function(lyr) {
|
|
@@ -7064,6 +7096,7 @@
|
|
|
7064
7096
|
var DatasetUtils = /*#__PURE__*/Object.freeze({
|
|
7065
7097
|
__proto__: null,
|
|
7066
7098
|
splitDataset: splitDataset,
|
|
7099
|
+
mergeDatasetInfo: mergeDatasetInfo,
|
|
7067
7100
|
splitApartLayers: splitApartLayers,
|
|
7068
7101
|
copyDataset: copyDataset,
|
|
7069
7102
|
copyDatasetForExport: copyDatasetForExport,
|
|
@@ -11205,20 +11238,43 @@
|
|
|
11205
11238
|
return dest;
|
|
11206
11239
|
};
|
|
11207
11240
|
|
|
11241
|
+
// Receives a directory path, in which the final subdirectory may include the
|
|
11242
|
+
// "*" wildcard, e.g. '.' 'data' '*' 'data/*' '2023-*'
|
|
11243
|
+
// Returns an array of expanded directory names
|
|
11244
|
+
// TODO: add support for wildcards in other subdirectories
|
|
11245
|
+
cli.expandDirectoryName = function(name) {
|
|
11246
|
+
var info = parseLocalPath(name);
|
|
11247
|
+
// final directory name is parsed as info.filename
|
|
11248
|
+
if (!info.filename.includes('*')) {
|
|
11249
|
+
return [name];
|
|
11250
|
+
}
|
|
11251
|
+
var rxp = utils.wildcardToRegExp(info.filename);
|
|
11252
|
+
var dirs = [];
|
|
11253
|
+
require$1('fs').readdirSync(info.directory || '.').forEach(function(item) {
|
|
11254
|
+
var path = info.directory ? require$1('path').join(info.directory, item) : item;
|
|
11255
|
+
if (rxp.test(item) && cli.isDirectory(path)) {
|
|
11256
|
+
dirs.push(path);
|
|
11257
|
+
}
|
|
11258
|
+
});
|
|
11259
|
+
return dirs;
|
|
11260
|
+
};
|
|
11261
|
+
|
|
11208
11262
|
// Expand any "*" wild cards in file name
|
|
11209
11263
|
// (For the Windows command line; unix shells do this automatically)
|
|
11210
11264
|
cli.expandFileName = function(name) {
|
|
11211
11265
|
var info = parseLocalPath(name),
|
|
11212
11266
|
rxp = utils.wildcardToRegExp(info.filename),
|
|
11213
|
-
|
|
11267
|
+
dirs = cli.expandDirectoryName(info.directory || '.'),
|
|
11214
11268
|
files = [];
|
|
11215
11269
|
|
|
11216
11270
|
try {
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11271
|
+
dirs.forEach(function(dir) {
|
|
11272
|
+
require$1('fs').readdirSync(dir).forEach(function(item) {
|
|
11273
|
+
var path = require$1('path').join(dir, item);
|
|
11274
|
+
if (rxp.test(item) && cli.isFile(path)) {
|
|
11275
|
+
files.push(path);
|
|
11276
|
+
}
|
|
11277
|
+
});
|
|
11222
11278
|
});
|
|
11223
11279
|
} catch(e) {}
|
|
11224
11280
|
|
|
@@ -28239,20 +28295,23 @@ ${svg}
|
|
|
28239
28295
|
};
|
|
28240
28296
|
|
|
28241
28297
|
this.setDefaultTarget = function(layers, dataset) {
|
|
28242
|
-
|
|
28243
|
-
datasets.push(dataset);
|
|
28244
|
-
}
|
|
28245
|
-
defaultTargets = [{
|
|
28298
|
+
this.setDefaultTargets([{
|
|
28246
28299
|
// Copy layers array, in case layers is a reference to dataset.layers.
|
|
28247
28300
|
// This prevents layers that are added to the dataset inside a command from
|
|
28248
28301
|
// being added to the next command's target, e.g. debugging layers added
|
|
28249
28302
|
// by '-join unmatched unjoined'.
|
|
28250
28303
|
layers: layers.concat(),
|
|
28251
28304
|
dataset: dataset
|
|
28252
|
-
}];
|
|
28305
|
+
}]);
|
|
28253
28306
|
};
|
|
28254
28307
|
|
|
28308
|
+
// arr: array of target objects {layers:[], dataset:{}}
|
|
28255
28309
|
this.setDefaultTargets = function(arr) {
|
|
28310
|
+
arr.forEach(function(target) {
|
|
28311
|
+
if (datasets.indexOf(target.dataset) == -1) {
|
|
28312
|
+
datasets.push(target.dataset);
|
|
28313
|
+
}
|
|
28314
|
+
});
|
|
28256
28315
|
defaultTargets = arr;
|
|
28257
28316
|
};
|
|
28258
28317
|
|
|
@@ -28345,6 +28404,30 @@ ${svg}
|
|
|
28345
28404
|
stashVar('input_files', job.input_files);
|
|
28346
28405
|
}
|
|
28347
28406
|
|
|
28407
|
+
// Apply a command to an array of target layers
|
|
28408
|
+
function applyCommandToEachLayer(func, targetLayers) {
|
|
28409
|
+
var args = utils.toArray(arguments).slice(2);
|
|
28410
|
+
return targetLayers.reduce(function(memo, lyr) {
|
|
28411
|
+
var result = func.apply(null, [lyr].concat(args));
|
|
28412
|
+
if (utils.isArray(result)) { // some commands return an array of layers
|
|
28413
|
+
memo = memo.concat(result);
|
|
28414
|
+
} else if (result) { // assuming result is a layer
|
|
28415
|
+
memo.push(result);
|
|
28416
|
+
}
|
|
28417
|
+
return memo;
|
|
28418
|
+
}, []);
|
|
28419
|
+
}
|
|
28420
|
+
|
|
28421
|
+
function applyCommandToEachTarget(func, targets) {
|
|
28422
|
+
var args = utils.toArray(arguments).slice(2);
|
|
28423
|
+
targets.forEach(function(target) {
|
|
28424
|
+
var result = func.apply(null, [target].concat(args));
|
|
28425
|
+
if (result) {
|
|
28426
|
+
error('Unexpected output from command');
|
|
28427
|
+
}
|
|
28428
|
+
});
|
|
28429
|
+
}
|
|
28430
|
+
|
|
28348
28431
|
cmd.addShape = addShape;
|
|
28349
28432
|
|
|
28350
28433
|
function addShape(targetLayers, targetDataset, opts) {
|
|
@@ -36290,6 +36373,7 @@ ${svg}
|
|
|
36290
36373
|
var opts = parseExternalCommand(name, cmdDefn, cmdOpts._);
|
|
36291
36374
|
var targets = catalog.findCommandTargets(opts.target || '*');
|
|
36292
36375
|
var target = targets[0];
|
|
36376
|
+
var output;
|
|
36293
36377
|
if (!target) {
|
|
36294
36378
|
stop('Missing a target');
|
|
36295
36379
|
}
|
|
@@ -36300,12 +36384,34 @@ ${svg}
|
|
|
36300
36384
|
stop("Targetting layers from multiple datasets is not supported");
|
|
36301
36385
|
}
|
|
36302
36386
|
if (targetType == 'layer') {
|
|
36303
|
-
cmdDefn.command(target.layers[0], target.dataset, opts.options);
|
|
36387
|
+
output = cmdDefn.command(target.layers[0], target.dataset, opts.options);
|
|
36304
36388
|
} else if (targetType == 'layers') {
|
|
36305
|
-
cmdDefn.command(target.layers, target.dataset, opts.options);
|
|
36389
|
+
output = cmdDefn.command(target.layers, target.dataset, opts.options);
|
|
36390
|
+
}
|
|
36391
|
+
if (output) {
|
|
36392
|
+
integrateOutput(output, target, catalog, opts);
|
|
36306
36393
|
}
|
|
36307
36394
|
};
|
|
36308
36395
|
|
|
36396
|
+
// TODO: remove restrictions on output data
|
|
36397
|
+
function integrateOutput(output, input, catalog, opts) {
|
|
36398
|
+
if (!output.dataset || !output.layers || output.layers.length > 0 === false) {
|
|
36399
|
+
stop('Invalid command output');
|
|
36400
|
+
}
|
|
36401
|
+
if (output.dataset == input.dataset) {
|
|
36402
|
+
stop('External commands are not currently allowed to modify input datasets');
|
|
36403
|
+
}
|
|
36404
|
+
if (output.dataset.layers.length != output.layers.length) {
|
|
36405
|
+
stop('Currently not supported: targetting a subset of output layers');
|
|
36406
|
+
}
|
|
36407
|
+
if (!opts.no_replace) {
|
|
36408
|
+
input.layers.forEach(function(lyr) {
|
|
36409
|
+
catalog.deleteLayer(lyr, input.dataset);
|
|
36410
|
+
});
|
|
36411
|
+
}
|
|
36412
|
+
catalog.addDataset(output.dataset);
|
|
36413
|
+
}
|
|
36414
|
+
|
|
36309
36415
|
function parseExternalCommand(name, cmdDefn, tokens) {
|
|
36310
36416
|
var parser = new CommandParser();
|
|
36311
36417
|
var cmd = parser.command(name);
|
|
@@ -40720,7 +40826,8 @@ ${svg}
|
|
|
40720
40826
|
function makeCircleCoords(center, opts) {
|
|
40721
40827
|
var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
|
|
40722
40828
|
var radius = opts.interval / 2 * (1 - margin);
|
|
40723
|
-
|
|
40829
|
+
var vertices = opts.vertices || 20;
|
|
40830
|
+
return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
|
|
40724
40831
|
}
|
|
40725
40832
|
|
|
40726
40833
|
// Returns a function that receives a cell index and returns indices of points
|
|
@@ -40731,12 +40838,15 @@ ${svg}
|
|
|
40731
40838
|
var bboxIndex = new Flatbush(points.length);
|
|
40732
40839
|
var empty = [];
|
|
40733
40840
|
points.forEach(function(p) {
|
|
40841
|
+
var bbox = getPointBounds(p, radius);
|
|
40734
40842
|
addPointToGridIndex(p, gridIndex, grid);
|
|
40735
|
-
bboxIndex.add.apply(bboxIndex,
|
|
40843
|
+
bboxIndex.add.apply(bboxIndex, bbox);
|
|
40736
40844
|
});
|
|
40737
40845
|
bboxIndex.finish();
|
|
40738
40846
|
return function(i) {
|
|
40739
|
-
if (!gridIndex.hasId(i))
|
|
40847
|
+
if (!gridIndex.hasId(i)) {
|
|
40848
|
+
return empty;
|
|
40849
|
+
}
|
|
40740
40850
|
var bbox = grid.idxToBBox(i);
|
|
40741
40851
|
var indices = bboxIndex.search.apply(bboxIndex, bbox);
|
|
40742
40852
|
return indices;
|
|
@@ -40870,6 +40980,7 @@ ${svg}
|
|
|
40870
40980
|
calcWeights: calcWeights,
|
|
40871
40981
|
twoCircleIntersection: twoCircleIntersection,
|
|
40872
40982
|
makeCellPolygon: makeCellPolygon,
|
|
40983
|
+
makeCircleCoords: makeCircleCoords,
|
|
40873
40984
|
getPointIndex: getPointIndex,
|
|
40874
40985
|
getAlignedGridBounds: getAlignedGridBounds,
|
|
40875
40986
|
getCenteredGridBounds: getCenteredGridBounds,
|
|
@@ -41198,8 +41309,7 @@ ${svg}
|
|
|
41198
41309
|
}
|
|
41199
41310
|
}
|
|
41200
41311
|
} catch(e) {
|
|
41201
|
-
|
|
41202
|
-
stop('Unable to load external module:', e.message);
|
|
41312
|
+
stop('Unable to load external module:', e.message, getErrorDetail(e));
|
|
41203
41313
|
}
|
|
41204
41314
|
if (moduleName || opts.alias) {
|
|
41205
41315
|
defs[opts.alias || moduleName] = mod;
|
|
@@ -42230,9 +42340,10 @@ ${svg}
|
|
|
42230
42340
|
}
|
|
42231
42341
|
};
|
|
42232
42342
|
|
|
42233
|
-
cmd.snap = function(
|
|
42343
|
+
cmd.snap = function(target, opts) {
|
|
42234
42344
|
var interval = 0;
|
|
42235
42345
|
var snapCount = 0;
|
|
42346
|
+
var dataset = target.dataset;
|
|
42236
42347
|
var arcs = dataset.arcs;
|
|
42237
42348
|
var arcBounds = arcs && arcs.getBounds();
|
|
42238
42349
|
if (!arcBounds || !arcBounds.hasBounds()) {
|
|
@@ -43367,7 +43478,7 @@ ${svg}
|
|
|
43367
43478
|
function commandAcceptsMultipleTargetDatasets(name) {
|
|
43368
43479
|
return name == 'rotate' || name == 'info' || name == 'proj' || name == 'require' ||
|
|
43369
43480
|
name == 'drop' || name == 'target' || name == 'if' || name == 'elif' ||
|
|
43370
|
-
name == 'else' || name == 'endif' || name == 'run' || name == 'i';
|
|
43481
|
+
name == 'else' || name == 'endif' || name == 'run' || name == 'i' || name == 'snap';
|
|
43371
43482
|
}
|
|
43372
43483
|
|
|
43373
43484
|
function commandAcceptsEmptyTarget(name) {
|
|
@@ -43449,6 +43560,10 @@ ${svg}
|
|
|
43449
43560
|
source = findCommandSource(convertSourceName(opts.source, targets), job.catalog, opts);
|
|
43450
43561
|
}
|
|
43451
43562
|
|
|
43563
|
+
// identify command target/input (for postprocessing)
|
|
43564
|
+
// TODO: support commands with multiple target datasets
|
|
43565
|
+
// target = name == 'i' ? null : targets[0];
|
|
43566
|
+
|
|
43452
43567
|
if (name == 'add-shape') {
|
|
43453
43568
|
if (!targetDataset) {
|
|
43454
43569
|
targetDataset = {info: {}, layers: []};
|
|
@@ -43556,6 +43671,9 @@ ${svg}
|
|
|
43556
43671
|
} else if (name == 'graticule') {
|
|
43557
43672
|
job.catalog.addDataset(cmd.graticule(targetDataset, opts));
|
|
43558
43673
|
|
|
43674
|
+
} else if (name == 'grid') {
|
|
43675
|
+
outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
|
|
43676
|
+
|
|
43559
43677
|
} else if (name == 'help') {
|
|
43560
43678
|
// placing help command here to handle errors from invalid command names
|
|
43561
43679
|
cmd.printHelp(command.options);
|
|
@@ -43627,9 +43745,6 @@ ${svg}
|
|
|
43627
43745
|
} else if (name == 'point-to-grid') {
|
|
43628
43746
|
outputLayers = cmd.pointToGrid(targetLayers, targetDataset, opts);
|
|
43629
43747
|
|
|
43630
|
-
} else if (name == 'grid') {
|
|
43631
|
-
outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
|
|
43632
|
-
|
|
43633
43748
|
} else if (name == 'points') {
|
|
43634
43749
|
outputLayers = applyCommandToEachLayer(cmd.createPointLayer, targetLayers, targetDataset, opts);
|
|
43635
43750
|
|
|
@@ -43693,7 +43808,8 @@ ${svg}
|
|
|
43693
43808
|
outputLayers = cmd.sliceLayers(targetLayers, source, targetDataset, opts);
|
|
43694
43809
|
|
|
43695
43810
|
} else if (name == 'snap') {
|
|
43696
|
-
cmd.snap(targetDataset, opts);
|
|
43811
|
+
// cmd.snap(targetDataset, opts);
|
|
43812
|
+
applyCommandToEachTarget(targets, opts);
|
|
43697
43813
|
|
|
43698
43814
|
} else if (name == 'sort') {
|
|
43699
43815
|
applyCommandToEachLayer(cmd.sortFeatures, targetLayers, arcs, opts);
|
|
@@ -43784,9 +43900,12 @@ ${svg}
|
|
|
43784
43900
|
|
|
43785
43901
|
// delete arcs if no longer needed (e.g. after -points command)
|
|
43786
43902
|
// (after output layers have been integrated)
|
|
43903
|
+
// TODO: be more selective (e.g. -i command doesn't need cleanup)
|
|
43904
|
+
// or: detect if arcs have been changed
|
|
43787
43905
|
if (targetDataset) {
|
|
43788
43906
|
cleanupArcs(targetDataset);
|
|
43789
43907
|
}
|
|
43908
|
+
|
|
43790
43909
|
} catch(e) {
|
|
43791
43910
|
return done(e);
|
|
43792
43911
|
}
|
|
@@ -43808,20 +43927,6 @@ ${svg}
|
|
|
43808
43927
|
});
|
|
43809
43928
|
}
|
|
43810
43929
|
|
|
43811
|
-
// Apply a command to an array of target layers
|
|
43812
|
-
function applyCommandToEachLayer(func, targetLayers) {
|
|
43813
|
-
var args = utils.toArray(arguments).slice(2);
|
|
43814
|
-
return targetLayers.reduce(function(memo, lyr) {
|
|
43815
|
-
var result = func.apply(null, [lyr].concat(args));
|
|
43816
|
-
if (utils.isArray(result)) { // some commands return an array of layers
|
|
43817
|
-
memo = memo.concat(result);
|
|
43818
|
-
} else if (result) { // assuming result is a layer
|
|
43819
|
-
memo.push(result);
|
|
43820
|
-
}
|
|
43821
|
-
return memo;
|
|
43822
|
-
}, []);
|
|
43823
|
-
}
|
|
43824
|
-
|
|
43825
43930
|
// Parse command line args into commands and run them
|
|
43826
43931
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
43827
43932
|
// function(argv[, input], callback)
|
|
@@ -44465,6 +44570,7 @@ ${svg}
|
|
|
44465
44570
|
editArcs,
|
|
44466
44571
|
GeoJSONReader,
|
|
44467
44572
|
Heap,
|
|
44573
|
+
IdLookupIndex,
|
|
44468
44574
|
NodeCollection,
|
|
44469
44575
|
parseDMS,
|
|
44470
44576
|
formatDMS,
|
package/www/page.css
CHANGED
|
@@ -256,7 +256,7 @@ body {
|
|
|
256
256
|
|
|
257
257
|
/* --- Error message ---------- */
|
|
258
258
|
|
|
259
|
-
.
|
|
259
|
+
.alert-wrapper {
|
|
260
260
|
z-index: 120;
|
|
261
261
|
text-align: center;
|
|
262
262
|
position: absolute;
|
|
@@ -266,29 +266,33 @@ body {
|
|
|
266
266
|
left: 0;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
.
|
|
269
|
+
.alert-wrapper p.error-message {
|
|
270
270
|
margin: 1px 0 0 0;
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
-
.
|
|
274
|
-
margin-top: 8px;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.error-title {
|
|
273
|
+
.alert-title {
|
|
278
274
|
line-height: 1.1;
|
|
279
275
|
font-weight: bold;
|
|
280
276
|
margin-bottom: 5px;
|
|
281
277
|
}
|
|
282
278
|
|
|
283
|
-
div.error-
|
|
279
|
+
div.alert-title, div.error-message {
|
|
280
|
+
font-size: 16px;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.alert-wrapper .alert-btn {
|
|
284
|
+
margin-top: 8px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
div.alert-box {
|
|
284
288
|
margin-top: 42px; /* 55px; */
|
|
285
289
|
overflow: auto;
|
|
286
290
|
max-height: 70%;
|
|
287
291
|
max-width: 400px;
|
|
288
|
-
font-size: 16px;
|
|
289
292
|
}
|
|
290
293
|
|
|
291
294
|
|
|
295
|
+
|
|
292
296
|
/* --- Splash screen -------------- */
|
|
293
297
|
|
|
294
298
|
.splash-screen #splash-screen {
|
|
@@ -513,7 +517,7 @@ body.dragover #import-options-drop-area .drop-area {
|
|
|
513
517
|
text-align: left;
|
|
514
518
|
margin-top: 12px;
|
|
515
519
|
margin-right: 20px;
|
|
516
|
-
padding:
|
|
520
|
+
padding: 11px 16px 12px 18px;
|
|
517
521
|
vertical-align: top;
|
|
518
522
|
display: inline-block;
|
|
519
523
|
/* border: 1px solid #aaa; */
|
|
@@ -553,6 +557,7 @@ body.dragover #import-options-drop-area .drop-area {
|
|
|
553
557
|
top: 1px;
|
|
554
558
|
width: 12px;
|
|
555
559
|
height: 12px;
|
|
560
|
+
cursor: pointer;
|
|
556
561
|
}
|
|
557
562
|
|
|
558
563
|
.info-box .tip-button {
|
|
@@ -800,7 +805,7 @@ img.close-btn {
|
|
|
800
805
|
float: right;
|
|
801
806
|
height: 18px;
|
|
802
807
|
width: 18px;
|
|
803
|
-
margin-top: 1px;
|
|
808
|
+
/* margin-top: 1px; */
|
|
804
809
|
margin-right: -3px;
|
|
805
810
|
cursor: pointer;
|
|
806
811
|
border-radius: 4px;
|
|
@@ -1227,13 +1232,16 @@ div.basemap-style-btn.active img {
|
|
|
1227
1232
|
top: 23px;
|
|
1228
1233
|
}
|
|
1229
1234
|
|
|
1230
|
-
|
|
1231
|
-
display: none;
|
|
1235
|
+
.inline-checkbox {
|
|
1232
1236
|
position: relative;
|
|
1233
1237
|
top: 1px;
|
|
1234
1238
|
left: 5px;
|
|
1235
1239
|
}
|
|
1236
1240
|
|
|
1241
|
+
#save-preference {
|
|
1242
|
+
/* display: none; */
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1237
1245
|
.nav-sub-menu {
|
|
1238
1246
|
position: absolute;
|
|
1239
1247
|
z-index: -1;
|
|
@@ -1316,25 +1324,32 @@ div.basemap-style-btn.active img {
|
|
|
1316
1324
|
background: white;
|
|
1317
1325
|
}
|
|
1318
1326
|
|
|
1319
|
-
|
|
1327
|
+
/*.save-menu-btn {
|
|
1320
1328
|
display: inline-block;
|
|
1321
1329
|
border-radius: 4px;
|
|
1322
1330
|
border: 1px solid #aaa;
|
|
1323
1331
|
font-size: 12px;
|
|
1324
1332
|
margin-left: 2px;
|
|
1325
1333
|
padding: 1px 2px 3px 2px;
|
|
1326
|
-
}
|
|
1334
|
+
}*/
|
|
1327
1335
|
|
|
1328
|
-
.save-menu-link,
|
|
1329
1336
|
.save-menu-btn {
|
|
1330
|
-
|
|
1337
|
+
display: inline-block;
|
|
1338
|
+
font-size: 12px;
|
|
1339
|
+
margin-top: 2px;
|
|
1331
1340
|
}
|
|
1332
1341
|
|
|
1333
1342
|
.save-menu-btn:hover {
|
|
1334
|
-
background: #e6f7ff;
|
|
1335
1343
|
color: black;
|
|
1336
1344
|
}
|
|
1337
1345
|
|
|
1346
|
+
.save-menu-link,
|
|
1347
|
+
.save-menu-btn {
|
|
1348
|
+
cursor: pointer;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1338
1353
|
.save-menu-link:hover {
|
|
1339
1354
|
/* background: #e6f7ff; */
|
|
1340
1355
|
font-weight: bold;
|