1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207 |
- 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 };
|