12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205 |
- 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 { controlPointService } from "../Service/ControlPointService";
- export default class MoveRoad {
- constructor() {
- this.moveFlag = false;
- //拖拽墙角的时候,墙角的父亲与其他墙角相交
- this.adsorbPointRoads = {};
- //拖拽墙角的时候,该墙角与其他墙面相交
- this.splitRoadId = null;
- }
- // 测试要考虑pointId拖拽到包含他的所有墙的另一头
- // 这个函数不会删除/拆分/合并墙或者点
- moveingRoadPoint(pointId, position, modifyPoint) {
- let point = dataService.getRoadPoint(pointId);
- let linkedPointId = null;
- let linkedRoadId = null;
- if (modifyPoint != null) {
- position = {
- x: modifyPoint.x,
- y: modifyPoint.y,
- };
- linkedPointId = modifyPoint.linkedPointId;
- 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,
- linkedPointId,
- 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("linkedPointId") &&
- modifyPoint.linkedPointId != null
- ) {
- const roadId = roadService.getRoadId(pointId, modifyPoint.linkedPointId);
- // 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("linkedPointIdX") &&
- modifyPoint.linkedPointIdX
- ) {
- point.setPosition(position);
- }
- if (
- modifyPoint.hasOwnProperty("linkedPointIdY") &&
- modifyPoint.linkedPointIdY
- ) {
- 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, linkedPointId, linkedRoadId) {
- const point = dataService.getRoadPoint(pointId);
- // 先判断第二点(这些墙之间或者与别的墙之间的角度必须大于MinAngle)
- let flag = this.isOKForMinAngleRoad(pointId, position);
- // 开始考虑第一点
- if (flag) {
- // 不仅仅角度,还有相交
- flag = this.isOKForCross(
- pointId,
- position,
- point.parent,
- linkedPointId,
- 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;
- }
- // linkedPointId,linkedRoadId表示吸附
- // roadIds是pointId的parent
- isOKForCross(pointId, position, roadIds, linkedPointId, 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,
- linkedPointId,
- 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,
- linkedPointId,
- 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 != linkedPointId && road.endId != linkedPointId) {
- // 交叉了
- 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 != linkedPointId) {
- // 交叉了
- this.adsorbPointRoads[startPoint.vectorId] = dragRoadId;
- //为了找到全部的吸附点,暂时返回true,在外面一层再做判断
- return true;
- }
- } else if (
- mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
- mathUtil.PointInSegment(join2, position1, position2)
- ) {
- if (road.endId != linkedPointId) {
- // 交叉了
- 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 != linkedPointId &&
- road.endId != linkedPointId &&
- roadId != linkedRoadId
- ) {
- // 交叉了
- //return false
- return true;
- }
- } else if (
- mathUtil.getDistance(join2, position2) < Constant.minRealDis &&
- mathUtil.PointInSegment(join2, startPoint, endPoint)
- ) {
- if (
- road.startId != linkedPointId &&
- road.endId != linkedPointId &&
- 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.getEdge(road.leftEdgeId);
- leftEdge.start.x += dx;
- leftEdge.start.y += dy;
- leftEdge.end.x += dx;
- leftEdge.end.y += dy;
- let rightEdge = dataService.getEdge(road.rightEdgeId);
- rightEdge.start.x += dx;
- rightEdge.start.y += dy;
- rightEdge.end.x += dx;
- rightEdge.end.y += dy;
- roadService.setLanes(roadId);
- roadService.setMidDivide(roadId);
- }
- }
- //需要更新:points,leftLanes,rightLanes,leftEdgeId,rightEdgeId
- moveCurveRoad(curveRoadId, dx, dy) {
- dx = dx;
- dy = -dy;
- const curveRoad = dataService.getCurveRoad(curveRoadId);
- const leftCurveEdge = dataService.getCurveEdge(curveRoad.leftEdgeId);
- const rightCurveEdge = dataService.getCurveEdge(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);
- }
- moveControlPoint(controlPointId, position) {
- controlPointService.updateForMovePoint(controlPointId, position);
- }
- moveEdge(edgeId, position) {
- const edge = dataService.getEdge(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.getCurveEdge(curveEdgeId);
- const parent = curveEdge.getParent();
- const curveRoad = dataService.getCurveRoad(parent);
- let joinInfo = null;
- let dir = "left";
- if (curveRoad.rightEdgeId == curveEdgeId) {
- dir = "right";
- }
- // const line = mathUtil.createLine1(
- // curveRoad.points[index],
- // curveRoad.points[index + 1]
- // );
- // const newWidth = mathUtil.getDisForPoinLine(position, line);
- if (dir == "left") {
- joinInfo = mathUtil.getHitInfoForCurve(
- position,
- curveRoad.curves[index],
- curveRoad.leftWidth * 2
- );
- } else if (dir == "right") {
- joinInfo = mathUtil.getHitInfoForCurve(
- position,
- curveRoad.curves[index],
- curveRoad.rightWidth * 2
- );
- }
- 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 };
|