Przeglądaj źródła

补充椭圆和双箭头

xushiting 2 lat temu
rodzic
commit
c1717c2b17
82 zmienionych plików z 717 dodań i 190 usunięć
  1. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684981380403427.jpg
  2. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684981392379423.jpg
  3. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684981690823299.jpg
  4. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684981813727847.jpg
  5. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/168498185190750.jpg
  6. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982521536513.jpg
  7. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/168498258354861.jpg
  8. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982602345927.jpg
  9. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982614404900.jpg
  10. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982630441428.jpg
  11. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982775481202.jpg
  12. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982783718721.jpg
  13. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982797389788.jpg
  14. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982808361415.jpg
  15. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982817640326.jpg
  16. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684982846992359.jpg
  17. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1684983189514979.jpg
  18. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685090734679518.jpg
  19. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685090766602910.jpg
  20. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685090842465745.jpg
  21. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685090971141498.jpg
  22. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092161846986.jpg
  23. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092358147452.jpg
  24. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092384554366.jpg
  25. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092398313152.jpg
  26. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092454347433.jpg
  27. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092513558194.jpg
  28. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685092558520358.jpg
  29. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685093031491241.jpg
  30. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685093083403734.jpg
  31. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/168509740548985.jpg
  32. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685321643447385.jpg
  33. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685326881979122.jpg
  34. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685409351535271.jpg
  35. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685419555245870.jpg
  36. BIN
      server/test/SS-t-P1d6CwREny2/attach/upload/1685518326422647.jpg
  37. 1 1
      server/test/a0k4xu045_202305311600080410/attach/sceneStore
  38. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685588337649731.jpg
  39. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685588346747547.jpg
  40. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685589935435527.jpg
  41. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685605180660219.jpg
  42. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685605201633510.jpg
  43. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685606643779840.jpg
  44. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685611746481601.jpg
  45. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685611922011238.jpg
  46. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685611958579479.jpg
  47. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685612025771148.jpg
  48. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685612108390263.jpg
  49. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/168561374297373.jpg
  50. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685676756774549.jpg
  51. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1685698112862240.jpg
  52. BIN
      server/test/a0k4xu045_202305311600080410/attach/upload/1686042790901717.jpg
  53. 26 15
      src/graphic/CanvasStyle/default.js
  54. 17 11
      src/graphic/CanvasStyle/focus.js
  55. 15 12
      src/graphic/CanvasStyle/select.js
  56. 1 1
      src/graphic/Controls/AddCircle.js
  57. 52 0
      src/graphic/Controls/AddElliptic.js
  58. 2 1
      src/graphic/Controls/AddLine.js
  59. 82 0
      src/graphic/Controls/MoveElliptic.js
  60. 9 0
      src/graphic/Controls/UIControl.js
  61. 63 0
      src/graphic/Geometry/Elliptic.js
  62. 1 1
      src/graphic/Geometry/Line.js
  63. 2 2
      src/graphic/Geometry/SVG.js
  64. 44 0
      src/graphic/History/Change.js
  65. 47 0
      src/graphic/History/History.js
  66. 53 6
      src/graphic/History/HistoryUtil.js
  67. 81 2
      src/graphic/Layer.js
  68. 82 113
      src/graphic/ListenLayer.js
  69. 20 18
      src/graphic/Renderer/Draw.js
  70. 8 0
      src/graphic/Renderer/Render.js
  71. 15 0
      src/graphic/Service/CurvePointService.js
  72. 19 1
      src/graphic/Service/DataService.js
  73. 37 0
      src/graphic/Service/EllipticService.js
  74. 1 0
      src/graphic/Service/StateService.js
  75. 5 2
      src/graphic/Service/UIService.js
  76. 13 0
      src/graphic/Util/MathUtil.js
  77. 4 0
      src/graphic/enum/HistoryEvents.js
  78. 4 0
      src/graphic/enum/LayerEvents.js
  79. 4 0
      src/graphic/enum/SVGType.js
  80. 4 2
      src/graphic/enum/UIEvents.js
  81. 2 1
      src/graphic/enum/VectorCategory.js
  82. 3 1
      src/graphic/enum/VectorType.js

BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684981380403427.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684981392379423.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684981690823299.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684981813727847.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/168498185190750.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982521536513.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/168498258354861.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982602345927.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982614404900.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982630441428.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982775481202.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982783718721.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982797389788.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982808361415.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982817640326.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684982846992359.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1684983189514979.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685090734679518.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685090766602910.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685090842465745.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685090971141498.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092161846986.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092358147452.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092384554366.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092398313152.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092454347433.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092513558194.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685092558520358.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685093031491241.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685093083403734.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/168509740548985.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685321643447385.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685326881979122.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685409351535271.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685419555245870.jpg


BIN
server/test/SS-t-P1d6CwREny2/attach/upload/1685518326422647.jpg


Plik diff jest za duży
+ 1 - 1
server/test/a0k4xu045_202305311600080410/attach/sceneStore


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685588337649731.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685588346747547.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685589935435527.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685605180660219.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685605201633510.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685606643779840.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685611746481601.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685611922011238.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685611958579479.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685612025771148.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685612108390263.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/168561374297373.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685676756774549.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1685698112862240.jpg


BIN
server/test/a0k4xu045_202305311600080410/attach/upload/1686042790901717.jpg


+ 26 - 15
src/graphic/CanvasStyle/default.js

@@ -1,4 +1,4 @@
-import { coordinate } from '../Coordinate.js'
+import { coordinate } from "../Coordinate.js";
 
 const Road = {
   strokeStyle: "#939393",
@@ -18,7 +18,12 @@ const Lane = {
   dash: [8 * coordinate.ratio, 8 * coordinate.ratio],
 };
 
-const ArrowLine = {
+const SingleArrowLine = {
+  lineWidth: 2 * coordinate.ratio,
+  strokeStyle: "red",
+};
+
+const DoubleArrowLine = {
   lineWidth: 2 * coordinate.ratio,
   strokeStyle: "red",
 };
@@ -98,6 +103,13 @@ const Circle = {
   radius: 30 * coordinate.ratio,
 };
 
+const Elliptic = {
+  strokeStyle: "red",
+  fillStyle: "rgba(0,0,0,0)",
+  lineWidth: 2 * coordinate.ratio,
+  radius: 30 * coordinate.ratio,
+};
+
 const Measure = {
   txt: "rgba(255,255,255,1)", //画墙/选墙的时候 测量值的颜色
   strokeStyle: "rgba(255,255,255,1)",
@@ -109,8 +121,8 @@ const NormalLine = {
   lineWidth: 2 * coordinate.ratio,
 };
 const CurveLine = {
-  ...NormalLine
-}
+  ...NormalLine,
+};
 
 const GuideLine = {
   strokeStyle: "#CED806",
@@ -124,7 +136,7 @@ const MeasureLine = {
     fontSize: 12,
     fillColor: "#fff",
     padding: 6 * coordinate.ratio,
-    backColor: "#2F8FFF"
+    backColor: "#2F8FFF",
   },
 };
 const BaseLine = {
@@ -142,8 +154,8 @@ const BasePoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 1 * coordinate.ratio,
-  }
-}
+  },
+};
 
 const Element = {
   AddingPoint: {
@@ -176,7 +188,6 @@ const Element = {
   },
 };
 
-
 const TestPoint = {
   strokeStyle: "rgba(0,0,0,0)",
   fillStyle: "#fff",
@@ -187,16 +198,14 @@ const TestPoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 3 * coordinate.ratio,
-  }
-}
+  },
+};
 
 const SVG = {
   fillStyle: "rgba(0,0,0,0)",
   strokeStyle: "black",
-  lineWidth: 2 * coordinate.ratio
-}
-
-
+  lineWidth: 2 * coordinate.ratio,
+};
 
 export default {
   NormalLine,
@@ -210,6 +219,7 @@ export default {
   Point,
   BaseLine,
   Circle,
+  Elliptic,
   Text,
   CrossPoint,
   CurveLine,
@@ -223,7 +233,8 @@ export default {
   Element,
   TestPoint,
   RoadPoint,
-  ArrowLine,
+  SingleArrowLine,
+  DoubleArrowLine,
   BasePoint,
   bgColor: "#fff",
 };

+ 17 - 11
src/graphic/CanvasStyle/focus.js

@@ -1,5 +1,5 @@
 import def from "./default.js";
-import {coordinate} from "@/graphic/Coordinate.js";
+import { coordinate } from "@/graphic/Coordinate.js";
 
 const Road = {
   ...def.Road,
@@ -20,7 +20,7 @@ const MeasureLine = {
     fontSize: 12,
     fillColor: "#fff",
     padding: 6 * coordinate.ratio,
-    backColor: "red"
+    backColor: "red",
   },
 };
 const NormalLine = {
@@ -80,7 +80,13 @@ const CurveRoadEdge = {
   lineWidth: 2 * coordinate.ratio,
   strokeStyle: "#3290FF",
 };
-const ArrowLine = {
+
+const SingleArrowLine = {
+  lineWidth: 2 * coordinate.ratio,
+  strokeStyle: "red",
+};
+
+const DoubleArrowLine = {
   lineWidth: 2 * coordinate.ratio,
   strokeStyle: "red",
 };
@@ -95,9 +101,8 @@ const BasePoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 1 * coordinate.ratio,
-  }
-}
-
+  },
+};
 
 const TestPoint = {
   strokeStyle: "rgba(0,0,0,0)",
@@ -109,8 +114,8 @@ const TestPoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 3 * coordinate.ratio,
-  }
-}
+  },
+};
 const BaseLine = {
   strokeStyle: "#3290FF",
   lineWidth: 1 * coordinate.ratio,
@@ -119,8 +124,8 @@ const BaseLine = {
 const SVG = {
   fillStyle: "rgba(50,144,255,0.2)",
   strokeStyle: "black",
-  lineWidth: 2 * coordinate.ratio
-}
+  lineWidth: 2 * coordinate.ratio,
+};
 
 export default {
   Road,
@@ -128,7 +133,8 @@ export default {
   BasePoint,
   Point,
   SVG,
-  ArrowLine,
+  SingleArrowLine,
+  DoubleArrowLine,
   RoadPoint,
   CurveRoadPoint,
   CrossPoint,

+ 15 - 12
src/graphic/CanvasStyle/select.js

@@ -1,5 +1,5 @@
 import def from "./default.js";
-import {coordinate} from "@/graphic/Coordinate.js";
+import { coordinate } from "@/graphic/Coordinate.js";
 
 const Road = {
   ...def.Road,
@@ -20,7 +20,7 @@ const MeasureLine = {
     fontSize: 12,
     fillColor: "#fff",
     padding: 6 * coordinate.ratio,
-    backColor: "red"
+    backColor: "red",
   },
 };
 
@@ -38,7 +38,11 @@ const CurveLine = {
   lineWidth: 2 * coordinate.ratio,
   strokeStyle: "#3290FF",
 };
-const ArrowLine = {
+const SingleArrowLine = {
+  lineWidth: 2 * coordinate.ratio,
+  strokeStyle: "red",
+};
+const DoubleArrowLine = {
   lineWidth: 2 * coordinate.ratio,
   strokeStyle: "red",
 };
@@ -95,8 +99,8 @@ const BasePoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 1 * coordinate.ratio,
-  }
-}
+  },
+};
 
 const TestPoint = {
   strokeStyle: "rgba(0,0,0,0)",
@@ -108,16 +112,14 @@ const TestPoint = {
     fillStyle: "rgba(255,255,255,0)",
     radius: 8 * coordinate.ratio,
     lineWidth: 3 * coordinate.ratio,
-  }
-}
-
+  },
+};
 
 const SVG = {
   fillStyle: "rgba(50,144,255,0.2)",
   strokeStyle: "black",
-  lineWidth: 2 * coordinate.ratio
-}
-
+  lineWidth: 2 * coordinate.ratio,
+};
 
 export default {
   Road,
@@ -137,5 +139,6 @@ export default {
   RoadEdge,
   NormalLine,
   CurveRoadEdge,
-  ArrowLine,
+  SingleArrowLine,
+  DoubleArrowLine,
 };

+ 1 - 1
src/graphic/Controls/AddCircle.js

@@ -29,7 +29,7 @@ export default class AddCircle {
 
   finish(position) {
     if (this.newCircle != null && mathUtil.equalPoint(this.center, position)) {
-      dataService.deleteLine(this.newLine.vectorId);
+      dataService.deleteCircle(this.newCircle.vectorId);
     }
   }
 

+ 52 - 0
src/graphic/Controls/AddElliptic.js

@@ -0,0 +1,52 @@
+import { mathUtil } from "../Util/MathUtil";
+import { ellipticService } from "../Service/EllipticService";
+import { listenLayer } from "../ListenLayer";
+
+export default class AddElliptic {
+  constructor() {
+    this.newElliptic = null;
+    this.center = null;
+  }
+
+  setCenter(value) {
+    this.center = {};
+    mathUtil.clonePoint(this.center, value);
+  }
+
+  buildElliptic(position) {
+    if (
+      this.newElliptic == null &&
+      !mathUtil.equalPoint(this.center, position)
+    ) {
+      const radius = mathUtil.getDistance(this.center, position);
+      this.newElliptic = ellipticService.create(this.center, radius, radius);
+    }
+  }
+
+  // updateElliptic(position, index) {
+  //   if (
+  //     this.newElliptic != null &&
+  //     !mathUtil.equalPoint(this.center, position)
+  //   ) {
+  //     this.newElliptic.setRadius(mathUtil.getDistance(this.center, position));
+  //     this.newElliptic.createPoints();
+  //   }
+  // }
+
+  finish(position) {
+    if (
+      this.newElliptic != null &&
+      mathUtil.equalPoint(this.center, position)
+    ) {
+      dataService.deleteElliptic(this.newElliptic.vectorId);
+    }
+  }
+
+  clear() {
+    this.newElliptic = null;
+    this.center = null;
+  }
+}
+
+const addElliptic = new AddElliptic();
+export { addElliptic };

+ 2 - 1
src/graphic/Controls/AddLine.js

@@ -59,7 +59,8 @@ export default class AddLine {
       } else if (
         listenLayer.modifyPoint &&
         listenLayer.modifyPoint.linkedPointId &&
-        this.newLine.getCategory() != VectorCategory.Line.ArrowLine &&
+        this.newLine.getCategory() != VectorCategory.Line.SingleArrowLine &&
+        this.newLine.getCategory() != VectorCategory.Line.DoubleArrowLine &&
         this.newLine.getCategory() != VectorCategory.Line.GuideLine
       ) {
         pointService.mergePoint(

+ 82 - 0
src/graphic/Controls/MoveElliptic.js

@@ -0,0 +1,82 @@
+import { dataService } from "../Service/DataService";
+import { mathUtil } from "../Util/MathUtil";
+import Constant from "../Constant.js";
+
+export default class MoveElliptic {
+  constructor() {}
+
+  moveFull(ellipticId, dx, dy) {
+    dx = dx;
+    dy = -dy;
+    let elliptic = dataService.getElliptic(ellipticId);
+    elliptic.center.x += dx;
+    elliptic.center.y += dy;
+    elliptic.createPoints();
+  }
+
+  movePoint(position, ellipticId, pointIndex) {
+    let elliptic = dataService.getElliptic(ellipticId);
+    let flag = this.check(position, elliptic.center, pointIndex);
+    if (flag) {
+      const lineA = mathUtil.createLine1(
+        elliptic.points[2],
+        elliptic.points[3]
+      );
+      const lineB = mathUtil.createLine1(
+        elliptic.points[0],
+        elliptic.points[1]
+      );
+
+      let join, distance;
+      if (pointIndex == 0) {
+        join = mathUtil.getJoinLinePoint(position, lineB);
+        distance = mathUtil.getDistance(join, elliptic.center);
+        elliptic.points[pointIndex].y = elliptic.center.y + distance;
+        elliptic.points[1].y = elliptic.center.y - distance;
+        elliptic.setRadiusY(distance);
+      } else if (pointIndex == 1) {
+        join = mathUtil.getJoinLinePoint(position, lineB);
+        distance = mathUtil.getDistance(join, elliptic.center);
+        elliptic.points[pointIndex].y = elliptic.center.y - distance;
+        elliptic.points[0].y = elliptic.center.y + distance;
+        elliptic.setRadiusY(distance);
+      } else if (pointIndex == 2) {
+        join = mathUtil.getJoinLinePoint(position, lineA);
+        distance = mathUtil.getDistance(join, elliptic.center);
+        elliptic.points[pointIndex].x = elliptic.center.x - distance;
+        elliptic.points[3].y = elliptic.center.x + distance;
+        elliptic.setRadiusX(distance);
+      } else if (pointIndex == 3) {
+        join = mathUtil.getJoinLinePoint(position, lineA);
+        distance = mathUtil.getDistance(join, elliptic.center);
+        elliptic.points[pointIndex].x = elliptic.center.x + distance;
+        elliptic.points[2].x = elliptic.center.x - distance;
+        elliptic.setRadiusX(distance);
+      }
+    }
+  }
+
+  check(position, center, pointIndex) {
+    if (pointIndex == 0) {
+      if (position.y > center.y) {
+        return true;
+      }
+    } else if (pointIndex == 1) {
+      if (position.y < center.y) {
+        return true;
+      }
+    } else if (pointIndex == 2) {
+      if (position.x < center.x) {
+        return true;
+      }
+    } else if (pointIndex == 3) {
+      if (position.x > center.x) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+const moveElliptic = new MoveElliptic();
+export { moveElliptic };

+ 9 - 0
src/graphic/Controls/UIControl.js

@@ -23,6 +23,7 @@ import Message from "@/components/base/components/message/message.vue";
 import { pointService } from "../Service/PointService.js";
 import Settings from "../Settings.js";
 import { addPoint } from "./AddPoint.js";
+import { ellipticService } from "../Service/EllipticService.js";
 
 export default class UIControl {
   constructor(layer, newsletter, graphicStateUI) {
@@ -90,6 +91,8 @@ export default class UIControl {
           stateService.setEventName(LayerEvents.AddPoint);
         } else if (selectUI == UIEvents.Circle) {
           stateService.setEventName(LayerEvents.AddCircle);
+        } else if (selectUI == UIEvents.Elliptic) {
+          stateService.setEventName(LayerEvents.AddElliptic);
         } else if (selectUI == UIEvents.Text) {
           stateService.setEventName(LayerEvents.AddText);
         } else if (selectUI == UIEvents.Magnifier) {
@@ -145,6 +148,9 @@ export default class UIControl {
       case VectorType.Circle:
         dataService.deleteCircle(vectorId);
         break;
+      case VectorType.Elliptic:
+        dataService.deleteElliptic(vectorId);
+        break;
       case VectorType.Text:
         dataService.deleteText(vectorId);
         break;
@@ -169,6 +175,9 @@ export default class UIControl {
       case VectorType.Circle:
         circleService.copy(vectorId);
         break;
+      case VectorType.Elliptic:
+        ellipticService.copy(vectorId);
+        break;
       case VectorType.Text:
         textService.copy(vectorId);
         break;

+ 63 - 0
src/graphic/Geometry/Elliptic.js

@@ -0,0 +1,63 @@
+import VectorType from "../enum/VectorType.js";
+import SelectState from "../enum/SelectState.js";
+import Geometry from "./Geometry";
+import Constant from "../Constant.js";
+import Style from "../CanvasStyle";
+
+//不靠墙
+export default class Elliptic extends Geometry {
+  constructor(center, radiusX, radiusY, vectorId) {
+    super();
+    //this.radiusX = Style.Elliptic.radiusX;
+    //this.radiusY = Style.Elliptic.radiusY;
+    this.center = null;
+    //this.color = Style.Elliptic.strokeStyle;
+    this.points = []; //包含椭圆上下左右四个点(数组的顺序是上下左右)
+    this.geoType = VectorType.Elliptic;
+    this.setId(vectorId);
+
+    this.setRadiusX(radiusX);
+    this.setRadiusY(radiusY);
+    this.setCenter(center);
+    this.createPoints();
+  }
+
+  createPoints() {
+    this.points[0] = {
+      x: this.center.x,
+      y: this.center.y + this.radiusX,
+    };
+    this.points[1] = {
+      x: this.center.x,
+      y: this.center.y - this.radiusX,
+    };
+    this.points[2] = {
+      x: this.center.x - this.radius,
+      y: this.center.y,
+    };
+    this.points[3] = {
+      x: this.center.x + this.radius,
+      y: this.center.y,
+    };
+  }
+
+  setPoints(points) {
+    if (points && points.length == 4) {
+      this.points = JSON.parse(JSON.stringify(points));
+    } else {
+      this.createPoints();
+    }
+  }
+
+  setColor(value) {
+    this.color = value;
+  }
+
+  setRadiusX(radiusX) {
+    this.radiusX = radiusX;
+  }
+
+  setRadiusY(radiusY) {
+    this.radiusY = radiusY;
+  }
+}

+ 1 - 1
src/graphic/Geometry/Line.js

@@ -12,7 +12,7 @@ export default class Line extends Geometry {
     this.startId = startId;
     this.endId = endId;
     this.category = Settings.selectLineCategory;
-    this.color = Style.ArrowLine.strokeStyle; //箭头类型会用到
+    this.color = Style.SingleArrowLine.strokeStyle; //箭头类型会用到
     this.value = null; //测量线会用到
     this.geoType = VectorType.Line;
     this.setId(vectorId);

+ 2 - 2
src/graphic/Geometry/SVG.js

@@ -6,12 +6,12 @@ import Constant from "../Constant.js";
 
 //const sideWidth = 10;
 export default class SVG extends Geometry {
-  constructor(center, name, vectorId) {
+  constructor(center, type, vectorId) {
     super();
     this.center = center;
     this.points = null; //包裹的矩形的四个顶点
     this.angle = 0; //逆时针为负,顺时针为正。单位是:°
-    this.name = name;
+    this.type = type;
     this.geoType = VectorType.SVG;
     this.scale = this.getScale(); //缩放比例
     this.setBoundingVertexs();

+ 44 - 0
src/graphic/History/Change.js

@@ -32,6 +32,9 @@ export default class Change {
     this.lastData.circles = JSON.parse(
       JSON.stringify(dataService.getCircles())
     );
+    this.lastData.elliptics = JSON.parse(
+      JSON.stringify(dataService.getElliptics())
+    );
     this.lastData.magnifiers = JSON.parse(
       JSON.stringify(dataService.getMagnifiers())
     );
@@ -68,6 +71,7 @@ export default class Change {
     this.compareCurvePoints();
     this.compareCurveLines();
     this.compareCircles();
+    this.compareElliptics();
     this.compareTexts();
     this.compareMagnifiers();
     this.compareSVGs();
@@ -85,6 +89,7 @@ export default class Change {
       this.currentData.curvePoints.length == 0 &&
       this.currentData.curveLines.length == 0 &&
       this.currentData.circles.length == 0 &&
+      this.currentData.elliptics.length == 0 &&
       this.currentData.texts.length == 0 &&
       this.currentData.magnifiers.length == 0 &&
       this.currentData.roadPoints.length == 0 &&
@@ -344,6 +349,45 @@ export default class Change {
     }
   }
 
+  compareElliptics() {
+    const elliptics = dataService.getElliptics();
+    this.currentData.elliptics = [];
+
+    for (const key in elliptics) {
+      const elliptic = elliptics[key];
+      // 不存在意味着增加
+      if (!this.lastData.elliptics[key]) {
+        const item = {
+          handle: HistoryEvents.AddElliptic,
+          elliptic: historyUtil.getDataForElliptic(elliptic),
+        };
+        this.currentData.elliptics.push(item);
+      } else {
+        const lastElliptic = this.lastData.elliptics[key];
+        if (!historyUtil.isDifferentForElliptics(elliptic, lastElliptic)) {
+          delete this.lastData.elliptics[key];
+          continue;
+        } else {
+          const item = {
+            handle: HistoryEvents.ModifyElliptic,
+            preElliptic: historyUtil.getDataForElliptic(lastElliptic),
+            curElliptic: historyUtil.getDataForElliptic(elliptic),
+          };
+          this.currentData.elliptics.push(item);
+        }
+      }
+      delete this.lastData.elliptics[key];
+    }
+
+    for (const key in this.lastData.elliptics) {
+      const item = {
+        handle: HistoryEvents.DeleteElliptic,
+        elliptic: historyUtil.getDataForElliptic(this.lastData.elliptics[key]),
+      };
+      this.currentData.elliptics.push(item);
+    }
+  }
+
   compareMagnifiers() {
     const magnifiers = dataService.getMagnifiers();
     this.currentData.magnifiers = [];

+ 47 - 0
src/graphic/History/History.js

@@ -10,6 +10,7 @@ import { svgService } from "../Service/SVGService";
 import { roadPointService } from "../Service/RoadPointService";
 import { lineService } from "../Service/LineService";
 import { circleService } from "../Service/CircleService";
+import { ellipticService } from "../Service/EllipticService";
 import { pointService } from "../Service/PointService";
 import { edgeService } from "../Service/EdgeService";
 import { magnifierService } from "../Service/MagnifierService";
@@ -105,6 +106,7 @@ export default class History {
       this.goPreForCurvePoints(item.curvePoints);
       this.goPreForCurveLines(item.curveLines);
       this.goPreForCircles(item.circles);
+      this.goPreForElliptics(item.elliptics);
       this.goPreForTexts(item.texts);
       this.goPreForMagnifiers(item.magnifiers);
       this.goPreForSVGs(item.svgs);
@@ -237,6 +239,28 @@ export default class History {
     }
   }
 
+  goPreForElliptics(itemForElliptics) {
+    for (let i = 0; i < itemForElliptics.length; ++i) {
+      const item = itemForElliptics[i];
+      if (item.handle == HistoryEvents.AddElliptic) {
+        dataService.deleteElliptic(item.elliptic.id);
+      } else if (item.handle == HistoryEvents.DeleteElliptic) {
+        const preElliptic = item.elliptic;
+        let newElliptic = ellipticService.create(
+          preElliptic.center,
+          preElliptic.radiusX,
+          preElliptic.radiusY,
+          preElliptic.id
+        );
+        historyUtil.assignEllipticFromElliptic(newElliptic, preElliptic);
+      } else if (item.handle == HistoryEvents.ModifyElliptic) {
+        const preElliptic = item.preElliptic;
+        let currentElliptic = dataService.getElliptic(item.curElliptic.id);
+        historyUtil.assignEllipticFromElliptic(currentElliptic, preElliptic);
+      }
+    }
+  }
+
   goPreForTexts(itemForTexts) {
     for (let i = 0; i < itemForTexts.length; ++i) {
       const item = itemForTexts[i];
@@ -581,6 +605,28 @@ export default class History {
     }
   }
 
+  goNextForElliptics(itemForElliptics) {
+    for (let i = 0; i < itemForElliptics.length; ++i) {
+      const item = itemForElliptics[i];
+      if (item.handle == HistoryEvents.AddElliptic) {
+        const preElliptic = item.elliptic;
+        let newElliptic = ellipticService.create(
+          preElliptic.center,
+          preElliptic.radiusX,
+          preElliptic.radiusY,
+          preElliptic.id
+        );
+        historyUtil.assignEllipticFromElliptic(newElliptic, preElliptic);
+      } else if (item.handle == HistoryEvents.DeleteElliptic) {
+        dataService.deleteElliptic(item.elliptic.id);
+      } else if (item.handle == HistoryEvents.ModifyElliptic) {
+        const currentElliptic = item.curElliptic;
+        let preElliptic = dataService.getElliptic(item.preElliptic.id);
+        historyUtil.assignEllipticFromElliptic(preElliptic, currentElliptic);
+      }
+    }
+  }
+
   goNextForTexts(itemForTexts) {
     for (let i = 0; i < itemForTexts.length; ++i) {
       const item = itemForTexts[i];
@@ -826,6 +872,7 @@ export default class History {
       this.goNextForCurvePoints(item.curvePoints);
       this.goNextForCurveLines(item.curveLines);
       this.goNextForCircles(item.circles);
+      this.goNextForElliptics(item.elliptics);
       this.goNextForTexts(item.texts);
       this.goNextForMagnifiers(item.magnifiers);
       this.goNextForSVGs(item.svgs);

+ 53 - 6
src/graphic/History/HistoryUtil.js

@@ -72,6 +72,19 @@ export default class HistoryUtil {
     }
   }
 
+  isDifferentForElliptics(elliptic1, elliptic2) {
+    if (
+      mathUtil.equalPoint(elliptic1.center, elliptic2.center) &&
+      elliptic1.radiusX == elliptic2.radiusX &&
+      elliptic1.radiusY == elliptic2.radiusY &&
+      elliptic1.color == elliptic2.color
+    ) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
   isDifferentForTexts(text1, text2) {
     if (
       mathUtil.equalPoint(text1.center, text2.center) &&
@@ -98,7 +111,7 @@ export default class HistoryUtil {
   isDifferentForSVGs(svg1, svg2) {
     if (
       mathUtil.equalPoint(svg1.center, svg2.center) &&
-      svg1.name == svg2.name &&
+      svg1.type == svg2.type &&
       svg1.angle == svg2.angle &&
       svg1.scale == svg2.scale
     ) {
@@ -313,6 +326,17 @@ export default class HistoryUtil {
     this.setCircleInfo(circleInfo);
   }
 
+  assignEllipticFromElliptic(elliptic1, elliptic2) {
+    const ellipticInfo = {};
+    ellipticInfo.vectorId = elliptic1.vectorId;
+    ellipticInfo.center = elliptic2.center;
+    ellipticInfo.radiusX = elliptic2.radiusX;
+    ellipticInfo.radiusY = elliptic2.radiusY;
+    ellipticInfo.points = JSON.parse(JSON.stringify(elliptic2.points));
+    ellipticInfo.color = elliptic2.color;
+    this.setEllipticInfo(ellipticInfo);
+  }
+
   assignTextFromText(text1, text2) {
     const textInfo = {};
     textInfo.vectorId = text1.vectorId;
@@ -336,7 +360,7 @@ export default class HistoryUtil {
   assignSVGFromSVG(svg1, svg2) {
     const svgInfo = {};
     svgInfo.vectorId = svg1.vectorId;
-    svgInfo.name = svg2.name;
+    svgInfo.type = svg2.type;
     svgInfo.center = JSON.parse(JSON.stringify(svg2.center));
     svgInfo.points = JSON.parse(JSON.stringify(svg2.points));
     svgInfo.angle = svg2.angle;
@@ -550,6 +574,19 @@ export default class HistoryUtil {
     return data;
   }
 
+  getDataForElliptic(elliptic) {
+    const data = {};
+    data.id = elliptic.vectorId;
+    data.center = {};
+    mathUtil.clonePoint(data.center, elliptic.center);
+    data.radiusX = elliptic.radiusX;
+    data.radiusY = elliptic.radiusY;
+    data.points = elliptic.points;
+    data.color = elliptic.color;
+    data.type = elliptic.geoType;
+    return data;
+  }
+
   getDataForText(text) {
     const data = {};
     data.id = text.vectorId;
@@ -588,7 +625,7 @@ export default class HistoryUtil {
     mathUtil.clonePoint(data.points[2], svg.points[2]);
     data.points[3] = {};
     mathUtil.clonePoint(data.points[3], svg.points[3]);
-    data.name = svg.name;
+    data.type = svg.type;
     data.angle = svg.angle;
     data.scale = svg.scale;
     return data;
@@ -769,6 +806,16 @@ export default class HistoryUtil {
     return circle;
   }
 
+  setEllipticInfo(ellipticInfo) {
+    let elliptic = dataService.getElliptic(ellipticInfo.vectorId);
+    elliptic.center = ellipticInfo.center;
+    elliptic.radiusX = ellipticInfo.radiusX;
+    elliptic.radiusY = ellipticInfo.radiusY;
+    elliptic.color = ellipticInfo.color;
+    elliptic.points = ellipticInfo.points;
+    return elliptic;
+  }
+
   setTextInfo(textInfo) {
     let text = dataService.getText(textInfo.vectorId);
     text.vectorId = textInfo.vectorId;
@@ -792,7 +839,7 @@ export default class HistoryUtil {
     svg.vectorId = svgInfo.vectorId;
     svg.center = JSON.parse(JSON.stringify(svgInfo.center));
     svg.points = JSON.parse(JSON.stringify(svgInfo.points));
-    svg.name = svgInfo.name;
+    svg.type = svgInfo.type;
     svg.angle = svgInfo.angle;
     svg.scale = svgInfo.scale;
   }
@@ -809,7 +856,7 @@ export default class HistoryUtil {
     roadEdge.vectorId = roadEdgeInfo.vectorId;
     mathUtil.clonePoint(roadEdge.start, roadEdgeInfo.start);
     mathUtil.clonePoint(roadEdge.end, roadEdgeInfo.end);
-    roadEdge.name = roadEdgeInfo.name;
+    roadEdge.type = roadEdgeInfo.type;
   }
 
   setRoadInfo(roadInfo) {
@@ -856,7 +903,7 @@ export default class HistoryUtil {
     mathUtil.clonePoint(curveRoadEdge.end, curveRoadEdgeInfo.end);
     mathUtil.clonePoints(curveRoadEdge.points, curveRoadEdgeInfo.points);
     curveRoadEdge.curves = JSON.parse(JSON.stringify(curveRoadEdgeInfo.curves));
-    curveRoadEdge.name = curveRoadEdgeInfo.name;
+    curveRoadEdge.type = curveRoadEdgeInfo.type;
   }
 
   setCurveRoadInfo(curveRoadInfo) {

+ 81 - 2
src/graphic/Layer.js

@@ -13,6 +13,7 @@ import { addRoad } from "./Controls/AddRoad";
 import { addLine } from "./Controls/AddLine";
 import { addPoint } from "./Controls/AddPoint";
 import { addCircle } from "./Controls/AddCircle";
+import { addElliptic } from "./Controls/AddElliptic";
 import { addText } from "./Controls/AddText";
 import { addMagnifier } from "./Controls/AddMagnifier";
 import { addSVG } from "./Controls/AddSVG";
@@ -20,6 +21,7 @@ import { moveRoad } from "./Controls/MoveRoad";
 import { moveLine } from "./Controls/MoveLine";
 import { movePoint } from "./Controls/MovePoint";
 import { moveCircle } from "./Controls/MoveCircle";
+import { moveElliptic } from "./Controls/MoveElliptic";
 import { coordinate } from "./Coordinate";
 import Render from "./Renderer/Render";
 import { draw } from "./Renderer/Draw";
@@ -161,6 +163,10 @@ export default class Layer {
         stateService.setEventName(LayerEvents.AddingCircle);
         addCircle.setCenter(position);
         break;
+      case LayerEvents.AddElliptic:
+        stateService.setEventName(LayerEvents.AddingElliptic);
+        addElliptic.setCenter(position);
+        break;
       case LayerEvents.AddText:
         stateService.setEventName(LayerEvents.MoveText);
         addText.buildText(position);
@@ -360,6 +366,20 @@ export default class Layer {
         elementService.showPoint();
         this.showElementLine(position);
         break;
+      case LayerEvents.AddElliptic:
+        needAutoRedraw = true;
+        listenLayer.start(position);
+        if (listenLayer.modifyPoint) {
+          position = {
+            x: listenLayer.modifyPoint.x,
+            y: listenLayer.modifyPoint.y,
+          };
+        }
+        elementService.hideAll();
+        elementService.setPoint(position);
+        elementService.showPoint();
+        this.showElementLine(position);
+        break;
       case LayerEvents.AddingRoad:
         needAutoRedraw = true;
         listenLayer.start(position);
@@ -458,8 +478,6 @@ export default class Layer {
             y: listenLayer.modifyPoint.y,
           };
         }
-        // elementService.execute(addCircle.center, position);
-        // elementService.setPoint(position);
         if (addCircle.newCircle == null) {
           addCircle.buildCircle(position);
         } else {
@@ -470,6 +488,29 @@ export default class Layer {
         elementService.showPoint();
         this.showElementLine(position);
         break;
+      case LayerEvents.AddingElliptic:
+        needAutoRedraw = true;
+        let exceptEllipticId = null;
+        if (addElliptic.newElliptic != null) {
+          exceptEllipticId = addElliptic.newElliptic.vectorId;
+        }
+        listenLayer.start(position, { exceptEllipticId: exceptEllipticId });
+        if (listenLayer.modifyPoint) {
+          position = {
+            x: listenLayer.modifyPoint.x,
+            y: listenLayer.modifyPoint.y,
+          };
+        }
+        if (addElliptic.newElliptic == null) {
+          addElliptic.buildElliptic(position);
+        } else {
+          addElliptic.updateElliptic(position);
+        }
+        elementService.hideAll();
+        elementService.setPoint(position);
+        elementService.showPoint();
+        this.showElementLine(position);
+        break;
       case LayerEvents.MoveRoad:
         needAutoRedraw = true;
         //只允许拖拽一条公路
@@ -681,6 +722,31 @@ export default class Layer {
           needAutoRedraw = true;
         }
         break;
+      case LayerEvents.MoveElliptic:
+        if (draggingItem != null) {
+          if (draggingItem.state == -1) {
+            moveElliptic.moveFull(
+              draggingItem.vectorId,
+              (dx * coordinate.defaultZoom) / coordinate.zoom,
+              (dy * coordinate.defaultZoom) / coordinate.zoom
+            );
+          } else if (
+            draggingItem.state == 0 ||
+            draggingItem.state == 1 ||
+            draggingItem.state == 2 ||
+            draggingItem.state == 3
+          ) {
+            moveElliptic.movePoint(
+              position,
+              draggingItem.vectorId,
+              draggingItem.state
+            );
+          } else {
+            debugger;
+          }
+          needAutoRedraw = true;
+        }
+        break;
       case LayerEvents.MoveText:
         needAutoRedraw = true;
         if (draggingItem != null) {
@@ -857,6 +923,13 @@ export default class Layer {
         this.history.save();
         elementService.hideAll();
         break;
+      case LayerEvents.AddingElliptic:
+        needAutoRedraw = true;
+        addElliptic.finish(position);
+        addElliptic.clear();
+        this.history.save();
+        elementService.hideAll();
+        break;
       case LayerEvents.MoveText:
         needAutoRedraw = true;
         this.history.save();
@@ -933,6 +1006,10 @@ export default class Layer {
         needAutoRedraw = true;
         this.history.save();
         break;
+      case LayerEvents.MoveElliptic:
+        needAutoRedraw = true;
+        this.history.save();
+        break;
       case LayerEvents.AddPoint:
         if (
           Settings.selectBasePointId != null &&
@@ -1199,6 +1276,8 @@ export default class Layer {
           stateService.setEventName(LayerEvents.MoveCurveLine);
         } else if (selectItem.type == VectorType.Circle) {
           stateService.setEventName(LayerEvents.MoveCircle);
+        } else if (selectItem.type == VectorType.Elliptic) {
+          stateService.setEventName(LayerEvents.MoveElliptic);
         } else if (selectItem.type == VectorType.Text) {
           stateService.setEventName(LayerEvents.MoveText);
         } else if (selectItem.type == VectorType.Magnifier) {

+ 82 - 113
src/graphic/ListenLayer.js

@@ -11,6 +11,7 @@ import { coordinate } from "./Coordinate";
 import { draw } from "./Renderer/Draw.js";
 import { edgeService } from "./Service/EdgeService";
 import VectorCategory from "./enum/VectorCategory";
+import LayerEvents from "./enum/LayerEvents";
 
 export default class ListenLayer {
   constructor() {
@@ -78,6 +79,10 @@ export default class ListenLayer {
       position,
       exceptVectorIds.exceptCircleId
     );
+    selectInfo.ellipticInfo = this.isSelectElliptic(
+      position,
+      exceptVectorIds.exceptEllipticId
+    );
     //交叉口拐弯处的控制点
     selectInfo.crossPointInfo = this.isSelectCrossCrossPoint(
       position,
@@ -291,6 +296,11 @@ export default class ListenLayer {
       if (exceptLineId == lineId) {
         continue;
       }
+      if (stateService.getEventName() == LayerEvents.MovePoint) {
+        console.log("选中的isSelectLine:" + exceptLineId);
+        debugger;
+      }
+
       const line = dataService.getLine(lineId);
       if (
         line.getCategory() == VectorCategory.Line.PositionLine ||
@@ -373,121 +383,68 @@ export default class ListenLayer {
     return circleInfo;
   }
 
-  // isSelectCurveLine(position, exceptCurveLineId) {
-  //   let curveLineInfo = {
-  //     curveLineId: null,
-  //     type: null,
-  //     distance: null,
-  //   };
-  //   let seqInfo = {};
-  //   const curveLines = dataService.getCurveLines();
+  isSelectElliptic(position, exceptEllipticId) {
+    let ellipticInfo = {
+      ellipticId: null,
+      type: null,
+      distance: null,
+    };
+    const elliptics = dataService.getElliptics();
+    let distance;
+    for (const ellipticId in elliptics) {
+      if (ellipticId == exceptEllipticId) {
+        continue;
+      }
+      const elliptic = dataService.getElliptic(ellipticId);
+      for (let i = 0; i < elliptic.points.length; ++i) {
+        distance = this.getDistance(position, elliptic.points[i]);
+        if (distance < Constant.minAdsorbPix) {
+          ellipticInfo = {
+            ellipticId: ellipticId,
+            type: VectorType.Elliptic,
+            distance: distance,
+            x: elliptic.points[i].x,
+            y: elliptic.points[i].y,
+            index: i,
+          };
+          return ellipticInfo;
+        }
+      }
 
-  //   for (const curveLineId in curveLines) {
-  //     if (curveLineId == exceptCurveLineId) {
-  //       continue;
-  //     }
-  //     const curveLine = dataService.getCurveLine(curveLineId);
-  //     let joinInfo = this.distanceForBezier(
-  //       position,
-  //       curveRoad.curves,
-  //       Constant.minAdsorbPix / 2
-  //     );
+      const distanceX = mathUtil.getDistance(
+        elliptic.points[2],
+        elliptic.points[3]
+      );
+      const distanceY = mathUtil.getDistance(
+        elliptic.points[0],
+        elliptic.points[1]
+      );
+      const flag = mathUtil.isPointInElliptic(
+        position,
+        elliptic.center,
+        distanceX,
+        distanceY
+      );
+      distance = this.getDistance(position, elliptic.center);
+      if (flag) {
+        if (
+          ellipticInfo.ellipticId == null ||
+          distance < ellipticInfo.distance
+        ) {
+          ellipticInfo = {
+            ellipticId: ellipticId,
+            type: VectorType.Elliptic,
+            distance: distance,
+            x: elliptic.center.x,
+            y: elliptic.center.y,
+            index: -1,
+          };
+        }
+      }
+    }
 
-  //     if (
-  //       mathUtil.isClockwise([curveRoad.points[0], joinInfo.position, position])
-  //     ) {
-  //       //选中了路
-  //       if (joinInfo.distance < curveRoad.leftWidth - Constant.minAdsorbPix) {
-  //         curveRoadInfo = {
-  //           curveRoadId: curveRoadId,
-  //           type: VectorType.CurveRoad,
-  //           distance: joinInfo.distance,
-  //           x: joinInfo.position.x,
-  //           y: joinInfo.position.y,
-  //         };
-  //       }
-  //       //选中了edge
-  //       else if (
-  //         joinInfo.distance <
-  //         curveRoad.leftWidth + Constant.minAdsorbPix
-  //       ) {
-  //         const leftCurveEdge = dataService.getCurveRoadEdge(
-  //           curveRoad.leftEdgeId
-  //         );
-  //         joinInfo = this.distanceForBezier(
-  //           position,
-  //           leftCurveEdge.curves,
-  //           curveRoad.leftWidth
-  //         );
-  //         const index = mathUtil.getIndexForCurvesPoints(
-  //           joinInfo.position,
-  //           curveRoad.points
-  //         );
-  //         curveEdgeInfo = {
-  //           curveEdgeId: curveRoad.leftEdgeId,
-  //           type: VectorType.CurveRoadEdge,
-  //           distance: joinInfo.distance,
-  //           selectIndex: index,
-  //           x: joinInfo.position.x,
-  //           y: joinInfo.position.y,
-  //         };
-  //       }
-  //     } else if (
-  //       !mathUtil.isClockwise([
-  //         curveRoad.points[0],
-  //         joinInfo.position,
-  //         position,
-  //       ])
-  //     ) {
-  //       //选中了路
-  //       if (joinInfo.distance < curveRoad.rightWidth - Constant.minAdsorbPix) {
-  //         curveRoadInfo = {
-  //           curveRoadId: curveRoadId,
-  //           type: VectorType.CurveRoad,
-  //           distance: joinInfo.distance,
-  //           x: joinInfo.position.x,
-  //           y: joinInfo.position.y,
-  //         };
-  //       }
-  //       //选中了edge
-  //       else if (
-  //         joinInfo.distance <
-  //         curveRoad.rightWidth + Constant.minAdsorbPix
-  //       ) {
-  //         const rightCurveEdge = dataService.getCurveRoadEdge(
-  //           curveRoad.rightEdgeId
-  //         );
-  //         joinInfo = this.distanceForBezier(
-  //           position,
-  //           rightCurveEdge.curves,
-  //           curveRoad.rightWidth
-  //         );
-  //         const index = mathUtil.getIndexForCurvesPoints(
-  //           joinInfo.position,
-  //           curveRoad.points
-  //         );
-  //         curveEdgeInfo = {
-  //           curveEdgeId: curveRoad.rightEdgeId,
-  //           type: VectorType.CurveRoadEdge,
-  //           distance: joinInfo.distance,
-  //           selectIndex: index,
-  //           x: joinInfo.position.x,
-  //           y: joinInfo.position.y,
-  //         };
-  //       }
-  //     }
-  //   }
-  //   if (curveRoadInfo.curveRoadId) {
-  //     return curveRoadInfo;
-  //   } else if (curveEdgeInfo.curveEdgeId) {
-  //     return curveEdgeInfo;
-  //   } else {
-  //     return {
-  //       curveRoadId: null,
-  //       curveEdgeId: null,
-  //     };
-  //   }
-  // }
+    return ellipticInfo;
+  }
 
   isSelectRoadPoint(position, exceptRoadPointId) {
     let roadPointInfo = {
@@ -1138,6 +1095,12 @@ export default class ListenLayer {
       this.modifyPoint.index = info.circleInfo.index;
       this.modifyPoint.x = info.circleInfo.x;
       this.modifyPoint.y = info.circleInfo.y;
+    } else if (info && info.ellipticInfo.ellipticId) {
+      this.modifyPoint = {};
+      this.modifyPoint.linkedEllipticId = info.ellipticInfo.ellipticId;
+      this.modifyPoint.index = info.ellipticInfo.index;
+      this.modifyPoint.x = info.ellipticInfo.x;
+      this.modifyPoint.y = info.ellipticInfo.y;
     } else if (info && info.roadPointInfo.linkedRoadPointIdX) {
       this.modifyPoint = {};
       this.modifyPoint.linkedRoadPointIdX =
@@ -1298,6 +1261,12 @@ export default class ListenLayer {
         VectorType.Circle,
         this.modifyPoint.index
       );
+    } else if (this.modifyPoint.linkedEllipticId) {
+      stateService.setSelectItem(
+        this.modifyPoint.linkedEllipticId,
+        VectorType.Elliptic,
+        this.modifyPoint.index
+      );
     } else {
       stateService.clearSelectItem();
     }

+ 20 - 18
src/graphic/Renderer/Draw.js

@@ -9,7 +9,7 @@ import { elementService } from "../Service/ElementService.js";
 import UIEvents from "@/graphic/enum/UIEvents.js";
 import VectorCategory from "@/graphic/enum/VectorCategory.js";
 import Settings from "@/graphic/Settings.js";
-import { Canvg } from 'canvg'
+import { Canvg } from "canvg";
 import SVGIcons from "../CanvasStyle/ImageLabels/SVGIcons";
 
 const imgCache = {};
@@ -729,24 +729,22 @@ export default class Draw {
   }
 
   drawSVG(vector) {
-    const points = vector.points.map(coordinate.getScreenXY.bind(coordinate))
-    const svgWidth= 64
-    const svgHidth= 64
-    const width = mathUtil.getDistance(points[0], points[1])
-    const height = mathUtil.getDistance(points[0], points[3])
-    const dires = [points[0], {...points[0], x: 10000}, points[1]]
-    let angle = mathUtil.Angle(...dires) * (Math.PI / 180)
+    const points = vector.points.map(coordinate.getScreenXY.bind(coordinate));
+    const svgWidth = 64;
+    const svgHidth = 64;
+    const width = mathUtil.getDistance(points[0], points[1]);
+    const height = mathUtil.getDistance(points[0], points[3]);
+    const dires = [points[0], { ...points[0], x: 10000 }, points[1]];
+    let angle = mathUtil.Angle(...dires) * (Math.PI / 180);
     angle = mathUtil.isClockwise(dires) ? angle : -angle;
 
     this.context.save();
-    this.context.translate(points[0].x, points[0].y)
-    this.context.rotate(angle)
-    this.context.scale(width / svgWidth, height / svgHidth)
-    const [style] = help.setVectorStyle(this.context, vector)
-    this.context.lineWidth = style.lineWidth / (width / svgWidth)
-    SVGIcons.keche_plane.draw(this.context)
-
-
+    this.context.translate(points[0].x, points[0].y);
+    this.context.rotate(angle);
+    this.context.scale(width / svgWidth, height / svgHidth);
+    const [style] = help.setVectorStyle(this.context, vector);
+    this.context.lineWidth = style.lineWidth / (width / svgWidth);
+    SVGIcons.keche_plane.draw(this.context);
 
     if (import.meta.env.DEV) {
       this.context.restore();
@@ -825,7 +823,7 @@ export default class Draw {
 
   drawCurveLine(vector) {
     // points  CurveLine
-    console.log(vector)
+    console.log(vector);
     const ctx = this.context;
     ctx.save();
     help.setVectorStyle(ctx, vector);
@@ -867,7 +865,11 @@ export default class Draw {
     };
 
     switch (vector.category) {
-      case VectorCategory.Line.ArrowLine:
+      case VectorCategory.Line.SingleArrowLine:
+        this.drawArrow(vector);
+        drawPoints();
+        break;
+      case VectorCategory.Line.DoubleArrowLine:
         this.drawArrow(vector);
         drawPoints();
         break;

+ 8 - 0
src/graphic/Renderer/Render.js

@@ -57,6 +57,9 @@ export default class Render {
       case VectorType.Circle:
         draw.drawCircle(vector);
         break;
+      case VectorType.Elliptic:
+        draw.drawCircle(vector);
+        break;
       case VectorType.Magnifier:
         draw.drawMagnifier(vector);
         break;
@@ -162,6 +165,11 @@ export default class Render {
       this.drawGeometry(circles[key]);
     }
 
+    const elliptics = dataService.getElliptics();
+    for (const key in elliptics) {
+      this.drawGeometry(elliptics[key]);
+    }
+
     const texts = dataService.getTexts();
     for (const key in texts) {
       this.drawGeometry(texts[key]);

+ 15 - 0
src/graphic/Service/CurvePointService.js

@@ -0,0 +1,15 @@
+import CurvePoint from "../Geometry/CurvePoint.js";
+import { dataService } from "./DataService.js";
+
+export default class CurvePointService {
+  constructor() {}
+
+  create(position, vectorId) {
+    let curvePoint = new CurvePoint(position, vectorId);
+    dataService.addCurvePoint(curvePoint);
+    return curvePoint;
+  }
+}
+
+const curvePointService = new CurvePointService();
+export { curvePointService };

+ 19 - 1
src/graphic/Service/DataService.js

@@ -76,8 +76,8 @@ export class DataService {
     //线段(完全或者直线)上的端点
     this.vectorData.points = {};
     this.vectorData.curvePoints = {};
-
     this.vectorData.circles = {};
+    this.vectorData.elliptics = {};
     //基准点
     this.vectorData.basePointIds = [];
     this.vectorData.texts = {};
@@ -200,6 +200,23 @@ export class DataService {
     delete this.vectorData.circles[circleId];
   }
 
+  //椭圆
+  getElliptics() {
+    return this.vectorData.elliptics;
+  }
+
+  getElliptic(ellipticId) {
+    return this.vectorData.elliptics[ellipticId];
+  }
+
+  addElliptic(elliptic) {
+    this.vectorData.elliptics[elliptic.vectorId] = elliptic;
+  }
+
+  deleteElliptic(ellipticId) {
+    delete this.vectorData.elliptics[ellipticId];
+  }
+
   //弯曲线条
   addCurveLine(curveLine) {
     this.vectorData.curvelines[curveLine.vectorId] = curveLine;
@@ -569,6 +586,7 @@ export class DataService {
     this.vectorData.points = {};
     this.vectorData.curvePoints = {};
     this.vectorData.circles = {};
+    this.vectorData.elliptics = {};
     //基准点
     this.vectorData.basePointIds = [];
     this.vectorData.texts = {};

+ 37 - 0
src/graphic/Service/EllipticService.js

@@ -0,0 +1,37 @@
+import Point from "../Geometry/Point.js";
+import Elliptic from "../Geometry/Elliptic.js";
+import { dataService } from "./DataService.js";
+import { uiService } from "./UIService.js";
+import VectorCategory from "../enum/VectorCategory.js";
+import { mathUtil } from "../Util/MathUtil.js";
+import Constant from "../Constant.js";
+
+export default class EllipticService {
+  constructor() {}
+
+  create(center, radiusX, radiusY, vectorId) {
+    if (
+      !center ||
+      !radiusX ||
+      radiusX < Constant.minAdsorbPix / 2 ||
+      !radiusY ||
+      radiusY < Constant.minAdsorbPix / 2
+    ) {
+      return null;
+    }
+    let elliptic = new Elliptic(center, radiusX, radiusY, vectorId);
+    dataService.addElliptic(elliptic);
+    return elliptic;
+  }
+
+  copy(vectorId) {
+    let elliptic = dataService.getElliptic(vectorId);
+    let center = uiService.getNewPositionForPop(elliptic.center);
+    let newElliptic = this.create(center, elliptic.radiusX, elliptic.radiusY);
+    newElliptic.setColor(elliptic.color);
+    return newElliptic;
+  }
+}
+
+const ellipticService = new EllipticService();
+export { ellipticService };

+ 1 - 0
src/graphic/Service/StateService.js

@@ -37,6 +37,7 @@ export default class StateService {
       const point = dataService.getPoint(vectorId);
       this.selectItem.category = point.getCategory();
     }
+    console.log("选中的元素:" + JSON.stringify(this.selectItem));
   }
 
   getSelectItem() {

+ 5 - 2
src/graphic/Service/UIService.js

@@ -64,8 +64,11 @@ export default class UIService {
   }
 
   isBelongLine(ui) {
-    if (ui == UIEvents.Arrow) {
-      this.setSelectLineCategory(VectorCategory.Line.ArrowLine);
+    if (ui == UIEvents.SingleArrow) {
+      this.setSelectLineCategory(VectorCategory.Line.SingleArrowLine);
+      return true;
+    } else if (ui == UIEvents.DoubleArrow) {
+      this.setSelectLineCategory(VectorCategory.Line.DoubleArrowLine);
       return true;
     } else if (ui == UIEvents.MeasureLine) {
       this.setSelectLineCategory(VectorCategory.Line.MeasureLine);

+ 13 - 0
src/graphic/Util/MathUtil.js

@@ -493,6 +493,19 @@ export default class MathUtil {
     return inside;
   }
 
+  //a表示横轴,b表示竖轴
+  isPointInElliptic(point, center, a, b) {
+    let r =
+      Math.pow((point.x - center.x) / a, 2) +
+      Math.pow((point.y - center.y) / b, 2);
+
+    if (r <= 1) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   // 点到线段的距离
   // 在minDistance范围内,会吸附到point1/point2上
   // 返回值:type是1表示吸附在point1,是2表示吸附在point2,是0表示在线段point1-point2上;

+ 4 - 0
src/graphic/enum/HistoryEvents.js

@@ -35,6 +35,10 @@ const HistoryEvents = {
   DeleteCircle: "deleteCircle",
   ModifyCircle: "modifyCircle",
 
+  AddElliptic: "addElliptic",
+  DeleteElliptic: "deleteElliptic",
+  ModifyElliptic: "modifyElliptic",
+
   AddMagnifier: "addMagnifier",
   DeleteMagnifier: "deleteMagnifier",
   ModifyMagnifier: "modifyMagnifier",

+ 4 - 0
src/graphic/enum/LayerEvents.js

@@ -23,6 +23,10 @@ const LayerEvents = {
   AddingCircle: "addingCircle",
   MoveCircle: "moveCircle",
 
+  AddElliptic: "addElliptic",
+  AddingElliptic: "addingElliptic",
+  MoveElliptic: "moveElliptic",
+
   MoveCrossPoint: "moveCrossPoint",
   MoveEdge: "moveEdge",
   MoveCurveEdge: "moveCurveEdge",

+ 4 - 0
src/graphic/enum/SVGType.js

@@ -0,0 +1,4 @@
+const SVGType = {
+  BusPlane: "BusPlane",
+};
+export default SVGType;

+ 4 - 2
src/graphic/enum/UIEvents.js

@@ -3,17 +3,19 @@ const UIEvents = {
   // 客车平面
   BusPlane: "BusPlane",
 
-
   // 画直线线
   Line: "line",
   // 画曲线
   CurveLine: "Curveline",
   // 画圆
   Circle: "Circle",
+  // 画椭圆
+  Elliptic: "Elliptic",
   // 图例
   Img: "backgroundImage",
   // 箭头
-  Arrow: "ArrowLine",
+  SingleArrow: "SingleArrowLine",
+  DoubleArrow: "DoubleArrowLine",
   //基准线
   BaseLine: "BaseLine",
   //基准点

+ 2 - 1
src/graphic/enum/VectorCategory.js

@@ -1,6 +1,7 @@
 const VectorCategory = {
   Line: {
-    ArrowLine: "ArrowLine",
+    SingleArrowLine: "SingleArrowLine",
+    DoubleArrowLine: "DoubleArrowLine",
     NormalLine: "NormalLine",
     BaseLine: "BaseLine",
     MeasureLine: "MeasureLine",

+ 3 - 1
src/graphic/enum/VectorType.js

@@ -1,13 +1,15 @@
 const VectorType = {
   CrossPoint: "CrossPoint",
   Circle: "Circle",
+  Elliptic: "Elliptic",
   Img: "Img",
   Point: "Point",
   Line: "Line",
   CurvePoint: "CurvePoint",
   CurveLine: "CurveLine",
   MeasureArrow: "MeasureArrow",
-  ArrowLine: "ArrowLine",
+  SingleArrowLine: "SingleArrowLine",
+  DoubleArrowLine: "DoubleArrowLine",
   Road: "Road",
   RoadEdge: "RoadEdge",
   RoadPoint: "RoadPoint",