mapshaper 0.6.32 → 0.6.33
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 +41 -14
- package/package.json +1 -1
- package/www/mapshaper-gui.js +17 -10
- package/www/mapshaper.js +41 -14
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.33";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -11665,8 +11665,16 @@
|
|
|
11665
11665
|
}
|
|
11666
11666
|
cands.forEach(function(cand) {
|
|
11667
11667
|
var p = getTestPoint(cand.ids);
|
|
11668
|
-
var isEnclosed = b.containsPoint(p[0], p[1]) &&
|
|
11669
|
-
|
|
11668
|
+
var isEnclosed = b.containsPoint(p[0], p[1]) &&
|
|
11669
|
+
// added a bounds-in-bounds test to handle a case where the test point
|
|
11670
|
+
// fell along the shared boundary of two rings, but the rings did no overlap
|
|
11671
|
+
// (this gave a false positive for the enclosure test)
|
|
11672
|
+
// (for speed, the midpoint of an arc is used as the test point; this
|
|
11673
|
+
// works well in the typical case where rings to not share an edge.
|
|
11674
|
+
// Finding an internal test point would be better, we just need a fast
|
|
11675
|
+
// function to find internal points)
|
|
11676
|
+
b.contains(cand.bounds) &&
|
|
11677
|
+
(index ? index.pointInPolygon(p[0], p[1]) : geom.testPointInRing(p[0], p[1], pathIds, arcs));
|
|
11670
11678
|
if (isEnclosed) {
|
|
11671
11679
|
paths.push(cand.ids);
|
|
11672
11680
|
}
|
|
@@ -11674,6 +11682,7 @@
|
|
|
11674
11682
|
return paths.length > 0 ? paths : null;
|
|
11675
11683
|
};
|
|
11676
11684
|
|
|
11685
|
+
// return array of indexed paths within a given shape
|
|
11677
11686
|
this.findPathsInsideShape = function(shape) {
|
|
11678
11687
|
var paths = []; // list of enclosed paths
|
|
11679
11688
|
shape.forEach(function(ids) {
|
|
@@ -12075,7 +12084,6 @@
|
|
|
12075
12084
|
yy = coords.yy,
|
|
12076
12085
|
ids = nodes.getConnectedArcs(fromArcId),
|
|
12077
12086
|
toArcId = fromArcId; // initialize to fromArcId -- an error condition
|
|
12078
|
-
|
|
12079
12087
|
if (filter) {
|
|
12080
12088
|
ids = ids.filter(filter);
|
|
12081
12089
|
}
|
|
@@ -12104,14 +12112,12 @@
|
|
|
12104
12112
|
continue;
|
|
12105
12113
|
}
|
|
12106
12114
|
icand = arcs.indexOfVertex(candId, -2);
|
|
12107
|
-
|
|
12108
12115
|
if (toArcId == fromArcId) {
|
|
12109
12116
|
// first valid candidate
|
|
12110
12117
|
ito = icand;
|
|
12111
12118
|
toArcId = candId;
|
|
12112
12119
|
continue;
|
|
12113
12120
|
}
|
|
12114
|
-
|
|
12115
12121
|
code = chooseRighthandPath(fromX, fromY, nodeX, nodeY, xx[ito], yy[ito], xx[icand], yy[icand]);
|
|
12116
12122
|
if (code == 2) {
|
|
12117
12123
|
ito = icand;
|
|
@@ -12119,6 +12125,7 @@
|
|
|
12119
12125
|
}
|
|
12120
12126
|
}
|
|
12121
12127
|
|
|
12128
|
+
|
|
12122
12129
|
if (toArcId == fromArcId) {
|
|
12123
12130
|
// This shouldn't occur, assuming that other arcs are present
|
|
12124
12131
|
error("Pathfinder error");
|
|
@@ -12183,6 +12190,9 @@
|
|
|
12183
12190
|
chooseRighthandVector: chooseRighthandVector
|
|
12184
12191
|
});
|
|
12185
12192
|
|
|
12193
|
+
var FWD_USED = 0x8;
|
|
12194
|
+
var REV_USED = 0x80;
|
|
12195
|
+
|
|
12186
12196
|
function setBits(bits, arcBits, mask) {
|
|
12187
12197
|
return (bits & ~mask) | (arcBits & mask);
|
|
12188
12198
|
}
|
|
@@ -12210,6 +12220,16 @@
|
|
|
12210
12220
|
return bits & 7;
|
|
12211
12221
|
}
|
|
12212
12222
|
|
|
12223
|
+
function markPathsAsUsed(paths, routesArr) {
|
|
12224
|
+
forEachArcId(paths, function(arcId) {
|
|
12225
|
+
if (arcId < 0) {
|
|
12226
|
+
routesArr[~arcId] |= REV_USED;
|
|
12227
|
+
} else {
|
|
12228
|
+
routesArr[arcId] |= FWD_USED;
|
|
12229
|
+
}
|
|
12230
|
+
});
|
|
12231
|
+
}
|
|
12232
|
+
|
|
12213
12233
|
// Open arc pathways in a single shape or array of shapes
|
|
12214
12234
|
//
|
|
12215
12235
|
function openArcRoutes(paths, arcColl, routesArr, fwd, rev, dissolve, orBits) {
|
|
@@ -12400,6 +12420,7 @@
|
|
|
12400
12420
|
andBits: andBits,
|
|
12401
12421
|
setRouteBits: setRouteBits,
|
|
12402
12422
|
getRouteBits: getRouteBits,
|
|
12423
|
+
markPathsAsUsed: markPathsAsUsed,
|
|
12403
12424
|
openArcRoutes: openArcRoutes,
|
|
12404
12425
|
closeArcRoutes: closeArcRoutes,
|
|
12405
12426
|
getPathFinder: getPathFinder,
|
|
@@ -33401,7 +33422,7 @@ ${svg}
|
|
|
33401
33422
|
var clipArcTouches = 0;
|
|
33402
33423
|
var clipArcUses = 0;
|
|
33403
33424
|
var usedClipArcs = [];
|
|
33404
|
-
var
|
|
33425
|
+
var findPath = getPathFinder(nodes, useRoute, routeIsActive);
|
|
33405
33426
|
var dissolvePolygon = getPolygonDissolver(nodes);
|
|
33406
33427
|
|
|
33407
33428
|
// The following cleanup step is a performance bottleneck (it often takes longer than
|
|
@@ -33434,12 +33455,16 @@ ${svg}
|
|
|
33434
33455
|
return null;
|
|
33435
33456
|
});
|
|
33436
33457
|
|
|
33458
|
+
markPathsAsUsed(clippedShapes, routeFlags); // to help us find unused paths later
|
|
33459
|
+
|
|
33460
|
+
|
|
33437
33461
|
// add clip/erase polygons that are fully contained in a target polygon
|
|
33438
33462
|
// need to index only non-intersecting clip shapes
|
|
33439
33463
|
// (Intersecting shapes have one or more arcs that have been scanned)
|
|
33440
33464
|
|
|
33441
33465
|
// first, find shapes that do not intersect the target layer
|
|
33442
33466
|
// (these could be inside or outside the target polygons)
|
|
33467
|
+
|
|
33443
33468
|
var undividedClipShapes = findUndividedClipShapes(clipShapes);
|
|
33444
33469
|
|
|
33445
33470
|
closeArcRoutes(clipShapes, arcs, routeFlags, true, true); // not needed?
|
|
@@ -33468,7 +33493,7 @@ ${svg}
|
|
|
33468
33493
|
for (var i=0, n=ids.length; i<n; i++) {
|
|
33469
33494
|
clipArcTouches = 0;
|
|
33470
33495
|
clipArcUses = 0;
|
|
33471
|
-
path =
|
|
33496
|
+
path = findPath(ids[i]);
|
|
33472
33497
|
if (path) {
|
|
33473
33498
|
// if ring doesn't touch/intersect a clip/erase polygon, check if it is contained
|
|
33474
33499
|
// if (clipArcTouches === 0) {
|
|
@@ -33487,6 +33512,7 @@ ${svg}
|
|
|
33487
33512
|
}
|
|
33488
33513
|
});
|
|
33489
33514
|
|
|
33515
|
+
|
|
33490
33516
|
// Clear pathways of current target shape to hidden/closed
|
|
33491
33517
|
closeArcRoutes(shape, arcs, routeFlags, true, true, true);
|
|
33492
33518
|
// Also clear pathways of any clip arcs that were used
|
|
@@ -33557,8 +33583,9 @@ ${svg}
|
|
|
33557
33583
|
return usable;
|
|
33558
33584
|
}
|
|
33559
33585
|
|
|
33560
|
-
|
|
33561
|
-
//
|
|
33586
|
+
|
|
33587
|
+
// Filter a collection of shapes to exclude paths that incorporate parts of
|
|
33588
|
+
// clip/erase polygons and paths that are hidden (e.g. internal boundaries)
|
|
33562
33589
|
function findUndividedClipShapes(clipShapes) {
|
|
33563
33590
|
return clipShapes.map(function(shape) {
|
|
33564
33591
|
var usableParts = [];
|
|
@@ -33582,12 +33609,12 @@ ${svg}
|
|
|
33582
33609
|
});
|
|
33583
33610
|
}
|
|
33584
33611
|
|
|
33585
|
-
|
|
33586
|
-
// (not testing open/closed or visible/hidden)
|
|
33612
|
+
|
|
33587
33613
|
function arcIsUnused(id, flags) {
|
|
33588
33614
|
var abs = absArcId(id),
|
|
33589
33615
|
flag = flags[abs];
|
|
33590
|
-
return (flag &
|
|
33616
|
+
return (flag & 0x88) === 0;
|
|
33617
|
+
// return id < 0 ? (flag & 0x80) === 0 : (flag & 0x8) === 0;
|
|
33591
33618
|
}
|
|
33592
33619
|
|
|
33593
33620
|
function arcIsVisible(id, flags) {
|
|
@@ -33610,7 +33637,7 @@ ${svg}
|
|
|
33610
33637
|
enclosedPaths.forEach(function(ids) {
|
|
33611
33638
|
var path;
|
|
33612
33639
|
for (var j=0; j<ids.length; j++) {
|
|
33613
|
-
path =
|
|
33640
|
+
path = findPath(ids[j]);
|
|
33614
33641
|
if (path) {
|
|
33615
33642
|
dissolvedPaths.push(path);
|
|
33616
33643
|
}
|
package/package.json
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -4038,8 +4038,11 @@
|
|
|
4038
4038
|
}
|
|
4039
4039
|
|
|
4040
4040
|
function updateMenuBtn() {
|
|
4041
|
-
var
|
|
4042
|
-
|
|
4041
|
+
var lyrName = model.getActiveLayer().layer.name || '';
|
|
4042
|
+
var menuTitle = lyrName || '[unnamed layer]';
|
|
4043
|
+
var pageTitle = lyrName || 'mapshaper';
|
|
4044
|
+
btn.classed('active', 'true').findChild('.layer-name').html(menuTitle + " ▼");
|
|
4045
|
+
window.document.title = pageTitle;
|
|
4043
4046
|
}
|
|
4044
4047
|
|
|
4045
4048
|
function render() {
|
|
@@ -10172,12 +10175,12 @@
|
|
|
10172
10175
|
return action == 'hover' && _overlayCanv.visible();
|
|
10173
10176
|
}
|
|
10174
10177
|
|
|
10175
|
-
function drawCanvasLayer(
|
|
10176
|
-
if (!
|
|
10177
|
-
if (
|
|
10178
|
-
drawOutlineLayerToCanvas(
|
|
10178
|
+
function drawCanvasLayer(lyr, canv) {
|
|
10179
|
+
if (!lyr) return;
|
|
10180
|
+
if (lyr.style.type == 'outline') {
|
|
10181
|
+
drawOutlineLayerToCanvas(lyr, canv, ext);
|
|
10179
10182
|
} else {
|
|
10180
|
-
drawStyledLayerToCanvas(
|
|
10183
|
+
drawStyledLayerToCanvas(lyr, canv, ext);
|
|
10181
10184
|
}
|
|
10182
10185
|
}
|
|
10183
10186
|
|
|
@@ -11039,7 +11042,9 @@
|
|
|
11039
11042
|
} else {
|
|
11040
11043
|
_overlayLyr = null;
|
|
11041
11044
|
}
|
|
11042
|
-
|
|
11045
|
+
// 'hover' bypasses style creation in drawLayers2()... sometimes we need that
|
|
11046
|
+
// drawLayers('hover');
|
|
11047
|
+
drawLayers();
|
|
11043
11048
|
}
|
|
11044
11049
|
|
|
11045
11050
|
function getDisplayOptions() {
|
|
@@ -11054,12 +11059,14 @@
|
|
|
11054
11059
|
return flags.simplify_method || flags.simplify || flags.proj ||
|
|
11055
11060
|
flags.arc_count || flags.repair || flags.clip || flags.erase ||
|
|
11056
11061
|
flags.slice || flags.affine || flags.rectangle || flags.buffer ||
|
|
11057
|
-
flags.union || flags.mosaic || flags.snap || flags.clean || false;
|
|
11062
|
+
flags.union || flags.mosaic || flags.snap || flags.clean || flags.drop || false;
|
|
11058
11063
|
}
|
|
11059
11064
|
|
|
11060
11065
|
// Test if an update allows hover popup to stay open
|
|
11061
11066
|
function popupCanStayOpen(flags) {
|
|
11062
|
-
//
|
|
11067
|
+
// keeping popup open after -drop geometry causes problems...
|
|
11068
|
+
// // if (arcsMayHaveChanged(flags)) return false;
|
|
11069
|
+
if (arcsMayHaveChanged(flags)) return false;
|
|
11063
11070
|
if (flags.points || flags.proj) return false;
|
|
11064
11071
|
if (!flags.same_table) return false;
|
|
11065
11072
|
return true;
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.33";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -11665,8 +11665,16 @@
|
|
|
11665
11665
|
}
|
|
11666
11666
|
cands.forEach(function(cand) {
|
|
11667
11667
|
var p = getTestPoint(cand.ids);
|
|
11668
|
-
var isEnclosed = b.containsPoint(p[0], p[1]) &&
|
|
11669
|
-
|
|
11668
|
+
var isEnclosed = b.containsPoint(p[0], p[1]) &&
|
|
11669
|
+
// added a bounds-in-bounds test to handle a case where the test point
|
|
11670
|
+
// fell along the shared boundary of two rings, but the rings did no overlap
|
|
11671
|
+
// (this gave a false positive for the enclosure test)
|
|
11672
|
+
// (for speed, the midpoint of an arc is used as the test point; this
|
|
11673
|
+
// works well in the typical case where rings to not share an edge.
|
|
11674
|
+
// Finding an internal test point would be better, we just need a fast
|
|
11675
|
+
// function to find internal points)
|
|
11676
|
+
b.contains(cand.bounds) &&
|
|
11677
|
+
(index ? index.pointInPolygon(p[0], p[1]) : geom.testPointInRing(p[0], p[1], pathIds, arcs));
|
|
11670
11678
|
if (isEnclosed) {
|
|
11671
11679
|
paths.push(cand.ids);
|
|
11672
11680
|
}
|
|
@@ -11674,6 +11682,7 @@
|
|
|
11674
11682
|
return paths.length > 0 ? paths : null;
|
|
11675
11683
|
};
|
|
11676
11684
|
|
|
11685
|
+
// return array of indexed paths within a given shape
|
|
11677
11686
|
this.findPathsInsideShape = function(shape) {
|
|
11678
11687
|
var paths = []; // list of enclosed paths
|
|
11679
11688
|
shape.forEach(function(ids) {
|
|
@@ -12075,7 +12084,6 @@
|
|
|
12075
12084
|
yy = coords.yy,
|
|
12076
12085
|
ids = nodes.getConnectedArcs(fromArcId),
|
|
12077
12086
|
toArcId = fromArcId; // initialize to fromArcId -- an error condition
|
|
12078
|
-
|
|
12079
12087
|
if (filter) {
|
|
12080
12088
|
ids = ids.filter(filter);
|
|
12081
12089
|
}
|
|
@@ -12104,14 +12112,12 @@
|
|
|
12104
12112
|
continue;
|
|
12105
12113
|
}
|
|
12106
12114
|
icand = arcs.indexOfVertex(candId, -2);
|
|
12107
|
-
|
|
12108
12115
|
if (toArcId == fromArcId) {
|
|
12109
12116
|
// first valid candidate
|
|
12110
12117
|
ito = icand;
|
|
12111
12118
|
toArcId = candId;
|
|
12112
12119
|
continue;
|
|
12113
12120
|
}
|
|
12114
|
-
|
|
12115
12121
|
code = chooseRighthandPath(fromX, fromY, nodeX, nodeY, xx[ito], yy[ito], xx[icand], yy[icand]);
|
|
12116
12122
|
if (code == 2) {
|
|
12117
12123
|
ito = icand;
|
|
@@ -12119,6 +12125,7 @@
|
|
|
12119
12125
|
}
|
|
12120
12126
|
}
|
|
12121
12127
|
|
|
12128
|
+
|
|
12122
12129
|
if (toArcId == fromArcId) {
|
|
12123
12130
|
// This shouldn't occur, assuming that other arcs are present
|
|
12124
12131
|
error("Pathfinder error");
|
|
@@ -12183,6 +12190,9 @@
|
|
|
12183
12190
|
chooseRighthandVector: chooseRighthandVector
|
|
12184
12191
|
});
|
|
12185
12192
|
|
|
12193
|
+
var FWD_USED = 0x8;
|
|
12194
|
+
var REV_USED = 0x80;
|
|
12195
|
+
|
|
12186
12196
|
function setBits(bits, arcBits, mask) {
|
|
12187
12197
|
return (bits & ~mask) | (arcBits & mask);
|
|
12188
12198
|
}
|
|
@@ -12210,6 +12220,16 @@
|
|
|
12210
12220
|
return bits & 7;
|
|
12211
12221
|
}
|
|
12212
12222
|
|
|
12223
|
+
function markPathsAsUsed(paths, routesArr) {
|
|
12224
|
+
forEachArcId(paths, function(arcId) {
|
|
12225
|
+
if (arcId < 0) {
|
|
12226
|
+
routesArr[~arcId] |= REV_USED;
|
|
12227
|
+
} else {
|
|
12228
|
+
routesArr[arcId] |= FWD_USED;
|
|
12229
|
+
}
|
|
12230
|
+
});
|
|
12231
|
+
}
|
|
12232
|
+
|
|
12213
12233
|
// Open arc pathways in a single shape or array of shapes
|
|
12214
12234
|
//
|
|
12215
12235
|
function openArcRoutes(paths, arcColl, routesArr, fwd, rev, dissolve, orBits) {
|
|
@@ -12400,6 +12420,7 @@
|
|
|
12400
12420
|
andBits: andBits,
|
|
12401
12421
|
setRouteBits: setRouteBits,
|
|
12402
12422
|
getRouteBits: getRouteBits,
|
|
12423
|
+
markPathsAsUsed: markPathsAsUsed,
|
|
12403
12424
|
openArcRoutes: openArcRoutes,
|
|
12404
12425
|
closeArcRoutes: closeArcRoutes,
|
|
12405
12426
|
getPathFinder: getPathFinder,
|
|
@@ -33401,7 +33422,7 @@ ${svg}
|
|
|
33401
33422
|
var clipArcTouches = 0;
|
|
33402
33423
|
var clipArcUses = 0;
|
|
33403
33424
|
var usedClipArcs = [];
|
|
33404
|
-
var
|
|
33425
|
+
var findPath = getPathFinder(nodes, useRoute, routeIsActive);
|
|
33405
33426
|
var dissolvePolygon = getPolygonDissolver(nodes);
|
|
33406
33427
|
|
|
33407
33428
|
// The following cleanup step is a performance bottleneck (it often takes longer than
|
|
@@ -33434,12 +33455,16 @@ ${svg}
|
|
|
33434
33455
|
return null;
|
|
33435
33456
|
});
|
|
33436
33457
|
|
|
33458
|
+
markPathsAsUsed(clippedShapes, routeFlags); // to help us find unused paths later
|
|
33459
|
+
|
|
33460
|
+
|
|
33437
33461
|
// add clip/erase polygons that are fully contained in a target polygon
|
|
33438
33462
|
// need to index only non-intersecting clip shapes
|
|
33439
33463
|
// (Intersecting shapes have one or more arcs that have been scanned)
|
|
33440
33464
|
|
|
33441
33465
|
// first, find shapes that do not intersect the target layer
|
|
33442
33466
|
// (these could be inside or outside the target polygons)
|
|
33467
|
+
|
|
33443
33468
|
var undividedClipShapes = findUndividedClipShapes(clipShapes);
|
|
33444
33469
|
|
|
33445
33470
|
closeArcRoutes(clipShapes, arcs, routeFlags, true, true); // not needed?
|
|
@@ -33468,7 +33493,7 @@ ${svg}
|
|
|
33468
33493
|
for (var i=0, n=ids.length; i<n; i++) {
|
|
33469
33494
|
clipArcTouches = 0;
|
|
33470
33495
|
clipArcUses = 0;
|
|
33471
|
-
path =
|
|
33496
|
+
path = findPath(ids[i]);
|
|
33472
33497
|
if (path) {
|
|
33473
33498
|
// if ring doesn't touch/intersect a clip/erase polygon, check if it is contained
|
|
33474
33499
|
// if (clipArcTouches === 0) {
|
|
@@ -33487,6 +33512,7 @@ ${svg}
|
|
|
33487
33512
|
}
|
|
33488
33513
|
});
|
|
33489
33514
|
|
|
33515
|
+
|
|
33490
33516
|
// Clear pathways of current target shape to hidden/closed
|
|
33491
33517
|
closeArcRoutes(shape, arcs, routeFlags, true, true, true);
|
|
33492
33518
|
// Also clear pathways of any clip arcs that were used
|
|
@@ -33557,8 +33583,9 @@ ${svg}
|
|
|
33557
33583
|
return usable;
|
|
33558
33584
|
}
|
|
33559
33585
|
|
|
33560
|
-
|
|
33561
|
-
//
|
|
33586
|
+
|
|
33587
|
+
// Filter a collection of shapes to exclude paths that incorporate parts of
|
|
33588
|
+
// clip/erase polygons and paths that are hidden (e.g. internal boundaries)
|
|
33562
33589
|
function findUndividedClipShapes(clipShapes) {
|
|
33563
33590
|
return clipShapes.map(function(shape) {
|
|
33564
33591
|
var usableParts = [];
|
|
@@ -33582,12 +33609,12 @@ ${svg}
|
|
|
33582
33609
|
});
|
|
33583
33610
|
}
|
|
33584
33611
|
|
|
33585
|
-
|
|
33586
|
-
// (not testing open/closed or visible/hidden)
|
|
33612
|
+
|
|
33587
33613
|
function arcIsUnused(id, flags) {
|
|
33588
33614
|
var abs = absArcId(id),
|
|
33589
33615
|
flag = flags[abs];
|
|
33590
|
-
return (flag &
|
|
33616
|
+
return (flag & 0x88) === 0;
|
|
33617
|
+
// return id < 0 ? (flag & 0x80) === 0 : (flag & 0x8) === 0;
|
|
33591
33618
|
}
|
|
33592
33619
|
|
|
33593
33620
|
function arcIsVisible(id, flags) {
|
|
@@ -33610,7 +33637,7 @@ ${svg}
|
|
|
33610
33637
|
enclosedPaths.forEach(function(ids) {
|
|
33611
33638
|
var path;
|
|
33612
33639
|
for (var j=0; j<ids.length; j++) {
|
|
33613
|
-
path =
|
|
33640
|
+
path = findPath(ids[j]);
|
|
33614
33641
|
if (path) {
|
|
33615
33642
|
dissolvedPaths.push(path);
|
|
33616
33643
|
}
|