Browse Source

继续绘图

xushiting 2 years ago
parent
commit
69883aa2a1

+ 10 - 1
src/graphic/Controls/AddRoad.js

@@ -3,7 +3,7 @@ import Constant from "../Constant";
 import { mathUtil } from "../Util/MathUtil";
 import { dataService } from "../Service/DataService";
 import { pointService } from "../Service/PointService";
-import { elementService } from "../Service/ElementService";
+import { curveRoadService } from "../Service/CurveRoadService";
 import { stateService } from "../Service/StateService";
 import VectorType from "../enum/VectorType";
 import { roadService } from "../Service/RoadService";
@@ -299,6 +299,15 @@ export default class AddRoad {
     return false;
   }
 
+  /******************************************************************************************************************************************************************************/
+  buildCurveRoad() {
+    console.log("添加曲线路段!");
+    const start = pointService.create(this.startInfo.position);
+    const end = pointService.create(this.endInfo.position);
+    curveRoadService.create(start.vectorId, end.vectorId);
+    listenLayer.clear();
+  }
+  /******************************************************************************************************************************************************************************/
   clear() {
     this.startInfo = {};
     this.endInfo = {};

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

@@ -66,49 +66,7 @@ export default class MoveRoad {
       point.setPosition(position);
     }
 
-    // let newPosition = null;
     if (modifyPoint == null) {
-      // //90°或者180°纠正
-      // //不考虑当前角度
-
-      // //当前点的parent只有一个,考虑邻居点
-      // let neighPoints = roadService.getNeighPoints(pointId);
-      // if (neighPoints.length == 1) {
-      //   newPosition = elementService.checkAngle(
-      //     position,
-      //     neighPoints[0].vectorId,
-      //     pointId
-      //   );
-      // }
-      // //当前点的parent有两个
-      // else if (neighPoints.length == 2) {
-      //   newPosition = elementService.checkAngle(
-      //     position,
-      //     neighPoints[0].vectorId,
-      //     pointId
-      //   );
-      //   if (!newPosition) {
-      //     newPosition = elementService.checkAngle(
-      //       position,
-      //       neighPoints[1].vectorId,
-      //       pointId
-      //     );
-      //   }
-      // }
-
-      // if (newPosition) {
-      //   flag = this.canMoveForPoint(
-      //     pointId,
-      //     newPosition,
-      //     linkedPointId,
-      //     linkedRoadId
-      //   );
-      //   if (!flag) {
-      //     return false;
-      //   }
-      //   mathUtil.clonePoint(position, newPosition);
-      // }
-
       point.setPosition(position);
     }
     // 与别的墙角重合
@@ -243,7 +201,7 @@ export default class MoveRoad {
       const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId);
       startLimitLine = roadService.getMidLine(tempRoad);
       limitInfos.startRoadId = tempRoad.vectorId;
-      if (angle > (Constant.maxAngle / 180) * Math.PI) {
+      if (angle > Constant.maxAngle) {
         startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
         limitInfos.startRoadId = null;
         limitInfos.newStartRoadId = true;
@@ -273,11 +231,11 @@ export default class MoveRoad {
       if (join1 == null && join2 == null) {
         let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId);
         let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId);
-        if (angle0 > Math.PI) {
-          angle0 = Math.PI - angle0;
+        if (angle0 > 180) {
+          angle0 = 180 - angle0;
         }
-        if (angle1 > Math.PI) {
-          angle1 = Math.PI - angle1;
+        if (angle1 > 180) {
+          angle1 = 180 - angle1;
         }
         if (angle0 < angle1) {
           tempRoadId = info.min0.roadId;
@@ -307,7 +265,7 @@ export default class MoveRoad {
       const tempStartPoint = dataService.getPoint(tempRoad.startId);
       const tempEndPoint = dataService.getPoint(tempRoad.endId);
       if (
-        angle > (Constant.maxAngle / 180) * Math.PI ||
+        angle > Constant.maxAngle ||
         !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
       ) {
         startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
@@ -330,7 +288,7 @@ export default class MoveRoad {
       const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId);
       endLimitLine = roadService.getMidLine(tempRoad);
       limitInfos.endRoadId = tempRoad.vectorId;
-      if (angle > (Constant.maxAngle / 180) * Math.PI) {
+      if (angle > Constant.maxAngle) {
         endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
         limitInfos.endRoadId = null;
         limitInfos.newEndRoadId = true;
@@ -360,11 +318,11 @@ export default class MoveRoad {
       if (join1 == null && join2 == null) {
         let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId);
         let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId);
-        if (angle0 > Math.PI) {
-          angle0 = Math.PI - angle0;
+        if (angle0 > 180) {
+          angle0 = 180 - angle0;
         }
-        if (angle1 > Math.PI) {
-          angle1 = Math.PI - angle1;
+        if (angle1 > 180) {
+          angle1 = 180 - angle1;
         }
         if (angle0 < angle1) {
           tempRoadId = info.min0.roadId;
@@ -394,7 +352,7 @@ export default class MoveRoad {
       const tempEndPoint = dataService.getPoint(tempRoad.end);
 
       if (
-        angle > (Constant.maxAngle / 180) * Math.PI ||
+        angle > Constant.maxAngle ||
         !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
       ) {
         endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
@@ -432,7 +390,7 @@ export default class MoveRoad {
     const parent = point.parent;
 
     const angle = this.getMinAngle(pointId, position);
-    if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
+    if (Math.abs(angle) < Constant.minAngle) {
       return false;
     }
 
@@ -441,7 +399,7 @@ export default class MoveRoad {
       const road = dataService.getRoad(key);
       const otherPointId = road.getOtherPointId(pointId);
       const info = this.getNeighMinAngle(otherPointId, key, position);
-      if (info && Math.abs(info.angle) < (Constant.minAngle / 180) * Math.PI) {
+      if (info && Math.abs(info.angle) < Constant.minAngle) {
         return false;
       } else {
         const otherPoint = dataService.getPoint(otherPointId);
@@ -460,7 +418,7 @@ export default class MoveRoad {
     const parent = point.parent;
     let angle = null;
     if (Object.keys(parent).length == 1) {
-      return 2 * Math.PI;
+      return 360;
     } else if (Object.keys(parent).length == 2) {
       const road1 = dataService.getRoad(Object.keys(parent)[0]);
       const road2 = dataService.getRoad(Object.keys(parent)[1]);
@@ -489,7 +447,7 @@ export default class MoveRoad {
           let angle = mathUtil.Angle(position, _position, otherPoint);
           // 统一按照逆时针顺序
           if (otherPoint.y < position.y) {
-            angle = 2 * Math.PI - angle;
+            angle = 360 - angle;
           }
           angles.push(angle);
         }
@@ -497,7 +455,7 @@ export default class MoveRoad {
 
       angles = angles.sort(sortNumber);
 
-      let minAngle = 2 * Math.PI;
+      let minAngle = 360;
       for (let i = 0; i < angles.length - 1; ++i) {
         for (let j = i + 1; j < angles.length; ++j) {
           const _angle = angles[j] - angles[i];
@@ -509,8 +467,8 @@ export default class MoveRoad {
 
       const angle1 = angles[0];
       const angle2 = angles[angles.length - 1];
-      if (angle1 < Math.PI && angle2 > Math.PI) {
-        const dAngle = 2 * Math.PI + angle1 - angle2;
+      if (angle1 < 180 && angle2 > 180) {
+        const dAngle = 360 + angle1 - angle2;
         if (dAngle < minAngle) {
           minAngle = dAngle;
         }
@@ -866,7 +824,7 @@ export default class MoveRoad {
       const otherPointId = road.getOtherPointId(pointId);
       const otherPoint = dataService.getPoint(otherPointId);
       const angle = mathUtil.Angle(point, otherPoint, newPoint2);
-      if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
+      if (Math.abs(angle) < Constant.minAngle) {
         return false;
       }
     }
@@ -899,7 +857,7 @@ export default class MoveRoad {
         let parent = adsorbPoint.parent;
         for (const key in parent) {
           const angle = roadService.AngleForRoad3(roadId, key);
-          if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
+          if (Math.abs(angle) < Constant.minAngle) {
             return true;
           }
         }
@@ -908,7 +866,7 @@ export default class MoveRoad {
         parent = adsorbPoint.parent;
         for (const key in parent) {
           const angle = roadService.AngleForRoad3(roadId, key);
-          if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
+          if (Math.abs(angle) < Constant.minAngle) {
             return true;
           }
         }
@@ -1069,7 +1027,7 @@ export default class MoveRoad {
             // 只更新坐标
             if (
               Object.keys(point.parent).length == 3 &&
-              angle > (Constant.maxAngle / 180) * Math.PI
+              angle > Constant.maxAngle
             ) {
               point.setPosition(virtualInfo.virtualPosition);
             }

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

@@ -52,6 +52,8 @@ export default class UIControl {
         //执行新的事件
         if (this.selectUI == UIEvents.Road) {
           stateService.setEventName(LayerEvents.AddRoad);
+        } else if (this.selectUI == UIEvents.CurveRoad) {
+          stateService.setEventName(LayerEvents.AddCurveRoad);
         } else if (this.selectUI == UIEvents.Tag) {
           stateService.setEventName(LayerEvents.AddTag);
         } else if (this.selectUI == UIEvents.Img) {

+ 16 - 0
src/graphic/Geometry/CurveRoad.js

@@ -0,0 +1,16 @@
+import VectorType from "../enum/VectorType.js";
+import Geometry from "./Geometry.js";
+import Road from "./Road.js";
+import Constant from "../Constant";
+
+export default class CurveRoad extends Road {
+  constructor(startId, endId, vectorId) {
+    super(startId, endId, vectorId);
+    this.points = []; //中心线上一系列控制点。数组是从start到end。
+    this.leftEdgePoints = [];
+    this.rightEdgePoints = [];
+    this.leftDrivewayCount = 2; //左边的车道个数
+    this.rightDrivewayCount = 2; //右边的车道个数
+    this.geoType = VectorType.CurveRoad;
+  }
+}

+ 1 - 0
src/graphic/Geometry/Edge.js

@@ -10,6 +10,7 @@ export default class Edge extends Geometry {
     this.start = {};
     this.end = {};
     this.vectorId = null;
+    this.points = [];
     this.geoType = VectorType.Edge;
     this.setId(vectorId);
 

+ 1 - 2
src/graphic/Geometry/Road.js

@@ -10,8 +10,7 @@ export default class Road extends Geometry {
     this.leftEdgeId = null;
     this.rightEdgeId = null;
     this.width = Constant.defaultRoadWidth; //默认宽度
-    this.isCurve = false;
-    this.points = []; //中心线上一系列控制点。数组是从start到end。
+
     this.leftDrivewayCount = 1; //左边的车道个数
     this.rightDrivewayCount = 1; //右边的车道个数
     this.geoType = VectorType.Road;

+ 71 - 4
src/graphic/Layer.js

@@ -23,6 +23,7 @@ import History from "./History/History";
 import mitt from "mitt";
 import { roadService } from "./Service/RoadService";
 import { edgeService } from "./Service/EdgeService";
+import { pointService } from "./Service/PointService";
 
 const minDragDis = 10;
 
@@ -152,8 +153,12 @@ export default class Layer {
           };
         }
 
+        elementService.hideAll();
         elementService.setPoint(position);
         elementService.showPoint();
+        if (listenLayer.modifyPoint) {
+          elementService.execute(listenLayer.modifyPoint, position);
+        }
         break;
       case LayerEvents.AddingRoad:
         needAutoRedraw = true;
@@ -201,6 +206,7 @@ export default class Layer {
         break;
       case LayerEvents.MoveRoadPoint:
         let point = dataService.getPoint(draggingItem.vectorId);
+        //listenLayer.start(position, draggingItem.vectorId, point.parent);
         listenLayer.start(position, draggingItem.vectorId, point.parent);
         if (listenLayer.modifyPoint) {
           position = {
@@ -247,6 +253,47 @@ export default class Layer {
         }
         needAutoRedraw = true;
         break;
+      case LayerEvents.AddCurveRoad:
+        needAutoRedraw = true;
+        listenLayer.start(position);
+        if (listenLayer.modifyPoint) {
+          position = {
+            x: listenLayer.modifyPoint.x,
+            y: listenLayer.modifyPoint.y,
+          };
+        }
+
+        elementService.hideAll();
+        elementService.setPoint(position);
+        elementService.showPoint();
+        if (listenLayer.modifyPoint) {
+          elementService.execute(listenLayer.modifyPoint, position);
+        }
+        break;
+      case LayerEvents.AddingCurveRoad:
+        needAutoRedraw = true;
+        listenLayer.start(position);
+        if (listenLayer.modifyPoint) {
+          position = {
+            x: listenLayer.modifyPoint.x,
+            y: listenLayer.modifyPoint.y,
+          };
+        }
+
+        elementService.execute(addRoad.startInfo.position, position);
+        elementService.setPoint(position);
+        elementService.setNewRoad(addRoad.startInfo.position, position);
+        elementService.showNewRoad();
+        elementService.setNewRoadGeoType(VectorType.Road);
+
+        addRoad.setNewRoadPoint("end", position);
+        addRoad.canAdd = addRoad.canAddRoadForEnd(position);
+        if (!addRoad.canAdd) {
+          elementService.setNewRoadState("error");
+        } else {
+          elementService.setNewRoadState("normal");
+        }
+        break;
       case LayerEvents.AddMeasureLine:
         needAutoRedraw = true;
         listenLayer.start(position);
@@ -348,10 +395,10 @@ export default class Layer {
             listenLayer.modifyPoint &&
             listenLayer.modifyPoint.hasOwnProperty("linkedRoadId")
           ) {
-            point = roadService.createPoint(
-              listenLayer.modifyPoint.x,
-              listenLayer.modifyPoint.y
-            );
+            point = pointService.create({
+              x: listenLayer.modifyPoint.x,
+              y: listenLayer.modifyPoint.y,
+            });
             roadService.splitRoad(
               listenLayer.modifyPoint.linkedRoadId,
               point.vectorId,
@@ -382,6 +429,18 @@ export default class Layer {
           elementService.hideAll();
         }
         break;
+      case LayerEvents.AddCurveRoad:
+        addRoad.setNewRoadPoint("start", position);
+        break;
+      case LayerEvents.AddingCurveRoad:
+        needAutoRedraw = true;
+        if (addRoad.canAdd) {
+          addRoad.buildRoad();
+          addRoad.clear();
+          this.history.save();
+          elementService.hideAll();
+        }
+        break;
       case LayerEvents.MoveRoad:
         needAutoRedraw = true;
         if (focusItem != null && focusItem.type == VectorType.Road) {
@@ -483,6 +542,10 @@ export default class Layer {
           stateService.setEventName(LayerEvents.MoveRoad);
         } else if (selectItem.type == VectorType.RoadCorner) {
           stateService.setEventName(LayerEvents.MoveRoadPoint);
+        } else if (selectItem.type == VectorType.CurveRoad) {
+          stateService.setEventName(LayerEvents.MoveCurveRoad);
+        } else if (selectItem.type == VectorType.CurveRoadCorner) {
+          stateService.setEventName(LayerEvents.MoveCurveRoadPoint);
         } else if (selectItem.type == VectorType.Tag) {
           stateService.setEventName(LayerEvents.MoveTag);
         } else if (selectItem.type == VectorType.MeasureLine) {
@@ -499,6 +562,10 @@ export default class Layer {
         stateService.setEventName(LayerEvents.AddingRoad);
       } else if (eventName == LayerEvents.AddingRoad) {
         stateService.setEventName(LayerEvents.AddRoad);
+      } else if (eventName == LayerEvents.AddCurveRoad) {
+        stateService.setEventName(LayerEvents.AddingCurveRoad);
+      } else if (eventName == LayerEvents.AddingCurveRoad) {
+        stateService.setEventName(LayerEvents.AddCurveRoad);
       } else if (eventName == LayerEvents.AddMeasureLine) {
         stateService.setEventName(LayerEvents.AddingMeasureLine);
       } else if (eventName == LayerEvents.AddingMeasureLine) {

+ 72 - 72
src/graphic/ListenLayer.js

@@ -141,42 +141,42 @@ export default class ListenLayer {
             break;
           }
         }
-        // //start部分找到了与x接近的其他点
-        // if (Math.abs(position.x - startPoint.x) < Constant.minAdsorbPix) {
-        //   if (!modifyPoint.linkedPointIdX) {
-        //     modifyPoint.x = startPoint.x;
-        //     modifyPoint.linkedPointIdX = road.startId;
-        //   } else {
-        //     const linkedPointX = dataService.getPoint(
-        //       modifyPoint.linkedPointIdX
-        //     );
-        //     if (
-        //       mathUtil.getDistance(position, linkedPointX) >
-        //       mathUtil.getDistance(position, startPoint)
-        //     ) {
-        //       modifyPoint.x = startPoint.x;
-        //       modifyPoint.linkedPointIdX = road.startId;
-        //     }
-        //   }
-        // }
-        // //start部分找到了与y接近的其他点
-        // if (Math.abs(position.y - startPoint.y) < Constant.minAdsorbPix) {
-        //   if (!modifyPoint.linkedPointIdY) {
-        //     modifyPoint.y = startPoint.y;
-        //     modifyPoint.linkedPointIdY = road.startId;
-        //   } else {
-        //     const linkedPointY = dataService.getPoint(
-        //       modifyPoint.linkedPointIdY
-        //     );
-        //     if (
-        //       mathUtil.getDistance(position, linkedPointY) >
-        //       mathUtil.getDistance(position, startPoint)
-        //     ) {
-        //       modifyPoint.y = startPoint.y;
-        //       modifyPoint.linkedPointIdY = road.startId;
-        //     }
-        //   }
-        // }
+        //start部分找到了与x接近的其他点
+        if (Math.abs(position.x - startPoint.x) < Constant.minAdsorbPix) {
+          if (!modifyPoint.linkedPointIdX) {
+            modifyPoint.x = startPoint.x;
+            modifyPoint.linkedPointIdX = road.startId;
+          } else {
+            const linkedPointX = dataService.getPoint(
+              modifyPoint.linkedPointIdX
+            );
+            if (
+              mathUtil.getDistance(position, linkedPointX) >
+              mathUtil.getDistance(position, startPoint)
+            ) {
+              modifyPoint.x = startPoint.x;
+              modifyPoint.linkedPointIdX = road.startId;
+            }
+          }
+        }
+        //start部分找到了与y接近的其他点
+        if (Math.abs(position.y - startPoint.y) < Constant.minAdsorbPix) {
+          if (!modifyPoint.linkedPointIdY) {
+            modifyPoint.y = startPoint.y;
+            modifyPoint.linkedPointIdY = road.startId;
+          } else {
+            const linkedPointY = dataService.getPoint(
+              modifyPoint.linkedPointIdY
+            );
+            if (
+              mathUtil.getDistance(position, linkedPointY) >
+              mathUtil.getDistance(position, startPoint)
+            ) {
+              modifyPoint.y = startPoint.y;
+              modifyPoint.linkedPointIdY = road.startId;
+            }
+          }
+        }
       }
 
       if (hasPointIds.indexOf(road.endId) == -1) {
@@ -202,42 +202,42 @@ export default class ListenLayer {
             break;
           }
         }
-        // //end部分找到了与x接近的其他点
-        // if (Math.abs(position.x - endPoint.x) < Constant.minAdsorbPix) {
-        //   if (!modifyPoint.linkedPointIdX) {
-        //     modifyPoint.x = endPoint.x;
-        //     modifyPoint.linkedPointIdX = road.endId;
-        //   } else {
-        //     const linkedPointX = dataService.getPoint(
-        //       modifyPoint.linkedPointIdX
-        //     );
-        //     if (
-        //       mathUtil.getDistance(position, linkedPointX) >
-        //       mathUtil.getDistance(position, endPoint)
-        //     ) {
-        //       modifyPoint.x = endPoint.x;
-        //       modifyPoint.linkedPointIdX = road.endId;
-        //     }
-        //   }
-        // }
-        // //end部分找到了与y接近的其他点
-        // if (Math.abs(position.y - endPoint.y) < Constant.minAdsorbPix) {
-        //   if (!modifyPoint.linkedPointIdY) {
-        //     modifyPoint.y = endPoint.y;
-        //     modifyPoint.linkedPointIdY = road.endId;
-        //   } else {
-        //     const linkedPointY = dataService.getPoint(
-        //       modifyPoint.linkedPointIdY
-        //     );
-        //     if (
-        //       mathUtil.getDistance(position, linkedPointY) >
-        //       mathUtil.getDistance(position, endPoint)
-        //     ) {
-        //       modifyPoint.y = endPoint.y;
-        //       modifyPoint.linkedPointIdY = road.endId;
-        //     }
-        //   }
-        // }
+        //end部分找到了与x接近的其他点
+        if (Math.abs(position.x - endPoint.x) < Constant.minAdsorbPix) {
+          if (!modifyPoint.linkedPointIdX) {
+            modifyPoint.x = endPoint.x;
+            modifyPoint.linkedPointIdX = road.endId;
+          } else {
+            const linkedPointX = dataService.getPoint(
+              modifyPoint.linkedPointIdX
+            );
+            if (
+              mathUtil.getDistance(position, linkedPointX) >
+              mathUtil.getDistance(position, endPoint)
+            ) {
+              modifyPoint.x = endPoint.x;
+              modifyPoint.linkedPointIdX = road.endId;
+            }
+          }
+        }
+        //end部分找到了与y接近的其他点
+        if (Math.abs(position.y - endPoint.y) < Constant.minAdsorbPix) {
+          if (!modifyPoint.linkedPointIdY) {
+            modifyPoint.y = endPoint.y;
+            modifyPoint.linkedPointIdY = road.endId;
+          } else {
+            const linkedPointY = dataService.getPoint(
+              modifyPoint.linkedPointIdY
+            );
+            if (
+              mathUtil.getDistance(position, linkedPointY) >
+              mathUtil.getDistance(position, endPoint)
+            ) {
+              modifyPoint.y = endPoint.y;
+              modifyPoint.linkedPointIdY = road.endId;
+            }
+          }
+        }
       }
 
       distance = mathUtil.getDistance(position, join);

+ 12 - 5
src/graphic/Renderer/Render.js

@@ -20,6 +20,9 @@ export default class Render {
       case VectorType.Road:
         draw.drawRoad(vector, false);
         return;
+      case VectorType.CurveRoad:
+        draw.drawCurveRoad(vector, false);
+        return;
       case VectorType.Point:
         draw.drawPoint(vector);
         return;
@@ -93,15 +96,19 @@ export default class Render {
     draw.clear();
 
     let roads = dataService.getRoads();
-
     for (let key in roads) {
       this.drawGeometry(roads[key]);
     }
 
-    // let points = dataService.getPoints();
-    // for (let key in points) {
-    //   this.drawGeometry(points[key]);
-    // }
+    let points = dataService.getPoints();
+    for (let key in points) {
+      this.drawGeometry(points[key]);
+    }
+
+    let curveRoads = dataService.getCurveRoads();
+    for (let key in curveRoads) {
+      this.drawGeometry(curveRoads[key]);
+    }
 
     let controlPoints = dataService.getControlPoints();
     for (let key in controlPoints) {

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

@@ -0,0 +1,203 @@
+import { dataService } from "./DataService";
+import { pointService } from "./PointService";
+import { mathUtil } from "../Util/MathUtil.js";
+import CurveRoad from "../Geometry/CurveRoad.js";
+
+export default class CurveRoadService {
+  constructor() {}
+
+  create(startId, endId, vectorId) {
+    let curveRoad = new CurveRoad(startId, endId, vectorId);
+    dataService.addCurveRoad(curveRoad);
+
+    let startPoint = dataService.getPoint(startId);
+    startPoint.setPointParent(curveRoad.vectorId, "start");
+
+    let endPoint = dataService.getPoint(endId);
+    endPoint.setPointParent(curveRoad.vectorId, "end");
+
+    let edgePoints = mathUtil.RectangleVertex(
+      startPoint,
+      endPoint,
+      curveRoad.width
+    );
+    let leftEdge = edgeService.create(
+      edgePoints.leftEdgeStart,
+      edgePoints.leftEdgeEnd,
+      null,
+      vectorId
+    );
+
+    let rightEdge = edgeService.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);
+    }
+    this.addCPoint(
+      curveRoad,
+      {
+        x: (startPoint.x + endPoint.x) / 2,
+        y: (startPoint.y + endPoint.y) / 2,
+      },
+      0
+    );
+
+    let lanes = this.setLanes(
+      curveRoad.points,
+      curveRoad.leftEdgePoints,
+      curveRoad.rightEdgePoints,
+      curveRoad.leftDrivewayCount,
+      curveRoad.rightDrivewayCount
+    );
+    road.leftLanes = lanes.leftLanes;
+    road.rightLanes = lanes.rightLanes;
+    return road;
+  }
+
+  addCPoint(curveRoad, position, startIndex) {
+    let point = pointService.create(position);
+    curveRoad.points[startIndex + 1] = point;
+  }
+
+  moveCPoint(position) {}
+
+  setLanesPoints(curveRoadId) {
+    let curveRoad = dataService.getCurveRoad(curveRoadId);
+    let startPoint = dataService.getPoint(curveRoad.startId);
+    let endPoint = dataService.getPoint(curveRoad.endId);
+
+    let midPoint = pointService.create({
+      x: (startPoint.x + endPoint.x) / 2,
+      y: (startPoint.y + endPoint.y) / 2,
+    });
+
+    curveRoad.points = [];
+    curveRoad.points.push(startPoint);
+    curveRoad.points.push(midPoint);
+    curveRoad.points.push(endPoint);
+  }
+
+  //车道
+  //points的第一个元素是start,最后一个是end
+  setLanes(points, leftEdgePoints, rightEdgePoints, leftCount, rightCount) {
+    let leftLanes = [];
+    let rightLanes = [];
+
+    const len = points.length;
+    let leftdx1 = leftEdgePoints[0].x - points[0].x;
+    leftdx1 = leftdx1 / leftCount;
+
+    let leftdy1 = leftEdgePoints[0].y - points[0].y;
+    leftdy1 = leftdy1 / leftCount;
+
+    let leftdx2 = leftEdgePoints[len - 1].x - points[len - 1].x;
+    leftdx2 = leftdx2 / leftCount;
+
+    let leftdy2 = leftEdgePoints[len - 1].y - points[len - 1].y;
+    leftdy2 = leftdy2 / leftCount;
+
+    for (let i = 0; i < leftCount - 1; ++i) {
+      for (let j = 0; j < points.length; ++j) {
+        leftLanes[i] = [];
+        leftLanes[i][j] = {};
+        if (j == 0) {
+          leftLanes[i][j].x = points[j].x + leftdx1 * (i + 1);
+          leftLanes[i][j].y = points[j].y + leftdy1 * (i + 1);
+        } else if (j == points.length - 1) {
+          leftLanes[i][j].x = points[j].x + leftdx2 * (i + 1);
+          leftLanes[i][j].y = points[j].y + leftdy2 * (i + 1);
+        } else {
+          let edgePoints1 = mathUtil.RectangleVertex(
+            points[j],
+            points[j - 1],
+            leftdx1
+          );
+          let line1 = mathUtil.createLine1(
+            edgePoints1.leftEdgeStart,
+            edgePoints1.leftEdgeEnd
+          );
+
+          let edgePoints2 = mathUtil.RectangleVertex(
+            points[j],
+            points[j + 1],
+            leftdx1
+          );
+          let line2 = mathUtil.createLine1(
+            edgePoints2.leftEdgeStart,
+            edgePoints2.leftEdgeEnd
+          );
+
+          let join = mathUtil.getIntersectionPoint(line1, line2);
+          leftLanes[i][j].x = join.x;
+          leftLanes[i][j].y = join.y;
+        }
+      }
+    }
+
+    let rightdx1 = rightEdgePoints[0].x - points[0].x;
+    rightdx1 = rightdx1 / rightCount;
+
+    let rightdy1 = rightEdgePoints[0].y - points[0].y;
+    rightdy1 = rightdy1 / rightCount;
+
+    let rightdx2 = rightEdgePoints[len - 1].x - points[len - 1].x;
+    rightdx2 = rightdx2 / rightCount;
+
+    let rightdy2 = rightEdgePoints[len - 1].y - points[len - 1].y;
+    rightdy2 = rightdy2 / rightCount;
+
+    for (let i = 0; i < rightCount - 1; ++i) {
+      for (let j = 0; j < points.length; ++j) {
+        rightLanes[i] = [];
+        rightLanes[i][j] = {};
+        if (j == 0) {
+          rightLanes[i][j].x = points[j].x + rightdx1 * (i + 1);
+          rightLanes[i][j].y = points[j].y + rightdy1 * (i + 1);
+        } else if (j == points.length - 1) {
+          rightLanes[i][j].x = points[j].x + rightdy2 * (i + 1);
+          rightLanes[i][j].y = points[j].y + rightdy2 * (i + 1);
+        } else {
+          let edgePoints1 = mathUtil.RectangleVertex(
+            points[j],
+            points[j - 1],
+            rightdx1
+          );
+          let line1 = mathUtil.createLine1(
+            edgePoints1.rightEdgeStart,
+            edgePoints1.rightEdgeEnd
+          );
+
+          let edgePoints2 = mathUtil.RectangleVertex(
+            points[j],
+            points[j + 1],
+            rightdx1
+          );
+          let line2 = mathUtil.createLine1(
+            edgePoints2.rightEdgeStart,
+            edgePoints2.rightEdgeEnd
+          );
+
+          let join = mathUtil.getIntersectionPoint(line1, line2);
+          rightLanes[i][j].x = join.x;
+          rightLanes[i][j].y = join.y;
+        }
+      }
+    }
+
+    return {
+      leftLanes: leftLanes,
+      rightLanes: rightLanes,
+    };
+  }
+}
+
+const curveRoadService = new CurveRoadService();
+export { curveRoadService };

+ 24 - 0
src/graphic/Service/DataService.js

@@ -24,6 +24,7 @@ export class DataService {
     this.vectorData.points = {};
     this.vectorData.controlPoints = {};
     this.vectorData.roads = {};
+    this.vectorData.curveRoads = {};
     this.vectorData.edges = {};
     this.vectorData.tags = {};
   }
@@ -31,6 +32,29 @@ export class DataService {
   /**
    * 对公路的操作
    */
+  getCurveRoads() {
+    return this.vectorData.curveRoads;
+  }
+
+  getCurveRoad(curveRoadId) {
+    if (curveRoadId) {
+      return this.vectorData.curveRoads[curveRoadId];
+    } else {
+      return null;
+    }
+  }
+
+  addCurveRoad(curveRoad) {
+    this.vectorData.curveRoads[curveRoad.vectorId] = curveRoad;
+  }
+
+  deleteCurveRoad(curveRoadId) {
+    let curveRoad = this.getCurveRoad(curveRoadId);
+    this.deletePoint(curveRoad.startId, curveRoadId);
+    this.deletePoint(curveRoad.endId, curveRoadId);
+    delete this.vectorData.curveRoads[curveRoadId];
+  }
+
   getRoads() {
     return this.vectorData.roads;
   }

+ 3 - 3
src/graphic/Service/ElementService.js

@@ -290,11 +290,11 @@ export class ElementService {
   //   let newPosition = null;
   //   for (let i = 0; i < points.length; ++i) {
   //     let angle = mathUtil.Angle(point, position, points[i]);
-  //     if (Math.abs((angle / Math.PI) * 180 - 90) < 5) {
+  //     if (Math.abs((angle - 90) < 5) {
   //       newPosition = ajust(position, point, points[i], 1);
   //     } else if (
-  //       Math.abs((angle / Math.PI) * 180) < 5 ||
-  //       Math.abs((angle / Math.PI) * 180 - 180) < 5
+  //       Math.abs(angle < 5 ||
+  //       Math.abs(angle - 180) < 5
   //     ) {
   //       newPosition = ajust(position, point, points[i], 2);
   //     }

+ 3 - 2
src/graphic/Service/RoadService.js

@@ -232,7 +232,7 @@ export default class RoadService {
     const join = mathUtil.getIntersectionPoint2(start1, end1, start2, end2);
 
     if (join == null) {
-      return Math.PI;
+      return 180;
     }
 
     // start和start相交
@@ -547,7 +547,7 @@ export default class RoadService {
         const otherPointId2 = road2.getOtherPointId(pointId2);
         const otherPoint2 = dataService.getPoint(otherPointId2);
         const angle = mathUtil.Angle(point2, otherPoint1, otherPoint2);
-        if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
+        if (Math.abs(angle) < Constant.minAngle) {
           return false;
         }
       }
@@ -587,6 +587,7 @@ export default class RoadService {
         );
       }
     }
+    edgeService.updateEdgeForMovePoint(pointId2);
     return true;
   }
 

+ 5 - 5
src/graphic/Util/MathUtil.js

@@ -44,10 +44,10 @@ export default class MathUtil {
   }
 
   createLine2(point, angle) {
-    if (angle == Math.PI / 2 || angle == 1.5 * Math.PI) {
+    if (angle == 90 || angle == 270) {
       return { x: point.x };
     }
-    let a = Math.tan(angle);
+    let a = Math.tan((angle / 180) * Math.PI);
     let b = point.y - a * point.x;
     if (a != 0) {
       return { a: a, b: b };
@@ -133,8 +133,8 @@ export default class MathUtil {
     let angle2 = this.Angle(point, point2, { x: point.x + 1, y: point.y });
     let angle3 = this.Angle(point, point3, { x: point.x + 1, y: point.y });
     let angle4 = this.Angle(point, point4, { x: point.x + 1, y: point.y });
-    if (angle > Math.PI) {
-      angle = 2 * Math.PI - angle;
+    if (angle > 180) {
+      angle = 360 - angle;
     }
     if (
       Math.abs((angle1 + angle3) / 2 - angle) <
@@ -1021,7 +1021,7 @@ export default class MathUtil {
 
   angleTo(v1, v2) {
     const denominator = Math.sqrt(this.lengthSq(v1) * this.lengthSq(v2));
-    if (denominator === 0) return Math.PI / 2;
+    if (denominator === 0) return 90;
     const theta = this.dot(v1, v2) / denominator;
     //return Math.acos(this.clamp(theta, -1, 1));
     return (Math.acos(this.clamp(theta, -1, 1)) / Math.PI) * 180;

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

@@ -1,10 +1,15 @@
 const LayerEvents = {
   PanBackGround: "panBackGround", //拖拽背景
 
-  AddRoad: "addRoad", //开始添加墙
-  AddingRoad: "addingRoad", //添加墙进行中
-  MoveRoad: "moveRoad", //拖拽墙面
-  MoveRoadPoint: "moveRoadPoint", //拖拽墙角
+  AddRoad: "addRoad",
+  AddingRoad: "addingRoad",
+  MoveRoad: "moveRoad",
+  MoveRoadPoint: "moveRoadPoint",
+
+  AddCurveRoad: "addCurveRoad",
+  AddingCurveRoad: "addingCurveRoad",
+  MoveCurveRoad: "moveCurveRoad",
+  MoveCurveRoadPoint: "moveCurveRoadPoint",
 
   AddTag: "addTag",
   MoveTag: "moveTag",

+ 1 - 0
src/graphic/enum/UIEvents.js

@@ -1,5 +1,6 @@
 const UIEvents = {
   Road: "road",
+  CurveRoad: "curveRoad",
   Tag: "tag", //这个是标注,暂时这样
   Img: "backgroundImage",
   MeasureLine: "measure",

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

@@ -7,8 +7,10 @@ const VectorType = {
   MeasureLine: "MeasureLine",
   MeasureArrow: "MeasureArrow",
   RoadCorner: "RoadCorner",
+  CurveRoadCorner: "CurveRoadCorner",
   Edge: "Edge",
   Road: "Road",
+  CurveRoad: "CurveRoad",
   Tag: "Tag",
 };
 export default VectorType;