mapshaper 0.5.66 → 0.5.70
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/CHANGELOG.md +13 -0
- package/mapshaper.js +139 -42
- package/package.json +3 -2
- package/www/elements.css +1 -1
- package/www/mapshaper-gui.js +18 -3
- package/www/mapshaper.js +139 -42
- package/www/page.css +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
v0.5.70
|
|
2
|
+
* Added -join duplication option, which duplicates features in the target layer when many-to-one joins occur.
|
|
3
|
+
|
|
4
|
+
v0.5.69
|
|
5
|
+
* Added undocumented -ignore command.
|
|
6
|
+
* Bug fix
|
|
7
|
+
|
|
8
|
+
v0.5.68
|
|
9
|
+
* Bug fix
|
|
10
|
+
|
|
11
|
+
v0.5.67
|
|
12
|
+
* Bug fix
|
|
13
|
+
|
|
1
14
|
v0.5.66
|
|
2
15
|
* Improve interactive selection.
|
|
3
16
|
* Added undocumented -define command.
|
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.69";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1167,6 +1167,10 @@
|
|
|
1167
1167
|
throw new UserError(formatLogArgs(arguments));
|
|
1168
1168
|
};
|
|
1169
1169
|
|
|
1170
|
+
var _interrupt = function() {
|
|
1171
|
+
throw new NonFatalError(formatLogArgs(arguments));
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1170
1174
|
var _message = function() {
|
|
1171
1175
|
logArgs(arguments);
|
|
1172
1176
|
};
|
|
@@ -1185,10 +1189,14 @@
|
|
|
1185
1189
|
}
|
|
1186
1190
|
|
|
1187
1191
|
// Handle an error caused by invalid input or misuse of API
|
|
1188
|
-
function stop
|
|
1192
|
+
function stop() {
|
|
1189
1193
|
_stop.apply(null, utils.toArray(arguments));
|
|
1190
1194
|
}
|
|
1191
1195
|
|
|
1196
|
+
function interrupt() {
|
|
1197
|
+
_interrupt.apply(null, utils.toArray(arguments));
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1192
1200
|
// Print a status message
|
|
1193
1201
|
function message() {
|
|
1194
1202
|
_message.apply(null, messageArgs(arguments));
|
|
@@ -1228,7 +1236,9 @@
|
|
|
1228
1236
|
if (utils.isString(err)) {
|
|
1229
1237
|
err = new UserError(err);
|
|
1230
1238
|
}
|
|
1231
|
-
if (err.name == '
|
|
1239
|
+
if (err.name == 'NonFatalError') {
|
|
1240
|
+
console.error(messageArgs([err.message]).join(' '));
|
|
1241
|
+
} else if (err.name == 'UserError') {
|
|
1232
1242
|
msg = err.message;
|
|
1233
1243
|
if (!/Error/.test(msg)) {
|
|
1234
1244
|
msg = "Error: " + msg;
|
|
@@ -1248,6 +1258,12 @@
|
|
|
1248
1258
|
return err;
|
|
1249
1259
|
}
|
|
1250
1260
|
|
|
1261
|
+
function NonFatalError(msg) {
|
|
1262
|
+
var err = new Error(msg);
|
|
1263
|
+
err.name = 'NonFatalError';
|
|
1264
|
+
return err;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1251
1267
|
function formatColumns(arr, alignments) {
|
|
1252
1268
|
var widths = arr.reduce(function(memo, line) {
|
|
1253
1269
|
return line.map(function(str, i) {
|
|
@@ -1308,6 +1324,7 @@
|
|
|
1308
1324
|
loggingEnabled: loggingEnabled,
|
|
1309
1325
|
error: error,
|
|
1310
1326
|
stop: stop,
|
|
1327
|
+
interrupt: interrupt,
|
|
1311
1328
|
message: message,
|
|
1312
1329
|
setLoggingFunctions: setLoggingFunctions,
|
|
1313
1330
|
print: print,
|
|
@@ -1315,6 +1332,7 @@
|
|
|
1315
1332
|
debug: debug,
|
|
1316
1333
|
printError: printError,
|
|
1317
1334
|
UserError: UserError,
|
|
1335
|
+
NonFatalError: NonFatalError,
|
|
1318
1336
|
formatColumns: formatColumns,
|
|
1319
1337
|
formatStringsAsGrid: formatStringsAsGrid,
|
|
1320
1338
|
formatLogArgs: formatLogArgs,
|
|
@@ -14306,7 +14324,7 @@
|
|
|
14306
14324
|
joinStr = obj.tag == 'text' || obj.tag == 'tspan' ? '' : '\n';
|
|
14307
14325
|
svg += '>' + joinStr;
|
|
14308
14326
|
if (obj.value) {
|
|
14309
|
-
svg += obj.value;
|
|
14327
|
+
svg += stringEscape(obj.value);
|
|
14310
14328
|
}
|
|
14311
14329
|
if (obj.children) {
|
|
14312
14330
|
svg += obj.children.map(stringify).join(joinStr);
|
|
@@ -14329,8 +14347,13 @@
|
|
|
14329
14347
|
"'": '''
|
|
14330
14348
|
};
|
|
14331
14349
|
function stringEscape(s) {
|
|
14332
|
-
return String(s).replace(rxp, function(
|
|
14333
|
-
|
|
14350
|
+
return String(s).replace(rxp, function(match, i) {
|
|
14351
|
+
var entity = map[match];
|
|
14352
|
+
// don't replace & with &
|
|
14353
|
+
if (match == '&' && s.substr(i, entity.length) == entity) {
|
|
14354
|
+
return '&';
|
|
14355
|
+
}
|
|
14356
|
+
return entity;
|
|
14334
14357
|
});
|
|
14335
14358
|
}
|
|
14336
14359
|
|
|
@@ -17140,7 +17163,7 @@ ${svg}
|
|
|
17140
17163
|
c = buf[i];
|
|
17141
17164
|
if (c == DQUOTE) {
|
|
17142
17165
|
inQuotedText = !inQuotedText;
|
|
17143
|
-
} else if (c == CR || c == LF) {
|
|
17166
|
+
} else if ((c == CR || c == LF) && !inQuotedText) {
|
|
17144
17167
|
if (c == CR && i + 1 < bufLen && buf[i + 1] == LF) {
|
|
17145
17168
|
// first half of CRLF pair: advance one byte
|
|
17146
17169
|
i++;
|
|
@@ -17234,6 +17257,7 @@ ${svg}
|
|
|
17234
17257
|
getRowConverter: getRowConverter,
|
|
17235
17258
|
parseDelimHeaderSection: parseDelimHeaderSection,
|
|
17236
17259
|
getDelimFieldFilter: getDelimFieldFilter,
|
|
17260
|
+
readLinesAsString: readLinesAsString,
|
|
17237
17261
|
parseDelimText: parseDelimText
|
|
17238
17262
|
});
|
|
17239
17263
|
|
|
@@ -18415,6 +18439,9 @@ ${svg}
|
|
|
18415
18439
|
type: 'strings',
|
|
18416
18440
|
describe: '[CSV] comma-sep. list of fields to import'
|
|
18417
18441
|
})
|
|
18442
|
+
// .option('csv-comment', {
|
|
18443
|
+
// describe: '[CSV] comment line character(s)'
|
|
18444
|
+
// })
|
|
18418
18445
|
.option('decimal-comma', {
|
|
18419
18446
|
type: 'flag',
|
|
18420
18447
|
describe: '[CSV] import numbers formatted like 1.000,01 or 1 000,01'
|
|
@@ -19164,6 +19191,14 @@ ${svg}
|
|
|
19164
19191
|
.option('target', targetOpt)
|
|
19165
19192
|
.option('no-replace', noReplaceOpt);
|
|
19166
19193
|
|
|
19194
|
+
parser.command('ignore')
|
|
19195
|
+
// .describe('stop processing if a condition is met')
|
|
19196
|
+
.option('empty', {
|
|
19197
|
+
describe: 'ignore empty files',
|
|
19198
|
+
type: 'flag'
|
|
19199
|
+
})
|
|
19200
|
+
.option('target', targetOpt);
|
|
19201
|
+
|
|
19167
19202
|
parser.command('inlay')
|
|
19168
19203
|
.describe('inscribe a polygon layer inside another polygon layer')
|
|
19169
19204
|
.option('source', {
|
|
@@ -19235,6 +19270,10 @@ ${svg}
|
|
|
19235
19270
|
// describe: 'use planar geometry when interpolating by area' // useful for testing
|
|
19236
19271
|
type: 'flag'
|
|
19237
19272
|
})
|
|
19273
|
+
.option('duplication', {
|
|
19274
|
+
describe: 'duplicate target features on many-to-one joins',
|
|
19275
|
+
type: 'flag'
|
|
19276
|
+
})
|
|
19238
19277
|
.option('string-fields', stringFieldsOpt)
|
|
19239
19278
|
.option('field-types', fieldTypesOpt)
|
|
19240
19279
|
.option('sum-fields', {
|
|
@@ -29801,13 +29840,19 @@ ${svg}
|
|
|
29801
29840
|
getJoinFilter: getJoinFilter
|
|
29802
29841
|
});
|
|
29803
29842
|
|
|
29843
|
+
function joinTables(dest, src, join, opts) {
|
|
29844
|
+
return joinTableToLayer({data: dest}, src, join, opts);
|
|
29845
|
+
}
|
|
29846
|
+
|
|
29804
29847
|
// Join data from @src table to records in @dest table
|
|
29805
29848
|
// @join function
|
|
29806
29849
|
// Receives index of record in the dest table
|
|
29807
29850
|
// Returns array of matching records in src table, or null if no matches
|
|
29808
29851
|
//
|
|
29809
|
-
function
|
|
29810
|
-
var
|
|
29852
|
+
function joinTableToLayer(destLyr, src, join, opts) {
|
|
29853
|
+
var dest = destLyr.data,
|
|
29854
|
+
useDuplication = !!opts.duplication,
|
|
29855
|
+
srcRecords = src.getRecords(),
|
|
29811
29856
|
destRecords = dest.getRecords(),
|
|
29812
29857
|
prefix = opts.prefix || '',
|
|
29813
29858
|
unmatchedRecords = [],
|
|
@@ -29822,6 +29867,14 @@ ${svg}
|
|
|
29822
29867
|
retn = {},
|
|
29823
29868
|
srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
|
|
29824
29869
|
|
|
29870
|
+
// support for duplication
|
|
29871
|
+
var duplicateRecords, destShapes;
|
|
29872
|
+
if (useDuplication) {
|
|
29873
|
+
if (opts.calc) stop('duplication and calc options cannot be used together');
|
|
29874
|
+
duplicateRecords = dest.clone().getRecords();
|
|
29875
|
+
destShapes = destLyr.shapes || [];
|
|
29876
|
+
}
|
|
29877
|
+
|
|
29825
29878
|
if (opts.where) {
|
|
29826
29879
|
filter = getJoinFilter(src, opts.where);
|
|
29827
29880
|
}
|
|
@@ -29831,7 +29884,8 @@ ${svg}
|
|
|
29831
29884
|
}
|
|
29832
29885
|
|
|
29833
29886
|
// join source records to target records
|
|
29834
|
-
|
|
29887
|
+
n = destRecords.length;
|
|
29888
|
+
for (i=0; i<n; i++) {
|
|
29835
29889
|
destRec = destRecords[i];
|
|
29836
29890
|
joins = join(i);
|
|
29837
29891
|
if (joins && filter) {
|
|
@@ -29842,7 +29896,12 @@ ${svg}
|
|
|
29842
29896
|
for (j=0, count=0, m=joins ? joins.length : 0; j<m; j++) {
|
|
29843
29897
|
srcId = joins[j];
|
|
29844
29898
|
srcRec = srcRecords[srcId];
|
|
29845
|
-
if (count
|
|
29899
|
+
if (count > 0 && useDuplication) {
|
|
29900
|
+
destRec = copyRecord(duplicateRecords[i]);
|
|
29901
|
+
destRecords.push(destRec);
|
|
29902
|
+
destShapes.push(cloneShape(destShapes[i]));
|
|
29903
|
+
}
|
|
29904
|
+
if (count === 0 || useDuplication) {
|
|
29846
29905
|
if (copyFields.length > 0) {
|
|
29847
29906
|
// only copying the first match
|
|
29848
29907
|
joinByCopy(destRec, srcRec, copyFields, prefix);
|
|
@@ -29874,7 +29933,7 @@ ${svg}
|
|
|
29874
29933
|
}
|
|
29875
29934
|
}
|
|
29876
29935
|
|
|
29877
|
-
printJoinMessage(matchCount,
|
|
29936
|
+
printJoinMessage(matchCount, n,
|
|
29878
29937
|
countJoins(joinCounts), srcRecords.length, skipCount, collisionCount, collisionFields);
|
|
29879
29938
|
|
|
29880
29939
|
if (opts.unjoined) {
|
|
@@ -29902,6 +29961,7 @@ ${svg}
|
|
|
29902
29961
|
});
|
|
29903
29962
|
}
|
|
29904
29963
|
|
|
29964
|
+
|
|
29905
29965
|
function countJoins(counts) {
|
|
29906
29966
|
var joinCount = 0;
|
|
29907
29967
|
for (var i=0, n=counts.length; i<n; i++) {
|
|
@@ -29964,14 +30024,16 @@ ${svg}
|
|
|
29964
30024
|
|
|
29965
30025
|
function printJoinMessage(matches, n, joins, m, skipped, collisions, collisionFields) {
|
|
29966
30026
|
// TODO: add tip for troubleshooting join problems, if join is less than perfect.
|
|
30027
|
+
var unmatched = n - matches;
|
|
29967
30028
|
if (matches > 0 === false) {
|
|
29968
30029
|
message("No records could be joined");
|
|
29969
30030
|
return;
|
|
29970
30031
|
}
|
|
29971
30032
|
message(utils.format("Joined data from %'d source record%s to %'d target record%s",
|
|
29972
30033
|
joins, utils.pluralSuffix(joins), matches, utils.pluralSuffix(matches)));
|
|
29973
|
-
if (
|
|
29974
|
-
message(utils.format('%d
|
|
30034
|
+
if (unmatched > 0) {
|
|
30035
|
+
message(utils.format('%d target record%s received no data', unmatched, utils.pluralSuffix(unmatched)));
|
|
30036
|
+
// message(utils.format('%d target records received no data', n-matches));
|
|
29975
30037
|
}
|
|
29976
30038
|
if (joins < m) {
|
|
29977
30039
|
message(utils.format("%d/%d source records could not be joined", m-joins, m));
|
|
@@ -30020,6 +30082,7 @@ ${svg}
|
|
|
30020
30082
|
var JoinTables = /*#__PURE__*/Object.freeze({
|
|
30021
30083
|
__proto__: null,
|
|
30022
30084
|
joinTables: joinTables,
|
|
30085
|
+
joinTableToLayer: joinTableToLayer,
|
|
30023
30086
|
validateFieldNames: validateFieldNames,
|
|
30024
30087
|
updateUnmatchedRecord: updateUnmatchedRecord,
|
|
30025
30088
|
findCollisionFields: findCollisionFields,
|
|
@@ -31486,13 +31549,13 @@ ${svg}
|
|
|
31486
31549
|
// TODO: option to copy points that can't be joined to a new layer
|
|
31487
31550
|
var joinFunction = getPolygonToPointsFunction(targetLyr, arcs, pointLyr, opts);
|
|
31488
31551
|
prepJoinLayers(targetLyr, pointLyr);
|
|
31489
|
-
return
|
|
31552
|
+
return joinTableToLayer(targetLyr, pointLyr.data, joinFunction, opts);
|
|
31490
31553
|
}
|
|
31491
31554
|
|
|
31492
31555
|
function joinPolygonsToPoints(targetLyr, polygonLyr, arcs, opts) {
|
|
31493
31556
|
var joinFunction = getPointToPolygonsFunction(targetLyr, polygonLyr, arcs, opts);
|
|
31494
31557
|
prepJoinLayers(targetLyr, polygonLyr);
|
|
31495
|
-
return
|
|
31558
|
+
return joinTableToLayer(targetLyr, polygonLyr.data, joinFunction, opts);
|
|
31496
31559
|
}
|
|
31497
31560
|
|
|
31498
31561
|
|
|
@@ -33278,6 +33341,12 @@ ${svg}
|
|
|
33278
33341
|
};
|
|
33279
33342
|
}
|
|
33280
33343
|
|
|
33344
|
+
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
33345
|
+
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
33346
|
+
interrupt('Layer is empty, stopping processing');
|
|
33347
|
+
}
|
|
33348
|
+
};
|
|
33349
|
+
|
|
33281
33350
|
cmd.include = function(opts) {
|
|
33282
33351
|
var content, obj, context;
|
|
33283
33352
|
// TODO: handle web context
|
|
@@ -33653,9 +33722,10 @@ ${svg}
|
|
|
33653
33722
|
|
|
33654
33723
|
var joinOpts = utils.extend({}, opts);
|
|
33655
33724
|
var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33656
|
-
var retn =
|
|
33725
|
+
var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
|
|
33657
33726
|
|
|
33658
33727
|
if (opts.interpolate) {
|
|
33728
|
+
if (opts.duplication) stop('duplication and interpolate options cannot be used together');
|
|
33659
33729
|
interpolateFieldsByArea(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33660
33730
|
}
|
|
33661
33731
|
return retn;
|
|
@@ -34570,7 +34640,7 @@ ${svg}
|
|
|
34570
34640
|
function joinPointsToPoints(targetLyr, srcLyr, crs, opts) {
|
|
34571
34641
|
var joinFunction = getPointToPointFunction(targetLyr, srcLyr, crs, opts);
|
|
34572
34642
|
prepJoinLayers(targetLyr, srcLyr);
|
|
34573
|
-
return
|
|
34643
|
+
return joinTableToLayer(targetLyr, srcLyr.data, joinFunction, opts);
|
|
34574
34644
|
}
|
|
34575
34645
|
|
|
34576
34646
|
function getPointToPointFunction(targetLyr, srcLyr, crs, opts) {
|
|
@@ -34620,14 +34690,14 @@ ${svg}
|
|
|
34620
34690
|
}
|
|
34621
34691
|
};
|
|
34622
34692
|
|
|
34623
|
-
function joinAttributesToFeatures(
|
|
34693
|
+
function joinAttributesToFeatures(destLyr, srcTable, opts) {
|
|
34624
34694
|
var keys = opts.keys,
|
|
34625
34695
|
destKey = keys[0],
|
|
34626
34696
|
srcKey = keys[1],
|
|
34627
|
-
destTable =
|
|
34697
|
+
destTable = destLyr.data,
|
|
34628
34698
|
joinFunction = getJoinByKey(destTable, destKey, srcTable, srcKey);
|
|
34629
34699
|
validateFieldNames(keys);
|
|
34630
|
-
return
|
|
34700
|
+
return joinTableToLayer(destLyr, srcTable, joinFunction, opts);
|
|
34631
34701
|
}
|
|
34632
34702
|
|
|
34633
34703
|
// Return a function for translating a target id to an array of source ids based on values
|
|
@@ -37703,6 +37773,9 @@ ${svg}
|
|
|
37703
37773
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
37704
37774
|
}
|
|
37705
37775
|
|
|
37776
|
+
} else if (name == 'ignore') {
|
|
37777
|
+
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
37778
|
+
|
|
37706
37779
|
} else if (name == 'include') {
|
|
37707
37780
|
cmd.include(opts);
|
|
37708
37781
|
|
|
@@ -38073,6 +38146,7 @@ ${svg}
|
|
|
38073
38146
|
cmd.options.output = outputArr;
|
|
38074
38147
|
}
|
|
38075
38148
|
});
|
|
38149
|
+
|
|
38076
38150
|
runParsedCommands(commands, null, callback);
|
|
38077
38151
|
}
|
|
38078
38152
|
|
|
@@ -38133,10 +38207,6 @@ ${svg}
|
|
|
38133
38207
|
error("Changed in v0.4: runParsedCommands() takes a Catalog object");
|
|
38134
38208
|
}
|
|
38135
38209
|
|
|
38136
|
-
if (!utils.isFunction(done)) {
|
|
38137
|
-
error("Missing a callback function");
|
|
38138
|
-
}
|
|
38139
|
-
|
|
38140
38210
|
if (!utils.isArray(commands)) {
|
|
38141
38211
|
error("Expected an array of parsed commands");
|
|
38142
38212
|
}
|
|
@@ -38157,18 +38227,25 @@ ${svg}
|
|
|
38157
38227
|
// that it can modify the output dataset in-place instead of making a copy.
|
|
38158
38228
|
commands[commands.length-1].options.final = true;
|
|
38159
38229
|
}
|
|
38160
|
-
commands = divideImportCommand(commands);
|
|
38161
|
-
utils.reduceAsync(commands, catalog, nextCommand, done);
|
|
38162
38230
|
|
|
38163
|
-
|
|
38164
|
-
|
|
38165
|
-
|
|
38166
|
-
|
|
38167
|
-
|
|
38231
|
+
var groups = divideImportCommand(commands);
|
|
38232
|
+
if (groups.length == 1) {
|
|
38233
|
+
// run a simple sequence of commands (input files are not batched)
|
|
38234
|
+
return runParsedCommands2(commands, catalog, done);
|
|
38235
|
+
}
|
|
38236
|
+
|
|
38237
|
+
// run duplicated commands (i.e. batch mode)
|
|
38238
|
+
utils.reduceAsync(groups, catalog, nextGroup, done);
|
|
38239
|
+
|
|
38240
|
+
function nextGroup(catalog, commands, next) {
|
|
38241
|
+
runParsedCommands2(commands, catalog, function(err, catalog) {
|
|
38242
|
+
err = filterError(err);
|
|
38243
|
+
next(err, catalog);
|
|
38244
|
+
});
|
|
38168
38245
|
}
|
|
38169
38246
|
|
|
38170
38247
|
function done(err, catalog) {
|
|
38171
|
-
|
|
38248
|
+
err = filterError(err);
|
|
38172
38249
|
cb(err, catalog);
|
|
38173
38250
|
setStateVar('current_command', null);
|
|
38174
38251
|
setStateVar('verbose', false);
|
|
@@ -38176,11 +38253,31 @@ ${svg}
|
|
|
38176
38253
|
}
|
|
38177
38254
|
}
|
|
38178
38255
|
|
|
38256
|
+
function filterError(err) {
|
|
38257
|
+
if (err) printError(err);
|
|
38258
|
+
if (err && err.name == 'NonFatalError') {
|
|
38259
|
+
return null;
|
|
38260
|
+
}
|
|
38261
|
+
return err;
|
|
38262
|
+
}
|
|
38263
|
+
|
|
38264
|
+
function runParsedCommands2(commands, catalog, cb) {
|
|
38265
|
+
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
38266
|
+
|
|
38267
|
+
function nextCommand(catalog, cmd, next) {
|
|
38268
|
+
setStateVar('current_command', cmd.name); // for log msgs
|
|
38269
|
+
setStateVar('verbose', !!cmd.options.verbose);
|
|
38270
|
+
setStateVar('debug', !!cmd.options.debug);
|
|
38271
|
+
runCommand(cmd, catalog, next);
|
|
38272
|
+
}
|
|
38273
|
+
}
|
|
38274
|
+
|
|
38275
|
+
|
|
38179
38276
|
// If an initial import command indicates that several input files should be
|
|
38180
38277
|
// processed separately, then duplicate the sequence of commands to run
|
|
38181
38278
|
// once for each input file
|
|
38182
38279
|
// @commands Array of parsed commands
|
|
38183
|
-
// Returns:
|
|
38280
|
+
// Returns: Array of one or more sequences of parsed commands
|
|
38184
38281
|
//
|
|
38185
38282
|
function divideImportCommand(commands) {
|
|
38186
38283
|
var firstCmd = commands[0],
|
|
@@ -38188,23 +38285,23 @@ ${svg}
|
|
|
38188
38285
|
|
|
38189
38286
|
if (firstCmd.name != 'i' || opts.stdin || opts.merge_files ||
|
|
38190
38287
|
opts.combine_files || !opts.files || opts.files.length < 2) {
|
|
38191
|
-
return commands;
|
|
38288
|
+
return [commands];
|
|
38192
38289
|
}
|
|
38193
38290
|
|
|
38194
|
-
return
|
|
38195
|
-
var
|
|
38291
|
+
return opts.files.map(function(file) {
|
|
38292
|
+
var group = [{
|
|
38196
38293
|
name: 'i',
|
|
38197
38294
|
options: utils.defaults({
|
|
38198
38295
|
files:[file],
|
|
38199
38296
|
replace: true // kludge to replace data catalog
|
|
38200
38297
|
}, opts)
|
|
38201
|
-
};
|
|
38202
|
-
|
|
38203
|
-
|
|
38204
|
-
|
|
38205
|
-
}, []);
|
|
38298
|
+
}];
|
|
38299
|
+
group.push.apply(group, commands.slice(1));
|
|
38300
|
+
return group;
|
|
38301
|
+
});
|
|
38206
38302
|
}
|
|
38207
38303
|
|
|
38304
|
+
|
|
38208
38305
|
function printStartupMessages() {
|
|
38209
38306
|
// print heap memory message if running with a custom amount
|
|
38210
38307
|
var rxp = /^--max-old-space-size=([0-9]+)$/;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.70",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"commander": "^5.1.0",
|
|
44
44
|
"cookies": "^0.8.0",
|
|
45
|
-
"d3-
|
|
45
|
+
"d3-color": "2.0.0",
|
|
46
|
+
"d3-scale-chromatic": "2.0.0",
|
|
46
47
|
"delaunator": "^5.0.0",
|
|
47
48
|
"flatbush": "^3.2.1",
|
|
48
49
|
"geokdbush": "^1.1.0",
|
package/www/elements.css
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -3976,6 +3976,10 @@
|
|
|
3976
3976
|
throw new UserError$1(formatLogArgs(arguments));
|
|
3977
3977
|
};
|
|
3978
3978
|
|
|
3979
|
+
var _interrupt = function() {
|
|
3980
|
+
throw new NonFatalError(formatLogArgs(arguments));
|
|
3981
|
+
};
|
|
3982
|
+
|
|
3979
3983
|
var _message = function() {
|
|
3980
3984
|
logArgs(arguments);
|
|
3981
3985
|
};
|
|
@@ -3994,10 +3998,14 @@
|
|
|
3994
3998
|
}
|
|
3995
3999
|
|
|
3996
4000
|
// Handle an error caused by invalid input or misuse of API
|
|
3997
|
-
function stop$1
|
|
4001
|
+
function stop$1() {
|
|
3998
4002
|
_stop.apply(null, utils$1.toArray(arguments));
|
|
3999
4003
|
}
|
|
4000
4004
|
|
|
4005
|
+
function interrupt() {
|
|
4006
|
+
_interrupt.apply(null, utils$1.toArray(arguments));
|
|
4007
|
+
}
|
|
4008
|
+
|
|
4001
4009
|
// Print a status message
|
|
4002
4010
|
function message$1() {
|
|
4003
4011
|
_message.apply(null, messageArgs(arguments));
|
|
@@ -4037,7 +4045,9 @@
|
|
|
4037
4045
|
if (utils$1.isString(err)) {
|
|
4038
4046
|
err = new UserError$1(err);
|
|
4039
4047
|
}
|
|
4040
|
-
if (err.name == '
|
|
4048
|
+
if (err.name == 'NonFatalError') {
|
|
4049
|
+
console.error(messageArgs([err.message]).join(' '));
|
|
4050
|
+
} else if (err.name == 'UserError') {
|
|
4041
4051
|
msg = err.message;
|
|
4042
4052
|
if (!/Error/.test(msg)) {
|
|
4043
4053
|
msg = "Error: " + msg;
|
|
@@ -4057,6 +4067,12 @@
|
|
|
4057
4067
|
return err;
|
|
4058
4068
|
}
|
|
4059
4069
|
|
|
4070
|
+
function NonFatalError(msg) {
|
|
4071
|
+
var err = new Error(msg);
|
|
4072
|
+
err.name = 'NonFatalError';
|
|
4073
|
+
return err;
|
|
4074
|
+
}
|
|
4075
|
+
|
|
4060
4076
|
function formatColumns(arr, alignments) {
|
|
4061
4077
|
var widths = arr.reduce(function(memo, line) {
|
|
4062
4078
|
return line.map(function(str, i) {
|
|
@@ -9526,7 +9542,6 @@
|
|
|
9526
9542
|
return style;
|
|
9527
9543
|
}
|
|
9528
9544
|
|
|
9529
|
-
|
|
9530
9545
|
// Returns a display style for the overlay layer.
|
|
9531
9546
|
// The overlay layer renders several kinds of feature, each of which is displayed
|
|
9532
9547
|
// with a different style.
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.69";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -1167,6 +1167,10 @@
|
|
|
1167
1167
|
throw new UserError(formatLogArgs(arguments));
|
|
1168
1168
|
};
|
|
1169
1169
|
|
|
1170
|
+
var _interrupt = function() {
|
|
1171
|
+
throw new NonFatalError(formatLogArgs(arguments));
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1170
1174
|
var _message = function() {
|
|
1171
1175
|
logArgs(arguments);
|
|
1172
1176
|
};
|
|
@@ -1185,10 +1189,14 @@
|
|
|
1185
1189
|
}
|
|
1186
1190
|
|
|
1187
1191
|
// Handle an error caused by invalid input or misuse of API
|
|
1188
|
-
function stop
|
|
1192
|
+
function stop() {
|
|
1189
1193
|
_stop.apply(null, utils.toArray(arguments));
|
|
1190
1194
|
}
|
|
1191
1195
|
|
|
1196
|
+
function interrupt() {
|
|
1197
|
+
_interrupt.apply(null, utils.toArray(arguments));
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1192
1200
|
// Print a status message
|
|
1193
1201
|
function message() {
|
|
1194
1202
|
_message.apply(null, messageArgs(arguments));
|
|
@@ -1228,7 +1236,9 @@
|
|
|
1228
1236
|
if (utils.isString(err)) {
|
|
1229
1237
|
err = new UserError(err);
|
|
1230
1238
|
}
|
|
1231
|
-
if (err.name == '
|
|
1239
|
+
if (err.name == 'NonFatalError') {
|
|
1240
|
+
console.error(messageArgs([err.message]).join(' '));
|
|
1241
|
+
} else if (err.name == 'UserError') {
|
|
1232
1242
|
msg = err.message;
|
|
1233
1243
|
if (!/Error/.test(msg)) {
|
|
1234
1244
|
msg = "Error: " + msg;
|
|
@@ -1248,6 +1258,12 @@
|
|
|
1248
1258
|
return err;
|
|
1249
1259
|
}
|
|
1250
1260
|
|
|
1261
|
+
function NonFatalError(msg) {
|
|
1262
|
+
var err = new Error(msg);
|
|
1263
|
+
err.name = 'NonFatalError';
|
|
1264
|
+
return err;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1251
1267
|
function formatColumns(arr, alignments) {
|
|
1252
1268
|
var widths = arr.reduce(function(memo, line) {
|
|
1253
1269
|
return line.map(function(str, i) {
|
|
@@ -1308,6 +1324,7 @@
|
|
|
1308
1324
|
loggingEnabled: loggingEnabled,
|
|
1309
1325
|
error: error,
|
|
1310
1326
|
stop: stop,
|
|
1327
|
+
interrupt: interrupt,
|
|
1311
1328
|
message: message,
|
|
1312
1329
|
setLoggingFunctions: setLoggingFunctions,
|
|
1313
1330
|
print: print,
|
|
@@ -1315,6 +1332,7 @@
|
|
|
1315
1332
|
debug: debug,
|
|
1316
1333
|
printError: printError,
|
|
1317
1334
|
UserError: UserError,
|
|
1335
|
+
NonFatalError: NonFatalError,
|
|
1318
1336
|
formatColumns: formatColumns,
|
|
1319
1337
|
formatStringsAsGrid: formatStringsAsGrid,
|
|
1320
1338
|
formatLogArgs: formatLogArgs,
|
|
@@ -14306,7 +14324,7 @@
|
|
|
14306
14324
|
joinStr = obj.tag == 'text' || obj.tag == 'tspan' ? '' : '\n';
|
|
14307
14325
|
svg += '>' + joinStr;
|
|
14308
14326
|
if (obj.value) {
|
|
14309
|
-
svg += obj.value;
|
|
14327
|
+
svg += stringEscape(obj.value);
|
|
14310
14328
|
}
|
|
14311
14329
|
if (obj.children) {
|
|
14312
14330
|
svg += obj.children.map(stringify).join(joinStr);
|
|
@@ -14329,8 +14347,13 @@
|
|
|
14329
14347
|
"'": '''
|
|
14330
14348
|
};
|
|
14331
14349
|
function stringEscape(s) {
|
|
14332
|
-
return String(s).replace(rxp, function(
|
|
14333
|
-
|
|
14350
|
+
return String(s).replace(rxp, function(match, i) {
|
|
14351
|
+
var entity = map[match];
|
|
14352
|
+
// don't replace & with &amp;
|
|
14353
|
+
if (match == '&' && s.substr(i, entity.length) == entity) {
|
|
14354
|
+
return '&';
|
|
14355
|
+
}
|
|
14356
|
+
return entity;
|
|
14334
14357
|
});
|
|
14335
14358
|
}
|
|
14336
14359
|
|
|
@@ -17140,7 +17163,7 @@ ${svg}
|
|
|
17140
17163
|
c = buf[i];
|
|
17141
17164
|
if (c == DQUOTE) {
|
|
17142
17165
|
inQuotedText = !inQuotedText;
|
|
17143
|
-
} else if (c == CR || c == LF) {
|
|
17166
|
+
} else if ((c == CR || c == LF) && !inQuotedText) {
|
|
17144
17167
|
if (c == CR && i + 1 < bufLen && buf[i + 1] == LF) {
|
|
17145
17168
|
// first half of CRLF pair: advance one byte
|
|
17146
17169
|
i++;
|
|
@@ -17234,6 +17257,7 @@ ${svg}
|
|
|
17234
17257
|
getRowConverter: getRowConverter,
|
|
17235
17258
|
parseDelimHeaderSection: parseDelimHeaderSection,
|
|
17236
17259
|
getDelimFieldFilter: getDelimFieldFilter,
|
|
17260
|
+
readLinesAsString: readLinesAsString,
|
|
17237
17261
|
parseDelimText: parseDelimText
|
|
17238
17262
|
});
|
|
17239
17263
|
|
|
@@ -18415,6 +18439,9 @@ ${svg}
|
|
|
18415
18439
|
type: 'strings',
|
|
18416
18440
|
describe: '[CSV] comma-sep. list of fields to import'
|
|
18417
18441
|
})
|
|
18442
|
+
// .option('csv-comment', {
|
|
18443
|
+
// describe: '[CSV] comment line character(s)'
|
|
18444
|
+
// })
|
|
18418
18445
|
.option('decimal-comma', {
|
|
18419
18446
|
type: 'flag',
|
|
18420
18447
|
describe: '[CSV] import numbers formatted like 1.000,01 or 1 000,01'
|
|
@@ -19164,6 +19191,14 @@ ${svg}
|
|
|
19164
19191
|
.option('target', targetOpt)
|
|
19165
19192
|
.option('no-replace', noReplaceOpt);
|
|
19166
19193
|
|
|
19194
|
+
parser.command('ignore')
|
|
19195
|
+
// .describe('stop processing if a condition is met')
|
|
19196
|
+
.option('empty', {
|
|
19197
|
+
describe: 'ignore empty files',
|
|
19198
|
+
type: 'flag'
|
|
19199
|
+
})
|
|
19200
|
+
.option('target', targetOpt);
|
|
19201
|
+
|
|
19167
19202
|
parser.command('inlay')
|
|
19168
19203
|
.describe('inscribe a polygon layer inside another polygon layer')
|
|
19169
19204
|
.option('source', {
|
|
@@ -19235,6 +19270,10 @@ ${svg}
|
|
|
19235
19270
|
// describe: 'use planar geometry when interpolating by area' // useful for testing
|
|
19236
19271
|
type: 'flag'
|
|
19237
19272
|
})
|
|
19273
|
+
.option('duplication', {
|
|
19274
|
+
describe: 'duplicate target features on many-to-one joins',
|
|
19275
|
+
type: 'flag'
|
|
19276
|
+
})
|
|
19238
19277
|
.option('string-fields', stringFieldsOpt)
|
|
19239
19278
|
.option('field-types', fieldTypesOpt)
|
|
19240
19279
|
.option('sum-fields', {
|
|
@@ -29801,13 +29840,19 @@ ${svg}
|
|
|
29801
29840
|
getJoinFilter: getJoinFilter
|
|
29802
29841
|
});
|
|
29803
29842
|
|
|
29843
|
+
function joinTables(dest, src, join, opts) {
|
|
29844
|
+
return joinTableToLayer({data: dest}, src, join, opts);
|
|
29845
|
+
}
|
|
29846
|
+
|
|
29804
29847
|
// Join data from @src table to records in @dest table
|
|
29805
29848
|
// @join function
|
|
29806
29849
|
// Receives index of record in the dest table
|
|
29807
29850
|
// Returns array of matching records in src table, or null if no matches
|
|
29808
29851
|
//
|
|
29809
|
-
function
|
|
29810
|
-
var
|
|
29852
|
+
function joinTableToLayer(destLyr, src, join, opts) {
|
|
29853
|
+
var dest = destLyr.data,
|
|
29854
|
+
useDuplication = !!opts.duplication,
|
|
29855
|
+
srcRecords = src.getRecords(),
|
|
29811
29856
|
destRecords = dest.getRecords(),
|
|
29812
29857
|
prefix = opts.prefix || '',
|
|
29813
29858
|
unmatchedRecords = [],
|
|
@@ -29822,6 +29867,14 @@ ${svg}
|
|
|
29822
29867
|
retn = {},
|
|
29823
29868
|
srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
|
|
29824
29869
|
|
|
29870
|
+
// support for duplication
|
|
29871
|
+
var duplicateRecords, destShapes;
|
|
29872
|
+
if (useDuplication) {
|
|
29873
|
+
if (opts.calc) stop('duplication and calc options cannot be used together');
|
|
29874
|
+
duplicateRecords = dest.clone().getRecords();
|
|
29875
|
+
destShapes = destLyr.shapes || [];
|
|
29876
|
+
}
|
|
29877
|
+
|
|
29825
29878
|
if (opts.where) {
|
|
29826
29879
|
filter = getJoinFilter(src, opts.where);
|
|
29827
29880
|
}
|
|
@@ -29831,7 +29884,8 @@ ${svg}
|
|
|
29831
29884
|
}
|
|
29832
29885
|
|
|
29833
29886
|
// join source records to target records
|
|
29834
|
-
|
|
29887
|
+
n = destRecords.length;
|
|
29888
|
+
for (i=0; i<n; i++) {
|
|
29835
29889
|
destRec = destRecords[i];
|
|
29836
29890
|
joins = join(i);
|
|
29837
29891
|
if (joins && filter) {
|
|
@@ -29842,7 +29896,12 @@ ${svg}
|
|
|
29842
29896
|
for (j=0, count=0, m=joins ? joins.length : 0; j<m; j++) {
|
|
29843
29897
|
srcId = joins[j];
|
|
29844
29898
|
srcRec = srcRecords[srcId];
|
|
29845
|
-
if (count
|
|
29899
|
+
if (count > 0 && useDuplication) {
|
|
29900
|
+
destRec = copyRecord(duplicateRecords[i]);
|
|
29901
|
+
destRecords.push(destRec);
|
|
29902
|
+
destShapes.push(cloneShape(destShapes[i]));
|
|
29903
|
+
}
|
|
29904
|
+
if (count === 0 || useDuplication) {
|
|
29846
29905
|
if (copyFields.length > 0) {
|
|
29847
29906
|
// only copying the first match
|
|
29848
29907
|
joinByCopy(destRec, srcRec, copyFields, prefix);
|
|
@@ -29874,7 +29933,7 @@ ${svg}
|
|
|
29874
29933
|
}
|
|
29875
29934
|
}
|
|
29876
29935
|
|
|
29877
|
-
printJoinMessage(matchCount,
|
|
29936
|
+
printJoinMessage(matchCount, n,
|
|
29878
29937
|
countJoins(joinCounts), srcRecords.length, skipCount, collisionCount, collisionFields);
|
|
29879
29938
|
|
|
29880
29939
|
if (opts.unjoined) {
|
|
@@ -29902,6 +29961,7 @@ ${svg}
|
|
|
29902
29961
|
});
|
|
29903
29962
|
}
|
|
29904
29963
|
|
|
29964
|
+
|
|
29905
29965
|
function countJoins(counts) {
|
|
29906
29966
|
var joinCount = 0;
|
|
29907
29967
|
for (var i=0, n=counts.length; i<n; i++) {
|
|
@@ -29964,14 +30024,16 @@ ${svg}
|
|
|
29964
30024
|
|
|
29965
30025
|
function printJoinMessage(matches, n, joins, m, skipped, collisions, collisionFields) {
|
|
29966
30026
|
// TODO: add tip for troubleshooting join problems, if join is less than perfect.
|
|
30027
|
+
var unmatched = n - matches;
|
|
29967
30028
|
if (matches > 0 === false) {
|
|
29968
30029
|
message("No records could be joined");
|
|
29969
30030
|
return;
|
|
29970
30031
|
}
|
|
29971
30032
|
message(utils.format("Joined data from %'d source record%s to %'d target record%s",
|
|
29972
30033
|
joins, utils.pluralSuffix(joins), matches, utils.pluralSuffix(matches)));
|
|
29973
|
-
if (
|
|
29974
|
-
message(utils.format('%d
|
|
30034
|
+
if (unmatched > 0) {
|
|
30035
|
+
message(utils.format('%d target record%s received no data', unmatched, utils.pluralSuffix(unmatched)));
|
|
30036
|
+
// message(utils.format('%d target records received no data', n-matches));
|
|
29975
30037
|
}
|
|
29976
30038
|
if (joins < m) {
|
|
29977
30039
|
message(utils.format("%d/%d source records could not be joined", m-joins, m));
|
|
@@ -30020,6 +30082,7 @@ ${svg}
|
|
|
30020
30082
|
var JoinTables = /*#__PURE__*/Object.freeze({
|
|
30021
30083
|
__proto__: null,
|
|
30022
30084
|
joinTables: joinTables,
|
|
30085
|
+
joinTableToLayer: joinTableToLayer,
|
|
30023
30086
|
validateFieldNames: validateFieldNames,
|
|
30024
30087
|
updateUnmatchedRecord: updateUnmatchedRecord,
|
|
30025
30088
|
findCollisionFields: findCollisionFields,
|
|
@@ -31486,13 +31549,13 @@ ${svg}
|
|
|
31486
31549
|
// TODO: option to copy points that can't be joined to a new layer
|
|
31487
31550
|
var joinFunction = getPolygonToPointsFunction(targetLyr, arcs, pointLyr, opts);
|
|
31488
31551
|
prepJoinLayers(targetLyr, pointLyr);
|
|
31489
|
-
return
|
|
31552
|
+
return joinTableToLayer(targetLyr, pointLyr.data, joinFunction, opts);
|
|
31490
31553
|
}
|
|
31491
31554
|
|
|
31492
31555
|
function joinPolygonsToPoints(targetLyr, polygonLyr, arcs, opts) {
|
|
31493
31556
|
var joinFunction = getPointToPolygonsFunction(targetLyr, polygonLyr, arcs, opts);
|
|
31494
31557
|
prepJoinLayers(targetLyr, polygonLyr);
|
|
31495
|
-
return
|
|
31558
|
+
return joinTableToLayer(targetLyr, polygonLyr.data, joinFunction, opts);
|
|
31496
31559
|
}
|
|
31497
31560
|
|
|
31498
31561
|
|
|
@@ -33278,6 +33341,12 @@ ${svg}
|
|
|
33278
33341
|
};
|
|
33279
33342
|
}
|
|
33280
33343
|
|
|
33344
|
+
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
33345
|
+
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
33346
|
+
interrupt('Layer is empty, stopping processing');
|
|
33347
|
+
}
|
|
33348
|
+
};
|
|
33349
|
+
|
|
33281
33350
|
cmd.include = function(opts) {
|
|
33282
33351
|
var content, obj, context;
|
|
33283
33352
|
// TODO: handle web context
|
|
@@ -33653,9 +33722,10 @@ ${svg}
|
|
|
33653
33722
|
|
|
33654
33723
|
var joinOpts = utils.extend({}, opts);
|
|
33655
33724
|
var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33656
|
-
var retn =
|
|
33725
|
+
var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
|
|
33657
33726
|
|
|
33658
33727
|
if (opts.interpolate) {
|
|
33728
|
+
if (opts.duplication) stop('duplication and interpolate options cannot be used together');
|
|
33659
33729
|
interpolateFieldsByArea(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33660
33730
|
}
|
|
33661
33731
|
return retn;
|
|
@@ -34570,7 +34640,7 @@ ${svg}
|
|
|
34570
34640
|
function joinPointsToPoints(targetLyr, srcLyr, crs, opts) {
|
|
34571
34641
|
var joinFunction = getPointToPointFunction(targetLyr, srcLyr, crs, opts);
|
|
34572
34642
|
prepJoinLayers(targetLyr, srcLyr);
|
|
34573
|
-
return
|
|
34643
|
+
return joinTableToLayer(targetLyr, srcLyr.data, joinFunction, opts);
|
|
34574
34644
|
}
|
|
34575
34645
|
|
|
34576
34646
|
function getPointToPointFunction(targetLyr, srcLyr, crs, opts) {
|
|
@@ -34620,14 +34690,14 @@ ${svg}
|
|
|
34620
34690
|
}
|
|
34621
34691
|
};
|
|
34622
34692
|
|
|
34623
|
-
function joinAttributesToFeatures(
|
|
34693
|
+
function joinAttributesToFeatures(destLyr, srcTable, opts) {
|
|
34624
34694
|
var keys = opts.keys,
|
|
34625
34695
|
destKey = keys[0],
|
|
34626
34696
|
srcKey = keys[1],
|
|
34627
|
-
destTable =
|
|
34697
|
+
destTable = destLyr.data,
|
|
34628
34698
|
joinFunction = getJoinByKey(destTable, destKey, srcTable, srcKey);
|
|
34629
34699
|
validateFieldNames(keys);
|
|
34630
|
-
return
|
|
34700
|
+
return joinTableToLayer(destLyr, srcTable, joinFunction, opts);
|
|
34631
34701
|
}
|
|
34632
34702
|
|
|
34633
34703
|
// Return a function for translating a target id to an array of source ids based on values
|
|
@@ -37703,6 +37773,9 @@ ${svg}
|
|
|
37703
37773
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
37704
37774
|
}
|
|
37705
37775
|
|
|
37776
|
+
} else if (name == 'ignore') {
|
|
37777
|
+
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
37778
|
+
|
|
37706
37779
|
} else if (name == 'include') {
|
|
37707
37780
|
cmd.include(opts);
|
|
37708
37781
|
|
|
@@ -38073,6 +38146,7 @@ ${svg}
|
|
|
38073
38146
|
cmd.options.output = outputArr;
|
|
38074
38147
|
}
|
|
38075
38148
|
});
|
|
38149
|
+
|
|
38076
38150
|
runParsedCommands(commands, null, callback);
|
|
38077
38151
|
}
|
|
38078
38152
|
|
|
@@ -38133,10 +38207,6 @@ ${svg}
|
|
|
38133
38207
|
error("Changed in v0.4: runParsedCommands() takes a Catalog object");
|
|
38134
38208
|
}
|
|
38135
38209
|
|
|
38136
|
-
if (!utils.isFunction(done)) {
|
|
38137
|
-
error("Missing a callback function");
|
|
38138
|
-
}
|
|
38139
|
-
|
|
38140
38210
|
if (!utils.isArray(commands)) {
|
|
38141
38211
|
error("Expected an array of parsed commands");
|
|
38142
38212
|
}
|
|
@@ -38157,18 +38227,25 @@ ${svg}
|
|
|
38157
38227
|
// that it can modify the output dataset in-place instead of making a copy.
|
|
38158
38228
|
commands[commands.length-1].options.final = true;
|
|
38159
38229
|
}
|
|
38160
|
-
commands = divideImportCommand(commands);
|
|
38161
|
-
utils.reduceAsync(commands, catalog, nextCommand, done);
|
|
38162
38230
|
|
|
38163
|
-
|
|
38164
|
-
|
|
38165
|
-
|
|
38166
|
-
|
|
38167
|
-
|
|
38231
|
+
var groups = divideImportCommand(commands);
|
|
38232
|
+
if (groups.length == 1) {
|
|
38233
|
+
// run a simple sequence of commands (input files are not batched)
|
|
38234
|
+
return runParsedCommands2(commands, catalog, done);
|
|
38235
|
+
}
|
|
38236
|
+
|
|
38237
|
+
// run duplicated commands (i.e. batch mode)
|
|
38238
|
+
utils.reduceAsync(groups, catalog, nextGroup, done);
|
|
38239
|
+
|
|
38240
|
+
function nextGroup(catalog, commands, next) {
|
|
38241
|
+
runParsedCommands2(commands, catalog, function(err, catalog) {
|
|
38242
|
+
err = filterError(err);
|
|
38243
|
+
next(err, catalog);
|
|
38244
|
+
});
|
|
38168
38245
|
}
|
|
38169
38246
|
|
|
38170
38247
|
function done(err, catalog) {
|
|
38171
|
-
|
|
38248
|
+
err = filterError(err);
|
|
38172
38249
|
cb(err, catalog);
|
|
38173
38250
|
setStateVar('current_command', null);
|
|
38174
38251
|
setStateVar('verbose', false);
|
|
@@ -38176,11 +38253,31 @@ ${svg}
|
|
|
38176
38253
|
}
|
|
38177
38254
|
}
|
|
38178
38255
|
|
|
38256
|
+
function filterError(err) {
|
|
38257
|
+
if (err) printError(err);
|
|
38258
|
+
if (err && err.name == 'NonFatalError') {
|
|
38259
|
+
return null;
|
|
38260
|
+
}
|
|
38261
|
+
return err;
|
|
38262
|
+
}
|
|
38263
|
+
|
|
38264
|
+
function runParsedCommands2(commands, catalog, cb) {
|
|
38265
|
+
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
38266
|
+
|
|
38267
|
+
function nextCommand(catalog, cmd, next) {
|
|
38268
|
+
setStateVar('current_command', cmd.name); // for log msgs
|
|
38269
|
+
setStateVar('verbose', !!cmd.options.verbose);
|
|
38270
|
+
setStateVar('debug', !!cmd.options.debug);
|
|
38271
|
+
runCommand(cmd, catalog, next);
|
|
38272
|
+
}
|
|
38273
|
+
}
|
|
38274
|
+
|
|
38275
|
+
|
|
38179
38276
|
// If an initial import command indicates that several input files should be
|
|
38180
38277
|
// processed separately, then duplicate the sequence of commands to run
|
|
38181
38278
|
// once for each input file
|
|
38182
38279
|
// @commands Array of parsed commands
|
|
38183
|
-
// Returns:
|
|
38280
|
+
// Returns: Array of one or more sequences of parsed commands
|
|
38184
38281
|
//
|
|
38185
38282
|
function divideImportCommand(commands) {
|
|
38186
38283
|
var firstCmd = commands[0],
|
|
@@ -38188,23 +38285,23 @@ ${svg}
|
|
|
38188
38285
|
|
|
38189
38286
|
if (firstCmd.name != 'i' || opts.stdin || opts.merge_files ||
|
|
38190
38287
|
opts.combine_files || !opts.files || opts.files.length < 2) {
|
|
38191
|
-
return commands;
|
|
38288
|
+
return [commands];
|
|
38192
38289
|
}
|
|
38193
38290
|
|
|
38194
|
-
return
|
|
38195
|
-
var
|
|
38291
|
+
return opts.files.map(function(file) {
|
|
38292
|
+
var group = [{
|
|
38196
38293
|
name: 'i',
|
|
38197
38294
|
options: utils.defaults({
|
|
38198
38295
|
files:[file],
|
|
38199
38296
|
replace: true // kludge to replace data catalog
|
|
38200
38297
|
}, opts)
|
|
38201
|
-
};
|
|
38202
|
-
|
|
38203
|
-
|
|
38204
|
-
|
|
38205
|
-
}, []);
|
|
38298
|
+
}];
|
|
38299
|
+
group.push.apply(group, commands.slice(1));
|
|
38300
|
+
return group;
|
|
38301
|
+
});
|
|
38206
38302
|
}
|
|
38207
38303
|
|
|
38304
|
+
|
|
38208
38305
|
function printStartupMessages() {
|
|
38209
38306
|
// print heap memory message if running with a custom amount
|
|
38210
38307
|
var rxp = /^--max-old-space-size=([0-9]+)$/;
|
package/www/page.css
CHANGED
|
@@ -456,7 +456,7 @@ body.dragover #import-options-drop-area .drop-area {
|
|
|
456
456
|
text-align: left;
|
|
457
457
|
margin-top: 12px;
|
|
458
458
|
margin-right: 20px;
|
|
459
|
-
padding:
|
|
459
|
+
padding: 12px 18px 12px 18px;
|
|
460
460
|
vertical-align: top;
|
|
461
461
|
display: inline-block;
|
|
462
462
|
/* border: 1px solid #aaa; */
|
|
@@ -904,7 +904,7 @@ img.close-btn:hover,
|
|
|
904
904
|
box-sizing: border-box;
|
|
905
905
|
overflow: hidden;
|
|
906
906
|
overflow-y: auto;
|
|
907
|
-
padding: 4px 12px;
|
|
907
|
+
padding: 4px 12px 3px;
|
|
908
908
|
line-height: 1.2;
|
|
909
909
|
}
|
|
910
910
|
|