Skip to content

Commit 480f490

Browse files
authored
Add new option to disable vertex snapping - snapVertex (#1539) (minor)
* Add new option to disable vertex snapping * Add snapVertex to TypeScript * add missing snap option to default Edit options
1 parent 408b197 commit 480f490

File tree

7 files changed

+179
-46
lines changed

7 files changed

+179
-46
lines changed

cypress/e2e/line.cy.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,47 @@ describe('Draw & Edit Line', () => {
407407

408408
cy.hasVertexMarkers(2);
409409
});
410+
411+
it("doesn't snap to the vertex", () => {
412+
cy.window().then(({ map }) => {
413+
map.pm.setGlobalOptions({ snapVertex: false });
414+
});
415+
416+
// activate polyline drawing
417+
cy.toolbarButton('polyline')
418+
.click()
419+
.closest('.button-container')
420+
.should('have.class', 'active');
421+
422+
// draw a polyline
423+
cy.get(mapSelector).click(90, 250).click(150, 50).click(150, 50);
424+
425+
// activate polyline drawing
426+
cy.toolbarButton('polyline')
427+
.click()
428+
.closest('.button-container')
429+
.should('have.class', 'active');
430+
431+
// draw a polyline
432+
cy.get(mapSelector).click(150, 60).click(250, 50).click(250, 50);
433+
434+
cy.window().then(({ map }) => {
435+
const layer = map.pm.getGeomanDrawLayers()[1];
436+
expect(layer.getLatLngs()[0].lat).to.eq(51.52538802368748);
437+
expect(layer.getLatLngs()[0].lng).to.eq(-0.15050450596240997);
438+
});
439+
440+
cy.toolbarButton('edit').click();
441+
442+
cy.get(mapSelector)
443+
.trigger('mousedown', 150, 60, { which: 1 })
444+
.trigger('mousemove', 150, 55, { which: 1 })
445+
.trigger('mouseup', 150, 55, { which: 1 });
446+
447+
cy.window().then(({ map }) => {
448+
const layer = map.pm.getGeomanDrawLayers()[1];
449+
expect(layer.getLatLngs()[0].lat).to.eq(51.5258877375718);
450+
expect(layer.getLatLngs()[0].lng).to.eq(-0.15026355008465944);
451+
});
452+
});
410453
});

cypress/e2e/polygon.cy.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,4 +1418,51 @@ describe('Draw & Edit Poly', () => {
14181418

14191419
cy.hasVertexMarkers(3);
14201420
});
1421+
1422+
it("doesn't snap to the vertex", () => {
1423+
cy.window().then(({ map }) => {
1424+
map.pm.setGlobalOptions({ snapVertex: false });
1425+
});
1426+
1427+
cy.toolbarButton('polygon')
1428+
.click()
1429+
.closest('.button-container')
1430+
.should('have.class', 'active');
1431+
1432+
cy.get(mapSelector)
1433+
.click(50, 250)
1434+
.click(150, 50)
1435+
.click(250, 50)
1436+
.click(50, 250);
1437+
1438+
cy.toolbarButton('polygon')
1439+
.click()
1440+
.closest('.button-container')
1441+
.should('have.class', 'active');
1442+
1443+
cy.get(mapSelector)
1444+
.click(150, 60)
1445+
.click(250, 90)
1446+
.click(200, 90)
1447+
.click(150, 60);
1448+
1449+
cy.window().then(({ map }) => {
1450+
const layer = map.pm.getGeomanDrawLayers()[1];
1451+
expect(layer.getLatLngs()[0][0].lat).to.eq(51.5255134425896);
1452+
expect(layer.getLatLngs()[0][0].lng).to.eq(-0.15071868896484378);
1453+
});
1454+
1455+
cy.toolbarButton('edit').click();
1456+
1457+
cy.get(mapSelector)
1458+
.trigger('mousedown', 150, 60, { which: 1 })
1459+
.trigger('mousemove', 150, 55, { which: 1 })
1460+
.trigger('mouseup', 150, 55, { which: 1 });
1461+
1462+
cy.window().then(({ map }) => {
1463+
const layer = map.pm.getGeomanDrawLayers()[1];
1464+
expect(layer.getLatLngs()[0][0].lat).to.eq(51.52594064813257);
1465+
expect(layer.getLatLngs()[0][0].lng).to.eq(-0.15037536621093753);
1466+
});
1467+
});
14211468
});

cypress/e2e/rectangle.cy.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,4 +1040,43 @@ describe('Draw Rectangle', () => {
10401040
expect(map.pm.getGeomanDrawLayers().length).to.eql(0);
10411041
});
10421042
});
1043+
1044+
it("doesn't snap to the vertex", () => {
1045+
cy.window().then(({ map }) => {
1046+
map.pm.setGlobalOptions({ snapVertex: false });
1047+
});
1048+
1049+
cy.toolbarButton('rectangle')
1050+
.click()
1051+
.closest('.button-container')
1052+
.should('have.class', 'active');
1053+
1054+
cy.get(mapSelector).click(90, 250).click(150, 50);
1055+
1056+
cy.toolbarButton('rectangle')
1057+
.click()
1058+
.closest('.button-container')
1059+
.should('have.class', 'active');
1060+
1061+
cy.get(mapSelector).click(150, 60).click(250, 90);
1062+
1063+
cy.window().then(({ map }) => {
1064+
const layer = map.pm.getGeomanDrawLayers()[1];
1065+
expect(layer.getLatLngs()[0][1].lat).to.eq(51.52529983831507);
1066+
expect(layer.getLatLngs()[0][1].lng).to.eq(-0.15003204345703128);
1067+
});
1068+
1069+
cy.toolbarButton('edit').click();
1070+
1071+
cy.get(mapSelector)
1072+
.trigger('mousedown', 150, 60, { which: 1 })
1073+
.trigger('mousemove', 150, 55, { which: 1 })
1074+
.trigger('mouseup', 150, 55, { which: 1 });
1075+
1076+
cy.window().then(({ map }) => {
1077+
const layer = map.pm.getGeomanDrawLayers()[1];
1078+
expect(layer.getLatLngs()[0][1].lat).to.eq(51.525833847122584);
1079+
expect(layer.getLatLngs()[0][1].lng).to.eq(-0.13286590576171878);
1080+
});
1081+
});
10431082
});

leaflet-geoman.d.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,12 +1132,7 @@ declare module 'leaflet' {
11321132
event: any;
11331133
}) => boolean;
11341134

1135-
interface EditModeOptions {
1136-
/** Enable snapping to other layers vertices for precision drawing. Can be disabled by holding the ALT key (default:true). */
1137-
snappable?: boolean;
1138-
1139-
/** The distance to another vertex when a snap should happen (default:20). */
1140-
snapDistance?: number;
1135+
interface EditModeOptions extends SnappingOptions {
11411136

11421137
/** Allow self intersections (default:true). */
11431138
allowSelfIntersection?: boolean;
@@ -1229,18 +1224,7 @@ declare module 'leaflet' {
12291224
className?: string;
12301225
}
12311226

1232-
interface DrawModeOptions {
1233-
/** Enable snapping to other layers vertices for precision drawing. Can be disabled by holding the ALT key (default:true). */
1234-
snappable?: boolean;
1235-
1236-
/** The distance to another vertex when a snap should happen (default:20). */
1237-
snapDistance?: number;
1238-
1239-
/** Allow snapping in the middle of two vertices (middleMarker)(default:false). */
1240-
snapMiddle?: boolean;
1241-
1242-
/** Allow snapping between two vertices. (default: true)*/
1243-
snapSegment?: boolean;
1227+
interface DrawModeOptions extends SnappingOptions {
12441228

12451229
/** Require the last point of a shape to be snapped. (default: false). */
12461230
requireSnapToFinish?: boolean;
@@ -1318,6 +1302,23 @@ declare module 'leaflet' {
13181302
textOptions?: TextOptions;
13191303
}
13201304

1305+
interface SnappingOptions {
1306+
/** Enable snapping to other layers vertices for precision drawing. Can be disabled by holding the ALT key (default:true). */
1307+
snappable?: boolean;
1308+
1309+
/** The distance to another vertex when a snap should happen (default:20). */
1310+
snapDistance?: number;
1311+
1312+
/** Allow snapping in the middle of two vertices (middleMarker)(default:false). */
1313+
snapMiddle?: boolean;
1314+
1315+
/** Allow snapping between two vertices. (default: true)*/
1316+
snapSegment?: boolean;
1317+
1318+
/** Allow snapping to vertices. (default: true)*/
1319+
snapVertex?: boolean;
1320+
}
1321+
13211322
/**
13221323
* PM toolbar options.
13231324
*/

src/js/Draw/L.PM.Draw.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ const Draw = L.Class.extend({
3838
text: null,
3939
focusAfterDraw: null,
4040
removeIfEmpty: null,
41-
className: null
41+
className: null,
4242
},
43+
snapVertex: true,
4344
},
4445
setOptions(options) {
4546
L.Util.setOptions(this, options);

src/js/Edit/L.PM.Edit.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const Edit = L.Class.extend({
2828
moveVertexValidation: undefined,
2929
resizeableCircleMarker: false,
3030
resizeableCircle: true,
31+
snapMiddle: false,
32+
snapVertex: true,
3133
},
3234
setOptions(options) {
3335
L.Util.setOptions(this, options);

src/js/Mixins/Snapping.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -490,40 +490,40 @@ const SnapMixin = {
490490
// The closest point on the closest segment of the closest polygon to P. That's right.
491491
const C = closestLayer.latlng;
492492

493-
// distances from A to C and B to C to check which one is closer to C
494-
const distanceAC = this._getDistance(map, A, C);
495-
const distanceBC = this._getDistance(map, B, C);
493+
// the latlng we ultemately want to snap to
494+
let snapLatlng = C;
496495

497-
// closest latlng of A and B to C
498-
let closestVertexLatLng = distanceAC < distanceBC ? A : B;
496+
if (this.options.snapVertex) {
497+
// distances from A to C and B to C to check which one is closer to C
498+
const distanceAC = this._getDistance(map, A, C);
499+
const distanceBC = this._getDistance(map, B, C);
499500

500-
// distance between closestVertexLatLng and C
501-
let shortestDistance = distanceAC < distanceBC ? distanceAC : distanceBC;
501+
// closest latlng of A and B to C
502+
let closestVertexLatLng = distanceAC < distanceBC ? A : B;
502503

503-
// snap to middle (M) of segment if option is enabled
504-
if (this.options.snapMiddle) {
505-
const M = L.PM.Utils.calcMiddleLatLng(map, A, B);
506-
const distanceMC = this._getDistance(map, M, C);
504+
// distance between closestVertexLatLng and C
505+
let shortestDistance = distanceAC < distanceBC ? distanceAC : distanceBC;
507506

508-
if (distanceMC < distanceAC && distanceMC < distanceBC) {
509-
// M is the nearest vertex
510-
closestVertexLatLng = M;
511-
shortestDistance = distanceMC;
512-
}
513-
}
507+
// snap to middle (M) of segment if option is enabled
508+
if (this.options.snapMiddle) {
509+
const M = L.PM.Utils.calcMiddleLatLng(map, A, B);
510+
const distanceMC = this._getDistance(map, M, C);
514511

515-
// the distance that needs to be undercut to trigger priority
516-
const priorityDistance = this.options.snapDistance;
512+
if (distanceMC < distanceAC && distanceMC < distanceBC) {
513+
// M is the nearest vertex
514+
closestVertexLatLng = M;
515+
shortestDistance = distanceMC;
516+
}
517+
}
517518

518-
// the latlng we ultemately want to snap to
519-
let snapLatlng;
519+
// the distance that needs to be undercut to trigger priority
520+
const priorityDistance = this.options.snapDistance;
520521

521-
// if C is closer to the closestVertexLatLng (A, B or M) than the snapDistance,
522-
// the closestVertexLatLng has priority over C as the snapping point.
523-
if (shortestDistance < priorityDistance) {
524-
snapLatlng = closestVertexLatLng;
525-
} else {
526-
snapLatlng = C;
522+
// if C is closer to the closestVertexLatLng (A, B or M) than the snapDistance,
523+
// the closestVertexLatLng has priority over C as the snapping point.
524+
if (shortestDistance < priorityDistance) {
525+
snapLatlng = closestVertexLatLng;
526+
}
527527
}
528528

529529
// return the copy of snapping point

0 commit comments

Comments
 (0)