Browse Source

Merge remote-tracking branch 'origin/master'

bill 2 years ago
parent
commit
57bc15cfe8

+ 2 - 0
src/graphic/Constant.js

@@ -34,5 +34,7 @@ const Constant = {
   maxRoadSideWidth: 800,
   oneWay: "oneWay", //one表示单向,two表示双向
   twoWay: "twoWay", //one表示单向,two表示双向
+  defaultSingleLaneWidth: 30, //单个车道的宽度
+  defaultMidDivideWidth: 5, //隔离带的宽度
 };
 export default Constant;

+ 8 - 8
src/graphic/Controls/AddCrossRoad.js

@@ -30,10 +30,10 @@ export default class AddCrossRoad {
     });
 
     //需要设置公路的车道数,是否双向等等
-    // this.leftDrivewayCount = Setting.roadLeftDrivewayCount;
-    // this.rightDrivewayCount = Setting.roadRightDrivewayCount;
-    // this.singleRoadDrivewayCount = Setting.singleRoadDrivewayCount;
-    // this.way = Setting.wayType;
+    // this.leftDrivewayCount = Settings.roadLeftDrivewayCount;
+    // this.rightDrivewayCount = Settings.roadRightDrivewayCount;
+    // this.singleRoadDrivewayCount = Settings.singleRoadDrivewayCount;
+    // this.way = Settings.wayType;
 
     roadService.create(start1.vectorId, end.vectorId);
     roadService.create(start2.vectorId, end.vectorId);
@@ -66,10 +66,10 @@ export default class AddCrossRoad {
     });
 
     //需要设置公路的车道数,是否双向等等
-    // this.leftDrivewayCount = Setting.roadLeftDrivewayCount;
-    // this.rightDrivewayCount = Setting.roadRightDrivewayCount;
-    // this.singleRoadDrivewayCount = Setting.singleRoadDrivewayCount;
-    // this.way = Setting.wayType;
+    // this.leftDrivewayCount = Settings.roadLeftDrivewayCount;
+    // this.rightDrivewayCount = Settings.roadRightDrivewayCount;
+    // this.singleRoadDrivewayCount = Settings.singleRoadDrivewayCount;
+    // this.way = Settings.wayType;
 
     roadService.create(start1.vectorId, end.vectorId);
     roadService.create(start2.vectorId, end.vectorId);

+ 20 - 14
src/graphic/Geometry/ControlPoint.js

@@ -44,33 +44,39 @@ export default class ControlPoint extends Geometry {
   setExtremePoint() {
     let points = [];
     let edge1 = dataService.getRoadEdge(this.edgeInfo1.id);
+    let curve = {};
     if (this.edgeInfo1.dir == "start") {
-      points[0] = edge1.start;
+      curve.start = {};
+      mathUtil.clonePoint(curve.start, edge1.start);
     } else if (this.edgeInfo1.dir == "end") {
-      points[0] = edge1.end;
+      curve.start = {};
+      mathUtil.clonePoint(curve.start, edge1.end);
     }
-    points[1] = {
+    curve.controls = [];
+    curve.controls.push({
       x: this.x,
       y: this.y,
-    };
+    });
     let edge2 = dataService.getRoadEdge(this.edgeInfo2.id);
     if (this.edgeInfo2.dir == "start") {
-      points[2] = edge2.start;
+      curve.end = {};
+      mathUtil.clonePoint(curve.end, edge2.start);
     } else if (this.edgeInfo2.dir == "end") {
-      points[2] = edge2.end;
+      curve.end = {};
+      mathUtil.clonePoint(curve.end, edge2.end);
     }
-    let curves = mathUtil.getCurvesByPoints(points);
-    let joinInfo = mathUtil.getHitInfoForCurves(
-      points[1],
-      curves,
+
+    let joinInfo = mathUtil.getHitInfoForCurve(
+      curve.controls[0],
+      curve,
       Constant.defaultRoadWidth
     );
     this.extremePoint = {};
     mathUtil.clonePoint(this.extremePoint, joinInfo.position);
     this.curves = mathUtil.getCurvesByPoints([
-      points[0],
+      curve.start,
       this.extremePoint,
-      points[2],
+      curve.end,
     ]);
   }
 
@@ -83,8 +89,8 @@ export default class ControlPoint extends Geometry {
       points[0] = edge1.end;
     }
     points[1] = {
-      x: this.x,
-      y: this.y,
+      x: this.extremePoint.x,
+      y: this.extremePoint.y,
     };
     let edge2 = dataService.getRoadEdge(this.edgeInfo2.id);
     if (this.edgeInfo2.dir == "start") {

+ 8 - 8
src/graphic/Geometry/CurveRoad.js

@@ -1,6 +1,6 @@
 import VectorType from "../enum/VectorType.js";
 import Road from "./Road.js";
-import Setting from "../Setting";
+import Settings from "../Settings";
 
 export default class CurveRoad extends Road {
   constructor(startId, endId, vectorId) {
@@ -9,20 +9,20 @@ export default class CurveRoad extends Road {
     this.leftLanesCurves = []; //左车道曲线
     this.rightLanesCurves = []; //左车道曲线
     this.singleLanesCurves = []; //单向车道
-    this.leftDrivewayCount = Setting.curveRoadLeftDrivewayCount; //左边的车道个数
-    this.rightDrivewayCount = Setting.curveRoadRightDrivewayCount; //右边的车道个数
-    this.leftWidth = Setting.leftCurveRoadWidth;
-    this.rightWidth = Setting.rightCurveRoadWidth;
+    this.leftDrivewayCount = Settings.curveRoadLeftDrivewayCount; //左边的车道个数
+    this.rightDrivewayCount = Settings.curveRoadRightDrivewayCount; //右边的车道个数
+    this.leftWidth = Settings.leftCurveRoadWidth;
+    this.rightWidth = Settings.rightCurveRoadWidth;
     this.midDivide = {
       leftMidDivide: [],
       leftMidDivideCurves: [],
       rightMidDivide: [],
       rightMidDivideCurves: [],
-      midDivideWidth: Setting.curveRoadMidDivideWidth,
+      midDivideWidth: Settings.curveRoadMidDivideWidth,
     };
     this.curves = [];
-    this.singleCurveRoadWidth = Setting.singleCurveRoadWidth;
-    this.singleCurveRoadDrivewayCount = Setting.singleCurveRoadDrivewayCount;
+    this.singleCurveRoadWidth = Settings.singleCurveRoadWidth;
+    this.singleCurveRoadDrivewayCount = Settings.singleCurveRoadDrivewayCount;
     this.geoType = VectorType.CurveRoad;
     this.setId(vectorId);
   }

+ 13 - 9
src/graphic/Geometry/Road.js

@@ -1,6 +1,6 @@
 import VectorType from "../enum/VectorType.js";
 import Geometry from "./Geometry.js";
-import Setting from "../Setting";
+import Settings from "../Settings";
 import Constant from "../Constant";
 
 export default class Road extends Geometry {
@@ -18,17 +18,17 @@ export default class Road extends Geometry {
     this.midDivide = {
       leftMidDivide: {},
       rightMidDivide: {},
-      midDivideWidth: Setting.roadMidDivideWidth,
+      midDivideWidth: Settings.roadMidDivideWidth,
     };
 
-    this.leftDrivewayCount = Setting.roadLeftDrivewayCount; //左边的车道个数
-    this.rightDrivewayCount = Setting.roadRightDrivewayCount; //右边的车道个数
+    this.leftDrivewayCount = Settings.roadLeftDrivewayCount; //左边的车道个数
+    this.rightDrivewayCount = Settings.roadRightDrivewayCount; //右边的车道个数
     this.geoType = VectorType.Road;
-    this.leftWidth = Setting.leftRoadWidth;
-    this.rightWidth = Setting.rightRoadWidth;
-    this.singleRoadWidth = Setting.singleRoadWidth;
-    this.singleRoadDrivewayCount = Setting.singleRoadDrivewayCount;
-    this.way = Setting.wayType;
+    this.leftWidth = Settings.leftRoadWidth;
+    this.rightWidth = Settings.rightRoadWidth;
+    this.singleRoadWidth = Settings.singleRoadWidth;
+    this.singleRoadDrivewayCount = Settings.singleRoadDrivewayCount;
+    this.way = Settings.wayType;
     this.setId(vectorId);
   }
 
@@ -83,4 +83,8 @@ export default class Road extends Geometry {
       this.rightDrivewayCount = 0;
     }
   }
+
+  setWay(value) {
+    this.way = value;
+  }
 }

+ 148 - 1
src/graphic/History/Change.js

@@ -27,6 +27,19 @@ export default class Change {
       JSON.stringify(dataService.getMagnifiers())
     );
     this.lastData.svgs = JSON.parse(JSON.stringify(dataService.getSVGs()));
+    this.lastData.roadPoints = JSON.parse(
+      JSON.stringify(dataService.getRoadPoints())
+    );
+    this.lastData.roadEdges = JSON.parse(
+      JSON.stringify(dataService.getRoadEdges())
+    );
+    this.lastData.roads = JSON.parse(JSON.stringify(dataService.getRoads()));
+    this.lastData.curveRoads = JSON.parse(
+      JSON.stringify(dataService.getCurveRoads())
+    );
+    this.lastData.controlPoints = JSON.parse(
+      JSON.stringify(dataService.getControlPoints())
+    );
   }
 
   operate() {
@@ -39,12 +52,20 @@ export default class Change {
     this.compareTexts();
     this.compareMagnifiers();
     this.compareSVGs();
+    this.compareRoadPoints();
+    this.compareRoadEdges();
+    this.compareRoads();
+    this.compareCurveRoads();
+    this.compareControlPoints();
     if (
       this.currentData.points.length == 0 &&
       this.currentData.lines.length == 0 &&
       this.currentData.circles.length == 0 &&
       this.currentData.texts.length == 0 &&
-      this.currentData.magnifiers.length == 0
+      this.currentData.magnifiers.length == 0 &&
+      this.currentData.roadPoints.length == 0 &&
+      this.currentData.roadEdges.length == 0 &&
+      this.currentData.roads.length == 0
     ) {
       this.saveCurrentInfo();
       return false;
@@ -330,6 +351,132 @@ export default class Change {
       this.currentData.svgs.push(item);
     }
   }
+
+  compareRoadPoints() {
+    this.currentData.roadPoints = [];
+    const roadPoints = dataService.getRoadPoints();
+
+    for (const key in roadPoints) {
+      const roadPoint = roadPoints[key];
+      const lastRoadPoint = this.lastData.roadPoints[key];
+
+      // 不存在意味着增加
+      if (!lastRoadPoint) {
+        const item = {
+          handle: HistoryEvents.AddRoadPoint,
+          roadPoint: historyUtil.getDataForRoadPoint(roadPoint),
+        };
+        this.currentData.roadPoints.push(item);
+      } else {
+        if (!historyUtil.isDifferentForRoadPoints(roadPoint, lastRoadPoint)) {
+          delete this.lastData.roadPoints[key];
+          continue;
+        } else {
+          const item = {
+            handle: HistoryEvents.ModifyRoadPoint,
+            preRoadPoint: historyUtil.getDataForRoadPoint(lastRoadPoint),
+            curRoadPoint: historyUtil.getDataForRoadPoint(roadPoint),
+          };
+          this.currentData.roadPoints.push(item);
+        }
+      }
+      delete this.lastData.roadPoints[key];
+    }
+
+    for (const key in this.lastData.roadPoints) {
+      const item = {
+        handle: HistoryEvents.DeleteRoadPoint,
+        roadPoint: historyUtil.getDataForRoadPoint(
+          this.lastData.roadPoints[key]
+        ),
+      };
+      this.currentData.roadPoints.push(item);
+    }
+  }
+
+  compareRoadEdges() {
+    this.currentData.roadEdges = [];
+    const roadEdges = dataService.getRoadEdges();
+
+    for (const key in roadEdges) {
+      const roadEdge = roadEdges[key];
+      const lastRoadEdge = this.lastData.roadEdges[key];
+
+      // 不存在意味着增加
+      if (!lastRoadEdge) {
+        const item = {
+          handle: HistoryEvents.AddRoadEdge,
+          roadEdge: historyUtil.getDataForRoadEdge(roadEdge),
+        };
+        this.currentData.roadEdges.push(item);
+      } else {
+        if (!historyUtil.isDifferentForRoadEdges(roadEdge, lastRoadEdge)) {
+          delete this.lastData.roadEdges[key];
+          continue;
+        } else {
+          const item = {
+            handle: HistoryEvents.ModifyRoadEdge,
+            preRoadEdge: historyUtil.getDataForRoadEdge(lastRoadEdge),
+            curRoadEdge: historyUtil.getDataForRoadEdge(roadEdge),
+          };
+          this.currentData.roadEdges.push(item);
+        }
+      }
+      delete this.lastData.roadEdges[key];
+    }
+
+    for (const key in this.lastData.roadEdges) {
+      const item = {
+        handle: HistoryEvents.DeleteRoadEdge,
+        roadEdge: historyUtil.getDataForRoadEdge(this.lastData.roadEdges[key]),
+      };
+      this.currentData.roadEdges.push(item);
+    }
+  }
+
+  compareRoads() {
+    this.currentData.roads = [];
+    const roads = dataService.getRoads();
+
+    for (const key in roads) {
+      const road = roads[key];
+      const lastRoad = this.lastData.roads[key];
+
+      // 不存在意味着增加
+      if (!lastRoad) {
+        const item = {
+          handle: HistoryEvents.AddRoad,
+          road: historyUtil.getDataForRoad(road),
+        };
+        this.currentData.roads.push(item);
+      } else {
+        if (!historyUtil.isDifferentForRoads(road, lastRoad)) {
+          delete this.lastData.roads[key];
+          continue;
+        } else {
+          const item = {
+            handle: HistoryEvents.ModifyRoad,
+            preRoad: historyUtil.getDataForRoad(lastRoad),
+            curRoad: historyUtil.getDataForRoad(road),
+          };
+          this.currentData.roads.push(item);
+        }
+      }
+      delete this.lastData.roads[key];
+    }
+
+    for (const key in this.lastData.roads) {
+      const item = {
+        handle: HistoryEvents.DeleteRoad,
+        road: historyUtil.getDataForRoad(this.lastData.roads[key]),
+      };
+      this.currentData.roads.push(item);
+    }
+  }
+
+  compareCurveRoads() {}
+
+  compareControlPoints() {}
 }
 
 const change = new Change();

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

@@ -11,6 +11,7 @@ import { roadPointService } from "../Service/RoadPointService";
 import { lineService } from "../Service/LineService";
 import { circleService } from "../Service/CircleService";
 import { pointService } from "../Service/PointService";
+import { edgeService } from "../Service/EdgeService";
 import { magnifierService } from "../Service/MagnifierService";
 
 export default class History {
@@ -99,6 +100,9 @@ export default class History {
       this.goPreForTexts(item.texts);
       this.goPreForMagnifiers(item.magnifiers);
       this.goPreForSVGs(item.svgs);
+      this.goPreForRoadPoints(item.roadPoints);
+      this.goPreForRoadEdges(item.roadEdges);
+      this.goPreForRoads(item.roads);
       historyService.undoHistoryRecord();
       change.saveCurrentInfo();
       this.setState();
@@ -224,6 +228,69 @@ export default class History {
     }
   }
 
+  goPreForRoadPoints(itemForRoadPoints) {
+    for (let i = 0; i < itemForRoadPoints.length; ++i) {
+      const item = itemForRoadPoints[i];
+      if (item.handle == HistoryEvents.AddRoadPoint) {
+        dataService.deleteRoadPoint(item.roadPoint.id);
+      } else if (item.handle == HistoryEvents.DeleteRoadPoint) {
+        let newRoadPoint = roadPointService.create(
+          item.roadPoint.position,
+          item.roadPoint.id
+        );
+        historyUtil.assignRoadPointFromRoadPoint(newRoadPoint, item.roadPoint);
+      } else if (item.handle == HistoryEvents.ModifyRoadPoint) {
+        const preRoadPoint = item.preRoadPoint;
+        let currentRoadPoint = dataService.getRoadPoint(item.curRoadPoint.id);
+        historyUtil.assignRoadPointFromRoadPoint(
+          currentRoadPoint,
+          preRoadPoint
+        );
+      }
+    }
+  }
+
+  goPreForRoadEdges(itemForRoadEdges) {
+    for (let i = 0; i < itemForRoadEdges.length; ++i) {
+      const item = itemForRoadEdges[i];
+      if (item.handle == HistoryEvents.AddRoadEdge) {
+        dataService.deleteRoadEdge(item.roadEdge.id);
+      } else if (item.handle == HistoryEvents.DeleteRoadEdge) {
+        let newRoadEdge = edgeService.create(
+          item.roadEdge.start,
+          item.roadEdge.end,
+          item.roadEdge.id,
+          item.roadEdge.parent
+        );
+        historyUtil.assignRoadEdgeFromRoadEdge(newRoadEdge, item.roadEdge);
+      } else if (item.handle == HistoryEvents.ModifyRoadEdge) {
+        const preRoadEdge = item.preRoadEdge;
+        let currentRoadEdge = dataService.getRoadEdge(item.curRoadEdge.id);
+        historyUtil.assignRoadEdgeFromRoadEdge(currentRoadEdge, preRoadEdge);
+      }
+    }
+  }
+
+  goPreForRoads(itemForRoads) {
+    for (let i = 0; i < itemForRoads.length; ++i) {
+      const item = itemForRoads[i];
+      if (item.handle == HistoryEvents.AddRoad) {
+        dataService.deleteRoad(item.road.id);
+      } else if (item.handle == HistoryEvents.DeleteRoad) {
+        let newRoad = roadService.create(
+          item.road.startId,
+          item.road.endId,
+          item.road.id
+        );
+        historyUtil.assignRoadFromRoad(newRoad, item.road);
+      } else if (item.handle == HistoryEvents.ModifyRoad) {
+        const preRoad = item.preRoad;
+        let currentRoad = dataService.getRoad(item.curRoad.id);
+        historyUtil.assignRoadFromRoad(currentRoad, preRoad);
+      }
+    }
+  }
+
   goNextForPoints(itemForPoints) {
     for (let i = 0; i < itemForPoints.length; ++i) {
       const item = itemForPoints[i];
@@ -341,6 +408,69 @@ export default class History {
     }
   }
 
+  goNextForRoadPoints(itemForRoadPoints) {
+    for (let i = 0; i < itemForRoadPoints.length; ++i) {
+      const item = itemForRoadPoints[i];
+      if (item.handle == HistoryEvents.AddRoadPoint) {
+        let vRoadPoint = roadPointService.create(
+          item.roadPoint.position,
+          item.roadPoint.id
+        );
+        historyUtil.assignRoadPointFromRoadPoint(vRoadPoint, item.roadPoint);
+      } else if (item.handle == HistoryEvents.DeleteRoadPoint) {
+        dataService.deleteRoadPoint(item.roadPoint.id);
+      } else if (item.handle == HistoryEvents.ModifyRoadPoint) {
+        const currentRoadPoint = item.curRoadPoint;
+        let preRoadPoint = dataService.getRoadPoint(item.curRoadPoint.id);
+        historyUtil.assignRoadPointFromRoadPoint(
+          preRoadPoint,
+          currentRoadPoint
+        );
+      }
+    }
+  }
+
+  goNextForRoadEdges(itemForRoadEdges) {
+    for (let i = 0; i < itemForRoadEdges.length; ++i) {
+      const item = itemForRoadEdges[i];
+      if (item.handle == HistoryEvents.AddRoadEdge) {
+        let vRoadEdge = edgeService.create(
+          item.roadEdge.start,
+          item.roadEdge.end,
+          item.roadEdge.id,
+          item.roadEdge.parent
+        );
+        historyUtil.assignRoadEdgeFromRoadEdge(vRoadEdge, item.roadEdge);
+      } else if (item.handle == HistoryEvents.DeleteRoadEdge) {
+        dataService.deleteRoadEdge(item.roadEdge.id);
+      } else if (item.handle == HistoryEvents.ModifyRoadEdge) {
+        const currentRoadEdge = item.curRoadEdge;
+        let preRoadEdge = dataService.getRoadEdge(item.curRoadEdge.id);
+        historyUtil.assignRoadEdgeFromRoadEdge(preRoadEdge, currentRoadEdge);
+      }
+    }
+  }
+
+  goNextForRoads(itemForRoads) {
+    for (let i = 0; i < itemForRoads.length; ++i) {
+      const item = itemForRoads[i];
+      if (item.handle == HistoryEvents.AddRoad) {
+        let vRoad = roadService.create(
+          item.road.startId,
+          item.road.endId,
+          item.road.id
+        );
+        historyUtil.assignRoadFromRoad(vRoad, item.road);
+      } else if (item.handle == HistoryEvents.DeleteRoad) {
+        dataService.deleteRoad(item.road.id);
+      } else if (item.handle == HistoryEvents.ModifyRoad) {
+        const currentRoad = item.curRoad;
+        let preRoad = dataService.getRoad(item.curRoad.id);
+        historyUtil.assignRoadFromRoad(preRoad, currentRoad);
+      }
+    }
+  }
+
   // 恢复
   goNextState() {
     historyService.redoHistoryRecord();
@@ -354,6 +484,9 @@ export default class History {
       this.goNextForTexts(item.texts);
       this.goNextForMagnifiers(item.magnifiers);
       this.goNextForSVGs(item.svgs);
+      this.goNextForRoadPoints(item.roadPoints);
+      this.goNextForRoadEdges(item.roadEdges);
+      this.goNextForRoads(item.roads);
       change.saveCurrentInfo();
       this.setState();
     } else {

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

@@ -1,6 +1,7 @@
 import { mathUtil } from "../Util/MathUtil";
 import { dataService } from "../Service/DataService";
 import { textService } from "../Service/TextService";
+import Constant from "../Constant";
 
 export default class HistoryUtil {
   constructor() {}
@@ -83,6 +84,66 @@ export default class HistoryUtil {
     }
   }
 
+  isDifferentForRoadPoints(roadPoint1, roadPoint2) {
+    if (
+      mathUtil.equalPoint(roadPoint1, roadPoint2) &&
+      JSON.stringify(roadPoint1.parent) == JSON.stringify(roadPoint2.parent)
+    ) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  isDifferentForRoadEdges(roadEdge1, roadEdge2) {
+    if (
+      mathUtil.equalPoint(roadEdge1.start, roadEdge2.start) &&
+      mathUtil.equalPoint(roadEdge1.end, roadEdge2.end) &&
+      roadEdge1.parent == roadEdge2.parent
+    ) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  isDifferentForRoads(road1, road2) {
+    if (
+      road1.startId == road2.startId &&
+      road1.endId == road2.endId &&
+      road1.leftEdgeId == road2.leftEdgeId &&
+      road1.rightEdgeId == road2.rightEdgeId &&
+      road1.way == road2.way
+    ) {
+      if (road1.way == Constant.oneWay) {
+        if (
+          road1.singleRoadWidth == road2.singleRoadWidth &&
+          road1.singleRoadDrivewayCount == road2.singleRoadDrivewayCount
+        ) {
+          return false;
+        } else {
+          return true;
+        }
+      } else if (road1.way == Constant.twoWay) {
+        if (
+          road1.leftWidth == road2.leftWidth &&
+          road1.rightWidth == road2.rightWidth &&
+          road1.leftDrivewayCount == road2.leftDrivewayCount &&
+          road1.rightDrivewayCount == road2.rightDrivewayCount &&
+          road1.midDivide.midDivideWidth == road2.midDivide.midDivideWidth
+        ) {
+          return false;
+        } else {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    } else {
+      return true;
+    }
+  }
+
   // // road2赋值给road1
   // assignRoadFromRoad(road1, road2) {
   //   const roadInfo = {};
@@ -147,6 +208,50 @@ export default class HistoryUtil {
     this.setSVGInfo(svgInfo);
   }
 
+  assignRoadPointFromRoadPoint(roadPoint1, roadPoint2) {
+    const roadPointInfo = {};
+    roadPointInfo.vectorId = roadPoint1.vectorId;
+    roadPointInfo.position = {
+      x: roadPoint2.position.x,
+      y: roadPoint2.position.y,
+    };
+    roadPointInfo.parent = JSON.parse(JSON.stringify(roadPoint2.parent));
+    this.setRoadPointInfo(roadPointInfo);
+  }
+
+  assignRoadEdgeFromRoadEdge(roadEdge1, roadEdge2) {
+    const roadEdgeInfo = {};
+    roadEdgeInfo.vectorId = roadEdge1.vectorId;
+    roadEdgeInfo.start = { x: roadEdge2.start.x, y: roadEdge2.start.y };
+    roadEdgeInfo.end = { x: roadEdge2.end.x, y: roadEdge2.end.y };
+    roadEdgeInfo.parent = roadEdge2.parent;
+    this.setRoadEdgeInfo(roadEdgeInfo);
+  }
+
+  assignRoadFromRoad(road1, road2) {
+    const roadInfo = {};
+    roadInfo.vectorId = road1.vectorId;
+    roadInfo.startId = road2.startId;
+    roadInfo.endId = road2.endId;
+    roadInfo.leftEdgeId = road2.leftEdgeId;
+    roadInfo.rightEdgeId = road2.rightEdgeId;
+    roadInfo.way = road2.way;
+    if (road2.way == Constant.oneWay) {
+      roadInfo.singleRoadWidth = road2.singleRoadWidth;
+      roadInfo.singleRoadDrivewayCount = road2.singleRoadDrivewayCount;
+      roadInfo.singleLanes = JSON.parse(JSON.stringify(road2.singleLanes));
+    } else if (road2.way == Constant.twoWay) {
+      roadInfo.leftWidth = road2.leftWidth;
+      roadInfo.rightWidth = road2.rightWidth;
+      roadInfo.leftDrivewayCount = road2.leftDrivewayCount;
+      roadInfo.rightDrivewayCount = road2.rightDrivewayCount;
+      roadInfo.midDivide = JSON.parse(JSON.stringify(road2.midDivide));
+      roadInfo.leftLanes = JSON.parse(JSON.stringify(road2.leftLanes));
+      roadInfo.rightLanes = JSON.parse(JSON.stringify(road2.rightLanes));
+    }
+    this.setRoadInfo(roadInfo);
+  }
+
   getDataForPoint(point) {
     const data = {};
     data.id = point.vectorId;
@@ -211,12 +316,52 @@ export default class HistoryUtil {
     return data;
   }
 
-  // setRoadInfo(roadInfo) {
-  //   let road = dataService.getRoad(roadInfo.vectorId);
-  //   road.start = roadInfo.start;
-  //   road.end = roadInfo.end;
-  //   return road;
-  // }
+  getDataForRoadPoint(roadPoint) {
+    const data = {};
+    data.id = roadPoint.vectorId;
+    data.type = roadPoint.geoType;
+    data.position = {};
+    mathUtil.clonePoint(data.position, roadPoint);
+    data.parent = JSON.parse(JSON.stringify(roadPoint.parent));
+    return data;
+  }
+
+  getDataForRoadEdge(roadEdge) {
+    const data = {};
+    data.id = roadEdge.vectorId;
+    data.type = roadEdge.geoType;
+    data.parent = roadEdge.parent;
+    data.start = {};
+    data.start = JSON.parse(JSON.stringify(roadEdge.start));
+    data.end = {};
+    data.end = JSON.parse(JSON.stringify(roadEdge.end));
+    return data;
+  }
+
+  getDataForRoad(road) {
+    const data = {};
+    data.id = road.vectorId;
+    data.type = road.geoType;
+    data.startId = road.startId;
+    data.endId = road.endId;
+    data.leftEdgeId = road.leftEdgeId;
+    data.rightEdgeId = road.rightEdgeId;
+    data.way = road.way;
+    if (road.way == Constant.oneWay) {
+      data.singleRoadWidth = road.singleRoadWidth;
+      data.singleRoadDrivewayCount = road.singleRoadDrivewayCount;
+      data.singleLanes = JSON.parse(JSON.stringify(road.singleLanes));
+    } else if (road.way == Constant.twoWay) {
+      data.leftWidth = road.leftWidth;
+      data.rightWidth = road.rightWidth;
+      data.leftDrivewayCount = road.leftDrivewayCount;
+      data.rightDrivewayCount = road.rightDrivewayCount;
+      data.midDivide = JSON.parse(JSON.stringify(road.midDivide));
+      data.leftLanes = JSON.parse(JSON.stringify(road.leftLanes));
+      data.rightLanes = JSON.parse(JSON.stringify(road.rightLanes));
+    }
+    return data;
+  }
 
   setPointInfo(pointInfo) {
     let point = dataService.getPoint(pointInfo.vectorId);
@@ -266,6 +411,44 @@ export default class HistoryUtil {
     svg.center = JSON.parse(JSON.stringify(svgInfo.center));
     svg.name = svgInfo.name;
   }
+
+  setRoadPointInfo(roadPointInfo) {
+    let roadPoint = dataService.getRoadPoint(roadPointInfo.vectorId);
+    roadPoint.vectorId = roadPointInfo.vectorId;
+    mathUtil.clonePoint(roadPoint, roadPointInfo.position);
+    roadPoint.parent = JSON.parse(JSON.stringify(roadPointInfo.parent));
+  }
+
+  setRoadEdgeInfo(roadEdgeInfo) {
+    let roadEdge = dataService.getRoadEdge(roadEdgeInfo.vectorId);
+    roadEdge.vectorId = roadEdgeInfo.vectorId;
+    mathUtil.clonePoint(roadEdge.start, roadEdgeInfo.start);
+    mathUtil.clonePoint(roadEdge.end, roadEdgeInfo.end);
+    roadEdge.name = roadEdgeInfo.name;
+  }
+
+  setRoadInfo(roadInfo) {
+    let road = dataService.getRoad(roadInfo.vectorId);
+    road.vectorId = roadInfo.vectorId;
+    road.startId = roadInfo.startId;
+    road.endId = roadInfo.endId;
+    road.leftEdgeId = roadInfo.leftEdgeId;
+    road.rightEdgeId = roadInfo.rightEdgeId;
+    road.way = roadInfo.way;
+    if (road.way == Constant.oneWay) {
+      road.singleRoadWidth = roadInfo.singleRoadWidth;
+      road.singleRoadDrivewayCount = roadInfo.singleRoadDrivewayCount;
+      road.singleLanes = JSON.parse(JSON.stringify(roadInfo.singleLanes));
+    } else if (road.way == Constant.twoWay) {
+      road.leftWidth = roadInfo.leftWidth;
+      road.rightWidth = roadInfo.rightWidth;
+      road.leftDrivewayCount = roadInfo.leftDrivewayCount;
+      road.rightDrivewayCount = roadInfo.rightDrivewayCount;
+      road.midDivide = JSON.parse(JSON.stringify(roadInfo.midDivide));
+      road.leftLanes = JSON.parse(JSON.stringify(roadInfo.leftLanes));
+      road.rightLanes = JSON.parse(JSON.stringify(roadInfo.rightLanes));
+    }
+  }
 }
 
 const historyUtil = new HistoryUtil();

+ 42 - 26
src/graphic/ListenLayer.js

@@ -531,44 +531,60 @@ export default class ListenLayer {
       const rightEdge = dataService.getRoadEdge(road.rightEdgeId);
       const roadLine = roadService.getMidLine(road);
       let join = mathUtil.getJoinLinePoint(position, roadLine);
-      const distance = mathUtil.getDistance(position, join);
-      if (!mathUtil.isContainForSegment(join, startPoint, endPoint)) {
-        continue;
-      }
-      if (distance < Constant.minAdsorbPix) {
-        roadInfo = {
-          roadId: roadId,
-          type: VectorType.Road,
-          distance: distance,
-        };
+      let distance = mathUtil.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,
+          };
+        }
       }
+
       //检查edge
-      else {
-        let leftLine = mathUtil.createLine1(leftEdge.start, leftEdge.end);
-        join = mathUtil.getJoinLinePoint(position, leftLine);
-        if (distance < Constant.minAdsorbPix) {
+      let leftLine = mathUtil.createLine1(leftEdge.start, leftEdge.end);
+      join = mathUtil.getJoinLinePoint(position, leftLine);
+      distance = mathUtil.getDistance(position, join);
+      if (
+        mathUtil.isContainForSegment(join, leftEdge.start, leftEdge.end) &&
+        distance < Constant.minAdsorbPix
+      ) {
+        if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
           edgeInfo = {
             edgeId: road.leftEdgeId,
             type: VectorType.RoadEdge,
             distance: distance,
             dir: "left",
           };
-        } else {
-          let rightLine = mathUtil.createLine1(rightEdge.start, rightEdge.end);
-          join = mathUtil.getJoinLinePoint(position, rightLine);
-          if (distance < Constant.minAdsorbPix) {
-            edgeInfo = {
-              edgeId: road.rightEdgeId,
-              type: VectorType.RoadEdge,
-              distance: distance,
-              dir: "right",
-            };
-          }
+        }
+      }
+
+      let rightLine = mathUtil.createLine1(rightEdge.start, rightEdge.end);
+      join = mathUtil.getJoinLinePoint(position, rightLine);
+      distance = mathUtil.getDistance(position, join);
+      if (
+        mathUtil.isContainForSegment(join, rightEdge.start, rightEdge.end) &&
+        distance < Constant.minAdsorbPix
+      ) {
+        if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
+          edgeInfo = {
+            edgeId: road.rightEdgeId,
+            type: VectorType.RoadEdge,
+            distance: distance,
+            dir: "right",
+          };
         }
       }
     }
 
-    if (roadInfo.roadId) {
+    if (
+      roadInfo.roadId &&
+      (!edgeInfo.edgeId || roadInfo.distance < edgeInfo.distance)
+    ) {
       const linkedRoad = dataService.getRoad(roadInfo.roadId);
       const linkedRoadLine = roadService.getMidLine(linkedRoad);
       const linkedPosition = mathUtil.getJoinLinePoint(

+ 21 - 14
src/graphic/Renderer/Draw.js

@@ -21,7 +21,7 @@ const help = {
       [stateService.getDraggingItem(), "Dragging"],
       [stateService.getFocusItem(), "Focus"],
     ];
-    let currentAttr
+    let currentAttr;
 
     return [
       itemsEntry.reduce((prev, [item, attr]) => {
@@ -31,13 +31,13 @@ const help = {
           geoId === item.vectorId
         ) {
           if (Style[attr] && Style[attr][geoType]) {
-            currentAttr = attr
+            currentAttr = attr;
             return Style[attr][geoType];
           }
         }
         return prev;
       }, Style[geoType]),
-      currentAttr
+      currentAttr,
     ];
   },
   setVectorStyle(ctx, vector, geoType = vector.geoType) {
@@ -305,6 +305,7 @@ export default class Draw {
     const extremePoint = coordinate.getScreenXY(vector.extremePoint);
     const ctx = this.context;
     ctx.save();
+    ctx.strokeStyle = "red";
     ctx.beginPath();
     ctx.arc(
       // pt.x,
@@ -324,9 +325,11 @@ export default class Draw {
     ctx.beginPath();
     help.setVectorStyle(ctx, null, "RoadEdge");
     //曲线
-    ctx.moveTo(start.x, start.y);
-    ctx.quadraticCurveTo(pt.x, pt.y, end.x, end.y);
-    ctx.stroke();
+    // ctx.moveTo(start.x, start.y);
+    // ctx.quadraticCurveTo(pt.x, pt.y, end.x, end.y);
+
+    const [coves] = help.transformCoves([vector.curves]);
+    help.drawCoves(ctx, coves);
     ctx.restore();
   }
 
@@ -409,9 +412,13 @@ export default class Draw {
     ctx.moveTo(start.x, start.y);
     ctx.lineTo(end.x, end.y);
 
-    const dires = vector.category === UIEvents.MeasureLine
-      ? [[start, end], [end, start]]
-      : [[start, end]]
+    const dires =
+      vector.category === UIEvents.MeasureLine
+        ? [
+            [start, end],
+            [end, start],
+          ]
+        : [[start, end]];
     for (let [start, end] of dires) {
       const lines = mathUtil.getArrow(start, end);
       ctx.moveTo(lines[0].x, lines[0].y);
@@ -471,14 +478,14 @@ export default class Draw {
         const imgCenter = coordinate.getScreenXY(backImg.center);
         const start = {
           x: imgCenter.x - help.getReal(img.width) / 2,
-          y: imgCenter.y - help.getReal(img.height) / 2 ,
+          y: imgCenter.y - help.getReal(img.height) / 2,
         };
-        const ro = img.width / help.getReal(img.width)
+        const ro = img.width / help.getReal(img.width);
         imgBound = [
           (pt.x - start.x - size) * ro,
           (pt.y - start.y - size) * ro,
-          (size * 2) * ro,
-            (size * 2) * ro,
+          size * 2 * ro,
+          size * 2 * ro,
         ];
       }
       const size = help.getReal(style.target.radius);
@@ -559,7 +566,7 @@ export default class Draw {
     this.context.font = `${vector.fontSize}px Microsoft YaHei`;
     this.drawTextByInfo(vector.center, vector.value, 0, false);
 
-    const ctx = this.context
+    const ctx = this.context;
     const pt = coordinate.getScreenXY(vector.center);
     const text = ctx.measureText(vector.value);
     pt.x -= text.width / 2;

+ 2 - 2
src/graphic/Service/CurveRoadService.js

@@ -512,8 +512,8 @@ export default class CurveRoadService extends RoadService {
     if (curveRoad.way == Constant.oneWay) {
       edgePoints = mathUtil.getOffset(
         curveRoad.points,
-        curveRoad.leftWidth,
-        curveRoad.rightWidth
+        curveRoad.singleRoadWidth / 2,
+        curveRoad.singleRoadWidth / 2
       );
     } else if (curveRoad.way == Constant.twoWay) {
       edgePoints = mathUtil.getOffset(

+ 8 - 4
src/graphic/Service/DataService.js

@@ -300,10 +300,6 @@ export class DataService {
     delete this.vectorData.roads[roadId];
   }
 
-  deleteRoadEdge(edgeId) {
-    delete this.vectorData.roadEdges[edgeId];
-  }
-
   /**
    * 对端点的操作
    */
@@ -348,6 +344,14 @@ export class DataService {
     this.vectorData.roadPoints[roadPoint.vectorId] = roadPoint;
   }
 
+  getRoadEdges() {
+    return this.vectorData.roadEdges;
+  }
+
+  deleteRoadEdge(edgeId) {
+    delete this.vectorData.roadEdges[edgeId];
+  }
+
   getRoadEdge(roadEdgeId) {
     return this.vectorData.roadEdges[roadEdgeId];
   }

+ 1 - 6
src/graphic/Service/EdgeService.js

@@ -30,7 +30,7 @@ export default class EdgeService {
       edgePoints = mathUtil.RectangleVertex(
         startPoint,
         endPoint,
-        road.leftWidth * 2
+        road.singleRoadWidth
       );
     } else {
       edgePoints = mathUtil.RectangleVertex(
@@ -43,11 +43,6 @@ export default class EdgeService {
     mathUtil.clonePoint(leftEdge.end, edgePoints.leftEdgeEnd);
 
     if (road.way == Constant.oneWay) {
-      edgePoints = mathUtil.RectangleVertex(
-        startPoint,
-        endPoint,
-        road.rightWidth * 2
-      );
     } else {
       edgePoints = mathUtil.RectangleVertex(
         startPoint,

+ 7 - 1
src/graphic/Service/ElementService.js

@@ -7,6 +7,7 @@ import ElementEvents from "../enum/ElementEvents.js";
 import VectorCategory from "../enum/VectorCategory.js";
 import { listenLayer } from "../ListenLayer";
 import Constant from "../Constant";
+import Settings from "../Settings";
 import { dataService } from "./DataService.js";
 import { mathUtil } from "../Util/MathUtil";
 import { coordinate } from "../Coordinate.js";
@@ -172,16 +173,21 @@ export class ElementService {
   setNewRoad(point1, point2) {
     this.newRoad.start.setPosition(point1);
     this.newRoad.end.setPosition(point2);
+    this.newRoad.setWay(Settings.wayType);
+
     //需要更新Edge坐标
     if (!mathUtil.equalPoint(point1, point2)) {
       let edgePoints = null;
       if (this.newRoad.way == Constant.oneWay) {
+        this.newRoad.singleRoadWidth = Settings.singleRoadWidth;
         edgePoints = mathUtil.RectangleVertex(
           point1,
           point2,
-          this.newRoad.leftWidth + this.newRoad.rightWidth
+          this.newRoad.singleRoadWidth
         );
       } else if (this.newRoad.way == Constant.twoWay) {
+        this.newRoad.leftWidth = Settings.leftRoadWidth;
+        this.newRoad.rightWidth = Settings.rightRoadWidth;
         edgePoints = mathUtil.RectangleVertex(
           point1,
           point2,

+ 52 - 18
src/graphic/Service/UIService.js

@@ -1,36 +1,50 @@
 import Text from "../Geometry/Text.js";
 import { dataService } from "./DataService.js";
 import { mathUtil } from "../Util/MathUtil.js";
-import Setting from "../Setting";
+import Settings from "../Settings";
 import { coordinate } from "../Coordinate.js";
+import UIEvents from "../enum/UIEvents.js";
+import Constant from "../Constant.js";
 
 export default class UIService {
   constructor() {}
 
   isBelongRoad(ui) {
-    if (ui == "OneEdgeOneLanRoad") {
-      this.setRoadLeftDrivewayCount(0);
-      this.setRoadRightDrivewayCount(0);
+    if (ui == UIEvents.OneEdgeOneLanRoad) {
+      this.setWayType(Constant.oneWay);
+      this.setSingleRoadDrivewayCount(1);
+      this.setSingleRoadWidth(Settings.singleLaneWidth);
       return true;
-    } else if (ui == "OneEdgeTwoLanRoad") {
-      this.setRoadLeftDrivewayCount(0);
-      this.setRoadRightDrivewayCount(0);
+    } else if (ui == UIEvents.OneEdgeTwoLanRoad) {
+      this.setWayType(Constant.oneWay);
+      this.setSingleRoadDrivewayCount(2);
+      this.setSingleRoadWidth(Settings.singleLaneWidth * 2);
       return true;
-    } else if (ui == "OneEdgeThreeLanRoad") {
-      this.setRoadLeftDrivewayCount(0);
-      this.setRoadRightDrivewayCount(0);
+    } else if (ui == UIEvents.OneEdgeThreeLanRoad) {
+      this.setWayType(Constant.oneWay);
+      this.setSingleRoadDrivewayCount(3);
+      this.setSingleRoadWidth(Settings.singleLaneWidth * 3);
       return true;
-    } else if (ui == "TwoEdgeOneLanRoad") {
+    } else if (ui == UIEvents.TwoEdgeOneLanRoad) {
+      this.setWayType(Constant.twoWay);
       this.setRoadLeftDrivewayCount(1);
       this.setRoadRightDrivewayCount(1);
+      this.setLeftRoadWidth(Settings.singleLaneWidth);
+      this.setRightRoadWidth(Settings.singleLaneWidth);
       return true;
-    } else if (ui == "TwoEdgeTwoLanRoad") {
+    } else if (ui == UIEvents.TwoEdgeTwoLanRoad) {
+      this.setWayType(Constant.twoWay);
       this.setRoadLeftDrivewayCount(2);
       this.setRoadRightDrivewayCount(2);
+      this.setLeftRoadWidth(Settings.singleLaneWidth * 2);
+      this.setRightRoadWidth(Settings.singleLaneWidth * 2);
       return true;
-    } else if (ui == "TwoEdgeThreeLanRoad") {
+    } else if (ui == UIEvents.TwoEdgeThreeLanRoad) {
+      this.setWayType(Constant.twoWay);
       this.setRoadLeftDrivewayCount(3);
       this.setRoadRightDrivewayCount(3);
+      this.setLeftRoadWidth(Settings.singleLaneWidth * 3);
+      this.setRightRoadWidth(Settings.singleLaneWidth * 3);
       return true;
     }
     return false;
@@ -41,27 +55,47 @@ export default class UIService {
       this.setRoadLeftDrivewayCount(0);
       this.setRoadRightDrivewayCount(0);
       return true;
-    } else if (ui == "OneEdgeOneLanRoad") {
+    } else if (ui == UIEvents.OneEdgeOneLanRoad) {
       this.setRoadLeftDrivewayCount(0);
       this.setRoadRightDrivewayCount(0);
       return true;
     }
   }
 
+  setWayType(value) {
+    Settings.wayType = value;
+  }
+
+  setSingleRoadDrivewayCount(value) {
+    Settings.singleRoadDrivewayCount = value;
+  }
+
   setRoadLeftDrivewayCount(value) {
-    Setting.roadLeftDrivewayCount = value;
+    Settings.roadLeftDrivewayCount = value;
   }
 
   setRoadRightDrivewayCount(value) {
-    Setting.roadRightDrivewayCount = value;
+    Settings.roadRightDrivewayCount = value;
   }
 
   setCurveRoadLeftDrivewayCount(value) {
-    Setting.curveRoadLeftDrivewayCount = value;
+    Settings.curveRoadLeftDrivewayCount = value;
   }
 
   setCurveRoadRightDrivewayCount(value) {
-    Setting.curveRoadRightDrivewayCount = value;
+    Settings.curveRoadRightDrivewayCount = value;
+  }
+
+  setSingleRoadWidth(value) {
+    Settings.singleRoadWidth = value;
+  }
+
+  setLeftRoadWidth(value) {
+    Settings.leftRoadWidth = value;
+  }
+
+  setRightRoadWidth(value) {
+    Settings.rightRoadWidth = value;
   }
 
   //如果position在屏幕左上角,返回的就朝向右下角,如果是右下角,则返回的是左上角。其他情况以此类推

+ 5 - 4
src/graphic/Setting.js

@@ -1,5 +1,5 @@
 import Constant from "./Constant";
-const Setting = {
+const Settings = {
   roadLeftDrivewayCount: 1,
   roadRightDrivewayCount: 1,
   curveRoadLeftDrivewayCount: 1,
@@ -12,8 +12,9 @@ const Setting = {
   rightRoadWidth: 50,
   leftCurveRoadWidth: 50,
   rightCurveRoadWidth: 50,
-  roadMidDivideWidth: 40,
-  curveRoadMidDivideWidth: 40,
+  singleLaneWidth: Constant.defaultSingleLaneWidth,
+  roadMidDivideWidth: Constant.defaultMidDivideWidth,
+  curveRoadMidDivideWidth: Constant.defaultMidDivideWidth,
   wayType: Constant.twoWay, //one表示单向,two表示双向
 };
-export default Setting;
+export default Settings;

+ 6 - 2
src/graphic/enum/HistoryEvents.js

@@ -1,7 +1,11 @@
 const HistoryEvents = {
   AddRoadPoint: "addRoadPoint",
-  DeletePoint: "deletePoint",
-  ModifyPoint: "modifyPoint",
+  DeleteRoadPoint: "deleteRoadPoint",
+  ModifyRoadPoint: "modifyRoadPoint",
+
+  AddRoadEdge: "addRoadEdge",
+  DeleteRoadEdge: "deleteRoadEdge",
+  ModifyRoadEdge: "modifyRoadEdge",
 
   AddRoad: "addRoad",
   DeleteRoad: "deleteRoad",