xushiting 2 年之前
父節點
當前提交
046c2007bc

+ 29 - 23
src/graphic/Controls/MoveRoad.js

@@ -33,9 +33,9 @@ export default class MoveRoad {
       linkedRoadPointId = modifyPoint.linkedRoadPointId;
       linkedRoadId = modifyPoint.linkedRoadId;
     }
-    if (point.x == position.x && point.y == position.y) {
-      return false;
-    }
+    // if (point.x == position.x && point.y == position.y) {
+    //   return false;
+    // }
     this.adsorbPointRoads = {};
     this.splitRoadId = null;
     let flag = this.canMoveForPoint(
@@ -99,21 +99,34 @@ export default class MoveRoad {
         return false;
       }
       point.setPosition(modifyPoint);
+    } else if (
+      modifyPoint.hasOwnProperty("linkedRoadPointIdX") &&
+      modifyPoint.linkedRoadPointIdX
+    ) {
+      point.setPosition(position);
+    } else if (
+      modifyPoint.hasOwnProperty("linkedRoadPointIdY") &&
+      modifyPoint.linkedRoadPointIdY
+    ) {
+      point.setPosition(position);
     } else {
-      if (
-        modifyPoint.hasOwnProperty("linkedRoadPointIdX") &&
-        modifyPoint.linkedRoadPointIdX
-      ) {
-        point.setPosition(position);
-      }
-
-      if (
-        modifyPoint.hasOwnProperty("linkedRoadPointIdY") &&
-        modifyPoint.linkedRoadPointIdY
-      ) {
-        point.setPosition(position);
-      }
+      return false;
     }
+    // else {
+    //   if (
+    //     modifyPoint.hasOwnProperty("linkedRoadPointIdX") &&
+    //     modifyPoint.linkedRoadPointIdX
+    //   ) {
+    //     point.setPosition(position);
+    //   }
+
+    //   if (
+    //     modifyPoint.hasOwnProperty("linkedRoadPointIdY") &&
+    //     modifyPoint.linkedRoadPointIdY
+    //   ) {
+    //     point.setPosition(position);
+    //   }
+    // }
 
     edgeService.updateEdgeForMovePoint(pointId);
     return true;
@@ -1128,13 +1141,6 @@ export default class MoveRoad {
   //   // 还缺少road和newRoad相交,这需要等另一头的point完成后最后处理
   // }
 
-  deleteRoadForLinked(roadId) {
-    const road = dataService.getRoad(roadId);
-    roadService.subtraRoadFromIntersect(road.startId, roadId);
-    roadService.subtraRoadFromIntersect(road.endId, roadId);
-    dataService.deleteRoad(roadId);
-  }
-
   /******************************************************************************************************************************************************************************/
   moveCurveRoadPoint(pointId, position) {
     // let point = dataService.getCurvePoint(pointId);

+ 151 - 1
src/graphic/Controls/UIControl.js

@@ -2,7 +2,9 @@ import { coordinate } from "../Coordinate.js";
 import LayerEvents from "../enum/LayerEvents.js";
 import UIEvents from "../enum/UIEvents.js";
 import VectorType from "../enum/VectorType.js";
+import VectorStyle from "../enum/VectorStyle.js";
 import GeoActions from "../enum/GeoActions.js";
+import VectorEvents from "../enum/VectorEvents.js";
 import { stateService } from "../Service/StateService.js";
 import { uiService } from "../Service/UIService.js";
 import { dataService } from "../Service/DataService.js";
@@ -25,6 +27,8 @@ import Settings from "../Settings.js";
 import { addPoint } from "./AddPoint.js";
 import { ellipticService } from "../Service/EllipticService.js";
 import { curveRoadPointService } from "../Service/CurveRoadPointService.js";
+import { roadService } from "../Service/RoadService.js";
+import { curveRoadService } from "../Service/CurveRoadService.js";
 
 export default class UIControl {
   constructor(layer, newsletter, graphicStateUI) {
@@ -109,7 +113,136 @@ export default class UIControl {
     }
   }
 
-  updateVectorForSelectUI(selectUI) {}
+  updateVectorForSelectUI(selectUI) {
+    const focusItem = stateService.getFocusItem();
+    if (uiService.isBelongRoadEdgeStyle(selectUI)) {
+      let roadEdge = dataService.getRoadEdge(focusItem.vectorId);
+      if (roadEdge) {
+        roadEdge.setStyle(selectUI);
+      } else {
+        roadEdge = dataService.getCurveRoadEdge(focusItem.vectorId);
+        roadEdge.setStyle(selectUI);
+      }
+    } else if (selectUI == VectorEvents.AddLane) {
+      if (focusItem && focusItem.vectorId) {
+        stateService.setEventName(VectorEvents.AddLane);
+      }
+      // if (focusItem && focusItem.dir && focusItem.vectorId) {
+      //   let road = dataService.getRoad(focusItem.vectorId);
+      //   if (road) {
+      //     if (focusItem.dir == "left") {
+      //       roadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.leftDrivewayCount + 1,
+      //         focusItem.dir
+      //       );
+      //     } else {
+      //       roadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.rightDrivewayCount + 1,
+      //         focusItem.dir
+      //       );
+      //     }
+      //   } else {
+      //     road = dataService.getCurveRoad(focusItem.vectorId);
+      //     if (focusItem.dir == "left") {
+      //       curveRoadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.leftDrivewayCount + 1,
+      //         focusItem.dir
+      //       );
+      //     } else {
+      //       curveRoadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.rightDrivewayCount + 1,
+      //         focusItem.dir
+      //       );
+      //     }
+      //   }
+      // }
+    } else if (selectUI == VectorEvents.DelLane) {
+      if (focusItem && focusItem.vectorId) {
+        stateService.setEventName(VectorEvents.DelLane);
+      }
+      // if (focusItem && focusItem.dir && focusItem.vectorId) {
+      //   let road = dataService.getRoad(focusItem.vectorId);
+      //   if (road) {
+      //     if (focusItem.dir == "left") {
+      //       roadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.leftDrivewayCount - 1,
+      //         focusItem.dir
+      //       );
+      //     } else {
+      //       roadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.rightDrivewayCount - 1,
+      //         focusItem.dir
+      //       );
+      //     }
+      //   } else {
+      //     road = dataService.getCurveRoad(focusItem.vectorId);
+      //     if (focusItem.dir == "left") {
+      //       curveRoadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.leftDrivewayCount - 1,
+      //         focusItem.dir
+      //       );
+      //     } else {
+      //       curveRoadService.updateForAddSubtractLanesCount(
+      //         road.vectorId,
+      //         road.rightDrivewayCount - 1,
+      //         focusItem.dir
+      //       );
+      //     }
+      //   }
+      // }
+    } else if (selectUI == VectorEvents.AddCrossPoint) {
+      if (focusItem && focusItem.vectorId) {
+        stateService.setEventName(VectorEvents.AddCrossPoint);
+      }
+      // if (focusItem && focusItem.dir && focusItem.vectorId) {
+      //   const curveRoad = dataService.getCurveRoad(focusItem.vectorId);
+      //   let index = mathUtil.getIndexForCurvesPoints(
+      //     this.mousePosition,
+      //     curveRoad.points
+      //   );
+      //   if (index != -1) {
+      //     curveRoadService.addCPoint(curveRoad, this.mousePosition, index);
+      //   } else {
+      //     const dis1 = mathUtil.getDistance(
+      //       curveRoad.points[0],
+      //       this.mousePosition
+      //     );
+      //     const dis2 = mathUtil.getDistance(
+      //       curveRoad.points[curveRoad.points.length - 1],
+      //       this.mousePosition
+      //     );
+      //     if (dis1 > dis2) {
+      //       curveRoadService.addCPoint(
+      //         curveRoad,
+      //         this.mousePosition,
+      //         curveRoad.points.length - 2
+      //       );
+      //     } else {
+      //       curveRoadService.addCPoint(curveRoad, this.mousePosition, 1);
+      //     }
+      //   }
+      // }
+    } else if (selectUI == VectorEvents.MinusCrossPoint) {
+      if (focusItem && focusItem.vectorId) {
+        stateService.setEventName(VectorEvents.MinusCrossPoint);
+      }
+      // if (focusItem && focusItem.dir && focusItem.vectorId) {
+      //   const curvePoint = dataService.getCurveRoadPoint(focusItem.vectorId);
+      //   const curveRoad = dataService.getCurveRoad(curvePoint.parent);
+      //   curveRoadService.subCPoint(curveRoad, curvePoint.getIndex());
+      // }
+    } else if (selectUI == VectorEvents.AddBranchRoad) {
+    } else if (selectUI == VectorEvents.AddNarrowRoad) {
+    } else if (selectUI == VectorEvents.UnLock) {
+    }
+  }
 
   async handleGeo(action) {
     let needAutoRedraw = false;
@@ -163,6 +296,12 @@ export default class UIControl {
       case VectorType.Magnifier:
         dataService.deleteMagnifier(vectorId);
         break;
+      case VectorType.Road:
+        roadService.deleteRoadForLinked(vectorId);
+        break;
+      case VectorType.CurveRoad:
+        dataService.deleteCurveRoad(vectorId);
+        break;
     }
     this.layer.exit();
     uiService.setSelectLineCategory(VectorCategory.Line.NormalLine);
@@ -172,6 +311,7 @@ export default class UIControl {
 
   //复制按钮
   async copyVector(vectorId, geoType) {
+    let item;
     switch (geoType) {
       case VectorType.Line:
         lineService.copy(vectorId);
@@ -187,6 +327,16 @@ export default class UIControl {
       case VectorType.Text:
         textService.copy(vectorId);
         break;
+      case VectorType.Road:
+        const roadId = roadService.copyRoad(vectorId);
+        item = stateService.getFocusItem();
+        item.vectorId = roadId;
+        break;
+      case VectorType.CurveRoad:
+        const curveRoadId = curveRoadService.copyCurveRoad(vectorId);
+        item = stateService.getFocusItem();
+        item.vectorId = curveRoadId;
+        break;
       case VectorType.Magnifier:
         await magnifierService.copy(vectorId);
         break;

+ 250 - 17
src/graphic/Layer.js

@@ -42,6 +42,7 @@ import Settings from "./Settings";
 import Constant from "./Constant";
 import { uiService } from "./Service/UIService";
 import { imageService } from "./Service/ImageService";
+import VectorEvents from "./enum/VectorEvents";
 
 const minDragDis = 10;
 const minZoom = 20;
@@ -127,6 +128,7 @@ export default class Layer {
     this.dragging = false;
     //用于支持平板电脑
     listenLayer.start(position);
+    let selectItem = stateService.getSelectItem();
     this.setEventName("mouseDown");
     const eventName = stateService.getEventName();
     switch (eventName) {
@@ -193,8 +195,124 @@ export default class Layer {
         );
         addMagnifier.clear();
         break;
+      case VectorEvents.AddLane:
+        if (selectItem && selectItem.dir && selectItem.vectorId) {
+          let road = dataService.getRoad(selectItem.vectorId);
+          if (road) {
+            if (selectItem.dir == "left") {
+              roadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.leftDrivewayCount + 1,
+                selectItem.dir
+              );
+            } else {
+              roadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.rightDrivewayCount + 1,
+                selectItem.dir
+              );
+            }
+          } else {
+            road = dataService.getCurveRoad(selectItem.vectorId);
+            if (selectItem.dir == "left") {
+              curveRoadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.leftDrivewayCount + 1,
+                selectItem.dir
+              );
+            } else {
+              curveRoadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.rightDrivewayCount + 1,
+                selectItem.dir
+              );
+            }
+          }
+          stateService.clearEventName();
+          this.history.save();
+          this.renderer.autoRedraw();
+        }
+        break;
+      case VectorEvents.DelLane:
+        if (selectItem && selectItem.dir && selectItem.vectorId) {
+          let road = dataService.getRoad(selectItem.vectorId);
+          if (road) {
+            if (selectItem.dir == "left") {
+              roadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.leftDrivewayCount - 1,
+                selectItem.dir
+              );
+            } else {
+              roadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.rightDrivewayCount - 1,
+                selectItem.dir
+              );
+            }
+          } else {
+            road = dataService.getCurveRoad(selectItem.vectorId);
+            if (selectItem.dir == "left") {
+              curveRoadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.leftDrivewayCount - 1,
+                selectItem.dir
+              );
+            } else {
+              curveRoadService.updateForAddSubtractLanesCount(
+                road.vectorId,
+                road.rightDrivewayCount - 1,
+                selectItem.dir
+              );
+            }
+          }
+          stateService.clearEventName();
+          this.history.save();
+          this.renderer.autoRedraw();
+        }
+        break;
+      case VectorEvents.AddCrossPoint:
+        if (selectItem && selectItem.dir && selectItem.vectorId) {
+          const curveRoad = dataService.getCurveRoad(selectItem.vectorId);
+          let index = mathUtil.getIndexForCurvesPoints(
+            position,
+            curveRoad.points
+          );
+          if (index != -1) {
+            curveRoadService.addCPoint(curveRoad, position, index);
+          } else {
+            const dis1 = mathUtil.getDistance(curveRoad.points[0], position);
+            const dis2 = mathUtil.getDistance(
+              curveRoad.points[curveRoad.points.length - 1],
+              position
+            );
+            if (dis1 > dis2) {
+              curveRoadService.addCPoint(
+                curveRoad,
+                position,
+                curveRoad.points.length - 2
+              );
+            } else {
+              curveRoadService.addCPoint(curveRoad, position, 1);
+            }
+          }
+          stateService.clearEventName();
+          this.history.save();
+          this.renderer.autoRedraw();
+        }
+        break;
+      case VectorEvents.MinusCrossPoint:
+        if (selectItem && selectItem.dir && selectItem.vectorId) {
+          const curvePoint = dataService.getCurveRoadPoint(selectItem.vectorId);
+          const curveRoad = dataService.getCurveRoad(curvePoint.parent);
+          curveRoadService.subCPoint(curveRoad, curvePoint.getIndex());
+          stateService.clearEventName();
+          this.history.save();
+          this.renderer.autoRedraw();
+        }
+        break;
     }
-    const selectItem = stateService.getSelectItem();
+    selectItem = stateService.getSelectItem();
     stateService.setDraggingItem(selectItem);
     // 清除上一个状态
     // 设置当前事件名称
@@ -322,7 +440,7 @@ export default class Layer {
         //鼠标样式
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddLine:
         needAutoRedraw = true;
@@ -336,7 +454,7 @@ export default class Layer {
         elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddCurveLine:
         needAutoRedraw = true;
@@ -350,7 +468,7 @@ export default class Layer {
         elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddCircle:
         needAutoRedraw = true;
@@ -403,7 +521,7 @@ export default class Layer {
           elementService.setNewRoadState("normal");
         }
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddingLine:
         needAutoRedraw = true;
@@ -433,7 +551,7 @@ export default class Layer {
         elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddingCurveLine:
         needAutoRedraw = true;
@@ -463,7 +581,7 @@ export default class Layer {
         elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddingCircle:
         needAutoRedraw = true;
@@ -535,11 +653,19 @@ export default class Layer {
           exceptRoadPointId: draggingItem.vectorId,
           exceptRoadIds: point.parent,
         });
-        if (listenLayer.modifyPoint) {
+        if (
+          listenLayer.modifyPoint &&
+          (listenLayer.modifyPoint.linkedRoadPointId ||
+            listenLayer.modifyPoint.linkedRoadId ||
+            listenLayer.modifyPoint.linkedRoadPointIdX ||
+            listenLayer.modifyPoint.linkedRoadPointIdY)
+        ) {
           position = {
             x: listenLayer.modifyPoint.x,
             y: listenLayer.modifyPoint.y,
           };
+        } else {
+          listenLayer.modifyPoint = null;
         }
 
         let flag = moveRoad.moveingRoadPoint(
@@ -550,7 +676,7 @@ export default class Layer {
         if (!flag) {
           elementService.hideAll();
         } else {
-          this.showElementLine(point);
+          this.showElementLine(point, eventName);
         }
         needAutoRedraw = true;
         break;
@@ -566,7 +692,7 @@ export default class Layer {
         elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.AddingCurveRoad:
         needAutoRedraw = true;
@@ -591,7 +717,7 @@ export default class Layer {
           elementService.setNewRoadState("normal");
         }
         elementService.showPoint();
-        this.showElementLine(position);
+        this.showElementLine(position, eventName);
         break;
       case LayerEvents.MoveCurveRoad:
         needAutoRedraw = true;
@@ -610,14 +736,23 @@ export default class Layer {
           exceptRoadPointId: draggingItem.vectorId,
           exceptCurveRoadId: point.parent, //不会融合,所以parent只有一个
         });
-        if (listenLayer.modifyPoint) {
+        if (
+          listenLayer.modifyPoint &&
+          (listenLayer.modifyPoint.linkedRoadPointId ||
+            listenLayer.modifyPoint.linkedRoadId ||
+            listenLayer.modifyPoint.linkedRoadPointIdX ||
+            listenLayer.modifyPoint.linkedRoadPointIdY ||
+            listenLayer.modifyPoint.linkedCurvePointIdX ||
+            listenLayer.modifyPoint.linkedCurvePointIdY ||
+            listenLayer.modifyPoint.linkedCurveRoadPointIdX)
+        ) {
           position = {
             x: listenLayer.modifyPoint.x,
             y: listenLayer.modifyPoint.y,
           };
         }
         moveRoad.moveCurveRoadPoint(draggingItem.vectorId, position);
-        this.showElementLine(point);
+        this.showElementLine(point, eventName);
         needAutoRedraw = true;
         break;
       case LayerEvents.MoveCrossPoint:
@@ -665,7 +800,7 @@ export default class Layer {
             };
           }
           movePoint.movePoint(position, draggingItem.vectorId);
-          this.showElementLine(point);
+          this.showElementLine(point, eventName);
           needAutoRedraw = true;
         }
         break;
@@ -683,7 +818,7 @@ export default class Layer {
             };
           }
           movePoint.moveCurvePoint(position, draggingItem.vectorId);
-          this.showElementLine(curvePoint);
+          this.showElementLine(curvePoint, eventName);
           needAutoRedraw = true;
         }
         break;
@@ -811,6 +946,7 @@ export default class Layer {
         vectorId: selectItem.vectorId,
         type: selectItem.type,
         cursor: { x: this.lastX, y: this.lastY },
+        dir: selectItem.dir,
       };
       stateService.setFocusItem(focusItem);
       this.uiControl.focusVector = focusItem;
@@ -1368,6 +1504,104 @@ export default class Layer {
     }
   }
 
+  // showElementLine(point, eventName) {
+  //   let otherPoint1 = null;
+  //   let otherPoint2 = null;
+  //   if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedRoadPointIdX &&
+  //     (eventName == LayerEvents.AddingRoad ||
+  //       eventName == LayerEvents.MoveRoadPoint ||
+  //       eventName == LayerEvents.AddRoad)
+  //   ) {
+  //     otherPoint1 = dataService.getRoadPoint(
+  //       listenLayer.modifyPoint.linkedRoadPointIdX
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedCurveRoadPointIdX &&
+  //     (eventName == LayerEvents.AddingCurveRoad ||
+  //       eventName == LayerEvents.MoveCurveRoadPoint ||
+  //       eventName == LayerEvents.AddCurveRoad)
+  //   ) {
+  //     otherPoint1 = dataService.getCurveRoadPoint(
+  //       listenLayer.modifyPoint.linkedCurvePointIdX
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedPointIdX &&
+  //     (eventName == LayerEvents.AddLine || eventName == LayerEvents.MovePoint)
+  //   ) {
+  //     otherPoint1 = dataService.getPoint(
+  //       listenLayer.modifyPoint.linkedPointIdX
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedCurvePointIdX &&
+  //     (eventName == LayerEvents.AddCurveLine ||
+  //       eventName == LayerEvents.MoveCurvePoint)
+  //   ) {
+  //     otherPoint1 = dataService.getCurvePoint(
+  //       listenLayer.modifyPoint.linkedCurvePointIdX
+  //     );
+  //   }
+
+  //   if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedRoadPointIdY &&
+  //     (eventName == LayerEvents.AddingRoad ||
+  //       eventName == LayerEvents.MoveRoadPoint ||
+  //       eventName == LayerEvents.AddRoad)
+  //   ) {
+  //     otherPoint2 = dataService.getRoadPoint(
+  //       listenLayer.modifyPoint.linkedRoadPointIdY
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedCurvePointIdY &&
+  //     (eventName == LayerEvents.AddingCurveRoad ||
+  //       eventName == LayerEvents.MoveCurveRoadPoint ||
+  //       eventName == LayerEvents.AddCurveRoad)
+  //   ) {
+  //     otherPoint2 = dataService.getCurveRoadPoint(
+  //       listenLayer.modifyPoint.linkedCurvePointIdY
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedPointIdY &&
+  //     (eventName == LayerEvents.AddLine || eventName == LayerEvents.MovePoint)
+  //   ) {
+  //     otherPoint2 = dataService.getPoint(
+  //       listenLayer.modifyPoint.linkedPointIdY
+  //     );
+  //   } else if (
+  //     listenLayer.modifyPoint &&
+  //     listenLayer.modifyPoint.linkedCurvePointIdY &&
+  //     (eventName == LayerEvents.AddCurveLine ||
+  //       eventName == LayerEvents.MoveCurvePoint)
+  //   ) {
+  //     otherPoint2 = dataService.getCurvePoint(
+  //       listenLayer.modifyPoint.linkedCurvePointIdY
+  //     );
+  //   }
+
+  //   let otherPoint = {};
+  //   if (otherPoint1) {
+  //     otherPoint.x = otherPoint1.x;
+  //     otherPoint.y = otherPoint1.y;
+  //   }
+  //   if (otherPoint2) {
+  //     otherPoint.y = otherPoint2.y;
+  //     if (!otherPoint.hasOwnProperty("x")) {
+  //       otherPoint.x = otherPoint2.x;
+  //     }
+  //   }
+  //   if (otherPoint.hasOwnProperty("x") && otherPoint.hasOwnProperty("y")) {
+  //     elementService.execute(otherPoint, point);
+  //   } else {
+  //     elementService.hideAll();
+  //   }
+  // }
   showElementLine(point) {
     let otherPoint1 = null;
     let otherPoint2 = null;
@@ -1377,7 +1611,7 @@ export default class Layer {
       );
     } else if (
       listenLayer.modifyPoint &&
-      listenLayer.modifyPoint.linkedCurvePointIdX
+      listenLayer.modifyPoint.linkedCurveRoadPointIdX
     ) {
       otherPoint1 = dataService.getCurveRoadPoint(
         listenLayer.modifyPoint.linkedCurvePointIdX
@@ -1436,7 +1670,6 @@ export default class Layer {
         otherPoint.x = otherPoint2.x;
       }
     }
-
     elementService.execute(otherPoint, point);
   }
 }

+ 103 - 52
src/graphic/ListenLayer.js

@@ -603,6 +603,7 @@ export default class ListenLayer {
       roadId: null,
       type: null,
       distance: null,
+      dir: null,
     };
     let edgeInfo = {
       edgeId: null,
@@ -622,10 +623,29 @@ export default class ListenLayer {
       const rightEdge = dataService.getRoadEdge(road.rightEdgeId);
       const roadLine = roadService.getMidLine(road);
       let join = mathUtil.getJoinLinePoint(position, roadLine);
+
+      let leftLine = mathUtil.createLine1(leftEdge.start, leftEdge.end);
+      let leftJoin = mathUtil.getJoinLinePoint(position, leftLine);
+      let rightLine = mathUtil.createLine1(rightEdge.start, rightEdge.end);
+      let rightJoin = mathUtil.getJoinLinePoint(position, rightLine);
+
+      // let distance = this.getDistance(position, join);
+      // if (
+      //   mathUtil.isContainForSegment(join, startPoint, endPoint) &&
+      //   distance < Constant.minAdsorbPix
+      // ) {
+      //   if (!roadInfo.roadId || distance < roadInfo.distance) {
+      //     roadInfo = {
+      //       roadId: roadId,
+      //       type: VectorType.Road,
+      //       distance: distance,
+      //     };
+      //   }
+      // }
       let distance = this.getDistance(position, join);
       if (
-        mathUtil.isContainForSegment(join, startPoint, endPoint) &&
-        distance < Constant.minAdsorbPix
+        mathUtil.isContainForSegment(position, join, leftJoin) ||
+        mathUtil.isContainForSegment(position, join, rightJoin)
       ) {
         if (!roadInfo.roadId || distance < roadInfo.distance) {
           roadInfo = {
@@ -637,12 +657,10 @@ export default class ListenLayer {
       }
 
       //检查edge
-      let leftLine = mathUtil.createLine1(leftEdge.start, leftEdge.end);
-      join = mathUtil.getJoinLinePoint(position, leftLine);
-      distance = this.getDistance(position, join);
+      distance = this.getDistance(position, leftJoin);
       if (
-        mathUtil.isContainForSegment(join, leftEdge.start, leftEdge.end) &&
-        distance < Constant.minAdsorbPix
+        mathUtil.isContainForSegment(leftJoin, leftEdge.start, leftEdge.end) &&
+        distance < Constant.minAdsorbPix / 2
       ) {
         if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
           edgeInfo = {
@@ -654,12 +672,14 @@ export default class ListenLayer {
         }
       }
 
-      let rightLine = mathUtil.createLine1(rightEdge.start, rightEdge.end);
-      join = mathUtil.getJoinLinePoint(position, rightLine);
-      distance = this.getDistance(position, join);
+      distance = this.getDistance(position, rightJoin);
       if (
-        mathUtil.isContainForSegment(join, rightEdge.start, rightEdge.end) &&
-        distance < Constant.minAdsorbPix
+        mathUtil.isContainForSegment(
+          rightJoin,
+          rightEdge.start,
+          rightEdge.end
+        ) &&
+        distance < Constant.minAdsorbPix / 2
       ) {
         if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
           edgeInfo = {
@@ -670,6 +690,19 @@ export default class ListenLayer {
           };
         }
       }
+
+      if (roadInfo.roadId && !edgeInfo.edgeId) {
+        const join1 = mathUtil.getJoinLinePoint(position, leftLine);
+        const join2 = mathUtil.getJoinLinePoint(position, rightLine);
+        if (
+          mathUtil.getDistance(join1, position) >
+          mathUtil.getDistance(join2, position)
+        ) {
+          roadInfo.dir = "right";
+        } else {
+          roadInfo.dir = "left";
+        }
+      }
     }
 
     if (
@@ -684,6 +717,9 @@ export default class ListenLayer {
       );
       roadInfo.x = linkedPosition.x;
       roadInfo.y = linkedPosition.y;
+      if (edgeInfo.dir && !roadInfo.dir) {
+        roadInfo.dir = edgeInfo.dir;
+      }
       return roadInfo;
     } else if (edgeInfo.edgeId) {
       if (edgeInfo.dir == "left") {
@@ -741,51 +777,59 @@ export default class ListenLayer {
         };
       }
       //检查edge
-      else {
-        const leftCurveEdge = dataService.getCurveRoadEdge(
-          curveRoad.leftEdgeId
-        );
-        joinInfo = this.distanceForBezier(
-          position,
-          leftCurveEdge.curves,
-          Constant.minAdsorbPix
+      const leftCurveEdge = dataService.getCurveRoadEdge(curveRoad.leftEdgeId);
+      const leftJoinInfo = this.distanceForBezier(
+        position,
+        leftCurveEdge.curves,
+        Constant.minAdsorbPix
+      );
+
+      const rightCurveEdge = dataService.getCurveRoadEdge(
+        curveRoad.rightEdgeId
+      );
+      const rightJoinInfo = this.distanceForBezier(
+        position,
+        rightCurveEdge.curves,
+        Constant.minAdsorbPix
+      );
+      if (curveRoadInfo.curveRoadId) {
+        if (
+          mathUtil.getDistance(position, leftJoinInfo.position) >
+          mathUtil.getDistance(position, rightJoinInfo.position)
+        ) {
+          curveRoadInfo.dir = "right";
+        } else {
+          curveRoadInfo.dir = "left";
+        }
+      }
+
+      if (leftJoinInfo.distance < Constant.minAdsorbPix) {
+        const index = mathUtil.getIndexForCurvesPoints(
+          leftJoinInfo.position,
+          curveRoad.points
         );
-        if (joinInfo.distance < Constant.minAdsorbPix) {
+        curveEdgeInfo = {
+          curveEdgeId: curveRoad.leftEdgeId,
+          type: VectorType.CurveRoadEdge,
+          distance: leftJoinInfo.distance,
+          selectIndex: index,
+          x: leftJoinInfo.position.x,
+          y: leftJoinInfo.position.y,
+        };
+      } else {
+        if (rightJoinInfo.distance < Constant.minAdsorbPix) {
           const index = mathUtil.getIndexForCurvesPoints(
-            joinInfo.position,
+            rightJoinInfo.position,
             curveRoad.points
           );
           curveEdgeInfo = {
-            curveEdgeId: curveRoad.leftEdgeId,
+            curveEdgeId: curveRoad.rightEdgeId,
             type: VectorType.CurveRoadEdge,
-            distance: joinInfo.distance,
+            distance: rightJoinInfo.distance,
             selectIndex: index,
-            x: joinInfo.position.x,
-            y: joinInfo.position.y,
+            x: rightJoinInfo.position.x,
+            y: rightJoinInfo.position.y,
           };
-        } else {
-          const rightCurveEdge = dataService.getCurveRoadEdge(
-            curveRoad.rightEdgeId
-          );
-          joinInfo = this.distanceForBezier(
-            position,
-            rightCurveEdge.curves,
-            Constant.minAdsorbPix
-          );
-          if (joinInfo.distance < Constant.minAdsorbPix) {
-            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,
-            };
-          }
         }
       }
     }
@@ -1007,19 +1051,23 @@ export default class ListenLayer {
           this.modifyPoint.linkedRoadId = info.roadEdgeInfo.roadId;
           this.modifyPoint.x = info.roadEdgeInfo.x;
           this.modifyPoint.y = info.roadEdgeInfo.y;
+          this.modifyPoint.dir = info.roadEdgeInfo.dir;
         } else {
           this.modifyPoint.linkedCurveRoadId = curveRoadEdgeInfo.curveRoadId;
           this.modifyPoint.x = info.curveRoadEdgeInfo.x;
           this.modifyPoint.y = info.curveRoadEdgeInfo.y;
+          this.modifyPoint.dir = info.curveRoadEdgeInfo.dir;
         }
       } else if (info.roadEdgeInfo.roadId) {
         this.modifyPoint.linkedRoadId = info.roadEdgeInfo.roadId;
         this.modifyPoint.x = info.roadEdgeInfo.x;
         this.modifyPoint.y = info.roadEdgeInfo.y;
+        this.modifyPoint.dir = info.roadEdgeInfo.dir;
       } else if (info.curveRoadEdgeInfo.curveRoadId) {
         this.modifyPoint.linkedCurveRoadId = info.curveRoadEdgeInfo.curveRoadId;
         this.modifyPoint.x = info.curveRoadEdgeInfo.x;
         this.modifyPoint.y = info.curveRoadEdgeInfo.y;
+        this.modifyPoint.dir = info.curveRoadEdgeInfo.dir;
       }
     } else if (info && info.crossPointInfo.crossCrossPointId) {
       this.modifyPoint = {};
@@ -1180,19 +1228,22 @@ export default class ListenLayer {
       stateService.setSelectItem(
         this.modifyPoint.linkedCurveRoadPointId,
         VectorType.CurveRoadPoint,
-        SelectState.Select
+        SelectState.Select,
+        this.modifyPoint.dir
       );
     } else if (this.modifyPoint.linkedRoadId) {
       stateService.setSelectItem(
         this.modifyPoint.linkedRoadId,
         VectorType.Road,
-        SelectState.Select
+        SelectState.Select,
+        this.modifyPoint.dir
       );
     } else if (this.modifyPoint.linkedCurveRoadId) {
       stateService.setSelectItem(
         this.modifyPoint.linkedCurveRoadId,
         VectorType.CurveRoad,
-        SelectState.Select
+        SelectState.Select,
+        this.modifyPoint.dir
       );
     } else if (this.modifyPoint.linkedCrossCrossPointId) {
       stateService.setSelectItem(

+ 89 - 0
src/graphic/Service/CurveRoadService.js

@@ -96,6 +96,95 @@ export default class CurveRoadService extends RoadService {
     return curveRoad;
   }
 
+  copyCurveRoad(vectorId) {
+    let curveRoad = dataService.getCurveRoad(vectorId);
+    let startPoint = dataService.getCurveRoadPoint(curveRoad.startId);
+    let endPoint = dataService.getCurveRoadPoint(curveRoad.endId);
+
+    let newStartPoint = uiService.getNewPositionForPop(startPoint);
+    newStartPoint = curveRoadPointService.create(newStartPoint);
+    let newEndPoint = uiService.getNewPositionForPop(endPoint);
+    newEndPoint = curveRoadPointService.create(newEndPoint);
+
+    let newCurveRoad = new CurveRoad(
+      newStartPoint.vectorId,
+      newEndPoint.vectorId
+    );
+    dataService.addCurveRoad(newCurveRoad);
+
+    newStartPoint.setPointParent(curveRoad.vectorId);
+    newStartPoint.setIndex(0);
+
+    newEndPoint.setPointParent(curveRoad.vectorId);
+    newEndPoint.setIndex(endPoint.getIndex());
+
+    newCurveRoad.setWay(curveRoad.way);
+    newCurveRoad.singleRoadWidth = curveRoad.singleRoadWidth;
+    newCurveRoad.leftWidth = curveRoad.leftWidth;
+    newCurveRoad.rightWidth = curveRoad.rightWidth;
+
+    let edgePoints;
+    if (newCurveRoad.way == Constant.oneWay) {
+      edgePoints = mathUtil.RectangleVertex(
+        startPoint,
+        endPoint,
+        curveRoad.singleRoadWidth
+      );
+    } else {
+      edgePoints = mathUtil.RectangleVertex(
+        startPoint,
+        endPoint,
+        curveRoad.leftWidth +
+          curveRoad.rightWidth +
+          curveRoad.midDivide.midDivideWidth
+      );
+    }
+
+    let leftEdge = curveEdgeService.create(
+      edgePoints.leftEdgeStart,
+      edgePoints.leftEdgeEnd,
+      null,
+      vectorId
+    );
+
+    let rightEdge = curveEdgeService.create(
+      edgePoints.rightEdgeStart,
+      edgePoints.rightEdgeEnd,
+      null,
+      vectorId
+    );
+
+    curveRoad.setLeftEdge(leftEdge.vectorId);
+    curveRoad.setRightEdge(rightEdge.vectorId);
+    if (!vectorId) {
+      leftEdge.setEdgeParent(curveRoad.vectorId);
+      rightEdge.setEdgeParent(curveRoad.vectorId);
+    }
+
+    curveRoad.points.push(startPoint);
+    curveRoad.points.push(endPoint);
+
+    leftEdge.points.push(edgePoints.leftEdgeStart);
+    leftEdge.points.push(edgePoints.leftEdgeEnd);
+
+    rightEdge.points.push(edgePoints.rightEdgeStart);
+    rightEdge.points.push(edgePoints.rightEdgeEnd);
+
+    for (let i = 1; i < curveRoad.points.length - 1; ++i) {
+      this.addCPoint(
+        newCurveRoad,
+        curveRoad.points[i],
+        curveRoad.points[i].getIndex()
+      );
+    }
+
+    newCurveRoad.singleRoadDrivewayCount = curveRoad.singleRoadDrivewayCount;
+    newCurveRoad.leftDrivewayCount = curveRoad.leftDrivewayCount;
+    newCurveRoad.rightDrivewayCount = curveRoad.rightDrivewayCount;
+    this.setLanes(newCurveRoad.vectorId);
+    return newCurveRoad.vectorId;
+  }
+
   //不能加首尾,只能加中间
   //完全不处理车道,都放在setLanes上处理
   addCPoint(curveRoad, position, startIndex) {

+ 72 - 0
src/graphic/Service/RoadService.js

@@ -1,5 +1,6 @@
 import RoadPoint from "../Geometry/RoadPoint.js";
 import Road from "../Geometry/Road.js";
+import CurveRoad from "../Geometry/CurveRoad.js";
 import { dataService } from "./DataService.js";
 import { roadPointService } from "./RoadPointService.js";
 import { edgeService } from "./EdgeService.js";
@@ -7,6 +8,8 @@ import { mathUtil } from "../Util/MathUtil.js";
 import Constant from "../Constant";
 import { crossPointService } from "./CrossPointService.js";
 import { lineService } from "./LineService.js";
+import { uiService } from "./UIService.js";
+
 export default class RoadService {
   constructor() {}
 
@@ -71,6 +74,68 @@ export default class RoadService {
     return road;
   }
 
+  copyRoad(vectorId) {
+    let road = dataService.getRoad(vectorId);
+    let startPoint = dataService.getRoadPoint(road.startId);
+    let endPoint = dataService.getRoadPoint(road.endId);
+
+    let newStartPoint = uiService.getNewPositionForPop(startPoint);
+    newStartPoint = roadPointService.create(newStartPoint);
+    let newEndPoint = uiService.getNewPositionForPop(endPoint);
+    newEndPoint = roadPointService.create(newEndPoint);
+
+    let newRoad = new Road(newStartPoint.vectorId, newEndPoint.vectorId);
+    dataService.addRoad(newRoad);
+
+    newStartPoint.setPointParent(newRoad.vectorId, "start");
+    newEndPoint.setPointParent(newRoad.vectorId, "end");
+
+    newRoad.setWay(road.way);
+    newRoad.singleRoadWidth = road.singleRoadWidth;
+    newRoad.leftWidth = road.leftWidth;
+    newRoad.rightWidth = road.rightWidth;
+
+    let edgePoints;
+    if (newRoad.way == Constant.oneWay) {
+      edgePoints = mathUtil.RectangleVertex(
+        newStartPoint,
+        newEndPoint,
+        road.singleRoadWidth
+      );
+    } else {
+      edgePoints = mathUtil.RectangleVertex(
+        newStartPoint,
+        newEndPoint,
+        road.leftWidth + road.rightWidth + road.midDivide.midDivideWidth
+      );
+    }
+    let leftEdge = edgeService.create(
+      edgePoints.leftEdgeStart,
+      edgePoints.leftEdgeEnd,
+      null,
+      vectorId
+    );
+
+    let rightEdge = edgeService.create(
+      edgePoints.rightEdgeStart,
+      edgePoints.rightEdgeEnd,
+      null,
+      vectorId
+    );
+
+    newRoad.setLeftEdge(leftEdge.vectorId);
+    newRoad.setRightEdge(rightEdge.vectorId);
+    if (!vectorId) {
+      leftEdge.setEdgeParent(newRoad.vectorId);
+      rightEdge.setEdgeParent(newRoad.vectorId);
+    }
+    newRoad.singleRoadDrivewayCount = road.singleRoadDrivewayCount;
+    newRoad.leftDrivewayCount = road.leftDrivewayCount;
+    newRoad.rightDrivewayCount = road.rightDrivewayCount;
+    this.setLanes(newRoad.vectorId);
+    return newRoad.vectorId;
+  }
+
   getMidLine(road) {
     let startPoint = dataService.getRoadPoint(road.startId);
     let endPoint = dataService.getRoadPoint(road.endId);
@@ -538,6 +603,13 @@ export default class RoadService {
     this.setLanes(roadId, null, dir);
   }
 
+  deleteRoadForLinked(roadId) {
+    const road = dataService.getRoad(roadId);
+    this.subtraRoadFromIntersect(road.startId, roadId);
+    this.subtraRoadFromIntersect(road.endId, roadId);
+    dataService.deleteRoad(roadId);
+  }
+
   setRoadPointId = function (roadId, pointId, dir) {
     const vectorInfo = {};
     vectorInfo.roadId = roadId;

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

@@ -24,11 +24,12 @@ export default class StateService {
   }
 
   // type表示类型,state默认是select,但是有的元素需要知道选中的是哪个顶点
-  setSelectItem(vectorId, type, state) {
+  setSelectItem(vectorId, type, state, dir) {
     this.selectItem = {};
     this.selectItem.vectorId = vectorId;
     this.selectItem.type = type;
     this.selectItem.state = state;
+    this.selectItem.dir = dir;
 
     if (type == VectorType.Line) {
       const line = dataService.getLine(vectorId);

+ 25 - 0
src/graphic/Service/UIService.js

@@ -6,6 +6,7 @@ import { coordinate } from "../Coordinate.js";
 import UIEvents from "../enum/UIEvents.js";
 import VectorCategory from "../enum/VectorCategory.js";
 import Constant from "../Constant.js";
+import VectorStyle from "../enum/VectorStyle.js";
 
 export default class UIService {
   constructor() {}
@@ -111,6 +112,30 @@ export default class UIService {
     }
   }
 
+  isBelongRoadEdgeStyle(ui) {
+    if (ui == VectorStyle.SingleSolidLine) {
+      return true;
+    } else if (ui == VectorStyle.SingleDashedLine) {
+      return true;
+    } else if (ui == VectorStyle.DoubleSolidLine) {
+      return true;
+    } else if (ui == VectorStyle.DoubleDashedLine) {
+      return true;
+    } else if (ui == VectorStyle.BrokenLine) {
+      return true;
+    } else if (ui == VectorStyle.PointDrawLine) {
+      return true;
+    } else if (ui == VectorStyle.Greenbelt) {
+      return true;
+    } else if (ui == VectorStyle.Bold) {
+      return true;
+    } else if (ui == VectorStyle.Thinning) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   setWayType(value) {
     Settings.wayType = value;
   }

+ 1 - 19
src/graphic/enum/VectorEvents.js

@@ -6,24 +6,6 @@ const VectorEvents = {
   AddCrossPoint: "AddCrossPoint",
   // 减控制点
   MinusCrossPoint: "MinusCrossPoint",
-  // 单实线
-  SingleSolidLine: "SingleSolidLine",
-  // 单虚线
-  SingleDashedLine: "SingleDashedLine",
-  // 双实线
-  DoubleSolidLine: "DoubleSolidLine",
-  // 双虚线
-  DoubleDashedLine: "DoubleDashedLine",
-  // 折线
-  BrokenLine: "BrokenLine",
-  // 点画线
-  PointDrawLine: "PointDrawLine",
-  // 绿化带
-  Greenbelt: "Greenbelt",
-  // 加粗
-  Bold: "Bold",
-  // 变细
-  Thinning: "Thinning",
   // 加支路
   AddBranchRoad: "AddBranchRoad",
   // 加窄路
@@ -31,7 +13,7 @@ const VectorEvents = {
   // 加车道
   AddLane: "AddLane",
   // 减车道
-  DelLane: "DelLane"
+  DelLane: "DelLane",
 };
 
 export default VectorEvents;