mapshaper 0.6.109 → 0.6.110

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.109",
3
+ "version": "0.6.110",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -43,6 +43,7 @@
43
43
  "@tmcw/togeojson": "^5.6.0",
44
44
  "@xmldom/xmldom": "^0.8.6",
45
45
  "adm-zip": "^0.5.9",
46
+ "big.js": "^7.0.1",
46
47
  "commander": "7.0.0",
47
48
  "cookies": "^0.8.0",
48
49
  "d3-color": "3.1.0",
@@ -69,7 +70,6 @@
69
70
  "csv-spectrum": "^1.0.0",
70
71
  "eslint": "^8.16.0",
71
72
  "mocha": "^10.2.0",
72
- "robust-predicates": "^3.0.2",
73
73
  "rollup": "^4.44.1",
74
74
  "rollup-plugin-polyfill-node": "^0.13.0",
75
75
  "shell-quote": "^1.7.4",
package/www/elements.css CHANGED
@@ -131,7 +131,7 @@ div.tip {
131
131
  .btn {
132
132
  text-align: center;
133
133
  /* padding: 4px 7px 5px 7px; */
134
- padding: 3px 6px 4px 6px;
134
+ padding: 5px 6px 4px 6px;
135
135
  border-radius: 4px;
136
136
  line-height: 1;
137
137
  display: inline-block;
package/www/index.html CHANGED
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <title>mapshaper</title>
5
5
  <meta name="Description" content="A tool for topologically aware shape simplification. Reads and writes Shapefile, GeoJSON and TopoJSON formats.">
@@ -42,24 +42,6 @@
42
42
  <svg id="ribbon-icon" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="15" height="25" viewBox="0 1 15 20">
43
43
  <polygon points="8 14.5 13 19 13 4 3 4 3 19 8 14.5" fill="#30d4ef"/>
44
44
  </svg>
45
-
46
- <defs>
47
- <style>
48
- .cls-1 {
49
- fill: #0c0a0a;
50
- }
51
- </style>
52
- </defs>
53
- <g id="left_arrow">
54
- <polygon class="cls-1" points="0.5 6 6.5 11.5 6.5 0.5 0.5 6"/>
55
- </g>
56
- </svg>
57
-
58
- <svg id="info-menu-icon" xmlns="http://www.w3.org/2000/svg" width="8" height="12" viewBox="0 0 8 12">
59
- <g id="left_arrow">
60
- <polygon class="cls-1" points="0.5 6 6.5 11.5 6.5 0.5 0.5 6"/>
61
- </g>
62
- </svg>
63
45
 
64
46
  </div>
65
47
 
@@ -70,13 +52,15 @@
70
52
 
71
53
  <div class="simplify-control-wrapper"><div class="simplify-control"><div class="header-btn btn simplify-settings-btn">Settings</div>
72
54
  <div class="slider">
73
- <div class="handle"><img src="images/slider_handle_v1.png" alt=""/></div>
55
+ <div class="handle"><img src="images/slider_handle_v1.png" alt=""></div>
74
56
  <div class="track"></div>
75
57
  </div>
76
- <input type="text" value="label" class="clicktext" />
58
+ <input type="text" value="label" class="clicktext">
59
+ <!-- <div class="header-btn btn simplify-done-btn">Done</div> -->
77
60
  </div></div>
78
61
  <div id="mode-buttons" class="page-header-buttons">
79
- <span class="console-btn header-btn btn">Console</span><span class="display-btn header-btn btn">Display</span><span class="separator"></span><span class="separator"></span><span class="simplify-btn header-btn btn">Simplify</span><span class="separator"></span><span class="export-btn header-btn btn">Export</span>
62
+ <!-- <span class="project-btn header-btn btn">Project</span><span class="separator"> -->
63
+ <span class="console-btn header-btn btn">Console</span><span class="display-btn header-btn btn">Display</span><span class="separator"></span><span class="separator"></span></span><span class="simplify-btn header-btn btn">Simplify</span><span class="separator"></span><span class="export-btn header-btn btn">Export</span>
80
64
  </div>
81
65
  <div id="splash-buttons" class="page-header-buttons">
82
66
  <a href="https://github.com/mbloch/mapshaper/wiki"><span id="wiki-btn" class="header-btn btn">Wiki</span></a><span class="separator"></span><a href="https://github.com/mbloch/mapshaper"><span id="github-btn" class="header-btn btn">GitHub</span></a>
@@ -96,8 +80,8 @@
96
80
  <div class="layer-menu">
97
81
  <h3>Layers</h3>
98
82
  <div class="pin-all pinnable">
99
- <img class="eye-btn black-eye" src="images/eye.png">
100
- <img class="eye-btn green-eye" src="images/eye2.png">
83
+ <img class="eye-btn black-eye" src="images/eye.png" alt="">
84
+ <img class="eye-btn green-eye" src="images/eye2.png" alt="">
101
85
  </div>
102
86
  <div class="layer-list"></div>
103
87
  <!-- <h4>Sources</h4> -->
@@ -146,7 +130,7 @@
146
130
  <div class="info-box">
147
131
  <div class="close2-btn"></div>
148
132
  <h3>Export options</h3>
149
- <div class=export-layers>
133
+ <div class="export-layers">
150
134
  <h4 class="menu-title">Layers</h4>
151
135
  <div class="export-layer-list option-menu"></div>
152
136
  </div>
@@ -161,8 +145,8 @@
161
145
 
162
146
  <div style="height:11px"></div>
163
147
 
164
- <div class="option-menu"><input type="text" class="text-input advanced-options" placeholder="command line options" />
165
- <a href="https://github.com/mbloch/mapshaper/wiki/Command-Reference#-o-output" target="_mapshaper_output_docs">
148
+ <div class="option-menu"><input type="text" class="text-input advanced-options" placeholder="command line options">
149
+ <a href="https://github.com/mbloch/mapshaper/wiki/Command-Reference#-o-output" target="mapshaper_output_docs">
166
150
  <div class="tip-button">?<div class="tip-anchor">
167
151
  <div class="tip">Enter options from the command line interface for
168
152
  the -o command. Examples: bbox no-quantization
@@ -171,8 +155,8 @@ precision=0.001. Click to see all options.</div></div></div></a>
171
155
  <!-- <div class="option-menu">
172
156
  <input id="ofile-name" class="text-input" type="text" placeholder="output file name" />
173
157
  </div> -->
174
- <div><span id="save-preference" style="display: none;"><input type="checkbox"/>choose output directory</span></div>
175
- <div><span id="save-to-clipboard" style="display: inline-block;"><input type="checkbox"/>save to clipboard</span></div>
158
+ <div><span id="save-preference" style="display: none;"><input type="checkbox">choose output directory</span></div>
159
+ <div><span id="save-to-clipboard" style="display: inline-block;"><input type="checkbox">save to clipboard</span></div>
176
160
  </div>
177
161
  <div id="export-btn" class="btn dialog-btn" style="margin-top: 5px;">Export</div>
178
162
 
@@ -184,8 +168,8 @@ precision=0.001. Click to see all options.</div></div></div></a>
184
168
  <div class="close2-btn"></div>
185
169
  <h3>Display options</h3>
186
170
 
187
- <div class=""><label for="intersections-opt"><input type="checkbox" id="intersections-opt" class="checkbox intersections-opt"/>detect line intersections</label></div>
188
- <div class=""><label for="ghost-opt"><input type="checkbox" id="ghost-opt" class="checkbox ghost-opt"/>show reference lines</label></div>
171
+ <div class=""><label><input type="checkbox" id="intersections-opt" class="checkbox intersections-opt">detect line intersections</label></div>
172
+ <div class=""><label><input type="checkbox" id="ghost-opt" class="checkbox ghost-opt">show reference lines</label></div>
189
173
 
190
174
  <div class="basemap-opts">
191
175
  <h4>Basemaps</h4>
@@ -202,18 +186,33 @@ precision=0.001. Click to see all options.</div></div></div></a>
202
186
  </div>
203
187
  </div>
204
188
 
189
+ <div class="project-options main-area popup-dialog popup-align-left">
190
+ <div class="info-box">
191
+ <div class="close2-btn"></div>
192
+ <h3>Projections</h3>
193
+ <div class="option-menu">
194
+ <div id="proj-list"></div>
195
+ <div id="proj-option-list"></div>
196
+ </div>
197
+ <div>
198
+ <div class="preview-btn btn dialog-btn">Preview</div>
199
+ <div class="apply-btn btn dialog-btn">Apply</div>
200
+ </div>
201
+ </div>
202
+ </div>
203
+
205
204
  <div class="simplify-options main-area popup-dialog">
206
205
  <div class="info-box">
207
206
  <div class="close2-btn"></div>
208
207
  <h3>Simplification</h3>
209
208
  <div class="option-menu">
210
- <div><label for="import-retain-opt"><input type="checkbox" class="checkbox import-retain-opt"/>prevent shape removal</label>
209
+ <div><label><input type="checkbox" class="checkbox import-retain-opt" id="import-retain-opt">prevent shape removal</label>
211
210
  <div class="tip-button">?<div class="tip-anchor">
212
211
  <div class="tip">Prevent small polygon features from
213
212
  disappearing at high simplification. Keeps
214
213
  the largest ring of multi-ring features.
215
214
  </div></div></div></div>
216
- <div class="planar-opt-wrapper"><label for="planar-opt"><input type="checkbox" class="checkbox planar-opt"/>use planar geometry</label>
215
+ <div class="planar-opt-wrapper"><label><input type="checkbox" class="checkbox planar-opt" id="planar-opt">use planar geometry</label>
217
216
  <div class="tip-button">?<div class="tip-anchor">
218
217
  <div class="tip">Treat x, y values as Cartesian coordinates
219
218
  on a plane, rather than as longitude, latitude
@@ -229,7 +228,7 @@ coordinates on a sphere.
229
228
  distance of original lines. Good for
230
229
  thinning dense points, but spikes
231
230
  tend to form at high simplification.</div></div></div>
232
- </div>
231
+ </div>
233
232
 
234
233
  <div><label><input type="radio" name="method" value="visvalingam" class="radio">Visvalingam / effective area</label><div class="tip-button">?<div class="tip-anchor">
235
234
  <div class="tip">Lines are simplified by iteratively
@@ -258,7 +257,7 @@ a smoother appearance.</div></div></div></div>
258
257
  <div class="cancel-btn close2-btn"></div>
259
258
  <h3 class="list-header">Import files</h3>
260
259
  <div class="import-instructions">
261
- <span><input type="checkbox" class="advanced-import-options" />with advanced options</span>
260
+ <span><input type="checkbox" class="advanced-import-options">with advanced options</span>
262
261
  <div class="mini-drop-area">
263
262
  <div class="subtitle">Drop, paste or <span class="add-btn inline-btn btn"><span class="label-text">select</span></span> files to import.</div>
264
263
  <div class="subtitle">Shapefile, GeoJSON, TopoJSON, KML and CSV formats are supported. Files can be zipped or gzipped.</div>
@@ -267,29 +266,24 @@ a smoother appearance.</div></div></div></div>
267
266
  <div class="queued-file-section">
268
267
  <!-- <h4>Files</h4> -->
269
268
  <div class="dropped-file-list"></div>
270
-
271
269
  <div class="option-menu">
272
-
273
- <div id="path-import-options">
274
- <!-- <h4>Options</h4> -->
270
+ <div id="path-import-options">
275
271
  </div>
276
-
277
- <div style="margin-top: 10px"><input type="text" class="text-input advanced-options" placeholder="import options" />
278
- <a href="https://github.com/mbloch/mapshaper/wiki/Command-Reference#-i-input" target="_mapshaper_import_docs">
272
+ <div style="margin-top: 10px"><input type="text" class="text-input advanced-options" placeholder="import options">
273
+ <a href="https://github.com/mbloch/mapshaper/wiki/Command-Reference#-i-input" target="mapshaper_import_docs">
279
274
  <div class="tip-button">?<div class="tip-anchor">
280
275
  <div class="tip">Enter options from the command line
281
276
  interface. Examples: <span id="import-option-examples">snap no-topology
282
- encoding=big5</span>. Click to see all options.</div></div></div></div>
277
+ encoding=big5</span>. Click to see all options.</div></div></div>
283
278
  </a>
284
-
285
279
  </div>
286
280
 
287
281
  <!-- <div class="cancel-btn btn dialog-btn">Cancel</div>
288
282
  <div class="add-btn btn dialog-btn">Select</div> -->
289
283
  <div class="submit-btn btn dialog-btn default-btn disabled">Submit</div>
290
284
 
285
+ </div>
291
286
  </div>
292
-
293
287
  </div> <!-- .info-box -->
294
288
  </div> <!-- import-options -->
295
289
 
@@ -310,14 +304,14 @@ encoding=big5</span>. Click to see all options.</div></div></div></div>
310
304
  </div>
311
305
  </div>
312
306
 
313
- <div id="import-options-drop-area" class="main-area drop-area-wrapper hidden">
307
+ <div id="import-options-drop-area" class="main-area drop-area-wrapper hidden">
314
308
  <div class="drop-area"></div>
315
309
  </div>
316
310
 
317
- <script src="basemap.js" type="text/javascript"></script>
318
- <script src="modules.js" type="text/javascript"></script>
319
- <script src="mapshaper.js" type="text/javascript"></script>
320
- <script src="manifest.js" type="text/javascript"></script>
321
- <script src="mapshaper-gui.js" type="text/javascript"></script>
311
+ <script src="basemap.js"></script>
312
+ <script src="modules.js"></script>
313
+ <script src="mapshaper.js"></script>
314
+ <script src="manifest.js"></script>
315
+ <script src="mapshaper-gui.js"></script>
322
316
  </body>
323
317
  </html>
@@ -3227,18 +3227,20 @@
3227
3227
  }
3228
3228
 
3229
3229
  // p1, p2: two points in source data CRS coords.
3230
- function appendNewPath(lyr, p1, p2) {
3230
+ function appendNewPath(lyr, points) {
3231
3231
  var arcId = lyr.gui.displayArcs.size();
3232
3232
  internal.appendEmptyArc(lyr.gui.displayArcs);
3233
3233
  lyr.shapes.push([[arcId]]);
3234
3234
  if (isProjectedLayer(lyr)) {
3235
3235
  internal.appendEmptyArc(lyr.gui.source.dataset.arcs);
3236
3236
  }
3237
- appendVertex$1(lyr, p1);
3238
- appendVertex$1(lyr, p2);
3237
+ points.forEach(function(p) {
3238
+ appendVertex$1(lyr, p);
3239
+ });
3239
3240
  appendNewDataRecord(lyr);
3240
3241
  }
3241
3242
 
3243
+
3242
3244
  function deleteLastPath(lyr) {
3243
3245
  var arcId = lyr.gui.displayArcs.size() - 1;
3244
3246
  if (lyr.data) {
@@ -4310,7 +4312,9 @@
4310
4312
  if (_unsimplifiedXX && action == 'simplify_drag_end') {
4311
4313
  // re-use previously generated intersection data (optimization)
4312
4314
  } else {
4315
+ // console.time('xx');
4313
4316
  _unsimplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
4317
+ // console.timeEnd('xx');
4314
4318
  }
4315
4319
  }
4316
4320
  showIntersections(_simplifiedXX || _unsimplifiedXX, e.layer, arcs);
@@ -5840,7 +5844,7 @@
5840
5844
  empty: ['edit_polygons', 'edit_lines', 'edit_points', 'box'],
5841
5845
  polygons: ['info', 'selection', 'box', 'edit_polygons'],
5842
5846
  rectangles: ['info', 'selection', 'box', 'rectangles', 'edit_polygons'],
5843
- lines: ['info', 'selection', 'box' , 'edit_lines'],
5847
+ lines: ['info', 'selection', 'box', 'edit_lines'], // 'snip_lines'
5844
5848
  table: ['info', 'selection'],
5845
5849
  labels: ['info', 'selection', 'box', 'labels', 'edit_points'],
5846
5850
  points: ['info', 'selection', 'box', 'edit_points'] // , 'add-points'
@@ -5861,6 +5865,7 @@
5861
5865
  edit_points: 'add/drag points',
5862
5866
  edit_lines: 'draw/edit polylines',
5863
5867
  edit_polygons: 'draw/edit polygons',
5868
+ snip_lines: 'snip polylines',
5864
5869
  vertices: 'edit vertices',
5865
5870
  selection: 'selection tool',
5866
5871
  'add-points': 'add points',
@@ -5924,7 +5929,7 @@
5924
5929
  };
5925
5930
 
5926
5931
  this.modeUsesHitDetection = function(mode) {
5927
- return ['info', 'selection', 'data', 'labels', 'edit_points', 'vertices', 'rectangles', 'edit_lines', 'edit_polygons'].includes(mode);
5932
+ return ['info', 'selection', 'data', 'labels', 'edit_points', 'vertices', 'rectangles', 'edit_lines', 'edit_polygons', 'snip_lines'].includes(mode);
5928
5933
  };
5929
5934
 
5930
5935
  this.modeUsesPopup = function(mode) {
@@ -6270,13 +6275,21 @@
6270
6275
 
6271
6276
  function verbose() {
6272
6277
  // verbose can be set globally with the -verbose command or separately for each command
6273
- if (getStashedVar('VERBOSE')) {
6278
+ if (useVerbose()) {
6274
6279
  message.apply(null, arguments);
6275
6280
  }
6276
6281
  }
6277
6282
 
6283
+ function useVerbose() {
6284
+ return getStashedVar('VERBOSE');
6285
+ }
6286
+
6287
+ function useDebug() {
6288
+ return getStashedVar('DEBUG');
6289
+ }
6290
+
6278
6291
  function debug() {
6279
- if (getStashedVar('DEBUG')) {
6292
+ if (useDebug()) {
6280
6293
  logArgs(arguments);
6281
6294
  }
6282
6295
  }
@@ -9954,7 +9967,7 @@
9954
9967
 
9955
9968
  hit.on('contextmenu', function(e) {
9956
9969
  if (!e.overMap || e.mode == 'edit_lines' || e.mode == 'edit_polygons' ||
9957
- e.mode == 'edit_points') {
9970
+ e.mode == 'edit_points' || e.mode == 'snip_lines') {
9958
9971
  return;
9959
9972
  }
9960
9973
  var target = hit.getHitTarget();
@@ -10082,7 +10095,8 @@
10082
10095
  return [lyr];
10083
10096
  }
10084
10097
  if (styleOpts.interactionMode == 'edit_lines' ||
10085
- styleOpts.interactionMode == 'edit_polygons') {
10098
+ styleOpts.interactionMode == 'edit_polygons' ||
10099
+ styleOpts.interactionMode == 'snip_lines') {
10086
10100
  // special overlay: shape editing mode
10087
10101
  lyr = getOverlayLayer(activeLyr, hitData.ids);
10088
10102
  lyr.gui.style = getLineEditingStyle(hitData);
@@ -10583,7 +10597,7 @@
10583
10597
  }
10584
10598
 
10585
10599
  // pixel distance threshold for hovering near a vertex or segment midpoint
10586
- var HOVER_THRESHOLD = 10;
10600
+ var HOVER_THRESHOLD$1 = 10;
10587
10601
 
10588
10602
  function initLineEditing(gui, ext, hit) {
10589
10603
  var hoverVertexInfo;
@@ -10645,7 +10659,7 @@
10645
10659
  gui.on('redo_path_add', function(e) {
10646
10660
  var target = hit.getHitTarget();
10647
10661
  clearDrawingInfo();
10648
- appendNewPath(target, e.p1, e.p2);
10662
+ appendNewPath(target, [e.p1, e.p2]);
10649
10663
  deleteLastVertex(target); // second vertex is a placeholder
10650
10664
  gui.undo.redo(); // add next vertex in the path
10651
10665
  fullRedraw();
@@ -11044,7 +11058,7 @@
11044
11058
  function startNewPath(p2) {
11045
11059
  var target = hit.getHitTarget();
11046
11060
  var p1 = hoverVertexInfo?.point || p2;
11047
- appendNewPath(target, p1, p2);
11061
+ appendNewPath(target, [p1, p2]);
11048
11062
  gui.dispatchEvent('path_add', {target, p1, p2});
11049
11063
  drawingId = target.shapes.length - 1;
11050
11064
  hit.setDrawingId(drawingId);
@@ -11120,7 +11134,7 @@
11120
11134
  var i = data.ii[arcId];
11121
11135
  var pathLen = data.nn[arcId];
11122
11136
  var pixelDist = dist / ext.getPixelSize();
11123
- if (pixelDist > HOVER_THRESHOLD || pathLen < 4) {
11137
+ if (pixelDist > HOVER_THRESHOLD$1 || pathLen < 4) {
11124
11138
  return null;
11125
11139
  }
11126
11140
  return {
@@ -11139,7 +11153,7 @@
11139
11153
  var p2 = target.gui.displayArcs.getVertex2(ids[0]);
11140
11154
  var dist = geom.distance2D(p[0], p[1], p2[0], p2[1]);
11141
11155
  var pixelDist = dist / ext.getPixelSize();
11142
- if (pixelDist > HOVER_THRESHOLD) {
11156
+ if (pixelDist > HOVER_THRESHOLD$1) {
11143
11157
  return null;
11144
11158
  }
11145
11159
  var point = getVertexCoords(target, ids[0]); // data coordinates
@@ -11177,7 +11191,7 @@
11177
11191
  }
11178
11192
  });
11179
11193
 
11180
- if (closest.distance / ext.getPixelSize() > HOVER_THRESHOLD) {
11194
+ if (closest.distance / ext.getPixelSize() > HOVER_THRESHOLD$1) {
11181
11195
  return null;
11182
11196
  }
11183
11197
  closest.point = translateDisplayPoint(target, closest.displayPoint);
@@ -11227,10 +11241,154 @@
11227
11241
  }
11228
11242
  }
11229
11243
 
11244
+ function snipLineAtVertex(lyr, fid, vid) {
11245
+ // find the feature part and arc containing the vertex
11246
+ // divide the one feature into two features
11247
+ // divide the arc into two new arcs
11248
+ var arc1, arc2;
11249
+ // divide the feature into two parts
11250
+ }
11251
+
11252
+ function mergeLinesAtVertex(lyr) {
11253
+
11254
+ }
11255
+
11256
+ // TODO: support snipping rings (by snipping in two places)
11257
+
11258
+
11259
+ // pixel distance threshold for hovering near a vertex or segment midpoint
11260
+ var HOVER_THRESHOLD = 10;
11261
+
11262
+ function initSnipTool(gui, ext, hit) {
11263
+ var _active = true;
11264
+ var hoverVertexInfo;
11265
+ var prevHoverEvent;
11266
+
11267
+ gui.on('interaction_mode_change', function(e) {
11268
+ if (active()) {
11269
+ turnOff();
11270
+ }
11271
+ // updateCursor();
11272
+ }, null, 10); // higher priority than hit control, so turnOff() has correct hit target
11273
+
11274
+
11275
+ // hover event highlights the nearest point in close proximity to the pointer
11276
+ // ... or the closest point along the segment (for adding a new vertex)
11277
+ hit.on('hover', function(e) {
11278
+ if (!active()) return;
11279
+
11280
+ // highlight nearby snappable vertex (the closest vertex on a nearby line,
11281
+ // or the first vertex of the current drawing path if not near a line)
11282
+ hoverVertexInfo = e.id >= 0 && findDraggableVertices(e) ||
11283
+ e.id >= 0 && findInterpolatedPoint(e);
11284
+ if (hoverVertexInfo) {
11285
+ // hovering near a vertex: highlight the vertex
11286
+ hit.setHoverVertex(hoverVertexInfo.displayPoint, hoverVertexInfo.type);
11287
+ } else {
11288
+ clearHoverVertex();
11289
+ }
11290
+ // updateCursor();
11291
+ prevHoverEvent = e;
11292
+ }, null, 100);
11293
+
11294
+ hit.on('click', function(e) {
11295
+ if (!active() || !hoverVertexInfo) return;
11296
+ var target = hit.getHitTarget();
11297
+ if (vertexIsEndpoint(hoverVertexInfo, target)) {
11298
+ // TODO: don't allow hovering on endpoints
11299
+ return;
11300
+ }
11301
+
11302
+ if (hoverVertexInfo.type == 'interpolated') {
11303
+ insertVertex$1(target, hoverVertexInfo.i, hoverVertexInfo.point);
11304
+ hoverVertexInfo.ids = [hoverVertexInfo.i];
11305
+ }
11306
+
11307
+ snipLineAtVertex(target, e.id, hoverVertexInfo.ids[0]);
11308
+
11309
+ hit.setHoverVertex(hoverVertexInfo.displayPoint, hoverVertexInfo.type);
11310
+
11311
+ });
11312
+
11313
+ // return data on the nearest vertex (or identical vertices) to the pointer
11314
+ // (if within a distance threshold)
11315
+ //
11316
+ function findDraggableVertices(e) {
11317
+ var target = hit.getHitTarget();
11318
+ var shp = target.shapes[e.id];
11319
+ var p = ext.pixCoordsToMapCoords(e.x, e.y);
11320
+ var ids = internal.findNearestVertices(p, shp, target.gui.displayArcs);
11321
+ var p2 = target.gui.displayArcs.getVertex2(ids[0]);
11322
+ var dist = geom.distance2D(p[0], p[1], p2[0], p2[1]);
11323
+ var pixelDist = dist / ext.getPixelSize();
11324
+ if (pixelDist > HOVER_THRESHOLD) {
11325
+ return null;
11326
+ }
11327
+ var point = getVertexCoords(target, ids[0]); // data coordinates
11328
+ var displayPoint = target.gui.displayArcs.getVertex2(ids[0]);
11329
+ return {target, ids, point, displayPoint, type: 'vertex'};
11330
+ }
11331
+
11332
+ function findInterpolatedPoint(e) {
11333
+ var target = hit.getHitTarget();
11334
+ //// vertex insertion not supported with simplification
11335
+ // if (!target.arcs.isFlat()) return null;
11336
+ var p = ext.pixCoordsToMapCoords(e.x, e.y);
11337
+ var minDist = Infinity;
11338
+ var shp = target.shapes[e.id];
11339
+ var closest;
11340
+ internal.forEachSegmentInShape(shp, target.gui.displayArcs, function(i, j, xx, yy) {
11341
+ var x1 = xx[i],
11342
+ y1 = yy[i],
11343
+ x2 = xx[j],
11344
+ y2 = yy[j],
11345
+ p2 = internal.findClosestPointOnSeg(p[0], p[1], x1, y1, x2, y2, 0),
11346
+ dist = geom.distance2D(p2[0], p2[1], p[0], p[1]);
11347
+ if (dist < minDist) {
11348
+ minDist = dist;
11349
+ closest = {
11350
+ i: (i < j ? i : j) + 1, // insertion vertex id
11351
+ displayPoint: p2,
11352
+ distance: dist
11353
+ };
11354
+ }
11355
+ });
11356
+
11357
+ if (closest.distance / ext.getPixelSize() > HOVER_THRESHOLD) {
11358
+ return null;
11359
+ }
11360
+ closest.point = translateDisplayPoint(target, closest.displayPoint);
11361
+ closest.type = 'interpolated';
11362
+ closest.target = target;
11363
+ return closest;
11364
+ }
11365
+
11366
+ function vertexIsEndpoint(info, target) {
11367
+ var vId = info.ids[0];
11368
+ return internal.vertexIsArcStart(vId, target.gui.displayArcs) ||
11369
+ internal.vertexIsArcEnd(vId, target.gui.displayArcs);
11370
+ }
11371
+
11372
+ function clearHoverVertex() {
11373
+ hit.clearHoverVertex();
11374
+ hoverVertexInfo = null;
11375
+ }
11376
+
11377
+ function active() {
11378
+ return _active && gui.interaction.getMode() == 'snip_lines';
11379
+ }
11380
+
11381
+ function turnOff() {
11382
+
11383
+ }
11384
+
11385
+ }
11386
+
11230
11387
  function initInteractiveEditing(gui, ext, hit) {
11231
11388
  initLabelDragging(gui, ext, hit);
11232
11389
  initPointEditing(gui, ext, hit);
11233
11390
  initLineEditing(gui, ext, hit);
11391
+ initSnipTool(gui, ext, hit);
11234
11392
  }
11235
11393
 
11236
11394
  var darkStroke = "#334",
@@ -11567,7 +11725,8 @@
11567
11725
  var ymax = maxAbs(_fullBounds.ymin, _fullBounds.ymax, _fullBounds.centerY());
11568
11726
  var xscale = _fullBounds.width() / _position.width() / xmax / minPixelScale;
11569
11727
  var yscale = _fullBounds.height() / _position.height() / ymax / minPixelScale;
11570
- return Math.min(xscale, yscale);
11728
+ // return Math.min(xscale, yscale);
11729
+ return Math.max(xscale, yscale);
11571
11730
  }
11572
11731
 
11573
11732
  function maxAbs() {
@@ -12169,8 +12328,8 @@
12169
12328
  s = 1;
12170
12329
  if (mapScale < 0.5) {
12171
12330
  s *= Math.pow(mapScale + 0.5, 0.35);
12172
- } else if (mapScale > 100) {
12173
- s *= Math.pow(mapScale - 99, 0.10);
12331
+ } else if (mapScale > 30) {
12332
+ s *= Math.pow(mapScale - 29, 0.065);
12174
12333
  }
12175
12334
  return s;
12176
12335
  }
@@ -13612,7 +13771,11 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13612
13771
  }
13613
13772
  }
13614
13773
 
13615
- return {refresh, show: onUpdate};
13774
+ function isOn() {
13775
+ return !!activeStyle;
13776
+ }
13777
+
13778
+ return {refresh, show: onUpdate, isOn};
13616
13779
  }
13617
13780
 
13618
13781
  function DisplayOptions(gui) {
@@ -13673,6 +13836,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13673
13836
  };
13674
13837
  }
13675
13838
 
13839
+ // import { ProjectOptions } from './gui-project-control';
13840
+
13841
+
13676
13842
  function GuiInstance(container, opts) {
13677
13843
  var gui = new ModeSwitcher();
13678
13844
  opts = utils$1.extend({
@@ -13696,6 +13862,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13696
13862
  gui.contextMenu = new ContextMenu();
13697
13863
  gui.undo = new Undo(gui);
13698
13864
  gui.map = new MshpMap(gui);
13865
+ // gui.project = new ProjectOptions(gui);
13699
13866
 
13700
13867
 
13701
13868
  gui.state = {};