mapshaper 0.5.91 → 0.5.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mapshaper-gui +16 -9
- package/mapshaper.js +90 -47
- package/package.json +2 -2
- package/www/index.html +1 -1
- package/www/mapshaper-gui.js +361 -291
- package/www/mapshaper.js +90 -47
package/bin/mapshaper-gui
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
var defaultPort = 5555,
|
|
4
|
-
|
|
4
|
+
commander = require('commander'),
|
|
5
|
+
program = new commander.Command()
|
|
5
6
|
.name('mapshaper-gui')
|
|
6
7
|
.usage('[options] [file ...]')
|
|
7
8
|
.option('-p, --port <port>', 'http port of server on localhost', defaultPort)
|
|
@@ -10,10 +11,13 @@ var defaultPort = 5555,
|
|
|
10
11
|
.option('-f, --force-save', 'allow overwriting input files with output files')
|
|
11
12
|
.option('-a, --display-all', 'turn on visibility of all layers')
|
|
12
13
|
.option('-n, --name <name(s)>', 'rename input layer or layers')
|
|
14
|
+
.option('-c, --commands <string>', 'console commands to run initially')
|
|
13
15
|
.option('-t, --target <name>', 'name of layer to select initially')
|
|
16
|
+
.addOption(new commander.Option('-b, --blurb <text>',
|
|
17
|
+
'replace the default blurb on the import screen').hideHelp())
|
|
14
18
|
.helpOption('-h, --help', 'show this help message')
|
|
15
19
|
.version(require('../package.json').version)
|
|
16
|
-
.parse(),
|
|
20
|
+
.parse(process.argv),
|
|
17
21
|
opts = program.opts(),
|
|
18
22
|
http = require("http"),
|
|
19
23
|
path = require("path"),
|
|
@@ -26,7 +30,6 @@ var defaultPort = 5555,
|
|
|
26
30
|
dataFiles = expandShapefiles(program.args),
|
|
27
31
|
probeCount = 0,
|
|
28
32
|
sessionId = null;
|
|
29
|
-
|
|
30
33
|
validateFiles(dataFiles);
|
|
31
34
|
|
|
32
35
|
process.on('uncaughtException', function(err) {
|
|
@@ -204,12 +207,16 @@ function validateOutputFile(file) {
|
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
function getManifestJS(files, opts) {
|
|
207
|
-
var o = {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
var o = {
|
|
211
|
+
files: files,
|
|
212
|
+
target: opts.target,
|
|
213
|
+
allow_saving: opts.directSave,
|
|
214
|
+
display_all: opts.displayAll,
|
|
215
|
+
quick_view: opts.quickView,
|
|
216
|
+
name: opts.name,
|
|
217
|
+
commands: opts.commands,
|
|
218
|
+
blurb: opts.blurb
|
|
219
|
+
};
|
|
213
220
|
return "mapshaper.manifest = " + JSON.stringify(o) + ";\n";
|
|
214
221
|
}
|
|
215
222
|
|
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.91";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -2158,6 +2158,7 @@
|
|
|
2158
2158
|
function getPointToPathInfo(px, py, ids, arcs) {
|
|
2159
2159
|
var iter = arcs.getShapeIter(ids);
|
|
2160
2160
|
var pPathSq = Infinity;
|
|
2161
|
+
var arcId;
|
|
2161
2162
|
var ax, ay, bx, by, axmin, aymin, bxmin, bymin, pabSq;
|
|
2162
2163
|
if (iter.hasNext()) {
|
|
2163
2164
|
ax = axmin = bxmin = iter.x;
|
|
@@ -2169,6 +2170,7 @@
|
|
|
2169
2170
|
pabSq = pointSegDistSq2(px, py, ax, ay, bx, by);
|
|
2170
2171
|
if (pabSq < pPathSq) {
|
|
2171
2172
|
pPathSq = pabSq;
|
|
2173
|
+
arcId = iter._ids[iter._i]; // kludge
|
|
2172
2174
|
axmin = ax;
|
|
2173
2175
|
aymin = ay;
|
|
2174
2176
|
bxmin = bx;
|
|
@@ -2180,7 +2182,8 @@
|
|
|
2180
2182
|
if (pPathSq == Infinity) return {distance: Infinity};
|
|
2181
2183
|
return {
|
|
2182
2184
|
segment: [[axmin, aymin], [bxmin, bymin]],
|
|
2183
|
-
distance: Math.sqrt(pPathSq)
|
|
2185
|
+
distance: Math.sqrt(pPathSq),
|
|
2186
|
+
arcId: arcId
|
|
2184
2187
|
};
|
|
2185
2188
|
}
|
|
2186
2189
|
|
|
@@ -2188,11 +2191,20 @@
|
|
|
2188
2191
|
// Return unsigned distance of a point to the nearest point on a polygon or polyline path
|
|
2189
2192
|
//
|
|
2190
2193
|
function getPointToShapeDistance(x, y, shp, arcs) {
|
|
2191
|
-
var
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2194
|
+
var info = getPointToShapeInfo(x, y, shp, arcs);
|
|
2195
|
+
return info ? info.distance : Infinity;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
function getPointToShapeInfo(x, y, shp, arcs) {
|
|
2199
|
+
return (shp || []).reduce(function(memo, ids) {
|
|
2200
|
+
var pathInfo = getPointToPathInfo(x, y, ids, arcs);
|
|
2201
|
+
if (!memo || pathInfo.distance < memo.distance) return pathInfo;
|
|
2202
|
+
return memo;
|
|
2203
|
+
}, null) || {
|
|
2204
|
+
distance: Infinity,
|
|
2205
|
+
arcId: -1,
|
|
2206
|
+
segment: null
|
|
2207
|
+
};
|
|
2196
2208
|
}
|
|
2197
2209
|
|
|
2198
2210
|
// @ids array of arc ids
|
|
@@ -2277,6 +2289,7 @@
|
|
|
2277
2289
|
getPointToPathDistance: getPointToPathDistance,
|
|
2278
2290
|
getPointToPathInfo: getPointToPathInfo,
|
|
2279
2291
|
getPointToShapeDistance: getPointToShapeDistance,
|
|
2292
|
+
getPointToShapeInfo: getPointToShapeInfo,
|
|
2280
2293
|
getAvgPathXY: getAvgPathXY,
|
|
2281
2294
|
getMaxPath: getMaxPath,
|
|
2282
2295
|
countVerticesInPath: countVerticesInPath,
|
|
@@ -5377,6 +5390,10 @@
|
|
|
5377
5390
|
};
|
|
5378
5391
|
};
|
|
5379
5392
|
|
|
5393
|
+
this.getVertex2 = function(i) {
|
|
5394
|
+
return [_xx[i], _yy[i]];
|
|
5395
|
+
};
|
|
5396
|
+
|
|
5380
5397
|
// @nth: index of vertex. ~(idx) starts from the opposite endpoint
|
|
5381
5398
|
this.indexOfVertex = function(arcId, nth) {
|
|
5382
5399
|
var absId = arcId < 0 ? ~arcId : arcId,
|
|
@@ -27167,7 +27184,7 @@ ${svg}
|
|
|
27167
27184
|
}
|
|
27168
27185
|
|
|
27169
27186
|
function samePoint(a, b) {
|
|
27170
|
-
return a[0] === b[0] && a[1] === b[1];
|
|
27187
|
+
return a && b && a[0] === b[0] && a[1] === b[1];
|
|
27171
27188
|
}
|
|
27172
27189
|
|
|
27173
27190
|
function isClosedPath(arr) {
|
|
@@ -27781,11 +27798,15 @@ ${svg}
|
|
|
27781
27798
|
}
|
|
27782
27799
|
|
|
27783
27800
|
function getCategoricalColorScheme(name, n) {
|
|
27801
|
+
var colors;
|
|
27784
27802
|
initSchemes();
|
|
27785
|
-
if (
|
|
27786
|
-
stop(
|
|
27803
|
+
if (!isColorSchemeName(name)) {
|
|
27804
|
+
stop('Unknown color scheme name:', name);
|
|
27805
|
+
} else if (isCategoricalColorScheme(name)) {
|
|
27806
|
+
colors = ramps[name] || require('d3-scale-chromatic')['scheme' + name];
|
|
27807
|
+
} else {
|
|
27808
|
+
colors = getColorRamp(name, n);
|
|
27787
27809
|
}
|
|
27788
|
-
var colors = ramps[name] || require('d3-scale-chromatic')['scheme' + name];
|
|
27789
27810
|
if (n > colors.length) {
|
|
27790
27811
|
stop(name, 'does not contain', n, 'colors');
|
|
27791
27812
|
}
|
|
@@ -27798,6 +27819,11 @@ ${svg}
|
|
|
27798
27819
|
index.diverging.includes(name) || index.rainbow.includes(name);
|
|
27799
27820
|
}
|
|
27800
27821
|
|
|
27822
|
+
function isCategoricalColorScheme(name) {
|
|
27823
|
+
initSchemes();
|
|
27824
|
+
return index.categorical.includes(name);
|
|
27825
|
+
}
|
|
27826
|
+
|
|
27801
27827
|
function getColorRamp(name, n, stops) {
|
|
27802
27828
|
initSchemes();
|
|
27803
27829
|
var lib = require('d3-scale-chromatic');
|
|
@@ -28287,7 +28313,7 @@ ${svg}
|
|
|
28287
28313
|
};
|
|
28288
28314
|
}
|
|
28289
28315
|
|
|
28290
|
-
function getSequentialClassifier$1(classValues, nullValue, dataValues, opts) {
|
|
28316
|
+
function getSequentialClassifier$1(classValues, nullValue, dataValues, method, opts) {
|
|
28291
28317
|
var numValues = classValues.length;
|
|
28292
28318
|
var numBuckets = opts.continuous ? numValues - 1 : numValues;
|
|
28293
28319
|
|
|
@@ -28295,7 +28321,6 @@ ${svg}
|
|
|
28295
28321
|
// discreetly classed values
|
|
28296
28322
|
var numBreaks = numBuckets - 1;
|
|
28297
28323
|
var round = opts.precision ? getRoundingFunction(opts.precision) : null;
|
|
28298
|
-
var method = opts.method || 'quantile';
|
|
28299
28324
|
var breaks, classifier, dataToClass, classToValue;
|
|
28300
28325
|
|
|
28301
28326
|
if (round) {
|
|
@@ -28900,34 +28925,35 @@ ${svg}
|
|
|
28900
28925
|
var opts = optsArg || {};
|
|
28901
28926
|
var records = lyr.data && lyr.data.getRecords();
|
|
28902
28927
|
var nullValue = opts.null_value || null;
|
|
28903
|
-
var
|
|
28928
|
+
var valuesAreColors = !!opts.colors || !!opts.color_scheme;
|
|
28904
28929
|
var colorScheme;
|
|
28905
|
-
var
|
|
28906
|
-
var
|
|
28930
|
+
var values, classifyByValue, classifyById;
|
|
28931
|
+
var numClasses, numValues;
|
|
28907
28932
|
var dataField, outputField;
|
|
28933
|
+
var method;
|
|
28908
28934
|
|
|
28909
28935
|
// validate explicitly set classes
|
|
28910
28936
|
if (opts.classes) {
|
|
28911
28937
|
if (!utils.isInteger(opts.classes) || opts.classes > 1 === false) {
|
|
28912
28938
|
stop('Invalid number of classes:', opts.classes, '(expected a value greater than 1)');
|
|
28913
28939
|
}
|
|
28914
|
-
|
|
28940
|
+
numClasses = opts.classes;
|
|
28915
28941
|
}
|
|
28916
28942
|
|
|
28917
28943
|
// TODO: better validation of breaks values
|
|
28918
28944
|
if (opts.breaks) {
|
|
28919
|
-
|
|
28945
|
+
numClasses = opts.breaks.length + 1;
|
|
28920
28946
|
}
|
|
28921
28947
|
|
|
28922
28948
|
if (opts.index_field) {
|
|
28923
28949
|
dataField = opts.index_field;
|
|
28924
|
-
if (
|
|
28950
|
+
if (numClasses > 0 === false) {
|
|
28925
28951
|
stop('The index-field= option requires the classes= option to be set');
|
|
28926
28952
|
}
|
|
28927
28953
|
// You can't infer the number of classes by looking at index values;
|
|
28928
28954
|
// this can cause unwanted interpolation if one or more values are
|
|
28929
28955
|
// not present in the index field
|
|
28930
|
-
//
|
|
28956
|
+
// numClasses = validateClassIndexField(records, opts.index_field);
|
|
28931
28957
|
|
|
28932
28958
|
} else if (opts.field) {
|
|
28933
28959
|
dataField = opts.field;
|
|
@@ -28938,7 +28964,19 @@ ${svg}
|
|
|
28938
28964
|
opts.categories = getUniqFieldValues(records, dataField);
|
|
28939
28965
|
}
|
|
28940
28966
|
|
|
28941
|
-
|
|
28967
|
+
// get classification method
|
|
28968
|
+
//
|
|
28969
|
+
if (opts.method) {
|
|
28970
|
+
method = opts.method;
|
|
28971
|
+
} else if (opts.categories) {
|
|
28972
|
+
method = 'categorical';
|
|
28973
|
+
} else if (opts.index_field) {
|
|
28974
|
+
method = 'indexed';
|
|
28975
|
+
} else {
|
|
28976
|
+
method = 'quantile'; // TODO: validate data field
|
|
28977
|
+
}
|
|
28978
|
+
|
|
28979
|
+
if (method == 'non-adjacent') {
|
|
28942
28980
|
if (lyr.geometry_type != 'polygon') {
|
|
28943
28981
|
stop('The non-adjacent option requires a polygon layer');
|
|
28944
28982
|
}
|
|
@@ -28951,8 +28989,8 @@ ${svg}
|
|
|
28951
28989
|
requireDataField(lyr.data, dataField);
|
|
28952
28990
|
}
|
|
28953
28991
|
|
|
28954
|
-
if (
|
|
28955
|
-
numValues = opts.continuous ?
|
|
28992
|
+
if (numClasses) {
|
|
28993
|
+
numValues = opts.continuous ? numClasses + 1 : numClasses;
|
|
28956
28994
|
}
|
|
28957
28995
|
|
|
28958
28996
|
// support both deprecated color-scheme= option and colors=<color-scheme> syntax
|
|
@@ -28967,39 +29005,44 @@ ${svg}
|
|
|
28967
29005
|
opts.colors.forEach(parseColor); // validate colors -- error if unparsable
|
|
28968
29006
|
}
|
|
28969
29007
|
|
|
29008
|
+
/// get values (usually colors)
|
|
29009
|
+
///
|
|
28970
29010
|
if (colorScheme) {
|
|
28971
|
-
|
|
29011
|
+
if (method == 'non-adjacent') {
|
|
29012
|
+
numClasses = numValues = numClasses || 5;
|
|
29013
|
+
values = getCategoricalColorScheme(colorScheme, numValues);
|
|
29014
|
+
|
|
29015
|
+
} else if (method == 'categorical') {
|
|
29016
|
+
values = getCategoricalColorScheme(colorScheme, opts.categories.length);
|
|
29017
|
+
numClasses = numValues = values.length;
|
|
28972
29018
|
|
|
28973
|
-
if (opts.categories) {
|
|
28974
|
-
classValues = getCategoricalColorScheme(colorScheme, opts.categories.length);
|
|
28975
|
-
numBuckets = numValues = classValues.length;
|
|
28976
29019
|
} else {
|
|
28977
|
-
if (!
|
|
29020
|
+
if (!numClasses) {
|
|
28978
29021
|
// stop('color-scheme= option requires classes= or breaks=');
|
|
28979
|
-
|
|
28980
|
-
numValues = opts.continuous ?
|
|
29022
|
+
numClasses = 4; // use a default number of classes
|
|
29023
|
+
numValues = opts.continuous ? numClasses + 1 : numClasses;
|
|
28981
29024
|
}
|
|
28982
|
-
|
|
29025
|
+
values = getColorRamp(colorScheme, numValues, opts.stops);
|
|
28983
29026
|
}
|
|
28984
29027
|
|
|
28985
29028
|
} else if (opts.colors || opts.values) {
|
|
28986
|
-
|
|
29029
|
+
values = opts.values ? parseValues(opts.values) : opts.colors;
|
|
28987
29030
|
if (!numValues) {
|
|
28988
|
-
numValues =
|
|
29031
|
+
numValues = values.length;
|
|
28989
29032
|
}
|
|
28990
|
-
if ((
|
|
29033
|
+
if ((values.length != numValues || opts.stops) && numValues > 1) {
|
|
28991
29034
|
// TODO: handle numValues == 1
|
|
28992
29035
|
// TODO: check for non-interpolatable value types (e.g. boolean, text)
|
|
28993
|
-
|
|
29036
|
+
values = interpolateValuesToClasses(values, numValues, opts.stops);
|
|
28994
29037
|
}
|
|
28995
29038
|
|
|
28996
29039
|
} else if (numValues > 1) {
|
|
28997
29040
|
// no values were given: assign indexes for each class
|
|
28998
|
-
|
|
29041
|
+
values = getIndexValues(numValues);
|
|
28999
29042
|
nullValue = -1;
|
|
29000
29043
|
}
|
|
29001
29044
|
|
|
29002
|
-
if (
|
|
29045
|
+
if (valuesAreColors) {
|
|
29003
29046
|
nullValue = nullValue || '#eee';
|
|
29004
29047
|
}
|
|
29005
29048
|
|
|
@@ -29008,24 +29051,24 @@ ${svg}
|
|
|
29008
29051
|
}
|
|
29009
29052
|
|
|
29010
29053
|
if (opts.invert) {
|
|
29011
|
-
|
|
29054
|
+
values = values.concat().reverse();
|
|
29012
29055
|
}
|
|
29013
29056
|
|
|
29014
|
-
if (
|
|
29015
|
-
message('Colors:', formatValuesForLogging(
|
|
29057
|
+
if (valuesAreColors) {
|
|
29058
|
+
message('Colors:', formatValuesForLogging(values));
|
|
29016
29059
|
}
|
|
29017
29060
|
|
|
29018
29061
|
// get a function to convert input data to class indexes
|
|
29019
29062
|
//
|
|
29020
|
-
if (
|
|
29021
|
-
classifyById = getNonAdjacentClassifier(lyr, dataset,
|
|
29063
|
+
if (method == 'non-adjacent') {
|
|
29064
|
+
classifyById = getNonAdjacentClassifier(lyr, dataset, values);
|
|
29022
29065
|
} else if (opts.index_field) {
|
|
29023
29066
|
// data is pre-classified... just read the index from a field
|
|
29024
|
-
classifyByValue = getIndexedClassifier(
|
|
29025
|
-
} else if (
|
|
29026
|
-
classifyByValue = getCategoricalClassifier(
|
|
29067
|
+
classifyByValue = getIndexedClassifier(values, nullValue, opts);
|
|
29068
|
+
} else if (method == 'categorical') {
|
|
29069
|
+
classifyByValue = getCategoricalClassifier(values, nullValue, opts);
|
|
29027
29070
|
} else {
|
|
29028
|
-
classifyByValue = getSequentialClassifier$1(
|
|
29071
|
+
classifyByValue = getSequentialClassifier$1(values, nullValue, getFieldValues(records, dataField), method, opts);
|
|
29029
29072
|
}
|
|
29030
29073
|
|
|
29031
29074
|
if (classifyByValue) {
|
|
@@ -29038,7 +29081,7 @@ ${svg}
|
|
|
29038
29081
|
|
|
29039
29082
|
// get the name of the output field
|
|
29040
29083
|
//
|
|
29041
|
-
if (
|
|
29084
|
+
if (valuesAreColors) {
|
|
29042
29085
|
outputField = lyr.geometry_type == 'polyline' ? 'stroke' : 'fill';
|
|
29043
29086
|
} else {
|
|
29044
29087
|
outputField = 'class';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.92",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"!.DS_Store"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"commander": "
|
|
43
|
+
"commander": "7.0.0",
|
|
44
44
|
"cookies": "^0.8.0",
|
|
45
45
|
"d3-color": "2.0.0",
|
|
46
46
|
"d3-scale-chromatic": "2.0.0",
|
package/www/index.html
CHANGED
|
@@ -201,7 +201,7 @@ a smoother appearance.</div></div></div></div>
|
|
|
201
201
|
|
|
202
202
|
<div id="splash-screen" class="main-area">
|
|
203
203
|
<div>
|
|
204
|
-
<h3>Mapshaper is an editor for map data</h3>
|
|
204
|
+
<h3 id="splash-screen-blurb">Mapshaper is an editor for map data</h3>
|
|
205
205
|
</div>
|
|
206
206
|
<div id="drop-areas" class="drop-area-wrapper main-area">
|
|
207
207
|
|