rts-sim-testing-client/src/graphics/axleCountingSection/AxleCountingSectionAssistant.ts

398 lines
12 KiB
TypeScript
Raw Normal View History

2023-07-12 17:16:12 +08:00
import { FederatedPointerEvent, IHitArea, IPointData, Point } from 'pixi.js';
2023-07-07 17:15:53 +08:00
import {
GraphicDrawAssistant,
GraphicIdGenerator,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
linePoint,
} from 'src/jl-graphic';
import {
IAxleCountingSectionData,
AxleCountingSection,
AxleCountingSectionTemplate,
AxleCountingSectionConsts,
2023-07-11 15:35:35 +08:00
ITurnoutPosRefData,
2023-07-07 17:15:53 +08:00
} from './AxleCountingSection';
import { AxleCounting } from '../axleCounting/AxleCounting';
2023-07-12 18:42:52 +08:00
import { Turnout, TurnoutPort } from '../turnout/Turnout';
2023-07-07 17:15:53 +08:00
import { createRelatedRefProto } from '../CommonGraphics';
2023-07-10 13:37:13 +08:00
function hasCommonElements(arr1: string[], arr2: string[]) {
2023-07-07 17:15:53 +08:00
for (let i = 0; i < arr1.length; i++) {
if (arr2.includes(arr1[i])) {
2023-07-10 13:37:13 +08:00
return arr1[i];
2023-07-07 17:15:53 +08:00
}
}
return false;
}
function hasSamePosition(point1: IPointData, point2: IPointData): boolean {
if (
Math.abs(point1.x - point2.x) < 20 &&
Math.abs(point1.y - point2.y) < 20
) {
return true;
}
return false;
}
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);
2023-07-12 17:16:12 +08:00
AxleCountingSectionInteraction.init(app);
2023-07-07 17:15:53 +08:00
}
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;
}
2023-07-11 15:35:35 +08:00
draw(
graphics: AxleCounting[],
commonElement: JlGraphic[],
2023-07-11 17:42:04 +08:00
map: Map<string, number>,
2023-07-11 15:35:35 +08:00
turoutPos?: number
) {
2023-07-11 17:42:04 +08:00
if (
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`)
)
return;
2023-07-07 17:15:53 +08:00
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);
2023-07-11 15:35:35 +08:00
const turnoutPosData: ITurnoutPosRefData[] = [];
if (commonElement[0].type == 'Turnout') {
2023-07-12 18:42:52 +08:00
commonElement.forEach((Turnout, i) => {
if (commonElement.length == 2) {
if (turoutPos == -1) {
if (i == 1) {
turnoutPosData.push({
id: Turnout.id,
position: 1,
});
} else {
turnoutPosData.push({
id: Turnout.id,
position: 0,
});
}
} else
turnoutPosData.push({
id: Turnout.id,
position: 0,
});
2023-07-11 15:35:35 +08:00
} else {
if (turoutPos == 0) {
turnoutPosData.push({
id: Turnout.id,
position: 0,
});
} else {
turnoutPosData.push({
id: Turnout.id,
position: 1,
});
}
}
});
}
2023-07-07 17:15:53 +08:00
axleCountingSection.datas.paRef = paRef;
axleCountingSection.datas.pbRef = pbRef;
2023-07-11 15:35:35 +08:00
axleCountingSection.datas.turnoutPosRef = turnoutPosData;
2023-07-07 17:15:53 +08:00
this.storeGraphic(axleCountingSection);
axleCountingSection.loadRelations();
}
oneGenerates() {
2023-07-11 17:42:04 +08:00
const map = new Map();
2023-07-10 15:03:47 +08:00
const axleCountingSections =
2023-07-07 17:25:51 +08:00
this.app.queryStore.queryByType<AxleCountingSection>(
AxleCountingSection.Type
);
2023-07-11 17:42:04 +08:00
axleCountingSections.forEach((axleCountingSection) => {
map.set(
`${axleCountingSection.datas.paRef?.id}+${axleCountingSection.datas.pbRef?.id}`,
1
);
});
2023-07-07 17:15:53 +08:00
const axleCountings = this.app.queryStore.queryByType<AxleCounting>(
AxleCounting.Type
);
const hasfourTurnout: AxleCounting[][] = [];
axleCountings.forEach((axleCounting) => {
const refDeviceTarget = axleCounting.datas.axleCountingRef.map(
(ref) => ref.id
);
for (let i = 0; i < axleCountings.length - 1; i++) {
if (axleCountings[i].id == axleCounting.id) return;
const refDevice = axleCountings[i].datas.axleCountingRef.map(
(ref) => ref.id
);
2023-07-10 13:37:13 +08:00
const commonElementId = hasCommonElements(refDeviceTarget, refDevice);
if (commonElementId) {
const commonElement = this.app.queryStore.queryById(commonElementId);
let draw = true;
2023-07-11 15:35:35 +08:00
let turoutPos = 0;
//道岔BC端处的计轴不构成计轴区段
2023-07-10 13:37:13 +08:00
if (commonElement.type == 'Turnout') {
let targetPort, port;
axleCounting.datas.axleCountingRef.forEach((ref) => {
if (ref.id == commonElementId) {
targetPort = ref.devicePort;
}
});
axleCountings[i].datas.axleCountingRef.forEach((ref) => {
if (ref.id == commonElementId) {
port = ref.devicePort;
}
});
if (
(targetPort == 1 && port == 2) ||
(targetPort == 2 && port == 1)
) {
draw = false;
}
2023-07-11 15:35:35 +08:00
if (targetPort == 2 || port == 2) {
turoutPos = 1;
}
2023-07-10 13:37:13 +08:00
}
if (draw) {
2023-07-11 15:35:35 +08:00
this.draw(
[axleCounting, axleCountings[i]],
[commonElement],
2023-07-11 17:42:04 +08:00
map,
2023-07-11 15:35:35 +08:00
turoutPos
);
2023-07-10 13:37:13 +08:00
}
2023-07-07 17:15:53 +08:00
}
if (hasSamePosition(axleCounting, axleCountings[i])) {
hasfourTurnout.push([axleCounting, axleCountings[i]]);
}
}
});
2023-07-11 15:35:35 +08:00
//补4个道岔处的BB连接处的计轴区段
const fourAxleCounting: {
axleCounting: AxleCounting;
refTurout: Turnout;
}[] = [];
2023-07-07 17:15:53 +08:00
hasfourTurnout.forEach((axleCountings) => {
2023-07-10 10:04:53 +08:00
axleCountings.forEach((axleCounting) => {
//计轴关联的道岔
const axleCountingRelations =
axleCounting.relationManage.getRelationsOfGraphicAndOtherType(
axleCounting,
Turnout.Type
);
axleCountingRelations.forEach((relation) => {
const refTurnout = relation.getOtherGraphic<Turnout>(axleCounting);
//道岔关联的计轴
const turnoutRelations =
refTurnout.relationManage.getRelationsOfGraphicAndOtherType(
refTurnout,
AxleCounting.Type
);
turnoutRelations.forEach((relation) => {
const refAxleCounting =
relation.getOtherGraphic<AxleCounting>(refTurnout);
if (
refAxleCounting.id !== axleCountings[0].id &&
refAxleCounting.id !== axleCountings[1].id
) {
2023-07-11 15:35:35 +08:00
fourAxleCounting.push({
axleCounting: refAxleCounting,
refTurout: refTurnout,
});
2023-07-10 10:04:53 +08:00
}
});
});
2023-07-07 17:15:53 +08:00
});
});
2023-07-10 10:04:53 +08:00
for (let x = 0; x < fourAxleCounting.length; x += 4) {
const AxleCountings = fourAxleCounting.slice(x, x + 4);
for (let y = 0; y < 4; y++) {
2023-07-11 15:35:35 +08:00
if (
fourAxleCounting[x].axleCounting.id ==
AxleCountings[y].axleCounting.id
)
continue;
if (
fourAxleCounting[x].axleCounting.y == AxleCountings[y].axleCounting.y
) {
this.draw(
[fourAxleCounting[x].axleCounting, AxleCountings[y].axleCounting],
2023-07-11 17:42:04 +08:00
[fourAxleCounting[x].refTurout, AxleCountings[y].refTurout],
map
2023-07-11 15:35:35 +08:00
);
2023-07-10 10:04:53 +08:00
break;
}
2023-07-07 17:15:53 +08:00
}
2023-07-10 10:04:53 +08:00
for (let y = 0; y < 4; y++) {
2023-07-11 15:35:35 +08:00
if (
fourAxleCounting[x + 1].axleCounting.id ==
AxleCountings[y].axleCounting.id
)
continue;
if (
fourAxleCounting[x + 1].axleCounting.y ==
AxleCountings[y].axleCounting.y
) {
this.draw(
[
fourAxleCounting[x + 1].axleCounting,
AxleCountings[y].axleCounting,
],
2023-07-11 17:42:04 +08:00
[fourAxleCounting[x + 1].refTurout, AxleCountings[y].refTurout],
map
2023-07-11 15:35:35 +08:00
);
2023-07-10 10:04:53 +08:00
break;
}
2023-07-07 17:15:53 +08:00
}
2023-07-10 10:04:53 +08:00
}
2023-07-12 18:42:52 +08:00
//补删除计轴后的区段
const axleCountingAll = this.app.queryStore.queryByType<AxleCounting>(
AxleCounting.Type
);
const deleteRefTurout: string[] = [];
const redawAxleCounting: AxleCounting[] = [];
axleCountingAll.forEach((axleCounting) => {
const axleCountingRelations =
axleCounting.relationManage.getRelationsOfGraphicAndOtherType(
axleCounting,
AxleCountingSection.Type
);
if (
axleCounting.datas.axleCountingRef.length == 2 &&
axleCountingRelations.length < 2
) {
axleCounting.datas.axleCountingRef.forEach((ref) => {
if (ref.deviceType == 1) {
redawAxleCounting.push(axleCounting);
}
if (ref.deviceType == 1 && !deleteRefTurout.includes(ref.id)) {
deleteRefTurout.push(ref.id);
}
});
}
});
deleteRefTurout.forEach((id) => {
const turout = this.app.queryStore.queryById(id);
const turoutRelations =
turout.relationManage.getRelationsOfGraphicAndOtherType(
turout,
Turnout.Type
);
const refTurout = turoutRelations[0].getOtherGraphic(turout);
const refs = refTurout.relationManage
.getRelationsOfGraphicAndOtherType(refTurout, AxleCounting.Type)
.find(
(relation) =>
relation.getRelationParam(refTurout).param !== TurnoutPort.C
);
const refAxleCountin = refs?.getOtherGraphic(refTurout) as AxleCounting;
this.draw(
[refAxleCountin, redawAxleCounting[0]],
[refTurout, turout],
map
);
this.draw(
[refAxleCountin, redawAxleCounting[1]],
[refTurout, turout],
map,
-1
);
});
2023-07-07 17:15:53 +08:00
}
}
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<AxleCountingSection> {
static Name = 'AxleCountingSection_transform';
2023-07-12 17:16:12 +08:00
constructor(app: JlDrawApp) {
2023-07-07 17:15:53 +08:00
super(AxleCountingSectionInteraction.Name, app);
}
2023-07-12 17:16:12 +08:00
static init(app: JlDrawApp) {
return new AxleCountingSectionInteraction(app);
2023-07-07 17:15:53 +08:00
}
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;
}
}