import { mathUtil } from "./Util/MathUtil"; import { dataService } from "./Service/DataService.js"; import { stateService } from "./Service/StateService.js"; import { roadService } from "./Service/RoadService.js"; import Constant from "./Constant.js"; import VectorType from "./enum/VectorType.js"; import SelectState from "./enum/SelectState.js"; import bezierUtil from "./Util/bezierUtil.js"; import { elementService } from "./Service/ElementService"; import { coordinate } from "./Coordinate"; import { draw } from "./Renderer/Draw.js"; export default class ListenLayer { constructor() { this.roadInfo = { roadId: null, type: null, state: null, }; this.curveRoadInfo = { curveRoadId: null, type: null, state: null, }; this.pointInfo = { pointId: null, type: null, state: null, }; this.curvePointInfo = { curvePointId: null, type: null, state: null, }; this.tagInfo = { tagId: null, state: null, }; this.modifyPoint = null; // this.testStart = null; // this.testEnd = null; // this.testHit = false; } //开始监听,exceptPointId表示不考虑的点,exceptRoadIds表示不考虑的墙 start( position, exceptPointId, exceptRoadIds, exceptCurvePointId, exceptCurveRoadId ) { let isSame = false; this.clear(); let curveRoadInfo = this.isSelectCurveRoad(position, exceptCurveRoadId); let roadInfo = this.isSelectRoad(position, exceptRoadIds); let curvePointInfo = this.isSelectCurvePoint(position, exceptCurvePointId); let pointInfo = this.isSelectPoint(position, exceptPointId); this.setModifyPoint( position, pointInfo, curvePointInfo, roadInfo, curveRoadInfo ); // let flag1 = this.equalAndClone(this.curveRoadInfo, curveRoadInfo); // let flag2 = this.equalAndClone(this.roadInfo, roadInfo); // let flag3 = this.equalAndClone(this.curvePointInfo, curvePointInfo); // let flag4 = this.equalAndClone(this.pointInfo, pointInfo); // isSame = this.updateSelectItem(flag1, flag2, flag3, flag4); isSame = this.updateSelectItem(); return !isSame; } isSelectPoint(position, exceptPointId) { let pointInfo = { pointId: null, type: null, distance: null, }; let seqInfo = {}; const points = dataService.getPoints(); for (const pointId in points) { if (pointId == exceptPointId) { continue; } const point = dataService.getPoint(pointId); const distance = mathUtil.getDistance(position, point); if (distance < Constant.minAdsorbPix) { if (pointInfo.pointId == null) { pointInfo = { pointId: pointId, type: VectorType.Point, distance: distance, }; } else if (pointInfo.pointId != null) { if (distance < pointInfo.distance) { pointInfo = { pointId: pointId, type: VectorType.Point, distance: distance, }; } } } else { if (Math.abs(position.x - point.x) < Constant.minAdsorbPix) { seqInfo.linkedPointIdX = pointId; seqInfo.x = point.x; } else if (Math.abs(position.y - point.y) < Constant.minAdsorbPix) { seqInfo.linkedPointIdY = pointId; seqInfo.y = point.y; } } } if (pointInfo.pointId) { const linkedPoint = dataService.getPoint(pointInfo.pointId); pointInfo.x = linkedPoint.x; pointInfo.y = linkedPoint.y; } //因为这种纠正的权限最低 else { if (seqInfo.hasOwnProperty("linkedPointIdX")) { pointInfo.linkedPointIdX = seqInfo.linkedPointIdX; pointInfo.x = seqInfo.x; } if (seqInfo.hasOwnProperty("linkedPointIdY")) { pointInfo.linkedPointIdY = seqInfo.linkedPointIdY; pointInfo.y = seqInfo.y; } if (pointInfo.hasOwnProperty("y") && !pointInfo.hasOwnProperty("x")) { pointInfo.x = position.x; } if (pointInfo.hasOwnProperty("x") && !pointInfo.hasOwnProperty("y")) { pointInfo.y = position.y; } } return pointInfo; } isSelectCurvePoint(position, exceptCurvePointId) { let curvePointInfo = { curvePointId: null, type: null, distance: null, }; let seqInfo = {}; const curvePoints = dataService.getCurvePoints(); for (const curvePointId in curvePoints) { if (curvePointId == exceptCurvePointId) { continue; } const curvePoint = dataService.getCurvePoint(curvePointId); const distance = mathUtil.getDistance(position, curvePoint); if (distance < Constant.minAdsorbPix) { if (curvePointInfo.curvePointId == null) { curvePointInfo = { curvePointId: curvePointId, type: VectorType.CurvePoint, distance: distance, }; } else if (curvePointInfo.pointId != null) { if (distance < curvePointInfo.distance) { curvePointInfo = { curvePointId: curvePointId, type: VectorType.CurvePoint, distance: distance, }; } } } else { if (Math.abs(position.x - curvePoint.x) < Constant.minAdsorbPix) { seqInfo.linkedPointIdX = curvePointId; seqInfo.x = curvePoint.x; } else if ( Math.abs(position.y - curvePoint.y) < Constant.minAdsorbPix ) { seqInfo.linkedPointIdY = curvePointId; seqInfo.y = curvePoint.y; } } } if (curvePointInfo.curvePointId) { curvePointInfo.linkedCurvePointId = curvePointInfo.curvePointId; const linkedCurvePoint = dataService.getCurvePoint( curvePointInfo.curvePointId ); curvePointInfo.x = linkedCurvePoint.x; curvePointInfo.y = linkedCurvePoint.y; } else { if (seqInfo.hasOwnProperty("linkedPointIdX")) { curvePointInfo.linkedPointIdX = seqInfo.linkedPointIdX; curvePointInfo.x = seqInfo.x; } else if (seqInfo.hasOwnProperty("linkedPointIdY")) { curvePointInfo.linkedPointIdY = seqInfo.linkedPointIdY; curvePointInfo.y = seqInfo.y; } if ( curvePointInfo.hasOwnProperty("y") && !curvePointInfo.hasOwnProperty("x") ) { curvePointInfo.x = position.x; } if ( curvePointInfo.hasOwnProperty("x") && !curvePointInfo.hasOwnProperty("y") ) { curvePointInfo.y = position.y; } } return curvePointInfo; } isSelectRoad(position, exceptRoadIds) { let roadInfo = { roadId: null, type: null, distance: null, }; const roads = dataService.getRoads(); for (const roadId in roads) { if (exceptRoadIds != null && exceptRoadIds.hasOwnProperty(roadId)) { continue; } const road = dataService.getRoad(roadId); let startPoint = dataService.getPoint(road.startId); let endPoint = dataService.getPoint(road.endId); const roadLine = roadService.getMidLine(road); const join = mathUtil.getJoinLinePoint(position, roadLine); const distance = mathUtil.getDistance(position, join); if ( distance < road.width / 2 && mathUtil.isContainForSegment(join, startPoint, endPoint) ) { if (roadInfo.roadId == null) { roadInfo = { roadId: roadId, type: VectorType.Road, distance: distance, }; } else if (roadInfo.roadId != null) { if (distance < roadInfo.distance) { roadInfo = { roadId: roadId, type: VectorType.Road, distance: mathUtil.getDisForPoinLine(position, roadLine), }; } } } } if (roadInfo.roadId) { const linkedRoad = dataService.getRoad(roadInfo.roadId); const linkedRoadLine = roadService.getMidLine(linkedRoad); const linkedPosition = mathUtil.getJoinLinePoint( position, linkedRoadLine ); roadInfo.x = linkedPosition.x; roadInfo.y = linkedPosition.y; } return roadInfo; } isSelectCurveRoad(position, exceptCurveRoadId) { let curveRoadInfo = { curveRoadId: null, type: null, distance: null, }; const curveRoads = dataService.getCurveRoads(); for (const curveRoadId in curveRoads) { if (curveRoadId == exceptCurveRoadId) { continue; } const curveRoad = dataService.getCurveRoad(curveRoadId); let joinInfo = this.distanceForBezier(position, curveRoad.curves); if (joinInfo.distance < Constant.minAdsorbPix) { curveRoadInfo = { curveRoadId: curveRoadId, type: VectorType.CurveRoad, distance: joinInfo.distance, x: joinInfo.position.x, y: joinInfo.position.y, }; } } return curveRoadInfo; } setModifyPoint(position, pointInfo, curvePointInfo, roadInfo, curveRoadInfo) { //优先级最高 if (pointInfo.pointId || curvePointInfo.curvePointId) { this.modifyPoint = {}; if (pointInfo.pointId && curvePointInfo.curvePointId) { if (pointInfo.distance < curvePointInfo.distance) { this.modifyPoint.linkedPointId = pointInfo.pointId; this.modifyPoint.x = pointInfo.x; this.modifyPoint.y = pointInfo.y; } else { this.modifyPoint.linkedCurvePointId = curvePointInfo.curvePointId; this.modifyPoint.x = curvePointInfo.x; this.modifyPoint.y = curvePointInfo.y; } } else if (pointInfo.pointId) { this.modifyPoint.linkedPointId = pointInfo.pointId; this.modifyPoint.x = pointInfo.x; this.modifyPoint.y = pointInfo.y; } else if (curvePointInfo.curvePointId) { this.modifyPoint.linkedCurvePointId = curvePointInfo.curvePointId; this.modifyPoint.x = curvePointInfo.x; this.modifyPoint.y = curvePointInfo.y; } } else if (roadInfo.roadId || curveRoadInfo.curveRoadId) { this.modifyPoint = {}; if (roadInfo.roadId && curveRoadInfo.curveRoadId) { if (roadInfo.distance < curveRoadInfo.distance) { this.modifyPoint.linkedRoadId = roadInfo.roadId; this.modifyPoint.x = roadInfo.x; this.modifyPoint.y = roadInfo.y; } else { this.modifyPoint.linkedCurveRoadId = curveRoadInfo.curveRoadId; this.modifyPoint.x = curveRoadInfo.x; this.modifyPoint.y = curveRoadInfo.y; } } else if (roadInfo.roadId) { this.modifyPoint.linkedRoadId = roadInfo.roadId; this.modifyPoint.x = roadInfo.x; this.modifyPoint.y = roadInfo.y; } else if (curveRoadInfo.curveRoadId) { this.modifyPoint.linkedCurveRoadId = curveRoadInfo.curveRoadId; this.modifyPoint.x = curveRoadInfo.x; this.modifyPoint.y = curveRoadInfo.y; } } else if (pointInfo.linkedPointIdX) { this.modifyPoint = {}; this.modifyPoint.linkedPointIdX = pointInfo.linkedPointIdX; this.modifyPoint.x = pointInfo.x; this.modifyPoint.y = position.y; } else if (pointInfo.linkedPointIdY) { this.modifyPoint = {}; this.modifyPoint.linkedPointIdY = pointInfo.linkedPointIdY; this.modifyPoint.y = pointInfo.y; this.modifyPoint.x = position.x; } else if (curvePointInfo.linkedPointIdX) { this.modifyPoint = {}; this.modifyPoint.linkedPointIdX = curvePointInfo.linkedPointIdX; this.modifyPoint.x = curvePointInfo.x; this.modifyPoint.y = position.y; } else if (curvePointInfo.linkedPointIdY) { this.modifyPoint = {}; this.modifyPoint.linkedPointIdY = curvePointInfo.linkedPointIdY; this.modifyPoint.y = curvePointInfo.y; this.modifyPoint.x = position.x; } else { this.modifyPoint = null; } } updateSelectItem() { let selectItem = stateService.getSelectItem(); if (this.modifyPoint == null) { if (selectItem != null) { stateService.clearSelectItem(); return true; } else { return false; } } else if (this.modifyPoint.linkedPointId) { stateService.setSelectItem( this.modifyPoint.linkedPointId, VectorType.Point, SelectState.Select ); } else if (this.modifyPoint.linkedCurvePointId) { stateService.setSelectItem( this.modifyPoint.linkedCurvePointId, VectorType.CurvePoint, SelectState.Select ); } else if (this.modifyPoint.linkedRoadId) { stateService.setSelectItem( this.modifyPoint.linkedRoadId, VectorType.Road, SelectState.Select ); } else if (this.modifyPoint.linkedCurveRoadId) { stateService.setSelectItem( this.modifyPoint.linkedCurveRoadId, VectorType.CurveRoad, SelectState.Select ); } let newSelectItem = stateService.getSelectItem(); if (selectItem == null && newSelectItem == null) { return false; } else if (selectItem == null && newSelectItem != null) { return true; } else if (selectItem != null && newSelectItem == null) { return true; } else if (selectItem.vectorId == newSelectItem.vectorId) { return false; } else { return true; } // if (!flag1) { // stateService.setSelectItem( // this.curveRoadInfo.curveRoadId, // this.curveRoadInfo.type, // this.curveRoadInfo.state // ); // } // if (!flag2) { // stateService.setSelectItem( // this.roadInfo.roadId, // this.roadInfo.type, // this.roadInfo.state // ); // } // if (!flag3) { // stateService.setSelectItem( // this.curvePointInfo.curvePointId, // this.curvePointInfo.type, // this.curvePointInfo.state // ); // } // if (!flag4) { // stateService.setSelectItem( // this.pointInfo.pointId, // this.pointInfo.type, // this.pointInfo.state // ); // } // let selectItem = stateService.getSelectItem(); // if (selectItem != null) { // console.log("监听:" + JSON.stringify(selectItem)); // } // return flag1 && flag2 && flag3 && flag4; } distanceForBezier(position, curves) { let joinInfo = { position: null, distance: null, }; for (let i = 0; i < curves.length; ++i) { const curve = curves[i]; let bezierData = []; bezierData.push(curve.start.x); bezierData.push(curve.start.y); bezierData.push(curve.control.x); bezierData.push(curve.control.y); bezierData.push(curve.end.x); bezierData.push(curve.end.y); const { isHit, getInfo } = bezierUtil.measureBezier(...bezierData); const { point } = getInfo(position); if ( joinInfo.distance == null || mathUtil.getDistance(position, { x: point[0], y: point[1], }) < joinInfo.distance ) { joinInfo.distance = mathUtil.getDistance(position, { x: point[0], y: point[1], }); joinInfo.position = { x: point[0], y: point[1], }; } } return joinInfo; } equalAndClone(info1, info2) { let flag = true; for (let key in info1) { if (info1[key] != info2[key]) { flag = false; } info1[key] = info2[key]; } return flag; } clear() { this.roadInfo = { roadId: null, type: null, state: null, }; this.curveRoadInfo = { curveRoadId: null, type: null, state: null, }; this.pointInfo = { pointId: null, type: null, state: null, }; this.curvePointInfo = { curvePointId: null, type: null, state: null, }; this.tagInfo = { tagId: null, state: null, }; this.modifyPoint = null; } } const listenLayer = new ListenLayer(); export { listenLayer };