-
Notifications
You must be signed in to change notification settings - Fork 429
/
L.PM.Draw.Cut.js
99 lines (84 loc) · 2.78 KB
/
L.PM.Draw.Cut.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import intersect from '@turf/intersect';
import difference from '@turf/difference';
import Draw from './L.PM.Draw';
Draw.Cut = Draw.Polygon.extend({
initialize(map) {
this._map = map;
this._shape = 'Cut';
this.toolbarButtonName = 'cutPolygon';
},
_cut(layer) {
const all = this._map._layers;
// find all layers that intersect with `layer`, the just drawn cutting layer
const layers = Object.keys(all)
// convert object to array
.map(l => all[l])
// only layers handled by leaflet-geoman
.filter(l => l.pm)
// only polygons
.filter(l => l instanceof L.Polygon)
// exclude the drawn one
.filter(l => l !== layer)
// only layers with intersections
.filter(l => {
try {
return !!intersect(layer.toGeoJSON(15), l.toGeoJSON(15));
} catch (e) {
/* eslint-disable-next-line no-console */
console.error('You cant cut polygons with self-intersections');
return false;
}
});
// loop through all layers that intersect with the drawn (cutting) layer
layers.forEach(l => {
// find layer difference
const diff = difference(l.toGeoJSON(15), layer.toGeoJSON(15));
// the resulting layer after the cut
const resultingLayer = L.geoJSON(diff, l.options).addTo(this._map);
resultingLayer.addTo(this._map);
// give the new layer the original options
resultingLayer.pm.enable(this.options);
resultingLayer.pm.disable();
// fire pm:cut on the cutted layer
l.fire('pm:cut', {
shape: this._shape,
layer: resultingLayer,
originalLayer: l,
});
// fire pm:cut on the map
this._map.fire('pm:cut', {
shape: this._shape,
layer: resultingLayer,
originalLayer: l,
});
// add templayer prop so pm:remove isn't fired
l._pmTempLayer = true;
layer._pmTempLayer = true;
// remove old layer and cutting layer
l.remove();
layer.remove();
if (resultingLayer.getLayers().length === 0) {
this._map.pm.removeLayer({ target: resultingLayer });
}
});
},
_finishShape() {
// if self intersection is not allowed, do not finish the shape!
if (!this.options.allowSelfIntersection) {
this._handleSelfIntersection(false);
if (this._doesSelfIntersect) {
return;
}
}
const coords = this._layer.getLatLngs();
const polygonLayer = L.polygon(coords, this.options.pathOptions);
this._cut(polygonLayer);
// disable drawing
this.disable();
// clean up snapping states
this._cleanupSnapping();
// remove the first vertex from "other snapping layers"
this._otherSnapLayers.splice(this._tempSnapLayerIndex, 1);
delete this._tempSnapLayerIndex;
},
});