mapshaper 0.5.67 → 0.5.71
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 +10 -0
- package/mapshaper.js +393 -199
- package/package.json +3 -2
- package/www/mapshaper-gui.js +18 -2
- package/www/mapshaper.js +393 -199
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
|
|
|
@@ -18416,6 +18439,9 @@ ${svg}
|
|
|
18416
18439
|
type: 'strings',
|
|
18417
18440
|
describe: '[CSV] comma-sep. list of fields to import'
|
|
18418
18441
|
})
|
|
18442
|
+
// .option('csv-comment', {
|
|
18443
|
+
// describe: '[CSV] comment line character(s)'
|
|
18444
|
+
// })
|
|
18419
18445
|
.option('decimal-comma', {
|
|
18420
18446
|
type: 'flag',
|
|
18421
18447
|
describe: '[CSV] import numbers formatted like 1.000,01 or 1 000,01'
|
|
@@ -18652,7 +18678,8 @@ ${svg}
|
|
|
18652
18678
|
.option('no-replace', noReplaceOpt);
|
|
18653
18679
|
|
|
18654
18680
|
parser.command('classify')
|
|
18655
|
-
.describe('apply sequential or categorical classification')
|
|
18681
|
+
// .describe('apply sequential or categorical classification')
|
|
18682
|
+
.describe('assign colors or values using one of several methods')
|
|
18656
18683
|
.option('field', {
|
|
18657
18684
|
describe: 'name of field to classify',
|
|
18658
18685
|
DEFAULT: true
|
|
@@ -18672,6 +18699,10 @@ ${svg}
|
|
|
18672
18699
|
// deprecated in favor of colors=
|
|
18673
18700
|
// describe: 'name of a predefined color scheme (see -colors command)'
|
|
18674
18701
|
})
|
|
18702
|
+
.option('non-adjacent', {
|
|
18703
|
+
describe: 'assign non-adjacent colors to a polygon layer',
|
|
18704
|
+
assign_to: 'method'
|
|
18705
|
+
})
|
|
18675
18706
|
.option('stops', {
|
|
18676
18707
|
describe: 'a pair of values (0-100) for limiting a color ramp',
|
|
18677
18708
|
type: 'numbers'
|
|
@@ -18756,7 +18787,6 @@ ${svg}
|
|
|
18756
18787
|
.option('key-last-suffix', {
|
|
18757
18788
|
describe: 'string to append to last label'
|
|
18758
18789
|
})
|
|
18759
|
-
|
|
18760
18790
|
.option('target', targetOpt);
|
|
18761
18791
|
|
|
18762
18792
|
parser.command('clean')
|
|
@@ -19165,6 +19195,14 @@ ${svg}
|
|
|
19165
19195
|
.option('target', targetOpt)
|
|
19166
19196
|
.option('no-replace', noReplaceOpt);
|
|
19167
19197
|
|
|
19198
|
+
parser.command('ignore')
|
|
19199
|
+
// .describe('stop processing if a condition is met')
|
|
19200
|
+
.option('empty', {
|
|
19201
|
+
describe: 'ignore empty files',
|
|
19202
|
+
type: 'flag'
|
|
19203
|
+
})
|
|
19204
|
+
.option('target', targetOpt);
|
|
19205
|
+
|
|
19168
19206
|
parser.command('inlay')
|
|
19169
19207
|
.describe('inscribe a polygon layer inside another polygon layer')
|
|
19170
19208
|
.option('source', {
|
|
@@ -19236,6 +19274,10 @@ ${svg}
|
|
|
19236
19274
|
// describe: 'use planar geometry when interpolating by area' // useful for testing
|
|
19237
19275
|
type: 'flag'
|
|
19238
19276
|
})
|
|
19277
|
+
.option('duplication', {
|
|
19278
|
+
describe: 'duplicate target features on many-to-one joins',
|
|
19279
|
+
type: 'flag'
|
|
19280
|
+
})
|
|
19239
19281
|
.option('string-fields', stringFieldsOpt)
|
|
19240
19282
|
.option('field-types', fieldTypesOpt)
|
|
19241
19283
|
.option('sum-fields', {
|
|
@@ -28025,25 +28067,241 @@ ${svg}
|
|
|
28025
28067
|
return maxId + 1;
|
|
28026
28068
|
}
|
|
28027
28069
|
|
|
28028
|
-
|
|
28070
|
+
// Returns a function for constructing a query function that accepts an arc id and
|
|
28071
|
+
// returns information about the polygon or polygons that use the given arc.
|
|
28072
|
+
// TODO: explain this better.
|
|
28073
|
+
//
|
|
28074
|
+
// options:
|
|
28075
|
+
// filter: optional filter function; signature: function(idA, idB or -1) : boolean
|
|
28076
|
+
// reusable: flag that lets an arc be queried multiple times.
|
|
28077
|
+
function getArcClassifier(shapes, arcs) {
|
|
28078
|
+
var opts = arguments[2] || {},
|
|
28079
|
+
useOnce = !opts.reusable,
|
|
28080
|
+
n = arcs.size(),
|
|
28081
|
+
a = new Int32Array(n),
|
|
28082
|
+
b = new Int32Array(n);
|
|
28083
|
+
|
|
28084
|
+
utils.initializeArray(a, -1);
|
|
28085
|
+
utils.initializeArray(b, -1);
|
|
28086
|
+
|
|
28087
|
+
traversePaths(shapes, function(o) {
|
|
28088
|
+
var i = absArcId(o.arcId);
|
|
28089
|
+
var shpId = o.shapeId;
|
|
28090
|
+
var aval = a[i];
|
|
28091
|
+
if (aval == -1) {
|
|
28092
|
+
a[i] = shpId;
|
|
28093
|
+
} else if (shpId < aval) {
|
|
28094
|
+
b[i] = aval;
|
|
28095
|
+
a[i] = shpId;
|
|
28096
|
+
} else {
|
|
28097
|
+
b[i] = shpId;
|
|
28098
|
+
}
|
|
28099
|
+
});
|
|
28100
|
+
|
|
28101
|
+
function classify(arcId, getKey) {
|
|
28102
|
+
var i = absArcId(arcId);
|
|
28103
|
+
var shpA = a[i];
|
|
28104
|
+
var shpB = b[i];
|
|
28105
|
+
var key;
|
|
28106
|
+
if (shpA == -1) return null;
|
|
28107
|
+
key = getKey(shpA, shpB);
|
|
28108
|
+
if (key === null || key === false) return null;
|
|
28109
|
+
if (useOnce) {
|
|
28110
|
+
// arc can only be queried once
|
|
28111
|
+
a[i] = -1;
|
|
28112
|
+
b[i] = -1;
|
|
28113
|
+
}
|
|
28114
|
+
// use optional filter to exclude some arcs
|
|
28115
|
+
if (opts.filter && !opts.filter(shpA, shpB)) return null;
|
|
28116
|
+
return key;
|
|
28117
|
+
}
|
|
28118
|
+
|
|
28119
|
+
return function(getKey) {
|
|
28120
|
+
return function(arcId) {
|
|
28121
|
+
return classify(arcId, getKey);
|
|
28122
|
+
};
|
|
28123
|
+
};
|
|
28124
|
+
}
|
|
28125
|
+
|
|
28126
|
+
var ArcClassifier = /*#__PURE__*/Object.freeze({
|
|
28127
|
+
__proto__: null,
|
|
28128
|
+
getArcClassifier: getArcClassifier
|
|
28129
|
+
});
|
|
28130
|
+
|
|
28131
|
+
// Returns a function for querying the neighbors of a given shape. The function
|
|
28132
|
+
// can be called in either of two ways:
|
|
28133
|
+
//
|
|
28134
|
+
// 1. function(shapeId, callback)
|
|
28135
|
+
// Callback signature: function(adjacentShapeId, arcId)
|
|
28136
|
+
// The callback function is called once for each arc that the given feature
|
|
28137
|
+
// shares with another feature.
|
|
28138
|
+
//
|
|
28139
|
+
// 2. function(shapeId)
|
|
28140
|
+
// The function returns an array of unique ids of neighboring shapes, or
|
|
28141
|
+
// an empty array if a shape has no neighbors.
|
|
28142
|
+
//
|
|
28143
|
+
function getNeighborLookupFunction(lyr, arcs) {
|
|
28144
|
+
var classifier = getArcClassifier(lyr.shapes, arcs, {reusable: true});
|
|
28145
|
+
var classify = classifier(onShapes);
|
|
28146
|
+
var currShapeId;
|
|
28147
|
+
var neighbors;
|
|
28148
|
+
var callback;
|
|
28149
|
+
|
|
28150
|
+
function onShapes(a, b) {
|
|
28151
|
+
if (b == -1) return -1; // outer edges are b == -1
|
|
28152
|
+
return a == currShapeId ? b : a;
|
|
28153
|
+
}
|
|
28154
|
+
|
|
28155
|
+
function onArc(arcId) {
|
|
28156
|
+
var nabeId = classify(arcId);
|
|
28157
|
+
if (nabeId == -1) return;
|
|
28158
|
+
if (callback) {
|
|
28159
|
+
callback(nabeId, arcId);
|
|
28160
|
+
} else if (neighbors.indexOf(nabeId) == -1) {
|
|
28161
|
+
neighbors.push(nabeId);
|
|
28162
|
+
}
|
|
28163
|
+
}
|
|
28164
|
+
|
|
28165
|
+
return function(shpId, cb) {
|
|
28166
|
+
currShapeId = shpId;
|
|
28167
|
+
if (cb) {
|
|
28168
|
+
callback = cb;
|
|
28169
|
+
forEachArcId(lyr.shapes[shpId], onArc);
|
|
28170
|
+
callback = null;
|
|
28171
|
+
} else {
|
|
28172
|
+
neighbors = [];
|
|
28173
|
+
forEachArcId(lyr.shapes[shpId], onArc);
|
|
28174
|
+
return neighbors;
|
|
28175
|
+
}
|
|
28176
|
+
};
|
|
28177
|
+
}
|
|
28178
|
+
|
|
28179
|
+
|
|
28180
|
+
// Returns an array containing all pairs of adjacent shapes
|
|
28181
|
+
// in a collection of polygon shapes. A pair of shapes is represented as
|
|
28182
|
+
// an array of two shape indexes [a, b].
|
|
28183
|
+
function findPairsOfNeighbors(shapes, arcs) {
|
|
28184
|
+
var getKey = function(a, b) {
|
|
28185
|
+
return b > -1 && a > -1 ? [a, b] : null;
|
|
28186
|
+
};
|
|
28187
|
+
var classify = getArcClassifier(shapes, arcs)(getKey);
|
|
28188
|
+
var arr = [];
|
|
28189
|
+
var index = {};
|
|
28190
|
+
var onArc = function(arcId) {
|
|
28191
|
+
var obj = classify(arcId);
|
|
28192
|
+
var key;
|
|
28193
|
+
if (obj) {
|
|
28194
|
+
key = obj.join('~');
|
|
28195
|
+
if (key in index === false) {
|
|
28196
|
+
arr.push(obj);
|
|
28197
|
+
index[key] = true;
|
|
28198
|
+
}
|
|
28199
|
+
}
|
|
28200
|
+
};
|
|
28201
|
+
forEachArcId(shapes, onArc);
|
|
28202
|
+
return arr;
|
|
28203
|
+
}
|
|
28204
|
+
|
|
28205
|
+
var PolygonNeighbors = /*#__PURE__*/Object.freeze({
|
|
28206
|
+
__proto__: null,
|
|
28207
|
+
getNeighborLookupFunction: getNeighborLookupFunction,
|
|
28208
|
+
findPairsOfNeighbors: findPairsOfNeighbors
|
|
28209
|
+
});
|
|
28210
|
+
|
|
28211
|
+
function getNonAdjacentClassifier(lyr, dataset, colors) {
|
|
28212
|
+
requirePolygonLayer(lyr);
|
|
28213
|
+
var getNeighbors = getNeighborLookupFunction(lyr, dataset.arcs);
|
|
28214
|
+
var errorCount = 0;
|
|
28215
|
+
var data = utils.range(getFeatureCount(lyr)).map(function(shpId) {
|
|
28216
|
+
var nabes = getNeighbors(shpId) || [];
|
|
28217
|
+
return {
|
|
28218
|
+
nabes: nabes,
|
|
28219
|
+
n: nabes.length,
|
|
28220
|
+
colorId: -1
|
|
28221
|
+
};
|
|
28222
|
+
});
|
|
28223
|
+
var getSortedColorIds = getUpdateFunction(colors.length);
|
|
28224
|
+
var colorIds = getSortedColorIds();
|
|
28225
|
+
// Sort adjacency data by number of neighbors in descending order
|
|
28226
|
+
var sorted = data.concat();
|
|
28227
|
+
utils.sortOn(sorted, 'n', false);
|
|
28228
|
+
// Assign colors, starting with polygons with the largest number of neighbors
|
|
28229
|
+
sorted.forEach(function(d) {
|
|
28230
|
+
var colorId = pickColor(d, data, colorIds);
|
|
28231
|
+
if (colorId == -1) {
|
|
28232
|
+
errorCount++;
|
|
28233
|
+
colorId = colorIds[0];
|
|
28234
|
+
}
|
|
28235
|
+
d.colorId = colorId;
|
|
28236
|
+
colorIds = getSortedColorIds(colorId);
|
|
28237
|
+
});
|
|
28238
|
+
|
|
28239
|
+
if (errorCount > 0) {
|
|
28240
|
+
message(`Unable to find non-adjacent colors for ${errorCount} ${errorCount == 1 ? 'polygon' : 'polygons'}`);
|
|
28241
|
+
}
|
|
28242
|
+
return function(shpId) {
|
|
28243
|
+
return colors[data[shpId].colorId];
|
|
28244
|
+
};
|
|
28245
|
+
}
|
|
28246
|
+
|
|
28247
|
+
// Pick the id of a color that is not shared with a neighboring polygon
|
|
28248
|
+
function pickColor(d, data, colorIds) {
|
|
28249
|
+
var candidateId;
|
|
28250
|
+
for (var i=0; i<colorIds.length; i++) {
|
|
28251
|
+
candidateId = colorIds[i];
|
|
28252
|
+
if (isAvailableColor(d, data, candidateId)) {
|
|
28253
|
+
return candidateId;
|
|
28254
|
+
}
|
|
28255
|
+
}
|
|
28256
|
+
return -1; // no colors are available
|
|
28257
|
+
}
|
|
28258
|
+
|
|
28259
|
+
function isAvailableColor(d, data, colorId) {
|
|
28260
|
+
var nabes = d.nabes;
|
|
28261
|
+
for (var i=0; i<nabes.length; i++) {
|
|
28262
|
+
if (data[nabes[i]].colorId === colorId) return false;
|
|
28263
|
+
}
|
|
28264
|
+
return true;
|
|
28265
|
+
}
|
|
28266
|
+
|
|
28267
|
+
// Update function returns an array of ids, sorted in descending order of preference
|
|
28268
|
+
// (less-used ids are preferred).
|
|
28269
|
+
// Function recieves an (optional) id that was just used.
|
|
28270
|
+
function getUpdateFunction(n) {
|
|
28271
|
+
var ids = utils.range(n);
|
|
28272
|
+
var counts = new Uint32Array(n);
|
|
28273
|
+
return function(i) {
|
|
28274
|
+
if (i >= 0 && i < n) {
|
|
28275
|
+
counts[i]++;
|
|
28276
|
+
utils.sortArrayIndex(ids, counts, true);
|
|
28277
|
+
} else if (i !== undefined) {
|
|
28278
|
+
error('Unexpected color index:', i);
|
|
28279
|
+
}
|
|
28280
|
+
return ids;
|
|
28281
|
+
};
|
|
28282
|
+
}
|
|
28283
|
+
|
|
28284
|
+
cmd.classify = function(lyr, dataset, optsArg) {
|
|
28285
|
+
if (!lyr.data) {
|
|
28286
|
+
initDataTable(lyr);
|
|
28287
|
+
}
|
|
28029
28288
|
var opts = optsArg || {};
|
|
28030
28289
|
var records = lyr.data && lyr.data.getRecords();
|
|
28031
28290
|
var nullValue = opts.null_value || null;
|
|
28032
28291
|
var looksLikeColors = !!opts.colors || !!opts.color_scheme;
|
|
28033
28292
|
var colorScheme;
|
|
28034
|
-
var classValues,
|
|
28293
|
+
var classValues, classifyByValue, classifyById;
|
|
28035
28294
|
var numBuckets, numValues;
|
|
28036
28295
|
var dataField, outputField;
|
|
28037
28296
|
|
|
28038
28297
|
// validate explicitly set classes
|
|
28039
28298
|
if (opts.classes) {
|
|
28040
28299
|
if (!utils.isInteger(opts.classes) || opts.classes > 1 === false) {
|
|
28041
|
-
stop('Invalid classes
|
|
28300
|
+
stop('Invalid number of classes:', opts.classes, '(expected a value greater than 1)');
|
|
28042
28301
|
}
|
|
28043
28302
|
numBuckets = opts.classes;
|
|
28044
28303
|
}
|
|
28045
28304
|
|
|
28046
|
-
|
|
28047
28305
|
// TODO: better validation of breaks values
|
|
28048
28306
|
if (opts.breaks) {
|
|
28049
28307
|
numBuckets = opts.breaks.length + 1;
|
|
@@ -28061,9 +28319,6 @@ ${svg}
|
|
|
28061
28319
|
|
|
28062
28320
|
} else if (opts.field) {
|
|
28063
28321
|
dataField = opts.field;
|
|
28064
|
-
|
|
28065
|
-
} else {
|
|
28066
|
-
stop('Missing a data field to classify');
|
|
28067
28322
|
}
|
|
28068
28323
|
|
|
28069
28324
|
// expand categories if value is '*'
|
|
@@ -28071,7 +28326,18 @@ ${svg}
|
|
|
28071
28326
|
opts.categories = getUniqFieldValues(records, dataField);
|
|
28072
28327
|
}
|
|
28073
28328
|
|
|
28074
|
-
|
|
28329
|
+
if (opts.method == 'non-adjacent') {
|
|
28330
|
+
if (lyr.geometry_type != 'polygon') {
|
|
28331
|
+
stop('The non-adjacent option requires a polygon layer');
|
|
28332
|
+
}
|
|
28333
|
+
if (dataField) {
|
|
28334
|
+
stop('The non-adjacent option does not accept a data field argument');
|
|
28335
|
+
}
|
|
28336
|
+
} else if (!dataField) {
|
|
28337
|
+
stop('Missing a data field to classify');
|
|
28338
|
+
} else {
|
|
28339
|
+
requireDataField(lyr.data, dataField);
|
|
28340
|
+
}
|
|
28075
28341
|
|
|
28076
28342
|
if (numBuckets) {
|
|
28077
28343
|
numValues = opts.continuous ? numBuckets + 1 : numBuckets;
|
|
@@ -28139,15 +28405,25 @@ ${svg}
|
|
|
28139
28405
|
|
|
28140
28406
|
// get a function to convert input data to class indexes
|
|
28141
28407
|
//
|
|
28142
|
-
if (opts.
|
|
28408
|
+
if (opts.method == 'non-adjacent') {
|
|
28409
|
+
classifyById = getNonAdjacentClassifier(lyr, dataset, classValues);
|
|
28410
|
+
} else if (opts.index_field) {
|
|
28143
28411
|
// data is pre-classified... just read the index from a field
|
|
28144
|
-
|
|
28412
|
+
classifyByValue = getIndexedClassifier(classValues, nullValue, opts);
|
|
28145
28413
|
} else if (opts.categories) {
|
|
28146
|
-
|
|
28414
|
+
classifyByValue = getCategoricalClassifier(classValues, nullValue, opts);
|
|
28147
28415
|
} else {
|
|
28148
|
-
|
|
28416
|
+
classifyByValue = getSequentialClassifier(classValues, nullValue, getFieldValues(records, dataField), opts);
|
|
28417
|
+
}
|
|
28418
|
+
|
|
28419
|
+
if (classifyByValue) {
|
|
28420
|
+
classifyById = function(id) {
|
|
28421
|
+
var d = records[id] || {};
|
|
28422
|
+
return classifyByValue(d[dataField]);
|
|
28423
|
+
};
|
|
28149
28424
|
}
|
|
28150
28425
|
|
|
28426
|
+
|
|
28151
28427
|
// get the name of the output field
|
|
28152
28428
|
//
|
|
28153
28429
|
if (looksLikeColors) {
|
|
@@ -28163,8 +28439,7 @@ ${svg}
|
|
|
28163
28439
|
}
|
|
28164
28440
|
|
|
28165
28441
|
records.forEach(function(d, i) {
|
|
28166
|
-
d =
|
|
28167
|
-
d[outputField] = classify(d[dataField]);
|
|
28442
|
+
d[outputField] = classifyById(i);
|
|
28168
28443
|
});
|
|
28169
28444
|
};
|
|
28170
28445
|
|
|
@@ -28976,147 +29251,6 @@ ${svg}
|
|
|
28976
29251
|
getClipMessage: getClipMessage
|
|
28977
29252
|
});
|
|
28978
29253
|
|
|
28979
|
-
// Returns a function for constructing a query function that accepts an arc id and
|
|
28980
|
-
// returns information about the polygon or polygons that use the given arc.
|
|
28981
|
-
// TODO: explain this better.
|
|
28982
|
-
//
|
|
28983
|
-
// options:
|
|
28984
|
-
// filter: optional filter function; signature: function(idA, idB or -1) : boolean
|
|
28985
|
-
// reusable: flag that lets an arc be queried multiple times.
|
|
28986
|
-
function getArcClassifier(shapes, arcs) {
|
|
28987
|
-
var opts = arguments[2] || {},
|
|
28988
|
-
useOnce = !opts.reusable,
|
|
28989
|
-
n = arcs.size(),
|
|
28990
|
-
a = new Int32Array(n),
|
|
28991
|
-
b = new Int32Array(n);
|
|
28992
|
-
|
|
28993
|
-
utils.initializeArray(a, -1);
|
|
28994
|
-
utils.initializeArray(b, -1);
|
|
28995
|
-
|
|
28996
|
-
traversePaths(shapes, function(o) {
|
|
28997
|
-
var i = absArcId(o.arcId);
|
|
28998
|
-
var shpId = o.shapeId;
|
|
28999
|
-
var aval = a[i];
|
|
29000
|
-
if (aval == -1) {
|
|
29001
|
-
a[i] = shpId;
|
|
29002
|
-
} else if (shpId < aval) {
|
|
29003
|
-
b[i] = aval;
|
|
29004
|
-
a[i] = shpId;
|
|
29005
|
-
} else {
|
|
29006
|
-
b[i] = shpId;
|
|
29007
|
-
}
|
|
29008
|
-
});
|
|
29009
|
-
|
|
29010
|
-
function classify(arcId, getKey) {
|
|
29011
|
-
var i = absArcId(arcId);
|
|
29012
|
-
var shpA = a[i];
|
|
29013
|
-
var shpB = b[i];
|
|
29014
|
-
var key;
|
|
29015
|
-
if (shpA == -1) return null;
|
|
29016
|
-
key = getKey(shpA, shpB);
|
|
29017
|
-
if (key === null || key === false) return null;
|
|
29018
|
-
if (useOnce) {
|
|
29019
|
-
// arc can only be queried once
|
|
29020
|
-
a[i] = -1;
|
|
29021
|
-
b[i] = -1;
|
|
29022
|
-
}
|
|
29023
|
-
// use optional filter to exclude some arcs
|
|
29024
|
-
if (opts.filter && !opts.filter(shpA, shpB)) return null;
|
|
29025
|
-
return key;
|
|
29026
|
-
}
|
|
29027
|
-
|
|
29028
|
-
return function(getKey) {
|
|
29029
|
-
return function(arcId) {
|
|
29030
|
-
return classify(arcId, getKey);
|
|
29031
|
-
};
|
|
29032
|
-
};
|
|
29033
|
-
}
|
|
29034
|
-
|
|
29035
|
-
var ArcClassifier = /*#__PURE__*/Object.freeze({
|
|
29036
|
-
__proto__: null,
|
|
29037
|
-
getArcClassifier: getArcClassifier
|
|
29038
|
-
});
|
|
29039
|
-
|
|
29040
|
-
// Returns a function for querying the neighbors of a given shape. The function
|
|
29041
|
-
// can be called in either of two ways:
|
|
29042
|
-
//
|
|
29043
|
-
// 1. function(shapeId, callback)
|
|
29044
|
-
// Callback signature: function(adjacentShapeId, arcId)
|
|
29045
|
-
// The callback function is called once for each arc that the given feature
|
|
29046
|
-
// shares with another feature.
|
|
29047
|
-
//
|
|
29048
|
-
// 2. function(shapeId)
|
|
29049
|
-
// The function returns an array of unique ids of neighboring shapes, or
|
|
29050
|
-
// an empty array if a shape has no neighbors.
|
|
29051
|
-
//
|
|
29052
|
-
function getNeighborLookupFunction(lyr, arcs) {
|
|
29053
|
-
var classifier = getArcClassifier(lyr.shapes, arcs, {reusable: true});
|
|
29054
|
-
var classify = classifier(onShapes);
|
|
29055
|
-
var currShapeId;
|
|
29056
|
-
var neighbors;
|
|
29057
|
-
var callback;
|
|
29058
|
-
|
|
29059
|
-
function onShapes(a, b) {
|
|
29060
|
-
if (b == -1) return -1; // outer edges are b == -1
|
|
29061
|
-
return a == currShapeId ? b : a;
|
|
29062
|
-
}
|
|
29063
|
-
|
|
29064
|
-
function onArc(arcId) {
|
|
29065
|
-
var nabeId = classify(arcId);
|
|
29066
|
-
if (nabeId == -1) return;
|
|
29067
|
-
if (callback) {
|
|
29068
|
-
callback(nabeId, arcId);
|
|
29069
|
-
} else if (neighbors.indexOf(nabeId) == -1) {
|
|
29070
|
-
neighbors.push(nabeId);
|
|
29071
|
-
}
|
|
29072
|
-
}
|
|
29073
|
-
|
|
29074
|
-
return function(shpId, cb) {
|
|
29075
|
-
currShapeId = shpId;
|
|
29076
|
-
if (cb) {
|
|
29077
|
-
callback = cb;
|
|
29078
|
-
forEachArcId(lyr.shapes[shpId], onArc);
|
|
29079
|
-
callback = null;
|
|
29080
|
-
} else {
|
|
29081
|
-
neighbors = [];
|
|
29082
|
-
forEachArcId(lyr.shapes[shpId], onArc);
|
|
29083
|
-
return neighbors;
|
|
29084
|
-
}
|
|
29085
|
-
};
|
|
29086
|
-
}
|
|
29087
|
-
|
|
29088
|
-
|
|
29089
|
-
// Returns an array containing all pairs of adjacent shapes
|
|
29090
|
-
// in a collection of polygon shapes. A pair of shapes is represented as
|
|
29091
|
-
// an array of two shape indexes [a, b].
|
|
29092
|
-
function findPairsOfNeighbors(shapes, arcs) {
|
|
29093
|
-
var getKey = function(a, b) {
|
|
29094
|
-
return b > -1 && a > -1 ? [a, b] : null;
|
|
29095
|
-
};
|
|
29096
|
-
var classify = getArcClassifier(shapes, arcs)(getKey);
|
|
29097
|
-
var arr = [];
|
|
29098
|
-
var index = {};
|
|
29099
|
-
var onArc = function(arcId) {
|
|
29100
|
-
var obj = classify(arcId);
|
|
29101
|
-
var key;
|
|
29102
|
-
if (obj) {
|
|
29103
|
-
key = obj.join('~');
|
|
29104
|
-
if (key in index === false) {
|
|
29105
|
-
arr.push(obj);
|
|
29106
|
-
index[key] = true;
|
|
29107
|
-
}
|
|
29108
|
-
}
|
|
29109
|
-
};
|
|
29110
|
-
forEachArcId(shapes, onArc);
|
|
29111
|
-
return arr;
|
|
29112
|
-
}
|
|
29113
|
-
|
|
29114
|
-
var PolygonNeighbors = /*#__PURE__*/Object.freeze({
|
|
29115
|
-
__proto__: null,
|
|
29116
|
-
getNeighborLookupFunction: getNeighborLookupFunction,
|
|
29117
|
-
findPairsOfNeighbors: findPairsOfNeighbors
|
|
29118
|
-
});
|
|
29119
|
-
|
|
29120
29254
|
// Assign a cluster id to each polygon in a dataset, which can be used with
|
|
29121
29255
|
// one of the dissolve commands to dissolve the clusters
|
|
29122
29256
|
// Works by iteratively grouping pairs of polygons with the smallest distance
|
|
@@ -29803,12 +29937,19 @@ ${svg}
|
|
|
29803
29937
|
});
|
|
29804
29938
|
|
|
29805
29939
|
// Join data from @src table to records in @dest table
|
|
29940
|
+
function joinTables(dest, src, join, opts) {
|
|
29941
|
+
return joinTableToLayer({data: dest}, src, join, opts);
|
|
29942
|
+
}
|
|
29943
|
+
|
|
29944
|
+
// Join data from @src table to records in @destLyr layer.
|
|
29806
29945
|
// @join function
|
|
29807
29946
|
// Receives index of record in the dest table
|
|
29808
29947
|
// Returns array of matching records in src table, or null if no matches
|
|
29809
29948
|
//
|
|
29810
|
-
function
|
|
29811
|
-
var
|
|
29949
|
+
function joinTableToLayer(destLyr, src, join, opts) {
|
|
29950
|
+
var dest = destLyr.data,
|
|
29951
|
+
useDuplication = !!opts.duplication,
|
|
29952
|
+
srcRecords = src.getRecords(),
|
|
29812
29953
|
destRecords = dest.getRecords(),
|
|
29813
29954
|
prefix = opts.prefix || '',
|
|
29814
29955
|
unmatchedRecords = [],
|
|
@@ -29823,6 +29964,14 @@ ${svg}
|
|
|
29823
29964
|
retn = {},
|
|
29824
29965
|
srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
|
|
29825
29966
|
|
|
29967
|
+
// support for duplication of destination records
|
|
29968
|
+
var duplicateRecords, destShapes;
|
|
29969
|
+
if (useDuplication) {
|
|
29970
|
+
if (opts.calc) stop('duplication and calc options cannot be used together');
|
|
29971
|
+
duplicateRecords = dest.clone().getRecords();
|
|
29972
|
+
destShapes = destLyr.shapes || [];
|
|
29973
|
+
}
|
|
29974
|
+
|
|
29826
29975
|
if (opts.where) {
|
|
29827
29976
|
filter = getJoinFilter(src, opts.where);
|
|
29828
29977
|
}
|
|
@@ -29832,7 +29981,8 @@ ${svg}
|
|
|
29832
29981
|
}
|
|
29833
29982
|
|
|
29834
29983
|
// join source records to target records
|
|
29835
|
-
|
|
29984
|
+
n = destRecords.length;
|
|
29985
|
+
for (i=0; i<n; i++) {
|
|
29836
29986
|
destRec = destRecords[i];
|
|
29837
29987
|
joins = join(i);
|
|
29838
29988
|
if (joins && filter) {
|
|
@@ -29843,7 +29993,13 @@ ${svg}
|
|
|
29843
29993
|
for (j=0, count=0, m=joins ? joins.length : 0; j<m; j++) {
|
|
29844
29994
|
srcId = joins[j];
|
|
29845
29995
|
srcRec = srcRecords[srcId];
|
|
29846
|
-
|
|
29996
|
+
// duplication mode: many-to-one joins add new features to the target layer.
|
|
29997
|
+
if (count > 0 && useDuplication) {
|
|
29998
|
+
destRec = copyRecord(duplicateRecords[i]);
|
|
29999
|
+
destRecords.push(destRec);
|
|
30000
|
+
destShapes.push(cloneShape(destShapes[i]));
|
|
30001
|
+
}
|
|
30002
|
+
if (count === 0 || useDuplication) {
|
|
29847
30003
|
if (copyFields.length > 0) {
|
|
29848
30004
|
// only copying the first match
|
|
29849
30005
|
joinByCopy(destRec, srcRec, copyFields, prefix);
|
|
@@ -29875,7 +30031,7 @@ ${svg}
|
|
|
29875
30031
|
}
|
|
29876
30032
|
}
|
|
29877
30033
|
|
|
29878
|
-
printJoinMessage(matchCount,
|
|
30034
|
+
printJoinMessage(matchCount, n,
|
|
29879
30035
|
countJoins(joinCounts), srcRecords.length, skipCount, collisionCount, collisionFields);
|
|
29880
30036
|
|
|
29881
30037
|
if (opts.unjoined) {
|
|
@@ -29903,6 +30059,7 @@ ${svg}
|
|
|
29903
30059
|
});
|
|
29904
30060
|
}
|
|
29905
30061
|
|
|
30062
|
+
|
|
29906
30063
|
function countJoins(counts) {
|
|
29907
30064
|
var joinCount = 0;
|
|
29908
30065
|
for (var i=0, n=counts.length; i<n; i++) {
|
|
@@ -29965,14 +30122,16 @@ ${svg}
|
|
|
29965
30122
|
|
|
29966
30123
|
function printJoinMessage(matches, n, joins, m, skipped, collisions, collisionFields) {
|
|
29967
30124
|
// TODO: add tip for troubleshooting join problems, if join is less than perfect.
|
|
30125
|
+
var unmatched = n - matches;
|
|
29968
30126
|
if (matches > 0 === false) {
|
|
29969
30127
|
message("No records could be joined");
|
|
29970
30128
|
return;
|
|
29971
30129
|
}
|
|
29972
30130
|
message(utils.format("Joined data from %'d source record%s to %'d target record%s",
|
|
29973
30131
|
joins, utils.pluralSuffix(joins), matches, utils.pluralSuffix(matches)));
|
|
29974
|
-
if (
|
|
29975
|
-
message(utils.format('%d
|
|
30132
|
+
if (unmatched > 0) {
|
|
30133
|
+
message(utils.format('%d target record%s received no data', unmatched, utils.pluralSuffix(unmatched)));
|
|
30134
|
+
// message(utils.format('%d target records received no data', n-matches));
|
|
29976
30135
|
}
|
|
29977
30136
|
if (joins < m) {
|
|
29978
30137
|
message(utils.format("%d/%d source records could not be joined", m-joins, m));
|
|
@@ -30021,6 +30180,7 @@ ${svg}
|
|
|
30021
30180
|
var JoinTables = /*#__PURE__*/Object.freeze({
|
|
30022
30181
|
__proto__: null,
|
|
30023
30182
|
joinTables: joinTables,
|
|
30183
|
+
joinTableToLayer: joinTableToLayer,
|
|
30024
30184
|
validateFieldNames: validateFieldNames,
|
|
30025
30185
|
updateUnmatchedRecord: updateUnmatchedRecord,
|
|
30026
30186
|
findCollisionFields: findCollisionFields,
|
|
@@ -31487,13 +31647,13 @@ ${svg}
|
|
|
31487
31647
|
// TODO: option to copy points that can't be joined to a new layer
|
|
31488
31648
|
var joinFunction = getPolygonToPointsFunction(targetLyr, arcs, pointLyr, opts);
|
|
31489
31649
|
prepJoinLayers(targetLyr, pointLyr);
|
|
31490
|
-
return
|
|
31650
|
+
return joinTableToLayer(targetLyr, pointLyr.data, joinFunction, opts);
|
|
31491
31651
|
}
|
|
31492
31652
|
|
|
31493
31653
|
function joinPolygonsToPoints(targetLyr, polygonLyr, arcs, opts) {
|
|
31494
31654
|
var joinFunction = getPointToPolygonsFunction(targetLyr, polygonLyr, arcs, opts);
|
|
31495
31655
|
prepJoinLayers(targetLyr, polygonLyr);
|
|
31496
|
-
return
|
|
31656
|
+
return joinTableToLayer(targetLyr, polygonLyr.data, joinFunction, opts);
|
|
31497
31657
|
}
|
|
31498
31658
|
|
|
31499
31659
|
|
|
@@ -33279,6 +33439,12 @@ ${svg}
|
|
|
33279
33439
|
};
|
|
33280
33440
|
}
|
|
33281
33441
|
|
|
33442
|
+
cmd.ignore = function(targetLayer, dataset, opts) {
|
|
33443
|
+
if (opts.empty && layerIsEmpty(targetLayer)) {
|
|
33444
|
+
interrupt('Layer is empty, stopping processing');
|
|
33445
|
+
}
|
|
33446
|
+
};
|
|
33447
|
+
|
|
33282
33448
|
cmd.include = function(opts) {
|
|
33283
33449
|
var content, obj, context;
|
|
33284
33450
|
// TODO: handle web context
|
|
@@ -33654,9 +33820,10 @@ ${svg}
|
|
|
33654
33820
|
|
|
33655
33821
|
var joinOpts = utils.extend({}, opts);
|
|
33656
33822
|
var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33657
|
-
var retn =
|
|
33823
|
+
var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
|
|
33658
33824
|
|
|
33659
33825
|
if (opts.interpolate) {
|
|
33826
|
+
if (opts.duplication) stop('duplication and interpolate options cannot be used together');
|
|
33660
33827
|
interpolateFieldsByArea(targetLyr, sourceLyr, mosaicIndex, opts);
|
|
33661
33828
|
}
|
|
33662
33829
|
return retn;
|
|
@@ -34571,7 +34738,7 @@ ${svg}
|
|
|
34571
34738
|
function joinPointsToPoints(targetLyr, srcLyr, crs, opts) {
|
|
34572
34739
|
var joinFunction = getPointToPointFunction(targetLyr, srcLyr, crs, opts);
|
|
34573
34740
|
prepJoinLayers(targetLyr, srcLyr);
|
|
34574
|
-
return
|
|
34741
|
+
return joinTableToLayer(targetLyr, srcLyr.data, joinFunction, opts);
|
|
34575
34742
|
}
|
|
34576
34743
|
|
|
34577
34744
|
function getPointToPointFunction(targetLyr, srcLyr, crs, opts) {
|
|
@@ -34621,14 +34788,14 @@ ${svg}
|
|
|
34621
34788
|
}
|
|
34622
34789
|
};
|
|
34623
34790
|
|
|
34624
|
-
function joinAttributesToFeatures(
|
|
34791
|
+
function joinAttributesToFeatures(destLyr, srcTable, opts) {
|
|
34625
34792
|
var keys = opts.keys,
|
|
34626
34793
|
destKey = keys[0],
|
|
34627
34794
|
srcKey = keys[1],
|
|
34628
|
-
destTable =
|
|
34795
|
+
destTable = destLyr.data,
|
|
34629
34796
|
joinFunction = getJoinByKey(destTable, destKey, srcTable, srcKey);
|
|
34630
34797
|
validateFieldNames(keys);
|
|
34631
|
-
return
|
|
34798
|
+
return joinTableToLayer(destLyr, srcTable, joinFunction, opts);
|
|
34632
34799
|
}
|
|
34633
34800
|
|
|
34634
34801
|
// Return a function for translating a target id to an array of source ids based on values
|
|
@@ -37620,7 +37787,7 @@ ${svg}
|
|
|
37620
37787
|
applyCommandToEachLayer(cmd.calc, targetLayers, arcs, opts);
|
|
37621
37788
|
|
|
37622
37789
|
} else if (name == 'classify') {
|
|
37623
|
-
applyCommandToEachLayer(cmd.classify, targetLayers, opts);
|
|
37790
|
+
applyCommandToEachLayer(cmd.classify, targetLayers, targetDataset, opts);
|
|
37624
37791
|
|
|
37625
37792
|
} else if (name == 'clean') {
|
|
37626
37793
|
cmd.cleanLayers(targetLayers, targetDataset, opts);
|
|
@@ -37704,6 +37871,9 @@ ${svg}
|
|
|
37704
37871
|
outputLayers = targetDataset.layers; // kludge to allow layer naming below
|
|
37705
37872
|
}
|
|
37706
37873
|
|
|
37874
|
+
} else if (name == 'ignore') {
|
|
37875
|
+
applyCommandToEachLayer(cmd.ignore, targetLayers, targetDataset, opts);
|
|
37876
|
+
|
|
37707
37877
|
} else if (name == 'include') {
|
|
37708
37878
|
cmd.include(opts);
|
|
37709
37879
|
|
|
@@ -38074,6 +38244,7 @@ ${svg}
|
|
|
38074
38244
|
cmd.options.output = outputArr;
|
|
38075
38245
|
}
|
|
38076
38246
|
});
|
|
38247
|
+
|
|
38077
38248
|
runParsedCommands(commands, null, callback);
|
|
38078
38249
|
}
|
|
38079
38250
|
|
|
@@ -38134,10 +38305,6 @@ ${svg}
|
|
|
38134
38305
|
error("Changed in v0.4: runParsedCommands() takes a Catalog object");
|
|
38135
38306
|
}
|
|
38136
38307
|
|
|
38137
|
-
if (!utils.isFunction(done)) {
|
|
38138
|
-
error("Missing a callback function");
|
|
38139
|
-
}
|
|
38140
|
-
|
|
38141
38308
|
if (!utils.isArray(commands)) {
|
|
38142
38309
|
error("Expected an array of parsed commands");
|
|
38143
38310
|
}
|
|
@@ -38158,18 +38325,25 @@ ${svg}
|
|
|
38158
38325
|
// that it can modify the output dataset in-place instead of making a copy.
|
|
38159
38326
|
commands[commands.length-1].options.final = true;
|
|
38160
38327
|
}
|
|
38161
|
-
commands = divideImportCommand(commands);
|
|
38162
|
-
utils.reduceAsync(commands, catalog, nextCommand, done);
|
|
38163
38328
|
|
|
38164
|
-
|
|
38165
|
-
|
|
38166
|
-
|
|
38167
|
-
|
|
38168
|
-
|
|
38329
|
+
var groups = divideImportCommand(commands);
|
|
38330
|
+
if (groups.length == 1) {
|
|
38331
|
+
// run a simple sequence of commands (input files are not batched)
|
|
38332
|
+
return runParsedCommands2(commands, catalog, done);
|
|
38333
|
+
}
|
|
38334
|
+
|
|
38335
|
+
// run duplicated commands (i.e. batch mode)
|
|
38336
|
+
utils.reduceAsync(groups, catalog, nextGroup, done);
|
|
38337
|
+
|
|
38338
|
+
function nextGroup(catalog, commands, next) {
|
|
38339
|
+
runParsedCommands2(commands, catalog, function(err, catalog) {
|
|
38340
|
+
err = filterError(err);
|
|
38341
|
+
next(err, catalog);
|
|
38342
|
+
});
|
|
38169
38343
|
}
|
|
38170
38344
|
|
|
38171
38345
|
function done(err, catalog) {
|
|
38172
|
-
|
|
38346
|
+
err = filterError(err);
|
|
38173
38347
|
cb(err, catalog);
|
|
38174
38348
|
setStateVar('current_command', null);
|
|
38175
38349
|
setStateVar('verbose', false);
|
|
@@ -38177,11 +38351,31 @@ ${svg}
|
|
|
38177
38351
|
}
|
|
38178
38352
|
}
|
|
38179
38353
|
|
|
38354
|
+
function filterError(err) {
|
|
38355
|
+
if (err) printError(err);
|
|
38356
|
+
if (err && err.name == 'NonFatalError') {
|
|
38357
|
+
return null;
|
|
38358
|
+
}
|
|
38359
|
+
return err;
|
|
38360
|
+
}
|
|
38361
|
+
|
|
38362
|
+
function runParsedCommands2(commands, catalog, cb) {
|
|
38363
|
+
utils.reduceAsync(commands, catalog, nextCommand, cb);
|
|
38364
|
+
|
|
38365
|
+
function nextCommand(catalog, cmd, next) {
|
|
38366
|
+
setStateVar('current_command', cmd.name); // for log msgs
|
|
38367
|
+
setStateVar('verbose', !!cmd.options.verbose);
|
|
38368
|
+
setStateVar('debug', !!cmd.options.debug);
|
|
38369
|
+
runCommand(cmd, catalog, next);
|
|
38370
|
+
}
|
|
38371
|
+
}
|
|
38372
|
+
|
|
38373
|
+
|
|
38180
38374
|
// If an initial import command indicates that several input files should be
|
|
38181
38375
|
// processed separately, then duplicate the sequence of commands to run
|
|
38182
38376
|
// once for each input file
|
|
38183
38377
|
// @commands Array of parsed commands
|
|
38184
|
-
// Returns:
|
|
38378
|
+
// Returns: Array of one or more sequences of parsed commands
|
|
38185
38379
|
//
|
|
38186
38380
|
function divideImportCommand(commands) {
|
|
38187
38381
|
var firstCmd = commands[0],
|
|
@@ -38189,23 +38383,23 @@ ${svg}
|
|
|
38189
38383
|
|
|
38190
38384
|
if (firstCmd.name != 'i' || opts.stdin || opts.merge_files ||
|
|
38191
38385
|
opts.combine_files || !opts.files || opts.files.length < 2) {
|
|
38192
|
-
return commands;
|
|
38386
|
+
return [commands];
|
|
38193
38387
|
}
|
|
38194
38388
|
|
|
38195
|
-
return
|
|
38196
|
-
var
|
|
38389
|
+
return opts.files.map(function(file) {
|
|
38390
|
+
var group = [{
|
|
38197
38391
|
name: 'i',
|
|
38198
38392
|
options: utils.defaults({
|
|
38199
38393
|
files:[file],
|
|
38200
38394
|
replace: true // kludge to replace data catalog
|
|
38201
38395
|
}, opts)
|
|
38202
|
-
};
|
|
38203
|
-
|
|
38204
|
-
|
|
38205
|
-
|
|
38206
|
-
}, []);
|
|
38396
|
+
}];
|
|
38397
|
+
group.push.apply(group, commands.slice(1));
|
|
38398
|
+
return group;
|
|
38399
|
+
});
|
|
38207
38400
|
}
|
|
38208
38401
|
|
|
38402
|
+
|
|
38209
38403
|
function printStartupMessages() {
|
|
38210
38404
|
// print heap memory message if running with a custom amount
|
|
38211
38405
|
var rxp = /^--max-old-space-size=([0-9]+)$/;
|