mapshaper 0.6.78 → 0.6.79

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
@@ -45532,7 +45532,7 @@ ${svg}
45532
45532
  });
45533
45533
  }
45534
45534
 
45535
- var version = "0.6.78";
45535
+ var version = "0.6.79";
45536
45536
 
45537
45537
  // Parse command line args into commands and run them
45538
45538
  // 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.78",
3
+ "version": "0.6.79",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -3451,6 +3451,25 @@
3451
3451
  }
3452
3452
  }
3453
3453
 
3454
+ function deletePoint(lyr, fid) {
3455
+ var records = lyr.data?.getRecords();
3456
+ lyr.shapes.splice(fid, 1);
3457
+ if (records) records.splice(fid, 1);
3458
+ if (isProjectedLayer(lyr)) {
3459
+ lyr.gui.displayLayer.shapes.splice(fid, 1);
3460
+ }
3461
+ }
3462
+
3463
+ function insertPoint(lyr, fid, shp, d) {
3464
+ var records = lyr.data?.getRecords();
3465
+ if (records) records.splice(fid, 0, d);
3466
+ lyr.shapes.splice(fid, 0, shp);
3467
+ if (isProjectedLayer(lyr)) {
3468
+ var shp2 = projectPointCoords(shp, lyr.gui.projectPoint);
3469
+ lyr.gui.displayLayer.shapes.splice(fid, 0, shp2);
3470
+ }
3471
+ }
3472
+
3454
3473
  function deleteLastPoint(lyr) {
3455
3474
  if (lyr.data) {
3456
3475
  lyr.data.getRecords().pop();
@@ -5522,6 +5541,16 @@
5522
5541
  addHistoryState(undo, redo);
5523
5542
  });
5524
5543
 
5544
+ gui.on('point_delete', function(e) {
5545
+ var redo = function() {
5546
+ deletePoint(e.data.target, e.fid);
5547
+ };
5548
+ var undo = function() {
5549
+ insertPoint(e.data.target, e.fid, e.coords, e.d);
5550
+ };
5551
+ addHistoryState(undo, redo);
5552
+ });
5553
+
5525
5554
  gui.on('path_add', function(e) {
5526
5555
  var redo = function() {
5527
5556
  gui.dispatchEvent('redo_path_add', {p1: e.p1, p2: e.p2});
@@ -5591,6 +5620,7 @@
5591
5620
  gui.on('active', updateVisibility);
5592
5621
  gui.on('inactive', updateVisibility);
5593
5622
  gui.model.on('update', updateVisibility);
5623
+ gui.on('mode', updateVisibility);
5594
5624
 
5595
5625
  // @iconRef: selector for an (svg) button icon
5596
5626
  this.addButton = function(iconRef) {
@@ -5719,19 +5749,24 @@
5719
5749
  document.addEventListener('keyup', function(e) {
5720
5750
  if (!GUI.isActiveInstance(gui)) return;
5721
5751
  // this can fail to fire if keyup occurs over a context menu
5722
- // if (e.keyCode == 16) shiftDown = false;
5723
5752
  shiftDown = e.shiftKey;
5724
- if (e.keyCode == 17) ctrlDown = false;
5753
+ ctrlDown = e.ctrlKey;
5725
5754
  self.dispatchEvent('keyup', getEventData(e));
5726
5755
  });
5727
5756
 
5728
5757
  document.addEventListener('keydown', function(e) {
5729
5758
  if (!GUI.isActiveInstance(gui)) return;
5730
5759
  shiftDown = e.shiftKey;
5731
- if (e.keyCode == 17) ctrlDown = true;
5760
+ ctrlDown = e.ctrlKey;
5732
5761
  self.dispatchEvent('keydown', getEventData(e));
5733
5762
  });
5734
5763
 
5764
+ document.addEventListener('mousemove', function(e) {
5765
+ // refreshing these here to prevent problems when context menu opens
5766
+ shiftDown = e.shiftKey;
5767
+ ctrlDown = e.ctrlKey;
5768
+ });
5769
+
5735
5770
  this.shiftIsPressed = function() { return shiftDown; };
5736
5771
  this.ctrlIsPressed = function() { return ctrlDown; };
5737
5772
 
@@ -8060,7 +8095,7 @@
8060
8095
  self.setHitId = function(id) {
8061
8096
  if (storedData.id == id) return;
8062
8097
  storedData.id = id;
8063
- storedData.ids = [id];
8098
+ storedData.ids = id == -1 ? [] : [id];
8064
8099
  triggerHitEvent('change');
8065
8100
  };
8066
8101
 
@@ -9804,7 +9839,7 @@
9804
9839
  hit.on('contextmenu', function(e) {
9805
9840
  var target = hit.getHitTarget();
9806
9841
  if (!e.overMap || !target || e.mode == 'edit_lines' ||
9807
- e.mode == 'edit_polygons') {
9842
+ e.mode == 'edit_polygons' || e.mode == 'edit_points') {
9808
9843
  return;
9809
9844
  }
9810
9845
  gui.contextMenu.open(e, hit.getHitTarget());
@@ -10099,7 +10134,8 @@
10099
10134
  }
10100
10135
 
10101
10136
  function initPointEditing(gui, ext, hit) {
10102
- var symbolInfo;
10137
+ var instructionsShown = false;
10138
+ var symbolInfo, alert;
10103
10139
  function active(e) {
10104
10140
  return gui.interaction.getMode() == 'edit_points';
10105
10141
  }
@@ -10108,17 +10144,57 @@
10108
10144
  return active(e) && e.id > -1;
10109
10145
  }
10110
10146
 
10147
+ function hideInstructions() {
10148
+ if (!alert) return;
10149
+ alert.close('fade');
10150
+ alert = null;
10151
+ }
10152
+
10153
+ function showInstructions() {
10154
+ var isMac = navigator.userAgent.includes('Mac');
10155
+ var symbol = isMac ? '⌘' : '^';
10156
+ var msg = `Instructions: Click on the map to add points. Move points by dragging. Type ${symbol}Z/${symbol}Y to undo/redo.`;
10157
+ alert = showPopupAlert(msg, null, { non_blocking: true, max_width: '360px'});
10158
+ }
10159
+
10111
10160
  gui.on('interaction_mode_change', function(e) {
10112
10161
  if (e.mode == 'edit_points' && !gui.model.getActiveLayer()) {
10113
10162
  addEmptyLayer(gui, undefined, 'point');
10114
10163
  } else if (e.prev_mode == 'edit_points') {
10164
+ hideInstructions();
10115
10165
  gui.container.findChild('.map-layers').classed('add-points', false);
10116
10166
  }
10167
+ if (e.mode == 'edit_points' && !instructionsShown) {
10168
+ instructionsShown = true;
10169
+ showInstructions();
10170
+ }
10171
+ });
10117
10172
 
10173
+ hit.on('contextmenu', function(e) {
10174
+ if (!active(e)) return;
10175
+ var target = hit.getHitTarget();
10176
+ var id = e.id;
10177
+ if (id > -1) {
10178
+ e.deletePoint = function() {
10179
+ removePoint(target, id);
10180
+ };
10181
+ }
10182
+ gui.contextMenu.open(e, target);
10118
10183
  });
10119
10184
 
10185
+ function removePoint(target, id) {
10186
+ var d = target.data ? target.data.getRecords()[id] : null;
10187
+ var coords = target.shapes[id];
10188
+ deletePoint(target, id);
10189
+ gui.dispatchEvent('point_delete', {coords, d, target, fid: id});
10190
+ gui.dispatchEvent('map-needs-refresh');
10191
+ hit.setHitId(-1);
10192
+ }
10193
+
10120
10194
  hit.on('click', function(e) {
10121
10195
  if (overPoint(e) || !active(e)) return;
10196
+ hideInstructions();
10197
+
10122
10198
  // add point
10123
10199
  var p = pixToDataCoords(e.x, e.y);
10124
10200
  var target = hit.getHitTarget();
@@ -10135,6 +10211,7 @@
10135
10211
 
10136
10212
  hit.on('dragstart', function(e) {
10137
10213
  if (!overPoint(e)) return;
10214
+ hideInstructions();
10138
10215
  var target = hit.getHitTarget();
10139
10216
  symbolInfo = {
10140
10217
  FID: e.id,
@@ -12955,6 +13032,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12955
13032
  if (e.deleteVertex) {
12956
13033
  addMenuItem('Delete vertex', e.deleteVertex);
12957
13034
  }
13035
+ if (e.deletePoint) {
13036
+ addMenuItem('Delete point', e.deletePoint);
13037
+ }
12958
13038
  if (e.ids?.length) {
12959
13039
  addMenuItem('Copy as GeoJSON', copyGeoJSON);
12960
13040
  }
package/www/mapshaper.js CHANGED
@@ -45532,7 +45532,7 @@ ${svg}
45532
45532
  });
45533
45533
  }
45534
45534
 
45535
- var version = "0.6.78";
45535
+ var version = "0.6.79";
45536
45536
 
45537
45537
  // Parse command line args into commands and run them
45538
45538
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/www/page.css CHANGED
@@ -59,7 +59,7 @@ body.map-view {
59
59
 
60
60
 
61
61
  .selectable,.selectable * {
62
- user-select: default;
62
+ user-select: text;
63
63
  cursor: text;
64
64
  }
65
65
 
@@ -343,17 +343,17 @@ div.alert-box {
343
343
  }
344
344
 
345
345
  .mini-drop-area {
346
- border: 1.5px dashed #bbb;
347
- max-width: 240px;
346
+ border: 1.5px dashed #999;
347
+ max-width: 245px;
348
348
  border-radius: 9px;
349
- font-size: 15px;
349
+ font-size: 14px;
350
350
  line-height: 1.5;
351
- color: #888;
352
- /* background-color: #FFFEF8;*/
353
- padding: 6px 4px 7px 7px;
354
- padding: 11px 14px;
351
+ /* color: #555;*/
352
+ padding: 9px 11px 6px 11px;
355
353
  margin: 9px -1px 3px -1px;
356
354
  min-height: 120px;
355
+ background: #f8fdff;
356
+ ;
357
357
  }
358
358
 
359
359
  .catalog-mode .file-catalog {