mapshaper 0.7.24 → 0.7.25

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 CHANGED
@@ -42415,7 +42415,20 @@ ${svg}
42415
42415
  // TODO - figure out which bearing to use
42416
42416
  joinAngle = getJoinAngle(bearing, firstBearing);
42417
42417
  if (joinAngle > 0) {
42418
- builder.addBufferVertices(makeFinalJoin(x2, y2, bearing - 90, joinAngle, dist), segId - 1);
42418
+ // Close the ring exactly onto its first offset vertex (p1First).
42419
+ // makeFinalJoin's terminal point is recomputed via
42420
+ // getOffsetPoint(seam, (bearing-90)+joinAngle) -- mathematically equal
42421
+ // to p1First = getOffsetPoint(seam, firstBearing-90) but ~1 ULP away,
42422
+ // because the closing angle is summed differently. That sub-ULP gap
42423
+ // leaves a near-zero-width sliver at the seam that the winding-number
42424
+ // dissolve cannot resolve consistently across JS engines (Math.sin/cos
42425
+ // last-ULP values differ between V8 versions), intermittently splitting
42426
+ // the filled buffer into a source-as-hole "band". Reusing p1First closes
42427
+ // the seam exactly. Copy it: buffer[0] is the same p1First reference and
42428
+ // unprojectFeatures() rewrites ring coordinates in place for lat-long
42429
+ // datasets, so a shared reference would be mutated twice.
42430
+ builder.addBufferVertices(makeRoundJoin(x2, y2, bearing - 90, joinAngle, dist), segId - 1);
42431
+ if (p1First) builder.addBufferVertex(p1First.concat(), segId - 1);
42419
42432
  } else if (joinAngle < 0 && segId > 1 &&
42420
42433
  !bufferSegmentIntersection(p1Prev, p2Prev, p1First, p2First)) {
42421
42434
  // Concave closure with non-intersecting first/last offset segments:
@@ -43074,12 +43087,6 @@ ${svg}
43074
43087
  return verts;
43075
43088
  }
43076
43089
 
43077
- function makeFinalJoin(x, y, direction, angle, dist) {
43078
- var points = makeRoundJoin(x, y, direction, angle, dist);
43079
- points.push(getOffsetPoint(x, y, direction + angle, dist));
43080
- return points;
43081
- }
43082
-
43083
43090
  function makeRoundCap(x, y, startDir, dist) {
43084
43091
  var points = makeBearingAlignedArc(x, y, startDir, 180, dist);
43085
43092
  points.push(getOffsetPoint(x, y, startDir + 180, dist)); // add final vertex
@@ -61762,7 +61769,7 @@ ${svg}
61762
61769
  return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
61763
61770
  }
61764
61771
 
61765
- var version = "0.7.24";
61772
+ var version = "0.7.25";
61766
61773
 
61767
61774
  // Parse command line args into commands and run them
61768
61775
  // 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.7.24",
3
+ "version": "0.7.25",
4
4
  "description": "A tool for editing geospatial data for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/mapshaper.js CHANGED
@@ -42415,7 +42415,20 @@ ${svg}
42415
42415
  // TODO - figure out which bearing to use
42416
42416
  joinAngle = getJoinAngle(bearing, firstBearing);
42417
42417
  if (joinAngle > 0) {
42418
- builder.addBufferVertices(makeFinalJoin(x2, y2, bearing - 90, joinAngle, dist), segId - 1);
42418
+ // Close the ring exactly onto its first offset vertex (p1First).
42419
+ // makeFinalJoin's terminal point is recomputed via
42420
+ // getOffsetPoint(seam, (bearing-90)+joinAngle) -- mathematically equal
42421
+ // to p1First = getOffsetPoint(seam, firstBearing-90) but ~1 ULP away,
42422
+ // because the closing angle is summed differently. That sub-ULP gap
42423
+ // leaves a near-zero-width sliver at the seam that the winding-number
42424
+ // dissolve cannot resolve consistently across JS engines (Math.sin/cos
42425
+ // last-ULP values differ between V8 versions), intermittently splitting
42426
+ // the filled buffer into a source-as-hole "band". Reusing p1First closes
42427
+ // the seam exactly. Copy it: buffer[0] is the same p1First reference and
42428
+ // unprojectFeatures() rewrites ring coordinates in place for lat-long
42429
+ // datasets, so a shared reference would be mutated twice.
42430
+ builder.addBufferVertices(makeRoundJoin(x2, y2, bearing - 90, joinAngle, dist), segId - 1);
42431
+ if (p1First) builder.addBufferVertex(p1First.concat(), segId - 1);
42419
42432
  } else if (joinAngle < 0 && segId > 1 &&
42420
42433
  !bufferSegmentIntersection(p1Prev, p2Prev, p1First, p2First)) {
42421
42434
  // Concave closure with non-intersecting first/last offset segments:
@@ -43074,12 +43087,6 @@ ${svg}
43074
43087
  return verts;
43075
43088
  }
43076
43089
 
43077
- function makeFinalJoin(x, y, direction, angle, dist) {
43078
- var points = makeRoundJoin(x, y, direction, angle, dist);
43079
- points.push(getOffsetPoint(x, y, direction + angle, dist));
43080
- return points;
43081
- }
43082
-
43083
43090
  function makeRoundCap(x, y, startDir, dist) {
43084
43091
  var points = makeBearingAlignedArc(x, y, startDir, 180, dist);
43085
43092
  points.push(getOffsetPoint(x, y, startDir + 180, dist)); // add final vertex
@@ -61762,7 +61769,7 @@ ${svg}
61762
61769
  return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
61763
61770
  }
61764
61771
 
61765
- var version = "0.7.24";
61772
+ var version = "0.7.25";
61766
61773
 
61767
61774
  // Parse command line args into commands and run them
61768
61775
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.