浏览代码

继续绘图

xushiting 2 年之前
父节点
当前提交
544f03efb6

+ 12 - 0
src/graphic/Controls/AddRoad.js

@@ -49,6 +49,18 @@ export default class AddRoad {
       this.endInfo.position,
       splitPointIds[splitPointIds.length - 1]
     );
+
+    let hasComputerRoadIds = [];
+    for (let i = 0; i < splitPointIds.length; ++i) {
+      let point = dataService.getPoint(splitPointIds[i]);
+      let parent = point.getParent();
+      for (let key in parent) {
+        if (hasComputerRoadIds.indexOf(key) < 0) {
+          roadService.setLanes(key);
+          hasComputerRoadIds.push(key);
+        }
+      }
+    }
     listenLayer.clear();
   }
 

+ 79 - 68
src/graphic/Controls/MoveRoad.js

@@ -24,7 +24,7 @@ export default class MoveRoad {
 
   // 测试要考虑pointId拖拽到包含他的所有墙的另一头
   // 这个函数不会删除/拆分/合并墙或者点
-  movePoint(pointId, position, modifyPoint) {
+  moveingRoadPoint(pointId, position, modifyPoint) {
     let point = dataService.getPoint(pointId);
     let linkedPointId = null;
     let linkedRoadId = null;
@@ -114,6 +114,11 @@ export default class MoveRoad {
     }
 
     edgeService.updateEdgeForMovePoint(pointId);
+    let parent = point.getParent();
+    for (let key in parent) {
+      roadService.setLanes(key);
+    }
+
     return true;
   }
 
@@ -954,7 +959,7 @@ export default class MoveRoad {
     return flag;
   }
 
-  moveTo(roadId, dx, dy) {
+  moveRoad(roadId, dx, dy) {
     dx = dx;
     dy = -dy;
 
@@ -983,82 +988,88 @@ export default class MoveRoad {
       rightEdge.start.y += dy;
       rightEdge.end.x += dx;
       rightEdge.end.y += dy;
+
+      roadService.setLanes(roadId);
     }
   }
 
-  // 更新pointId的坐标
-  updatePointForMoveRoad(roadId, pointId, virtualInfo, limitRoadId, needNew) {
-    const point = dataService.getPoint(pointId);
-    const road = dataService.getRoad(roadId);
-    // 如果没有约束墙,只有两种情况:一种是不新建墙,另一种是需要新建墙
-    if (limitRoadId == null) {
-      // 不需要新建墙,这种情况一般是pointId的parent只有一个
-      if (!needNew) {
-        point.setPosition(virtualInfo.virtualPosition);
-      }
-      // 新建墙
-      else {
-        this.createRoadForMoveRoad(
-          pointId,
-          roadId,
-          virtualInfo.virtualPosition
-        );
+  // pointId1移动到pointId2
+  // 如果有一堵墙(roadId)的两头是pointId1和pointId2,那么这堵墙会被删除
+  moveTo(pointId1, pointId2) {
+    const roadId = roadService.getRoadId(pointId1, pointId2);
+    // 不能重合
+    let point1 = dataService.getPoint(pointId1);
+    let point2 = dataService.getPoint(pointId2);
+    if (!point2) {
+      return false;
+    }
+
+    let parent1 = point1.getParent();
+    const parent2 = point2.getParent();
+    //确保pointId1与pointId2重合后,墙的角度不能太小
+    for (const roadId1 in parent1) {
+      if (roadId1 == roadId) {
+        continue;
       }
-    } else {
-      /*
-        不新建墙:
-        1. 更新坐标(一种是当pointId的parent是2个,另一种是三个,但是roadId对应的两堵墙接近180°)
-        2. 拆分墙
-        3. 吸附邻居墙的另一个端点
-        新建墙:
-        */
-      // 不新建墙
-      if (!needNew) {
-        if (!virtualInfo.adsorb) {
-          // 只更新坐标
-          if (Object.keys(point.parent).length == 2) {
-            point.setPosition(virtualInfo.virtualPosition);
-          } else {
-            const info = roadService.roadIdForMinAngle(pointId, roadId);
-            const angle = roadService.AngleForRoad(
-              info.min0.roadId,
-              info.min1.roadId
-            );
-            // 只更新坐标
-            if (
-              Object.keys(point.parent).length == 3 &&
-              angle > Constant.maxAngle
-            ) {
-              point.setPosition(virtualInfo.virtualPosition);
-            }
-            // 拆分墙
-            else {
-              const dir = roadService.getDirction(pointId, roadId);
-              // 先断开链接
-              roadService.subtraRoadFromIntersect(pointId, roadId);
-              const newPointId = road.getPointId(dir);
-              const newPoint = dataService.getPoint(newPointId);
-              // 更新新坐标
-              newPoint.setPosition(virtualInfo.virtualPosition);
-              // 拆分
-              roadService.splitRoad(limitRoadId, newPointId, dir);
-            }
-          }
+
+      const road1 = dataService.getRoad(roadId1);
+      const otherPointId1 = road1.getOtherPointId(pointId1);
+      const otherPoint1 = dataService.getPoint(otherPointId1);
+
+      for (const roadId2 in parent2) {
+        if (roadId2 == roadId) {
+          continue;
         }
-        // 吸附邻居墙的另一个端点。
-        else {
-          roadService.moveTo(pointId, virtualInfo.adsorbPointId);
+        const road2 = dataService.getRoad(roadId2);
+        const otherPointId2 = road2.getOtherPointId(pointId2);
+        const otherPoint2 = dataService.getPoint(otherPointId2);
+        const angle = mathUtil.Angle(point2, otherPoint1, otherPoint2);
+        if (Math.abs(angle) < Constant.minAngle) {
+          return false;
         }
       }
-      // 新建墙
-      else {
-        this.createRoadForMoveRoad(
-          pointId,
-          roadId,
-          virtualInfo.virtualPosition
+    }
+    // pointId1,pointId2属于同一堵墙
+    if (roadId != null) {
+      dataService.deleteRoad(roadId);
+    }
+
+    point1 = dataService.getPoint(pointId1);
+    point2 = dataService.getPoint(pointId2);
+    if (!point1 || !point2) {
+      return false;
+    }
+
+    //准备合并
+    for (const roadId1 in parent1) {
+      const road1 = dataService.getRoad(roadId1);
+      const otherPointId = road1.getOtherPointId(pointId1);
+      const _roadId = this.getRoadId(otherPointId, pointId2);
+      if (_roadId != null) {
+        return false;
+      }
+
+      // road1上pointId1被pointId2取代
+      if (road1.startId == pointId1) {
+        dataService.deletePoint(road1.startId, roadId1);
+        road1.startId = pointId2;
+        point2.setPointParent(roadId1, "start");
+      } else if (road1.endId == pointId1) {
+        dataService.deletePoint(road1.endId, roadId1);
+        road1.endId = pointId2;
+        point2.setPointParent(roadId1, "end");
+      } else {
+        console.error(
+          "roadService.moveTo****************************************************"
         );
       }
     }
+
+    edgeService.updateEdgeForMovePoint(pointId2);
+    for (let key in parent2) {
+      roadService.setLanes(key);
+    }
+    return true;
   }
 
   //

+ 8 - 4
src/graphic/Layer.js

@@ -195,7 +195,7 @@ export default class Layer {
           Object.keys(end.getParent()).length == 1
         ) {
           //拖拽的路只有一条
-          moveRoad.moveTo(
+          moveRoad.moveRoad(
             draggingItem.vectorId,
             (dx * coordinate.defaultZoom) / coordinate.zoom,
             (dy * coordinate.defaultZoom) / coordinate.zoom
@@ -215,7 +215,7 @@ export default class Layer {
           };
         }
 
-        let flag = moveRoad.movePoint(
+        let flag = moveRoad.moveingRoadPoint(
           draggingItem.vectorId,
           position,
           listenLayer.modifyPoint
@@ -395,7 +395,7 @@ export default class Layer {
             listenLayer.modifyPoint &&
             listenLayer.modifyPoint.hasOwnProperty("linkedPointId")
           ) {
-            roadService.moveTo(
+            moveRoad.moveTo(
               draggingItem.vectorId,
               listenLayer.modifyPoint.linkedPointId
             );
@@ -418,7 +418,7 @@ export default class Layer {
               point.vectorId,
               "start"
             );
-            roadService.moveTo(draggingItem.vectorId, point.vectorId);
+            moveRoad.moveTo(draggingItem.vectorId, point.vectorId);
           } else if (moveRoad.splitRoadId != null) {
             roadService.splitRoad(
               moveRoad.splitRoadId,
@@ -428,6 +428,10 @@ export default class Layer {
           }
           //draggingItem.vectorId所在的墙面与其他墙角相交
           moveRoad.updateForAbsorbRoadPoints();
+          let parent = point.getParent();
+          for (let key in parent) {
+            roadService.setLanes(key);
+          }
           this.history.save();
         }
         break;

+ 26 - 0
src/graphic/ListenLayer.js

@@ -5,6 +5,7 @@ import { roadService } from "./Service/RoadService.js";
 import Constant from "./Constant.js";
 import VectorType from "./enum/VectorType.js";
 import SelectState from "./enum/SelectState.js";
+import bezierUtil from "./Util/bezierUtil.js";
 
 export default class ListenLayer {
   constructor() {
@@ -92,6 +93,7 @@ export default class ListenLayer {
       exceptCurveRoadId
     );
 
+    this.getNearForControlPoint();
     let min1 = info1.min1;
     let modifyPoint = info1.modifyPoint;
     let _modifyPoint = info1._modifyPoint;
@@ -420,6 +422,24 @@ export default class ListenLayer {
     };
   }
 
+  getNearForControlPoint() {
+    const controlPoints = dataService.getControlPoints();
+    for (const controlPoint in controlPoints) {
+      let bezierData = [];
+      let edge1 = dataService.getEdge(controlPoint.edgeInfo1.id);
+      let start = edge1.getPosition(controlPoint.edgeInfo1.dir);
+      let edge2 = dataService.getEdge(controlPoint.edgeInfo2.id);
+      let end = edge2.getPosition(controlPoint.edgeInfo2.dir);
+      bezierData.push(start.x);
+      bezierData.push(start.y);
+      bezierData.push(controlPoint.x);
+      bezierData.push(controlPoint.y);
+      bezierData.push(end.x, end.y);
+      bezierData.push(end.x, end.y);
+      this.isHitForBezier(bezierData);
+    }
+  }
+
   updateSelectInfos(nearest, minDistance) {
     //console.log("实时监控:" + JSON.stringify(nearest));
     // 墙角状态是否改变
@@ -698,6 +718,12 @@ export default class ListenLayer {
   //   return result;
   // }
 
+  isHitForBezier(bezierData, position) {
+    const { isHit, getInfo } = bezierUtil.measureBezier(...bezierData);
+    let flag = isHit(position.x, position.y, 20);
+    console.log("test");
+  }
+
   clear() {
     this.roadInfo = {
       roadId: null,

+ 3 - 55
src/graphic/Service/EdgeService.js

@@ -781,38 +781,6 @@ export default class EdgeService {
     }
   }
 
-  //和updateSingleEdgeForTwoRoad的功能相似,只是更新roadId对应pointId这一头的。pointId的parent无论有几个都支持
-  updateEdgeForSingleRoad(roadId, pointId) {
-    //console.log('更新'+pointId+'对应'+roadId+'两侧相交的edge交点');
-    //console.log('开始执行updateEdgeForSingleRoad');
-    let road = dataService.getRoad(roadId);
-    let point = dataService.getPoint(pointId);
-    let parent = point.getParent();
-    let dir = null;
-    if (road.startId == pointId) {
-      dir = "start";
-    } else if (road.endId == pointId) {
-      dir = "end";
-    } else {
-      console.error(
-        "updateEdgeForRoad*****************************************************"
-      );
-    }
-
-    if (Object.keys(parent).length == 1) {
-      this.updateDefaultEdge(roadId, dir);
-    } else if (Object.keys(parent).length == 2) {
-      this.updateEdgeForTwoRoad(Object.keys(parent)[0], Object.keys(parent)[1]);
-    } else if (Object.keys(parent).length > 2) {
-      let info = roadService.roadIdForMinAngle(pointId, roadId);
-      let roadId1 = info.min0.roadId;
-      let roadId2 = info.min1.roadId;
-
-      this.updateSingleEdgeForTwoRoad(roadId, roadId2);
-      this.updateSingleEdgeForTwoRoad(roadId1, roadId);
-    }
-  }
-
   //pointId的parent可以是1,2,>2
   //更新pointId对应的全部edge端点
   updateEdgeForMulRoad(pointId) {
@@ -824,8 +792,11 @@ export default class EdgeService {
     if (Object.keys(parent).length == 1) {
       let dir = roadService.getDirction(pointId, Object.keys(parent)[0]);
       this.updateDefaultEdge(Object.keys(parent)[0], dir);
+      roadService.setLanes(Object.keys(parent)[0], dir);
     } else if (Object.keys(parent).length == 2) {
       this.updateEdgeForTwoRoad(Object.keys(parent)[0], Object.keys(parent)[1]);
+      roadService.setLanes(Object.keys(parent)[0]);
+      roadService.setLanes(Object.keys(parent)[1]);
     } else if (Object.keys(parent).length > 2) {
       //起始墙:Object.keys(parent)[0]
       //开始
@@ -869,29 +840,6 @@ export default class EdgeService {
     }
   }
 
-  //pointId1和pointId2是roadId的两个端点,pointId1移动到和pointId2重合的位置
-  //这个函数解决:pointId1和pointId2的坐标重合了edge坐标
-  updateEdgeForSamePosition(pointId1, pointId2, roadId) {
-    let road = dataService.getRoad(roadId);
-    let point1 = dataService.getPoint(pointId1);
-    let point2 = dataService.getPoint(pointId2);
-    if (!mathUtil.equalPoint(point1, point2)) {
-      return;
-    }
-
-    let vLeft = dataService.getEdge(this.leftEdgeId);
-    let vRight = dataService.getEdge(this.rightEdgeId);
-
-    if (pointId1 == road.startId && pointId2 == road.endId) {
-      mathUtil.clonePoint(vLeft.start, vLeft.end);
-      mathUtil.clonePoint(vRight.start, vRight.end);
-    } else if (pointId1 == road.endId && pointId2 == road.startId) {
-      mathUtil.clonePoint(vLeft.end, vLeft.start);
-      mathUtil.clonePoint(vRight.end, vRight.start);
-    }
-    return;
-  }
-
   // pointId的坐标已经变了
   updateEdgeForMovePoint(pointId) {
     const point = dataService.getPoint(pointId);

+ 26 - 93
src/graphic/Service/RoadService.js

@@ -517,82 +517,7 @@ export default class RoadService {
     this.setRoadPointId(roadId, pointId, dir);
     // 第四步更新Edge
     edgeService.updateDefaultEdge(roadId, dir);
-  }
-
-  // pointId1移动到pointId2
-  // 如果有一堵墙(roadId)的两头是pointId1和pointId2,那么这堵墙会被删除
-  moveTo(pointId1, pointId2) {
-    const roadId = this.getRoadId(pointId1, pointId2);
-    // 不能重合
-    let point1 = dataService.getPoint(pointId1);
-    let point2 = dataService.getPoint(pointId2);
-    if (!point2) {
-      return false;
-    }
-    const dx = point1.x - point2.x;
-    const dy = point1.y - point2.y;
-    let parent1 = point1.getParent();
-    const parent2 = point2.getParent();
-    //确保pointId1与pointId2重合后,墙的角度不能太小
-    for (const roadId1 in parent1) {
-      if (roadId1 == roadId) {
-        continue;
-      }
-
-      const road1 = dataService.getRoad(roadId1);
-      const otherPointId1 = road1.getOtherPointId(pointId1);
-      const otherPoint1 = dataService.getPoint(otherPointId1);
-
-      for (const roadId2 in parent2) {
-        if (roadId2 == roadId) {
-          continue;
-        }
-        const road2 = dataService.getRoad(roadId2);
-        const otherPointId2 = road2.getOtherPointId(pointId2);
-        const otherPoint2 = dataService.getPoint(otherPointId2);
-        const angle = mathUtil.Angle(point2, otherPoint1, otherPoint2);
-        if (Math.abs(angle) < Constant.minAngle) {
-          return false;
-        }
-      }
-    }
-    // pointId1,pointId2属于同一堵墙
-    if (roadId != null) {
-      dataService.deleteRoad(roadId);
-    }
-
-    point1 = dataService.getPoint(pointId1);
-    point2 = dataService.getPoint(pointId2);
-    if (!point1 || !point2) {
-      return false;
-    }
-
-    //准备合并
-    for (const roadId1 in parent1) {
-      const road1 = dataService.getRoad(roadId1);
-      const otherPointId = road1.getOtherPointId(pointId1);
-      const _roadId = this.getRoadId(otherPointId, pointId2);
-      if (_roadId != null) {
-        return false;
-      }
-
-      // road1上pointId1被pointId2取代
-      if (road1.startId == pointId1) {
-        dataService.deletePoint(road1.startId, roadId1);
-        road1.startId = pointId2;
-        point2.setPointParent(roadId1, "start");
-      } else if (road1.endId == pointId1) {
-        dataService.deletePoint(road1.endId, roadId1);
-        road1.endId = pointId2;
-        point2.setPointParent(roadId1, "end");
-      } else {
-        console.error(
-          "roadService.moveTo****************************************************"
-        );
-      }
-    }
-    edgeService.updateEdgeForMovePoint(pointId2);
-    return true;
+    roadService.setLanes(roadId, dir);
   }
 
   setRoadPointId = function (roadId, pointId, dir) {
@@ -901,7 +826,7 @@ export default class RoadService {
   // }
 
   //设置车道
-  setLanes(roadId) {
+  setLanes(roadId, dir) {
     let road = dataService.getRoad(roadId);
     let startPoint = dataService.getPoint(road.startId);
     let endPoint = dataService.getPoint(road.endId);
@@ -964,25 +889,33 @@ export default class RoadService {
     rightdy2 = rightdy2 / rightCount;
 
     for (let i = 1; i < leftCount; ++i) {
-      road.leftLanes[i] = {};
-      road.leftLanes[i].start = {};
-      road.leftLanes[i].start.x = point1.x + leftdx1 * i;
-      road.leftLanes[i].start.y = point1.y + leftdy1 * i;
-
-      road.leftLanes[i].end = {};
-      road.leftLanes[i].end.x = point2.x + leftdx2 * i;
-      road.leftLanes[i].end.y = point2.y + leftdy2 * i;
+      if (!dir) {
+        road.leftLanes[i] = {};
+      }
+      if (dir == "start" || !dir) {
+        road.leftLanes[i].start = {};
+        road.leftLanes[i].start.x = point1.x + leftdx1 * i;
+        road.leftLanes[i].start.y = point1.y + leftdy1 * i;
+      } else if (dir == "end" || !dir) {
+        road.leftLanes[i].end = {};
+        road.leftLanes[i].end.x = point2.x + leftdx2 * i;
+        road.leftLanes[i].end.y = point2.y + leftdy2 * i;
+      }
     }
 
     for (let i = 1; i < rightCount; ++i) {
-      road.rightLanes[i] = {};
-      road.rightLanes[i].start = {};
-      road.rightLanes[i].start.x = point1.x + leftdx1 * i;
-      road.rightLanes[i].start.y = point1.y + leftdy1 * i;
-
-      road.rightLanes[i].end = {};
-      road.rightLanes[i].end.x = point2.x + leftdx2 * i;
-      road.rightLanes[i].end.y = point2.y + leftdy2 * i;
+      if (!dir) {
+        road.rightLanes[i] = {};
+      }
+      if (dir == "start" || !dir) {
+        road.rightLanes[i].start = {};
+        road.rightLanes[i].start.x = point1.x + leftdx1 * i;
+        road.rightLanes[i].start.y = point1.y + leftdy1 * i;
+      } else if (dir == "end" || !dir) {
+        road.rightLanes[i].end = {};
+        road.rightLanes[i].end.x = point2.x + leftdx2 * i;
+        road.rightLanes[i].end.y = point2.y + leftdy2 * i;
+      }
     }
   }