import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js'; import { GraphicDrawAssistant, GraphicIdGenerator, GraphicInteractionPlugin, JlDrawApp, JlGraphic, linePoint, } from 'src/jl-graphic'; import { IAxleCountingSectionData, AxleCountingSection, AxleCountingSectionTemplate, AxleCountingSectionConsts, ITurnoutPosRefData, } from './AxleCountingSection'; import { AxleCounting } from '../axleCounting/AxleCounting'; import { Section } from '../section/Section'; import { Turnout } from '../turnout/Turnout'; import { createRelatedRefProto } from '../CommonGraphics'; function removePortBC(a: T, b: T): boolean { if ((a == 'B' && b == 'C') || (a == 'C' && b == 'B')) { return false; } return true; } export interface IAxleCountingSectionDrawOptions { newData: () => IAxleCountingSectionData; } export class AxleCountingSectionDraw extends GraphicDrawAssistant< AxleCountingSectionTemplate, IAxleCountingSectionData > { codeGraph: AxleCountingSection; constructor(app: JlDrawApp, template: AxleCountingSectionTemplate) { super(app, template, 'sym_o_circle', '不展示'); this.codeGraph = this.graphicTemplate.new(); this.container.addChild(this.codeGraph); AxleCountingSectionInteraction.init(app); } bind(): void { super.bind(); this.codeGraph.loadData(this.graphicTemplate.datas); this.codeGraph.doRepaint(); } clearCache(): void { //this.codeGraph.destroy(); } onLeftDown(e: FederatedPointerEvent): void { this.container.position.copyFrom(this.toCanvasCoordinates(e.global)); this.createAndStore(true); } redraw(p: Point): void { this.container.position.copyFrom(p); } prepareData(data: IAxleCountingSectionData): boolean { data.transform = this.container.saveTransform(); return true; } draw( graphics: AxleCounting[], commonElement: JlGraphic[], map: Map, turoutPos?: number[] ) { if ( map.has(`${graphics[0].id}+${graphics[1].id}`) || map.has(`${graphics[1].id}+${graphics[0].id}`) ) return; map.set(`${graphics[0].id}+${graphics[1].id}`, 1); const axleCountingSection = new AxleCountingSection(); axleCountingSection.loadData(this.graphicTemplate.datas); axleCountingSection.datas.points = [ graphics[0].position, graphics[1].position, ]; axleCountingSection.id = GraphicIdGenerator.next(); const paRef = createRelatedRefProto(graphics[0].type, graphics[0].id); const pbRef = createRelatedRefProto(graphics[1].type, graphics[1].id); const turnoutPosData: ITurnoutPosRefData[] = []; if (commonElement[0].type == 'Turnout') { commonElement.forEach((Turnout, i) => { turnoutPosData.push({ id: Turnout.id, position: (turoutPos as number[])[i], }); }); } axleCountingSection.datas.paRef = paRef; axleCountingSection.datas.pbRef = pbRef; axleCountingSection.datas.turnoutPosRef = turnoutPosData; this.storeGraphic(axleCountingSection); axleCountingSection.loadRelations(); } oneGenerates() { const map = new Map(); const axleCountingSections = this.app.queryStore.queryByType( AxleCountingSection.Type ); axleCountingSections.forEach((axleCountingSection) => { map.set( `${axleCountingSection.datas.paRef?.id}+${axleCountingSection.datas.pbRef?.id}`, 1 ); }); const axleCountings = this.app.queryStore.queryByType( AxleCounting.Type ); axleCountings.forEach((axleCounting) => { //计轴关联的区段 const axleCountingRefSection = axleCounting.relationManage.getRelationsOfGraphicAndOtherType( axleCounting, Section.Type ); axleCountingRefSection.forEach((ref) => { const refDevice = ref.getOtherGraphic
(axleCounting); const refDevicePort = ref.getOtherRelationParam(axleCounting).param; const refDeviceOtherPort = refDevicePort == 'A' ? 'B' : 'A'; const otherPortRefAxle = refDevice.relationManage .getRelationsOfGraphicAndOtherType(refDevice, AxleCounting.Type) .find( (relation) => relation.getRelationParam(refDevice).param == refDeviceOtherPort ) ?.getOtherGraphic(refDevice); if (otherPortRefAxle !== undefined) { this.draw( [axleCounting, otherPortRefAxle as AxleCounting], [refDevice], map ); } }); //计轴关联的道岔 const axleCountingRefTurnout = axleCounting.relationManage.getRelationsOfGraphicAndOtherType( axleCounting, Turnout.Type ); axleCountingRefTurnout.forEach((ref) => { const refDevice = ref.getOtherGraphic(axleCounting); const refDevicePort = ref.getOtherRelationParam(axleCounting).param; let refDeviceOtherPort: string[] = []; switch (refDevicePort) { case 'A': refDeviceOtherPort = ['B', 'C']; break; case 'B': refDeviceOtherPort = ['A', 'C']; break; case 'C': refDeviceOtherPort = ['A', 'B']; break; } //关联道岔的其它端点--需要找路径 refDeviceOtherPort.forEach((port) => { const otherPortRefAxle = refDevice.relationManage .getRelationsOfGraphicAndOtherType(refDevice, AxleCounting.Type) .find( (relation) => relation.getRelationParam(refDevice).param == port ) ?.getOtherGraphic(refDevice); if ( otherPortRefAxle !== undefined && removePortBC(refDevicePort, port) ) { let turoutPos = 0; if (refDevicePort == 'C' || port == 'C') { turoutPos = 1; } this.draw( [axleCounting, otherPortRefAxle as AxleCounting], [refDevice], map, [turoutPos] ); } else if (otherPortRefAxle == undefined) { const refDeviceRefTurnoutRelation = refDevice.relationManage .getRelationsOfGraphicAndOtherType(refDevice, Turnout.Type) .find( (relation) => relation.getRelationParam(refDevice).param == port ); const refDeviceRefTurnout = refDeviceRefTurnoutRelation?.getOtherGraphic(refDevice); const refDeviceRefTurnoutPort = refDeviceRefTurnoutRelation?.getRelationParam( refDeviceRefTurnout as JlGraphic ).param; const otherPortRefAxleInfo: { axle: AxleCounting; turoutPort: string; }[] = []; refDeviceRefTurnout?.relationManage .getRelationsOfGraphicAndOtherType( refDeviceRefTurnout, AxleCounting.Type ) .filter((relation) => { return ( relation.getRelationParam(refDeviceRefTurnout).param !== refDeviceRefTurnoutPort ); }) .forEach((ref) => { otherPortRefAxleInfo.push({ axle: ref.getOtherGraphic(refDeviceRefTurnout), turoutPort: ref.getRelationParam(refDeviceRefTurnout).param, }); }); const bbConnect = port == 'B' && refDeviceRefTurnoutPort == 'B' ? true : false; otherPortRefAxleInfo?.forEach((info) => { if ( (refDevicePort !== 'C' && info.turoutPort !== 'C') || (refDevicePort == 'A' && info.turoutPort == 'C' && !bbConnect) ) { let turoutPos: number[] = []; if ( refDevicePort == 'A' && info.turoutPort == 'C' && !bbConnect ) { turoutPos = [0, 1]; } else { turoutPos = [0, 0]; } this.draw( [axleCounting, info.axle as AxleCounting], [refDevice, refDeviceRefTurnout as JlGraphic], map, turoutPos ); } }); } }); }); }); } } class AxleCountingSectionGraphicHitArea implements IHitArea { axleCountingSection: AxleCountingSection; constructor(axleCountingSection: AxleCountingSection) { this.axleCountingSection = axleCountingSection; } contains(x: number, y: number): boolean { for (let i = 1; i < this.axleCountingSection.datas.points.length; i++) { const p1 = this.axleCountingSection.datas.points[i - 1]; const p2 = this.axleCountingSection.datas.points[i]; if (linePoint(p1, p2, { x, y }, AxleCountingSectionConsts.lineWidth)) { return true; } } return false; } } export class AxleCountingSectionInteraction extends GraphicInteractionPlugin { static Name = 'AxleCountingSection_transform'; constructor(app: JlDrawApp) { super(AxleCountingSectionInteraction.Name, app); } static init(app: JlDrawApp) { return new AxleCountingSectionInteraction(app); } filter(...grahpics: JlGraphic[]): AxleCountingSection[] | undefined { return grahpics .filter((g) => g.type === AxleCountingSection.Type) .map((g) => g as AxleCountingSection); } bind(g: AxleCountingSection): void { g.eventMode = 'static'; g.cursor = 'pointer'; g.scalable = true; g.transformSave = true; g.lineGraphic.eventMode = 'static'; g.lineGraphic.cursor = 'pointer'; g.lineGraphic.hitArea = new AxleCountingSectionGraphicHitArea(g); g.labelGraphic.eventMode = 'static'; g.labelGraphic.cursor = 'pointer'; g.labelGraphic.selectable = true; g.labelGraphic.draggable = true; } unbind(g: AxleCountingSection): void { g.eventMode = 'none'; g.scalable = false; g.rotatable = false; g.lineGraphic.eventMode = 'none'; g.lineGraphic.draggable = false; g.lineGraphic.selectable = false; g.lineGraphic.transformSave = false; g.labelGraphic.eventMode = 'none'; g.labelGraphic.draggable = false; g.labelGraphic.selectable = false; g.labelGraphic.transformSave = false; } }