xushiting %!s(int64=2) %!d(string=hai) anos
pai
achega
2ce7e63a53

+ 4 - 2
src/graphic/Constant.js

@@ -24,11 +24,13 @@ const Constant = {
   // miniMap_Width: 1200,
   // miniMap_Height: 1200,
   minLen: 0.2, //挨着,比如:点是否在线段上
-  minAdsorbPix: 20, //最小吸附像素
-  minRealDis: 20,
+  minAdsorbPix: 10, //最小吸附像素
+  minRealDis: 10,
   defaultRoadWidth: 100, //默认公路宽度
   ratio: 1,
   minAngle: 10,
   maxAngle: 170,
+  minRoadSideWidth: 20,
+  maxRoadSideWidth: 800,
 };
 export default Constant;

+ 58 - 2
src/graphic/Controls/MoveRoad.js

@@ -156,8 +156,8 @@ export default class MoveRoad {
   }
 
   getNewPointsForMoveRoad(roadId, dx, dy) {
-    dx = dx / coordinate.res;
-    dy = -dy / coordinate.res;
+    dx = dx;
+    dy = -dy;
 
     const road = dataService.getRoad(roadId);
     const startPoint = dataService.getPoint(road.startId);
@@ -1142,6 +1142,62 @@ export default class MoveRoad {
   moveControlPoint(controlPointId, position) {
     controlPointService.updateForMovePoint(controlPointId, position);
   }
+
+  moveEdge(edgeId, position) {
+    const edge = dataService.getEdge(edgeId);
+    const parent = edge.getParent();
+    const road = dataService.getRoad(parent);
+    const line = roadService.getMidLine(road);
+
+    let dir = "left";
+    if (road.rightEdgeId == edgeId) {
+      dir = "right";
+    }
+
+    const newWidth = mathUtil.getDisForPoinLine(position, line);
+    if (
+      newWidth > Constant.minRoadSideWidth &&
+      newWidth < Constant.maxRoadSideWidth
+    ) {
+      roadService.updateForWidth(parent, newWidth, dir);
+    }
+  }
+
+  moveCurveEdge(curveEdgeId, index, position) {
+    const curveEdge = dataService.getCurveEdge(curveEdgeId);
+    const parent = curveEdge.getParent();
+    const curveRoad = dataService.getCurveRoad(parent);
+    let joinInfo = null;
+    let dir = "left";
+    if (curveRoad.rightEdgeId == curveEdgeId) {
+      dir = "right";
+    }
+    // const line = mathUtil.createLine1(
+    //   curveRoad.points[index],
+    //   curveRoad.points[index + 1]
+    // );
+    // const newWidth = mathUtil.getDisForPoinLine(position, line);
+    if (dir == "left") {
+      joinInfo = mathUtil.getHitInfoForCurve(
+        position,
+        curveRoad.curves[index],
+        curveRoad.leftWidth * 2
+      );
+    } else if (dir == "right") {
+      joinInfo = mathUtil.getHitInfoForCurve(
+        position,
+        curveRoad.curves[index],
+        curveRoad.rightWidth * 2
+      );
+    }
+    const newWidth = mathUtil.getDistance(joinInfo.position, position);
+    if (
+      newWidth > Constant.minRoadSideWidth &&
+      newWidth < Constant.maxRoadSideWidth
+    ) {
+      curveRoadService.updateForWidth(parent, newWidth, dir);
+    }
+  }
   /******************************************************************************************************************************************************************************/
 }
 

+ 46 - 11
src/graphic/Layer.js

@@ -370,6 +370,20 @@ export default class Layer {
         moveRoad.moveControlPoint(draggingItem.vectorId, position);
         needAutoRedraw = true;
         break;
+      case LayerEvents.MoveEdge:
+        moveRoad.moveEdge(draggingItem.vectorId, position);
+        needAutoRedraw = true;
+        break;
+      case LayerEvents.MoveCurveEdge:
+        if (listenLayer.modifyPoint) {
+          moveRoad.moveCurveEdge(
+            draggingItem.vectorId,
+            listenLayer.modifyPoint.selectIndex,
+            position
+          );
+        }
+        needAutoRedraw = true;
+        break;
       case LayerEvents.AddTag:
         needAutoRedraw = true;
         if (draggingItem == null) {
@@ -530,6 +544,14 @@ export default class Layer {
         needAutoRedraw = true;
         this.history.save();
         break;
+      case LayerEvents.MoveEdge:
+        needAutoRedraw = true;
+        this.history.save();
+        break;
+      case LayerEvents.MoveCurveEdge:
+        needAutoRedraw = true;
+        this.history.save();
+        break;
       case LayerEvents.MoveTag:
         needAutoRedraw = true;
         if (focusItem != null && focusItem.type == VectorType.Tag) {
@@ -595,10 +617,14 @@ export default class Layer {
       else if (e.code == "KeyA") {
         let road = dataService.getRoad(focusItem.vectorId);
         if (road) {
-          roadService.updateForWidth(road.vectorId, road.width + 50, dir);
+          roadService.updateForWidth(road.vectorId, road.leftWidth + 50, dir);
         } else {
           road = dataService.getCurveRoad(focusItem.vectorId);
-          curveRoadService.updateForWidth(road.vectorId, road.width + 50, dir);
+          curveRoadService.updateForWidth(
+            road.vectorId,
+            road.leftWidth + 50,
+            dir
+          );
         }
 
         this.renderer.autoRedraw();
@@ -608,10 +634,14 @@ export default class Layer {
       else if (e.code == "KeyB") {
         let road = dataService.getRoad(focusItem.vectorId);
         if (road) {
-          roadService.updateForWidth(road.vectorId, road.width - 25, dir);
+          roadService.updateForWidth(road.vectorId, road.leftWidth - 25, dir);
         } else {
           road = dataService.getCurveRoad(focusItem.vectorId);
-          curveRoadService.updateForWidth(road.vectorId, road.width - 25, dir);
+          curveRoadService.updateForWidth(
+            road.vectorId,
+            road.leftWidth - 25,
+            dir
+          );
         }
         this.renderer.autoRedraw();
         this.history.save();
@@ -758,13 +788,18 @@ export default class Layer {
           stateService.setEventName(LayerEvents.MoveCurveRoadPoint);
         } else if (selectItem.type == VectorType.ControlPoint) {
           stateService.setEventName(LayerEvents.MoveControlPoint);
-        } else if (selectItem.type == VectorType.Tag) {
-          stateService.setEventName(LayerEvents.MoveTag);
-        } else if (selectItem.type == VectorType.MeasureLine) {
-          stateService.setEventName(LayerEvents.MoveMeasureLine);
-        } else if (selectItem.type == VectorType.MeasureArrow) {
-          stateService.setEventName(LayerEvents.MoveMeasureArrow);
-        }
+        } else if (selectItem.type == VectorType.Edge) {
+          stateService.setEventName(LayerEvents.MoveEdge);
+        } else if (selectItem.type == VectorType.CurveEdge) {
+          stateService.setEventName(LayerEvents.MoveCurveEdge);
+        }
+        // else if (selectItem.type == VectorType.Tag) {
+        //   stateService.setEventName(LayerEvents.MoveTag);
+        // } else if (selectItem.type == VectorType.MeasureLine) {
+        //   stateService.setEventName(LayerEvents.MoveMeasureLine);
+        // } else if (selectItem.type == VectorType.MeasureArrow) {
+        //   stateService.setEventName(LayerEvents.MoveMeasureArrow);
+        // }
       }
     } else if (eventType == "mouseUp") {
       if (eventName == LayerEvents.AddTag) {

+ 213 - 141
src/graphic/ListenLayer.js

@@ -9,49 +9,11 @@ import bezierUtil from "./Util/bezierUtil.js";
 import { elementService } from "./Service/ElementService";
 import { coordinate } from "./Coordinate";
 import { draw } from "./Renderer/Draw.js";
+import { edgeService } from "./Service/EdgeService";
 
 export default class ListenLayer {
   constructor() {
-    this.roadInfo = {
-      roadId: null,
-      type: null,
-      state: null,
-    };
-
-    this.curveRoadInfo = {
-      curveRoadId: null,
-      type: null,
-      state: null,
-    };
-
-    this.pointInfo = {
-      pointId: null,
-      type: null,
-      state: null,
-    };
-
-    this.curvePointInfo = {
-      curvePointId: null,
-      type: null,
-      state: null,
-    };
-
-    this.crossControlPointInfo = {
-      crossControlPointId: null,
-      type: null,
-      distance: null,
-    };
-
-    this.tagInfo = {
-      tagId: null,
-      state: null,
-    };
-
     this.modifyPoint = null;
-
-    // this.testStart = null;
-    // this.testEnd = null;
-    // this.testHit = false;
   }
 
   //开始监听,exceptPointId表示不考虑的点,exceptRoadIds表示不考虑的墙
@@ -65,29 +27,24 @@ export default class ListenLayer {
   ) {
     let flag = false;
     this.clear();
-    let curveRoadInfo = this.isSelectCurveRoad(position, exceptCurveRoadId);
-    let roadInfo = this.isSelectRoad(position, exceptRoadIds);
+    let curveRoadEdgeInfo = this.isSelectCurveRoad(position, exceptCurveRoadId);
+    let roadEdgeInfo = this.isSelectRoad(position, exceptRoadIds);
     let curvePointInfo = this.isSelectCurvePoint(position, exceptCurvePointId);
     let pointInfo = this.isSelectPoint(position, exceptPointId);
     //交叉口拐弯处的控制点
     let controlPointInfo = this.isSelectCrossControlPoint(
       position,
-      exceptPointId
+      exceptCrossControlPointId
     );
 
     this.setModifyPoint(
       position,
       pointInfo,
       curvePointInfo,
-      roadInfo,
-      curveRoadInfo,
+      roadEdgeInfo,
+      curveRoadEdgeInfo,
       controlPointInfo
     );
-    // let flag1 = this.equalAndClone(this.curveRoadInfo, curveRoadInfo);
-    // let flag2 = this.equalAndClone(this.roadInfo, roadInfo);
-    // let flag3 = this.equalAndClone(this.curvePointInfo, curvePointInfo);
-    // let flag4 = this.equalAndClone(this.pointInfo, pointInfo);
-    // isSame = this.updateSelectItem(flag1, flag2, flag3, flag4);
     flag = this.updateSelectItem();
     return flag;
   }
@@ -242,6 +199,12 @@ export default class ListenLayer {
       type: null,
       distance: null,
     };
+    let edgeInfo = {
+      edgeId: null,
+      type: null,
+      distance: null,
+      dir: null,
+    };
     const roads = dataService.getRoads();
     for (const roadId in roads) {
       if (exceptRoadIds != null && exceptRoadIds.hasOwnProperty(roadId)) {
@@ -253,29 +216,48 @@ export default class ListenLayer {
       const roadLine = roadService.getMidLine(road);
       const join = mathUtil.getJoinLinePoint(position, roadLine);
       const distance = mathUtil.getDistance(position, join);
-      let width = road.rightWidth;
-      //逆时针的时候,position在左区域
-      if (distance > 1 && mathUtil.isClockwise([startPoint, join, position])) {
-        width = road.leftWidth;
+      if (!mathUtil.isContainForSegment(join, startPoint, endPoint)) {
+        return roadInfo;
       }
-      if (
-        distance < width &&
-        mathUtil.isContainForSegment(join, startPoint, endPoint)
-      ) {
-        if (roadInfo.roadId == null) {
+      if (distance < Constant.minAdsorbPix / 2) {
+        roadInfo = {
+          roadId: roadId,
+          type: VectorType.Road,
+          distance: distance,
+        };
+      }
+      //左边
+      else if (mathUtil.isClockwise([startPoint, join, position])) {
+        if (distance < road.leftWidth - Constant.minAdsorbPix) {
           roadInfo = {
             roadId: roadId,
             type: VectorType.Road,
             distance: distance,
           };
-        } else if (roadInfo.roadId != null) {
-          if (distance < roadInfo.distance) {
-            roadInfo = {
-              roadId: roadId,
-              type: VectorType.Road,
-              distance: mathUtil.getDisForPoinLine(position, roadLine),
-            };
-          }
+        } else if (distance < road.leftWidth + Constant.minAdsorbPix) {
+          edgeInfo = {
+            edgeId: road.leftEdgeId,
+            type: VectorType.Edge,
+            distance: distance,
+            dir: "left",
+          };
+        }
+      }
+      //右边
+      else {
+        if (distance < road.rightWidth - Constant.minAdsorbPix) {
+          roadInfo = {
+            roadId: roadId,
+            type: VectorType.Road,
+            distance: distance,
+          };
+        } else if (distance < road.rightWidth + Constant.minAdsorbPix) {
+          edgeInfo = {
+            edgeId: road.rightEdgeId,
+            type: VectorType.Edge,
+            distance: distance,
+            dir: "right",
+          };
         }
       }
     }
@@ -289,8 +271,27 @@ export default class ListenLayer {
       );
       roadInfo.x = linkedPosition.x;
       roadInfo.y = linkedPosition.y;
+      return roadInfo;
+    } else if (edgeInfo.edgeId) {
+      if (edgeInfo.dir == "left") {
+        const leftEdge = dataService.getEdge(edgeInfo.edgeId);
+        const leftLine = edgeService.getLine(leftEdge);
+        const linkedPosition = mathUtil.getJoinLinePoint(position, leftLine);
+        edgeInfo.x = linkedPosition.x;
+        edgeInfo.y = linkedPosition.y;
+      } else {
+        const rightEdge = dataService.getEdge(edgeInfo.edgeId);
+        const rightLine = edgeService.getLine(rightEdge);
+        const linkedPosition = mathUtil.getJoinLinePoint(position, rightLine);
+        edgeInfo.x = linkedPosition.x;
+        edgeInfo.y = linkedPosition.y;
+      }
+      return edgeInfo;
     }
-    return roadInfo;
+    return {
+      roadId: null,
+      edgeId: null,
+    };
   }
 
   isSelectCurveRoad(position, exceptCurveRoadId) {
@@ -299,6 +300,11 @@ export default class ListenLayer {
       type: null,
       distance: null,
     };
+    let curveEdgeInfo = {
+      curveEdgeId: null,
+      type: null,
+      distance: null,
+    };
 
     const curveRoads = dataService.getCurveRoads();
     for (const curveRoadId in curveRoads) {
@@ -311,33 +317,99 @@ export default class ListenLayer {
         curveRoad.curves,
         Math.max(curveRoad.leftWidth, curveRoad.rightWidth)
       );
+
       if (
-        (mathUtil.isClockwise([
+        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.getCurveEdge(curveRoad.leftEdgeId);
+          joinInfo = this.distanceForBezier(
+            position,
+            leftCurveEdge.curves,
+            curveRoad.leftWidth
+          );
+          const index = mathUtil.getIndexForCurvesPoints(
+            joinInfo.position,
+            curveRoad.points
+          );
+          curveEdgeInfo = {
+            curveEdgeId: curveRoad.leftEdgeId,
+            type: VectorType.CurveEdge,
+            distance: joinInfo.distance,
+            selectIndex: index,
+            x: joinInfo.position.x,
+            y: joinInfo.position.y,
+          };
+        }
+      } else if (
+        !mathUtil.isClockwise([
           curveRoad.points[0],
           joinInfo.position,
           position,
-        ]) &&
-          joinInfo.distance < curveRoad.leftWidth) ||
-        (mathUtil.isClockwise([
-          curveRoad.points[curveRoad.points.length - 1],
-          joinInfo.position,
-          position,
-        ]) &&
-          joinInfo.distance < curveRoad.rightWidth)
+        ])
       ) {
-        curveRoadInfo = {
-          curveRoadId: curveRoadId,
-          type: VectorType.CurveRoad,
-          distance: joinInfo.distance,
-          x: joinInfo.position.x,
-          y: joinInfo.position.y,
-        };
-
-        // draw.drawTestLine(position, joinInfo.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.getCurveEdge(
+            curveRoad.rightEdgeId
+          );
+          joinInfo = this.distanceForBezier(
+            position,
+            rightCurveEdge.curves,
+            curveRoad.rightWidth
+          );
+          const index = mathUtil.getIndexForCurvesPoints(
+            joinInfo.position,
+            curveRoad.points
+          );
+          curveEdgeInfo = {
+            curveEdgeId: curveRoad.rightEdgeId,
+            type: VectorType.CurveEdge,
+            distance: joinInfo.distance,
+            selectIndex: index,
+            x: joinInfo.position.x,
+            y: joinInfo.position.y,
+          };
+        }
       }
     }
-
-    return curveRoadInfo;
+    if (curveRoadInfo.curveRoadId) {
+      return curveRoadInfo;
+    } else if (curveEdgeInfo.curveEdgeId) {
+      return curveEdgeInfo;
+    } else {
+      return {
+        curveRoadId: null,
+        curveEdgeId: null,
+      };
+    }
   }
 
   isSelectCrossControlPoint(position, exceptCrossControlPointId) {
@@ -371,8 +443,8 @@ export default class ListenLayer {
     position,
     pointInfo,
     curvePointInfo,
-    roadInfo,
-    curveRoadInfo,
+    roadEdgeInfo,
+    curveRoadEdgeInfo,
     controlPointInfo
   ) {
     //优先级最高
@@ -397,26 +469,49 @@ export default class ListenLayer {
         this.modifyPoint.x = curvePointInfo.x;
         this.modifyPoint.y = curvePointInfo.y;
       }
-    } else if (roadInfo.roadId || curveRoadInfo.curveRoadId) {
+    } else if (roadEdgeInfo.roadId || curveRoadEdgeInfo.curveRoadId) {
       this.modifyPoint = {};
-      if (roadInfo.roadId && curveRoadInfo.curveRoadId) {
-        if (roadInfo.distance < curveRoadInfo.distance) {
-          this.modifyPoint.linkedRoadId = roadInfo.roadId;
-          this.modifyPoint.x = roadInfo.x;
-          this.modifyPoint.y = roadInfo.y;
+      if (roadEdgeInfo.roadId && curveRoadEdgeInfo.curveRoadId) {
+        if (roadEdgeInfo.distance < curveRoadEdgeInfo.distance) {
+          this.modifyPoint.linkedRoadId = roadEdgeInfo.roadId;
+          this.modifyPoint.x = roadEdgeInfo.x;
+          this.modifyPoint.y = roadEdgeInfo.y;
         } else {
-          this.modifyPoint.linkedCurveRoadId = curveRoadInfo.curveRoadId;
-          this.modifyPoint.x = curveRoadInfo.x;
-          this.modifyPoint.y = curveRoadInfo.y;
+          this.modifyPoint.linkedCurveRoadId = curveRoadEdgeInfo.curveRoadId;
+          this.modifyPoint.x = curveRoadEdgeInfo.x;
+          this.modifyPoint.y = curveRoadEdgeInfo.y;
         }
-      } else if (roadInfo.roadId) {
-        this.modifyPoint.linkedRoadId = roadInfo.roadId;
-        this.modifyPoint.x = roadInfo.x;
-        this.modifyPoint.y = roadInfo.y;
-      } else if (curveRoadInfo.curveRoadId) {
-        this.modifyPoint.linkedCurveRoadId = curveRoadInfo.curveRoadId;
-        this.modifyPoint.x = curveRoadInfo.x;
-        this.modifyPoint.y = curveRoadInfo.y;
+      } else if (roadEdgeInfo.roadId) {
+        this.modifyPoint.linkedRoadId = roadEdgeInfo.roadId;
+        this.modifyPoint.x = roadEdgeInfo.x;
+        this.modifyPoint.y = roadEdgeInfo.y;
+      } else if (curveRoadEdgeInfo.curveRoadId) {
+        this.modifyPoint.linkedCurveRoadId = curveRoadEdgeInfo.curveRoadId;
+        this.modifyPoint.x = curveRoadEdgeInfo.x;
+        this.modifyPoint.y = curveRoadEdgeInfo.y;
+      }
+    } else if (roadEdgeInfo.edgeId || curveRoadEdgeInfo.curveEdgeId) {
+      this.modifyPoint = {};
+      if (roadEdgeInfo.edgeId && curveRoadEdgeInfo.curveEdgeId) {
+        if (roadEdgeInfo.distance < curveRoadEdgeInfo.distance) {
+          this.modifyPoint.linkedEdgeId = roadEdgeInfo.edgeId;
+          this.modifyPoint.x = roadEdgeInfo.x;
+          this.modifyPoint.y = roadEdgeInfo.y;
+        } else {
+          this.modifyPoint.linkedCurveEdgeId = curveRoadEdgeInfo.curveEdgeId;
+          this.modifyPoint.selectIndex = curveRoadEdgeInfo.selectIndex;
+          this.modifyPoint.x = curveRoadEdgeInfo.x;
+          this.modifyPoint.y = curveRoadEdgeInfo.y;
+        }
+      } else if (roadEdgeInfo.edgeId) {
+        this.modifyPoint.linkedEdgeId = roadEdgeInfo.edgeId;
+        this.modifyPoint.x = roadEdgeInfo.x;
+        this.modifyPoint.y = roadEdgeInfo.y;
+      } else if (curveRoadEdgeInfo.curveEdgeId) {
+        this.modifyPoint.linkedCurveEdgeId = curveRoadEdgeInfo.curveEdgeId;
+        this.modifyPoint.selectIndex = curveRoadEdgeInfo.selectIndex;
+        this.modifyPoint.x = curveRoadEdgeInfo.x;
+        this.modifyPoint.y = curveRoadEdgeInfo.y;
       }
     } else if (controlPointInfo.crossControlPointId) {
       this.modifyPoint = {};
@@ -488,6 +583,18 @@ export default class ListenLayer {
         VectorType.ControlPoint,
         SelectState.Select
       );
+    } else if (this.modifyPoint.linkedEdgeId) {
+      stateService.setSelectItem(
+        this.modifyPoint.linkedEdgeId,
+        VectorType.Edge,
+        SelectState.Select
+      );
+    } else if (this.modifyPoint.linkedCurveEdgeId) {
+      stateService.setSelectItem(
+        this.modifyPoint.linkedCurveEdgeId,
+        VectorType.CurveEdge,
+        SelectState.Select
+      );
     }
 
     let newSelectItem = stateService.getSelectItem();
@@ -521,41 +628,6 @@ export default class ListenLayer {
   }
 
   clear() {
-    this.roadInfo = {
-      roadId: null,
-      type: null,
-      state: null,
-    };
-
-    this.curveRoadInfo = {
-      curveRoadId: null,
-      type: null,
-      state: null,
-    };
-
-    this.pointInfo = {
-      pointId: null,
-      type: null,
-      state: null,
-    };
-
-    this.curvePointInfo = {
-      curvePointId: null,
-      type: null,
-      state: null,
-    };
-
-    this.crossControlPointInfo = {
-      crossControlPointId: null,
-      type: null,
-      distance: null,
-    };
-
-    this.tagInfo = {
-      tagId: null,
-      state: null,
-    };
-
     this.modifyPoint = null;
   }
 }

+ 199 - 164
src/graphic/Service/CurveRoadService.js

@@ -402,181 +402,216 @@ export default class CurveRoadService extends RoadService {
     curveRoad.rightLanes = [];
   }
 
+  // updateForMovePoint(pointId, position) {
+  //   let curvePoint = dataService.getCurvePoint(pointId);
+  //   let curveRoadId = curvePoint.getParent();
+  //   let curveRoad = dataService.getCurveRoad(curveRoadId);
+
+  //   let index = curvePoint.getIndex();
+  //   let dx = position.x - curvePoint.x;
+  //   let dy = position.y - curvePoint.y;
+
+  //   curvePoint.setPosition(position);
+
+  //   let line = null;
+  //   let join = null;
+  //   let len = curveRoad.points.length;
+
+  //   const leftCurveEdge = dataService.getCurveEdge(curveRoad.leftEdgeId);
+  //   leftCurveEdge.points[index].x += dx;
+  //   leftCurveEdge.points[index].y += dy;
+
+  //   const rightCurveEdge = dataService.getCurveEdge(curveRoad.rightEdgeId);
+  //   rightCurveEdge.points[index].x += dx;
+  //   rightCurveEdge.points[index].y += dy;
+
+  //   if (index == 0 || index == 1) {
+  //     line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
+  //     if (
+  //       line != null &&
+  //       !line.hasOwnProperty("x") &&
+  //       !line.hasOwnProperty("y")
+  //     ) {
+  //       let line1 = mathUtil.createLine3(line, leftCurveEdge.points[index]);
+  //       join = mathUtil.getJoinLinePoint(curveRoad.points[0], line1);
+  //       leftCurveEdge.points[0].x = join.x;
+  //       leftCurveEdge.points[0].y = join.y;
+  //       leftCurveEdge.start.x = join.x;
+  //       leftCurveEdge.start.y = join.y;
+
+  //       let line2 = mathUtil.createLine3(line, rightCurveEdge.points[index]);
+  //       join = mathUtil.getJoinLinePoint(curveRoad.points[0], line2);
+  //       rightCurveEdge.points[0].x = join.x;
+  //       rightCurveEdge.points[0].y = join.y;
+  //       rightCurveEdge.start.x = join.x;
+  //       rightCurveEdge.start.y = join.y;
+  //     }
+  //   }
+
+  //   if (
+  //     index == curveRoad.points.length - 1 ||
+  //     index == curveRoad.points.length - 2
+  //   ) {
+  //     line = mathUtil.createLine1(
+  //       curveRoad.points[len - 2],
+  //       curveRoad.points[len - 1]
+  //     );
+  //     if (
+  //       line != null &&
+  //       !line.hasOwnProperty("x") &&
+  //       !line.hasOwnProperty("y")
+  //     ) {
+  //       let line1 = mathUtil.createLine3(line, leftCurveEdge.points[index]);
+  //       join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line1);
+  //       leftCurveEdge.points[len - 1].x = join.x;
+  //       leftCurveEdge.points[len - 1].y = join.y;
+  //       leftCurveEdge.end.x = join.x;
+  //       leftCurveEdge.end.y = join.y;
+  //       let line2 = mathUtil.createLine3(line, rightCurveEdge.points[index]);
+  //       join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line2);
+  //       rightCurveEdge.points[len - 1].x = join.x;
+  //       rightCurveEdge.points[len - 1].y = join.y;
+  //       rightCurveEdge.end.x = join.x;
+  //       rightCurveEdge.end.y = join.y;
+  //     }
+  //   }
+
+  //   for (let i = 0; i < curveRoad.leftLanes.length; ++i) {
+  //     curveRoad.leftLanes[i][index].x += dx;
+  //     curveRoad.leftLanes[i][index].y += dy;
+  //     //需要修改端点
+  //     if (
+  //       index == 0 ||
+  //       index == 1 ||
+  //       index == curveRoad.points.length - 1 ||
+  //       index == curveRoad.points.length - 2
+  //     ) {
+  //       if (index == 0 || index == 1) {
+  //         line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
+  //         if (
+  //           line != null &&
+  //           !line.hasOwnProperty("x") &&
+  //           !line.hasOwnProperty("y")
+  //         ) {
+  //           line = mathUtil.createLine3(line, curveRoad.leftLanes[i][index]);
+  //           join = mathUtil.getJoinLinePoint(curveRoad.points[0], line);
+  //           curveRoad.leftLanes[i][0].x = join.x;
+  //           curveRoad.leftLanes[i][0].y = join.y;
+  //         }
+  //       }
+
+  //       if (
+  //         index == curveRoad.points.length - 1 ||
+  //         index == curveRoad.points.length - 2
+  //       ) {
+  //         line = mathUtil.createLine1(
+  //           curveRoad.points[len - 2],
+  //           curveRoad.points[len - 1]
+  //         );
+  //         if (
+  //           line != null &&
+  //           !line.hasOwnProperty("x") &&
+  //           !line.hasOwnProperty("y")
+  //         ) {
+  //           line = mathUtil.createLine3(line, curveRoad.leftLanes[i][index]);
+  //           join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line);
+  //           curveRoad.leftLanes[i][len - 1].x = join.x;
+  //           curveRoad.leftLanes[i][len - 1].y = join.y;
+  //         }
+  //       }
+  //     }
+
+  //     curveRoad.leftLanesCurves[i] = mathUtil.getCurvesByPoints(
+  //       curveRoad.leftLanes[i]
+  //     );
+  //   }
+  //   for (let i = 0; i < curveRoad.rightLanes.length; ++i) {
+  //     curveRoad.rightLanes[i][index].x += dx;
+  //     curveRoad.rightLanes[i][index].y += dy;
+  //     //需要修改端点
+  //     if (
+  //       index == 0 ||
+  //       index == 1 ||
+  //       index == curveRoad.points.length - 1 ||
+  //       index == curveRoad.points.length - 2
+  //     ) {
+  //       if (index == 0 || index == 1) {
+  //         line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
+  //         if (
+  //           line != null &&
+  //           !line.hasOwnProperty("x") &&
+  //           !line.hasOwnProperty("y")
+  //         ) {
+  //           line = mathUtil.createLine3(line, curveRoad.rightLanes[i][index]);
+  //           join = mathUtil.getJoinLinePoint(curveRoad.points[0], line);
+  //           curveRoad.rightLanes[i][0].x = join.x;
+  //           curveRoad.rightLanes[i][0].y = join.y;
+  //         }
+  //       }
+  //       if (
+  //         index == curveRoad.points.length - 1 ||
+  //         index == curveRoad.points.length - 2
+  //       ) {
+  //         line = mathUtil.createLine1(
+  //           curveRoad.points[len - 2],
+  //           curveRoad.points[len - 1]
+  //         );
+  //         if (
+  //           line != null &&
+  //           !line.hasOwnProperty("x") &&
+  //           !line.hasOwnProperty("y")
+  //         ) {
+  //           line = mathUtil.createLine3(line, curveRoad.rightLanes[i][index]);
+  //           join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line);
+  //           curveRoad.rightLanes[i][len - 1].x = join.x;
+  //           curveRoad.rightLanes[i][len - 1].y = join.y;
+  //         }
+  //       }
+  //     }
+
+  //     curveRoad.rightLanesCurves[i] = mathUtil.getCurvesByPoints(
+  //       curveRoad.rightLanes[i]
+  //     );
+  //   }
+
+  //   this.setCurves(curveRoad);
+  //   curveEdgeService.setCurves(leftCurveEdge);
+  //   curveEdgeService.setCurves(rightCurveEdge);
+  // }
+
   updateForMovePoint(pointId, position) {
     let curvePoint = dataService.getCurvePoint(pointId);
     let curveRoadId = curvePoint.getParent();
     let curveRoad = dataService.getCurveRoad(curveRoadId);
-
+    let startPoint = dataService.getCurvePoint(curveRoad.startId);
+    let endPoint = dataService.getCurvePoint(curveRoad.endId);
     let index = curvePoint.getIndex();
-    let dx = position.x - curvePoint.x;
-    let dy = position.y - curvePoint.y;
-
-    curvePoint.setPosition(position);
-
-    let line = null;
-    let join = null;
-    let len = curveRoad.points.length;
+    mathUtil.clonePoint(curveRoad.points[index], position);
+    if (index == 0) {
+      mathUtil.clonePoint(startPoint, position);
+    } else if (index == curveRoad.points.length - 1) {
+      mathUtil.clonePoint(endPoint, position);
+    }
+    const edgePoints = mathUtil.getOffset(
+      curveRoad.points,
+      curveRoad.leftWidth,
+      curveRoad.rightWidth
+    );
 
     const leftCurveEdge = dataService.getCurveEdge(curveRoad.leftEdgeId);
-    leftCurveEdge.points[index].x += dx;
-    leftCurveEdge.points[index].y += dy;
-
+    leftCurveEdge.points = edgePoints.leftEdgePoints;
+    leftCurveEdge.start = leftCurveEdge.points[0];
+    leftCurveEdge.end = leftCurveEdge.points[leftCurveEdge.points.length - 1];
     const rightCurveEdge = dataService.getCurveEdge(curveRoad.rightEdgeId);
-    rightCurveEdge.points[index].x += dx;
-    rightCurveEdge.points[index].y += dy;
-
-    if (index == 0 || index == 1) {
-      line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
-      if (
-        line != null &&
-        !line.hasOwnProperty("x") &&
-        !line.hasOwnProperty("y")
-      ) {
-        let line1 = mathUtil.createLine3(line, leftCurveEdge.points[index]);
-        join = mathUtil.getJoinLinePoint(curveRoad.points[0], line1);
-        leftCurveEdge.points[0].x = join.x;
-        leftCurveEdge.points[0].y = join.y;
-        leftCurveEdge.start.x = join.x;
-        leftCurveEdge.start.y = join.y;
-
-        let line2 = mathUtil.createLine3(line, rightCurveEdge.points[index]);
-        join = mathUtil.getJoinLinePoint(curveRoad.points[0], line2);
-        rightCurveEdge.points[0].x = join.x;
-        rightCurveEdge.points[0].y = join.y;
-        rightCurveEdge.start.x = join.x;
-        rightCurveEdge.start.y = join.y;
-      }
-    }
-
-    if (
-      index == curveRoad.points.length - 1 ||
-      index == curveRoad.points.length - 2
-    ) {
-      line = mathUtil.createLine1(
-        curveRoad.points[len - 2],
-        curveRoad.points[len - 1]
-      );
-      if (
-        line != null &&
-        !line.hasOwnProperty("x") &&
-        !line.hasOwnProperty("y")
-      ) {
-        let line1 = mathUtil.createLine3(line, leftCurveEdge.points[index]);
-        join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line1);
-        leftCurveEdge.points[len - 1].x = join.x;
-        leftCurveEdge.points[len - 1].y = join.y;
-        leftCurveEdge.end.x = join.x;
-        leftCurveEdge.end.y = join.y;
-        let line2 = mathUtil.createLine3(line, rightCurveEdge.points[index]);
-        join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line2);
-        rightCurveEdge.points[len - 1].x = join.x;
-        rightCurveEdge.points[len - 1].y = join.y;
-        rightCurveEdge.end.x = join.x;
-        rightCurveEdge.end.y = join.y;
-      }
-    }
-
-    for (let i = 0; i < curveRoad.leftLanes.length; ++i) {
-      curveRoad.leftLanes[i][index].x += dx;
-      curveRoad.leftLanes[i][index].y += dy;
-      //需要修改端点
-      if (
-        index == 0 ||
-        index == 1 ||
-        index == curveRoad.points.length - 1 ||
-        index == curveRoad.points.length - 2
-      ) {
-        if (index == 0 || index == 1) {
-          line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
-          if (
-            line != null &&
-            !line.hasOwnProperty("x") &&
-            !line.hasOwnProperty("y")
-          ) {
-            line = mathUtil.createLine3(line, curveRoad.leftLanes[i][index]);
-            join = mathUtil.getJoinLinePoint(curveRoad.points[0], line);
-            curveRoad.leftLanes[i][0].x = join.x;
-            curveRoad.leftLanes[i][0].y = join.y;
-          }
-        }
-
-        if (
-          index == curveRoad.points.length - 1 ||
-          index == curveRoad.points.length - 2
-        ) {
-          line = mathUtil.createLine1(
-            curveRoad.points[len - 2],
-            curveRoad.points[len - 1]
-          );
-          if (
-            line != null &&
-            !line.hasOwnProperty("x") &&
-            !line.hasOwnProperty("y")
-          ) {
-            line = mathUtil.createLine3(line, curveRoad.leftLanes[i][index]);
-            join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line);
-            curveRoad.leftLanes[i][len - 1].x = join.x;
-            curveRoad.leftLanes[i][len - 1].y = join.y;
-          }
-        }
-      }
+    rightCurveEdge.points = edgePoints.rightEdgePoints;
+    rightCurveEdge.start = rightCurveEdge.points[0];
+    rightCurveEdge.end =
+      rightCurveEdge.points[rightCurveEdge.points.length - 1];
 
-      curveRoad.leftLanesCurves[i] = mathUtil.getCurvesByPoints(
-        curveRoad.leftLanes[i]
-      );
-    }
-    for (let i = 0; i < curveRoad.rightLanes.length; ++i) {
-      curveRoad.rightLanes[i][index].x += dx;
-      curveRoad.rightLanes[i][index].y += dy;
-      //需要修改端点
-      if (
-        index == 0 ||
-        index == 1 ||
-        index == curveRoad.points.length - 1 ||
-        index == curveRoad.points.length - 2
-      ) {
-        if (index == 0 || index == 1) {
-          line = mathUtil.createLine1(curveRoad.points[0], curveRoad.points[1]);
-          if (
-            line != null &&
-            !line.hasOwnProperty("x") &&
-            !line.hasOwnProperty("y")
-          ) {
-            line = mathUtil.createLine3(line, curveRoad.rightLanes[i][index]);
-            join = mathUtil.getJoinLinePoint(curveRoad.points[0], line);
-            curveRoad.rightLanes[i][0].x = join.x;
-            curveRoad.rightLanes[i][0].y = join.y;
-          }
-        }
-        if (
-          index == curveRoad.points.length - 1 ||
-          index == curveRoad.points.length - 2
-        ) {
-          line = mathUtil.createLine1(
-            curveRoad.points[len - 2],
-            curveRoad.points[len - 1]
-          );
-          if (
-            line != null &&
-            !line.hasOwnProperty("x") &&
-            !line.hasOwnProperty("y")
-          ) {
-            line = mathUtil.createLine3(line, curveRoad.rightLanes[i][index]);
-            join = mathUtil.getJoinLinePoint(curveRoad.points[len - 1], line);
-            curveRoad.rightLanes[i][len - 1].x = join.x;
-            curveRoad.rightLanes[i][len - 1].y = join.y;
-          }
-        }
-      }
-
-      curveRoad.rightLanesCurves[i] = mathUtil.getCurvesByPoints(
-        curveRoad.rightLanes[i]
-      );
-    }
-
-    this.setCurves(curveRoad);
     curveEdgeService.setCurves(leftCurveEdge);
     curveEdgeService.setCurves(rightCurveEdge);
+    this.setCurves(curveRoad);
+    this.setLanes(curveRoad);
   }
 
   //变宽或者变窄(车道数据不变)

+ 1 - 1
src/graphic/Service/RoadService.js

@@ -1133,7 +1133,7 @@ export default class RoadService {
     let endPoint = dataService.getPoint(road.endId);
     let leftEdge = dataService.getEdge(road.leftEdgeId);
     let rightEdge = dataService.getEdge(road.rightEdgeId);
-
+    road.setWidth(newWidth, dir);
     let edgePoints = mathUtil.RectangleVertex(startPoint, endPoint, newWidth);
     if (dir == "left") {
       mathUtil.clonePoint(leftEdge.start, edgePoints.leftEdgeStart);

+ 167 - 28
src/graphic/Util/MathUtil.js

@@ -1072,39 +1072,33 @@ export default class MathUtil {
 
   // 当前点 下一个点 下下个点
   getCurvesControls(p1, pt, p2, scale = 0.3) {
-    const vec1T = mathUtil.pointMinus(p1, pt);
-    const vecT2 = mathUtil.pointMinus(p1, pt);
+    const vec1T = this.pointMinus(p1, pt);
+    const vecT2 = this.pointMinus(p1, pt);
     const len1 = Math.hypot(vec1T.x, vec1T.y);
     const len2 = Math.hypot(vecT2.x, vecT2.y);
     const v = len1 / len2;
 
     let delta;
     if (v > 1) {
-      delta = mathUtil.pointMinus(
+      delta = this.pointMinus(
         p1,
-        mathUtil.pointPlus(
-          pt,
-          mathUtil.pointScale(mathUtil.pointMinus(p2, pt), 1 / v)
-        )
+        this.pointPlus(pt, this.pointScale(this.pointMinus(p2, pt), 1 / v))
       );
     } else {
-      delta = mathUtil.pointMinus(
-        mathUtil.pointPlus(
-          pt,
-          mathUtil.pointScale(mathUtil.pointMinus(p1, pt), v)
-        ),
+      delta = this.pointMinus(
+        this.pointPlus(pt, this.pointScale(this.pointMinus(p1, pt), v)),
         p2
       );
     }
-    delta = mathUtil.pointScale(delta, scale);
+    delta = this.pointScale(delta, scale);
 
     const control1 = {
-      x: mathUtil.pointPlus(pt, delta).x,
-      y: mathUtil.pointPlus(pt, delta).y,
+      x: this.pointPlus(pt, delta).x,
+      y: this.pointPlus(pt, delta).y,
     };
     const control2 = {
-      x: mathUtil.pointMinus(pt, delta).x,
-      y: mathUtil.pointMinus(pt, delta).y,
+      x: this.pointMinus(pt, delta).x,
+      y: this.pointMinus(pt, delta).y,
     };
     return { control1, control2 };
   }
@@ -1113,7 +1107,7 @@ export default class MathUtil {
     const curves = [];
     let preControl1, preControl2;
     for (let i = 0; i < points.length - 2; i++) {
-      const { control1, control2 } = mathUtil.getCurvesControls(
+      const { control1, control2 } = this.getCurvesControls(
         points[i],
         points[i + 1],
         points[i + 2],
@@ -1248,7 +1242,7 @@ export default class MathUtil {
   getHitInfoForThreeBezier(position, curve, rang = 3) {
     const { x: offsetX, y: offsetY } = position;
     // 用 x 求出对应的 t,用 t 求相应位置的 y,再比较得出的 y 与 offsetY 之间的差值
-    const tsx = mathUtil.getThreeBezierT(
+    const tsx = this.getThreeBezierT(
       curve.start.x,
       curve.controls[0].x,
       curve.controls[1].x,
@@ -1257,7 +1251,7 @@ export default class MathUtil {
     );
     for (let x = 0; x < 3; x++) {
       if (tsx[x] <= 1 && tsx[x] >= 0) {
-        const point = mathUtil.getThreeBezierPoint(
+        const point = this.getThreeBezierPoint(
           tsx[x],
           curve.start,
           curve.controls[0],
@@ -1267,13 +1261,13 @@ export default class MathUtil {
         if (Math.abs(point.y - offsetY) < rang) {
           return {
             position: point,
-            distance: mathUtil.getDistance(point, position),
+            distance: this.getDistance(point, position),
           };
         }
       }
     }
     // 如果上述没有结果,则用 y 求出对应的 t,再用 t 求出对应的 x,与 offsetX 进行匹配
-    const tsy = mathUtil.getThreeBezierT(
+    const tsy = this.getThreeBezierT(
       curve.start.y,
       curve.controls[0].y,
       curve.controls[1].y,
@@ -1282,7 +1276,7 @@ export default class MathUtil {
     );
     for (let y = 0; y < 3; y++) {
       if (tsy[y] <= 1 && tsy[y] >= 0) {
-        const point = mathUtil.getThreeBezierPoint(
+        const point = this.getThreeBezierPoint(
           tsy[y],
           curve.start,
           curve.controls[0],
@@ -1292,7 +1286,7 @@ export default class MathUtil {
         if (Math.abs(point.x - offsetX) < rang) {
           return {
             position: point,
-            distance: mathUtil.getDistance(point, position),
+            distance: this.getDistance(point, position),
           };
         }
       }
@@ -1315,7 +1309,7 @@ export default class MathUtil {
         x: point[0],
         y: point[1],
       },
-      distance: mathUtil.getDistance(position, {
+      distance: this.getDistance(position, {
         x: point[0],
         y: point[1],
       }),
@@ -1327,8 +1321,8 @@ export default class MathUtil {
     for (const curve of curves) {
       const tempJoinInfo =
         curve.controls.length === 2
-          ? mathUtil.getHitInfoForThreeBezier(pos, curve, roadWidth / 2)
-          : mathUtil.getHitInfoForTwoBezier(pos, curve);
+          ? this.getHitInfoForThreeBezier(pos, curve, roadWidth / 2)
+          : this.getHitInfoForTwoBezier(pos, curve);
 
       if (
         !joinInfo ||
@@ -1340,13 +1334,29 @@ export default class MathUtil {
     return joinInfo;
   }
 
+  getHitInfoForCurve(pos, curve, roadWidth) {
+    let joinInfo;
+    const tempJoinInfo =
+      curve.controls.length === 2
+        ? this.getHitInfoForThreeBezier(pos, curve, roadWidth / 2)
+        : this.getHitInfoForTwoBezier(pos, curve);
+
+    if (
+      !joinInfo ||
+      (tempJoinInfo && tempJoinInfo.distance < joinInfo.distance)
+    ) {
+      joinInfo = tempJoinInfo;
+    }
+    return joinInfo;
+  }
+
   getIndexForCurvesPoints(position, points) {
     let minDis = null;
     let index = -1;
     for (let i = 0; i < points.length - 1; ++i) {
       const line = this.createLine1(points[i], points[i + 1]);
       const join = this.getJoinLinePoint(position, line);
-      const dis = mathUtil.getDistance(position, join);
+      const dis = this.getDistance(position, join);
       if (this.isContainForSegment(join, points[i], points[i + 1])) {
         if (minDis == null || minDis > dis) {
           minDis = dis;
@@ -1356,6 +1366,135 @@ export default class MathUtil {
     }
     return index;
   }
+
+  // //获取一组点的偏移
+  // getOffset(points, leftWidth, rightWidth, dir) {
+  //   //斜边长度d已知,角度angle已知
+  //   //对边长度就是y的偏移量 就是 d * sin(angle) ==> d * Math.sin(angle * Math.PI / 180)
+  //   //邻边长度就是x的偏移量 就是 d * cos(angle) ==> d * Math.cos(angle * Math.PI / 180)
+  //   let result = {};
+  //   if (dir == "left" || !dir) {
+  //     let angle = 90;
+  //     let d = leftWidth;
+  //     result.leftEdgePoints = points.map((coords) => {
+  //       let ox = d * Math.cos((angle * Math.PI) / 180);
+  //       let oy = d * Math.sin((angle * Math.PI) / 180);
+  //       return {
+  //         x: coords.x + ox,
+  //         y: coords.y + oy,
+  //       };
+  //     });
+  //   }
+
+  //   if (dir == "right" || !dir) {
+  //     let angle = -90;
+  //     let d = rightWidth;
+
+  //     result.rightEdgePoints = points.map((coords) => {
+  //       let ox = d * Math.cos((angle * Math.PI) / 180);
+  //       let oy = d * Math.sin((angle * Math.PI) / 180);
+  //       return {
+  //         x: coords.x + ox,
+  //         y: coords.y + oy,
+  //       };
+  //     });
+  //   }
+  //   return result;
+  // }
+
+  getOffset(points, leftWidth, rightWidth, dir) {
+    let leftEdgePoints = [];
+    let rightEdgePoints = [];
+    for (let i = 0; i < points.length - 1; ++i) {
+      if (dir == "left" || !dir) {
+        let leftEdgePoins1 = this.RectangleVertex(
+          points[i],
+          points[i + 1],
+          leftWidth * 2
+        );
+        let leftLine1 = mathUtil.createLine1(
+          leftEdgePoins1.leftEdgeStart,
+          leftEdgePoins1.leftEdgeEnd
+        );
+        if (i != points.length - 2) {
+          let leftEdgePoins2 = this.RectangleVertex(
+            points[i + 1],
+            points[i + 2],
+            leftWidth * 2
+          );
+
+          let leftLine2 = mathUtil.createLine1(
+            leftEdgePoins2.leftEdgeStart,
+            leftEdgePoins2.leftEdgeEnd
+          );
+          let join = mathUtil.getIntersectionPoint(leftLine1, leftLine2);
+          if (join != null) {
+            leftEdgePoints[i + 1] = join;
+          } else {
+            leftEdgePoints[i + 1] = mathUtil.getJoinLinePoint(
+              points[i + 1],
+              leftLine1
+            );
+          }
+        } else {
+          leftEdgePoints[i + 1] = mathUtil.getJoinLinePoint(
+            points[i + 1],
+            leftLine1
+          );
+        }
+        if (!leftEdgePoints[0]) {
+          leftEdgePoints[0] = mathUtil.getJoinLinePoint(points[0], leftLine1);
+        }
+      }
+
+      if (dir == "right" || !dir) {
+        let rightEdgePoins1 = this.RectangleVertex(
+          points[i],
+          points[i + 1],
+          rightWidth * 2
+        );
+        let rightLine1 = mathUtil.createLine1(
+          rightEdgePoins1.rightEdgeStart,
+          rightEdgePoins1.rightEdgeEnd
+        );
+        if (i != points.length - 2) {
+          let rightEdgePoins2 = this.RectangleVertex(
+            points[i + 1],
+            points[i + 2],
+            rightWidth * 2
+          );
+
+          let rightLine2 = mathUtil.createLine1(
+            rightEdgePoins2.rightEdgeStart,
+            rightEdgePoins2.rightEdgeEnd
+          );
+          let join = mathUtil.getIntersectionPoint(rightLine1, rightLine2);
+          if (join != null) {
+            rightEdgePoints[i + 1] = join;
+          } else {
+            rightEdgePoints[i + 1] = mathUtil.getJoinLinePoint(
+              points[i + 1],
+              rightLine1
+            );
+          }
+        } else {
+          rightEdgePoints[i + 1] = mathUtil.getJoinLinePoint(
+            points[i + 1],
+            rightLine1
+          );
+        }
+
+        if (!rightEdgePoints[0]) {
+          rightEdgePoints[0] = mathUtil.getJoinLinePoint(points[0], rightLine1);
+        }
+      }
+    }
+
+    return {
+      leftEdgePoints: leftEdgePoints,
+      rightEdgePoints: rightEdgePoints,
+    };
+  }
 }
 
 const mathUtil = new MathUtil();

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

@@ -12,6 +12,8 @@ const LayerEvents = {
   MoveCurveRoadPoint: "moveCurveRoadPoint",
 
   MoveControlPoint: "moveControlPoint",
+  MoveEdge: "moveEdge",
+  MoveCurveEdge: "moveCurveEdge",
 
   AddTag: "addTag",
   MoveTag: "moveTag",