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/bin/mapshaper-gui +3 -2
- package/mapshaper.js +1761 -501
- package/package.json +2 -2
- package/www/assets/SourceSans3-VariableFont_wght.ttf +0 -0
- package/www/elements.css +1 -1
- package/www/index.html +45 -51
- package/www/mapshaper-gui.js +186 -19
- package/www/mapshaper.js +1761 -501
- package/www/page.css +21 -23
- package/www/assets/SourceSansPro-Regular.woff +0 -0
- package/www/assets/SourceSansPro-Semibold.woff +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
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",
|
|
Binary file
|
package/www/elements.css
CHANGED
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=""
|
|
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="
|
|
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="
|
|
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"
|
|
175
|
-
<div><span id="save-to-clipboard" style="display: inline-block;"><input type="checkbox"
|
|
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
|
|
188
|
-
<div class=""><label
|
|
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
|
|
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
|
|
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"
|
|
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
|
-
|
|
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
|
|
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"
|
|
318
|
-
<script src="modules.js"
|
|
319
|
-
<script src="mapshaper.js"
|
|
320
|
-
<script src="manifest.js"
|
|
321
|
-
<script src="mapshaper-gui.js"
|
|
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>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -3227,18 +3227,20 @@
|
|
|
3227
3227
|
}
|
|
3228
3228
|
|
|
3229
3229
|
// p1, p2: two points in source data CRS coords.
|
|
3230
|
-
function appendNewPath(lyr,
|
|
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
|
-
|
|
3238
|
-
|
|
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'
|
|
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 (
|
|
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 (
|
|
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 >
|
|
12173
|
-
s *= Math.pow(mapScale -
|
|
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
|
-
|
|
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 = {};
|