mapshaper 0.6.107 → 0.6.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mapshaper.js +29 -29
- package/package.json +2 -1
- package/www/index.html +0 -1
- package/www/mapshaper-gui.js +15 -7
- package/www/mapshaper.js +29 -29
package/mapshaper.js
CHANGED
|
@@ -3193,7 +3193,8 @@
|
|
|
3193
3193
|
var den = determinant2D(bx - ax, by - ay, dx - cx, dy - cy);
|
|
3194
3194
|
var m = orient2D(cx, cy, dx, dy, ax, ay) / den;
|
|
3195
3195
|
var p = [ax + m * (bx - ax), ay + m * (by - ay)];
|
|
3196
|
-
if (Math.abs(den) < 1e-
|
|
3196
|
+
if (Math.abs(den) < 1e-25) {
|
|
3197
|
+
// changed from 1e-18 to 1e-25 (see geom ex1)
|
|
3197
3198
|
// assume that collinear and near-collinear segment intersections have been
|
|
3198
3199
|
// accounted for already.
|
|
3199
3200
|
// TODO: is this a valid assumption?
|
|
@@ -13545,14 +13546,8 @@
|
|
|
13545
13546
|
function getBoundsPrecisionForDisplay(bbox) {
|
|
13546
13547
|
var w = Math.abs(bbox[2] - bbox[0]),
|
|
13547
13548
|
h = Math.abs(bbox[3] - bbox[1]),
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
range = Math.max(w, h) + 1e-8,
|
|
13551
|
-
digits = 0;
|
|
13552
|
-
while (range < 2000 && digits < 1) {
|
|
13553
|
-
range *= 10;
|
|
13554
|
-
digits++;
|
|
13555
|
-
}
|
|
13549
|
+
range = (w + h) / 2 + 1e-8,
|
|
13550
|
+
digits = Math.max(0, Math.round(3 - Math.log10(range)));
|
|
13556
13551
|
return digits;
|
|
13557
13552
|
}
|
|
13558
13553
|
|
|
@@ -16796,6 +16791,7 @@
|
|
|
16796
16791
|
arcs.flatten();
|
|
16797
16792
|
|
|
16798
16793
|
var changed = snapAndCut(dataset, snapDist);
|
|
16794
|
+
|
|
16799
16795
|
// Detect topology again if coordinates have changed
|
|
16800
16796
|
if (changed || opts.rebuild_topology) {
|
|
16801
16797
|
buildTopology(dataset);
|
|
@@ -16834,6 +16830,7 @@
|
|
|
16834
16830
|
if (cutCount > 0 || snapCount > 0 || dupeCount > 0) {
|
|
16835
16831
|
coordsHaveChanged = true;
|
|
16836
16832
|
}
|
|
16833
|
+
|
|
16837
16834
|
// perform a second snap + cut pass if needed
|
|
16838
16835
|
if (cutCount > 0) {
|
|
16839
16836
|
cutCount = 0;
|
|
@@ -16882,17 +16879,6 @@
|
|
|
16882
16879
|
}
|
|
16883
16880
|
}
|
|
16884
16881
|
|
|
16885
|
-
// Divides a collection of arcs at points where arc paths cross each other
|
|
16886
|
-
// Returns array for remapping arc ids
|
|
16887
|
-
function divideArcs(arcs, opts) {
|
|
16888
|
-
var points = findClippingPoints(arcs, opts);
|
|
16889
|
-
// TODO: avoid the following if no points need to be added
|
|
16890
|
-
var map = insertCutPoints(points, arcs);
|
|
16891
|
-
// segment-point intersections currently create duplicate points
|
|
16892
|
-
// TODO: consider dedup in a later cleanup pass?
|
|
16893
|
-
// arcs.dedupCoords();
|
|
16894
|
-
return map;
|
|
16895
|
-
}
|
|
16896
16882
|
|
|
16897
16883
|
function cutPathsAtIntersections(dataset, opts) {
|
|
16898
16884
|
var n = dataset.arcs.getPointCount();
|
|
@@ -16911,6 +16897,25 @@
|
|
|
16911
16897
|
});
|
|
16912
16898
|
}
|
|
16913
16899
|
|
|
16900
|
+
|
|
16901
|
+
// Divides a collection of arcs at points where arc paths cross each other
|
|
16902
|
+
// Returns array for remapping arc ids
|
|
16903
|
+
function divideArcs(arcs, opts) {
|
|
16904
|
+
var points = findClippingPoints(arcs, opts);
|
|
16905
|
+
// TODO: avoid the following if no points need to be added
|
|
16906
|
+
var map = insertCutPoints(points, arcs);
|
|
16907
|
+
// segment-point intersections currently create duplicate points
|
|
16908
|
+
// TODO: consider dedup in a later cleanup pass?
|
|
16909
|
+
// arcs.dedupCoords();
|
|
16910
|
+
return map;
|
|
16911
|
+
}
|
|
16912
|
+
|
|
16913
|
+
function findClippingPoints(arcs, opts) {
|
|
16914
|
+
var intersections = findSegmentIntersections(arcs, opts),
|
|
16915
|
+
data = arcs.getVertexData();
|
|
16916
|
+
return convertIntersectionsToCutPoints(intersections, data.xx, data.yy);
|
|
16917
|
+
}
|
|
16918
|
+
|
|
16914
16919
|
// Inserts array of cutting points into an ArcCollection
|
|
16915
16920
|
// Returns array for remapping arc ids
|
|
16916
16921
|
function insertCutPoints(unfilteredPoints, arcs) {
|
|
@@ -17043,12 +17048,6 @@
|
|
|
17043
17048
|
return filtered;
|
|
17044
17049
|
}
|
|
17045
17050
|
|
|
17046
|
-
function findClippingPoints(arcs, opts) {
|
|
17047
|
-
var intersections = findSegmentIntersections(arcs, opts),
|
|
17048
|
-
data = arcs.getVertexData();
|
|
17049
|
-
return convertIntersectionsToCutPoints(intersections, data.xx, data.yy);
|
|
17050
|
-
}
|
|
17051
|
-
|
|
17052
17051
|
var IntersectionCuts = /*#__PURE__*/Object.freeze({
|
|
17053
17052
|
__proto__: null,
|
|
17054
17053
|
addIntersectionCuts: addIntersectionCuts,
|
|
@@ -25446,6 +25445,9 @@ ${svg}
|
|
|
25446
25445
|
.option('calc', calcOpt)
|
|
25447
25446
|
.option('name', nameOpt)
|
|
25448
25447
|
.option('target', targetOpt)
|
|
25448
|
+
.option('no-snap', { // undocumented, for debugging
|
|
25449
|
+
type: 'flag'
|
|
25450
|
+
})
|
|
25449
25451
|
.option('no-replace', noReplaceOpt);
|
|
25450
25452
|
|
|
25451
25453
|
parser.command('point-grid')
|
|
@@ -30101,8 +30103,6 @@ ${svg}
|
|
|
30101
30103
|
const detright = (ax - cx) * (by - cy);
|
|
30102
30104
|
const det = detleft - detright;
|
|
30103
30105
|
|
|
30104
|
-
if (detleft === 0 || detright === 0 || (detleft > 0) !== (detright > 0)) return det;
|
|
30105
|
-
|
|
30106
30106
|
const detsum = Math.abs(detleft + detright);
|
|
30107
30107
|
if (Math.abs(det) >= ccwerrboundA * detsum) return det;
|
|
30108
30108
|
|
|
@@ -46044,7 +46044,7 @@ ${svg}
|
|
|
46044
46044
|
});
|
|
46045
46045
|
}
|
|
46046
46046
|
|
|
46047
|
-
var version = "0.6.
|
|
46047
|
+
var version = "0.6.109";
|
|
46048
46048
|
|
|
46049
46049
|
// Parse command line args into commands and run them
|
|
46050
46050
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.109",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"csv-spectrum": "^1.0.0",
|
|
70
70
|
"eslint": "^8.16.0",
|
|
71
71
|
"mocha": "^10.2.0",
|
|
72
|
+
"robust-predicates": "^3.0.2",
|
|
72
73
|
"rollup": "^4.44.1",
|
|
73
74
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
74
75
|
"shell-quote": "^1.7.4",
|
package/www/index.html
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -2726,11 +2726,12 @@
|
|
|
2726
2726
|
// p1: [x, y] coords
|
|
2727
2727
|
// p2: [x, y] coords offset by 1x1 pixel
|
|
2728
2728
|
function formatCoordsForDisplay(p1, p2) {
|
|
2729
|
+
var maxD = 13;
|
|
2729
2730
|
var dx = Math.abs(p1[0] - p2[0]);
|
|
2730
2731
|
var dy = Math.abs(p1[1] - p2[1]);
|
|
2731
2732
|
var offs = (dx + dy) / 2;
|
|
2732
2733
|
var decimals = 0;
|
|
2733
|
-
while (offs < 1 && decimals
|
|
2734
|
+
while (offs < 1 && decimals <= maxD) {
|
|
2734
2735
|
offs *= 10;
|
|
2735
2736
|
decimals++;
|
|
2736
2737
|
}
|
|
@@ -4757,6 +4758,7 @@
|
|
|
4757
4758
|
if (_open) close();
|
|
4758
4759
|
menu.empty();
|
|
4759
4760
|
|
|
4761
|
+
|
|
4760
4762
|
if (openMenu && openMenu != this) {
|
|
4761
4763
|
openMenu.close();
|
|
4762
4764
|
}
|
|
@@ -11560,6 +11562,7 @@
|
|
|
11560
11562
|
// stop zooming before rounding errors become too obvious
|
|
11561
11563
|
function maxScale() {
|
|
11562
11564
|
var minPixelScale = 1e-16;
|
|
11565
|
+
// var minPixelScale = 1e-17; // gets jumpy
|
|
11563
11566
|
var xmax = maxAbs(_fullBounds.xmin, _fullBounds.xmax, _fullBounds.centerX());
|
|
11564
11567
|
var ymax = maxAbs(_fullBounds.ymin, _fullBounds.ymax, _fullBounds.centerY());
|
|
11565
11568
|
var xscale = _fullBounds.width() / _position.width() / xmax / minPixelScale;
|
|
@@ -11906,9 +11909,8 @@
|
|
|
11906
11909
|
var iter = new internal.ShapeIter(arcs);
|
|
11907
11910
|
var t = getScaledTransform(_ext);
|
|
11908
11911
|
var bounds = _ext.getBounds();
|
|
11909
|
-
var radius = (style.strokeWidth > 2 ? style.strokeWidth *
|
|
11912
|
+
var radius = (style.strokeWidth > 2 ? style.strokeWidth * 1 : 2.2) * GUI.getPixelRatio() * getScaledLineScale(_ext, style);
|
|
11910
11913
|
var color = style.strokeColor || 'black';
|
|
11911
|
-
|
|
11912
11914
|
var i, j, p;
|
|
11913
11915
|
_ctx.beginPath();
|
|
11914
11916
|
_ctx.fillStyle = color;
|
|
@@ -12560,7 +12562,7 @@
|
|
|
12560
12562
|
var self = new EventDispatcher();
|
|
12561
12563
|
var box = new HighlightBox(gui, {name: 'box-tool', persistent: true, handles: true, draggable: true});
|
|
12562
12564
|
var popup = gui.container.findChild('.box-tool-options');
|
|
12563
|
-
var coords = popup.findChild('.box-coords');
|
|
12565
|
+
var coords = popup.findChild('.box-coords').hide();
|
|
12564
12566
|
var _on = false;
|
|
12565
12567
|
var instructionsShown = false;
|
|
12566
12568
|
var alert;
|
|
@@ -12994,6 +12996,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12994
12996
|
var fullBounds;
|
|
12995
12997
|
var needReset;
|
|
12996
12998
|
|
|
12999
|
+
if (!updated) {
|
|
13000
|
+
return; // e.g. if command is run in console before data is loaded
|
|
13001
|
+
}
|
|
13002
|
+
|
|
12997
13003
|
if (arcsMayHaveChanged(e.flags)) {
|
|
12998
13004
|
// regenerate filtered arcs the next time they are needed for rendering
|
|
12999
13005
|
// delete e.dataset.gui.displayArcs
|
|
@@ -13099,15 +13105,17 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13099
13105
|
// add margin
|
|
13100
13106
|
// use larger margin for small sizes
|
|
13101
13107
|
var widthPx = _ext.width();
|
|
13102
|
-
var marginPct = widthPx < 700 &&
|
|
13108
|
+
var marginPct = widthPx < 700 && 4.5 || widthPx < 800 && 4 || 3.5;
|
|
13103
13109
|
if (isTableView()) {
|
|
13104
13110
|
var n = internal.getFeatureCount(_activeLyr);
|
|
13105
13111
|
marginPct = n < 5 && 20 || n < 100 && 10 || 4;
|
|
13106
13112
|
}
|
|
13107
13113
|
b.scale(1 + marginPct / 100 * 2);
|
|
13108
13114
|
|
|
13109
|
-
// Inflate display bounding box
|
|
13110
|
-
b.
|
|
13115
|
+
// Inflate display bounding box of single-point layers and collapsed shapes a bit
|
|
13116
|
+
if (b.width() === 0 || b.height() === 0) {
|
|
13117
|
+
b.padBounds(1e-4, 1e-4, 1e-4, 1e-4);
|
|
13118
|
+
}
|
|
13111
13119
|
return b;
|
|
13112
13120
|
}
|
|
13113
13121
|
|
package/www/mapshaper.js
CHANGED
|
@@ -3193,7 +3193,8 @@
|
|
|
3193
3193
|
var den = determinant2D(bx - ax, by - ay, dx - cx, dy - cy);
|
|
3194
3194
|
var m = orient2D(cx, cy, dx, dy, ax, ay) / den;
|
|
3195
3195
|
var p = [ax + m * (bx - ax), ay + m * (by - ay)];
|
|
3196
|
-
if (Math.abs(den) < 1e-
|
|
3196
|
+
if (Math.abs(den) < 1e-25) {
|
|
3197
|
+
// changed from 1e-18 to 1e-25 (see geom ex1)
|
|
3197
3198
|
// assume that collinear and near-collinear segment intersections have been
|
|
3198
3199
|
// accounted for already.
|
|
3199
3200
|
// TODO: is this a valid assumption?
|
|
@@ -13545,14 +13546,8 @@
|
|
|
13545
13546
|
function getBoundsPrecisionForDisplay(bbox) {
|
|
13546
13547
|
var w = Math.abs(bbox[2] - bbox[0]),
|
|
13547
13548
|
h = Math.abs(bbox[3] - bbox[1]),
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
range = Math.max(w, h) + 1e-8,
|
|
13551
|
-
digits = 0;
|
|
13552
|
-
while (range < 2000 && digits < 1) {
|
|
13553
|
-
range *= 10;
|
|
13554
|
-
digits++;
|
|
13555
|
-
}
|
|
13549
|
+
range = (w + h) / 2 + 1e-8,
|
|
13550
|
+
digits = Math.max(0, Math.round(3 - Math.log10(range)));
|
|
13556
13551
|
return digits;
|
|
13557
13552
|
}
|
|
13558
13553
|
|
|
@@ -16796,6 +16791,7 @@
|
|
|
16796
16791
|
arcs.flatten();
|
|
16797
16792
|
|
|
16798
16793
|
var changed = snapAndCut(dataset, snapDist);
|
|
16794
|
+
|
|
16799
16795
|
// Detect topology again if coordinates have changed
|
|
16800
16796
|
if (changed || opts.rebuild_topology) {
|
|
16801
16797
|
buildTopology(dataset);
|
|
@@ -16834,6 +16830,7 @@
|
|
|
16834
16830
|
if (cutCount > 0 || snapCount > 0 || dupeCount > 0) {
|
|
16835
16831
|
coordsHaveChanged = true;
|
|
16836
16832
|
}
|
|
16833
|
+
|
|
16837
16834
|
// perform a second snap + cut pass if needed
|
|
16838
16835
|
if (cutCount > 0) {
|
|
16839
16836
|
cutCount = 0;
|
|
@@ -16882,17 +16879,6 @@
|
|
|
16882
16879
|
}
|
|
16883
16880
|
}
|
|
16884
16881
|
|
|
16885
|
-
// Divides a collection of arcs at points where arc paths cross each other
|
|
16886
|
-
// Returns array for remapping arc ids
|
|
16887
|
-
function divideArcs(arcs, opts) {
|
|
16888
|
-
var points = findClippingPoints(arcs, opts);
|
|
16889
|
-
// TODO: avoid the following if no points need to be added
|
|
16890
|
-
var map = insertCutPoints(points, arcs);
|
|
16891
|
-
// segment-point intersections currently create duplicate points
|
|
16892
|
-
// TODO: consider dedup in a later cleanup pass?
|
|
16893
|
-
// arcs.dedupCoords();
|
|
16894
|
-
return map;
|
|
16895
|
-
}
|
|
16896
16882
|
|
|
16897
16883
|
function cutPathsAtIntersections(dataset, opts) {
|
|
16898
16884
|
var n = dataset.arcs.getPointCount();
|
|
@@ -16911,6 +16897,25 @@
|
|
|
16911
16897
|
});
|
|
16912
16898
|
}
|
|
16913
16899
|
|
|
16900
|
+
|
|
16901
|
+
// Divides a collection of arcs at points where arc paths cross each other
|
|
16902
|
+
// Returns array for remapping arc ids
|
|
16903
|
+
function divideArcs(arcs, opts) {
|
|
16904
|
+
var points = findClippingPoints(arcs, opts);
|
|
16905
|
+
// TODO: avoid the following if no points need to be added
|
|
16906
|
+
var map = insertCutPoints(points, arcs);
|
|
16907
|
+
// segment-point intersections currently create duplicate points
|
|
16908
|
+
// TODO: consider dedup in a later cleanup pass?
|
|
16909
|
+
// arcs.dedupCoords();
|
|
16910
|
+
return map;
|
|
16911
|
+
}
|
|
16912
|
+
|
|
16913
|
+
function findClippingPoints(arcs, opts) {
|
|
16914
|
+
var intersections = findSegmentIntersections(arcs, opts),
|
|
16915
|
+
data = arcs.getVertexData();
|
|
16916
|
+
return convertIntersectionsToCutPoints(intersections, data.xx, data.yy);
|
|
16917
|
+
}
|
|
16918
|
+
|
|
16914
16919
|
// Inserts array of cutting points into an ArcCollection
|
|
16915
16920
|
// Returns array for remapping arc ids
|
|
16916
16921
|
function insertCutPoints(unfilteredPoints, arcs) {
|
|
@@ -17043,12 +17048,6 @@
|
|
|
17043
17048
|
return filtered;
|
|
17044
17049
|
}
|
|
17045
17050
|
|
|
17046
|
-
function findClippingPoints(arcs, opts) {
|
|
17047
|
-
var intersections = findSegmentIntersections(arcs, opts),
|
|
17048
|
-
data = arcs.getVertexData();
|
|
17049
|
-
return convertIntersectionsToCutPoints(intersections, data.xx, data.yy);
|
|
17050
|
-
}
|
|
17051
|
-
|
|
17052
17051
|
var IntersectionCuts = /*#__PURE__*/Object.freeze({
|
|
17053
17052
|
__proto__: null,
|
|
17054
17053
|
addIntersectionCuts: addIntersectionCuts,
|
|
@@ -25446,6 +25445,9 @@ ${svg}
|
|
|
25446
25445
|
.option('calc', calcOpt)
|
|
25447
25446
|
.option('name', nameOpt)
|
|
25448
25447
|
.option('target', targetOpt)
|
|
25448
|
+
.option('no-snap', { // undocumented, for debugging
|
|
25449
|
+
type: 'flag'
|
|
25450
|
+
})
|
|
25449
25451
|
.option('no-replace', noReplaceOpt);
|
|
25450
25452
|
|
|
25451
25453
|
parser.command('point-grid')
|
|
@@ -30101,8 +30103,6 @@ ${svg}
|
|
|
30101
30103
|
const detright = (ax - cx) * (by - cy);
|
|
30102
30104
|
const det = detleft - detright;
|
|
30103
30105
|
|
|
30104
|
-
if (detleft === 0 || detright === 0 || (detleft > 0) !== (detright > 0)) return det;
|
|
30105
|
-
|
|
30106
30106
|
const detsum = Math.abs(detleft + detright);
|
|
30107
30107
|
if (Math.abs(det) >= ccwerrboundA * detsum) return det;
|
|
30108
30108
|
|
|
@@ -46044,7 +46044,7 @@ ${svg}
|
|
|
46044
46044
|
});
|
|
46045
46045
|
}
|
|
46046
46046
|
|
|
46047
|
-
var version = "0.6.
|
|
46047
|
+
var version = "0.6.109";
|
|
46048
46048
|
|
|
46049
46049
|
// Parse command line args into commands and run them
|
|
46050
46050
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|