import { roadService } from "../Service/RoadService"; import { dataService } from "../Service/DataService"; import Constant from "../Constant"; import { mathUtil } from "../Util/MathUtil"; import { curveRoadService } from "../Service/CurveRoadService"; import { coordinate } from "../Coordinate"; import { edgeService } from "../Service/EdgeService"; import { crossPointService } from "../Service/CrossPointService"; export default class MoveRoad { constructor() { this.moveFlag = false; //拖拽墙角的时候,墙角的父亲与其他墙角相交 this.adsorbPointRoads = {}; //拖拽墙角的时候,该墙角与其他墙面相交 this.splitRoadId = null; } // 测试要考虑pointId拖拽到包含他的所有墙的另一头 // 这个函数不会删除/拆分/合并墙或者点 moveingRoadPoint(pointId, position, modifyPoint) { let point = dataService.getRoadPoint(pointId); let linkedRoadPointId = null; let linkedRoadId = null; if (modifyPoint != null) { position = { x: modifyPoint.x, y: modifyPoint.y, }; linkedRoadPointId = modifyPoint.linkedRoadPointId; linkedRoadId = modifyPoint.linkedRoadId; } if (point.x == position.x && point.y == position.y) { return false; } this.adsorbPointRoads = {}; this.splitRoadId = null; let flag = this.canMoveForPoint( pointId, position, linkedRoadPointId, linkedRoadId ); if (!flag) { return false; } if ( this.splitRoadId == null && Object.keys(this.adsorbPointRoads).length > 0 ) { //要吸附一下 const adsorbPointId = Object.keys(this.adsorbPointRoads)[0]; const road = dataService.getRoad(this.adsorbPointRoads[adsorbPointId]); const otherPointId = road.getOtherPointId(pointId); let otherPoint = dataService.getRoadPoint(otherPointId); let modifyPoint = dataService.getRoadPoint(adsorbPointId); let line = mathUtil.createLine1(otherPoint, modifyPoint); position = mathUtil.getJoinLinePoint(position, line); point.setPosition(position); } if (modifyPoint == null) { point.setPosition(position); } // 与别的墙角重合 else if ( modifyPoint.hasOwnProperty("linkedRoadPointId") && modifyPoint.linkedRoadPointId != null ) { const roadId = roadService.getRoadId( pointId, modifyPoint.linkedRoadPointId ); // pointId与linkedPointId属于同一堵墙,不允许,所以不移动 if (roadId != null) { return false; } else { point.setPosition(modifyPoint); } } // 与别的墙面重合 // 如果墙面的交点与其余墙角的距离过短,那也不允许拖动 else if (modifyPoint.hasOwnProperty("linkedRoadId")) { const road = dataService.getRoad(modifyPoint.linkedRoadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); // 与其余墙角的距离过短,不允许拖动 if ( mathUtil.getDistance(startPoint, position) < Constant.minRealDis || mathUtil.getDistance(endPoint, position) < Constant.minRealDis ) { return false; } point.setPosition(modifyPoint); } else { if ( modifyPoint.hasOwnProperty("linkedRoadPointIdX") && modifyPoint.linkedRoadPointIdX ) { point.setPosition(position); } if ( modifyPoint.hasOwnProperty("linkedRoadPointIdY") && modifyPoint.linkedRoadPointIdY ) { point.setPosition(position); } } edgeService.updateEdgeForMovePoint(pointId); return true; } //拖拽墙角/墙面,被其他墙角吸附 updateForAbsorbRoadPoints() { if (Object.keys(this.adsorbPointRoads).length == 0) { return; } else if (Object.keys(this.adsorbPointRoads).length == 2) { debugger; } let joins = []; let roadId = null; for (let key in this.adsorbPointRoads) { let point = dataService.getRoadPoint(key); joins.push({ join: point, pointId: key, }); roadId = this.adsorbPointRoads[key]; } const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); function sortNumber(a, b) { return ( mathUtil.getDistance(startPoint, a.join) - mathUtil.getDistance(startPoint, b.join) ); } joins = joins.sort(sortNumber.bind(this)); for (let i = 0; i < joins.length; ++i) { const info = joins[i]; const join = info.join; const pointId = info.pointId; roadService.splitRoad(roadId, pointId, "end"); } } getNewPointsForMoveRoad(roadId, dx, dy) { dx = dx; dy = -dy; const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); const p1 = { x: startPoint.x + dx, y: startPoint.y + dy }; const p2 = { x: endPoint.x + dx, y: endPoint.y + dy }; return { point1: p1, point2: p2, }; } getTwoLimitInfos(roadId, newLine) { const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); let startLimitLine, endLimitLine, info; const roadLine = roadService.getMidLine(road); const limitInfos = {}; limitInfos.newStartRoadId = false; // 不需要新建墙 limitInfos.newEndRoadId = false; // 不需要新建墙 // 先处理start if (Object.keys(startPoint.parent).length == 1) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; } else if (Object.keys(startPoint.parent).length == 2) { let tempRoad; if (Object.keys(startPoint.parent)[0] == roadId) { tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[1]); } else if (Object.keys(startPoint.parent)[1] == roadId) { tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[0]); } if (!tempRoad) { console.error(352); } const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId); startLimitLine = roadService.getMidLine(tempRoad); limitInfos.startRoadId = tempRoad.vectorId; if (angle > Constant.maxAngle) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; limitInfos.newStartRoadId = true; } } else { let tempRoad, tempRoadId; info = roadService.roadIdForMinAngle(road.startId, roadId); const road1 = dataService.getRoad(info.min0.roadId); const startPoint1 = dataService.getRoadPoint(road1.startId); const endPoint1 = dataService.getRoadPoint(road1.endId); const road2 = dataService.getRoad(info.min1.roadId); const startPoint2 = dataService.getRoadPoint(road2.startId); const endPoint2 = dataService.getRoadPoint(road2.endId); const join1 = mathUtil.getIntersectionPoint4( startPoint1, endPoint1, newLine ); const join2 = mathUtil.getIntersectionPoint4( startPoint2, endPoint2, newLine ); // 取角度大的 if (join1 == null && join2 == null) { let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId); let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId); if (angle0 > 180) { angle0 = 180 - angle0; } if (angle1 > 180) { angle1 = 180 - angle1; } if (angle0 < angle1) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } limitInfos.newStartRoadId = true; } // 取角度小的 else if (join1 != null && join2 != null) { if (info.min0.angle < info.min1.angle) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } } else if (join1 == null && join2 != null) { tempRoadId = info.min1.roadId; } else if (join1 != null && join2 == null) { tempRoadId = info.min0.roadId; } limitInfos.startRoadId = tempRoadId; tempRoad = dataService.getRoad(tempRoadId); const angle = roadService.AngleForRoad(tempRoadId, roadId); startLimitLine = roadService.getMidLine(tempRoad); let join = mathUtil.getIntersectionPoint(startLimitLine, newLine); const tempStartPoint = dataService.getRoadPoint(tempRoad.startId); const tempEndPoint = dataService.getRoadPoint(tempRoad.endId); if ( angle > Constant.maxAngle || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint) ) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; limitInfos.newStartRoadId = true; } } // 再处理end if (Object.keys(endPoint.parent).length == 1) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; } else if (Object.keys(endPoint.parent).length == 2) { let tempRoad; if (Object.keys(endPoint.parent)[0] == roadId) { tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[1]); } else if (Object.keys(endPoint.parent)[1] == roadId) { tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[0]); } const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId); endLimitLine = roadService.getMidLine(tempRoad); limitInfos.endRoadId = tempRoad.vectorId; if (angle > Constant.maxAngle) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; limitInfos.newEndRoadId = true; } } else { let tempRoad, tempRoadId; info = dataService.roadIdForMinAngle(road.endId, roadId); const road1 = dataService.getRoad(info.min0.roadId); const startPoint1 = dataService.getRoadPoint(road1.startId); const endPoint1 = dataService.getRoadPoint(road1.endId); const road2 = dataService.getRoad(info.min1.roadId); const startPoint2 = dataService.getRoadPoint(road2.startId); const endPoint2 = dataService.getRoadPoint(road2.endId); const join1 = mathUtil.getIntersectionPoint4( startPoint1, endPoint1, newLine ); const join2 = mathUtil.getIntersectionPoint4( startPoint2, endPoint2, newLine ); // 取角度大的 if (join1 == null && join2 == null) { let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId); let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId); if (angle0 > 180) { angle0 = 180 - angle0; } if (angle1 > 180) { angle1 = 180 - angle1; } if (angle0 < angle1) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } limitInfos.newEndRoadId = true; } // 取角度小的 else if (join1 != null && join2 != null) { if (info.min0.angle < info.min1.angle) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } } else if (join1 == null && join2 != null) { tempRoadId = info.min1.roadId; } else if (join1 != null && join2 == null) { tempRoadId = info.min0.roadId; } limitInfos.endRoadId = tempRoadId; tempRoad = dataService.getRoad(tempRoadId); const angle = roadService.AngleForRoad(tempRoadId, roadId); endLimitLine = roadService.getMidLine(tempRoad); let join = mathUtil.getIntersectionPoint(endLimitLine, newLine); const tempStartPoint = dataService.getRoadPoint(tempRoad.start); const tempEndPoint = dataService.getRoadPoint(tempRoad.end); if ( angle > Constant.maxAngle || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint) ) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; limitInfos.newEndRoadId = true; } } limitInfos.startLimitLine = startLimitLine; limitInfos.endLimitLine = endLimitLine; return limitInfos; } // 是否可以移动point // 两个判断:拖拽的墙(可能是多个),一方面不能与其他墙相交,另一方面这些墙之间或者与别的墙之间的角度必须大于Constant.minAngle canMoveForPoint(pointId, position, linkedRoadPointId, linkedRoadId) { const point = dataService.getRoadPoint(pointId); // 先判断第二点(这些墙之间或者与别的墙之间的角度必须大于MinAngle) let flag = this.isOKForMinAngleRoad(pointId, position); // 开始考虑第一点 if (flag) { // 不仅仅角度,还有相交 flag = this.isOKForCross( pointId, position, point.parent, linkedRoadPointId, linkedRoadId ); } return flag; } isOKForMinAngleRoad(pointId, position) { const point = dataService.getRoadPoint(pointId); const parent = point.parent; const angle = this.getMinAngle(pointId, position); if (Math.abs(angle) < Constant.minAngle) { return false; } // 判断邻居点 for (const key in parent) { 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) { return false; } else { const otherPoint = dataService.getRoadPoint(otherPointId); if (mathUtil.getDistance(position, otherPoint) < Constant.minRealDis) { return false; } } } return true; } //点pointId移动到position后,求出最小角度 getMinAngle(pointId, position) { const point = dataService.getRoadPoint(pointId); const parent = point.parent; let angle = null; if (Object.keys(parent).length == 1) { 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]); const otherPointId1 = road1.getOtherPointId(pointId); const otherPoint1 = dataService.getRoadPoint(otherPointId1); const otherPointId2 = road2.getOtherPointId(pointId); const otherPoint2 = dataService.getRoadPoint(otherPointId2); angle = mathUtil.Angle(position, otherPoint1, otherPoint2); return angle; } else { const _position = { x: position.x + 1, y: position.y, }; let angles = []; for (const key in parent) { const road = dataService.getRoad(key); const otherPointId = road.getOtherPointId(pointId); const otherPoint = dataService.getRoadPoint(otherPointId); if (mathUtil.equalPoint(_position, otherPoint)) { angles.push(0); continue; } else { let angle = mathUtil.Angle(position, _position, otherPoint); // 统一按照逆时针顺序 if (otherPoint.y < position.y) { angle = 360 - angle; } angles.push(angle); } } angles = angles.sort(sortNumber); 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]; if (_angle < minAngle) { minAngle = _angle; } } } const angle1 = angles[0]; const angle2 = angles[angles.length - 1]; if (angle1 < 180 && angle2 > 180) { const dAngle = 360 + angle1 - angle2; if (dAngle < minAngle) { minAngle = dAngle; } } return minAngle; } function sortNumber(a, b) { return a - b; } } // 用于邻居点 // pointId是顶点 // position是roadId相对于pointId另一头的点的坐标,一般发生改变的时候使用这个函数 getNeighMinAngle(otherPointId, roadId, position) { const point1 = dataService.getRoadPoint(otherPointId); const point2 = { x: position.x, y: position.y, }; let pointId3 = null; let point3 = null; let minAngle = null; let result = null; for (const key in point1.parent) { if (key == roadId) { continue; } const road = dataService.getRoad(key); pointId3 = road.getOtherPointId(otherPointId); point3 = dataService.getRoadPoint(pointId3); const angle = mathUtil.Angle(point1, point2, point3); if (minAngle == null || minAngle > angle) { minAngle = angle; result = { angle: minAngle, pointId: pointId3, }; } } return result; } // linkedRoadPointId,linkedRoadId表示吸附 // roadIds是pointId的parent isOKForCross(pointId, position, roadIds, linkedRoadPointId, linkedRoadId) { const roads = dataService.getRoads(); for (const key in roads) { if (roadIds.hasOwnProperty(key)) { continue; } else if (linkedRoadId == key) { continue; } for (const _key in roadIds) { //相连就不用考虑了 if (roadService.isRoadLink(key, _key)) { continue; } const _road = dataService.getRoad(_key); const otherPointId = _road.getOtherPointId(pointId); const otherPoint = dataService.getRoadPoint(otherPointId); const flag = this.isOKForCrossTwoRoad( position, otherPoint, key, linkedRoadPointId, linkedRoadId, _road.vectorId ); // 交叉 if (!flag) { this.adsorbPointRoads = {}; return false; } } } //需要吸附了。 if (Object.keys(this.adsorbPointRoads).length > 0) { return false; } else if (this.splitRoadId != null) { return false; } // 不交叉 return true; } // position1表示拖拽的点的坐标(修复过了的) // position2对应墙的另一头坐标 // roadId表示其余的墙(与position1无关的墙) isOKForCrossTwoRoad( position1, position2, roadId, linkedRoadPointId, linkedRoadId, dragRoadId ) { const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); const join = mathUtil.getIntersectionPoint3( position1, position2, startPoint, endPoint ); if ( join && road.startId != linkedRoadPointId && road.endId != linkedRoadPointId ) { // 交叉了 this.splitRoadId = roadId; return true; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); let join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2) ) { if (road.startId != linkedRoadPointId) { // 交叉了 this.adsorbPointRoads[startPoint.vectorId] = dragRoadId; //为了找到全部的吸附点,暂时返回true,在外面一层再做判断 return true; } } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2) ) { if (road.endId != linkedRoadPointId) { // 交叉了 this.adsorbPointRoads[endPoint.vectorId] = dragRoadId; //为了找到全部的吸附点,暂时返回true,在外面一层再做判断 return true; } } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); join2 = mathUtil.getJoinLinePoint(position2, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && mathUtil.PointInSegment(join1, startPoint, endPoint) ) { if ( road.startId != linkedRoadPointId && road.endId != linkedRoadPointId && roadId != linkedRoadId ) { // 交叉了 //return false return true; } } else if ( mathUtil.getDistance(join2, position2) < Constant.minRealDis && mathUtil.PointInSegment(join2, startPoint, endPoint) ) { if ( road.startId != linkedRoadPointId && road.endId != linkedRoadPointId && roadId != linkedRoadId ) { // 交叉了 //return false return true; } } } return true; } isOKForCrossTwoRoad2(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); let flag = mathUtil.crossTwoLines( position1, position2, startPoint, endPoint, 0.01 ); if (flag) { // 交叉了 return false; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } flag = this.isCoincide(position1, position2, roadId); if (!flag) { return false; } } return true; } isOKForCrossTwoRoad3(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); const flag = mathUtil.crossTwoLines( position1, position2, startPoint, endPoint, 0.01 ); if (flag) { // 交叉了 return false; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); const join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join1, position1, position2) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join2, position1, position2) ) { // 交叉了 return false; } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1) ) { // 交叉了 return false; } } return true; } isCoincide(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); let join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2) ) { // 交叉了 return false; } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); join2 = mathUtil.getJoinLinePoint(position2, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, position2) < Constant.minRealDis && roadService.isContain(road, join2) ) { // 交叉了 return false; } return true; } // 更新virtualPosition(一般是吸附) updateVirtualPosition(pointId, virtualPosition, limitRoadId, needNew) { const limitRoad = dataService.getRoad(limitRoadId); const point = dataService.getRoadPoint(pointId); let otherPointId, otherPoint; let adsorb = false; // 不需要新建墙 if (!needNew) { if (limitRoad != null) { otherPointId = limitRoad.getOtherPointId(pointId); otherPoint = dataService.getRoadPoint(otherPointId); // 会吸附另一头 if ( mathUtil.getDistance(virtualPosition, otherPoint) < Constant.minRealDis || (!roadService.isContain(limitRoad, virtualPosition) && mathUtil.getDistance(virtualPosition, otherPoint) < mathUtil.getDistance(virtualPosition, point)) ) { mathUtil.clonePoint(virtualPosition, otherPoint); adsorb = true; } } } // 需要新建墙 else { // 新建的墙太短,不允许 if (mathUtil.getDistance(point, virtualPosition) < Constant.minRealDis) { return null; } } return { adsorb: adsorb, adsorbPointId: adsorb ? otherPointId : null, virtualPosition: virtualPosition, }; } // 两条线段的夹角,这两条线段分别有一个端点挨的很近 isOKForTwoSegmentsAngle(pointId, pointId1, pointId2) { const point = dataService.getRoadPoint(pointId); const point1 = dataService.getRoadPoint(pointId1); const point2 = dataService.getRoadPoint(pointId2); const dx = point.x - point1.x; const dy = point.y - point1.y; const newPoint2 = { x: dx + point2.x, y: dy + point2.y, }; for (const key in point.parent) { const road = dataService.getRoad(key); const otherPointId = road.getOtherPointId(pointId); const otherPoint = dataService.getRoadPoint(otherPointId); const angle = mathUtil.Angle(point, otherPoint, newPoint2); if (Math.abs(angle) < Constant.minAngle) { return false; } } return true; } // 一头吸附后,是否会重合 // pointId属于roadId,当pointId吸附到adsorbPointId时 isCoincideForAdsorbOne(pointId, adsorbPointId, roadId) { if (pointId && adsorbPointId) { const road = dataService.getRoad(roadId); const otherPointId = road.getOtherPointId(pointId); const _roadId = roadService.getRoadId(otherPointId, adsorbPointId); if (_roadId != null) { return true; } } return false; } isCoincideForAdsorbOne2(roadId, adsorbPointId1, adsorbPointId2) { if (adsorbPointId1 && adsorbPointId2) { const _roadId = roadService.getRoadId(adsorbPointId1, adsorbPointId2); if (_roadId != null) { return true; } // 可能吸附的是两堵墙,但是这两堵墙呈180° else { let adsorbPoint = dataService.getRoadPoint(adsorbPointId1); let parent = adsorbPoint.parent; for (const key in parent) { const angle = roadService.AngleForRoad3(roadId, key); if (Math.abs(angle) < Constant.minAngle) { return true; } } adsorbPoint = dataService.getRoadPoint(adsorbPointId2); parent = adsorbPoint.parent; for (const key in parent) { const angle = roadService.AngleForRoad3(roadId, key); if (Math.abs(angle) < Constant.minAngle) { return true; } } } } return false; } // position1和position2表示road的两个端点坐标(下一步的) // position3和position4表示road的start一边的线段(startPoint——virtualStartPoint) // position5和position6表示road的end一边的线段(endPoint——virtualEndPoint) // adsorbPointId1对应start那一头的吸附点 // adsorbPointId2对应end那一头的吸附点 isOKForCrossForMoveRoad( position1, position2, roadId, startPointId, endPointId, adsorbPointId1, adsorbPointId2 ) { const startPoint = dataService.getRoadPoint(startPointId); const endPoint = dataService.getRoadPoint(endPointId); let flag = true; const roads = dataService.getRoads(); for (const key in roads) { if (key == roadId) { continue; } let flag1 = true; let flag2 = true; const _road = dataService.getRoad(key); if ( adsorbPointId1 && (adsorbPointId1 == _road.startId || adsorbPointId1 == _road.endId) ) { flag1 = false; } if ( adsorbPointId2 && (adsorbPointId2 == _road.startId || adsorbPointId2 == _road.endId) ) { flag2 = false; } if (_road.startId == startPointId || _road.endId == startPointId) { flag1 = false; } if (_road.startId == endPointId || _road.endId == endPointId) { flag2 = false; } // 两头不连 if (flag1 && flag2) { flag = this.isOKForCrossTwoRoad2(position1, position2, key); } if (!flag) { return false; } if ( flag1 && _road.startId != startPointId && _road.endId != startPointId ) { flag = this.isOKForCrossTwoRoad3(position1, startPoint, key); } if (!flag) { return false; } if (flag2 && _road.startId != endPointId && _road.endId != endPointId) { flag = this.isOKForCrossTwoRoad3(position2, endPoint, key); } if (!flag) { return false; } } return flag; } moveRoad(roadId, dx, dy) { dx = dx; dy = -dy; const road = dataService.getRoad(roadId); const startPoint = dataService.getRoadPoint(road.startId); const endPoint = dataService.getRoadPoint(road.endId); if ( Object.keys(startPoint.getParent()).length == 1 && Object.keys(endPoint.getParent()).length == 1 ) { const p1 = { x: startPoint.x + dx, y: startPoint.y + dy }; const p2 = { x: endPoint.x + dx, y: endPoint.y + dy }; startPoint.setPosition(p1); endPoint.setPosition(p2); let leftEdge = dataService.getRoadEdge(road.leftEdgeId); leftEdge.start.x += dx; leftEdge.start.y += dy; leftEdge.end.x += dx; leftEdge.end.y += dy; let rightEdge = dataService.getRoadEdge(road.rightEdgeId); rightEdge.start.x += dx; rightEdge.start.y += dy; rightEdge.end.x += dx; rightEdge.end.y += dy; roadService.setLanes(roadId); } } //需要更新:points,leftLanes,rightLanes,leftEdgeId,rightEdgeId moveCurveRoad(curveRoadId, dx, dy) { dx = dx; dy = -dy; const curveRoad = dataService.getCurveRoad(curveRoadId); const leftCurveEdge = dataService.getCurveRoadEdge(curveRoad.leftEdgeId); const rightCurveEdge = dataService.getCurveRoadEdge(curveRoad.rightEdgeId); for (let i = 0; i < curveRoad.points.length; ++i) { curveRoad.points[i].x += dx; curveRoad.points[i].y += dy; leftCurveEdge.points[i].x += dx; leftCurveEdge.points[i].y += dy; rightCurveEdge.points[i].x += dx; rightCurveEdge.points[i].y += dy; } curveRoad.curves = mathUtil.getCurvesByPoints(curveRoad.points); leftCurveEdge.curves = mathUtil.getCurvesByPoints(leftCurveEdge.points); rightCurveEdge.curves = mathUtil.getCurvesByPoints(rightCurveEdge.points); for (let i = 0; i < curveRoad.leftLanes.length; ++i) { for (let j = 0; j < curveRoad.leftLanes[i].length; ++j) { curveRoad.leftLanes[i][j].x += dx; curveRoad.leftLanes[i][j].y += dy; } curveRoad.leftLanesCurves[i] = mathUtil.getCurvesByPoints( curveRoad.leftLanes[i] ); } for (let i = 0; i < curveRoad.rightLanes.length; ++i) { for (let j = 0; j < curveRoad.rightLanes[i].length; ++j) { curveRoad.rightLanes[i][j].x += dx; curveRoad.rightLanes[i][j].y += dy; } curveRoad.rightLanesCurves[i] = mathUtil.getCurvesByPoints( curveRoad.rightLanes[i] ); } } // pointId1移动到pointId2 // 如果有一堵墙(roadId)的两头是pointId1和pointId2,那么这堵墙会被删除 moveTo(pointId1, pointId2) { const roadId = roadService.getRoadId(pointId1, pointId2); // 不能重合 let point1 = dataService.getRoadPoint(pointId1); let point2 = dataService.getRoadPoint(pointId2); if (!point2) { return false; } 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.getRoadPoint(otherPointId1); for (const roadId2 in parent2) { if (roadId2 == roadId) { continue; } const road2 = dataService.getRoad(roadId2); const otherPointId2 = road2.getOtherPointId(pointId2); const otherPoint2 = dataService.getRoadPoint(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.getRoadPoint(pointId1); point2 = dataService.getRoadPoint(pointId2); if (!point1 || !point2) { return false; } //准备合并 for (const roadId1 in parent1) { const road1 = dataService.getRoad(roadId1); const otherPointId = road1.getOtherPointId(pointId1); const _roadId = roadService.getRoadId(otherPointId, pointId2); if (_roadId != null) { return false; } // road1上pointId1被pointId2取代 if (road1.startId == pointId1) { dataService.deleteRoadPoint(road1.startId, roadId1); road1.startId = pointId2; point2.setPointParent(roadId1, "start"); } else if (road1.endId == pointId1) { dataService.deleteRoadPoint(road1.endId, roadId1); road1.endId = pointId2; point2.setPointParent(roadId1, "end"); } else { console.error( "roadService.moveTo****************************************************" ); } } edgeService.updateEdgeForMovePoint(pointId2); return true; } // // // createRoadForMoveRoad(pointId, roadId, newPosition) { // const road = dataService.getRoad(roadId); // const dir = roadService.getDirction(pointId, roadId); // // 第一步是断开连接 // roadService.subtraRoadFromIntersect(pointId, roadId); // // 第二步更新端点坐标 // const newPointId = road.getPointId(dir); // const newPoint = dataService.getRoadPoint(newPointId); // newPoint.setPosition(newPosition); // // 第三步先新建墙 // roadService.create(pointId, newPointId); // // 还缺少road和newRoad相交,这需要等另一头的point完成后最后处理 // } deleteRoadForLinked(roadId) { const road = dataService.getRoad(roadId); roadService.subtraRoadFromIntersect(road.startId, roadId); roadService.subtraRoadFromIntersect(road.endId, roadId); dataService.deleteRoad(roadId); } /******************************************************************************************************************************************************************************/ moveCurveRoadPoint(pointId, position) { // let point = dataService.getCurvePoint(pointId); // point.setPosition(position); // const curveRoadId = point.getParent(); // const curveRoad = dataService.getCurveRoad(curveRoadId); // curveRoadService.updateForMovePoint(curveRoad, point.index); curveRoadService.updateForMovePoint(pointId, position); } moveCrossPoint(crossPointId, position) { crossPointService.updateForMovePoint(crossPointId, position); } moveEdge(edgeId, position) { const edge = dataService.getRoadEdge(edgeId); const parent = edge.getParent(); const road = dataService.getRoad(parent); const line = roadService.getMidLine(road); let dir = "left"; if (road.rightEdgeId == edgeId) { dir = "right"; } const newWidth = mathUtil.getDisForPoinLine(position, line); if ( newWidth > Constant.minRoadSideWidth && newWidth < Constant.maxRoadSideWidth ) { roadService.updateForWidth(parent, newWidth, dir); } } moveCurveEdge(curveEdgeId, index, position) { const curveEdge = dataService.getCurveRoadEdge(curveEdgeId); const parent = curveEdge.getParent(); const curveRoad = dataService.getCurveRoad(parent); let joinInfo = null; let dir = "left"; if (curveRoad.rightEdgeId == curveEdgeId) { dir = "right"; } if (dir == "left") { joinInfo = mathUtil.getHitInfoForCurve( position, curveRoad.curves[index], curveRoad.leftWidth ); } else if (dir == "right") { joinInfo = mathUtil.getHitInfoForCurve( position, curveRoad.curves[index], curveRoad.rightWidth ); } const newWidth = mathUtil.getDistance(joinInfo.position, position); if ( newWidth > Constant.minRoadSideWidth && newWidth < Constant.maxRoadSideWidth ) { curveRoadService.updateForWidth(parent, newWidth, dir); } } /******************************************************************************************************************************************************************************/ } const moveRoad = new MoveRoad(); export { moveRoad };