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.
@@ -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" }, "subtractColor": "#D9460F", "hideMarkersOnDrag": true } };
11
- const edgeDeletion = { "enabled": true, "modifierKey": "auto", "hoverColor": "#D9460F", "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 }, "visualOptimization": { "sharpAngleThreshold": 30, "thresholdBoundingBox": 0.05, "thresholdDistance": 0.05, "useDistance": true, "useBoundingBox": false, "useAngles": false } };
13
- const polyLineOptions = { "color": "#50622b", "opacity": 1, "smoothFactor": 0, "noClip": true, "clickable": false, "weight": 2 };
14
- const subtractLineOptions = { "color": "#50622b", "opacity": 1, "smoothFactor": 0, "noClip": true, "clickable": false, "weight": 2 };
15
- const polygonOptions = { "smoothFactor": 0.3, "color": "#50622b", "fillColor": "#b4cd8a", "noClip": true };
16
- const holeOptions = { "color": "#aa0000", "fillColor": "#ffcccc", "weight": 2, "opacity": 1, "fillOpacity": 0.5 };
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 coords1 = getCoords(polygon2);
15882
- const coords2 = getCoords(latlngs);
15883
- for (const ring2 of coords2) {
15884
- for (const coord of ring2[0]) {
15885
- const point$1 = point(coord);
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 ring1 of coords1) {
15892
- for (const coord of ring1[0]) {
15893
- const point$1 = point(coord);
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
- const coordinates = newPoly.geometry.coordinates[0][0];
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
- const coordinates = newPoly.geometry.coordinates[0];
16021
- let minDistance = Infinity;
16022
- let insertIndex = 0;
16023
- for (let i = 0; i < coordinates.length - 1; i++) {
16024
- const edgeStart = coordinates[i];
16025
- const edgeEnd = coordinates[i + 1];
16026
- const distance2 = this.distanceToLineSegment(point2, edgeStart, edgeEnd);
16027
- if (distance2 < minDistance) {
16028
- minDistance = distance2;
16029
- insertIndex = i + 1;
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
- (_a2 = this.eventListeners.get(event)) == null ? void 0 : _a2.push(callback);
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
- if (this.eventListeners.has(event)) {
17301
- const listeners = this.eventListeners.get(event);
17302
- if (listeners) {
17303
- const index = listeners.indexOf(callback);
17304
- if (index > -1) {
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) => callback(data));
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
- console.log("PolygonDrawManager constructor");
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 = "#4CAF50";
17633
- element.style.borderColor = "#4CAF50";
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.polyLineOptions.color,
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 = "#4CAF50";
17838
- element2.style.borderColor = "#4CAF50";
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._polydrawModifierHandler = checkModifierAndUpdate;
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._polydrawModifierHandler;
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 marker._polydrawModifierHandler;
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.isPolygonCompletelyWithin(point2, polygon1)) {
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.isPolygonCompletelyWithin(point2, polygon2)) {
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 shouldCreateDonut = this.shouldCreateDonutPolygon(result, polygon2);
17985
- if (shouldCreateDonut) {
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.detectModifierKey(eventToCheck);
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 = "#D9460F";
18480
- element.style.borderColor = "#D9460F";
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._polydrawFeatureGroup = featureGroup;
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._polydrawFeatureGroup;
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("touchstart", (e) => {
18573
- console.log("marker touchstart");
18574
- e.stopPropagation();
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._polydrawFeatureGroup;
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.isModifierKeyPressed(e.originalEvent)) {
18692
- const poly = (_a2 = featureGroup.getLayers().find((layer) => layer instanceof L.Polygon)) == null ? void 0 : _a2.toGeoJSON();
18693
- if (poly) {
18694
- this.elbowClicked(e, poly);
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
- console.log("PolygonInteractionManager addHoleMarkers");
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
- const iconClasses = this.config.markers.holeIcon.styleClasses;
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: true,
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 el = marker.getElement();
18731
- if (el) el.style.pointerEvents = "auto";
18828
+ const el2 = marker.getElement();
18829
+ if (el2) el2.style.pointerEvents = "auto";
18732
18830
  });
18733
18831
  marker.on("click", (e) => {
18734
- var _a2, _b2;
18735
- (_b2 = (_a2 = e.originalEvent) == null ? void 0 : _a2.stopPropagation) == null ? void 0 : _b2.call(_a2);
18736
- L.DomEvent.stopPropagation(e);
18737
- });
18738
- marker.on("dragend", (e) => {
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("drag", (e) => {
18742
- this.markerDrag(featureGroup);
18838
+ marker.on("dragstart", () => {
18839
+ this.isDraggingMarker = true;
18840
+ this._activeMarker = marker;
18743
18841
  });
18744
18842
  marker.on("dragend", (e) => {
18745
- this.markerDragEnd(featureGroup);
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
- * Add edge click listeners to a polygon
18751
- */
18752
- addEdgeClickListeners(polygon2, featureGroup) {
18753
- console.log("PolygonInteractionManager addEdgeClickListeners");
18754
- const rawLatLngs = polygon2.getLatLngs();
18755
- let processedRings;
18756
- if (Array.isArray(rawLatLngs) && rawLatLngs.length > 0) {
18757
- if (Array.isArray(rawLatLngs[0])) {
18758
- if (Array.isArray(rawLatLngs[0][0]) && rawLatLngs[0][0].length > 0) {
18759
- const firstCoord = rawLatLngs[0][0][0];
18760
- if (firstCoord && typeof firstCoord === "object" && "lat" in firstCoord) {
18761
- processedRings = rawLatLngs[0];
18762
- } else {
18763
- processedRings = rawLatLngs[0];
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
- } else if (rawLatLngs[0][0] && typeof rawLatLngs[0][0] === "object" && "lat" in rawLatLngs[0][0]) {
18766
- processedRings = rawLatLngs;
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
- } else {
18776
- return;
18777
- }
18778
- processedRings.forEach((ring, ringIndex) => {
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
- const edgePolyline = L.polyline([edgeStart, edgeEnd], {
18786
- color: "transparent",
18787
- weight: 10,
18788
- opacity: 0,
18789
- interactive: true
18790
- });
18791
- edgePolyline._polydrawEdgeInfo = {
18792
- ringIndex,
18793
- edgeIndex: i,
18794
- startPoint: edgeStart,
18795
- endPoint: edgeEnd,
18796
- parentPolygon: polygon2,
18797
- parentFeatureGroup: featureGroup
18798
- };
18799
- edgePolyline.on("click", (e) => {
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.detectModifierKey(e.originalEvent || e);
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(poly, [
18958
- newPoint.lng,
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: "#7a9441",
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, poly) {
18994
- console.log("elbowClicked");
18995
- if (!this.config.modes.edgeDeletion) {
18996
- return;
18997
- }
18998
- if (!this.isModifierKeyPressed(e.originalEvent)) {
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 ringIndex = 0; ringIndex < allRings.length; ringIndex++) {
19006
- const ring = allRings[ringIndex];
19007
- const vertexIndex = ring.findIndex(
19008
- (coord) => Math.abs(coord[1] - clickedLatLng.lat) < 1e-4 && Math.abs(coord[0] - clickedLatLng.lng) < 1e-4
19009
- );
19010
- if (vertexIndex !== -1) {
19011
- targetRingIndex = ringIndex;
19012
- targetVertexIndex = vertexIndex;
19013
- break;
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 = allRings[targetRingIndex];
19020
- if (targetRing.length <= 4) {
19294
+ const targetRing = rings[targetRingIndex];
19295
+ if (targetRing.length <= 3) {
19021
19296
  return;
19022
19297
  }
19023
- const newAllRings = allRings.map((ring, ringIndex) => {
19024
- if (ringIndex === targetRingIndex) {
19025
- const newRing = [...ring];
19026
- newRing.splice(targetVertexIndex, 1);
19027
- return newRing;
19028
- } else {
19029
- return [...ring];
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
- const currentFeatureGroup = this.findFeatureGroupForPoly(poly);
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([newAllRings]);
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 (JSON.stringify(feature2.geometry.coordinates) === JSON.stringify(poly.geometry.coordinates)) {
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 layerLength = featureGroup.getLayers();
19065
- const posarrays = layerLength[0].getLatLngs();
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 = layerLength.filter((layer) => layer instanceof L.Marker);
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][0].length;
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
- layerLength[0].setLatLngs(newPos);
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.coordinates.length > 1) {
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
- (coord) => this.offsetPolygonCoordinates(coord, offsetLat, offsetLng)
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
- polygon2._polydrawOriginalHoleLinePositions.set(layer, layer.getLatLngs());
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
- const newLatLngs = originalPositions.map((latlng) => ({
19258
- lat: latlng.lat + offsetLat,
19259
- lng: latlng.lng + offsetLng
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
- detectModifierKey(event) {
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 userAgent = navigator.userAgent.toLowerCase();
19312
- const isMac = userAgent.includes("mac");
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.modifierSubtract.subtractColor
19609
+ color: this.config.colors.dragPolygons.subtract
19328
19610
  });
19329
19611
  } else {
19330
19612
  polygon2.setStyle({
19331
- color: this.config.polygonOptions.color
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.modifierSubtract.subtractColor;
19366
- element.style.borderColor = this.config.dragPolygons.modifierSubtract.subtractColor;
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
- console.log("PolygonInteractionManager handleModifierToggleDuringDrag");
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.coordinates.length > 0) {
19420
- intersectingFeatureGroups.push(featureGroup);
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
- isModifierKeyPressed(event) {
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
- if (isMac) {
19488
- return event.metaKey;
19489
- } else {
19490
- return event.ctrlKey;
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
- var _a2, _b2, _c, _d;
19500
- const isModifierPressed = this.detectModifierKey(e);
19790
+ const isModifierPressed = this.isEdgeDeletionModifierKeyPressed(e);
19501
19791
  if (isModifierPressed) {
19502
- element.style.backgroundColor = ((_b2 = (_a2 = this.config.dragPolygons) == null ? void 0 : _a2.modifierSubtract) == null ? void 0 : _b2.subtractColor) || "#D9460F";
19503
- element.style.borderColor = ((_d = (_c = this.config.dragPolygons) == null ? void 0 : _c.modifierSubtract) == null ? void 0 : _d.subtractColor) || "#D9460F";
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._polydrawModifierHandler = checkModifierAndUpdate;
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._polydrawModifierHandler;
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 marker._polydrawModifierHandler;
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(targetPoint, fc);
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: "menu-popup"
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
- console.warn("Error getting polygon GeoJSON from feature group:", error.message);
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
- console.warn("Error calculating total polygon perimeter:", error.message);
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: "info-popup"
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 { action, latLngs, featureGroup } = data;
19982
- const completePolygonGeoJSON = this.getCompletePolygonFromFeatureGroup(featureGroup);
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 { simplify: simplify3 = true, noMerge = false } = options;
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.holeOptions.color,
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.length > 1) {
20210
- firstFeature.geometry.coordinates.forEach((element) => {
20211
- try {
20212
- const feature2 = this.turfHelper.getMultiPolygon([element]);
20213
- polyIntersection = this.geometryManager.checkPolygonIntersection(feature2, latlngs);
20214
- if (polyIntersection) {
20215
- intersectingFeatureGroups.push(featureGroup);
20216
- polygonFeature.push(feature2);
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(this.config.polygonOptions);
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) || 0,
20486
- delete: ((_b2 = markers2.delete) == null ? void 0 : _b2.index) || 1,
20487
- info: ((_c = markers2.info) == null ? void 0 : _c.index) || 2
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
- * Handle marker hover when modifier key is held - event handler version
20954
+ * Updates map interactions based on the current drawing mode.
20621
20955
  */
20622
- __publicField(this, "onMarkerHoverForEdgeDeletionEvent", (e) => {
20623
- console.log("onMarkerHoverForEdgeDeletionEvent");
20624
- if (!this.isModifierKeyHeld) return;
20625
- const element = e.target;
20626
- if (element) {
20627
- element.style.backgroundColor = "#D9460F";
20628
- element.style.borderColor = "#D9460F";
20629
- element.classList.add("edge-deletion-hover");
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
- * Handle marker leave when modifier key is held - event handler version
20634
- */
20635
- __publicField(this, "onMarkerLeaveForEdgeDeletionEvent", (e) => {
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
- this.config = defaultConfig;
20645
- if (options == null ? void 0 : options.configPath) {
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
- const onSubtractClick = (e) => {
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
- const onEraseClick = (e) => {
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
- const onPointToPointClick = (e) => {
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
- onActivateToggle,
20793
- onDrawClick,
20794
- onSubtractClick,
20795
- onEraseClick,
20796
- onPointToPointClick
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
- this.tracer = L.polyline([], this.config.polyLineOptions);
20806
- try {
20807
- this.tracer.addTo(this.map);
20808
- } catch (error) {
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
- addTo(map) {
20872
- console.log("addTo");
20873
- super.addTo(map);
20874
- return this;
20875
- }
20876
- getFeatureGroups() {
20877
- return this.arrayOfFeatureGroups;
20878
- }
20879
- onRemove(_map) {
20880
- console.log("onRemove");
20881
- this.removeKeyboardHandlers();
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
- async addPredefinedPolygon(geographicBorders, options) {
20888
- console.log("addPredefinedPolygon");
20889
- if (!geographicBorders || geographicBorders.length === 0) {
20890
- throw new Error("Cannot add empty polygon array");
20891
- }
20892
- if (!this.map) {
20893
- throw new Error("Map not initialized");
20894
- }
20895
- if (!this.polygonMutationManager) {
20896
- throw new Error("PolygonMutationManager not initialized");
20897
- }
20898
- const visualOptimizationLevel = (options == null ? void 0 : options.visualOptimizationLevel) ?? 0;
20899
- for (const [groupIndex, group] of geographicBorders.entries()) {
20900
- if (!group || !group[0] || group[0].length < 4) {
20901
- throw new Error(
20902
- `Invalid polygon data at index ${groupIndex}: A polygon must have at least 3 unique vertices.`
20903
- );
20904
- }
20905
- try {
20906
- const coords = group.map((ring) => ring.map((latlng) => [latlng.lng, latlng.lat]));
20907
- const polygon2 = this.turfHelper.getMultiPolygon([coords]);
20908
- const result = await this.polygonMutationManager.addPolygon(polygon2, {
20909
- simplify: false,
20910
- noMerge: false,
20911
- visualOptimizationLevel
20912
- });
20913
- if (!result.success) {
20914
- console.error("Error adding polygon via manager:", result.error);
20915
- throw new Error(result.error || "Failed to add polygon");
20916
- }
20917
- this.polygonInformation.createPolygonInformationStorage(this.arrayOfFeatureGroups);
20918
- } catch (error) {
20919
- console.error("Error adding auto polygon:", error);
20920
- throw error;
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
- setDrawMode(mode) {
20925
- console.log("setDrawMode");
20926
- const previousMode = this.drawMode;
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
- if (previousMode === DrawMode.PointToPoint && mode !== DrawMode.PointToPoint) {
20932
- this.polygonDrawManager.clearP2pMarkers();
20933
- this.stopDraw();
20934
- } else if (mode === DrawMode.Off) {
20935
- this.stopDraw();
20936
- } else if (mode !== DrawMode.PointToPoint) {
20937
- this.stopDraw();
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
- if (this.map) {
20940
- const shouldShowCrosshair = this.modeManager.shouldShowCrosshairCursor();
20941
- const mapDragEnabled = this.modeManager.canPerformAction("mapDrag");
20942
- const mapZoomEnabled = this.modeManager.canPerformAction("mapZoom");
20943
- const mapDoubleClickEnabled = this.modeManager.canPerformAction("mapDoubleClickZoom");
20944
- if (shouldShowCrosshair) {
20945
- L.DomUtil.addClass(this.map.getContainer(), "crosshair-cursor-enabled");
20946
- } else {
20947
- L.DomUtil.removeClass(this.map.getContainer(), "crosshair-cursor-enabled");
20948
- }
20949
- this.events(mode !== DrawMode.Off);
20950
- try {
20951
- switch (mode) {
20952
- case DrawMode.Off:
20953
- this.tracer.setStyle({ color: "" });
20954
- break;
20955
- case DrawMode.Add:
20956
- this.tracer.setStyle({
20957
- color: defaultConfig.polyLineOptions.color,
20958
- dashArray: null
20959
- // Reset to solid line
20960
- });
20961
- break;
20962
- case DrawMode.Subtract:
20963
- this.tracer.setStyle({
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
- this.setLeafletMapEvents(mapDragEnabled, mapDoubleClickEnabled, mapZoomEnabled);
21395
+ } catch (error) {
20979
21396
  }
20980
21397
  }
20981
- getDrawMode() {
20982
- console.log("getDrawMode");
20983
- return this.modeManager.getCurrentMode();
20984
- }
20985
- on(event, callback) {
20986
- this.eventManager.on(event, callback);
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
- off(event, callback) {
20989
- this.eventManager.off(event, callback);
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
- removeAllFeatureGroups() {
21026
- console.log("removeAllFeatureGroups");
21027
- this.arrayOfFeatureGroups.forEach((featureGroups) => {
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
- async handleFreehandDrawCompletion(geoPos) {
21088
- try {
21089
- switch (this.modeManager.getCurrentMode()) {
21090
- case DrawMode.Add: {
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
- events(onoff) {
21165
- console.log("events");
21166
- const onoroff = onoff ? "on" : "off";
21167
- this.map[onoroff]("mousedown", this.mouseDown, this);
21168
- this.map[onoroff]("dblclick", this.handleDoubleClick, this);
21169
- if (onoff) {
21170
- this._boundTouchStart = (e) => this.mouseDown(e);
21171
- this.map.getContainer().addEventListener("touchstart", this._boundTouchStart, { passive: false });
21172
- } else {
21173
- if (this._boundTouchStart) {
21174
- this.map.getContainer().removeEventListener("touchstart", this._boundTouchStart);
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
- mouseDown(event) {
21179
- if ("cancelable" in event && event.cancelable) {
21180
- event.preventDefault();
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;