leaflet-polydraw 0.9.0 → 0.9.2
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/README.md +61 -11
- package/dist/polydraw.es.js +1255 -797
- package/dist/polydraw.es.js.map +1 -1
- package/dist/polydraw.umd.min.js +1 -1
- package/dist/polydraw.umd.min.js.map +1 -1
- package/dist/types/coordinate-utils.d.ts.map +1 -1
- package/dist/types/geometry-utils.d.ts.map +1 -1
- package/dist/types/managers/event-manager.d.ts +76 -4
- package/dist/types/managers/event-manager.d.ts.map +1 -1
- package/dist/types/managers/polygon-draw-manager.d.ts +2 -1
- package/dist/types/managers/polygon-draw-manager.d.ts.map +1 -1
- package/dist/types/managers/polygon-geometry-manager.d.ts +0 -16
- package/dist/types/managers/polygon-geometry-manager.d.ts.map +1 -1
- package/dist/types/managers/polygon-interaction-manager.d.ts +10 -5
- package/dist/types/managers/polygon-interaction-manager.d.ts.map +1 -1
- package/dist/types/managers/polygon-mutation-manager.d.ts +28 -9
- package/dist/types/managers/polygon-mutation-manager.d.ts.map +1 -1
- package/dist/types/map-state.d.ts.map +1 -1
- package/dist/types/polydraw.d.ts +160 -7
- package/dist/types/polydraw.d.ts.map +1 -1
- package/dist/types/styles/dynamic-styles.d.ts +3 -0
- package/dist/types/styles/dynamic-styles.d.ts.map +1 -0
- package/dist/types/turf-helper.d.ts +15 -4
- package/dist/types/turf-helper.d.ts.map +1 -1
- package/dist/types/types/polydraw-interfaces.d.ts +96 -10
- package/dist/types/types/polydraw-interfaces.d.ts.map +1 -1
- package/package.json +9 -3
package/dist/polydraw.es.js
CHANGED
|
@@ -7,18 +7,19 @@ const touchSupport = true;
|
|
|
7
7
|
const mergePolygons = true;
|
|
8
8
|
const kinks$1 = false;
|
|
9
9
|
const modes = { "draw": true, "subtract": true, "deleteAll": true, "p2p": true, "attachElbow": true, "dragElbow": true, "dragPolygons": true, "edgeDeletion": true };
|
|
10
|
-
const dragPolygons = { "realTimeUpdate": false, "showDragHandle": false, "opacity": 0.7, "dragCursor": "move", "hoverCursor": "grab", "markerBehavior": "hide", "markerAnimationDuration": 200, "autoMergeOnIntersect": true, "autoHoleOnContained": false, "dragInteractionBehavior": "auto", "modifierSubtract": { "enabled": true, "keys": { "windows": "ctrlKey", "mac": "metaKey", "linux": "ctrlKey" }, "
|
|
11
|
-
const edgeDeletion = { "enabled": true, "
|
|
12
|
-
const markers = { "deleteMarker": true, "infoMarker": true, "menuMarker": true, "coordsTitle": true, "zIndexOffset": 0, "markerIcon": { "styleClasses": ["polygon-marker"], "zIndexOffset": null }, "holeIcon": { "styleClasses": ["polygon-marker", "hole"], "zIndexOffset": null }, "markerInfoIcon": { "position": 3, "showArea": true, "showPerimeter": true, "useMetrics": true, "usePerimeterMinValue": false, "areaLabel": "Area", "perimeterLabel": "Perimeter", "values": { "min": { "metric": "50", "imperial": "100" }, "unknown": { "metric": "-", "imperial": "-" } }, "units": { "unknownUnit": "", "metric": { "onlyMetrics": true, "perimeter": { "m": "m", "km": "km" }, "area": { "m2": "m²", "km2": "km²", "daa": "daa", "ha": "ha" } }, "imperial": { "perimeter": { "feet": "ft", "yards": "yd", "miles": "mi" }, "area": { "feet2": "ft²", "yards2": "yd²", "acres": "ac", "miles2": "mi²" } } }, "styleClasses": ["polygon-marker", "info"], "zIndexOffset": 1e4 }, "markerMenuIcon": { "position": 7, "styleClasses": ["polygon-marker", "menu"], "zIndexOffset": 1e4 }, "markerDeleteIcon": { "position": 5, "styleClasses": ["polygon-marker", "delete"], "zIndexOffset": 1e4 }, "visualOptimization": { "sharpAngleThreshold": 30, "thresholdBoundingBox": 0.05, "thresholdDistance": 0.05, "useDistance": true, "useBoundingBox": false, "useAngles": false } };
|
|
13
|
-
const polyLineOptions = { "
|
|
14
|
-
const subtractLineOptions = { "
|
|
15
|
-
const polygonOptions = { "smoothFactor": 0.3, "
|
|
16
|
-
const holeOptions = { "
|
|
10
|
+
const dragPolygons = { "realTimeUpdate": false, "showDragHandle": false, "opacity": 0.7, "dragCursor": "move", "hoverCursor": "grab", "markerBehavior": "hide", "markerAnimationDuration": 200, "autoMergeOnIntersect": true, "autoHoleOnContained": false, "dragInteractionBehavior": "auto", "modifierSubtract": { "enabled": true, "keys": { "windows": "ctrlKey", "mac": "metaKey", "linux": "ctrlKey" }, "hideMarkersOnDrag": true } };
|
|
11
|
+
const edgeDeletion = { "enabled": true, "keys": { "windows": "ctrlKey", "mac": "metaKey", "linux": "ctrlKey" }, "confirmDeletion": false, "minVertices": 3 };
|
|
12
|
+
const markers = { "deleteMarker": true, "infoMarker": true, "menuMarker": true, "coordsTitle": true, "zIndexOffset": 0, "markerIcon": { "styleClasses": ["polygon-marker"], "zIndexOffset": null }, "holeIcon": { "styleClasses": ["polygon-marker", "hole"], "zIndexOffset": null }, "markerInfoIcon": { "position": 3, "showArea": true, "showPerimeter": true, "useMetrics": true, "usePerimeterMinValue": false, "areaLabel": "Area", "perimeterLabel": "Perimeter", "values": { "min": { "metric": "50", "imperial": "100" }, "unknown": { "metric": "-", "imperial": "-" } }, "units": { "unknownUnit": "", "metric": { "onlyMetrics": true, "perimeter": { "m": "m", "km": "km" }, "area": { "m2": "m²", "km2": "km²", "daa": "daa", "ha": "ha" } }, "imperial": { "perimeter": { "feet": "ft", "yards": "yd", "miles": "mi" }, "area": { "feet2": "ft²", "yards2": "yd²", "acres": "ac", "miles2": "mi²" } } }, "styleClasses": ["polygon-marker", "info"], "zIndexOffset": 1e4 }, "markerMenuIcon": { "position": 7, "styleClasses": ["polygon-marker", "menu"], "zIndexOffset": 1e4 }, "markerDeleteIcon": { "position": 5, "styleClasses": ["polygon-marker", "delete"], "zIndexOffset": 1e4 }, "holeMarkers": { "menuMarker": false, "deleteMarker": true, "infoMarker": false }, "visualOptimization": { "sharpAngleThreshold": 30, "thresholdBoundingBox": 0.05, "thresholdDistance": 0.05, "useDistance": true, "useBoundingBox": false, "useAngles": false } };
|
|
13
|
+
const polyLineOptions = { "opacity": 1, "smoothFactor": 0, "noClip": true, "clickable": false, "weight": 2 };
|
|
14
|
+
const subtractLineOptions = { "opacity": 1, "smoothFactor": 0, "noClip": true, "clickable": false, "weight": 2 };
|
|
15
|
+
const polygonOptions = { "smoothFactor": 0.3, "noClip": true };
|
|
16
|
+
const holeOptions = { "weight": 2, "opacity": 1, "fillOpacity": 0.5 };
|
|
17
17
|
const polygonCreation = { "method": "concaveman", "simplification": { "mode": "simple", "tolerance": 1e-5, "highQuality": false } };
|
|
18
18
|
const simplification = { "simplifyTolerance": { "tolerance": 1e-4, "highQuality": false, "mutate": false }, "dynamicMode": { "fractionGuard": 0.9, "multipiler": 2 } };
|
|
19
19
|
const menuOperations = { "simplify": { "processHoles": true }, "doubleElbows": { "processHoles": true }, "bbox": { "processHoles": true } };
|
|
20
20
|
const boundingBox = { "addMidPointMarkers": true };
|
|
21
21
|
const bezier$1 = { "resolution": 1e4, "sharpness": 0.75 };
|
|
22
|
+
const colors = { "dragPolygons": { "subtract": "#D9460F" }, "p2p": { "closingMarker": "#4CAF50" }, "edgeHover": "#7a9441", "edgeDeletion": { "hover": "#D9460F" }, "polyline": "#50622b", "subtractLine": "#50622b", "polygon": { "border": "#50622b", "fill": "#b4cd8a" }, "hole": { "border": "#aa0000", "fill": "#ffcccc" }, "styles": { "controlButton": { "backgroundColor": "#fff", "color": "#000" }, "controlButtonHover": { "backgroundColor": "#f4f4f4" }, "controlButtonActive": { "backgroundColor": "rgb(128, 218, 255)", "color": "#fff" }, "indicatorActive": { "backgroundColor": "#ffcc00" }, "p2pMarker": { "backgroundColor": "#fff", "borderColor": "#50622b" } } };
|
|
22
23
|
const defaultConfig = {
|
|
23
24
|
touchSupport,
|
|
24
25
|
mergePolygons,
|
|
@@ -35,7 +36,8 @@ const defaultConfig = {
|
|
|
35
36
|
simplification,
|
|
36
37
|
menuOperations,
|
|
37
38
|
boundingBox,
|
|
38
|
-
bezier: bezier$1
|
|
39
|
+
bezier: bezier$1,
|
|
40
|
+
colors
|
|
39
41
|
};
|
|
40
42
|
var DrawMode = /* @__PURE__ */ ((DrawMode2) => {
|
|
41
43
|
DrawMode2[DrawMode2["Off"] = 0] = "Off";
|
|
@@ -190,7 +192,7 @@ function degreesToRadians(degrees2) {
|
|
|
190
192
|
function isNumber(num) {
|
|
191
193
|
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
192
194
|
}
|
|
193
|
-
function isObject(input) {
|
|
195
|
+
function isObject$1(input) {
|
|
194
196
|
return input !== null && typeof input === "object" && !Array.isArray(input);
|
|
195
197
|
}
|
|
196
198
|
function getCoord(coord) {
|
|
@@ -1498,6 +1500,161 @@ function coordsToLine(coords, properties) {
|
|
|
1498
1500
|
}
|
|
1499
1501
|
return lineString(coords[0], properties);
|
|
1500
1502
|
}
|
|
1503
|
+
var __defProp$1 = Object.defineProperty;
|
|
1504
|
+
var __name = (target, value) => __defProp$1(target, "name", { value, configurable: true });
|
|
1505
|
+
var _GeojsonEquality = class _GeojsonEquality2 {
|
|
1506
|
+
constructor(opts) {
|
|
1507
|
+
this.direction = false;
|
|
1508
|
+
this.compareProperties = true;
|
|
1509
|
+
var _a2, _b2, _c;
|
|
1510
|
+
this.precision = 10 ** -((_a2 = opts == null ? void 0 : opts.precision) != null ? _a2 : 17);
|
|
1511
|
+
this.direction = (_b2 = opts == null ? void 0 : opts.direction) != null ? _b2 : false;
|
|
1512
|
+
this.compareProperties = (_c = opts == null ? void 0 : opts.compareProperties) != null ? _c : true;
|
|
1513
|
+
}
|
|
1514
|
+
compare(g1, g2) {
|
|
1515
|
+
if (g1.type !== g2.type) {
|
|
1516
|
+
return false;
|
|
1517
|
+
}
|
|
1518
|
+
if (!sameLength(g1, g2)) {
|
|
1519
|
+
return false;
|
|
1520
|
+
}
|
|
1521
|
+
switch (g1.type) {
|
|
1522
|
+
case "Point":
|
|
1523
|
+
return this.compareCoord(g1.coordinates, g2.coordinates);
|
|
1524
|
+
case "LineString":
|
|
1525
|
+
return this.compareLine(g1.coordinates, g2.coordinates);
|
|
1526
|
+
case "Polygon":
|
|
1527
|
+
return this.comparePolygon(g1, g2);
|
|
1528
|
+
case "GeometryCollection":
|
|
1529
|
+
return this.compareGeometryCollection(g1, g2);
|
|
1530
|
+
case "Feature":
|
|
1531
|
+
return this.compareFeature(g1, g2);
|
|
1532
|
+
case "FeatureCollection":
|
|
1533
|
+
return this.compareFeatureCollection(g1, g2);
|
|
1534
|
+
default:
|
|
1535
|
+
if (g1.type.startsWith("Multi")) {
|
|
1536
|
+
const g1s = explode$1(g1);
|
|
1537
|
+
const g2s = explode$1(
|
|
1538
|
+
g2
|
|
1539
|
+
);
|
|
1540
|
+
return g1s.every(
|
|
1541
|
+
(g1part) => g2s.some((g2part) => this.compare(g1part, g2part))
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
return false;
|
|
1546
|
+
}
|
|
1547
|
+
compareCoord(c1, c2) {
|
|
1548
|
+
return c1.length === c2.length && c1.every((c, i) => Math.abs(c - c2[i]) < this.precision);
|
|
1549
|
+
}
|
|
1550
|
+
compareLine(path1, path2, ind = 0, isPoly = false) {
|
|
1551
|
+
if (!sameLength(path1, path2)) {
|
|
1552
|
+
return false;
|
|
1553
|
+
}
|
|
1554
|
+
const p1 = path1;
|
|
1555
|
+
let p2 = path2;
|
|
1556
|
+
if (isPoly && !this.compareCoord(p1[0], p2[0])) {
|
|
1557
|
+
const startIndex = this.fixStartIndex(p2, p1);
|
|
1558
|
+
if (!startIndex) {
|
|
1559
|
+
return false;
|
|
1560
|
+
} else {
|
|
1561
|
+
p2 = startIndex;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
const sameDirection = this.compareCoord(p1[ind], p2[ind]);
|
|
1565
|
+
if (this.direction || sameDirection) {
|
|
1566
|
+
return this.comparePath(p1, p2);
|
|
1567
|
+
} else {
|
|
1568
|
+
if (this.compareCoord(p1[ind], p2[p2.length - (1 + ind)])) {
|
|
1569
|
+
return this.comparePath(p1.slice().reverse(), p2);
|
|
1570
|
+
}
|
|
1571
|
+
return false;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
fixStartIndex(sourcePath, targetPath) {
|
|
1575
|
+
let correctPath, ind = -1;
|
|
1576
|
+
for (let i = 0; i < sourcePath.length; i++) {
|
|
1577
|
+
if (this.compareCoord(sourcePath[i], targetPath[0])) {
|
|
1578
|
+
ind = i;
|
|
1579
|
+
break;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
if (ind >= 0) {
|
|
1583
|
+
correctPath = [].concat(
|
|
1584
|
+
sourcePath.slice(ind, sourcePath.length),
|
|
1585
|
+
sourcePath.slice(1, ind + 1)
|
|
1586
|
+
);
|
|
1587
|
+
}
|
|
1588
|
+
return correctPath;
|
|
1589
|
+
}
|
|
1590
|
+
comparePath(p1, p2) {
|
|
1591
|
+
return p1.every((c, i) => this.compareCoord(c, p2[i]));
|
|
1592
|
+
}
|
|
1593
|
+
comparePolygon(g1, g2) {
|
|
1594
|
+
if (this.compareLine(g1.coordinates[0], g2.coordinates[0], 1, true)) {
|
|
1595
|
+
const holes1 = g1.coordinates.slice(1, g1.coordinates.length);
|
|
1596
|
+
const holes2 = g2.coordinates.slice(1, g2.coordinates.length);
|
|
1597
|
+
return holes1.every(
|
|
1598
|
+
(h1) => holes2.some((h2) => this.compareLine(h1, h2, 1, true))
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
return false;
|
|
1602
|
+
}
|
|
1603
|
+
compareGeometryCollection(g1, g2) {
|
|
1604
|
+
return sameLength(g1.geometries, g2.geometries) && this.compareBBox(g1, g2) && g1.geometries.every((g, i) => this.compare(g, g2.geometries[i]));
|
|
1605
|
+
}
|
|
1606
|
+
compareFeature(g1, g2) {
|
|
1607
|
+
return g1.id === g2.id && (this.compareProperties ? equal(g1.properties, g2.properties) : true) && this.compareBBox(g1, g2) && this.compare(g1.geometry, g2.geometry);
|
|
1608
|
+
}
|
|
1609
|
+
compareFeatureCollection(g1, g2) {
|
|
1610
|
+
return sameLength(g1.features, g2.features) && this.compareBBox(g1, g2) && g1.features.every((f, i) => this.compare(f, g2.features[i]));
|
|
1611
|
+
}
|
|
1612
|
+
compareBBox(g1, g2) {
|
|
1613
|
+
return Boolean(!g1.bbox && !g2.bbox) || (g1.bbox && g2.bbox ? this.compareCoord(g1.bbox, g2.bbox) : false);
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
__name(_GeojsonEquality, "GeojsonEquality");
|
|
1617
|
+
var GeojsonEquality = _GeojsonEquality;
|
|
1618
|
+
function sameLength(g1, g2) {
|
|
1619
|
+
return g1.coordinates ? g1.coordinates.length === g2.coordinates.length : g1.length === g2.length;
|
|
1620
|
+
}
|
|
1621
|
+
__name(sameLength, "sameLength");
|
|
1622
|
+
function explode$1(g) {
|
|
1623
|
+
return g.coordinates.map((part) => ({
|
|
1624
|
+
type: g.type.replace("Multi", ""),
|
|
1625
|
+
coordinates: part
|
|
1626
|
+
}));
|
|
1627
|
+
}
|
|
1628
|
+
__name(explode$1, "explode");
|
|
1629
|
+
function geojsonEquality(g1, g2, opts) {
|
|
1630
|
+
const eq = new GeojsonEquality(opts);
|
|
1631
|
+
return eq.compare(g1, g2);
|
|
1632
|
+
}
|
|
1633
|
+
__name(geojsonEquality, "geojsonEquality");
|
|
1634
|
+
function equal(object1, object2) {
|
|
1635
|
+
if (object1 === null && object2 === null) {
|
|
1636
|
+
return true;
|
|
1637
|
+
}
|
|
1638
|
+
if (object1 === null || object2 === null) {
|
|
1639
|
+
return false;
|
|
1640
|
+
}
|
|
1641
|
+
const objKeys1 = Object.keys(object1);
|
|
1642
|
+
const objKeys2 = Object.keys(object2);
|
|
1643
|
+
if (objKeys1.length !== objKeys2.length) return false;
|
|
1644
|
+
for (var key of objKeys1) {
|
|
1645
|
+
const value1 = object1[key];
|
|
1646
|
+
const value2 = object2[key];
|
|
1647
|
+
const isObjects = isObject(value1) && isObject(value2);
|
|
1648
|
+
if (isObjects && !equal(value1, value2) || !isObjects && value1 !== value2) {
|
|
1649
|
+
return false;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
return true;
|
|
1653
|
+
}
|
|
1654
|
+
__name(equal, "equal");
|
|
1655
|
+
var isObject = /* @__PURE__ */ __name((object) => {
|
|
1656
|
+
return object != null && typeof object === "object";
|
|
1657
|
+
}, "isObject");
|
|
1501
1658
|
function cleanCoords(geojson, options = {}) {
|
|
1502
1659
|
var mutate = typeof options === "object" ? options.mutate : options;
|
|
1503
1660
|
if (!geojson) throw new Error("geojson is required");
|
|
@@ -1611,6 +1768,19 @@ function isPointOnLineSegment(start, end, point2) {
|
|
|
1611
1768
|
return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;
|
|
1612
1769
|
else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;
|
|
1613
1770
|
}
|
|
1771
|
+
function booleanEqual(feature1, feature2, options = {}) {
|
|
1772
|
+
let precision2 = options.precision;
|
|
1773
|
+
precision2 = precision2 === void 0 || precision2 === null || isNaN(precision2) ? 6 : precision2;
|
|
1774
|
+
if (typeof precision2 !== "number" || !(precision2 >= 0)) {
|
|
1775
|
+
throw new Error("precision must be a positive number");
|
|
1776
|
+
}
|
|
1777
|
+
const type1 = getGeom(feature1).type;
|
|
1778
|
+
const type2 = getGeom(feature2).type;
|
|
1779
|
+
if (type1 !== type2) return false;
|
|
1780
|
+
return geojsonEquality(cleanCoords(feature1), cleanCoords(feature2), {
|
|
1781
|
+
precision: precision2
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1614
1784
|
function quickselect(arr, k, left, right, compare2) {
|
|
1615
1785
|
quickselectStep(arr, k, left || 0, right || arr.length - 1, compare2 || defaultCompare$1);
|
|
1616
1786
|
}
|
|
@@ -15011,7 +15181,7 @@ function simplify(points, tolerance, highestQuality) {
|
|
|
15011
15181
|
function simplify2(geojson, options = {}) {
|
|
15012
15182
|
var _a2, _b2, _c;
|
|
15013
15183
|
options = options != null ? options : {};
|
|
15014
|
-
if (!isObject(options)) throw new Error("options is invalid");
|
|
15184
|
+
if (!isObject$1(options)) throw new Error("options is invalid");
|
|
15015
15185
|
const tolerance = (_a2 = options.tolerance) != null ? _a2 : 1;
|
|
15016
15186
|
const highQuality = (_b2 = options.highQuality) != null ? _b2 : false;
|
|
15017
15187
|
const mutate = (_c = options.mutate) != null ? _c : false;
|
|
@@ -15878,22 +16048,16 @@ class TurfHelper {
|
|
|
15878
16048
|
} catch (error) {
|
|
15879
16049
|
}
|
|
15880
16050
|
try {
|
|
15881
|
-
const
|
|
15882
|
-
const
|
|
15883
|
-
for (const
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
if (booleanPointInPolygon(point$1, polygon2)) {
|
|
15887
|
-
return true;
|
|
15888
|
-
}
|
|
16051
|
+
const points1 = explode(polygon2);
|
|
16052
|
+
const points2 = explode(latlngs);
|
|
16053
|
+
for (const point2 of points2.features) {
|
|
16054
|
+
if (booleanPointInPolygon(point2, polygon2)) {
|
|
16055
|
+
return true;
|
|
15889
16056
|
}
|
|
15890
16057
|
}
|
|
15891
|
-
for (const
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
if (booleanPointInPolygon(point$1, latlngs)) {
|
|
15895
|
-
return true;
|
|
15896
|
-
}
|
|
16058
|
+
for (const point2 of points1.features) {
|
|
16059
|
+
if (booleanPointInPolygon(point2, latlngs)) {
|
|
16060
|
+
return true;
|
|
15897
16061
|
}
|
|
15898
16062
|
}
|
|
15899
16063
|
} catch (error) {
|
|
@@ -15984,12 +16148,47 @@ class TurfHelper {
|
|
|
15984
16148
|
return true;
|
|
15985
16149
|
}
|
|
15986
16150
|
}
|
|
16151
|
+
/**
|
|
16152
|
+
* Normalize various point-like inputs into a GeoJSON Feature<Point>.
|
|
16153
|
+
* Supports GeoJSON Feature<Point>, Turf Position [lng, lat], and Leaflet LatLngLiteral.
|
|
16154
|
+
*/
|
|
16155
|
+
toPointFeature(point$1) {
|
|
16156
|
+
var _a2, _b2;
|
|
16157
|
+
if ((point$1 == null ? void 0 : point$1.type) === "Feature" && ((_a2 = point$1.geometry) == null ? void 0 : _a2.type) === "Point") {
|
|
16158
|
+
return point$1;
|
|
16159
|
+
}
|
|
16160
|
+
if (Array.isArray(point$1) && point$1.length >= 2 && typeof point$1[0] === "number" && typeof point$1[1] === "number") {
|
|
16161
|
+
return point(point$1);
|
|
16162
|
+
}
|
|
16163
|
+
if (typeof (point$1 == null ? void 0 : point$1.lat) === "number" && typeof (point$1 == null ? void 0 : point$1.lng) === "number") {
|
|
16164
|
+
const p = point$1;
|
|
16165
|
+
return point([p.lng, p.lat]);
|
|
16166
|
+
}
|
|
16167
|
+
if (((_b2 = point$1 == null ? void 0 : point$1.geometry) == null ? void 0 : _b2.coordinates) && Array.isArray(point$1.geometry.coordinates)) {
|
|
16168
|
+
return point(point$1.geometry.coordinates);
|
|
16169
|
+
}
|
|
16170
|
+
throw new Error("Unsupported point format provided to toPointFeature");
|
|
16171
|
+
}
|
|
16172
|
+
/**
|
|
16173
|
+
* Check if a point lies within a polygon.
|
|
16174
|
+
* Accepts Feature<Point>, Turf Position [lng, lat], or Leaflet LatLngLiteral.
|
|
16175
|
+
* This normalization prevents noisy console warnings in tests.
|
|
16176
|
+
*/
|
|
16177
|
+
isPointInsidePolygon(point2, polygon2) {
|
|
16178
|
+
try {
|
|
16179
|
+
const pointFeature = this.toPointFeature(point2);
|
|
16180
|
+
return booleanPointInPolygon(pointFeature, polygon2);
|
|
16181
|
+
} catch (error) {
|
|
16182
|
+
return false;
|
|
16183
|
+
}
|
|
16184
|
+
}
|
|
15987
16185
|
/**
|
|
15988
16186
|
* Checks if two polygons are equal.
|
|
15989
16187
|
* @param polygon1 First polygon.
|
|
15990
16188
|
* @param polygon2 Second polygon.
|
|
15991
16189
|
*/
|
|
15992
16190
|
equalPolygons(polygon1, polygon2) {
|
|
16191
|
+
return booleanEqual(polygon1, polygon2);
|
|
15993
16192
|
}
|
|
15994
16193
|
convertToBoundingBoxPolygon(polygon2) {
|
|
15995
16194
|
const bbox$1 = bbox(polygon2.geometry);
|
|
@@ -16000,37 +16199,31 @@ class TurfHelper {
|
|
|
16000
16199
|
const multi = multiPolygon([poly.geometry.coordinates]);
|
|
16001
16200
|
return multi;
|
|
16002
16201
|
}
|
|
16003
|
-
injectPointToPolygon(polygon2, point2) {
|
|
16202
|
+
injectPointToPolygon(polygon2, point2, ringIndex) {
|
|
16004
16203
|
const newPoly = JSON.parse(JSON.stringify(polygon2));
|
|
16204
|
+
let targetRing;
|
|
16005
16205
|
if (newPoly.geometry.type === "MultiPolygon") {
|
|
16006
|
-
|
|
16007
|
-
let minDistance = Infinity;
|
|
16008
|
-
let insertIndex = 0;
|
|
16009
|
-
for (let i = 0; i < coordinates.length - 1; i++) {
|
|
16010
|
-
const edgeStart = coordinates[i];
|
|
16011
|
-
const edgeEnd = coordinates[i + 1];
|
|
16012
|
-
const distance2 = this.distanceToLineSegment(point2, edgeStart, edgeEnd);
|
|
16013
|
-
if (distance2 < minDistance) {
|
|
16014
|
-
minDistance = distance2;
|
|
16015
|
-
insertIndex = i + 1;
|
|
16016
|
-
}
|
|
16017
|
-
}
|
|
16018
|
-
coordinates.splice(insertIndex, 0, point2);
|
|
16206
|
+
targetRing = newPoly.geometry.coordinates[0][ringIndex];
|
|
16019
16207
|
} else if (newPoly.geometry.type === "Polygon") {
|
|
16020
|
-
|
|
16021
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
|
|
16025
|
-
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
|
|
16030
|
-
|
|
16208
|
+
targetRing = newPoly.geometry.coordinates[ringIndex];
|
|
16209
|
+
} else {
|
|
16210
|
+
return newPoly;
|
|
16211
|
+
}
|
|
16212
|
+
if (!targetRing) {
|
|
16213
|
+
return newPoly;
|
|
16214
|
+
}
|
|
16215
|
+
let minDistance = Infinity;
|
|
16216
|
+
let insertIndex = 0;
|
|
16217
|
+
for (let i = 0; i < targetRing.length - 1; i++) {
|
|
16218
|
+
const edgeStart = targetRing[i];
|
|
16219
|
+
const edgeEnd = targetRing[i + 1];
|
|
16220
|
+
const distance2 = this.distanceToLineSegment(point2, edgeStart, edgeEnd);
|
|
16221
|
+
if (distance2 < minDistance) {
|
|
16222
|
+
minDistance = distance2;
|
|
16223
|
+
insertIndex = i + 1;
|
|
16031
16224
|
}
|
|
16032
|
-
coordinates.splice(insertIndex, 0, point2);
|
|
16033
16225
|
}
|
|
16226
|
+
targetRing.splice(insertIndex, 0, point2);
|
|
16034
16227
|
return newPoly;
|
|
16035
16228
|
}
|
|
16036
16229
|
distanceToLineSegment(point2, lineStart, lineEnd) {
|
|
@@ -17285,11 +17478,10 @@ class EventManager {
|
|
|
17285
17478
|
* @param callback - The callback to execute when the event is emitted.
|
|
17286
17479
|
*/
|
|
17287
17480
|
on(event, callback) {
|
|
17288
|
-
var _a2;
|
|
17289
17481
|
if (!this.eventListeners.has(event)) {
|
|
17290
17482
|
this.eventListeners.set(event, []);
|
|
17291
17483
|
}
|
|
17292
|
-
|
|
17484
|
+
this.eventListeners.get(event).push(callback);
|
|
17293
17485
|
}
|
|
17294
17486
|
/**
|
|
17295
17487
|
* Unregister an event listener.
|
|
@@ -17297,13 +17489,11 @@ class EventManager {
|
|
|
17297
17489
|
* @param callback - The specific callback to remove.
|
|
17298
17490
|
*/
|
|
17299
17491
|
off(event, callback) {
|
|
17300
|
-
|
|
17301
|
-
|
|
17302
|
-
|
|
17303
|
-
|
|
17304
|
-
|
|
17305
|
-
listeners.splice(index, 1);
|
|
17306
|
-
}
|
|
17492
|
+
const listeners = this.eventListeners.get(event);
|
|
17493
|
+
if (listeners) {
|
|
17494
|
+
const index = listeners.indexOf(callback);
|
|
17495
|
+
if (index > -1) {
|
|
17496
|
+
listeners.splice(index, 1);
|
|
17307
17497
|
}
|
|
17308
17498
|
}
|
|
17309
17499
|
}
|
|
@@ -17315,7 +17505,9 @@ class EventManager {
|
|
|
17315
17505
|
emit(event, data) {
|
|
17316
17506
|
var _a2;
|
|
17317
17507
|
if (this.eventListeners.has(event)) {
|
|
17318
|
-
(_a2 = this.eventListeners.get(event)) == null ? void 0 : _a2.forEach((callback) =>
|
|
17508
|
+
(_a2 = this.eventListeners.get(event)) == null ? void 0 : _a2.forEach((callback) => {
|
|
17509
|
+
callback(data);
|
|
17510
|
+
});
|
|
17319
17511
|
}
|
|
17320
17512
|
}
|
|
17321
17513
|
}
|
|
@@ -17514,7 +17706,7 @@ class PolygonDrawManager {
|
|
|
17514
17706
|
// Point-to-Point drawing state
|
|
17515
17707
|
__publicField(this, "p2pMarkers", []);
|
|
17516
17708
|
__publicField(this, "isModifierKeyHeld", false);
|
|
17517
|
-
|
|
17709
|
+
__publicField(this, "markerModifierHandlers", /* @__PURE__ */ new WeakMap());
|
|
17518
17710
|
this.turfHelper = dependencies.turfHelper;
|
|
17519
17711
|
this.map = dependencies.map;
|
|
17520
17712
|
this.config = dependencies.config;
|
|
@@ -17526,7 +17718,6 @@ class PolygonDrawManager {
|
|
|
17526
17718
|
* Handle mouse move during freehand drawing
|
|
17527
17719
|
*/
|
|
17528
17720
|
mouseMove(event) {
|
|
17529
|
-
console.log("mouseMove");
|
|
17530
17721
|
if ("latlng" in event && event.latlng) {
|
|
17531
17722
|
this.tracer.addLatLng(event.latlng);
|
|
17532
17723
|
} else if ("touches" in event && event.touches && event.touches.length > 0) {
|
|
@@ -17541,12 +17732,11 @@ class PolygonDrawManager {
|
|
|
17541
17732
|
* Handle mouse up/leave to complete freehand drawing
|
|
17542
17733
|
*/
|
|
17543
17734
|
async mouseUpLeave(event) {
|
|
17544
|
-
console.log("mouseUpLeave");
|
|
17545
17735
|
const tracerGeoJSON = this.tracer.toGeoJSON();
|
|
17546
17736
|
if (!tracerGeoJSON || !tracerGeoJSON.geometry || !tracerGeoJSON.geometry.coordinates || tracerGeoJSON.geometry.coordinates.length < 3) {
|
|
17547
17737
|
return {
|
|
17548
17738
|
success: false,
|
|
17549
|
-
error: "Not enough points to form a valid polygon"
|
|
17739
|
+
error: "Not enough points to form a valid polygon. Event: " + JSON.stringify(event)
|
|
17550
17740
|
};
|
|
17551
17741
|
}
|
|
17552
17742
|
let geoPos;
|
|
@@ -17555,13 +17745,13 @@ class PolygonDrawManager {
|
|
|
17555
17745
|
} catch (error) {
|
|
17556
17746
|
return {
|
|
17557
17747
|
success: false,
|
|
17558
|
-
error: error instanceof Error ? error.message : "Failed to create polygon from trace"
|
|
17748
|
+
error: (error instanceof Error ? error.message : "Failed to create polygon from trace") + ". Event: " + JSON.stringify(event)
|
|
17559
17749
|
};
|
|
17560
17750
|
}
|
|
17561
17751
|
if (!geoPos || !geoPos.geometry || !geoPos.geometry.coordinates || geoPos.geometry.coordinates.length === 0) {
|
|
17562
17752
|
return {
|
|
17563
17753
|
success: false,
|
|
17564
|
-
error: "Invalid polygon created from trace"
|
|
17754
|
+
error: "Invalid polygon created from trace. Event: " + JSON.stringify(event)
|
|
17565
17755
|
};
|
|
17566
17756
|
}
|
|
17567
17757
|
this.eventManager.emit("polydraw:polygon:created", {
|
|
@@ -17587,7 +17777,6 @@ class PolygonDrawManager {
|
|
|
17587
17777
|
* Handle point-to-point click
|
|
17588
17778
|
*/
|
|
17589
17779
|
handlePointToPointClick(clickLatLng) {
|
|
17590
|
-
console.log("handlePointToPointClick");
|
|
17591
17780
|
if (!clickLatLng) {
|
|
17592
17781
|
return;
|
|
17593
17782
|
}
|
|
@@ -17616,7 +17805,6 @@ class PolygonDrawManager {
|
|
|
17616
17805
|
this.updateP2PTracer();
|
|
17617
17806
|
});
|
|
17618
17807
|
pointMarker.on("click", (e) => {
|
|
17619
|
-
console.log("p2p marker click");
|
|
17620
17808
|
if (this.isModifierKeyHeld && this.config.modes.edgeDeletion) {
|
|
17621
17809
|
this.deleteP2PMarker(pointMarker);
|
|
17622
17810
|
L.DomEvent.stopPropagation(e);
|
|
@@ -17629,8 +17817,8 @@ class PolygonDrawManager {
|
|
|
17629
17817
|
if (this.p2pMarkers.length >= 3) {
|
|
17630
17818
|
const element = pointMarker.getElement();
|
|
17631
17819
|
if (element) {
|
|
17632
|
-
element.style.backgroundColor =
|
|
17633
|
-
element.style.borderColor =
|
|
17820
|
+
element.style.backgroundColor = this.config.colors.p2p.closingMarker;
|
|
17821
|
+
element.style.borderColor = this.config.colors.p2p.closingMarker;
|
|
17634
17822
|
element.style.cursor = "pointer";
|
|
17635
17823
|
element.title = "Click to close polygon";
|
|
17636
17824
|
}
|
|
@@ -17646,7 +17834,6 @@ class PolygonDrawManager {
|
|
|
17646
17834
|
}
|
|
17647
17835
|
});
|
|
17648
17836
|
pointMarker.on("click", (e) => {
|
|
17649
|
-
console.log("p2p first marker click");
|
|
17650
17837
|
if (this.isModifierKeyHeld && this.config.modes.edgeDeletion) {
|
|
17651
17838
|
this.deleteP2PMarker(pointMarker);
|
|
17652
17839
|
L.DomEvent.stopPropagation(e);
|
|
@@ -17667,7 +17854,6 @@ class PolygonDrawManager {
|
|
|
17667
17854
|
* Handle double-click to complete point-to-point polygon
|
|
17668
17855
|
*/
|
|
17669
17856
|
handleDoubleClick(e) {
|
|
17670
|
-
console.log("handleDoubleClick");
|
|
17671
17857
|
if (this.modeManager.getCurrentMode() !== DrawMode.PointToPoint) {
|
|
17672
17858
|
return;
|
|
17673
17859
|
}
|
|
@@ -17679,7 +17865,6 @@ class PolygonDrawManager {
|
|
|
17679
17865
|
* Complete point-to-point polygon drawing
|
|
17680
17866
|
*/
|
|
17681
17867
|
completePointToPointPolygon() {
|
|
17682
|
-
console.log("PolygonDrawManager completePointToPointPolygon");
|
|
17683
17868
|
const points = this.p2pMarkers.map((marker) => marker.getLatLng());
|
|
17684
17869
|
if (points.length < 3) {
|
|
17685
17870
|
return;
|
|
@@ -17710,7 +17895,6 @@ class PolygonDrawManager {
|
|
|
17710
17895
|
* Cancel point-to-point drawing
|
|
17711
17896
|
*/
|
|
17712
17897
|
cancelPointToPointDrawing() {
|
|
17713
|
-
console.log("PolygonDrawManager cancelPointToPointDrawing");
|
|
17714
17898
|
this.clearP2pMarkers();
|
|
17715
17899
|
this.resetTracer();
|
|
17716
17900
|
this.eventManager.emit("polydraw:draw:cancel", {
|
|
@@ -17721,7 +17905,6 @@ class PolygonDrawManager {
|
|
|
17721
17905
|
* Clear all P2P markers
|
|
17722
17906
|
*/
|
|
17723
17907
|
clearP2pMarkers() {
|
|
17724
|
-
console.log("PolygonDrawManager clearP2pMarkers");
|
|
17725
17908
|
this.p2pMarkers.forEach((marker) => this.map.removeLayer(marker));
|
|
17726
17909
|
this.p2pMarkers = [];
|
|
17727
17910
|
}
|
|
@@ -17729,7 +17912,6 @@ class PolygonDrawManager {
|
|
|
17729
17912
|
* Reset the tracer
|
|
17730
17913
|
*/
|
|
17731
17914
|
resetTracer() {
|
|
17732
|
-
console.log("PolygonDrawManager resetTracer");
|
|
17733
17915
|
this.tracer.setLatLngs([]);
|
|
17734
17916
|
try {
|
|
17735
17917
|
this.tracer.setStyle({
|
|
@@ -17742,7 +17924,6 @@ class PolygonDrawManager {
|
|
|
17742
17924
|
* Check if clicking on the first point to close polygon
|
|
17743
17925
|
*/
|
|
17744
17926
|
isClickingFirstPoint(clickLatLng, firstPoint) {
|
|
17745
|
-
console.log("PolygonDrawManager isClickingFirstPoint");
|
|
17746
17927
|
if (!firstPoint) return false;
|
|
17747
17928
|
const zoom = this.map.getZoom();
|
|
17748
17929
|
const baseTolerance = 5e-4;
|
|
@@ -17761,7 +17942,7 @@ class PolygonDrawManager {
|
|
|
17761
17942
|
if (this.p2pMarkers.length >= 2) {
|
|
17762
17943
|
try {
|
|
17763
17944
|
this.tracer.setStyle({
|
|
17764
|
-
color: this.config.
|
|
17945
|
+
color: this.config.colors.polyline,
|
|
17765
17946
|
dashArray: "5, 5"
|
|
17766
17947
|
});
|
|
17767
17948
|
} catch (error) {
|
|
@@ -17793,21 +17974,18 @@ class PolygonDrawManager {
|
|
|
17793
17974
|
* Get current P2P markers (for external access)
|
|
17794
17975
|
*/
|
|
17795
17976
|
getP2pMarkers() {
|
|
17796
|
-
console.log("PolygonDrawManager getP2pMarkers");
|
|
17797
17977
|
return [...this.p2pMarkers];
|
|
17798
17978
|
}
|
|
17799
17979
|
/**
|
|
17800
17980
|
* Check if currently in point-to-point drawing mode
|
|
17801
17981
|
*/
|
|
17802
17982
|
isInPointToPointMode() {
|
|
17803
|
-
console.log("PolygonDrawManager isInPointToPointMode");
|
|
17804
17983
|
return this.modeManager.getCurrentMode() === DrawMode.PointToPoint;
|
|
17805
17984
|
}
|
|
17806
17985
|
/**
|
|
17807
17986
|
* Get current tracer points count
|
|
17808
17987
|
*/
|
|
17809
17988
|
getTracerPointsCount() {
|
|
17810
|
-
console.log("PolygonDrawManager getTracerPointsCount");
|
|
17811
17989
|
const points = this.tracer.getLatLngs();
|
|
17812
17990
|
return points.length;
|
|
17813
17991
|
}
|
|
@@ -17834,8 +18012,8 @@ class PolygonDrawManager {
|
|
|
17834
18012
|
if (this.p2pMarkers.length >= 3) {
|
|
17835
18013
|
const element2 = firstMarker.getElement();
|
|
17836
18014
|
if (element2) {
|
|
17837
|
-
element2.style.backgroundColor =
|
|
17838
|
-
element2.style.borderColor =
|
|
18015
|
+
element2.style.backgroundColor = this.config.colors.p2p.closingMarker;
|
|
18016
|
+
element2.style.borderColor = this.config.colors.p2p.closingMarker;
|
|
17839
18017
|
element2.style.cursor = "pointer";
|
|
17840
18018
|
element2.title = "Click to close polygon";
|
|
17841
18019
|
}
|
|
@@ -17886,7 +18064,7 @@ class PolygonDrawManager {
|
|
|
17886
18064
|
}
|
|
17887
18065
|
}
|
|
17888
18066
|
};
|
|
17889
|
-
marker
|
|
18067
|
+
this.markerModifierHandlers.set(marker, checkModifierAndUpdate);
|
|
17890
18068
|
document.addEventListener("keydown", checkModifierAndUpdate);
|
|
17891
18069
|
document.addEventListener("keyup", checkModifierAndUpdate);
|
|
17892
18070
|
element.addEventListener("mousemove", checkModifierAndUpdate);
|
|
@@ -17897,12 +18075,12 @@ class PolygonDrawManager {
|
|
|
17897
18075
|
container.style.cursor = "";
|
|
17898
18076
|
} catch (error) {
|
|
17899
18077
|
}
|
|
17900
|
-
const handler = marker
|
|
18078
|
+
const handler = this.markerModifierHandlers.get(marker);
|
|
17901
18079
|
if (handler) {
|
|
17902
18080
|
document.removeEventListener("keydown", handler);
|
|
17903
18081
|
document.removeEventListener("keyup", handler);
|
|
17904
18082
|
element.removeEventListener("mousemove", handler);
|
|
17905
|
-
delete
|
|
18083
|
+
this.markerModifierHandlers.delete(marker);
|
|
17906
18084
|
}
|
|
17907
18085
|
}
|
|
17908
18086
|
}
|
|
@@ -17953,7 +18131,7 @@ class PolygonGeometryManager {
|
|
|
17953
18131
|
geometry: { type: "Point", coordinates: coord },
|
|
17954
18132
|
properties: {}
|
|
17955
18133
|
};
|
|
17956
|
-
if (this.turfHelper.
|
|
18134
|
+
if (this.turfHelper.isPointInsidePolygon(point2, polygon1)) {
|
|
17957
18135
|
return true;
|
|
17958
18136
|
}
|
|
17959
18137
|
}
|
|
@@ -17965,7 +18143,7 @@ class PolygonGeometryManager {
|
|
|
17965
18143
|
geometry: { type: "Point", coordinates: coord },
|
|
17966
18144
|
properties: {}
|
|
17967
18145
|
};
|
|
17968
|
-
if (this.turfHelper.
|
|
18146
|
+
if (this.turfHelper.isPointInsidePolygon(point2, polygon2)) {
|
|
17969
18147
|
return true;
|
|
17970
18148
|
}
|
|
17971
18149
|
}
|
|
@@ -17981,19 +18159,8 @@ class PolygonGeometryManager {
|
|
|
17981
18159
|
try {
|
|
17982
18160
|
let result = newPolygon;
|
|
17983
18161
|
for (const polygon2 of polygons) {
|
|
17984
|
-
const
|
|
17985
|
-
|
|
17986
|
-
const donutPolygon = this.createDonutPolygon(result, polygon2);
|
|
17987
|
-
if (donutPolygon) {
|
|
17988
|
-
result = donutPolygon;
|
|
17989
|
-
} else {
|
|
17990
|
-
const union3 = this.turfHelper.union(result, polygon2);
|
|
17991
|
-
result = union3;
|
|
17992
|
-
}
|
|
17993
|
-
} else {
|
|
17994
|
-
const union3 = this.turfHelper.union(result, polygon2);
|
|
17995
|
-
result = union3;
|
|
17996
|
-
}
|
|
18162
|
+
const union3 = this.turfHelper.union(result, polygon2);
|
|
18163
|
+
result = union3;
|
|
17997
18164
|
}
|
|
17998
18165
|
return {
|
|
17999
18166
|
success: true,
|
|
@@ -18304,93 +18471,6 @@ class PolygonGeometryManager {
|
|
|
18304
18471
|
return null;
|
|
18305
18472
|
}
|
|
18306
18473
|
}
|
|
18307
|
-
/**
|
|
18308
|
-
* Determine if two polygons should create a donut instead of a regular union
|
|
18309
|
-
*/
|
|
18310
|
-
shouldCreateDonutPolygon(polygon1, polygon2) {
|
|
18311
|
-
try {
|
|
18312
|
-
return false;
|
|
18313
|
-
} catch (error) {
|
|
18314
|
-
console.warn("Error in shouldCreateDonutPolygon:", error.message);
|
|
18315
|
-
return false;
|
|
18316
|
-
}
|
|
18317
|
-
}
|
|
18318
|
-
/**
|
|
18319
|
-
* Create a donut polygon from two intersecting polygons
|
|
18320
|
-
*/
|
|
18321
|
-
createDonutPolygon(polygon1, polygon2) {
|
|
18322
|
-
try {
|
|
18323
|
-
const area1 = this.turfHelper.getPolygonArea(polygon1);
|
|
18324
|
-
const area2 = this.turfHelper.getPolygonArea(polygon2);
|
|
18325
|
-
let outerPolygon;
|
|
18326
|
-
let innerPolygon;
|
|
18327
|
-
if (area1 > area2) {
|
|
18328
|
-
outerPolygon = polygon1;
|
|
18329
|
-
innerPolygon = polygon2;
|
|
18330
|
-
} else {
|
|
18331
|
-
outerPolygon = polygon2;
|
|
18332
|
-
innerPolygon = polygon1;
|
|
18333
|
-
}
|
|
18334
|
-
const innerWithinOuter = this.turfHelper.isPolygonCompletelyWithin(
|
|
18335
|
-
innerPolygon,
|
|
18336
|
-
outerPolygon
|
|
18337
|
-
);
|
|
18338
|
-
if (innerWithinOuter) {
|
|
18339
|
-
return this.createDonutFromContainment(outerPolygon, innerPolygon);
|
|
18340
|
-
} else {
|
|
18341
|
-
return this.createDonutFromIntersection(outerPolygon, innerPolygon);
|
|
18342
|
-
}
|
|
18343
|
-
} catch (error) {
|
|
18344
|
-
console.warn("Error in createDonutPolygon:", error.message);
|
|
18345
|
-
return null;
|
|
18346
|
-
}
|
|
18347
|
-
}
|
|
18348
|
-
/**
|
|
18349
|
-
* Create donut when one polygon is completely within another
|
|
18350
|
-
*/
|
|
18351
|
-
createDonutFromContainment(outerPolygon, innerPolygon) {
|
|
18352
|
-
try {
|
|
18353
|
-
const outerCoords = this.turfHelper.getCoords(outerPolygon);
|
|
18354
|
-
const innerCoords = this.turfHelper.getCoords(innerPolygon);
|
|
18355
|
-
const donutCoords = [
|
|
18356
|
-
outerCoords[0][0],
|
|
18357
|
-
// Outer ring
|
|
18358
|
-
innerCoords[0][0]
|
|
18359
|
-
// Inner ring as hole
|
|
18360
|
-
];
|
|
18361
|
-
return {
|
|
18362
|
-
type: "Feature",
|
|
18363
|
-
geometry: {
|
|
18364
|
-
type: "Polygon",
|
|
18365
|
-
coordinates: donutCoords
|
|
18366
|
-
},
|
|
18367
|
-
properties: {}
|
|
18368
|
-
};
|
|
18369
|
-
} catch (error) {
|
|
18370
|
-
console.warn("Error in createDonutFromContainment:", error.message);
|
|
18371
|
-
return null;
|
|
18372
|
-
}
|
|
18373
|
-
}
|
|
18374
|
-
/**
|
|
18375
|
-
* Create donut from intersecting polygons (C-to-O scenario)
|
|
18376
|
-
*/
|
|
18377
|
-
createDonutFromIntersection(polygon1, polygon2) {
|
|
18378
|
-
try {
|
|
18379
|
-
const union3 = this.turfHelper.union(polygon1, polygon2);
|
|
18380
|
-
if (!union3) {
|
|
18381
|
-
return null;
|
|
18382
|
-
}
|
|
18383
|
-
const intersection3 = this.turfHelper.getIntersection(polygon1, polygon2);
|
|
18384
|
-
if (!intersection3) {
|
|
18385
|
-
return union3;
|
|
18386
|
-
}
|
|
18387
|
-
const donut = this.turfHelper.polygonDifference(union3, intersection3);
|
|
18388
|
-
return donut;
|
|
18389
|
-
} catch (error) {
|
|
18390
|
-
console.warn("Error in createDonutFromIntersection:", error.message);
|
|
18391
|
-
return null;
|
|
18392
|
-
}
|
|
18393
|
-
}
|
|
18394
18474
|
}
|
|
18395
18475
|
class IconFactory {
|
|
18396
18476
|
/**
|
|
@@ -18405,6 +18485,8 @@ class IconFactory {
|
|
|
18405
18485
|
}
|
|
18406
18486
|
class PolygonInteractionManager {
|
|
18407
18487
|
constructor(dependencies, featureGroupAccess) {
|
|
18488
|
+
__publicField(this, "markerFeatureGroupMap", /* @__PURE__ */ new WeakMap());
|
|
18489
|
+
__publicField(this, "markerModifierHandlers", /* @__PURE__ */ new WeakMap());
|
|
18408
18490
|
__publicField(this, "_activeMarker", null);
|
|
18409
18491
|
__publicField(this, "isDraggingMarker", false);
|
|
18410
18492
|
__publicField(this, "turfHelper");
|
|
@@ -18424,12 +18506,11 @@ class PolygonInteractionManager {
|
|
|
18424
18506
|
__publicField(this, "removeFeatureGroup");
|
|
18425
18507
|
// Polygon dragging methods
|
|
18426
18508
|
__publicField(this, "onPolygonMouseMove", (e) => {
|
|
18427
|
-
console.log("PolygonInteractionManager onPolygonMouseMove");
|
|
18428
18509
|
if (!this.currentDragPolygon || !this.currentDragPolygon._polydrawDragData.isDragging) return;
|
|
18429
18510
|
const polygon2 = this.currentDragPolygon;
|
|
18430
18511
|
const dragData = polygon2._polydrawDragData;
|
|
18431
18512
|
const eventToCheck = e.originalEvent && "metaKey" in e.originalEvent ? e.originalEvent : e;
|
|
18432
|
-
const currentModifierState = this.
|
|
18513
|
+
const currentModifierState = this.detectDragSubtractModifierKey(eventToCheck);
|
|
18433
18514
|
if (currentModifierState !== this.currentModifierDragMode) {
|
|
18434
18515
|
this.handleModifierToggleDuringDrag(eventToCheck);
|
|
18435
18516
|
}
|
|
@@ -18442,7 +18523,6 @@ class PolygonInteractionManager {
|
|
|
18442
18523
|
this.updateMarkersAndHoleLinesDuringDrag(polygon2, offsetLat, offsetLng);
|
|
18443
18524
|
});
|
|
18444
18525
|
__publicField(this, "onPolygonMouseUp", (e) => {
|
|
18445
|
-
console.log("PolygonInteractionManager onPolygonMouseUp");
|
|
18446
18526
|
if (!this.currentDragPolygon || !this.currentDragPolygon._polydrawDragData.isDragging) return;
|
|
18447
18527
|
const polygon2 = this.currentDragPolygon;
|
|
18448
18528
|
const dragData = polygon2._polydrawDragData;
|
|
@@ -18472,17 +18552,15 @@ class PolygonInteractionManager {
|
|
|
18472
18552
|
this.currentDragPolygon = null;
|
|
18473
18553
|
});
|
|
18474
18554
|
__publicField(this, "onMarkerHoverForEdgeDeletionEvent", (e) => {
|
|
18475
|
-
console.log("PolygonInteractionManager onMarkerHoverForEdgeDeletionEvent");
|
|
18476
18555
|
if (!this.isModifierKeyHeld) return;
|
|
18477
18556
|
const element = e.target;
|
|
18478
18557
|
if (element) {
|
|
18479
|
-
element.style.backgroundColor =
|
|
18480
|
-
element.style.borderColor =
|
|
18558
|
+
element.style.backgroundColor = this.config.colors.edgeDeletion.hover;
|
|
18559
|
+
element.style.borderColor = this.config.colors.edgeDeletion.hover;
|
|
18481
18560
|
element.classList.add("edge-deletion-hover");
|
|
18482
18561
|
}
|
|
18483
18562
|
});
|
|
18484
18563
|
__publicField(this, "onMarkerLeaveForEdgeDeletionEvent", (e) => {
|
|
18485
|
-
console.log("PolygonInteractionManager onMarkerLeaveForEdgeDeletionEvent");
|
|
18486
18564
|
const element = e.target;
|
|
18487
18565
|
if (element) {
|
|
18488
18566
|
element.style.backgroundColor = "";
|
|
@@ -18490,7 +18568,6 @@ class PolygonInteractionManager {
|
|
|
18490
18568
|
element.classList.remove("edge-deletion-hover");
|
|
18491
18569
|
}
|
|
18492
18570
|
});
|
|
18493
|
-
console.log("PolygonInteractionManager constructor");
|
|
18494
18571
|
this.turfHelper = dependencies.turfHelper;
|
|
18495
18572
|
this.polygonInformation = dependencies.polygonInformation;
|
|
18496
18573
|
this.map = dependencies.map;
|
|
@@ -18505,7 +18582,6 @@ class PolygonInteractionManager {
|
|
|
18505
18582
|
* Add markers to a polygon feature group
|
|
18506
18583
|
*/
|
|
18507
18584
|
addMarkers(latlngs, featureGroup) {
|
|
18508
|
-
console.log("PolygonInteractionManager addMarkers");
|
|
18509
18585
|
let menuMarkerIdx = this.getMarkerIndex(latlngs, this.config.markers.markerMenuIcon.position);
|
|
18510
18586
|
let deleteMarkerIdx = this.getMarkerIndex(
|
|
18511
18587
|
latlngs,
|
|
@@ -18540,7 +18616,7 @@ class PolygonInteractionManager {
|
|
|
18540
18616
|
zIndexOffset: this.config.markers.markerIcon.zIndexOffset ?? this.config.markers.zIndexOffset
|
|
18541
18617
|
});
|
|
18542
18618
|
featureGroup.addLayer(marker).addTo(this.map);
|
|
18543
|
-
marker
|
|
18619
|
+
this.markerFeatureGroupMap.set(marker, featureGroup);
|
|
18544
18620
|
marker.on("add", () => {
|
|
18545
18621
|
const el2 = marker.getElement();
|
|
18546
18622
|
if (el2) el2.style.pointerEvents = "auto";
|
|
@@ -18557,7 +18633,7 @@ class PolygonInteractionManager {
|
|
|
18557
18633
|
this._activeMarker = marker;
|
|
18558
18634
|
});
|
|
18559
18635
|
marker.on("dragend", (e) => {
|
|
18560
|
-
const fg = marker
|
|
18636
|
+
const fg = this.markerFeatureGroupMap.get(marker);
|
|
18561
18637
|
if (this.modeManager.canPerformAction("markerDrag") && fg) {
|
|
18562
18638
|
this.markerDragEnd(fg);
|
|
18563
18639
|
}
|
|
@@ -18569,17 +18645,19 @@ class PolygonInteractionManager {
|
|
|
18569
18645
|
});
|
|
18570
18646
|
const el = marker.getElement();
|
|
18571
18647
|
if (el) {
|
|
18572
|
-
el.addEventListener(
|
|
18573
|
-
|
|
18574
|
-
e
|
|
18575
|
-
|
|
18648
|
+
el.addEventListener(
|
|
18649
|
+
"touchstart",
|
|
18650
|
+
(e) => {
|
|
18651
|
+
e.stopPropagation();
|
|
18652
|
+
},
|
|
18653
|
+
{ passive: true }
|
|
18654
|
+
);
|
|
18576
18655
|
el.addEventListener("touchend", (e) => {
|
|
18577
|
-
console.log("marker touchend");
|
|
18578
18656
|
e.preventDefault();
|
|
18579
18657
|
e.stopPropagation();
|
|
18580
18658
|
marker.fire("click");
|
|
18581
18659
|
if (this.isDraggingMarker && !isSpecialMarker) {
|
|
18582
|
-
const fg = marker
|
|
18660
|
+
const fg = this.markerFeatureGroupMap.get(marker);
|
|
18583
18661
|
if (this.modeManager.canPerformAction("markerDrag") && fg) {
|
|
18584
18662
|
this.markerDragEnd(fg);
|
|
18585
18663
|
}
|
|
@@ -18604,7 +18682,6 @@ class PolygonInteractionManager {
|
|
|
18604
18682
|
if (i === menuMarkerIdx && this.config.markers.menuMarker) {
|
|
18605
18683
|
marker.options.zIndexOffset = this.config.markers.markerMenuIcon.zIndexOffset ?? this.config.markers.zIndexOffset;
|
|
18606
18684
|
marker.on("click", () => {
|
|
18607
|
-
console.log("menu marker clicked");
|
|
18608
18685
|
const polygonGeoJSON = this.getPolygonGeoJSONFromFeatureGroup(featureGroup);
|
|
18609
18686
|
const centerOfMass2 = PolygonUtil.getCenterOfMass(polygonGeoJSON);
|
|
18610
18687
|
const menuPopup = this.generateMenuMarkerPopup(latlngs, featureGroup);
|
|
@@ -18624,14 +18701,12 @@ class PolygonInteractionManager {
|
|
|
18624
18701
|
popupContent.style.transform = `translateX(${mapBounds.right - popupBounds.right}px)`;
|
|
18625
18702
|
}
|
|
18626
18703
|
}, 0);
|
|
18627
|
-
console.log("popupopen, setting touchAction to manipulation");
|
|
18628
18704
|
const container2 = this.map.getContainer();
|
|
18629
18705
|
if (container2) {
|
|
18630
18706
|
container2.style.touchAction = "manipulation";
|
|
18631
18707
|
}
|
|
18632
18708
|
});
|
|
18633
18709
|
marker.on("popupclose", () => {
|
|
18634
|
-
console.log("popupclose, resetting touchAction");
|
|
18635
18710
|
const container2 = this.map.getContainer();
|
|
18636
18711
|
if (container2) {
|
|
18637
18712
|
container2.style.touchAction = "";
|
|
@@ -18644,7 +18719,6 @@ class PolygonInteractionManager {
|
|
|
18644
18719
|
const perimeter = this.getTotalPolygonPerimeter(polygonGeoJSON);
|
|
18645
18720
|
marker.options.zIndexOffset = this.config.markers.markerInfoIcon.zIndexOffset ?? this.config.markers.zIndexOffset;
|
|
18646
18721
|
marker.on("click", () => {
|
|
18647
|
-
console.log("info marker clicked");
|
|
18648
18722
|
const infoPopup = this.generateInfoMarkerPopup(area2, perimeter);
|
|
18649
18723
|
const centerOfMass2 = PolygonUtil.getCenterOfMass(polygonGeoJSON);
|
|
18650
18724
|
infoPopup.setLatLng(centerOfMass2).openOn(this.map);
|
|
@@ -18663,14 +18737,12 @@ class PolygonInteractionManager {
|
|
|
18663
18737
|
popupContent.style.transform = `translateX(${mapBounds.right - popupBounds.right}px)`;
|
|
18664
18738
|
}
|
|
18665
18739
|
}, 0);
|
|
18666
|
-
console.log("popupopen, setting touchAction to manipulation");
|
|
18667
18740
|
const container2 = this.map.getContainer();
|
|
18668
18741
|
if (container2) {
|
|
18669
18742
|
container2.style.touchAction = "manipulation";
|
|
18670
18743
|
}
|
|
18671
18744
|
});
|
|
18672
18745
|
marker.on("popupclose", () => {
|
|
18673
|
-
console.log("popupclose, resetting touchAction");
|
|
18674
18746
|
const container2 = this.map.getContainer();
|
|
18675
18747
|
if (container2) {
|
|
18676
18748
|
container2.style.touchAction = "";
|
|
@@ -18685,13 +18757,11 @@ class PolygonInteractionManager {
|
|
|
18685
18757
|
this._activeMarker = marker;
|
|
18686
18758
|
});
|
|
18687
18759
|
marker.on("click", (e) => {
|
|
18688
|
-
var _a2;
|
|
18689
|
-
console.log("marker click");
|
|
18690
18760
|
if (this.modeManager.isInOffMode()) {
|
|
18691
|
-
if (this.
|
|
18692
|
-
const
|
|
18693
|
-
if (
|
|
18694
|
-
this.elbowClicked(e,
|
|
18761
|
+
if (this.isEdgeDeletionModifierKeyPressed(e.originalEvent)) {
|
|
18762
|
+
const polygonLayer = featureGroup.getLayers().find((layer) => layer instanceof L.Polygon);
|
|
18763
|
+
if (polygonLayer) {
|
|
18764
|
+
this.elbowClicked(e, polygonLayer, marker.getLatLng());
|
|
18695
18765
|
}
|
|
18696
18766
|
} else {
|
|
18697
18767
|
if (i === deleteMarkerIdx && this.config.markers.deleteMarker) {
|
|
@@ -18712,91 +18782,292 @@ class PolygonInteractionManager {
|
|
|
18712
18782
|
}
|
|
18713
18783
|
}
|
|
18714
18784
|
/**
|
|
18715
|
-
* Add hole markers to a polygon feature group
|
|
18785
|
+
* Add hole markers to a polygon feature group, with configurable special markers.
|
|
18716
18786
|
*/
|
|
18717
18787
|
addHoleMarkers(latlngs, featureGroup) {
|
|
18718
|
-
|
|
18788
|
+
var _a2, _b2, _c;
|
|
18789
|
+
const holeMenuEnabled = ((_a2 = this.config.markers.holeMarkers) == null ? void 0 : _a2.menuMarker) ?? false;
|
|
18790
|
+
const holeDeleteEnabled = ((_b2 = this.config.markers.holeMarkers) == null ? void 0 : _b2.deleteMarker) ?? false;
|
|
18791
|
+
const holeInfoEnabled = ((_c = this.config.markers.holeMarkers) == null ? void 0 : _c.infoMarker) ?? false;
|
|
18792
|
+
let menuMarkerIdx = this.getMarkerIndex(latlngs, this.config.markers.markerMenuIcon.position);
|
|
18793
|
+
let deleteMarkerIdx = this.getMarkerIndex(
|
|
18794
|
+
latlngs,
|
|
18795
|
+
this.config.markers.markerDeleteIcon.position
|
|
18796
|
+
);
|
|
18797
|
+
let infoMarkerIdx = this.getMarkerIndex(latlngs, this.config.markers.markerInfoIcon.position);
|
|
18798
|
+
const separatedIndices = this.ensureMarkerSeparation(latlngs.length, {
|
|
18799
|
+
menu: { index: menuMarkerIdx, enabled: holeMenuEnabled },
|
|
18800
|
+
delete: { index: deleteMarkerIdx, enabled: holeDeleteEnabled },
|
|
18801
|
+
info: { index: infoMarkerIdx, enabled: holeInfoEnabled }
|
|
18802
|
+
});
|
|
18803
|
+
menuMarkerIdx = separatedIndices.menu;
|
|
18804
|
+
deleteMarkerIdx = separatedIndices.delete;
|
|
18805
|
+
infoMarkerIdx = separatedIndices.info;
|
|
18719
18806
|
latlngs.forEach((latlng, i) => {
|
|
18720
|
-
|
|
18807
|
+
let iconClasses = this.config.markers.holeIcon.styleClasses;
|
|
18808
|
+
if (i === menuMarkerIdx && holeMenuEnabled) {
|
|
18809
|
+
iconClasses = this.config.markers.markerMenuIcon.styleClasses;
|
|
18810
|
+
}
|
|
18811
|
+
if (i === deleteMarkerIdx && holeDeleteEnabled) {
|
|
18812
|
+
iconClasses = this.config.markers.markerDeleteIcon.styleClasses;
|
|
18813
|
+
}
|
|
18814
|
+
if (i === infoMarkerIdx && holeInfoEnabled) {
|
|
18815
|
+
iconClasses = this.config.markers.markerInfoIcon.styleClasses;
|
|
18816
|
+
}
|
|
18721
18817
|
const processedClasses = Array.isArray(iconClasses) ? iconClasses : [iconClasses];
|
|
18818
|
+
const isSpecialMarker = i === menuMarkerIdx && holeMenuEnabled || i === deleteMarkerIdx && holeDeleteEnabled || i === infoMarkerIdx && holeInfoEnabled;
|
|
18722
18819
|
const marker = new L.Marker(latlng, {
|
|
18723
18820
|
icon: this.createDivIcon(processedClasses),
|
|
18724
|
-
draggable:
|
|
18725
|
-
title: this.getLatLngInfoString(latlng),
|
|
18821
|
+
draggable: this.config.modes.dragElbow,
|
|
18822
|
+
title: this.config.markers.coordsTitle ? this.getLatLngInfoString(latlng) : "",
|
|
18726
18823
|
zIndexOffset: this.config.markers.holeIcon.zIndexOffset ?? this.config.markers.zIndexOffset
|
|
18727
18824
|
});
|
|
18728
18825
|
featureGroup.addLayer(marker).addTo(this.map);
|
|
18826
|
+
this.markerFeatureGroupMap.set(marker, featureGroup);
|
|
18729
18827
|
marker.on("add", () => {
|
|
18730
|
-
const
|
|
18731
|
-
if (
|
|
18828
|
+
const el2 = marker.getElement();
|
|
18829
|
+
if (el2) el2.style.pointerEvents = "auto";
|
|
18732
18830
|
});
|
|
18733
18831
|
marker.on("click", (e) => {
|
|
18734
|
-
var
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
L.DomEvent.stopPropagation(e);
|
|
18832
|
+
var _a3, _b3;
|
|
18833
|
+
if (this.isDraggingMarker) {
|
|
18834
|
+
(_b3 = (_a3 = e.originalEvent) == null ? void 0 : _a3.stopPropagation) == null ? void 0 : _b3.call(_a3);
|
|
18835
|
+
L.DomEvent.stopPropagation(e);
|
|
18836
|
+
}
|
|
18740
18837
|
});
|
|
18741
|
-
marker.on("
|
|
18742
|
-
this.
|
|
18838
|
+
marker.on("dragstart", () => {
|
|
18839
|
+
this.isDraggingMarker = true;
|
|
18840
|
+
this._activeMarker = marker;
|
|
18743
18841
|
});
|
|
18744
18842
|
marker.on("dragend", (e) => {
|
|
18745
|
-
this.
|
|
18843
|
+
const fg = this.markerFeatureGroupMap.get(marker);
|
|
18844
|
+
if (this.modeManager.canPerformAction("markerDrag") && fg) {
|
|
18845
|
+
this.markerDragEnd(fg);
|
|
18846
|
+
}
|
|
18847
|
+
this._activeMarker = null;
|
|
18848
|
+
L.DomEvent.stopPropagation(e);
|
|
18849
|
+
setTimeout(() => {
|
|
18850
|
+
this.isDraggingMarker = false;
|
|
18851
|
+
}, 10);
|
|
18746
18852
|
});
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
if (
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18853
|
+
const el = marker.getElement();
|
|
18854
|
+
if (el) {
|
|
18855
|
+
el.addEventListener(
|
|
18856
|
+
"touchstart",
|
|
18857
|
+
(e) => {
|
|
18858
|
+
e.stopPropagation();
|
|
18859
|
+
},
|
|
18860
|
+
{ passive: true }
|
|
18861
|
+
);
|
|
18862
|
+
el.addEventListener("touchend", (e) => {
|
|
18863
|
+
e.preventDefault();
|
|
18864
|
+
e.stopPropagation();
|
|
18865
|
+
marker.fire("click");
|
|
18866
|
+
if (this.isDraggingMarker && !isSpecialMarker) {
|
|
18867
|
+
const fg = this.markerFeatureGroupMap.get(marker);
|
|
18868
|
+
if (this.modeManager.canPerformAction("markerDrag") && fg) {
|
|
18869
|
+
this.markerDragEnd(fg);
|
|
18870
|
+
}
|
|
18764
18871
|
}
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
} else {
|
|
18768
|
-
processedRings = rawLatLngs[0];
|
|
18769
|
-
}
|
|
18770
|
-
} else if (rawLatLngs[0] && typeof rawLatLngs[0] === "object" && "lat" in rawLatLngs[0]) {
|
|
18771
|
-
processedRings = [rawLatLngs];
|
|
18772
|
-
} else {
|
|
18773
|
-
processedRings = [rawLatLngs];
|
|
18872
|
+
this._activeMarker = null;
|
|
18873
|
+
});
|
|
18774
18874
|
}
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
for (let i = 0; i < ring.length; i++) {
|
|
18780
|
-
const edgeStart = ring[i];
|
|
18781
|
-
const edgeEnd = ring[(i + 1) % ring.length];
|
|
18782
|
-
if (edgeStart.lat === edgeEnd.lat && edgeStart.lng === edgeEnd.lng) {
|
|
18783
|
-
continue;
|
|
18875
|
+
if (i === menuMarkerIdx || i === deleteMarkerIdx || i === infoMarkerIdx) {
|
|
18876
|
+
const element = marker.getElement();
|
|
18877
|
+
if (element) {
|
|
18878
|
+
element.style.zIndex = "10000";
|
|
18784
18879
|
}
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
18880
|
+
}
|
|
18881
|
+
if (this.config.modes.dragElbow) {
|
|
18882
|
+
const createDragHandler = (fg) => () => {
|
|
18883
|
+
if (this.modeManager.canPerformAction("markerDrag")) {
|
|
18884
|
+
this.markerDrag(fg);
|
|
18885
|
+
}
|
|
18886
|
+
};
|
|
18887
|
+
marker.on("drag", createDragHandler(featureGroup));
|
|
18888
|
+
}
|
|
18889
|
+
if (i === menuMarkerIdx && holeMenuEnabled) {
|
|
18890
|
+
marker.options.zIndexOffset = this.config.markers.markerMenuIcon.zIndexOffset ?? this.config.markers.zIndexOffset;
|
|
18891
|
+
marker.on("click", () => {
|
|
18892
|
+
const ring = latlngs.map((pt) => [pt.lng, pt.lat]);
|
|
18893
|
+
ring.push(ring[0]);
|
|
18894
|
+
const holePolygon = {
|
|
18895
|
+
type: "Feature",
|
|
18896
|
+
properties: {},
|
|
18897
|
+
geometry: {
|
|
18898
|
+
type: "Polygon",
|
|
18899
|
+
coordinates: [ring]
|
|
18900
|
+
}
|
|
18901
|
+
};
|
|
18902
|
+
const centerOfMass2 = PolygonUtil.getCenterOfMass(holePolygon);
|
|
18903
|
+
const menuPopup = this.generateMenuMarkerPopup(latlngs, featureGroup);
|
|
18904
|
+
menuPopup.setLatLng(centerOfMass2).openOn(this.map);
|
|
18905
|
+
});
|
|
18906
|
+
marker.on("popupopen", (e) => {
|
|
18907
|
+
const popup = e.popup;
|
|
18908
|
+
const popupContent = popup.getElement();
|
|
18909
|
+
if (!popupContent) return;
|
|
18910
|
+
setTimeout(() => {
|
|
18911
|
+
const mapContainer = this.map.getContainer();
|
|
18912
|
+
const mapBounds = mapContainer.getBoundingClientRect();
|
|
18913
|
+
const popupBounds = popupContent.getBoundingClientRect();
|
|
18914
|
+
if (popupBounds.left < mapBounds.left) {
|
|
18915
|
+
popupContent.style.transform = `translateX(${mapBounds.left - popupBounds.left}px)`;
|
|
18916
|
+
} else if (popupBounds.right > mapBounds.right) {
|
|
18917
|
+
popupContent.style.transform = `translateX(${mapBounds.right - popupBounds.right}px)`;
|
|
18918
|
+
}
|
|
18919
|
+
}, 0);
|
|
18920
|
+
const container = this.map.getContainer();
|
|
18921
|
+
if (container) {
|
|
18922
|
+
container.style.touchAction = "manipulation";
|
|
18923
|
+
}
|
|
18924
|
+
});
|
|
18925
|
+
marker.on("popupclose", () => {
|
|
18926
|
+
const container = this.map.getContainer();
|
|
18927
|
+
if (container) {
|
|
18928
|
+
container.style.touchAction = "";
|
|
18929
|
+
}
|
|
18930
|
+
});
|
|
18931
|
+
}
|
|
18932
|
+
if (i === infoMarkerIdx && holeInfoEnabled) {
|
|
18933
|
+
const ring = latlngs.map((latlng2) => [latlng2.lng, latlng2.lat]);
|
|
18934
|
+
ring.push(ring[0]);
|
|
18935
|
+
const holePolygon = {
|
|
18936
|
+
type: "Feature",
|
|
18937
|
+
properties: {},
|
|
18938
|
+
geometry: {
|
|
18939
|
+
type: "Polygon",
|
|
18940
|
+
coordinates: [ring]
|
|
18941
|
+
}
|
|
18942
|
+
};
|
|
18943
|
+
const area2 = this.turfHelper.getPolygonArea(holePolygon);
|
|
18944
|
+
const perimeter = this.turfHelper.getPolygonPerimeter(holePolygon) * 1e3;
|
|
18945
|
+
marker.options.zIndexOffset = this.config.markers.markerInfoIcon.zIndexOffset ?? this.config.markers.zIndexOffset;
|
|
18946
|
+
marker.on("click", () => {
|
|
18947
|
+
const infoPopup = this.generateInfoMarkerPopup(area2, perimeter);
|
|
18948
|
+
infoPopup.setLatLng(latlng).openOn(this.map);
|
|
18949
|
+
});
|
|
18950
|
+
}
|
|
18951
|
+
marker.on("mousedown", (e) => {
|
|
18952
|
+
if (!this.modeManager.isInOffMode()) {
|
|
18953
|
+
L.DomEvent.stopPropagation(e);
|
|
18954
|
+
this.map.fire("mousedown", e);
|
|
18955
|
+
}
|
|
18956
|
+
this._activeMarker = marker;
|
|
18957
|
+
});
|
|
18958
|
+
marker.on("click", (e) => {
|
|
18959
|
+
if (this.modeManager.isInOffMode()) {
|
|
18960
|
+
if (this.isEdgeDeletionModifierKeyPressed(e.originalEvent)) {
|
|
18961
|
+
const polygonLayer = featureGroup.getLayers().find((layer) => layer instanceof L.Polygon);
|
|
18962
|
+
if (polygonLayer) {
|
|
18963
|
+
this.elbowClicked(e, polygonLayer, marker.getLatLng());
|
|
18964
|
+
}
|
|
18965
|
+
} else {
|
|
18966
|
+
if (i === deleteMarkerIdx && holeDeleteEnabled) {
|
|
18967
|
+
this.map.closePopup();
|
|
18968
|
+
const parentPolygon = featureGroup.getLayers().find((layer) => layer instanceof L.Polygon);
|
|
18969
|
+
if (parentPolygon) {
|
|
18970
|
+
const rawLatLngs = parentPolygon.getLatLngs();
|
|
18971
|
+
let rings = [];
|
|
18972
|
+
if (Array.isArray(rawLatLngs) && rawLatLngs.length > 0) {
|
|
18973
|
+
if (Array.isArray(rawLatLngs[0])) {
|
|
18974
|
+
const first = rawLatLngs[0];
|
|
18975
|
+
if (Array.isArray(first) && Array.isArray(first[0])) {
|
|
18976
|
+
rings = rawLatLngs[0];
|
|
18977
|
+
} else {
|
|
18978
|
+
rings = rawLatLngs;
|
|
18979
|
+
}
|
|
18980
|
+
} else {
|
|
18981
|
+
rings = [rawLatLngs];
|
|
18982
|
+
}
|
|
18983
|
+
}
|
|
18984
|
+
const target = marker.getLatLng();
|
|
18985
|
+
let holeIndex = -1;
|
|
18986
|
+
for (let r = 1; r < rings.length; r++) {
|
|
18987
|
+
if (rings[r].some((p) => p.lat === target.lat && p.lng === target.lng)) {
|
|
18988
|
+
holeIndex = r;
|
|
18989
|
+
break;
|
|
18990
|
+
}
|
|
18991
|
+
}
|
|
18992
|
+
if (holeIndex > 0) {
|
|
18993
|
+
const newRings = rings.filter((_, idx) => idx !== holeIndex);
|
|
18994
|
+
const coords = newRings.map((ring) => {
|
|
18995
|
+
const arr = ring.map((ll) => [ll.lng, ll.lat]);
|
|
18996
|
+
if (arr.length > 0) {
|
|
18997
|
+
const firstPt = arr[0];
|
|
18998
|
+
const lastPt = arr[arr.length - 1];
|
|
18999
|
+
if (firstPt[0] !== lastPt[0] || firstPt[1] !== lastPt[1]) {
|
|
19000
|
+
arr.push([firstPt[0], firstPt[1]]);
|
|
19001
|
+
}
|
|
19002
|
+
}
|
|
19003
|
+
return arr;
|
|
19004
|
+
});
|
|
19005
|
+
const newPolygon = this.turfHelper.getMultiPolygon([coords]);
|
|
19006
|
+
this.removeFeatureGroup(featureGroup);
|
|
19007
|
+
this.eventManager.emit("polydraw:polygon:updated", {
|
|
19008
|
+
operation: "removeHole",
|
|
19009
|
+
polygon: newPolygon
|
|
19010
|
+
});
|
|
19011
|
+
}
|
|
19012
|
+
}
|
|
19013
|
+
}
|
|
19014
|
+
}
|
|
19015
|
+
}
|
|
19016
|
+
});
|
|
19017
|
+
marker.on("mouseover", () => this.onMarkerHoverForEdgeDeletion(marker, true));
|
|
19018
|
+
marker.on("mouseout", () => this.onMarkerHoverForEdgeDeletion(marker, false));
|
|
19019
|
+
});
|
|
19020
|
+
}
|
|
19021
|
+
/**
|
|
19022
|
+
* Add edge click listeners to a polygon
|
|
19023
|
+
*/
|
|
19024
|
+
addEdgeClickListeners(polygon2, featureGroup) {
|
|
19025
|
+
const rawLatLngs = polygon2.getLatLngs();
|
|
19026
|
+
let processedRings;
|
|
19027
|
+
if (Array.isArray(rawLatLngs) && rawLatLngs.length > 0) {
|
|
19028
|
+
if (Array.isArray(rawLatLngs[0])) {
|
|
19029
|
+
if (Array.isArray(rawLatLngs[0][0]) && rawLatLngs[0][0].length > 0) {
|
|
19030
|
+
const firstCoord = rawLatLngs[0][0][0];
|
|
19031
|
+
if (firstCoord && typeof firstCoord === "object" && "lat" in firstCoord) {
|
|
19032
|
+
processedRings = rawLatLngs[0];
|
|
19033
|
+
} else {
|
|
19034
|
+
processedRings = rawLatLngs[0];
|
|
19035
|
+
}
|
|
19036
|
+
} else if (rawLatLngs[0][0] && typeof rawLatLngs[0][0] === "object" && "lat" in rawLatLngs[0][0]) {
|
|
19037
|
+
processedRings = rawLatLngs;
|
|
19038
|
+
} else {
|
|
19039
|
+
processedRings = rawLatLngs[0];
|
|
19040
|
+
}
|
|
19041
|
+
} else if (rawLatLngs[0] && typeof rawLatLngs[0] === "object" && "lat" in rawLatLngs[0]) {
|
|
19042
|
+
processedRings = [rawLatLngs];
|
|
19043
|
+
} else {
|
|
19044
|
+
processedRings = [rawLatLngs];
|
|
19045
|
+
}
|
|
19046
|
+
} else {
|
|
19047
|
+
return;
|
|
19048
|
+
}
|
|
19049
|
+
processedRings.forEach((ring, ringIndex) => {
|
|
19050
|
+
for (let i = 0; i < ring.length; i++) {
|
|
19051
|
+
const edgeStart = ring[i];
|
|
19052
|
+
const edgeEnd = ring[(i + 1) % ring.length];
|
|
19053
|
+
if (edgeStart.lat === edgeEnd.lat && edgeStart.lng === edgeEnd.lng) {
|
|
19054
|
+
continue;
|
|
19055
|
+
}
|
|
19056
|
+
const edgePolyline = L.polyline([edgeStart, edgeEnd], {
|
|
19057
|
+
color: "transparent",
|
|
19058
|
+
weight: 10,
|
|
19059
|
+
opacity: 0,
|
|
19060
|
+
interactive: true
|
|
19061
|
+
});
|
|
19062
|
+
edgePolyline._polydrawEdgeInfo = {
|
|
19063
|
+
ringIndex,
|
|
19064
|
+
edgeIndex: i,
|
|
19065
|
+
startPoint: edgeStart,
|
|
19066
|
+
endPoint: edgeEnd,
|
|
19067
|
+
parentPolygon: polygon2,
|
|
19068
|
+
parentFeatureGroup: featureGroup
|
|
19069
|
+
};
|
|
19070
|
+
edgePolyline.on("click", (e) => {
|
|
18800
19071
|
this.onEdgeClick(e, edgePolyline);
|
|
18801
19072
|
});
|
|
18802
19073
|
edgePolyline.on("mouseover", () => {
|
|
@@ -18813,7 +19084,6 @@ class PolygonInteractionManager {
|
|
|
18813
19084
|
* Enable polygon dragging functionality
|
|
18814
19085
|
*/
|
|
18815
19086
|
enablePolygonDragging(polygon2, latlngs) {
|
|
18816
|
-
console.log("PolygonInteractionManager enablePolygonDragging");
|
|
18817
19087
|
if (!this.config.modes.dragPolygons) return;
|
|
18818
19088
|
polygon2._polydrawOriginalLatLngs = latlngs;
|
|
18819
19089
|
polygon2._polydrawDragData = {
|
|
@@ -18822,7 +19092,6 @@ class PolygonInteractionManager {
|
|
|
18822
19092
|
startLatLngs: null
|
|
18823
19093
|
};
|
|
18824
19094
|
polygon2.on("mousedown", (e) => {
|
|
18825
|
-
console.log("polygon mousedown");
|
|
18826
19095
|
if (!this.modeManager.isInOffMode()) {
|
|
18827
19096
|
L.DomEvent.stopPropagation(e);
|
|
18828
19097
|
this.map.fire("mousedown", e);
|
|
@@ -18831,9 +19100,9 @@ class PolygonInteractionManager {
|
|
|
18831
19100
|
if (!this.modeManager.canPerformAction("polygonDrag")) {
|
|
18832
19101
|
return;
|
|
18833
19102
|
}
|
|
18834
|
-
L.DomEvent.stopPropagation(e);
|
|
18835
|
-
L.DomEvent.preventDefault(e);
|
|
18836
|
-
const isModifierPressed = this.
|
|
19103
|
+
L.DomEvent.stopPropagation(e.originalEvent);
|
|
19104
|
+
L.DomEvent.preventDefault(e.originalEvent);
|
|
19105
|
+
const isModifierPressed = this.detectDragSubtractModifierKey(e.originalEvent);
|
|
18837
19106
|
this.currentModifierDragMode = isModifierPressed;
|
|
18838
19107
|
this.isModifierKeyHeld = isModifierPressed;
|
|
18839
19108
|
polygon2._polydrawDragData.isDragging = true;
|
|
@@ -18875,7 +19144,6 @@ class PolygonInteractionManager {
|
|
|
18875
19144
|
* Update marker draggable state based on current mode
|
|
18876
19145
|
*/
|
|
18877
19146
|
updateMarkerDraggableState() {
|
|
18878
|
-
console.log("PolygonInteractionManager updateMarkerDraggableState");
|
|
18879
19147
|
const shouldBeDraggable = this.modeManager.canPerformAction("markerDrag");
|
|
18880
19148
|
this.getFeatureGroups().forEach((featureGroup) => {
|
|
18881
19149
|
featureGroup.eachLayer((layer) => {
|
|
@@ -18900,7 +19168,6 @@ class PolygonInteractionManager {
|
|
|
18900
19168
|
* Update all markers for edge deletion visual feedback
|
|
18901
19169
|
*/
|
|
18902
19170
|
updateAllMarkersForEdgeDeletion(showFeedback) {
|
|
18903
|
-
console.log("PolygonInteractionManager updateAllMarkersForEdgeDeletion");
|
|
18904
19171
|
this.getFeatureGroups().forEach((featureGroup) => {
|
|
18905
19172
|
featureGroup.eachLayer((layer) => {
|
|
18906
19173
|
if (layer instanceof L.Marker) {
|
|
@@ -18913,7 +19180,6 @@ class PolygonInteractionManager {
|
|
|
18913
19180
|
* Update individual marker for edge deletion visual feedback
|
|
18914
19181
|
*/
|
|
18915
19182
|
updateMarkerForEdgeDeletion(marker, showFeedback) {
|
|
18916
|
-
console.log("PolygonInteractionManager updateMarkerForEdgeDeletion");
|
|
18917
19183
|
const element = marker.getElement();
|
|
18918
19184
|
if (!element) return;
|
|
18919
19185
|
if (showFeedback) {
|
|
@@ -18930,12 +19196,10 @@ class PolygonInteractionManager {
|
|
|
18930
19196
|
* Set modifier key held state
|
|
18931
19197
|
*/
|
|
18932
19198
|
setModifierKeyHeld(isHeld) {
|
|
18933
|
-
console.log("PolygonInteractionManager setModifierKeyHeld");
|
|
18934
19199
|
this.isModifierKeyHeld = isHeld;
|
|
18935
19200
|
}
|
|
18936
19201
|
// Private methods
|
|
18937
19202
|
onEdgeClick(e, edgePolyline) {
|
|
18938
|
-
console.log("onEdgeClick");
|
|
18939
19203
|
if (!this.config.modes.attachElbow) {
|
|
18940
19204
|
return;
|
|
18941
19205
|
}
|
|
@@ -18954,10 +19218,11 @@ class PolygonInteractionManager {
|
|
|
18954
19218
|
}
|
|
18955
19219
|
const poly = parentPolygon.toGeoJSON();
|
|
18956
19220
|
if (poly.geometry.type === "MultiPolygon" || poly.geometry.type === "Polygon") {
|
|
18957
|
-
const newPolygon = this.turfHelper.injectPointToPolygon(
|
|
18958
|
-
|
|
18959
|
-
newPoint.lat
|
|
18960
|
-
|
|
19221
|
+
const newPolygon = this.turfHelper.injectPointToPolygon(
|
|
19222
|
+
poly,
|
|
19223
|
+
[newPoint.lng, newPoint.lat],
|
|
19224
|
+
edgeInfo.ringIndex
|
|
19225
|
+
);
|
|
18961
19226
|
if (newPolygon) {
|
|
18962
19227
|
const polydrawPolygon = parentPolygon;
|
|
18963
19228
|
const optimizationLevel = polydrawPolygon._polydrawOptimizationLevel || 0;
|
|
@@ -18975,10 +19240,9 @@ class PolygonInteractionManager {
|
|
|
18975
19240
|
L.DomEvent.stopPropagation(e);
|
|
18976
19241
|
}
|
|
18977
19242
|
highlightEdgeOnHover(edgePolyline, isHovering) {
|
|
18978
|
-
console.log("PolygonInteractionManager highlightEdgeOnHover");
|
|
18979
19243
|
if (isHovering) {
|
|
18980
19244
|
edgePolyline.setStyle({
|
|
18981
|
-
color:
|
|
19245
|
+
color: this.config.colors.edgeHover,
|
|
18982
19246
|
weight: 4,
|
|
18983
19247
|
opacity: 1
|
|
18984
19248
|
});
|
|
@@ -18990,62 +19254,90 @@ class PolygonInteractionManager {
|
|
|
18990
19254
|
});
|
|
18991
19255
|
}
|
|
18992
19256
|
}
|
|
18993
|
-
elbowClicked(e,
|
|
18994
|
-
|
|
18995
|
-
if (!this.
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
19257
|
+
elbowClicked(e, polygonLayer, forcedLatLng) {
|
|
19258
|
+
if (!this.config.modes.edgeDeletion) return;
|
|
19259
|
+
if (!this.isEdgeDeletionModifierKeyPressed(e.originalEvent)) return;
|
|
19260
|
+
const clickedLatLng = forcedLatLng ?? e.latlng;
|
|
19261
|
+
const rawLatLngs = polygonLayer.getLatLngs();
|
|
19262
|
+
let rings = [];
|
|
19263
|
+
if (Array.isArray(rawLatLngs) && rawLatLngs.length > 0) {
|
|
19264
|
+
if (Array.isArray(rawLatLngs[0])) {
|
|
19265
|
+
const first = rawLatLngs[0];
|
|
19266
|
+
if (Array.isArray(first) && Array.isArray(first[0])) {
|
|
19267
|
+
rings = rawLatLngs[0];
|
|
19268
|
+
} else {
|
|
19269
|
+
rings = rawLatLngs;
|
|
19270
|
+
}
|
|
19271
|
+
} else {
|
|
19272
|
+
rings = [rawLatLngs];
|
|
19273
|
+
}
|
|
19274
|
+
} else {
|
|
18999
19275
|
return;
|
|
19000
19276
|
}
|
|
19001
|
-
const clickedLatLng = e.latlng;
|
|
19002
|
-
const allRings = poly.geometry.coordinates[0];
|
|
19003
19277
|
let targetRingIndex = -1;
|
|
19004
19278
|
let targetVertexIndex = -1;
|
|
19005
|
-
for (let
|
|
19006
|
-
const ring =
|
|
19007
|
-
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
|
|
19279
|
+
for (let r = 0; r < rings.length; r++) {
|
|
19280
|
+
const ring = rings[r];
|
|
19281
|
+
for (let v = 0; v < ring.length; v++) {
|
|
19282
|
+
const p = ring[v];
|
|
19283
|
+
if (p.lat === clickedLatLng.lat && p.lng === clickedLatLng.lng) {
|
|
19284
|
+
targetRingIndex = r;
|
|
19285
|
+
targetVertexIndex = v;
|
|
19286
|
+
break;
|
|
19287
|
+
}
|
|
19014
19288
|
}
|
|
19289
|
+
if (targetRingIndex !== -1) break;
|
|
19015
19290
|
}
|
|
19016
19291
|
if (targetRingIndex === -1 || targetVertexIndex === -1) {
|
|
19017
19292
|
return;
|
|
19018
19293
|
}
|
|
19019
|
-
const targetRing =
|
|
19020
|
-
if (targetRing.length <=
|
|
19294
|
+
const targetRing = rings[targetRingIndex];
|
|
19295
|
+
if (targetRing.length <= 3) {
|
|
19021
19296
|
return;
|
|
19022
19297
|
}
|
|
19023
|
-
const
|
|
19024
|
-
if (
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19298
|
+
const newRings = rings.map((ring, idx) => {
|
|
19299
|
+
if (idx !== targetRingIndex) return ring.slice();
|
|
19300
|
+
const nr = ring.slice();
|
|
19301
|
+
nr.splice(targetVertexIndex, 1);
|
|
19302
|
+
return nr;
|
|
19303
|
+
});
|
|
19304
|
+
const coords = newRings.map((ring) => {
|
|
19305
|
+
const arr = ring.map((ll) => [ll.lng, ll.lat]);
|
|
19306
|
+
if (arr.length > 0) {
|
|
19307
|
+
const first = arr[0];
|
|
19308
|
+
const last = arr[arr.length - 1];
|
|
19309
|
+
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
19310
|
+
arr.push([first[0], first[1]]);
|
|
19311
|
+
}
|
|
19030
19312
|
}
|
|
19313
|
+
return arr;
|
|
19031
19314
|
});
|
|
19032
|
-
|
|
19315
|
+
let currentFeatureGroup = null;
|
|
19316
|
+
for (const fg of this.getFeatureGroups()) {
|
|
19317
|
+
let found = false;
|
|
19318
|
+
fg.eachLayer((layer) => {
|
|
19319
|
+
if (layer === polygonLayer) found = true;
|
|
19320
|
+
});
|
|
19321
|
+
if (found) {
|
|
19322
|
+
currentFeatureGroup = fg;
|
|
19323
|
+
break;
|
|
19324
|
+
}
|
|
19325
|
+
}
|
|
19033
19326
|
if (currentFeatureGroup) {
|
|
19034
19327
|
this.removeFeatureGroup(currentFeatureGroup);
|
|
19035
19328
|
}
|
|
19036
|
-
const newPolygon = this.turfHelper.getMultiPolygon([
|
|
19329
|
+
const newPolygon = this.turfHelper.getMultiPolygon([coords]);
|
|
19037
19330
|
this.eventManager.emit("polydraw:polygon:updated", {
|
|
19038
19331
|
operation: "removeVertex",
|
|
19039
19332
|
polygon: newPolygon
|
|
19040
19333
|
});
|
|
19041
19334
|
}
|
|
19042
19335
|
findFeatureGroupForPoly(poly) {
|
|
19043
|
-
console.log("PolygonInteractionManager findFeatureGroupForPoly");
|
|
19044
19336
|
for (const featureGroup of this.getFeatureGroups()) {
|
|
19045
19337
|
const featureCollection2 = featureGroup.toGeoJSON();
|
|
19046
19338
|
if (featureCollection2 && featureCollection2.features && featureCollection2.features[0]) {
|
|
19047
19339
|
const feature2 = featureCollection2.features[0];
|
|
19048
|
-
if (
|
|
19340
|
+
if (this.turfHelper.equalPolygons(feature2, poly)) {
|
|
19049
19341
|
return featureGroup;
|
|
19050
19342
|
}
|
|
19051
19343
|
}
|
|
@@ -19057,14 +19349,14 @@ class PolygonInteractionManager {
|
|
|
19057
19349
|
console.warn("No active marker set for dragging.");
|
|
19058
19350
|
return;
|
|
19059
19351
|
}
|
|
19060
|
-
console.log("PolygonInteractionManager markerDrag", featureGroup);
|
|
19061
19352
|
const newPos = [];
|
|
19062
19353
|
let testarray = [];
|
|
19063
19354
|
let hole = [];
|
|
19064
|
-
const
|
|
19065
|
-
const
|
|
19355
|
+
const layers = featureGroup.getLayers();
|
|
19356
|
+
const polygonLayer = layers.find((l) => l instanceof L.Polygon);
|
|
19357
|
+
const posarrays = polygonLayer.getLatLngs();
|
|
19066
19358
|
let length2 = 0;
|
|
19067
|
-
const markers2 =
|
|
19359
|
+
const markers2 = layers.filter((layer) => layer instanceof L.Marker);
|
|
19068
19360
|
if (posarrays.length > 1) {
|
|
19069
19361
|
for (let index = 0; index < posarrays.length; index++) {
|
|
19070
19362
|
testarray = [];
|
|
@@ -19089,7 +19381,7 @@ class PolygonInteractionManager {
|
|
|
19089
19381
|
}
|
|
19090
19382
|
newPos.push(hole);
|
|
19091
19383
|
} else {
|
|
19092
|
-
length2 += posarrays[index - 1]
|
|
19384
|
+
length2 += posarrays[index - 1].length;
|
|
19093
19385
|
for (let j = length2; j < posarrays[index][0].length + length2; j++) {
|
|
19094
19386
|
if (markers2[j]) {
|
|
19095
19387
|
testarray.push(markers2[j].getLatLng());
|
|
@@ -19130,17 +19422,16 @@ class PolygonInteractionManager {
|
|
|
19130
19422
|
}
|
|
19131
19423
|
newPos.push(hole);
|
|
19132
19424
|
}
|
|
19133
|
-
|
|
19425
|
+
polygonLayer.setLatLngs(newPos);
|
|
19134
19426
|
}
|
|
19135
19427
|
async markerDragEnd(featureGroup) {
|
|
19136
|
-
console.log("PolygonInteractionManager markerDragEnd");
|
|
19137
19428
|
this.polygonInformation.deletePolygonInformationStorage();
|
|
19138
19429
|
const featureCollection2 = featureGroup.toGeoJSON();
|
|
19139
19430
|
if (!featureCollection2.features || featureCollection2.features.length === 0) {
|
|
19140
19431
|
return;
|
|
19141
19432
|
}
|
|
19142
19433
|
this.removeFeatureGroup(featureGroup);
|
|
19143
|
-
if (featureCollection2.features[0].geometry.
|
|
19434
|
+
if (featureCollection2.features[0].geometry.type === "MultiPolygon") {
|
|
19144
19435
|
for (const element of featureCollection2.features[0].geometry.coordinates) {
|
|
19145
19436
|
const feature2 = this.turfHelper.getMultiPolygon([element]);
|
|
19146
19437
|
if (this.turfHelper.hasKinks(feature2)) {
|
|
@@ -19161,9 +19452,9 @@ class PolygonInteractionManager {
|
|
|
19161
19452
|
}
|
|
19162
19453
|
}
|
|
19163
19454
|
} else {
|
|
19164
|
-
const feature2 = this.turfHelper.getMultiPolygon(
|
|
19455
|
+
const feature2 = this.turfHelper.getMultiPolygon([
|
|
19165
19456
|
featureCollection2.features[0].geometry.coordinates
|
|
19166
|
-
);
|
|
19457
|
+
]);
|
|
19167
19458
|
if (this.turfHelper.hasKinks(feature2)) {
|
|
19168
19459
|
const unkink = this.turfHelper.getKinks(feature2);
|
|
19169
19460
|
for (const polygon2 of unkink) {
|
|
@@ -19172,11 +19463,6 @@ class PolygonInteractionManager {
|
|
|
19172
19463
|
polygon: this.turfHelper.getTurfPolygon(polygon2),
|
|
19173
19464
|
allowMerge: true
|
|
19174
19465
|
});
|
|
19175
|
-
this.eventManager.emit("polydraw:polygon:updated", {
|
|
19176
|
-
operation: "markerDrag",
|
|
19177
|
-
polygon: this.turfHelper.getTurfPolygon(polygon2),
|
|
19178
|
-
allowMerge: true
|
|
19179
|
-
});
|
|
19180
19466
|
}
|
|
19181
19467
|
} else {
|
|
19182
19468
|
this.eventManager.emit("polydraw:polygon:updated", {
|
|
@@ -19184,33 +19470,20 @@ class PolygonInteractionManager {
|
|
|
19184
19470
|
polygon: feature2,
|
|
19185
19471
|
allowMerge: true
|
|
19186
19472
|
});
|
|
19187
|
-
this.eventManager.emit("polydraw:polygon:updated", {
|
|
19188
|
-
operation: "markerDrag",
|
|
19189
|
-
polygon: feature2,
|
|
19190
|
-
allowMerge: true
|
|
19191
|
-
});
|
|
19192
19473
|
}
|
|
19193
19474
|
}
|
|
19194
19475
|
this.polygonInformation.createPolygonInformationStorage(this.getFeatureGroups());
|
|
19195
19476
|
}
|
|
19196
19477
|
offsetPolygonCoordinates(latLngs, offsetLat, offsetLng) {
|
|
19197
|
-
console.log("PolygonInteractionManager offsetPolygonCoordinates");
|
|
19198
19478
|
if (!latLngs) return latLngs;
|
|
19199
19479
|
if (Array.isArray(latLngs[0])) {
|
|
19200
|
-
return latLngs.map((ring) => this.offsetPolygonCoordinates(ring, offsetLat, offsetLng));
|
|
19201
|
-
} else if (latLngs.lat !== void 0 && latLngs.lng !== void 0) {
|
|
19202
|
-
return {
|
|
19203
|
-
lat: latLngs.lat + offsetLat,
|
|
19204
|
-
lng: latLngs.lng + offsetLng
|
|
19205
|
-
};
|
|
19206
|
-
} else {
|
|
19207
19480
|
return latLngs.map(
|
|
19208
|
-
(
|
|
19481
|
+
(ring) => this.offsetPolygonCoordinates(ring, offsetLat, offsetLng)
|
|
19209
19482
|
);
|
|
19210
19483
|
}
|
|
19484
|
+
return latLngs.map((p) => L.latLng(p.lat + offsetLat, p.lng + offsetLng));
|
|
19211
19485
|
}
|
|
19212
19486
|
updateMarkersAndHoleLinesDuringDrag(polygon2, offsetLat, offsetLng) {
|
|
19213
|
-
console.log("PolygonInteractionManager updateMarkersAndHoleLinesDuringDrag");
|
|
19214
19487
|
try {
|
|
19215
19488
|
let featureGroup = null;
|
|
19216
19489
|
for (const fg of this.getFeatureGroups()) {
|
|
@@ -19237,7 +19510,8 @@ class PolygonInteractionManager {
|
|
|
19237
19510
|
if (layer instanceof L.Marker) {
|
|
19238
19511
|
polygon2._polydrawOriginalMarkerPositions.set(layer, layer.getLatLng());
|
|
19239
19512
|
} else if (layer instanceof L.Polyline && !(layer instanceof L.Polygon)) {
|
|
19240
|
-
|
|
19513
|
+
const latLngs = layer.getLatLngs();
|
|
19514
|
+
polygon2._polydrawOriginalHoleLinePositions.set(layer, latLngs);
|
|
19241
19515
|
}
|
|
19242
19516
|
});
|
|
19243
19517
|
}
|
|
@@ -19254,10 +19528,16 @@ class PolygonInteractionManager {
|
|
|
19254
19528
|
} else if (layer instanceof L.Polyline && !(layer instanceof L.Polygon)) {
|
|
19255
19529
|
const originalPositions = polygon2._polydrawOriginalHoleLinePositions.get(layer);
|
|
19256
19530
|
if (originalPositions) {
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19531
|
+
let newLatLngs;
|
|
19532
|
+
if (Array.isArray(originalPositions[0])) {
|
|
19533
|
+
newLatLngs = originalPositions.map(
|
|
19534
|
+
(ring) => ring.map((latlng) => L.latLng(latlng.lat + offsetLat, latlng.lng + offsetLng))
|
|
19535
|
+
);
|
|
19536
|
+
} else {
|
|
19537
|
+
newLatLngs = originalPositions.map(
|
|
19538
|
+
(latlng) => L.latLng(latlng.lat + offsetLat, latlng.lng + offsetLng)
|
|
19539
|
+
);
|
|
19540
|
+
}
|
|
19261
19541
|
layer.setLatLngs(newLatLngs);
|
|
19262
19542
|
}
|
|
19263
19543
|
}
|
|
@@ -19267,7 +19547,6 @@ class PolygonInteractionManager {
|
|
|
19267
19547
|
}
|
|
19268
19548
|
}
|
|
19269
19549
|
async updatePolygonAfterDrag(polygon2) {
|
|
19270
|
-
console.log("PolygonInteractionManager updatePolygonAfterDrag");
|
|
19271
19550
|
try {
|
|
19272
19551
|
let featureGroup = null;
|
|
19273
19552
|
for (const fg of this.getFeatureGroups()) {
|
|
@@ -19299,36 +19578,39 @@ class PolygonInteractionManager {
|
|
|
19299
19578
|
} catch (error) {
|
|
19300
19579
|
}
|
|
19301
19580
|
}
|
|
19302
|
-
|
|
19581
|
+
getDragSubtractModifierKey() {
|
|
19582
|
+
const { keys } = this.config.dragPolygons.modifierSubtract;
|
|
19583
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
19584
|
+
const isMac = userAgent.includes("mac");
|
|
19585
|
+
const isWindows = userAgent.includes("windows");
|
|
19586
|
+
if (isMac && keys.mac) return keys.mac;
|
|
19587
|
+
if (isWindows && keys.windows) return keys.windows;
|
|
19588
|
+
if (keys.linux) return keys.linux;
|
|
19589
|
+
return isMac ? "metaKey" : "ctrlKey";
|
|
19590
|
+
}
|
|
19591
|
+
detectDragSubtractModifierKey(event) {
|
|
19303
19592
|
var _a2, _b2;
|
|
19304
|
-
console.log("PolygonInteractionManager detectModifierKey");
|
|
19305
19593
|
if (!((_b2 = (_a2 = this.config.dragPolygons) == null ? void 0 : _a2.modifierSubtract) == null ? void 0 : _b2.enabled)) {
|
|
19306
19594
|
return false;
|
|
19307
19595
|
}
|
|
19308
19596
|
if (isTouchDevice()) {
|
|
19309
19597
|
return false;
|
|
19310
19598
|
}
|
|
19311
|
-
const
|
|
19312
|
-
|
|
19313
|
-
if (isMac) {
|
|
19314
|
-
return event.metaKey;
|
|
19315
|
-
} else {
|
|
19316
|
-
return event.ctrlKey;
|
|
19317
|
-
}
|
|
19599
|
+
const modifierKey = this.getDragSubtractModifierKey();
|
|
19600
|
+
return !!event[modifierKey];
|
|
19318
19601
|
}
|
|
19319
19602
|
setSubtractVisualMode(polygon2, enabled) {
|
|
19320
|
-
console.log("PolygonInteractionManager setSubtractVisualMode");
|
|
19321
19603
|
if (!polygon2 || !polygon2.setStyle) {
|
|
19322
19604
|
return;
|
|
19323
19605
|
}
|
|
19324
19606
|
try {
|
|
19325
19607
|
if (enabled) {
|
|
19326
19608
|
polygon2.setStyle({
|
|
19327
|
-
color: this.config.dragPolygons.
|
|
19609
|
+
color: this.config.colors.dragPolygons.subtract
|
|
19328
19610
|
});
|
|
19329
19611
|
} else {
|
|
19330
19612
|
polygon2.setStyle({
|
|
19331
|
-
color: this.config.
|
|
19613
|
+
color: this.config.colors.polygon.border
|
|
19332
19614
|
});
|
|
19333
19615
|
}
|
|
19334
19616
|
this.updateMarkerColorsForSubtractMode(polygon2, enabled);
|
|
@@ -19337,7 +19619,6 @@ class PolygonInteractionManager {
|
|
|
19337
19619
|
}
|
|
19338
19620
|
updateMarkerColorsForSubtractMode(polygon2, subtractMode) {
|
|
19339
19621
|
var _a2, _b2;
|
|
19340
|
-
console.log("PolygonInteractionManager updateMarkerColorsForSubtractMode");
|
|
19341
19622
|
try {
|
|
19342
19623
|
let featureGroup = null;
|
|
19343
19624
|
for (const fg of this.getFeatureGroups()) {
|
|
@@ -19362,8 +19643,8 @@ class PolygonInteractionManager {
|
|
|
19362
19643
|
element.style.display = "none";
|
|
19363
19644
|
element.classList.add("subtract-mode-hidden");
|
|
19364
19645
|
} else {
|
|
19365
|
-
element.style.backgroundColor = this.config.dragPolygons.
|
|
19366
|
-
element.style.borderColor = this.config.dragPolygons.
|
|
19646
|
+
element.style.backgroundColor = this.config.colors.dragPolygons.subtract;
|
|
19647
|
+
element.style.borderColor = this.config.colors.dragPolygons.subtract;
|
|
19367
19648
|
element.classList.add("subtract-mode");
|
|
19368
19649
|
}
|
|
19369
19650
|
} else {
|
|
@@ -19383,8 +19664,7 @@ class PolygonInteractionManager {
|
|
|
19383
19664
|
}
|
|
19384
19665
|
}
|
|
19385
19666
|
handleModifierToggleDuringDrag(event) {
|
|
19386
|
-
|
|
19387
|
-
const isModifierPressed = this.detectModifierKey(event);
|
|
19667
|
+
const isModifierPressed = this.detectDragSubtractModifierKey(event);
|
|
19388
19668
|
this.currentModifierDragMode = isModifierPressed;
|
|
19389
19669
|
this.isModifierKeyHeld = isModifierPressed;
|
|
19390
19670
|
if (this.currentDragPolygon) {
|
|
@@ -19392,11 +19672,9 @@ class PolygonInteractionManager {
|
|
|
19392
19672
|
}
|
|
19393
19673
|
}
|
|
19394
19674
|
isModifierDragActive() {
|
|
19395
|
-
console.log("PolygonInteractionManager isModifierDragActive");
|
|
19396
19675
|
return this.currentModifierDragMode;
|
|
19397
19676
|
}
|
|
19398
19677
|
performModifierSubtract(draggedGeoJSON, originalFeatureGroup) {
|
|
19399
|
-
console.log("PolygonInteractionManager performModifierSubtract");
|
|
19400
19678
|
try {
|
|
19401
19679
|
const draggedPolygon = this.turfHelper.getTurfPolygon(draggedGeoJSON);
|
|
19402
19680
|
const intersectingFeatureGroups = [];
|
|
@@ -19416,8 +19694,11 @@ class PolygonInteractionManager {
|
|
|
19416
19694
|
const existingPolygon = this.turfHelper.getTurfPolygon(firstFeature);
|
|
19417
19695
|
try {
|
|
19418
19696
|
const intersection3 = this.turfHelper.getIntersection(existingPolygon, draggedPolygon);
|
|
19419
|
-
if (intersection3 && intersection3.geometry && intersection3.geometry
|
|
19420
|
-
|
|
19697
|
+
if (intersection3 && intersection3.geometry && "coordinates" in intersection3.geometry) {
|
|
19698
|
+
const coords = intersection3.geometry.coordinates;
|
|
19699
|
+
if (coords.length > 0) {
|
|
19700
|
+
intersectingFeatureGroups.push(featureGroup);
|
|
19701
|
+
}
|
|
19421
19702
|
}
|
|
19422
19703
|
} catch (intersectError) {
|
|
19423
19704
|
try {
|
|
@@ -19477,30 +19758,39 @@ class PolygonInteractionManager {
|
|
|
19477
19758
|
boundingBoxesOverlap(bbox1, bbox2) {
|
|
19478
19759
|
return !(bbox1[2] < bbox2[0] || bbox2[2] < bbox1[0] || bbox1[3] < bbox2[1] || bbox2[3] < bbox1[1]);
|
|
19479
19760
|
}
|
|
19480
|
-
|
|
19481
|
-
console.log("PolygonInteractionManager isModifierKeyPressed");
|
|
19761
|
+
isDragSubtractModifierKeyPressed(event) {
|
|
19482
19762
|
if (isTouchDevice()) {
|
|
19483
19763
|
return false;
|
|
19484
19764
|
}
|
|
19765
|
+
const modifierKey = this.getDragSubtractModifierKey();
|
|
19766
|
+
return !!event[modifierKey];
|
|
19767
|
+
}
|
|
19768
|
+
getEdgeDeletionModifierKey() {
|
|
19769
|
+
const { keys } = this.config.edgeDeletion;
|
|
19485
19770
|
const userAgent = navigator.userAgent.toLowerCase();
|
|
19486
19771
|
const isMac = userAgent.includes("mac");
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19772
|
+
const isWindows = userAgent.includes("windows");
|
|
19773
|
+
if (isMac && keys.mac) return keys.mac;
|
|
19774
|
+
if (isWindows && keys.windows) return keys.windows;
|
|
19775
|
+
if (keys.linux) return keys.linux;
|
|
19776
|
+
return isMac ? "metaKey" : "ctrlKey";
|
|
19777
|
+
}
|
|
19778
|
+
isEdgeDeletionModifierKeyPressed(event) {
|
|
19779
|
+
if (isTouchDevice()) {
|
|
19780
|
+
return false;
|
|
19491
19781
|
}
|
|
19782
|
+
const modifierKey = this.getEdgeDeletionModifierKey();
|
|
19783
|
+
return !!event[modifierKey];
|
|
19492
19784
|
}
|
|
19493
19785
|
onMarkerHoverForEdgeDeletion(marker, isHovering) {
|
|
19494
|
-
console.log("PolygonInteractionManager onMarkerHoverForEdgeDeletion");
|
|
19495
19786
|
const element = marker.getElement();
|
|
19496
19787
|
if (!element) return;
|
|
19497
19788
|
if (isHovering) {
|
|
19498
19789
|
const checkModifierAndUpdate = (e) => {
|
|
19499
|
-
|
|
19500
|
-
const isModifierPressed = this.detectModifierKey(e);
|
|
19790
|
+
const isModifierPressed = this.isEdgeDeletionModifierKeyPressed(e);
|
|
19501
19791
|
if (isModifierPressed) {
|
|
19502
|
-
element.style.backgroundColor =
|
|
19503
|
-
element.style.borderColor =
|
|
19792
|
+
element.style.backgroundColor = this.config.colors.edgeDeletion.hover;
|
|
19793
|
+
element.style.borderColor = this.config.colors.edgeDeletion.hover;
|
|
19504
19794
|
element.classList.add("edge-deletion-hover");
|
|
19505
19795
|
try {
|
|
19506
19796
|
const container = this.map.getContainer();
|
|
@@ -19520,7 +19810,7 @@ class PolygonInteractionManager {
|
|
|
19520
19810
|
};
|
|
19521
19811
|
const initialEvent = new MouseEvent("mouseover");
|
|
19522
19812
|
checkModifierAndUpdate(initialEvent);
|
|
19523
|
-
marker
|
|
19813
|
+
this.markerModifierHandlers.set(marker, checkModifierAndUpdate);
|
|
19524
19814
|
document.addEventListener("keydown", checkModifierAndUpdate);
|
|
19525
19815
|
document.addEventListener("keyup", checkModifierAndUpdate);
|
|
19526
19816
|
element.addEventListener("mousemove", checkModifierAndUpdate);
|
|
@@ -19533,18 +19823,17 @@ class PolygonInteractionManager {
|
|
|
19533
19823
|
container.style.cursor = "";
|
|
19534
19824
|
} catch (error) {
|
|
19535
19825
|
}
|
|
19536
|
-
const handler = marker
|
|
19826
|
+
const handler = this.markerModifierHandlers.get(marker);
|
|
19537
19827
|
if (handler) {
|
|
19538
19828
|
document.removeEventListener("keydown", handler);
|
|
19539
19829
|
document.removeEventListener("keyup", handler);
|
|
19540
19830
|
element.removeEventListener("mousemove", handler);
|
|
19541
|
-
delete
|
|
19831
|
+
this.markerModifierHandlers.delete(marker);
|
|
19542
19832
|
}
|
|
19543
19833
|
}
|
|
19544
19834
|
}
|
|
19545
19835
|
// Helper methods
|
|
19546
19836
|
getMarkerIndex(latlngs, position) {
|
|
19547
|
-
console.log("PolygonInteractionManager getMarkerIndex");
|
|
19548
19837
|
const bounds = PolyDrawUtil.getBounds(latlngs, Math.sqrt(2) / 2);
|
|
19549
19838
|
const compass = new Compass(
|
|
19550
19839
|
bounds.getSouth(),
|
|
@@ -19559,11 +19848,13 @@ class PolygonInteractionManager {
|
|
|
19559
19848
|
};
|
|
19560
19849
|
const targetPoint = this.turfHelper.getCoord(latLngPoint);
|
|
19561
19850
|
const fc = this.turfHelper.getFeaturePointCollection(latlngs);
|
|
19562
|
-
const nearestPointIdx = this.turfHelper.getNearestPointIndex(
|
|
19851
|
+
const nearestPointIdx = this.turfHelper.getNearestPointIndex(
|
|
19852
|
+
targetPoint,
|
|
19853
|
+
fc
|
|
19854
|
+
);
|
|
19563
19855
|
return nearestPointIdx;
|
|
19564
19856
|
}
|
|
19565
19857
|
ensureMarkerSeparation(polygonLength, markers2) {
|
|
19566
|
-
console.log("PolygonInteractionManager ensureMarkerSeparation");
|
|
19567
19858
|
const enabledMarkers = [];
|
|
19568
19859
|
if (markers2.menu.enabled) {
|
|
19569
19860
|
enabledMarkers.push({ type: "menu", index: markers2.menu.index });
|
|
@@ -19606,7 +19897,6 @@ class PolygonInteractionManager {
|
|
|
19606
19897
|
};
|
|
19607
19898
|
}
|
|
19608
19899
|
findAlternativeMarkerPosition(polygonLength, originalIndex, usedIndices) {
|
|
19609
|
-
console.log("PolygonInteractionManager findAlternativeMarkerPosition");
|
|
19610
19900
|
const maxAttempts = polygonLength;
|
|
19611
19901
|
const step = Math.max(1, Math.floor(polygonLength / 8));
|
|
19612
19902
|
for (let attempt = 1; attempt < maxAttempts; attempt++) {
|
|
@@ -19628,15 +19918,12 @@ class PolygonInteractionManager {
|
|
|
19628
19918
|
return originalIndex;
|
|
19629
19919
|
}
|
|
19630
19920
|
createDivIcon(processedClasses) {
|
|
19631
|
-
console.log("PolygonInteractionManager createDivIcon");
|
|
19632
19921
|
return IconFactory.createDivIcon(processedClasses);
|
|
19633
19922
|
}
|
|
19634
19923
|
getLatLngInfoString(latlng) {
|
|
19635
|
-
console.log("PolygonInteractionManager getLatLngInfoString");
|
|
19636
19924
|
return "Latitude: " + latlng.lat + " Longitude: " + latlng.lng;
|
|
19637
19925
|
}
|
|
19638
19926
|
generateMenuMarkerPopup(latLngs, featureGroup) {
|
|
19639
|
-
console.log("PolygonInteractionManager generateMenuMarkerPopup");
|
|
19640
19927
|
const outerWrapper = document.createElement("div");
|
|
19641
19928
|
outerWrapper.classList.add("alter-marker-outer-wrapper");
|
|
19642
19929
|
const wrapper = document.createElement("div");
|
|
@@ -19757,16 +20044,16 @@ class PolygonInteractionManager {
|
|
|
19757
20044
|
btn.style.pointerEvents = "auto";
|
|
19758
20045
|
btn.addEventListener("click", (e) => e.stopPropagation());
|
|
19759
20046
|
});
|
|
20047
|
+
const isMobile = window.innerWidth <= 600;
|
|
19760
20048
|
const popup = L.popup({
|
|
19761
20049
|
closeButton: true,
|
|
19762
20050
|
autoClose: true,
|
|
19763
|
-
className:
|
|
20051
|
+
className: `menu-popup${isMobile ? " mobile-popup" : ""}`
|
|
19764
20052
|
}).setContent(outerWrapper);
|
|
19765
20053
|
this._openMenuPopup = popup;
|
|
19766
20054
|
return popup;
|
|
19767
20055
|
}
|
|
19768
20056
|
getPolygonGeoJSONFromFeatureGroup(featureGroup) {
|
|
19769
|
-
console.log("PolygonInteractionManager getPolygonGeoJSONFromFeatureGroup");
|
|
19770
20057
|
try {
|
|
19771
20058
|
let polygon2 = null;
|
|
19772
20059
|
featureGroup.eachLayer((layer) => {
|
|
@@ -19779,7 +20066,11 @@ class PolygonInteractionManager {
|
|
|
19779
20066
|
}
|
|
19780
20067
|
return polygon2.toGeoJSON();
|
|
19781
20068
|
} catch (error) {
|
|
19782
|
-
|
|
20069
|
+
if (error instanceof Error) {
|
|
20070
|
+
console.warn("Error getting polygon GeoJSON from feature group:", error.message);
|
|
20071
|
+
} else {
|
|
20072
|
+
console.warn("Error getting polygon GeoJSON from feature group:", error);
|
|
20073
|
+
}
|
|
19783
20074
|
return {
|
|
19784
20075
|
type: "Feature",
|
|
19785
20076
|
geometry: {
|
|
@@ -19799,7 +20090,6 @@ class PolygonInteractionManager {
|
|
|
19799
20090
|
}
|
|
19800
20091
|
}
|
|
19801
20092
|
getTotalPolygonPerimeter(polygonGeoJSON) {
|
|
19802
|
-
console.log("PolygonInteractionManager getTotalPolygonPerimeter");
|
|
19803
20093
|
try {
|
|
19804
20094
|
if (!polygonGeoJSON || !polygonGeoJSON.geometry) {
|
|
19805
20095
|
return 0;
|
|
@@ -19838,12 +20128,15 @@ class PolygonInteractionManager {
|
|
|
19838
20128
|
}
|
|
19839
20129
|
return totalPerimeter * 1e3;
|
|
19840
20130
|
} catch (error) {
|
|
19841
|
-
|
|
20131
|
+
if (error instanceof Error) {
|
|
20132
|
+
console.warn("Error calculating total polygon perimeter:", error.message);
|
|
20133
|
+
} else {
|
|
20134
|
+
console.warn("Error calculating total polygon perimeter:", error);
|
|
20135
|
+
}
|
|
19842
20136
|
return this.turfHelper.getPolygonPerimeter(polygonGeoJSON) * 1e3;
|
|
19843
20137
|
}
|
|
19844
20138
|
}
|
|
19845
20139
|
generateInfoMarkerPopup(area2, perimeter) {
|
|
19846
|
-
console.log("PolygonInteractionManager generateInfoMarkerPopup");
|
|
19847
20140
|
const _perimeter = new Perimeter(perimeter, this.config);
|
|
19848
20141
|
const _area = new Area(area2, this.config);
|
|
19849
20142
|
const outerWrapper = document.createElement("div");
|
|
@@ -19871,10 +20164,11 @@ class PolygonInteractionManager {
|
|
|
19871
20164
|
btn.style.pointerEvents = "auto";
|
|
19872
20165
|
btn.addEventListener("click", (e) => e.stopPropagation());
|
|
19873
20166
|
});
|
|
20167
|
+
const isMobile = window.innerWidth <= 600;
|
|
19874
20168
|
const popup = L.popup({
|
|
19875
20169
|
closeButton: true,
|
|
19876
20170
|
autoClose: true,
|
|
19877
|
-
className:
|
|
20171
|
+
className: `info-popup${isMobile ? " mobile-popup" : ""}`
|
|
19878
20172
|
}).setContent(outerWrapper);
|
|
19879
20173
|
return popup;
|
|
19880
20174
|
}
|
|
@@ -19959,7 +20253,7 @@ class PolygonMutationManager {
|
|
|
19959
20253
|
this.subtractPolygon(data.subtractPolygon);
|
|
19960
20254
|
});
|
|
19961
20255
|
this.eventManager.on("polydraw:polygon:deleted", () => {
|
|
19962
|
-
this.emit("polygonDeleted");
|
|
20256
|
+
this.emit("polygonDeleted", void 0);
|
|
19963
20257
|
});
|
|
19964
20258
|
}
|
|
19965
20259
|
/**
|
|
@@ -19978,11 +20272,10 @@ class PolygonMutationManager {
|
|
|
19978
20272
|
* Handle menu actions from interaction manager
|
|
19979
20273
|
*/
|
|
19980
20274
|
async handleMenuAction(data) {
|
|
19981
|
-
const
|
|
19982
|
-
|
|
19983
|
-
this.removeFeatureGroupInternal(featureGroup);
|
|
20275
|
+
const completePolygonGeoJSON = this.getCompletePolygonFromFeatureGroup(data.featureGroup);
|
|
20276
|
+
this.removeFeatureGroupInternal(data.featureGroup);
|
|
19984
20277
|
let result;
|
|
19985
|
-
switch (action) {
|
|
20278
|
+
switch (data.action) {
|
|
19986
20279
|
case "simplify": {
|
|
19987
20280
|
result = this.geometryManager.simplifyPolygon(completePolygonGeoJSON);
|
|
19988
20281
|
break;
|
|
@@ -20028,7 +20321,8 @@ class PolygonMutationManager {
|
|
|
20028
20321
|
* Add a polygon with optional merging logic
|
|
20029
20322
|
*/
|
|
20030
20323
|
async addPolygon(latlngs, options = {}) {
|
|
20031
|
-
const {
|
|
20324
|
+
const { noMerge = false } = options;
|
|
20325
|
+
const { simplify: simplify3 = true } = options;
|
|
20032
20326
|
try {
|
|
20033
20327
|
if (this.config.mergePolygons && !noMerge && this.getFeatureGroups().length > 0 && !this.config.kinks) {
|
|
20034
20328
|
return await this.mergePolygon(latlngs, options);
|
|
@@ -20153,9 +20447,11 @@ class PolygonMutationManager {
|
|
|
20153
20447
|
this.interactionManager.addMarkers(polyElement, featureGroup);
|
|
20154
20448
|
} else {
|
|
20155
20449
|
const holePolyline = L.polyline(polyElement, {
|
|
20156
|
-
color: this.config.
|
|
20450
|
+
color: this.config.colors.hole.border,
|
|
20157
20451
|
weight: this.config.holeOptions.weight || 2,
|
|
20158
|
-
opacity: this.config.holeOptions.opacity || 1
|
|
20452
|
+
opacity: this.config.holeOptions.opacity || 1,
|
|
20453
|
+
fillColor: this.config.colors.hole.fill,
|
|
20454
|
+
fillOpacity: this.config.holeOptions.fillOpacity || 0.5
|
|
20159
20455
|
});
|
|
20160
20456
|
featureGroup.addLayer(holePolyline);
|
|
20161
20457
|
this.interactionManager.addHoleMarkers(polyElement, featureGroup);
|
|
@@ -20206,18 +20502,23 @@ class PolygonMutationManager {
|
|
|
20206
20502
|
if (!firstFeature.geometry || !firstFeature.geometry.coordinates) {
|
|
20207
20503
|
return;
|
|
20208
20504
|
}
|
|
20209
|
-
if (firstFeature.geometry.coordinates
|
|
20210
|
-
firstFeature.geometry.coordinates.forEach(
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20505
|
+
if (this.isPositionArrayofArrays(firstFeature.geometry.coordinates)) {
|
|
20506
|
+
firstFeature.geometry.coordinates.forEach(
|
|
20507
|
+
(element) => {
|
|
20508
|
+
try {
|
|
20509
|
+
const feature2 = this.turfHelper.getMultiPolygon([element]);
|
|
20510
|
+
polyIntersection = this.geometryManager.checkPolygonIntersection(
|
|
20511
|
+
feature2,
|
|
20512
|
+
latlngs
|
|
20513
|
+
);
|
|
20514
|
+
if (polyIntersection) {
|
|
20515
|
+
intersectingFeatureGroups.push(featureGroup);
|
|
20516
|
+
polygonFeature.push(feature2);
|
|
20517
|
+
}
|
|
20518
|
+
} catch (error) {
|
|
20217
20519
|
}
|
|
20218
|
-
} catch (error) {
|
|
20219
20520
|
}
|
|
20220
|
-
|
|
20521
|
+
);
|
|
20221
20522
|
} else {
|
|
20222
20523
|
try {
|
|
20223
20524
|
const feature2 = this.turfHelper.getTurfPolygon(firstFeature);
|
|
@@ -20279,12 +20580,31 @@ class PolygonMutationManager {
|
|
|
20279
20580
|
};
|
|
20280
20581
|
}
|
|
20281
20582
|
}
|
|
20583
|
+
/**
|
|
20584
|
+
* Create a polygon from GeoJSON feature
|
|
20585
|
+
*/
|
|
20586
|
+
isPositionArrayofArrays(arr) {
|
|
20587
|
+
if (!Array.isArray(arr) || arr.length === 0) return false;
|
|
20588
|
+
const first = arr[0];
|
|
20589
|
+
if (!Array.isArray(first) || first.length === 0) return false;
|
|
20590
|
+
const second = first[0];
|
|
20591
|
+
if (!Array.isArray(second) || second.length === 0) return false;
|
|
20592
|
+
const leaf = second[0];
|
|
20593
|
+
return this.isPosition(leaf);
|
|
20594
|
+
}
|
|
20595
|
+
isPosition(val) {
|
|
20596
|
+
return Array.isArray(val) && val.length >= 2 && val.every((n) => typeof n === "number");
|
|
20597
|
+
}
|
|
20282
20598
|
/**
|
|
20283
20599
|
* Create a polygon from GeoJSON feature
|
|
20284
20600
|
*/
|
|
20285
20601
|
getPolygon(latlngs) {
|
|
20286
20602
|
const polygon2 = L.GeoJSON.geometryToLayer(latlngs);
|
|
20287
|
-
polygon2.setStyle(
|
|
20603
|
+
polygon2.setStyle({
|
|
20604
|
+
...this.config.polygonOptions,
|
|
20605
|
+
color: this.config.colors.polygon.border,
|
|
20606
|
+
fillColor: this.config.colors.polygon.fill
|
|
20607
|
+
});
|
|
20288
20608
|
polygon2._polydrawUniqueId = L.Util.stamp(polygon2) + "_" + Date.now();
|
|
20289
20609
|
delete polygon2._polydrawDragData;
|
|
20290
20610
|
delete polygon2._polydrawOriginalLatLngs;
|
|
@@ -20482,9 +20802,9 @@ class PolygonMutationManager {
|
|
|
20482
20802
|
ensureMarkerSeparation(polygonLength, markers2) {
|
|
20483
20803
|
var _a2, _b2, _c;
|
|
20484
20804
|
return {
|
|
20485
|
-
menu: ((_a2 = markers2.menu) == null ? void 0 : _a2.index)
|
|
20486
|
-
delete: ((_b2 = markers2.delete) == null ? void 0 : _b2.index)
|
|
20487
|
-
info: ((_c = markers2.info) == null ? void 0 : _c.index)
|
|
20805
|
+
menu: ((_a2 = markers2.menu) == null ? void 0 : _a2.index) ?? 0,
|
|
20806
|
+
delete: ((_b2 = markers2.delete) == null ? void 0 : _b2.index) ?? 1,
|
|
20807
|
+
info: ((_c = markers2.info) == null ? void 0 : _c.index) ?? 2
|
|
20488
20808
|
};
|
|
20489
20809
|
}
|
|
20490
20810
|
findAlternativeMarkerPosition(polygonLength, originalIndex, usedIndices) {
|
|
@@ -20592,9 +20912,23 @@ class PolygonMutationManager {
|
|
|
20592
20912
|
}
|
|
20593
20913
|
}
|
|
20594
20914
|
}
|
|
20915
|
+
function injectDynamicStyles(config) {
|
|
20916
|
+
const style = document.createElement("style");
|
|
20917
|
+
style.innerHTML = `
|
|
20918
|
+
.leaflet-control a { background-color: ${config.colors.styles.controlButton.backgroundColor}; color: ${config.colors.styles.controlButton.color}; display: flex; align-items: center; justify-content: center; }
|
|
20919
|
+
.leaflet-control a:hover { background-color: ${config.colors.styles.controlButtonHover.backgroundColor}; }
|
|
20920
|
+
.leaflet-control a.active { background-color: ${config.colors.styles.controlButtonActive.backgroundColor}; color: ${config.colors.styles.controlButtonActive.color}; }
|
|
20921
|
+
.polydraw-indicator-active { background-color: ${config.colors.styles.indicatorActive.backgroundColor} !important; }
|
|
20922
|
+
.crosshair-cursor-enabled { cursor: crosshair !important; }
|
|
20923
|
+
.crosshair-cursor-enabled * { cursor: crosshair !important; }
|
|
20924
|
+
.leaflet-polydraw-p2p-marker { background-color: ${config.colors.styles.p2pMarker.backgroundColor}; border: 2px solid ${config.colors.styles.p2pMarker.borderColor}; border-radius: 50%; box-sizing: border-box; }
|
|
20925
|
+
.leaflet-polydraw-p2p-first-marker { position: relative; }
|
|
20926
|
+
.leaflet-polydraw-p2p-first-marker:hover { transform: scale(1.5); transition: all 0.2s ease; }
|
|
20927
|
+
`;
|
|
20928
|
+
document.head.appendChild(style);
|
|
20929
|
+
}
|
|
20595
20930
|
class Polydraw extends L.Control {
|
|
20596
20931
|
constructor(options) {
|
|
20597
|
-
console.log("constructor");
|
|
20598
20932
|
super(options);
|
|
20599
20933
|
__publicField(this, "map");
|
|
20600
20934
|
__publicField(this, "tracer", {});
|
|
@@ -20617,139 +20951,38 @@ class Polydraw extends L.Control {
|
|
|
20617
20951
|
__publicField(this, "_boundTouchEnd");
|
|
20618
20952
|
__publicField(this, "_boundTouchStart");
|
|
20619
20953
|
/**
|
|
20620
|
-
*
|
|
20954
|
+
* Updates map interactions based on the current drawing mode.
|
|
20621
20955
|
*/
|
|
20622
|
-
__publicField(this, "
|
|
20623
|
-
|
|
20624
|
-
if (!
|
|
20625
|
-
const
|
|
20626
|
-
if (
|
|
20627
|
-
|
|
20628
|
-
|
|
20629
|
-
|
|
20956
|
+
__publicField(this, "_handleActivateToggle", () => {
|
|
20957
|
+
const container = this.getContainer();
|
|
20958
|
+
if (!container) return;
|
|
20959
|
+
const activate = container.querySelector(".icon-activate");
|
|
20960
|
+
if (L.DomUtil.hasClass(activate, "active")) {
|
|
20961
|
+
L.DomUtil.removeClass(activate, "active");
|
|
20962
|
+
if (this.subContainer) {
|
|
20963
|
+
this.subContainer.style.maxHeight = "0px";
|
|
20964
|
+
}
|
|
20965
|
+
} else {
|
|
20966
|
+
L.DomUtil.addClass(activate, "active");
|
|
20967
|
+
if (this.subContainer) {
|
|
20968
|
+
this.subContainer.style.maxHeight = "250px";
|
|
20969
|
+
}
|
|
20630
20970
|
}
|
|
20971
|
+
this.updateActivateButtonIndicator();
|
|
20631
20972
|
});
|
|
20632
|
-
|
|
20633
|
-
|
|
20634
|
-
|
|
20635
|
-
|
|
20636
|
-
console.log("onMarkerLeaveForEdgeDeletionEvent");
|
|
20637
|
-
const element = e.target;
|
|
20638
|
-
if (element) {
|
|
20639
|
-
element.style.backgroundColor = "";
|
|
20640
|
-
element.style.borderColor = "";
|
|
20641
|
-
element.classList.remove("edge-deletion-hover");
|
|
20973
|
+
__publicField(this, "_handleDrawClick", (e) => {
|
|
20974
|
+
if (e) {
|
|
20975
|
+
e.preventDefault();
|
|
20976
|
+
e.stopPropagation();
|
|
20642
20977
|
}
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
this.loadExternalConfig(options.configPath, options == null ? void 0 : options.config);
|
|
20647
|
-
} else {
|
|
20648
|
-
this.config = { ...defaultConfig, ...(options == null ? void 0 : options.config) || {} };
|
|
20649
|
-
this.initializeComponents();
|
|
20650
|
-
}
|
|
20651
|
-
}
|
|
20652
|
-
async loadExternalConfig(configPath, inlineConfig) {
|
|
20653
|
-
try {
|
|
20654
|
-
const response = await fetch(configPath);
|
|
20655
|
-
if (!response.ok) {
|
|
20656
|
-
throw new Error(
|
|
20657
|
-
`Failed to load config from ${configPath}: ${response.status} ${response.statusText}`
|
|
20658
|
-
);
|
|
20659
|
-
}
|
|
20660
|
-
const externalConfig = await response.json();
|
|
20661
|
-
this.config = {
|
|
20662
|
-
...defaultConfig,
|
|
20663
|
-
...externalConfig,
|
|
20664
|
-
...inlineConfig || {}
|
|
20665
|
-
};
|
|
20666
|
-
this.initializeComponents();
|
|
20667
|
-
} catch (error) {
|
|
20668
|
-
console.warn(
|
|
20669
|
-
"Failed to load external config, falling back to default + inline config:",
|
|
20670
|
-
error
|
|
20671
|
-
);
|
|
20672
|
-
this.config = { ...defaultConfig, ...inlineConfig || {} };
|
|
20673
|
-
this.initializeComponents();
|
|
20674
|
-
}
|
|
20675
|
-
}
|
|
20676
|
-
initializeComponents() {
|
|
20677
|
-
this.turfHelper = new TurfHelper(this.config);
|
|
20678
|
-
this.mapStateService = new MapStateService();
|
|
20679
|
-
this.eventManager = new EventManager();
|
|
20680
|
-
this.polygonInformation = new PolygonInformationService(this.mapStateService);
|
|
20681
|
-
this.modeManager = new ModeManager(this.config, this.eventManager);
|
|
20682
|
-
this.polygonInformation.onPolygonInfoUpdated((_k) => {
|
|
20683
|
-
this.updateActivateButtonIndicator();
|
|
20684
|
-
});
|
|
20685
|
-
this._boundKeyDownHandler = this.handleKeyDown.bind(this);
|
|
20686
|
-
this.polygonMutationManager = null;
|
|
20687
|
-
this.polygonDrawManager = null;
|
|
20688
|
-
}
|
|
20689
|
-
onAdd(_map) {
|
|
20690
|
-
_map._onResize = () => {
|
|
20691
|
-
};
|
|
20692
|
-
if (L.Browser.touch && L.Browser.mobile) {
|
|
20693
|
-
_map.tap = false;
|
|
20694
|
-
}
|
|
20695
|
-
console.log("iOS touch workaround applied");
|
|
20696
|
-
console.log("onAdd");
|
|
20697
|
-
this.map = _map;
|
|
20698
|
-
const style = document.createElement("style");
|
|
20699
|
-
style.innerHTML = `
|
|
20700
|
-
.leaflet-control a { background-color: #fff; color: #000; display: flex; align-items: center; justify-content: center; }
|
|
20701
|
-
.leaflet-control a:hover { background-color: #f4f4f4; }
|
|
20702
|
-
.leaflet-control a.active { background-color:rgb(128, 218, 255); color: #fff; }
|
|
20703
|
-
.polydraw-indicator-active { background-color: #ffcc00 !important; }
|
|
20704
|
-
.crosshair-cursor-enabled { cursor: crosshair !important; }
|
|
20705
|
-
.crosshair-cursor-enabled * { cursor: crosshair !important; }
|
|
20706
|
-
.leaflet-polydraw-p2p-marker { background-color: #fff; border: 2px solid #50622b; border-radius: 50%; box-sizing: border-box; }
|
|
20707
|
-
.leaflet-polydraw-p2p-first-marker { position: relative; }
|
|
20708
|
-
.leaflet-polydraw-p2p-first-marker:hover { transform: scale(1.5); transition: all 0.2s ease; }
|
|
20709
|
-
`;
|
|
20710
|
-
document.head.appendChild(style);
|
|
20711
|
-
this.setupKeyboardHandlers();
|
|
20712
|
-
const container = L.DomUtil.create("div", "leaflet-control leaflet-bar");
|
|
20713
|
-
L.DomEvent.disableClickPropagation(container);
|
|
20714
|
-
L.DomEvent.on(container, "mousedown", L.DomEvent.stopPropagation);
|
|
20715
|
-
L.DomEvent.on(container, "touchstart", L.DomEvent.stopPropagation);
|
|
20716
|
-
L.DomEvent.on(container, "click", L.DomEvent.stopPropagation);
|
|
20717
|
-
container.style.display = "flex";
|
|
20718
|
-
container.style.flexDirection = "column-reverse";
|
|
20719
|
-
this.subContainer = L.DomUtil.create("div", "sub-buttons", container);
|
|
20720
|
-
this.subContainer.style.maxHeight = "0px";
|
|
20721
|
-
this.subContainer.style.overflow = "hidden";
|
|
20722
|
-
this.subContainer.style.transition = "max-height 0.3s ease";
|
|
20723
|
-
const onActivateToggle = () => {
|
|
20724
|
-
const activate = container.querySelector(".icon-activate");
|
|
20725
|
-
if (L.DomUtil.hasClass(activate, "active")) {
|
|
20726
|
-
L.DomUtil.removeClass(activate, "active");
|
|
20727
|
-
if (this.subContainer) {
|
|
20728
|
-
this.subContainer.style.maxHeight = "0px";
|
|
20729
|
-
}
|
|
20730
|
-
} else {
|
|
20731
|
-
L.DomUtil.addClass(activate, "active");
|
|
20732
|
-
if (this.subContainer) {
|
|
20733
|
-
this.subContainer.style.maxHeight = "250px";
|
|
20734
|
-
}
|
|
20735
|
-
}
|
|
20736
|
-
this.updateActivateButtonIndicator();
|
|
20737
|
-
};
|
|
20738
|
-
const onDrawClick = (e) => {
|
|
20739
|
-
console.log("onDrawClick");
|
|
20740
|
-
if (e) {
|
|
20741
|
-
e.preventDefault();
|
|
20742
|
-
e.stopPropagation();
|
|
20743
|
-
}
|
|
20744
|
-
if (this.modeManager.getCurrentMode() === DrawMode.Add) {
|
|
20745
|
-
this.setDrawMode(DrawMode.Off);
|
|
20746
|
-
return;
|
|
20978
|
+
if (this.modeManager.getCurrentMode() === DrawMode.Add) {
|
|
20979
|
+
this.setDrawMode(DrawMode.Off);
|
|
20980
|
+
return;
|
|
20747
20981
|
}
|
|
20748
20982
|
this.setDrawMode(DrawMode.Add);
|
|
20749
20983
|
this.polygonInformation.saveCurrentState();
|
|
20750
|
-
};
|
|
20751
|
-
|
|
20752
|
-
console.log("onSubtractClick");
|
|
20984
|
+
});
|
|
20985
|
+
__publicField(this, "_handleSubtractClick", (e) => {
|
|
20753
20986
|
if (e) {
|
|
20754
20987
|
e.preventDefault();
|
|
20755
20988
|
e.stopPropagation();
|
|
@@ -20760,8 +20993,8 @@ class Polydraw extends L.Control {
|
|
|
20760
20993
|
}
|
|
20761
20994
|
this.setDrawMode(DrawMode.Subtract);
|
|
20762
20995
|
this.polygonInformation.saveCurrentState();
|
|
20763
|
-
};
|
|
20764
|
-
|
|
20996
|
+
});
|
|
20997
|
+
__publicField(this, "_handleEraseClick", (e) => {
|
|
20765
20998
|
this.map.closePopup();
|
|
20766
20999
|
if (e) {
|
|
20767
21000
|
e.preventDefault();
|
|
@@ -20771,9 +21004,8 @@ class Polydraw extends L.Control {
|
|
|
20771
21004
|
return;
|
|
20772
21005
|
}
|
|
20773
21006
|
this.removeAllFeatureGroups();
|
|
20774
|
-
};
|
|
20775
|
-
|
|
20776
|
-
console.log("onPointToPointClick");
|
|
21007
|
+
});
|
|
21008
|
+
__publicField(this, "_handlePointToPointClick", (e) => {
|
|
20777
21009
|
if (e) {
|
|
20778
21010
|
e.preventDefault();
|
|
20779
21011
|
e.stopPropagation();
|
|
@@ -20784,16 +21016,213 @@ class Polydraw extends L.Control {
|
|
|
20784
21016
|
}
|
|
20785
21017
|
this.setDrawMode(DrawMode.PointToPoint);
|
|
20786
21018
|
this.polygonInformation.saveCurrentState();
|
|
21019
|
+
});
|
|
21020
|
+
/**
|
|
21021
|
+
* Handle marker hover when modifier key is held - event handler version
|
|
21022
|
+
*/
|
|
21023
|
+
__publicField(this, "onMarkerHoverForEdgeDeletionEvent", (e) => {
|
|
21024
|
+
if (!this.isModifierKeyHeld) return;
|
|
21025
|
+
const element = e.target;
|
|
21026
|
+
if (element) {
|
|
21027
|
+
element.style.backgroundColor = this.config.colors.edgeDeletion.hover;
|
|
21028
|
+
element.style.borderColor = this.config.colors.edgeDeletion.hover;
|
|
21029
|
+
element.classList.add("edge-deletion-hover");
|
|
21030
|
+
}
|
|
21031
|
+
});
|
|
21032
|
+
/**
|
|
21033
|
+
* Handle marker leave when modifier key is held - event handler version
|
|
21034
|
+
*/
|
|
21035
|
+
__publicField(this, "onMarkerLeaveForEdgeDeletionEvent", (e) => {
|
|
21036
|
+
const element = e.target;
|
|
21037
|
+
if (element) {
|
|
21038
|
+
element.style.backgroundColor = "";
|
|
21039
|
+
element.style.borderColor = "";
|
|
21040
|
+
element.classList.remove("edge-deletion-hover");
|
|
21041
|
+
}
|
|
21042
|
+
});
|
|
21043
|
+
this.config = defaultConfig;
|
|
21044
|
+
if (options == null ? void 0 : options.configPath) {
|
|
21045
|
+
this.loadExternalConfig(options.configPath, options == null ? void 0 : options.config);
|
|
21046
|
+
} else {
|
|
21047
|
+
this.config = { ...defaultConfig, ...(options == null ? void 0 : options.config) || {} };
|
|
21048
|
+
this.initializeComponents();
|
|
21049
|
+
}
|
|
21050
|
+
}
|
|
21051
|
+
/**
|
|
21052
|
+
* Method called when the control is added to the map.
|
|
21053
|
+
* It initializes the control, creates the UI, and sets up event listeners.
|
|
21054
|
+
* @param _map - The map instance.
|
|
21055
|
+
* @returns The control's container element.
|
|
21056
|
+
*/
|
|
21057
|
+
onAdd(_map) {
|
|
21058
|
+
const extendedMap = _map;
|
|
21059
|
+
const browser = L.Browser;
|
|
21060
|
+
extendedMap._onResize = () => {
|
|
20787
21061
|
};
|
|
21062
|
+
if (browser.touch && browser.mobile) {
|
|
21063
|
+
extendedMap.tap = false;
|
|
21064
|
+
}
|
|
21065
|
+
this.map = _map;
|
|
21066
|
+
this.setupKeyboardHandlers();
|
|
21067
|
+
const container = L.DomUtil.create("div", "leaflet-control leaflet-bar");
|
|
21068
|
+
this.initializeUI(container);
|
|
21069
|
+
this.createTracer();
|
|
21070
|
+
this.initializeManagers();
|
|
21071
|
+
this.setupEventListeners();
|
|
21072
|
+
return container;
|
|
21073
|
+
}
|
|
21074
|
+
/**
|
|
21075
|
+
* Method called when the control is removed from the map.
|
|
21076
|
+
* It handles the cleanup of layers, events, and handlers.
|
|
21077
|
+
* @param _map - The map instance, unused but required by the L.Control interface.
|
|
21078
|
+
*/
|
|
21079
|
+
onRemove(_map) {
|
|
21080
|
+
this.removeKeyboardHandlers();
|
|
21081
|
+
if (this.tracer) {
|
|
21082
|
+
this.map.removeLayer(this.tracer);
|
|
21083
|
+
}
|
|
21084
|
+
this.removeAllFeatureGroups();
|
|
21085
|
+
}
|
|
21086
|
+
/**
|
|
21087
|
+
* Adds the control to the given map.
|
|
21088
|
+
* @param map - The map instance.
|
|
21089
|
+
* @returns The current instance of the control.
|
|
21090
|
+
*/
|
|
21091
|
+
addTo(map) {
|
|
21092
|
+
super.addTo(map);
|
|
21093
|
+
return this;
|
|
21094
|
+
}
|
|
21095
|
+
/**
|
|
21096
|
+
* Returns the array of feature groups currently managed by the control.
|
|
21097
|
+
* @returns An array of L.FeatureGroup objects.
|
|
21098
|
+
*/
|
|
21099
|
+
getFeatureGroups() {
|
|
21100
|
+
return this.arrayOfFeatureGroups;
|
|
21101
|
+
}
|
|
21102
|
+
/**
|
|
21103
|
+
* Adds a predefined polygon to the map.
|
|
21104
|
+
* @param geographicBorders - An array of LatLng arrays representing the polygon's coordinates.
|
|
21105
|
+
* @param options - Optional parameters, including visual optimization level.
|
|
21106
|
+
*/
|
|
21107
|
+
async addPredefinedPolygon(geographicBorders, options) {
|
|
21108
|
+
if (!geographicBorders || geographicBorders.length === 0) {
|
|
21109
|
+
throw new Error("Cannot add empty polygon array");
|
|
21110
|
+
}
|
|
21111
|
+
if (!this.map) {
|
|
21112
|
+
throw new Error("Map not initialized");
|
|
21113
|
+
}
|
|
21114
|
+
if (!this.polygonMutationManager) {
|
|
21115
|
+
throw new Error("PolygonMutationManager not initialized");
|
|
21116
|
+
}
|
|
21117
|
+
const visualOptimizationLevel = (options == null ? void 0 : options.visualOptimizationLevel) ?? 0;
|
|
21118
|
+
for (const [groupIndex, group] of geographicBorders.entries()) {
|
|
21119
|
+
if (!group || !group[0] || group[0].length < 4) {
|
|
21120
|
+
throw new Error(
|
|
21121
|
+
`Invalid polygon data at index ${groupIndex}: A polygon must have at least 3 unique vertices.`
|
|
21122
|
+
);
|
|
21123
|
+
}
|
|
21124
|
+
try {
|
|
21125
|
+
const coords = group.map((ring) => ring.map((latlng) => [latlng.lng, latlng.lat]));
|
|
21126
|
+
const polygon2 = this.turfHelper.getMultiPolygon([coords]);
|
|
21127
|
+
const result = await this.polygonMutationManager.addPolygon(polygon2, {
|
|
21128
|
+
simplify: false,
|
|
21129
|
+
noMerge: false,
|
|
21130
|
+
visualOptimizationLevel
|
|
21131
|
+
});
|
|
21132
|
+
if (!result.success) {
|
|
21133
|
+
console.error("Error adding polygon via manager:", result.error);
|
|
21134
|
+
throw new Error(result.error || "Failed to add polygon");
|
|
21135
|
+
}
|
|
21136
|
+
this.polygonInformation.createPolygonInformationStorage(this.arrayOfFeatureGroups);
|
|
21137
|
+
} catch (error) {
|
|
21138
|
+
console.error("Error adding auto polygon:", error);
|
|
21139
|
+
throw error;
|
|
21140
|
+
}
|
|
21141
|
+
}
|
|
21142
|
+
}
|
|
21143
|
+
/**
|
|
21144
|
+
* Sets the current drawing mode.
|
|
21145
|
+
* @param mode - The drawing mode to set.
|
|
21146
|
+
*/
|
|
21147
|
+
setDrawMode(mode) {
|
|
21148
|
+
const previousMode = this.drawMode;
|
|
21149
|
+
this._updateDrawModeState(mode);
|
|
21150
|
+
if (previousMode === DrawMode.PointToPoint && mode !== DrawMode.PointToPoint) {
|
|
21151
|
+
this.polygonDrawManager.clearP2pMarkers();
|
|
21152
|
+
this.stopDraw();
|
|
21153
|
+
} else if (mode === DrawMode.Off) {
|
|
21154
|
+
this.stopDraw();
|
|
21155
|
+
} else if (mode !== DrawMode.PointToPoint) {
|
|
21156
|
+
this.stopDraw();
|
|
21157
|
+
}
|
|
21158
|
+
if (this.map) {
|
|
21159
|
+
this._updateUIAfterDrawModeChange(mode);
|
|
21160
|
+
this._updateMapInteractions();
|
|
21161
|
+
}
|
|
21162
|
+
}
|
|
21163
|
+
/**
|
|
21164
|
+
* Returns the current drawing mode.
|
|
21165
|
+
* @returns The current DrawMode.
|
|
21166
|
+
*/
|
|
21167
|
+
getDrawMode() {
|
|
21168
|
+
return this.modeManager.getCurrentMode();
|
|
21169
|
+
}
|
|
21170
|
+
/**
|
|
21171
|
+
* Registers an event listener for a given event type.
|
|
21172
|
+
* @param event - The event type to listen for.
|
|
21173
|
+
* @param callback - The callback function to execute when the event is triggered.
|
|
21174
|
+
*/
|
|
21175
|
+
on(event, callback) {
|
|
21176
|
+
this.eventManager.on(event, callback);
|
|
21177
|
+
}
|
|
21178
|
+
/**
|
|
21179
|
+
* Unregisters an event listener for a given event type.
|
|
21180
|
+
* @param event - The event type to stop listening for.
|
|
21181
|
+
* @param callback - The callback function to remove.
|
|
21182
|
+
*/
|
|
21183
|
+
off(event, callback) {
|
|
21184
|
+
this.eventManager.off(event, callback);
|
|
21185
|
+
}
|
|
21186
|
+
/**
|
|
21187
|
+
* Removes all feature groups from the map and clears the internal storage.
|
|
21188
|
+
*/
|
|
21189
|
+
removeAllFeatureGroups() {
|
|
21190
|
+
this.arrayOfFeatureGroups.forEach((featureGroups) => {
|
|
21191
|
+
try {
|
|
21192
|
+
this.map.removeLayer(featureGroups);
|
|
21193
|
+
} catch (error) {
|
|
21194
|
+
}
|
|
21195
|
+
});
|
|
21196
|
+
this.arrayOfFeatureGroups.length = 0;
|
|
21197
|
+
this.polygonInformation.deletePolygonInformationStorage();
|
|
21198
|
+
this.polygonInformation.updatePolygons();
|
|
21199
|
+
this.updateActivateButtonIndicator();
|
|
21200
|
+
}
|
|
21201
|
+
/**
|
|
21202
|
+
* Initializes the user interface, creates DOM elements, sets up buttons, and injects styles.
|
|
21203
|
+
* @param container - The main control container element.
|
|
21204
|
+
*/
|
|
21205
|
+
initializeUI(container) {
|
|
21206
|
+
injectDynamicStyles(this.config);
|
|
21207
|
+
L.DomEvent.disableClickPropagation(container);
|
|
21208
|
+
L.DomEvent.on(container, "mousedown", L.DomEvent.stopPropagation);
|
|
21209
|
+
L.DomEvent.on(container, "touchstart", L.DomEvent.stopPropagation);
|
|
21210
|
+
L.DomEvent.on(container, "click", L.DomEvent.stopPropagation);
|
|
21211
|
+
container.style.display = "flex";
|
|
21212
|
+
container.style.flexDirection = "column-reverse";
|
|
21213
|
+
this.subContainer = L.DomUtil.create("div", "sub-buttons", container);
|
|
21214
|
+
this.subContainer.style.maxHeight = "0px";
|
|
21215
|
+
this.subContainer.style.overflow = "hidden";
|
|
21216
|
+
this.subContainer.style.transition = "max-height 0.3s ease";
|
|
20788
21217
|
createButtons(
|
|
20789
21218
|
container,
|
|
20790
21219
|
this.subContainer,
|
|
20791
21220
|
this.config,
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
|
|
21221
|
+
this._handleActivateToggle,
|
|
21222
|
+
this._handleDrawClick,
|
|
21223
|
+
this._handleSubtractClick,
|
|
21224
|
+
this._handleEraseClick,
|
|
21225
|
+
this._handlePointToPointClick
|
|
20797
21226
|
);
|
|
20798
21227
|
const uiUpdateListener = (mode) => {
|
|
20799
21228
|
const drawButton = container.querySelector(".icon-draw");
|
|
@@ -20802,30 +21231,12 @@ class Polydraw extends L.Control {
|
|
|
20802
21231
|
if (subtractButton) subtractButton.classList.toggle("active", mode === DrawMode.Subtract);
|
|
20803
21232
|
};
|
|
20804
21233
|
this.drawModeListeners.push(uiUpdateListener);
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
this.polygonDrawManager = new PolygonDrawManager({
|
|
20811
|
-
turfHelper: this.turfHelper,
|
|
20812
|
-
map: this.map,
|
|
20813
|
-
config: this.config,
|
|
20814
|
-
modeManager: this.modeManager,
|
|
20815
|
-
eventManager: this.eventManager,
|
|
20816
|
-
tracer: this.tracer
|
|
20817
|
-
});
|
|
20818
|
-
this.polygonMutationManager = new PolygonMutationManager({
|
|
20819
|
-
turfHelper: this.turfHelper,
|
|
20820
|
-
polygonInformation: this.polygonInformation,
|
|
20821
|
-
map: this.map,
|
|
20822
|
-
config: this.config,
|
|
20823
|
-
modeManager: this.modeManager,
|
|
20824
|
-
eventManager: this.eventManager,
|
|
20825
|
-
getFeatureGroups: () => this.arrayOfFeatureGroups
|
|
20826
|
-
});
|
|
21234
|
+
}
|
|
21235
|
+
/**
|
|
21236
|
+
* Attaches listeners to polygonMutationManager and eventManager.
|
|
21237
|
+
*/
|
|
21238
|
+
setupEventListeners() {
|
|
20827
21239
|
this.polygonMutationManager.on("polygonOperationComplete", (data) => {
|
|
20828
|
-
console.log("polygonOperationComplete");
|
|
20829
21240
|
this.updateActivateButtonIndicator();
|
|
20830
21241
|
this.modeManager.updateStateForMode(DrawMode.Off);
|
|
20831
21242
|
this.drawMode = DrawMode.Off;
|
|
@@ -20866,130 +21277,148 @@ class Polydraw extends L.Control {
|
|
|
20866
21277
|
this.stopDraw();
|
|
20867
21278
|
this.setDrawMode(DrawMode.Off);
|
|
20868
21279
|
});
|
|
20869
|
-
return container;
|
|
20870
21280
|
}
|
|
20871
|
-
|
|
20872
|
-
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
|
|
20879
|
-
|
|
20880
|
-
|
|
20881
|
-
|
|
20882
|
-
if (this.tracer) {
|
|
20883
|
-
this.map.removeLayer(this.tracer);
|
|
21281
|
+
/**
|
|
21282
|
+
* Initializes and adds the tracer polyline to the map.
|
|
21283
|
+
*/
|
|
21284
|
+
createTracer() {
|
|
21285
|
+
this.tracer = L.polyline([], {
|
|
21286
|
+
...this.config.polyLineOptions,
|
|
21287
|
+
color: this.config.colors.polyline
|
|
21288
|
+
});
|
|
21289
|
+
try {
|
|
21290
|
+
this.tracer.addTo(this.map);
|
|
21291
|
+
} catch (error) {
|
|
20884
21292
|
}
|
|
20885
|
-
this.removeAllFeatureGroups();
|
|
20886
21293
|
}
|
|
20887
|
-
|
|
20888
|
-
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
21294
|
+
/**
|
|
21295
|
+
* Sets up PolygonDrawManager and PolygonMutationManager with the map.
|
|
21296
|
+
*/
|
|
21297
|
+
initializeManagers() {
|
|
21298
|
+
this.polygonDrawManager = new PolygonDrawManager({
|
|
21299
|
+
turfHelper: this.turfHelper,
|
|
21300
|
+
map: this.map,
|
|
21301
|
+
config: this.config,
|
|
21302
|
+
modeManager: this.modeManager,
|
|
21303
|
+
eventManager: this.eventManager,
|
|
21304
|
+
tracer: this.tracer
|
|
21305
|
+
});
|
|
21306
|
+
this.polygonMutationManager = new PolygonMutationManager({
|
|
21307
|
+
turfHelper: this.turfHelper,
|
|
21308
|
+
polygonInformation: this.polygonInformation,
|
|
21309
|
+
map: this.map,
|
|
21310
|
+
config: this.config,
|
|
21311
|
+
modeManager: this.modeManager,
|
|
21312
|
+
eventManager: this.eventManager,
|
|
21313
|
+
getFeatureGroups: () => this.arrayOfFeatureGroups
|
|
21314
|
+
});
|
|
21315
|
+
}
|
|
21316
|
+
/**
|
|
21317
|
+
* Loads an external configuration file and merges it with the default and inline configs.
|
|
21318
|
+
* @param configPath - The path to the external configuration file.
|
|
21319
|
+
* @param inlineConfig - An optional inline configuration object.
|
|
21320
|
+
*/
|
|
21321
|
+
async loadExternalConfig(configPath, inlineConfig) {
|
|
21322
|
+
try {
|
|
21323
|
+
const response = await fetch(configPath);
|
|
21324
|
+
if (!response.ok) {
|
|
21325
|
+
throw new Error(
|
|
21326
|
+
`Failed to load config from ${configPath}: ${response.status} ${response.statusText}`
|
|
21327
|
+
);
|
|
20921
21328
|
}
|
|
21329
|
+
const externalConfig = await response.json();
|
|
21330
|
+
this.config = {
|
|
21331
|
+
...defaultConfig,
|
|
21332
|
+
...externalConfig,
|
|
21333
|
+
...inlineConfig || {}
|
|
21334
|
+
};
|
|
21335
|
+
this.initializeComponents();
|
|
21336
|
+
} catch (error) {
|
|
21337
|
+
console.warn(
|
|
21338
|
+
"Failed to load external config, falling back to default + inline config:",
|
|
21339
|
+
error
|
|
21340
|
+
);
|
|
21341
|
+
this.config = { ...defaultConfig, ...inlineConfig || {} };
|
|
21342
|
+
this.initializeComponents();
|
|
20922
21343
|
}
|
|
20923
21344
|
}
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
21345
|
+
/**
|
|
21346
|
+
* Initializes the core components of the Polydraw control.
|
|
21347
|
+
*/
|
|
21348
|
+
/**
|
|
21349
|
+
* Updates the state of the drawing mode.
|
|
21350
|
+
* @param mode - The new drawing mode.
|
|
21351
|
+
*/
|
|
21352
|
+
_updateDrawModeState(mode) {
|
|
20927
21353
|
this.drawMode = mode;
|
|
20928
21354
|
this.modeManager.updateStateForMode(mode);
|
|
20929
21355
|
this.emitDrawModeChanged();
|
|
20930
21356
|
this.updateMarkerDraggableState();
|
|
20931
|
-
|
|
20932
|
-
|
|
20933
|
-
|
|
20934
|
-
|
|
20935
|
-
|
|
20936
|
-
|
|
20937
|
-
|
|
21357
|
+
}
|
|
21358
|
+
/**
|
|
21359
|
+
* Updates the UI after a change in the drawing mode.
|
|
21360
|
+
* @param mode - The new drawing mode.
|
|
21361
|
+
*/
|
|
21362
|
+
_updateUIAfterDrawModeChange(mode) {
|
|
21363
|
+
const shouldShowCrosshair = this.modeManager.shouldShowCrosshairCursor();
|
|
21364
|
+
if (shouldShowCrosshair) {
|
|
21365
|
+
L.DomUtil.addClass(this.map.getContainer(), "crosshair-cursor-enabled");
|
|
21366
|
+
} else {
|
|
21367
|
+
L.DomUtil.removeClass(this.map.getContainer(), "crosshair-cursor-enabled");
|
|
20938
21368
|
}
|
|
20939
|
-
|
|
20940
|
-
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
|
|
20945
|
-
|
|
20946
|
-
|
|
20947
|
-
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
|
|
20951
|
-
|
|
20952
|
-
|
|
20953
|
-
this.
|
|
20954
|
-
|
|
20955
|
-
|
|
20956
|
-
|
|
20957
|
-
|
|
20958
|
-
|
|
20959
|
-
|
|
20960
|
-
|
|
20961
|
-
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
color: "#D9460F",
|
|
20965
|
-
dashArray: null
|
|
20966
|
-
// Reset to solid line
|
|
20967
|
-
});
|
|
20968
|
-
break;
|
|
20969
|
-
case DrawMode.PointToPoint:
|
|
20970
|
-
this.tracer.setStyle({
|
|
20971
|
-
color: defaultConfig.polyLineOptions.color,
|
|
20972
|
-
dashArray: "5, 5"
|
|
20973
|
-
});
|
|
20974
|
-
break;
|
|
20975
|
-
}
|
|
20976
|
-
} catch (error) {
|
|
21369
|
+
try {
|
|
21370
|
+
switch (mode) {
|
|
21371
|
+
case DrawMode.Off:
|
|
21372
|
+
this.tracer.setStyle({ color: "" });
|
|
21373
|
+
break;
|
|
21374
|
+
case DrawMode.Add:
|
|
21375
|
+
this.tracer.setStyle({
|
|
21376
|
+
color: this.config.colors.polyline,
|
|
21377
|
+
dashArray: null
|
|
21378
|
+
// Reset to solid line
|
|
21379
|
+
});
|
|
21380
|
+
break;
|
|
21381
|
+
case DrawMode.Subtract:
|
|
21382
|
+
this.tracer.setStyle({
|
|
21383
|
+
color: this.config.colors.subtractLine,
|
|
21384
|
+
dashArray: null
|
|
21385
|
+
// Reset to solid line
|
|
21386
|
+
});
|
|
21387
|
+
break;
|
|
21388
|
+
case DrawMode.PointToPoint:
|
|
21389
|
+
this.tracer.setStyle({
|
|
21390
|
+
color: this.config.colors.polyline,
|
|
21391
|
+
dashArray: "5, 5"
|
|
21392
|
+
});
|
|
21393
|
+
break;
|
|
20977
21394
|
}
|
|
20978
|
-
|
|
21395
|
+
} catch (error) {
|
|
20979
21396
|
}
|
|
20980
21397
|
}
|
|
20981
|
-
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
|
|
20985
|
-
|
|
20986
|
-
this.
|
|
21398
|
+
_updateMapInteractions() {
|
|
21399
|
+
const mapDragEnabled = this.modeManager.canPerformAction("mapDrag");
|
|
21400
|
+
const mapZoomEnabled = this.modeManager.canPerformAction("mapZoom");
|
|
21401
|
+
const mapDoubleClickEnabled = this.modeManager.canPerformAction("mapDoubleClickZoom");
|
|
21402
|
+
this.events(this.drawMode !== DrawMode.Off);
|
|
21403
|
+
this.setLeafletMapEvents(mapDragEnabled, mapDoubleClickEnabled, mapZoomEnabled);
|
|
20987
21404
|
}
|
|
20988
|
-
|
|
20989
|
-
this.
|
|
21405
|
+
initializeComponents() {
|
|
21406
|
+
this.turfHelper = new TurfHelper(this.config);
|
|
21407
|
+
this.mapStateService = new MapStateService();
|
|
21408
|
+
this.eventManager = new EventManager();
|
|
21409
|
+
this.polygonInformation = new PolygonInformationService(this.mapStateService);
|
|
21410
|
+
this.modeManager = new ModeManager(this.config, this.eventManager);
|
|
21411
|
+
this.polygonInformation.onPolygonInfoUpdated((_k) => {
|
|
21412
|
+
this.updateActivateButtonIndicator();
|
|
21413
|
+
});
|
|
21414
|
+
this._boundKeyDownHandler = this.handleKeyDown.bind(this);
|
|
21415
|
+
this.polygonMutationManager = null;
|
|
21416
|
+
this.polygonDrawManager = null;
|
|
20990
21417
|
}
|
|
21418
|
+
/**
|
|
21419
|
+
* Emits an event to notify listeners that the drawing mode has changed.
|
|
21420
|
+
*/
|
|
20991
21421
|
emitDrawModeChanged() {
|
|
20992
|
-
console.log("emitDrawModeChanged");
|
|
20993
21422
|
this.eventManager.emit("polydraw:mode:change", {
|
|
20994
21423
|
mode: this.modeManager.getCurrentMode()
|
|
20995
21424
|
});
|
|
@@ -21001,7 +21430,6 @@ class Polydraw extends L.Control {
|
|
|
21001
21430
|
* Update the draggable state of all existing markers when draw mode changes
|
|
21002
21431
|
*/
|
|
21003
21432
|
updateMarkerDraggableState() {
|
|
21004
|
-
console.log("updateMarkerDraggableState");
|
|
21005
21433
|
const shouldBeDraggable = this.modeManager.canPerformAction("markerDrag");
|
|
21006
21434
|
this.arrayOfFeatureGroups.forEach((featureGroup) => {
|
|
21007
21435
|
featureGroup.eachLayer((layer) => {
|
|
@@ -21022,36 +21450,35 @@ class Polydraw extends L.Control {
|
|
|
21022
21450
|
});
|
|
21023
21451
|
});
|
|
21024
21452
|
}
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
try {
|
|
21029
|
-
this.map.removeLayer(featureGroups);
|
|
21030
|
-
} catch (error) {
|
|
21031
|
-
}
|
|
21032
|
-
});
|
|
21033
|
-
this.arrayOfFeatureGroups.length = 0;
|
|
21034
|
-
this.polygonInformation.deletePolygonInformationStorage();
|
|
21035
|
-
this.polygonInformation.updatePolygons();
|
|
21036
|
-
this.updateActivateButtonIndicator();
|
|
21037
|
-
}
|
|
21453
|
+
/**
|
|
21454
|
+
* Stops the current drawing operation and resets the tracer.
|
|
21455
|
+
*/
|
|
21038
21456
|
stopDraw() {
|
|
21039
|
-
console.log("stopDraw");
|
|
21040
21457
|
this.resetTracker();
|
|
21041
21458
|
this.drawStartedEvents(false);
|
|
21042
21459
|
}
|
|
21460
|
+
/**
|
|
21461
|
+
* Enables or disables Leaflet's default map interactions.
|
|
21462
|
+
* @param enableDragging - Whether to enable map dragging.
|
|
21463
|
+
* @param enableDoubleClickZoom - Whether to enable double-click zoom.
|
|
21464
|
+
* @param enableScrollWheelZoom - Whether to enable scroll wheel zoom.
|
|
21465
|
+
*/
|
|
21043
21466
|
setLeafletMapEvents(enableDragging, enableDoubleClickZoom, enableScrollWheelZoom) {
|
|
21044
|
-
console.log("setLeafletMapEvents");
|
|
21045
21467
|
enableDragging ? this.map.dragging.enable() : this.map.dragging.disable();
|
|
21046
21468
|
enableDoubleClickZoom ? this.map.doubleClickZoom.enable() : this.map.doubleClickZoom.disable();
|
|
21047
21469
|
enableScrollWheelZoom ? this.map.scrollWheelZoom.enable() : this.map.scrollWheelZoom.disable();
|
|
21048
21470
|
}
|
|
21471
|
+
/**
|
|
21472
|
+
* Resets the tracer polyline by clearing its LatLngs.
|
|
21473
|
+
*/
|
|
21049
21474
|
resetTracker() {
|
|
21050
|
-
console.log("resetTracker");
|
|
21051
21475
|
this.tracer.setLatLngs([]);
|
|
21052
21476
|
}
|
|
21477
|
+
/**
|
|
21478
|
+
* Attaches or detaches the mouse move and mouse up event listeners for drawing.
|
|
21479
|
+
* @param onoff - A boolean indicating whether to attach or detach the events.
|
|
21480
|
+
*/
|
|
21053
21481
|
drawStartedEvents(onoff) {
|
|
21054
|
-
console.log("drawStartedEvents");
|
|
21055
21482
|
const onoroff = onoff ? "on" : "off";
|
|
21056
21483
|
this.map[onoroff]("mousemove", this.mouseMove, this);
|
|
21057
21484
|
this.map[onoroff]("mouseup", this.mouseUpLeave, this);
|
|
@@ -21069,8 +21496,58 @@ class Polydraw extends L.Control {
|
|
|
21069
21496
|
}
|
|
21070
21497
|
}
|
|
21071
21498
|
}
|
|
21499
|
+
/**
|
|
21500
|
+
* Attaches or detaches the main drawing event listeners.
|
|
21501
|
+
* @param onoff - A boolean indicating whether to attach or detach the events.
|
|
21502
|
+
*/
|
|
21503
|
+
events(onoff) {
|
|
21504
|
+
const onoroff = onoff ? "on" : "off";
|
|
21505
|
+
this.map[onoroff]("mousedown", this.mouseDown, this);
|
|
21506
|
+
this.map[onoroff]("dblclick", this.handleDoubleClick, this);
|
|
21507
|
+
if (onoff) {
|
|
21508
|
+
this._boundTouchStart = (e) => this.mouseDown(e);
|
|
21509
|
+
this.map.getContainer().addEventListener("touchstart", this._boundTouchStart, { passive: false });
|
|
21510
|
+
} else {
|
|
21511
|
+
if (this._boundTouchStart) {
|
|
21512
|
+
this.map.getContainer().removeEventListener("touchstart", this._boundTouchStart);
|
|
21513
|
+
}
|
|
21514
|
+
}
|
|
21515
|
+
}
|
|
21516
|
+
/**
|
|
21517
|
+
* Handles the mouse down event to start a drawing operation.
|
|
21518
|
+
* @param event - The mouse or touch event.
|
|
21519
|
+
*/
|
|
21520
|
+
mouseDown(event) {
|
|
21521
|
+
if ("cancelable" in event && event.cancelable) {
|
|
21522
|
+
event.preventDefault();
|
|
21523
|
+
}
|
|
21524
|
+
if (this.modeManager.isInOffMode()) {
|
|
21525
|
+
return;
|
|
21526
|
+
}
|
|
21527
|
+
let clickLatLng;
|
|
21528
|
+
if ("latlng" in event && event.latlng) {
|
|
21529
|
+
clickLatLng = event.latlng;
|
|
21530
|
+
} else if ("touches" in event && event.touches && event.touches.length > 0) {
|
|
21531
|
+
clickLatLng = this.map.containerPointToLatLng([
|
|
21532
|
+
event.touches[0].clientX,
|
|
21533
|
+
event.touches[0].clientY
|
|
21534
|
+
]);
|
|
21535
|
+
}
|
|
21536
|
+
if (!clickLatLng) {
|
|
21537
|
+
return;
|
|
21538
|
+
}
|
|
21539
|
+
if (this.modeManager.getCurrentMode() === DrawMode.PointToPoint) {
|
|
21540
|
+
this.polygonDrawManager.handlePointToPointClick(clickLatLng);
|
|
21541
|
+
return;
|
|
21542
|
+
}
|
|
21543
|
+
this.tracer.setLatLngs([clickLatLng]);
|
|
21544
|
+
this.startDraw();
|
|
21545
|
+
}
|
|
21546
|
+
/**
|
|
21547
|
+
* Handles the mouse move event to draw the tracer polyline.
|
|
21548
|
+
* @param event - The mouse or touch event.
|
|
21549
|
+
*/
|
|
21072
21550
|
mouseMove(event) {
|
|
21073
|
-
console.log("mouseMove");
|
|
21074
21551
|
if ("cancelable" in event && event.cancelable) {
|
|
21075
21552
|
event.preventDefault();
|
|
21076
21553
|
}
|
|
@@ -21084,38 +21561,14 @@ class Polydraw extends L.Control {
|
|
|
21084
21561
|
this.tracer.addLatLng(latlng);
|
|
21085
21562
|
}
|
|
21086
21563
|
}
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
|
|
21091
|
-
const result = await this.polygonMutationManager.addPolygon(geoPos, {
|
|
21092
|
-
simplify: true,
|
|
21093
|
-
noMerge: false
|
|
21094
|
-
});
|
|
21095
|
-
if (!result.success) {
|
|
21096
|
-
console.error("Error adding polygon via manager:", result.error);
|
|
21097
|
-
}
|
|
21098
|
-
break;
|
|
21099
|
-
}
|
|
21100
|
-
case DrawMode.Subtract: {
|
|
21101
|
-
const subtractResult = await this.polygonMutationManager.subtractPolygon(geoPos);
|
|
21102
|
-
if (!subtractResult.success) {
|
|
21103
|
-
console.error("Error subtracting polygon via manager:", subtractResult.error);
|
|
21104
|
-
}
|
|
21105
|
-
break;
|
|
21106
|
-
}
|
|
21107
|
-
default:
|
|
21108
|
-
break;
|
|
21109
|
-
}
|
|
21110
|
-
} catch (error) {
|
|
21111
|
-
console.error("Error in mouseUpLeave polygon operation:", error);
|
|
21112
|
-
}
|
|
21113
|
-
}
|
|
21564
|
+
/**
|
|
21565
|
+
* Handles the mouse up event to complete a drawing operation.
|
|
21566
|
+
* @param event - The mouse or touch event.
|
|
21567
|
+
*/
|
|
21114
21568
|
async mouseUpLeave(event) {
|
|
21115
21569
|
if ("cancelable" in event && event.cancelable) {
|
|
21116
21570
|
event.preventDefault();
|
|
21117
21571
|
}
|
|
21118
|
-
console.log("mouseUpLeave");
|
|
21119
21572
|
this.polygonInformation.deletePolygonInformationStorage();
|
|
21120
21573
|
const tracerGeoJSON = this.tracer.toGeoJSON();
|
|
21121
21574
|
if (!tracerGeoJSON || !tracerGeoJSON.geometry || !tracerGeoJSON.geometry.coordinates || tracerGeoJSON.geometry.coordinates.length < 3) {
|
|
@@ -21161,64 +21614,63 @@ class Polydraw extends L.Control {
|
|
|
21161
21614
|
}
|
|
21162
21615
|
this.polygonInformation.createPolygonInformationStorage(this.arrayOfFeatureGroups);
|
|
21163
21616
|
}
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
|
|
21617
|
+
/**
|
|
21618
|
+
* Handles the completion of a freehand drawing operation.
|
|
21619
|
+
* @param geoPos - The GeoJSON feature representing the drawn polygon.
|
|
21620
|
+
*/
|
|
21621
|
+
async handleFreehandDrawCompletion(geoPos) {
|
|
21622
|
+
try {
|
|
21623
|
+
switch (this.modeManager.getCurrentMode()) {
|
|
21624
|
+
case DrawMode.Add: {
|
|
21625
|
+
const result = await this.polygonMutationManager.addPolygon(geoPos, {
|
|
21626
|
+
simplify: true,
|
|
21627
|
+
noMerge: false
|
|
21628
|
+
});
|
|
21629
|
+
if (!result.success) {
|
|
21630
|
+
console.error("Error adding polygon via manager:", result.error);
|
|
21631
|
+
}
|
|
21632
|
+
break;
|
|
21633
|
+
}
|
|
21634
|
+
case DrawMode.Subtract: {
|
|
21635
|
+
const subtractResult = await this.polygonMutationManager.subtractPolygon(geoPos);
|
|
21636
|
+
if (!subtractResult.success) {
|
|
21637
|
+
console.error("Error subtracting polygon via manager:", subtractResult.error);
|
|
21638
|
+
}
|
|
21639
|
+
break;
|
|
21640
|
+
}
|
|
21641
|
+
default:
|
|
21642
|
+
break;
|
|
21175
21643
|
}
|
|
21644
|
+
} catch (error) {
|
|
21645
|
+
console.error("Error in mouseUpLeave polygon operation:", error);
|
|
21176
21646
|
}
|
|
21177
21647
|
}
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
}
|
|
21182
|
-
console.log("mouseDown");
|
|
21183
|
-
if (this.modeManager.isInOffMode()) {
|
|
21184
|
-
return;
|
|
21185
|
-
}
|
|
21186
|
-
let clickLatLng;
|
|
21187
|
-
if ("latlng" in event && event.latlng) {
|
|
21188
|
-
clickLatLng = event.latlng;
|
|
21189
|
-
} else if ("touches" in event && event.touches && event.touches.length > 0) {
|
|
21190
|
-
clickLatLng = this.map.containerPointToLatLng([
|
|
21191
|
-
event.touches[0].clientX,
|
|
21192
|
-
event.touches[0].clientY
|
|
21193
|
-
]);
|
|
21194
|
-
}
|
|
21195
|
-
if (!clickLatLng) {
|
|
21196
|
-
return;
|
|
21197
|
-
}
|
|
21198
|
-
if (this.modeManager.getCurrentMode() === DrawMode.PointToPoint) {
|
|
21199
|
-
this.polygonDrawManager.handlePointToPointClick(clickLatLng);
|
|
21200
|
-
return;
|
|
21201
|
-
}
|
|
21202
|
-
this.tracer.setLatLngs([clickLatLng]);
|
|
21203
|
-
this.startDraw();
|
|
21204
|
-
}
|
|
21648
|
+
/**
|
|
21649
|
+
* Starts a drawing operation by attaching the necessary event listeners.
|
|
21650
|
+
*/
|
|
21205
21651
|
startDraw() {
|
|
21206
|
-
console.log("startDraw");
|
|
21207
21652
|
this.drawStartedEvents(true);
|
|
21208
21653
|
}
|
|
21654
|
+
/**
|
|
21655
|
+
* Sets up the keyboard event handlers for the document.
|
|
21656
|
+
*/
|
|
21209
21657
|
setupKeyboardHandlers() {
|
|
21210
|
-
console.log("setupKeyboardHandlers");
|
|
21211
21658
|
this._boundKeyUpHandler = this.handleKeyUp.bind(this);
|
|
21212
21659
|
document.addEventListener("keydown", this._boundKeyDownHandler);
|
|
21213
21660
|
document.addEventListener("keyup", this._boundKeyUpHandler);
|
|
21214
21661
|
}
|
|
21662
|
+
/**
|
|
21663
|
+
* Removes the keyboard event handlers from the document.
|
|
21664
|
+
*/
|
|
21215
21665
|
removeKeyboardHandlers() {
|
|
21216
|
-
console.log("removeKeyboardHandlers");
|
|
21217
21666
|
document.removeEventListener("keydown", this._boundKeyDownHandler);
|
|
21218
21667
|
document.removeEventListener("keyup", this._boundKeyUpHandler);
|
|
21219
21668
|
}
|
|
21669
|
+
/**
|
|
21670
|
+
* Handles the key down event for keyboard shortcuts.
|
|
21671
|
+
* @param e - The keyboard event.
|
|
21672
|
+
*/
|
|
21220
21673
|
handleKeyDown(e) {
|
|
21221
|
-
console.log("handleKeyDown");
|
|
21222
21674
|
if (e.key === "Escape") {
|
|
21223
21675
|
if (this.modeManager.getCurrentMode() === DrawMode.PointToPoint) {
|
|
21224
21676
|
this.polygonDrawManager.cancelPointToPointDrawing();
|
|
@@ -21231,8 +21683,11 @@ class Polydraw extends L.Control {
|
|
|
21231
21683
|
this.updateAllMarkersForEdgeDeletion(true);
|
|
21232
21684
|
}
|
|
21233
21685
|
}
|
|
21686
|
+
/**
|
|
21687
|
+
* Handles the key up event for keyboard shortcuts.
|
|
21688
|
+
* @param e - The keyboard event.
|
|
21689
|
+
*/
|
|
21234
21690
|
handleKeyUp(e) {
|
|
21235
|
-
console.log("handleKeyUp");
|
|
21236
21691
|
const isModifierPressed = this.isModifierKeyPressed(e);
|
|
21237
21692
|
if (!isModifierPressed && this.isModifierKeyHeld) {
|
|
21238
21693
|
this.isModifierKeyHeld = false;
|
|
@@ -21244,7 +21699,6 @@ class Polydraw extends L.Control {
|
|
|
21244
21699
|
* Update all markers to show/hide edge deletion visual feedback
|
|
21245
21700
|
*/
|
|
21246
21701
|
updateAllMarkersForEdgeDeletion(showFeedback) {
|
|
21247
|
-
console.log("updateAllMarkersForEdgeDeletion");
|
|
21248
21702
|
this.arrayOfFeatureGroups.forEach((featureGroup) => {
|
|
21249
21703
|
featureGroup.eachLayer((layer) => {
|
|
21250
21704
|
if (layer instanceof L.Marker) {
|
|
@@ -21257,7 +21711,6 @@ class Polydraw extends L.Control {
|
|
|
21257
21711
|
* Update individual marker for edge deletion visual feedback
|
|
21258
21712
|
*/
|
|
21259
21713
|
updateMarkerForEdgeDeletion(marker, showFeedback) {
|
|
21260
|
-
console.log("updateMarkerForEdgeDeletion");
|
|
21261
21714
|
const element = marker.getElement();
|
|
21262
21715
|
if (!element) return;
|
|
21263
21716
|
if (showFeedback) {
|
|
@@ -21270,8 +21723,11 @@ class Polydraw extends L.Control {
|
|
|
21270
21723
|
element.style.borderColor = "";
|
|
21271
21724
|
}
|
|
21272
21725
|
}
|
|
21726
|
+
/**
|
|
21727
|
+
* Handles the double-click event for point-to-point drawing.
|
|
21728
|
+
* @param e - The mouse event.
|
|
21729
|
+
*/
|
|
21273
21730
|
handleDoubleClick(e) {
|
|
21274
|
-
console.log("handleDoubleClick");
|
|
21275
21731
|
if (this.modeManager.getCurrentMode() !== DrawMode.PointToPoint) {
|
|
21276
21732
|
return;
|
|
21277
21733
|
}
|
|
@@ -21281,7 +21737,6 @@ class Polydraw extends L.Control {
|
|
|
21281
21737
|
* Detect if modifier key is pressed (Ctrl on Windows/Linux, Cmd on Mac)
|
|
21282
21738
|
*/
|
|
21283
21739
|
isModifierKeyPressed(event) {
|
|
21284
|
-
console.log("isModifierKeyPressed");
|
|
21285
21740
|
const userAgent = navigator.userAgent.toLowerCase();
|
|
21286
21741
|
const isMac = userAgent.includes("mac");
|
|
21287
21742
|
if (isMac) {
|
|
@@ -21290,6 +21745,9 @@ class Polydraw extends L.Control {
|
|
|
21290
21745
|
return event.ctrlKey;
|
|
21291
21746
|
}
|
|
21292
21747
|
}
|
|
21748
|
+
/**
|
|
21749
|
+
* Updates the visual indicator on the activate button to show if there are active polygons.
|
|
21750
|
+
*/
|
|
21293
21751
|
updateActivateButtonIndicator() {
|
|
21294
21752
|
if (typeof this.getContainer !== "function") {
|
|
21295
21753
|
return;
|