mapshaper 0.6.80 → 0.6.82

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
@@ -39557,7 +39557,7 @@ ${svg}
39557
39557
  }
39558
39558
 
39559
39559
  function isCircleClippedProjection(P) {
39560
- return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers');
39560
+ return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos');
39561
39561
  }
39562
39562
 
39563
39563
  function getPerspectiveClipAngle(P) {
@@ -39572,7 +39572,7 @@ ${svg}
39572
39572
 
39573
39573
  function getDefaultClipAngle(P) {
39574
39574
  var slug = getCrsSlug(P);
39575
- if (slug == 'nsper') return getPerspectiveClipAngle(P);
39575
+ if (slug == 'nsper' || slug == 'geos') return getPerspectiveClipAngle(P);
39576
39576
  if (slug == 'tpers') {
39577
39577
  message('Automatic clipping is not supported for the Tilted Perspective projection');
39578
39578
  return 0;
@@ -45535,7 +45535,7 @@ ${svg}
45535
45535
  });
45536
45536
  }
45537
45537
 
45538
- var version = "0.6.80";
45538
+ var version = "0.6.82";
45539
45539
 
45540
45540
  // Parse command line args into commands and run them
45541
45541
  // 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.80",
3
+ "version": "0.6.82",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -56,7 +56,7 @@
56
56
  "iconv-lite": "^0.6.3",
57
57
  "idb-keyval": "^6.2.0",
58
58
  "kdbush": "^3.0.0",
59
- "mproj": "0.0.37",
59
+ "mproj": "0.0.38",
60
60
  "msgpackr": "^1.10.1",
61
61
  "opn": "^5.3.0",
62
62
  "rw": "~1.3.3",
package/www/index.html CHANGED
@@ -294,12 +294,11 @@ encoding=big5</span>. Click to see all options.</div></div></div></div>
294
294
  <div class="console-window"><div class="console-buffer selectable"></div></div>
295
295
  </div>
296
296
  <div class="mshp-main-map main-area map-area">
297
- <div class="coordinate-info colored-text selectable"></div>
298
297
  <div class="intersection-display">
299
298
  <span class="intersection-check text-btn colored-text">Check line intersections</span><span class="intersection-count">0 line intersections</span>
300
299
  <img class="close-btn" draggable="false" src="images/close.png">
301
300
  <div class="repair-btn text-btn colored-text">Repair</div>
302
-
301
+
303
302
  </div>
304
303
  <div class="map-layers"></div>
305
304
  <div class="basemap-container"><div class="basemap"></div></div>
@@ -3419,15 +3419,19 @@
3419
3419
  }
3420
3420
  }
3421
3421
 
3422
- function pencilPointIsSkippable(p2, points) {
3423
- var p1 = points[0];
3424
- var dist;
3425
- if (points.length < 2) return true;
3422
+ // Test if adding point p to a sequence of points (in pixel coords)
3423
+ // would result in a polyline that deviates from a straight line by
3424
+ // more than a given number of pixels
3425
+ //
3426
+ function pointExceedsTolerance(p, points, tolerance) {
3427
+ if (points.length < 2) return false;
3428
+ var p1 = points[0], p2, dist;
3426
3429
  for (var i=1; i<points.length; i++) {
3427
- dist = Math.sqrt(geom.pointSegDistSq(points[i][0], points[i][1], p1[0], p1[1], p2[0], p2[1]));
3428
- if (dist > 1.5) return false;
3430
+ p2 = points[i];
3431
+ dist = Math.sqrt(geom.pointSegDistSq(p2[0], p2[1], p1[0], p1[1], p[0], p[1]));
3432
+ if (dist > tolerance) return true;
3429
3433
  }
3430
- return true;
3434
+ return false;
3431
3435
  }
3432
3436
 
3433
3437
  function setZ(lyr, z) {
@@ -3499,6 +3503,15 @@
3499
3503
  }
3500
3504
  }
3501
3505
 
3506
+ function deleteFeature(lyr, fid) {
3507
+ var records = lyr.data?.getRecords();
3508
+ if (records) records.splice(fid, 1);
3509
+ lyr.shapes.splice(fid, 1);
3510
+ if (isProjectedLayer(lyr) && lyr.shapes != lyr.gui.displayLayer.shapes) {
3511
+ lyr.gui.displayLayer.shapes.splice(fid, 1);
3512
+ }
3513
+ }
3514
+
3502
3515
  // p: one point in source data coords
3503
3516
  function appendNewPoint(lyr, p) {
3504
3517
  lyr.shapes.push([p]);
@@ -3512,12 +3525,7 @@
3512
3525
  }
3513
3526
 
3514
3527
  function deletePoint(lyr, fid) {
3515
- var records = lyr.data?.getRecords();
3516
- lyr.shapes.splice(fid, 1);
3517
- if (records) records.splice(fid, 1);
3518
- if (isProjectedLayer(lyr)) {
3519
- lyr.gui.displayLayer.shapes.splice(fid, 1);
3520
- }
3528
+ deleteFeature(lyr, fid);
3521
3529
  }
3522
3530
 
3523
3531
  function insertPoint(lyr, fid, shp, d) {
@@ -5804,6 +5812,7 @@
5804
5812
  var ctrlDown = false;
5805
5813
  var metaDown = false;
5806
5814
  var altDown = false;
5815
+ var spaceDown = false;
5807
5816
 
5808
5817
  function updateControlKeys(e) {
5809
5818
  shiftDown = e.shiftKey;
@@ -5811,15 +5820,22 @@
5811
5820
  metaDown = e.metaKey;
5812
5821
  altDown = e.altKey;
5813
5822
  }
5823
+
5824
+ function mouseIsPressed() {
5825
+ return gui.map.getMouse().isDown();
5826
+ }
5827
+
5814
5828
  document.addEventListener('keyup', function(e) {
5815
- if (!GUI.isActiveInstance(gui)) return;
5829
+ if (!GUI.isActiveInstance(gui) || e.repeat) return;
5816
5830
  // this can fail to fire if keyup occurs over a context menu
5831
+ if (e.keyCode == 32) spaceDown = false;
5817
5832
  updateControlKeys(e);
5818
5833
  self.dispatchEvent('keyup', getEventData(e));
5819
5834
  });
5820
5835
 
5821
5836
  document.addEventListener('keydown', function(e) {
5822
- if (!GUI.isActiveInstance(gui)) return;
5837
+ if (!GUI.isActiveInstance(gui) || e.repeat) return;
5838
+ if (e.keyCode == 32) spaceDown = true;
5823
5839
  updateControlKeys(e);
5824
5840
  self.dispatchEvent('keydown', getEventData(e));
5825
5841
  });
@@ -5829,10 +5845,11 @@
5829
5845
  updateControlKeys(e);
5830
5846
  });
5831
5847
 
5832
- this.shiftIsPressed = function() { return shiftDown; };
5833
- this.ctrlIsPressed = function() { return ctrlDown; };
5834
- this.altIsPressed = function() { return altDown; };
5835
- this.metaIsPressed = function() { return metaDown; };
5848
+ this.shiftIsPressed = () => shiftDown;
5849
+ this.ctrlIsPressed = () => ctrlDown;
5850
+ this.altIsPressed = () => altDown;
5851
+ this.metaIsPressed = () => metaDown;
5852
+ this.spaceIsPressed = () => spaceDown;
5836
5853
 
5837
5854
  this.onMenuSubmit = function(menuEl, cb) {
5838
5855
  gui.on('enter_key', function(e) {
@@ -5870,7 +5887,7 @@
5870
5887
 
5871
5888
  var menus = {
5872
5889
  standard: ['info', 'selection', 'box'],
5873
- empty: ['edit_points', 'edit_lines', 'edit_polygons'],
5890
+ empty: ['edit_points', 'edit_lines', 'edit_polygons', 'box'],
5874
5891
  polygons: ['info', 'selection', 'box', 'edit_polygons'],
5875
5892
  rectangles: ['info', 'selection', 'box', 'rectangles'],
5876
5893
  lines: ['info', 'selection', 'box' , 'edit_lines'],
@@ -8536,69 +8553,6 @@
8536
8553
  return self;
8537
8554
  }
8538
8555
 
8539
- function CoordinatesDisplay(gui, ext, mouse) {
8540
- var readout = gui.container.findChild('.coordinate-info').hide();
8541
-
8542
- function enabled() {
8543
- var lyr = gui.map.getActiveLayer();
8544
- return !!(lyr && lyr.gui.displayLayer.geometry_type);
8545
- }
8546
-
8547
- gui.model.on('update', function(e) {
8548
- readout.hide();
8549
- });
8550
-
8551
- readout.on('copy', function(e) {
8552
- // remove selection on copy (using timeout or else copy is cancelled)
8553
- setTimeout(function() {
8554
- window.getSelection().removeAllRanges();
8555
- }, 50);
8556
- });
8557
-
8558
- // clear coords when map pans
8559
- ext.on('change', function() {
8560
- clearCoords();
8561
- // shapes may change along with map scale
8562
- // target = lyr ? lyr.getDisplayLayer() : null;
8563
- });
8564
-
8565
- mouse.on('leave', clearCoords);
8566
-
8567
- mouse.on('click', function(e) {
8568
- if (!enabled()) return;
8569
- GUI.selectElement(readout.node());
8570
- });
8571
-
8572
- mouse.on('hover', onMouseChange);
8573
- mouse.on('drag', onMouseChange, null, 10); // high priority so editor doesn't block propagation
8574
-
8575
- function onMouseChange(e) {
8576
- if (!enabled()) return;
8577
- if (isOverMap(e)) {
8578
- displayCoords(gui.map.translatePixelCoords(e.x, e.y));
8579
- } else {
8580
- clearCoords();
8581
- }
8582
- }
8583
-
8584
- function displayCoords(p) {
8585
- var p1 = gui.map.translatePixelCoords(0, ext.height());
8586
- var p2 = gui.map.translatePixelCoords(ext.width(), 0);
8587
- var bbox = p1.concat(p2);
8588
- var decimals = internal.getBoundsPrecisionForDisplay(bbox);
8589
- var str = internal.getRoundedCoordString(p, decimals);
8590
- readout.text(str).show();
8591
- }
8592
-
8593
- function clearCoords() {
8594
- readout.hide();
8595
- }
8596
-
8597
- function isOverMap(e) {
8598
- return e.x >= 0 && e.y >= 0 && e.x < ext.width() && e.y < ext.height();
8599
- }
8600
- }
8601
-
8602
8556
  function getTimerFunction() {
8603
8557
  return typeof requestAnimationFrame == 'function' ?
8604
8558
  requestAnimationFrame : function(cb) {setTimeout(cb, 25);};
@@ -9147,7 +9101,8 @@
9147
9101
  if (!boxCoords) return null;
9148
9102
  var dataBox = getBBoxCoords(gui.map.getActiveLayer(), boxCoords);
9149
9103
  fixBounds(dataBox);
9150
- return internal.getRoundedCoords(dataBox, internal.getBoundsPrecisionForDisplay(dataBox));
9104
+ // return internal.getRoundedCoords(dataBox, internal.getBoundsPrecisionForDisplay(dataBox));
9105
+ return dataBox;
9151
9106
  };
9152
9107
 
9153
9108
  box.turnOn = function() {
@@ -9336,6 +9291,14 @@
9336
9291
  if (useBoxZoom()) zoomBox.turnOn();
9337
9292
  dragStartEvt = e;
9338
9293
  gui.dispatchEvent('shift_drag_start');
9294
+ } else {
9295
+ El('body').addClass('pan');
9296
+ setTimeout(function() {
9297
+ var body = El('body');
9298
+ if (body.hasClass('pan')) {
9299
+ body.addClass('panning');
9300
+ }
9301
+ }, 100);
9339
9302
  }
9340
9303
  });
9341
9304
 
@@ -9355,6 +9318,8 @@
9355
9318
  shiftDrag = false;
9356
9319
  gui.dispatchEvent('shift_drag_end', getBoxData(e));
9357
9320
  zoomBox.turnOff();
9321
+ } else {
9322
+ El('body').removeClass('panning').removeClass('pan');
9358
9323
  }
9359
9324
  });
9360
9325
 
@@ -9904,12 +9869,18 @@
9904
9869
  });
9905
9870
 
9906
9871
  hit.on('contextmenu', function(e) {
9907
- var target = hit.getHitTarget();
9908
- if (!e.overMap || e.mode == 'edit_lines' ||
9909
- e.mode == 'edit_polygons' || e.mode == 'edit_points') {
9872
+ if (!e.overMap || e.mode == 'edit_lines' || e.mode == 'edit_polygons' ||
9873
+ e.mode == 'edit_points') {
9910
9874
  return;
9911
9875
  }
9912
- gui.contextMenu.open(e, hit.getHitTarget());
9876
+ var target = hit.getHitTarget();
9877
+ if (e.ids.length == 1) {
9878
+ e.deleteFeature = function() {
9879
+ deleteFeature(target, e.ids[0]);
9880
+ gui.model.updated({filter:true});
9881
+ };
9882
+ }
9883
+ gui.contextMenu.open(e, target);
9913
9884
  });
9914
9885
 
9915
9886
  hit.on('change', function(e) {
@@ -10332,23 +10303,27 @@
10332
10303
  var drawingId = -1; // feature id of path being drawn
10333
10304
  var sessionCount = 0;
10334
10305
  var alert;
10335
- var pencilPoints;
10306
+ var pencilPoints = [];
10336
10307
  var _dragging = false;
10337
10308
 
10338
10309
  function active() {
10339
10310
  return initialArcCount >= 0;
10340
10311
  }
10341
10312
 
10342
- function dragging() {
10313
+ function vertexDragging() {
10343
10314
  return _dragging;
10344
10315
  }
10345
10316
 
10346
- function drawing() {
10317
+ function pathDrawing() {
10347
10318
  return drawingId > -1;
10348
10319
  }
10349
10320
 
10350
- function usingPencil() {
10351
- return (gui.keyboard.altIsPressed() || gui.keyboard.metaIsPressed()) && active() && !dragging();
10321
+ function cmdKeyDown() {
10322
+ return gui.keyboard.altIsPressed() || gui.keyboard.metaIsPressed();
10323
+ }
10324
+
10325
+ function pencilIsActive() {
10326
+ return active() && (cmdKeyDown() || pathDrawing()) && !vertexDragging();
10352
10327
  }
10353
10328
 
10354
10329
  function polygonMode() {
@@ -10392,7 +10367,7 @@
10392
10367
 
10393
10368
  gui.on('redo_path_extend', function(e) {
10394
10369
  var target = hit.getHitTarget();
10395
- if (drawing() && prevHoverEvent) {
10370
+ if (pathDrawing() && prevHoverEvent) {
10396
10371
  updatePathEndpoint(e.p);
10397
10372
  appendVertex$1(target, pixToDataCoords(prevHoverEvent.x, prevHoverEvent.y));
10398
10373
  } else {
@@ -10405,7 +10380,7 @@
10405
10380
 
10406
10381
  gui.on('undo_path_extend', function(e) {
10407
10382
  var target = hit.getHitTarget();
10408
- if (drawing() && prevHoverEvent) {
10383
+ if (pathDrawing() && prevHoverEvent) {
10409
10384
  deleteLastVertex(target);
10410
10385
  updatePathEndpoint(pixToDataCoords(prevHoverEvent.x, prevHoverEvent.y));
10411
10386
  } else {
@@ -10433,9 +10408,7 @@
10433
10408
  function showInstructions() {
10434
10409
  var isMac = navigator.userAgent.includes('Mac');
10435
10410
  var undoKey = isMac ? '⌘' : '^';
10436
- var drawKey = isMac ? '⌘' : 'Alt';
10437
- var pathStr = polygonMode() ? 'closed paths' : 'paths';
10438
- var msg = `Instructions: Click to start a path or add a point. ${drawKey}-drag draws a path. Drag points to reshape. Type ${undoKey}Z/${undoKey}Y to undo/redo.`;
10411
+ var msg = `Instructions: click to start a path, click or drag to keep drawing. Drag vertices to reshape a path. Type ${undoKey}Z/${undoKey}Y to undo/redo.`;
10439
10412
  alert = showPopupAlert(msg, null, {
10440
10413
  non_blocking: true, max_width: '388px'});
10441
10414
  }
@@ -10494,10 +10467,17 @@
10494
10467
  drawingId = -1;
10495
10468
  hoverVertexInfo = null;
10496
10469
  prevClickEvent = prevHoverEvent = null;
10470
+ updateCursor();
10497
10471
  }
10498
10472
 
10473
+ gui.keyboard.on('keydown', function(e) {
10474
+ if (active() && e.keyName == 'space') {
10475
+ e.stopPropagation(); // prevent console from opening if shift-panning
10476
+ }
10477
+ }, null, 1);
10478
+
10499
10479
  hit.on('contextmenu', function(e) {
10500
- if (!active() || drawing() || dragging()) return;
10480
+ if (!active() || pathDrawing() || vertexDragging()) return;
10501
10481
  var target = hit.getHitTarget();
10502
10482
  var vInfo = hoverVertexInfo;
10503
10483
  if (hoverVertexInfo?.type == 'vertex' && !vertexIsEndpoint(vInfo, target)) {
@@ -10510,7 +10490,7 @@
10510
10490
  });
10511
10491
 
10512
10492
  hit.on('dragstart', function(e) {
10513
- if (!active() || drawing() || !hoverVertexInfo) return;
10493
+ if (!active() || pathDrawing() || !hoverVertexInfo) return;
10514
10494
  hideInstructions();
10515
10495
  e.originalEvent.stopPropagation();
10516
10496
  _dragging = true;
@@ -10522,15 +10502,43 @@
10522
10502
  hit.setHoverVertex(hoverVertexInfo.displayPoint, hoverVertexInfo.type);
10523
10503
  });
10524
10504
 
10505
+ gui.map.getMouse().on('dragend', function(e) {
10506
+ pencilPoints = []; // re-enable pencil after closing a path
10507
+ });
10508
+
10525
10509
  gui.map.getMouse().on('drag', function(e) {
10526
- if (!usingPencil()) return;
10527
- e.stopPropagation();
10510
+ if (!pencilIsActive()) {
10511
+ if (!pencilPoints) {
10512
+ // null points signals that a path was just completed -- block panning
10513
+ e.stopPropagation();
10514
+ }
10515
+ return;
10516
+ }
10517
+ if (gui.keyboard.spaceIsPressed()) {
10518
+ // pan if dragging with spacebar down
10519
+ pencilPoints = []; // don't continue previous line after panning
10520
+ return;
10521
+ }
10522
+ e.stopPropagation(); // prevent panning
10523
+ hoverVertexInfo = findPathStartInfo(e);
10528
10524
  var xy = [e.x, e.y];
10529
10525
  var p = pixToDataCoords(e.x, e.y);
10530
- if (!drawing()) {
10526
+ if (!pathDrawing()) {
10531
10527
  pencilPoints = [xy];
10532
10528
  startNewPath(p);
10533
- } else if (!pencilPoints || !pencilPointIsSkippable(xy, pencilPoints)) {
10529
+ } else if (pencilPoints.length == 0) {
10530
+ // start pencil-drawing when a path is started
10531
+ pencilPoints = [xy];
10532
+ extendCurrentPath(p);
10533
+ } else if (hoverVertexInfo && pencilPoints.length > 2) {
10534
+ // close path
10535
+ p = hoverVertexInfo.point;
10536
+ appendVertex$1(hit.getHitTarget(), p);
10537
+ extendCurrentPath(p);
10538
+ pencilPoints = null; // stop drawing
10539
+ } else if (pointExceedsTolerance(xy, pencilPoints, 1.5)) {
10540
+ xy = pencilPoints.pop();
10541
+ p = pixToDataCoords(xy[0], xy[1]);
10534
10542
  pencilPoints = [xy];
10535
10543
  extendCurrentPath(p);
10536
10544
  } else {
@@ -10541,7 +10549,9 @@
10541
10549
  }, null, 3); // higher priority than hit control
10542
10550
 
10543
10551
  hit.on('drag', function(e) {
10544
- if (!dragging() || drawing()) return;
10552
+ if (!vertexDragging() || pathDrawing()) {
10553
+ return;
10554
+ }
10545
10555
  e.originalEvent.stopPropagation();
10546
10556
  // dragging a vertex
10547
10557
  var target = hit.getHitTarget();
@@ -10556,7 +10566,7 @@
10556
10566
  });
10557
10567
 
10558
10568
  hit.on('dragend', function(e) {
10559
- if (!dragging()) return;
10569
+ if (!vertexDragging()) return;
10560
10570
  _dragging = false;
10561
10571
  var target = hit.getHitTarget();
10562
10572
  // kludge to get dataset to recalculate internal bounding boxes
@@ -10573,7 +10583,7 @@
10573
10583
  if (!active()) return;
10574
10584
  // double click finishes a path
10575
10585
  // note: if the preceding 'click' finished the path, this does not fire
10576
- if (drawing()) {
10586
+ if (pathDrawing()) {
10577
10587
  finishCurrentPath();
10578
10588
  e.originalEvent.stopPropagation(); // prevent dblclick zoom
10579
10589
  return;
@@ -10583,9 +10593,9 @@
10583
10593
  // hover event highlights the nearest point in close proximity to the pointer
10584
10594
  // ... or the closest point along the segment (for adding a new vertex)
10585
10595
  hit.on('hover', function(e) {
10586
- if (!active() || dragging()) return;
10596
+ if (!active() || vertexDragging()) return;
10587
10597
 
10588
- if (drawing()) {
10598
+ if (pathDrawing()) {
10589
10599
  if (!e.overMap) {
10590
10600
  finishCurrentPath();
10591
10601
  return;
@@ -10599,7 +10609,7 @@
10599
10609
  // highlight nearby snappable vertex (the closest vertex on a nearby line,
10600
10610
  // or the first vertex of the current drawing path if not near a line)
10601
10611
  hoverVertexInfo = e.id >= 0 && findDraggableVertices(e) ||
10602
- drawing() && findPathStartInfo(e) ||
10612
+ pathDrawing() && findPathStartInfo(e) ||
10603
10613
  e.id >= 0 && findInterpolatedPoint(e);
10604
10614
  if (hoverVertexInfo) {
10605
10615
  // hovering near a vertex: highlight the vertex
@@ -10616,10 +10626,13 @@
10616
10626
  if (!active()) return;
10617
10627
  if (detectDoubleClick(e)) return; // ignore second click of a dblclick
10618
10628
  var p = pixToDataCoords(e.x, e.y);
10619
- if (drawing()) {
10629
+ if (pathDrawing()) {
10620
10630
  extendCurrentPath(hoverVertexInfo?.point || p);
10621
10631
  } else if (gui.keyboard.shiftIsPressed()) {
10622
10632
  deleteActiveVertex(e);
10633
+ } else if (hoverVertexInfo?.type == 'interpolated') {
10634
+ // don't start new path if hovering along a segment -- this is
10635
+ // likely to be an attempt to add a new vertex, not start a new path
10623
10636
  } else {
10624
10637
  startNewPath(p);
10625
10638
  }
@@ -10646,9 +10659,11 @@
10646
10659
  }
10647
10660
 
10648
10661
  function updateCursor() {
10649
- gui.container.findChild('.map-layers').classed('drawing', active());
10650
- var useArrow = hoverVertexInfo && !hoverVertexInfo.extendable && !drawing();
10651
- gui.container.findChild('.map-layers').classed('dragging', useArrow);
10662
+ var el = gui.container.findChild('.map-layers');
10663
+ el.classed('draw-tool', active());
10664
+ var useArrow = hoverVertexInfo && !hoverVertexInfo.extendable && !pathDrawing();
10665
+ el.classed('dragging', useArrow);
10666
+ el.classed('drawing', pathDrawing());
10652
10667
  }
10653
10668
 
10654
10669
  function vertexIsEndpoint(info, target) {
@@ -10713,7 +10728,7 @@
10713
10728
  }
10714
10729
 
10715
10730
  function finishCurrentPath() {
10716
- if (!drawing()) return;
10731
+ if (!pathDrawing()) return;
10717
10732
  var target = hit.getHitTarget();
10718
10733
  if (getLastArcLength(target) <= 2) { // includes hover point
10719
10734
  deleteLastPath(target);
@@ -10736,12 +10751,6 @@
10736
10751
  updateCursor();
10737
10752
  }
10738
10753
 
10739
- function pencilDraw(e) {
10740
- var p = pixToDataCoords(e.x, e.y);
10741
- extendCurrentPath(p);
10742
-
10743
- }
10744
-
10745
10754
  // p: [x, y] source data coordinates of new point on path
10746
10755
  function extendCurrentPath(p) {
10747
10756
  var target = hit.getHitTarget();
@@ -10794,6 +10803,7 @@
10794
10803
  }
10795
10804
 
10796
10805
  function findPathStartInfo(e) {
10806
+ if (!pathDrawing()) return false;
10797
10807
  var target = hit.getHitTarget();
10798
10808
  var arcId = target.gui.displayArcs.size() - 1;
10799
10809
  var p1 = ext.translatePixelCoords(e.x, e.y); // mouse coords
@@ -12090,7 +12100,7 @@
12090
12100
 
12091
12101
  new SimpleButton(popup.findChild('.select-btn')).on('click', function() {
12092
12102
  var coords = box.getDataCoords();
12093
- if (!coords) return;
12103
+ if (!coords || noData()) return;
12094
12104
  gui.enterMode('selection_tool');
12095
12105
  gui.interaction.setMode('selection');
12096
12106
  // kludge to pass bbox to the selection tool
@@ -12099,6 +12109,10 @@
12099
12109
  });
12100
12110
  });
12101
12111
 
12112
+ function noData() {
12113
+ return !gui.model.getActiveLayer();
12114
+ }
12115
+
12102
12116
  new SimpleButton(popup.findChild('.clip-btn')).on('click', function() {
12103
12117
  runCommand('-clip bbox=' + box.getDataCoords().join(','));
12104
12118
  });
@@ -12156,7 +12170,9 @@
12156
12170
 
12157
12171
  function showCoords() {
12158
12172
  El(infoBtn.node()).addClass('selected-btn');
12159
- coords.text(box.getDataCoords().join(','));
12173
+ var bbox = box.getDataCoords();
12174
+ var rounded = internal.getRoundedCoords(bbox, internal.getBoundsPrecisionForDisplay(bbox));
12175
+ coords.text(rounded.join(','));
12160
12176
  coords.show();
12161
12177
  GUI.selectElement(coords.node());
12162
12178
  }
@@ -12571,9 +12587,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12571
12587
 
12572
12588
  _basemap = new Basemap(gui, _ext);
12573
12589
 
12574
- if (gui.options.showMouseCoordinates) {
12575
- new CoordinatesDisplay(gui, _ext, _mouse);
12576
- }
12577
12590
  _mouse.disable(); // wait for gui.focus() to activate mouse events
12578
12591
 
12579
12592
  model.on('select', function(e) {
@@ -13148,6 +13161,13 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13148
13161
  if (e.ids?.length) {
13149
13162
  addMenuItem('Copy as GeoJSON', copyGeoJSON);
13150
13163
  }
13164
+ if (e.deleteFeature) {
13165
+ addMenuItem(getDeleteLabel(), e.deleteFeature);
13166
+ }
13167
+
13168
+ function getDeleteLabel() {
13169
+ return 'Delete ' + (lyr.geometry_type == 'point' ? 'point' : 'shape');
13170
+ }
13151
13171
 
13152
13172
  function addCoords(p) {
13153
13173
  var coordStr = p[0] + ',' + p[1];
@@ -13195,7 +13215,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13195
13215
  inspectorControl: true,
13196
13216
  saveControl: true,
13197
13217
  disableNavigation: false,
13198
- showMouseCoordinates: true,
13199
13218
  focus: true
13200
13219
  }, opts);
13201
13220
 
package/www/mapshaper.js CHANGED
@@ -39557,7 +39557,7 @@ ${svg}
39557
39557
  }
39558
39558
 
39559
39559
  function isCircleClippedProjection(P) {
39560
- return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers');
39560
+ return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos');
39561
39561
  }
39562
39562
 
39563
39563
  function getPerspectiveClipAngle(P) {
@@ -39572,7 +39572,7 @@ ${svg}
39572
39572
 
39573
39573
  function getDefaultClipAngle(P) {
39574
39574
  var slug = getCrsSlug(P);
39575
- if (slug == 'nsper') return getPerspectiveClipAngle(P);
39575
+ if (slug == 'nsper' || slug == 'geos') return getPerspectiveClipAngle(P);
39576
39576
  if (slug == 'tpers') {
39577
39577
  message('Automatic clipping is not supported for the Tilted Perspective projection');
39578
39578
  return 0;
@@ -45535,7 +45535,7 @@ ${svg}
45535
45535
  });
45536
45536
  }
45537
45537
 
45538
- var version = "0.6.80";
45538
+ var version = "0.6.82";
45539
45539
 
45540
45540
  // Parse command line args into commands and run them
45541
45541
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.