Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f2c40f2a78 | ||
|
c8eef1fb1c | ||
|
b25fee816a | ||
|
c4cb584853 | ||
|
224f8975f8 | ||
|
5488cbea12 | ||
|
bc0017057c | ||
|
8076e0bd6d | ||
|
e10f41ce32 |
@ -23,7 +23,8 @@
|
|||||||
"centrifuge": "^4.0.1",
|
"centrifuge": "^4.0.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"google-protobuf": "^3.21.2",
|
"google-protobuf": "^3.21.2",
|
||||||
"jl-graphic": "git+https://git.code.tencent.com/jl-framework/graphic-pixi.git#v0.1.3",
|
"jl-graphic": "git+https://git.code.tencent.com/jl-framework/graphic-pixi.git#v0.1.8",
|
||||||
|
"rt-graphic-component": "git+https://git.code.tencent.com/jl-framework/rt-graphic-component.git#5eecd80",
|
||||||
"js-base64": "^3.7.5",
|
"js-base64": "^3.7.5",
|
||||||
"pinia": "^2.0.11",
|
"pinia": "^2.0.11",
|
||||||
"quasar": "^2.6.0",
|
"quasar": "^2.6.0",
|
||||||
|
@ -95,9 +95,9 @@ const stationName = computed(() => {
|
|||||||
});
|
});
|
||||||
const sectionName = computed(() => {
|
const sectionName = computed(() => {
|
||||||
const platform = drawStore.selectedGraphic as Platform;
|
const platform = drawStore.selectedGraphic as Platform;
|
||||||
if (platformModel.refSectionId) {
|
if (platformModel.refSection) {
|
||||||
const refSection = platform.queryStore.queryById<Section>(
|
const refSection = platform.queryStore.queryById<Section>(
|
||||||
platformModel.refSectionId
|
platformModel.refSection
|
||||||
);
|
);
|
||||||
return refSection.datas.code;
|
return refSection.datas.code;
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,10 @@ export class PlatformData extends GraphicDataBase implements IPlatformData {
|
|||||||
set refStation(v: number) {
|
set refStation(v: number) {
|
||||||
this.data.refStation = v;
|
this.data.refStation = v;
|
||||||
}
|
}
|
||||||
get refSectionId(): number {
|
get refSection(): number {
|
||||||
return this.data.refSectionId;
|
return this.data.refSectionId;
|
||||||
}
|
}
|
||||||
set refSectionId(v: number) {
|
set refSection(v: number) {
|
||||||
this.data.refSectionId = v;
|
this.data.refSectionId = v;
|
||||||
}
|
}
|
||||||
get centralizedStation(): number {
|
get centralizedStation(): number {
|
||||||
|
@ -33,12 +33,19 @@ import { ConcentrationDividingLineDraw } from 'src/graphics/concentrationDividin
|
|||||||
import { Rect, RectTemplate } from 'src/graphics/rect/Rect';
|
import { Rect, RectTemplate } from 'src/graphics/rect/Rect';
|
||||||
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
|
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
|
||||||
import { RectData } from './graphics/RectInteraction';
|
import { RectData } from './graphics/RectInteraction';
|
||||||
import { Platform, PlatformTemplate } from 'src/graphics/platform/Platform';
|
import {
|
||||||
|
Platform,
|
||||||
|
PlatformDraw,
|
||||||
|
PlatformTemplate,
|
||||||
|
} from 'src/graphics/platform/Platform';
|
||||||
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
|
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
|
||||||
import { PlatformDraw } from 'src/graphics/platform/PlatformDrawAssistant';
|
import {
|
||||||
import { Station, StationTemplate } from 'src/graphics/station/Station';
|
Station,
|
||||||
import { StationDraw } from 'src/graphics/station/StationDrawAssistant';
|
StationDraw,
|
||||||
|
StationTemplate,
|
||||||
|
} from 'src/graphics/station/Station';
|
||||||
import { StationData, StationState } from './graphics/StationInteraction';
|
import { StationData, StationState } from './graphics/StationInteraction';
|
||||||
|
import { StyleType } from 'rt-graphic-component/components/common/common';
|
||||||
import {
|
import {
|
||||||
StationLine,
|
StationLine,
|
||||||
StationLineTemplate,
|
StationLineTemplate,
|
||||||
@ -67,8 +74,11 @@ import {
|
|||||||
} from 'src/graphics/axleCounting/AxleCounting';
|
} from 'src/graphics/axleCounting/AxleCounting';
|
||||||
import { AxleCountingDraw } from 'src/graphics/axleCounting/AxleCountingDrawAssistant';
|
import { AxleCountingDraw } from 'src/graphics/axleCounting/AxleCountingDrawAssistant';
|
||||||
import { AxleCountingData } from './graphics/AxleCountingInteraction';
|
import { AxleCountingData } from './graphics/AxleCountingInteraction';
|
||||||
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
|
import {
|
||||||
import { TurnoutDraw } from 'src/graphics/turnout/TurnoutDrawAssistant';
|
Turnout,
|
||||||
|
TurnoutTemplate,
|
||||||
|
TurnoutDraw,
|
||||||
|
} from 'src/graphics/turnout/Turnout';
|
||||||
import { TurnoutData, TurnoutStates } from './graphics/TurnoutInteraction';
|
import { TurnoutData, TurnoutStates } from './graphics/TurnoutInteraction';
|
||||||
import { RunLine, RunLineTemplate } from 'src/graphics/runLine/RunLine';
|
import { RunLine, RunLineTemplate } from 'src/graphics/runLine/RunLine';
|
||||||
import { RunLineDraw } from 'src/graphics/runLine/RunLineDrawAssistant';
|
import { RunLineDraw } from 'src/graphics/runLine/RunLineDrawAssistant';
|
||||||
@ -84,7 +94,8 @@ import { PathLineDraw } from 'src/graphics/pathLine/PathLineDrawAssistant';
|
|||||||
import { PathLineData } from './graphics/PathLineInteraction';
|
import { PathLineData } from './graphics/PathLineInteraction';
|
||||||
import { toStorageTransform } from './graphics/GraphicDataBase';
|
import { toStorageTransform } from './graphics/GraphicDataBase';
|
||||||
import { SeparatorDraw } from 'src/graphics/separator/SeparatorDrawAssistant';
|
import { SeparatorDraw } from 'src/graphics/separator/SeparatorDrawAssistant';
|
||||||
import { Separator, SeparatorTemplate } from 'src/graphics/separator/Separator';
|
import { Separator } from 'src/graphics/separator/Separator';
|
||||||
|
import { SeparatorTemplate } from 'rt-graphic-component/components/packages/Separator/Separator';
|
||||||
import { SeparatorData } from './graphics/SeparatorInteraction';
|
import { SeparatorData } from './graphics/SeparatorInteraction';
|
||||||
import { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
|
import { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
|
||||||
import {
|
import {
|
||||||
@ -188,7 +199,7 @@ function constructMenu(app: IDrawApp): (e: FederatedMouseEvent) => void {
|
|||||||
const jumpStaitonItems: MenuItemOptions[] = [];
|
const jumpStaitonItems: MenuItemOptions[] = [];
|
||||||
stations.forEach((station) => {
|
stations.forEach((station) => {
|
||||||
const item: MenuItemOptions = {
|
const item: MenuItemOptions = {
|
||||||
name: station.datas.name,
|
name: station.datas.name as string,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
app.makeGraphicCenterShow(station);
|
app.makeGraphicCenterShow(station);
|
||||||
},
|
},
|
||||||
@ -233,11 +244,21 @@ export function initDrawApp(): IDrawApp {
|
|||||||
if (draftType === 'Line') {
|
if (draftType === 'Line') {
|
||||||
new PlatformDraw(
|
new PlatformDraw(
|
||||||
app,
|
app,
|
||||||
new PlatformTemplate(new PlatformData(), new PlatformState())
|
new PlatformTemplate(
|
||||||
|
new PlatformData(),
|
||||||
|
new PlatformState(),
|
||||||
|
StyleType.TH
|
||||||
|
),
|
||||||
|
'svguse:../../drawIcon.svg#icon-platform'
|
||||||
),
|
),
|
||||||
new StationDraw(
|
new StationDraw(
|
||||||
app,
|
app,
|
||||||
new StationTemplate(new StationData(), new StationState())
|
new StationTemplate(
|
||||||
|
new StationData(),
|
||||||
|
new StationState(),
|
||||||
|
StyleType.TH
|
||||||
|
),
|
||||||
|
'svguse:../../drawIcon.svg#icon-station'
|
||||||
),
|
),
|
||||||
new SignalDraw(
|
new SignalDraw(
|
||||||
app,
|
app,
|
||||||
@ -254,7 +275,11 @@ export function initDrawApp(): IDrawApp {
|
|||||||
),
|
),
|
||||||
new TurnoutDraw(
|
new TurnoutDraw(
|
||||||
app,
|
app,
|
||||||
new TurnoutTemplate(new TurnoutData(), new TurnoutStates())
|
new TurnoutTemplate(
|
||||||
|
new TurnoutData(),
|
||||||
|
new TurnoutStates(),
|
||||||
|
StyleType.TH
|
||||||
|
)
|
||||||
),
|
),
|
||||||
new TrainWindowDraw(app, new TrainWindowTemplate(new TrainWindowData())),
|
new TrainWindowDraw(app, new TrainWindowTemplate(new TrainWindowData())),
|
||||||
new OneClickGenerateDraw(app, new OneClickGenerateTemplate()),
|
new OneClickGenerateDraw(app, new OneClickGenerateTemplate()),
|
||||||
@ -262,7 +287,12 @@ export function initDrawApp(): IDrawApp {
|
|||||||
app,
|
app,
|
||||||
new AxleCountingTemplate(new AxleCountingData())
|
new AxleCountingTemplate(new AxleCountingData())
|
||||||
),
|
),
|
||||||
new SeparatorDraw(app, new SeparatorTemplate(new SeparatorData())),
|
new SeparatorDraw(
|
||||||
|
app,
|
||||||
|
new SeparatorTemplate(new SeparatorData(), {
|
||||||
|
lineColor: '0x617799',
|
||||||
|
})
|
||||||
|
),
|
||||||
new ConcentrationDividingLineDraw(
|
new ConcentrationDividingLineDraw(
|
||||||
app,
|
app,
|
||||||
new ConcentrationDividingLineTemplate(
|
new ConcentrationDividingLineTemplate(
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
PlatformOperateInteraction,
|
PlatformOperateInteraction,
|
||||||
PlatformState,
|
PlatformState,
|
||||||
} from './graphics/PlatformInteraction';
|
} from './graphics/PlatformInteraction';
|
||||||
import { PlatformTemplate, Platform } from 'src/graphics/platform/Platform';
|
import { Platform, PlatformTemplate } from 'src/graphics/platform/Platform';
|
||||||
import {
|
import {
|
||||||
StationData,
|
StationData,
|
||||||
StationOperateInteraction,
|
StationOperateInteraction,
|
||||||
@ -58,7 +58,7 @@ import {
|
|||||||
TrainWindowTemplate,
|
TrainWindowTemplate,
|
||||||
} from 'src/graphics/trainWindow/TrainWindow';
|
} from 'src/graphics/trainWindow/TrainWindow';
|
||||||
import { TrainWindowData } from './graphics/TrainWindowInteraction';
|
import { TrainWindowData } from './graphics/TrainWindowInteraction';
|
||||||
import { SeparatorTemplate } from 'src/graphics/separator/Separator';
|
import { SeparatorTemplate } from 'rt-graphic-component/components/packages/Separator/Separator';
|
||||||
import { SeparatorData } from './graphics/SeparatorInteraction';
|
import { SeparatorData } from './graphics/SeparatorInteraction';
|
||||||
import { ContextMenu, MenuItemOptions } from 'jl-graphic';
|
import { ContextMenu, MenuItemOptions } from 'jl-graphic';
|
||||||
import {
|
import {
|
||||||
@ -73,6 +73,7 @@ import {
|
|||||||
import { Notify, QNotifyUpdateOptions } from 'quasar';
|
import { Notify, QNotifyUpdateOptions } from 'quasar';
|
||||||
import { useLineNetStore } from 'src/stores/line-net-store';
|
import { useLineNetStore } from 'src/stores/line-net-store';
|
||||||
import { alert } from 'src/protos/alertInfo';
|
import { alert } from 'src/protos/alertInfo';
|
||||||
|
import { StyleType } from 'rt-graphic-component/components/common/common';
|
||||||
|
|
||||||
let lineApp: IGraphicApp | null = null;
|
let lineApp: IGraphicApp | null = null;
|
||||||
|
|
||||||
@ -111,12 +112,14 @@ export function initLineApp(): IGraphicApp {
|
|||||||
const graphicTemplate = [
|
const graphicTemplate = [
|
||||||
new TrainTemplate(new TrainData(), new TrainState()),
|
new TrainTemplate(new TrainData(), new TrainState()),
|
||||||
new SignalTemplate(new SignalData(), new SignalState()),
|
new SignalTemplate(new SignalData(), new SignalState()),
|
||||||
new PlatformTemplate(new PlatformData(), new PlatformState()),
|
new PlatformTemplate(new PlatformData(), new PlatformState(), StyleType.TH),
|
||||||
new StationTemplate(new StationData(), new StationState()),
|
new StationTemplate(new StationData(), new StationState(), StyleType.TH),
|
||||||
new TurnoutTemplate(new TurnoutData(), new TurnoutStates()),
|
new TurnoutTemplate(new TurnoutData(), new TurnoutStates(), StyleType.TH),
|
||||||
new SectionTemplate(new SectionData()),
|
new SectionTemplate(new SectionData()),
|
||||||
new LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
|
new LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
|
||||||
new SeparatorTemplate(new SeparatorData()),
|
new SeparatorTemplate(new SeparatorData(), {
|
||||||
|
lineColor: '0x617799',
|
||||||
|
}),
|
||||||
new AxleCountingTemplate(new AxleCountingData()),
|
new AxleCountingTemplate(new AxleCountingData()),
|
||||||
new TrainWindowTemplate(new TrainWindowData()),
|
new TrainWindowTemplate(new TrainWindowData()),
|
||||||
];
|
];
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
LogicSectionData,
|
LogicSectionData,
|
||||||
LogicSectionState,
|
LogicSectionState,
|
||||||
} from './graphics/LogicSectionInteraction';
|
} from './graphics/LogicSectionInteraction';
|
||||||
import { SeparatorTemplate } from 'src/graphics/separator/Separator';
|
import { SeparatorTemplate } from 'rt-graphic-component/components/packages/Separator/Separator';
|
||||||
import { AxleCountingTemplate } from 'src/graphics/axleCounting/AxleCounting';
|
import { AxleCountingTemplate } from 'src/graphics/axleCounting/AxleCounting';
|
||||||
import { SignalData, SignalState } from './graphics/SignalInteraction';
|
import { SignalData, SignalState } from './graphics/SignalInteraction';
|
||||||
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
|
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
|
||||||
@ -32,6 +32,7 @@ import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
|
|||||||
import { useRangeConfigStore } from 'src/stores/range-config-store';
|
import { useRangeConfigStore } from 'src/stores/range-config-store';
|
||||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||||
import { toUint8Array } from 'js-base64';
|
import { toUint8Array } from 'js-base64';
|
||||||
|
import { StyleType } from 'rt-graphic-component/components/common/common';
|
||||||
|
|
||||||
let rangeConfigApp: IGraphicApp;
|
let rangeConfigApp: IGraphicApp;
|
||||||
|
|
||||||
@ -57,9 +58,9 @@ export function initRangeConfigApp(lineId: number) {
|
|||||||
});
|
});
|
||||||
const graphicTemplate = [
|
const graphicTemplate = [
|
||||||
new SignalTemplate(new SignalData(), new SignalState()),
|
new SignalTemplate(new SignalData(), new SignalState()),
|
||||||
new PlatformTemplate(new PlatformData(), new PlatformState()),
|
new PlatformTemplate(new PlatformData(), new PlatformState(), StyleType.TH),
|
||||||
new StationTemplate(new StationData(), new StationState()),
|
new StationTemplate(new StationData(), new StationState(), StyleType.TH),
|
||||||
new TurnoutTemplate(new TurnoutData(), new TurnoutStates()),
|
new TurnoutTemplate(new TurnoutData(), new TurnoutStates(), StyleType.TH),
|
||||||
new SectionTemplate(new SectionData()),
|
new SectionTemplate(new SectionData()),
|
||||||
new LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
|
new LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
|
||||||
new SeparatorTemplate(new SeparatorData()),
|
new SeparatorTemplate(new SeparatorData()),
|
||||||
|
@ -1,116 +1,9 @@
|
|||||||
import { Color, Container, Graphics } from 'pixi.js';
|
|
||||||
import {
|
import {
|
||||||
GraphicData,
|
AxleCounting,
|
||||||
GraphicRelationParam,
|
IAxleCountingData,
|
||||||
JlGraphic,
|
AxleCountingTemplate,
|
||||||
JlGraphicTemplate,
|
AxleCountingConsts,
|
||||||
VectorText,
|
} from 'rt-graphic-component/components/packages/AxleCounting/AxleCounting';
|
||||||
} from 'jl-graphic';
|
|
||||||
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
|
|
||||||
import { KilometerSystem } from '../signal/Signal';
|
|
||||||
|
|
||||||
export interface IAxleCountingData extends GraphicData {
|
export { AxleCounting, AxleCountingTemplate, AxleCountingConsts };
|
||||||
get code(): string; // 编号
|
export type { IAxleCountingData };
|
||||||
set code(v: string);
|
|
||||||
get kilometerSystem(): KilometerSystem;
|
|
||||||
set kilometerSystem(v: KilometerSystem);
|
|
||||||
get axleCountingRef(): IRelatedRefData[]; //关联的设备
|
|
||||||
set axleCountingRef(ref: IRelatedRefData[]);
|
|
||||||
clone(): IAxleCountingData;
|
|
||||||
copyFrom(data: IAxleCountingData): void;
|
|
||||||
eq(other: IAxleCountingData): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AxleCountingConsts = {
|
|
||||||
radius: 6,
|
|
||||||
borderWidth: 1,
|
|
||||||
circleColorBlue: '0x08F80D',
|
|
||||||
codeColor: '0xF48815',
|
|
||||||
codeFontSize: 22,
|
|
||||||
codeOffsetY: 30,
|
|
||||||
kilometerCodeColor: '0xFFFFFF',
|
|
||||||
kilometerCodeFontSize: 14,
|
|
||||||
kilometerCodeOffsetY: 95,
|
|
||||||
offsetSection: 50,
|
|
||||||
};
|
|
||||||
class TwoCircleGraphic extends Container {
|
|
||||||
circleA: Graphics = new Graphics();
|
|
||||||
circleB: Graphics = new Graphics();
|
|
||||||
line: Graphics = new Graphics();
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.addChild(this.circleA);
|
|
||||||
this.addChild(this.circleB);
|
|
||||||
this.addChild(this.line);
|
|
||||||
}
|
|
||||||
draw(): void {
|
|
||||||
this.drawCircle(this.circleA);
|
|
||||||
this.drawCircle(this.circleB);
|
|
||||||
this.circleA.position.set(-12, 0);
|
|
||||||
this.circleB.position.set(12, 0);
|
|
||||||
this.line.clear();
|
|
||||||
this.line.lineStyle(1, new Color(AxleCountingConsts.circleColorBlue));
|
|
||||||
this.line.moveTo(-24, 0);
|
|
||||||
this.line.lineTo(24, 0);
|
|
||||||
}
|
|
||||||
drawCircle(circle: Graphics): void {
|
|
||||||
circle.clear();
|
|
||||||
circle.lineStyle(
|
|
||||||
AxleCountingConsts.borderWidth,
|
|
||||||
new Color(AxleCountingConsts.circleColorBlue)
|
|
||||||
);
|
|
||||||
circle.beginFill(AxleCountingConsts.circleColorBlue, 1);
|
|
||||||
circle.drawCircle(0, 0, AxleCountingConsts.radius);
|
|
||||||
circle.endFill;
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.circleA.clear();
|
|
||||||
this.circleB.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export class AxleCounting extends JlGraphic {
|
|
||||||
static Type = 'AxleCounting';
|
|
||||||
twoCircle: TwoCircleGraphic = new TwoCircleGraphic();
|
|
||||||
kilometerGraph: VectorText = new VectorText(''); //公里标
|
|
||||||
direction: number;
|
|
||||||
constructor(direction: number) {
|
|
||||||
super(AxleCounting.Type);
|
|
||||||
this.addChild(this.twoCircle);
|
|
||||||
this.addChild(this.kilometerGraph);
|
|
||||||
this.kilometerGraph.name = 'kilometer';
|
|
||||||
this.direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
get datas(): IAxleCountingData {
|
|
||||||
return this.getDatas<IAxleCountingData>();
|
|
||||||
}
|
|
||||||
doRepaint(): void {
|
|
||||||
this.twoCircle.draw();
|
|
||||||
}
|
|
||||||
loadRelations(): void {
|
|
||||||
if (this.datas.axleCountingRef.length) {
|
|
||||||
this.datas.axleCountingRef.forEach((device) => {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(this, 'A'),
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this.queryStore.queryById(device.id),
|
|
||||||
protoPort2Data(device.devicePort)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AxleCountingTemplate extends JlGraphicTemplate<AxleCounting> {
|
|
||||||
constructor(dataTemplate: IAxleCountingData) {
|
|
||||||
super(AxleCounting.Type, {
|
|
||||||
dataTemplate,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
new(): AxleCounting {
|
|
||||||
const axleCounting = new AxleCounting(1);
|
|
||||||
axleCounting.loadData(this.datas);
|
|
||||||
return axleCounting;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -112,14 +112,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
|
|||||||
const refData2 = createRelatedRefProto(graphic.type, graphic.id, port);
|
const refData2 = createRelatedRefProto(graphic.type, graphic.id, port);
|
||||||
const axleCounting = new AxleCounting(direction);
|
const axleCounting = new AxleCounting(direction);
|
||||||
axleCounting.loadData(this.graphicTemplate.datas);
|
axleCounting.loadData(this.graphicTemplate.datas);
|
||||||
if (graphic.type == 'Turnout') {
|
axleCounting.position.set(ps.x, ps.y);
|
||||||
axleCounting.position.set(ps.x, ps.y);
|
|
||||||
} else {
|
|
||||||
axleCounting.position.set(
|
|
||||||
ps.x,
|
|
||||||
ps.y - AxleCountingConsts.offsetSection * direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
axleCounting.id = GraphicIdGenerator.next();
|
axleCounting.id = GraphicIdGenerator.next();
|
||||||
axleCounting.datas.axleCountingRef = [refData2, refData1];
|
axleCounting.datas.axleCountingRef = [refData2, refData1];
|
||||||
axleCounting.datas.code = `${graphic.datas.code}-${port}+${refGraphic.datas.code}-${refPort}`;
|
axleCounting.datas.code = `${graphic.datas.code}-${port}+${refGraphic.datas.code}-${refPort}`;
|
||||||
@ -139,14 +132,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
|
|||||||
const refData = createRelatedRefProto(graphic.type, graphic.id, port);
|
const refData = createRelatedRefProto(graphic.type, graphic.id, port);
|
||||||
const axleCounting = new AxleCounting(direction);
|
const axleCounting = new AxleCounting(direction);
|
||||||
axleCounting.loadData(this.graphicTemplate.datas);
|
axleCounting.loadData(this.graphicTemplate.datas);
|
||||||
if (graphic.type == 'Turnout') {
|
axleCounting.position.set(ps.x, ps.y);
|
||||||
axleCounting.position.set(ps.x, ps.y);
|
|
||||||
} else {
|
|
||||||
axleCounting.position.set(
|
|
||||||
ps.x,
|
|
||||||
ps.y - AxleCountingConsts.offsetSection * direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
axleCounting.id = GraphicIdGenerator.next();
|
axleCounting.id = GraphicIdGenerator.next();
|
||||||
axleCounting.datas.axleCountingRef = [refData];
|
axleCounting.datas.axleCountingRef = [refData];
|
||||||
axleCounting.datas.code = `${graphic.datas.code}-${port}`;
|
axleCounting.datas.code = `${graphic.datas.code}-${port}`;
|
||||||
@ -362,21 +348,12 @@ export class AxleCountingInteraction extends GraphicInteractionPlugin<AxleCounti
|
|||||||
g.cursor = 'pointer';
|
g.cursor = 'pointer';
|
||||||
g.scalable = true;
|
g.scalable = true;
|
||||||
g.rotatable = true;
|
g.rotatable = true;
|
||||||
g.kilometerGraph.eventMode = 'static';
|
|
||||||
g.kilometerGraph.cursor = 'pointer';
|
|
||||||
g.kilometerGraph.draggable = true;
|
|
||||||
g.kilometerGraph.selectable = true;
|
|
||||||
g.kilometerGraph.transformSave = true;
|
|
||||||
g.on('selected', this.onSelected, this);
|
g.on('selected', this.onSelected, this);
|
||||||
}
|
}
|
||||||
unbind(g: AxleCounting): void {
|
unbind(g: AxleCounting): void {
|
||||||
g.eventMode = 'none';
|
g.eventMode = 'none';
|
||||||
g.scalable = false;
|
g.scalable = false;
|
||||||
g.rotatable = false;
|
g.rotatable = false;
|
||||||
g.kilometerGraph.eventMode = 'none';
|
|
||||||
g.kilometerGraph.draggable = false;
|
|
||||||
g.kilometerGraph.selectable = false;
|
|
||||||
g.kilometerGraph.transformSave = false;
|
|
||||||
g.off('selected', this.onSelected, this);
|
g.off('selected', this.onSelected, this);
|
||||||
}
|
}
|
||||||
onSelected(): void {
|
onSelected(): void {
|
||||||
|
@ -1,487 +1,8 @@
|
|||||||
import { Color, Container, Graphics, Point, Rectangle } from 'pixi.js';
|
import { THPlatform as Platform } from 'rt-graphic-component/components/packages/Platform/THPlatform';
|
||||||
import {
|
import { IPlatformData } from 'rt-graphic-component/components/packages/Platform/common/PlatformConfig';
|
||||||
GraphicData,
|
import { PlatformTemplate } from 'rt-graphic-component/components/packages/Platform/common/PlatformTemplate';
|
||||||
GraphicState,
|
import { ITHPlatformState as IPlatformState } from 'rt-graphic-component/components/packages/Platform/THPlatform';
|
||||||
JlGraphic,
|
import { PlatformDraw } from 'rt-graphic-component/components/packages/Platform/common/PlatformDrawAssistant';
|
||||||
JlGraphicTemplate,
|
|
||||||
VectorText,
|
|
||||||
calculateMirrorPoint,
|
|
||||||
distance2,
|
|
||||||
getRectangleCenter,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
import { Station } from '../station/Station';
|
|
||||||
import { Section } from '../section/Section';
|
|
||||||
|
|
||||||
export interface IPlatformData extends GraphicData {
|
export { Platform, PlatformTemplate, PlatformDraw };
|
||||||
get code(): string; // 编号
|
export type { IPlatformState, IPlatformData };
|
||||||
set code(v: string);
|
|
||||||
get hasdoor(): boolean; // 是否有屏蔽门
|
|
||||||
set hasdoor(v: boolean);
|
|
||||||
get direction(): string; // 屏蔽门上下
|
|
||||||
set direction(v: string);
|
|
||||||
get up(): boolean; // 站台上下行
|
|
||||||
set up(v: boolean);
|
|
||||||
get refStation(): number; // 关联的车站
|
|
||||||
set refStation(v: number);
|
|
||||||
get refSectionId(): number; // 关联的物理区段
|
|
||||||
set refSectionId(v: number);
|
|
||||||
get centralizedStation(): number; //所属集中站
|
|
||||||
set centralizedStation(v: number);
|
|
||||||
clone(): IPlatformData;
|
|
||||||
copyFrom(data: IPlatformData): void;
|
|
||||||
eq(other: IPlatformData): boolean;
|
|
||||||
}
|
|
||||||
export interface IPlatformState extends GraphicState {
|
|
||||||
get emergstop(): boolean; //紧急关闭
|
|
||||||
set emergstop(v: boolean);
|
|
||||||
get trainberth(): boolean; //列车停站
|
|
||||||
set trainberth(v: boolean);
|
|
||||||
get close(): boolean; //站台关闭,清客
|
|
||||||
set close(v: boolean);
|
|
||||||
get upHold(): boolean; //上行方向车站扣车
|
|
||||||
set upHold(v: boolean);
|
|
||||||
get downHold(): boolean; //下行方向车站扣车
|
|
||||||
set downHold(v: boolean);
|
|
||||||
get upOccHold(): boolean; //上行方向中心扣车
|
|
||||||
set upOccHold(v: boolean);
|
|
||||||
get downOccHold(): boolean; //下行方向中心扣车
|
|
||||||
set downOccHold(v: boolean);
|
|
||||||
get psdOpen(): boolean; //屏蔽门开
|
|
||||||
set psdOpen(v: boolean);
|
|
||||||
get psdCut(): boolean; //屏蔽门切除
|
|
||||||
set psdCut(v: boolean);
|
|
||||||
get upSkipstop(): boolean; //上行方向跳停
|
|
||||||
set upSkipstop(v: boolean);
|
|
||||||
get downSkipstop(): boolean; //下行方向跳停
|
|
||||||
set downSkipstop(v: boolean);
|
|
||||||
get upTrainSkipstop(): boolean; //上行方向指定列车跳停
|
|
||||||
set upTrainSkipstop(v: boolean);
|
|
||||||
get downTrainSkipstop(): boolean; //下行方向指定列车跳停
|
|
||||||
set downTrainSkipstop(v: boolean);
|
|
||||||
get nextSectionRunTime(): number; //下一区间运行时间
|
|
||||||
set nextSectionRunTime(v: number);
|
|
||||||
get nextSectionRunLevel(): number; //下一区间运行等级
|
|
||||||
set nextSectionRunLevel(v: number);
|
|
||||||
get stopTime(): number; //停站时间
|
|
||||||
set stopTime(v: number);
|
|
||||||
get rtuId(): number; // 集中站站号
|
|
||||||
set rtuId(v: number);
|
|
||||||
}
|
|
||||||
|
|
||||||
//站台颜色
|
|
||||||
export enum PlatformColorEnum {
|
|
||||||
grey = '0x7F7F7F', //站台没有列车停站
|
|
||||||
yellow = '0xfbff00', //列车在站台停站
|
|
||||||
blue = '0xC0C0FE', //列车在站台跳停
|
|
||||||
lozengeRed = '0xff0000', //站台旁的菱形图标
|
|
||||||
whiteNumbers = '0xffffff', //站台旁白色数字
|
|
||||||
whiteCircle = '0xffffff', //H字符旁的圆圈
|
|
||||||
HCharYellow = '0xfbff00', //站台旁的H字符
|
|
||||||
HCharWhite = '0xffffff',
|
|
||||||
HCharRed = '0xff0000',
|
|
||||||
doorGreen = '0x00FF00', //屏蔽门的颜色
|
|
||||||
doorRed = '0xff0000',
|
|
||||||
doorBlue = '0x4048C4',
|
|
||||||
blueShowColor = '0x3149c3',
|
|
||||||
}
|
|
||||||
|
|
||||||
const platformConsts = {
|
|
||||||
width: 90,
|
|
||||||
height: 20,
|
|
||||||
lineWidth: 3,
|
|
||||||
besideFontSize: 12,
|
|
||||||
doorOpenSpacing: 15,
|
|
||||||
doorPlatformSpacing: 10,
|
|
||||||
besideSpacing: 10,
|
|
||||||
circleRadius: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
//子元素--矩形
|
|
||||||
export class rectGraphic extends Container {
|
|
||||||
static Type = 'RectPlatForm';
|
|
||||||
rectGraphic: Graphics;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.rectGraphic = new Graphics();
|
|
||||||
this.addChild(this.rectGraphic);
|
|
||||||
}
|
|
||||||
draw(state: IPlatformState): void {
|
|
||||||
const rectGraphic = this.rectGraphic;
|
|
||||||
rectGraphic.clear();
|
|
||||||
let fillColor = PlatformColorEnum.grey;
|
|
||||||
if (state.trainberth) {
|
|
||||||
fillColor = PlatformColorEnum.yellow;
|
|
||||||
}
|
|
||||||
if (state.upSkipstop || state.downSkipstop) {
|
|
||||||
fillColor = PlatformColorEnum.blue;
|
|
||||||
}
|
|
||||||
rectGraphic.lineStyle(platformConsts.lineWidth, new Color(fillColor));
|
|
||||||
rectGraphic.beginFill(fillColor, 1);
|
|
||||||
rectGraphic.drawRect(0, 0, platformConsts.width, platformConsts.height);
|
|
||||||
rectGraphic.endFill;
|
|
||||||
const rectP = new Rectangle(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
platformConsts.width,
|
|
||||||
platformConsts.height
|
|
||||||
);
|
|
||||||
rectGraphic.pivot = getRectangleCenter(rectP);
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.rectGraphic.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//子元素--门
|
|
||||||
export class doorGraphic extends Container {
|
|
||||||
static Type = 'Door';
|
|
||||||
doorGraphic: Graphics;
|
|
||||||
doorCloseGraphic: Graphics;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.doorGraphic = new Graphics();
|
|
||||||
this.doorCloseGraphic = new Graphics();
|
|
||||||
this.addChild(this.doorGraphic);
|
|
||||||
this.addChild(this.doorCloseGraphic);
|
|
||||||
}
|
|
||||||
draw(stateData: IPlatformState, ipRtuStusDown: boolean): void {
|
|
||||||
const doorGraphic = this.doorGraphic;
|
|
||||||
const doorCloseGraphic = this.doorCloseGraphic;
|
|
||||||
doorGraphic.clear();
|
|
||||||
doorCloseGraphic.clear();
|
|
||||||
let lineColor = PlatformColorEnum.doorGreen;
|
|
||||||
if (ipRtuStusDown) {
|
|
||||||
lineColor = PlatformColorEnum.blueShowColor;
|
|
||||||
} else if (stateData.psdCut) {
|
|
||||||
lineColor = PlatformColorEnum.doorRed;
|
|
||||||
}
|
|
||||||
doorGraphic.lineStyle(platformConsts.lineWidth, new Color(lineColor));
|
|
||||||
doorGraphic.moveTo(
|
|
||||||
-platformConsts.width / 2 - platformConsts.lineWidth / 2,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
doorGraphic.lineTo(-platformConsts.doorOpenSpacing, 0);
|
|
||||||
doorGraphic.moveTo(platformConsts.doorOpenSpacing, 0);
|
|
||||||
doorGraphic.lineTo(
|
|
||||||
platformConsts.width / 2 + platformConsts.lineWidth / 2,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
//屏蔽门闭合
|
|
||||||
doorCloseGraphic.lineStyle(platformConsts.lineWidth, new Color(lineColor));
|
|
||||||
doorCloseGraphic.moveTo(-platformConsts.doorOpenSpacing, 0);
|
|
||||||
doorCloseGraphic.lineTo(platformConsts.doorOpenSpacing, 0);
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.doorGraphic.clear();
|
|
||||||
this.doorCloseGraphic.clear();
|
|
||||||
}
|
|
||||||
changeState(stateData: IPlatformState): void {
|
|
||||||
if (stateData.psdOpen) {
|
|
||||||
this.doorCloseGraphic.visible = false;
|
|
||||||
} else {
|
|
||||||
this.doorCloseGraphic.visible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//子元素--字符
|
|
||||||
class codeGraph extends Container {
|
|
||||||
static Type = 'Code';
|
|
||||||
character: VectorText = new VectorText(''); //扣车H
|
|
||||||
runLevel: VectorText = new VectorText(''); //运行等级
|
|
||||||
runTime: VectorText = new VectorText(''); //运行时间
|
|
||||||
stopTime: VectorText = new VectorText(''); //停站时间
|
|
||||||
circle: Graphics = new Graphics();
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.addChild(this.character);
|
|
||||||
this.addChild(this.runLevel);
|
|
||||||
this.addChild(this.circle);
|
|
||||||
this.addChild(this.stopTime);
|
|
||||||
this.addChild(this.runTime);
|
|
||||||
this.character.setVectorFontSize(platformConsts.besideFontSize);
|
|
||||||
this.runLevel.setVectorFontSize(platformConsts.besideFontSize);
|
|
||||||
this.stopTime.setVectorFontSize(platformConsts.besideFontSize);
|
|
||||||
this.runTime.setVectorFontSize(platformConsts.besideFontSize);
|
|
||||||
}
|
|
||||||
draw(): void {
|
|
||||||
//扣车
|
|
||||||
const character = this.character;
|
|
||||||
character.text = 'H';
|
|
||||||
character.anchor.set(0.5);
|
|
||||||
character.position.set(
|
|
||||||
-platformConsts.width / 2 -
|
|
||||||
platformConsts.lineWidth / 2 -
|
|
||||||
(platformConsts.besideSpacing * 2) / 3,
|
|
||||||
(platformConsts.height * 3) / 4
|
|
||||||
);
|
|
||||||
character.style.fill = PlatformColorEnum.whiteNumbers;
|
|
||||||
const circle = this.circle;
|
|
||||||
circle.clear();
|
|
||||||
circle.lineStyle(0.5, PlatformColorEnum.whiteCircle);
|
|
||||||
circle.drawCircle(0, 0, platformConsts.circleRadius);
|
|
||||||
circle.position.set(
|
|
||||||
-platformConsts.width / 2 -
|
|
||||||
platformConsts.lineWidth / 2 -
|
|
||||||
(platformConsts.besideSpacing * 4) / 3,
|
|
||||||
(platformConsts.height * 3) / 5
|
|
||||||
);
|
|
||||||
//区间运行等级状态
|
|
||||||
const runLevel = this.runLevel;
|
|
||||||
runLevel.anchor.set(0.5);
|
|
||||||
runLevel.position.set(
|
|
||||||
platformConsts.width / 2 +
|
|
||||||
platformConsts.lineWidth / 2 +
|
|
||||||
3 * platformConsts.besideSpacing,
|
|
||||||
-platformConsts.besideSpacing
|
|
||||||
);
|
|
||||||
runLevel.style.fill = PlatformColorEnum.whiteNumbers;
|
|
||||||
//区间运行时间
|
|
||||||
const runTime = this.runTime;
|
|
||||||
runTime.anchor.set(0.5);
|
|
||||||
runTime.position.set(
|
|
||||||
platformConsts.width / 2 +
|
|
||||||
platformConsts.lineWidth / 2 +
|
|
||||||
platformConsts.besideSpacing,
|
|
||||||
-platformConsts.besideSpacing
|
|
||||||
);
|
|
||||||
runTime.style.fill = PlatformColorEnum.whiteNumbers;
|
|
||||||
//停站时间
|
|
||||||
const stopTime = this.stopTime;
|
|
||||||
stopTime.anchor.set(0.5);
|
|
||||||
stopTime.position.set(
|
|
||||||
platformConsts.width / 2 +
|
|
||||||
platformConsts.lineWidth / 2 +
|
|
||||||
platformConsts.besideSpacing,
|
|
||||||
platformConsts.besideSpacing
|
|
||||||
);
|
|
||||||
stopTime.style.fill = PlatformColorEnum.whiteNumbers;
|
|
||||||
character.visible = false;
|
|
||||||
circle.visible = false;
|
|
||||||
runLevel.visible = false;
|
|
||||||
stopTime.visible = false;
|
|
||||||
runTime.visible = false;
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.character.destroy();
|
|
||||||
}
|
|
||||||
changeState(stateData: IPlatformState): void {
|
|
||||||
if (
|
|
||||||
stateData.upHold ||
|
|
||||||
stateData.upOccHold ||
|
|
||||||
stateData.downHold ||
|
|
||||||
stateData.downOccHold
|
|
||||||
) {
|
|
||||||
this.character.text = 'H';
|
|
||||||
this.character.visible = true;
|
|
||||||
this.circle.visible = true;
|
|
||||||
//上行扣车
|
|
||||||
if (stateData.upHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharYellow;
|
|
||||||
}
|
|
||||||
if (stateData.upOccHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharWhite;
|
|
||||||
}
|
|
||||||
if (stateData.upHold && stateData.upOccHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharRed;
|
|
||||||
}
|
|
||||||
//下行扣车
|
|
||||||
if (stateData.downHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharYellow;
|
|
||||||
}
|
|
||||||
if (stateData.downOccHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharWhite;
|
|
||||||
}
|
|
||||||
if (stateData.downHold && stateData.downOccHold) {
|
|
||||||
this.character.style.fill = PlatformColorEnum.HCharRed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//运行等级
|
|
||||||
if (stateData.nextSectionRunLevel) {
|
|
||||||
this.runLevel.visible = false;
|
|
||||||
this.runLevel.text = stateData.nextSectionRunLevel;
|
|
||||||
}
|
|
||||||
//运行时间
|
|
||||||
if (stateData.nextSectionRunTime) {
|
|
||||||
this.runTime.visible = true;
|
|
||||||
this.runTime.text = stateData.nextSectionRunTime;
|
|
||||||
}
|
|
||||||
//停站时间
|
|
||||||
if (stateData.stopTime) {
|
|
||||||
this.stopTime.visible = true;
|
|
||||||
this.stopTime.text = stateData.stopTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//子元素--站台旁菱形图标
|
|
||||||
class besideGraphic extends Container {
|
|
||||||
static Type = 'BesideGraphic';
|
|
||||||
besideGraphic: Graphics;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.besideGraphic = new Graphics();
|
|
||||||
this.addChild(this.besideGraphic);
|
|
||||||
}
|
|
||||||
draw(): void {
|
|
||||||
const besideGraphic = this.besideGraphic;
|
|
||||||
besideGraphic.clear();
|
|
||||||
besideGraphic.lineStyle(1, new Color(PlatformColorEnum.lozengeRed));
|
|
||||||
besideGraphic.beginFill(PlatformColorEnum.lozengeRed, 1);
|
|
||||||
besideGraphic.drawRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
platformConsts.height / 4,
|
|
||||||
platformConsts.height / 4
|
|
||||||
);
|
|
||||||
besideGraphic.endFill();
|
|
||||||
const rect = new Rectangle(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
platformConsts.height / 4,
|
|
||||||
platformConsts.height / 4
|
|
||||||
);
|
|
||||||
besideGraphic.pivot = getRectangleCenter(rect);
|
|
||||||
besideGraphic.rotation = Math.PI / 4;
|
|
||||||
besideGraphic.visible = false;
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.besideGraphic.clear();
|
|
||||||
}
|
|
||||||
changeState(stateData: IPlatformState): void {
|
|
||||||
if (stateData.emergstop) {
|
|
||||||
this.besideGraphic.visible = true;
|
|
||||||
} else {
|
|
||||||
this.besideGraphic.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Platform extends JlGraphic {
|
|
||||||
static Type = 'Platform';
|
|
||||||
platformGraphic: rectGraphic = new rectGraphic();
|
|
||||||
doorGraphic: doorGraphic = new doorGraphic();
|
|
||||||
besideGraphic: besideGraphic = new besideGraphic();
|
|
||||||
codeGraph: codeGraph = new codeGraph();
|
|
||||||
constructor() {
|
|
||||||
super(Platform.Type);
|
|
||||||
this.addChild(this.platformGraphic);
|
|
||||||
this.addChild(this.doorGraphic);
|
|
||||||
this.addChild(this.besideGraphic);
|
|
||||||
this.addChild(this.codeGraph);
|
|
||||||
}
|
|
||||||
|
|
||||||
get datas(): IPlatformData {
|
|
||||||
return this.getDatas<IPlatformData>();
|
|
||||||
}
|
|
||||||
get states(): IPlatformState {
|
|
||||||
return this.getStates<IPlatformState>();
|
|
||||||
}
|
|
||||||
get code(): string {
|
|
||||||
return this.datas.code;
|
|
||||||
}
|
|
||||||
doRepaint(): void {
|
|
||||||
const station = this.getGraphicApp().queryStore.queryByCodeAndType<Station>(
|
|
||||||
this.states.rtuId > 9 ? '' + this.states.rtuId : '0' + this.states.rtuId,
|
|
||||||
Station.Type
|
|
||||||
);
|
|
||||||
this.doorGraphic.clear();
|
|
||||||
if (this.datas.hasdoor) {
|
|
||||||
this.doorGraphic.draw(this.states, !!station?.states.ipRtuStusDown);
|
|
||||||
}
|
|
||||||
this.platformGraphic.draw(this.states);
|
|
||||||
this.besideGraphic.draw();
|
|
||||||
this.codeGraph.draw();
|
|
||||||
|
|
||||||
this.doorGraphic.position.set(
|
|
||||||
0,
|
|
||||||
-platformConsts.height / 2 - platformConsts.doorPlatformSpacing
|
|
||||||
);
|
|
||||||
this.besideGraphic.position.set(
|
|
||||||
0,
|
|
||||||
-platformConsts.height / 2 -
|
|
||||||
platformConsts.doorPlatformSpacing -
|
|
||||||
platformConsts.height / 3
|
|
||||||
);
|
|
||||||
this.codeGraph.position.set(0, 0);
|
|
||||||
//站台方向
|
|
||||||
if (this.datas.direction == 'down') {
|
|
||||||
const psChange = [
|
|
||||||
this.doorGraphic,
|
|
||||||
this.besideGraphic,
|
|
||||||
this.codeGraph.children[0],
|
|
||||||
this.codeGraph.children[1],
|
|
||||||
this.codeGraph.children[3],
|
|
||||||
this.codeGraph.children[4],
|
|
||||||
];
|
|
||||||
psChange.forEach((g) => {
|
|
||||||
g.position.copyFrom(calculateMirrorPoint(new Point(0, 0), g.position));
|
|
||||||
});
|
|
||||||
this.codeGraph.children[2].position.set(
|
|
||||||
platformConsts.width / 2 +
|
|
||||||
platformConsts.lineWidth / 2 +
|
|
||||||
(platformConsts.besideSpacing * 4) / 3,
|
|
||||||
(-platformConsts.height * 10) / 11
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (station?.states.ipRtuStusDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.changeState();
|
|
||||||
}
|
|
||||||
changeState(): void {
|
|
||||||
this.doorGraphic.changeState(this.states);
|
|
||||||
this.besideGraphic.changeState(this.states);
|
|
||||||
this.codeGraph.changeState(this.states);
|
|
||||||
}
|
|
||||||
buildRelation() {
|
|
||||||
const stationas = this.queryStore.queryByType<Station>(Station.Type);
|
|
||||||
for (let i = 0; i < stationas.length; i++) {
|
|
||||||
const sP = stationas[i].localBoundsToCanvasPoints();
|
|
||||||
if (this.x > sP[0].x && this.x < sP[1].x) {
|
|
||||||
this.datas.refStation = stationas[i].id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const sections = this.queryStore.queryByType<Section>(Section.Type);
|
|
||||||
const minDistanceRefSections: Section[] = [];
|
|
||||||
sections.forEach((section) => {
|
|
||||||
const sP = section.localBoundsToCanvasPoints();
|
|
||||||
if (this.x > sP[0].x && this.x < sP[1].x) {
|
|
||||||
minDistanceRefSections.push(section);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (minDistanceRefSections) {
|
|
||||||
const refSection = minDistanceRefSections.reduce((prev, cur) => {
|
|
||||||
return distance2(
|
|
||||||
prev.localToCanvasPoint(getRectangleCenter(prev.getLocalBounds())),
|
|
||||||
this.position
|
|
||||||
) >
|
|
||||||
distance2(
|
|
||||||
cur.localToCanvasPoint(getRectangleCenter(cur.getLocalBounds())),
|
|
||||||
this.position
|
|
||||||
)
|
|
||||||
? cur
|
|
||||||
: prev;
|
|
||||||
});
|
|
||||||
this.datas.refSectionId = refSection.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PlatformTemplate extends JlGraphicTemplate<Platform> {
|
|
||||||
hasdoor: boolean;
|
|
||||||
direction: string;
|
|
||||||
constructor(dataTemplate: IPlatformData, stateTemplate: IPlatformState) {
|
|
||||||
super(Platform.Type, {
|
|
||||||
dataTemplate,
|
|
||||||
stateTemplate,
|
|
||||||
});
|
|
||||||
this.hasdoor = true;
|
|
||||||
this.direction = 'up';
|
|
||||||
}
|
|
||||||
new(): Platform {
|
|
||||||
const platform = new Platform();
|
|
||||||
platform.loadData(this.datas);
|
|
||||||
platform.loadState(this.states);
|
|
||||||
return platform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
import { FederatedPointerEvent, Point } from 'pixi.js';
|
|
||||||
import {
|
|
||||||
AbsorbableLine,
|
|
||||||
AbsorbablePosition,
|
|
||||||
GraphicDrawAssistant,
|
|
||||||
GraphicInteractionPlugin,
|
|
||||||
IDrawApp,
|
|
||||||
JlGraphic,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
|
|
||||||
import { IPlatformData, Platform, PlatformTemplate } from './Platform';
|
|
||||||
|
|
||||||
export interface IPlatformDrawOptions {
|
|
||||||
newData: () => IPlatformData;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PlatformDraw extends GraphicDrawAssistant<
|
|
||||||
PlatformTemplate,
|
|
||||||
IPlatformData
|
|
||||||
> {
|
|
||||||
platformGraphic: Platform;
|
|
||||||
constructor(app: IDrawApp, template: PlatformTemplate) {
|
|
||||||
super(
|
|
||||||
app,
|
|
||||||
template,
|
|
||||||
'svguse:../../drawIcon.svg#icon-platform',
|
|
||||||
'站台Platform'
|
|
||||||
);
|
|
||||||
this.platformGraphic = this.graphicTemplate.new();
|
|
||||||
this.container.addChild(this.platformGraphic);
|
|
||||||
platformInteraction.init(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
bind(): void {
|
|
||||||
super.bind();
|
|
||||||
this.platformGraphic.loadData(this.graphicTemplate.datas);
|
|
||||||
this.platformGraphic.doRepaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearCache(): void {
|
|
||||||
//this.platformGraphic.clear();
|
|
||||||
}
|
|
||||||
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: IPlatformData): boolean {
|
|
||||||
const template = this.graphicTemplate;
|
|
||||||
data.hasdoor = template.hasdoor;
|
|
||||||
data.direction = template.direction;
|
|
||||||
data.transform = this.container.saveTransform();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAbsorbablePositions(platform: Platform): AbsorbablePosition[] {
|
|
||||||
const aps: AbsorbablePosition[] = [];
|
|
||||||
const platforms = platform.queryStore.queryByType<Platform>(Platform.Type);
|
|
||||||
const { width, height } = platform.getGraphicApp().canvas;
|
|
||||||
platforms.forEach((other) => {
|
|
||||||
if (other.id == platform.id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ps = other.datas.transform.position;
|
|
||||||
const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y });
|
|
||||||
const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height });
|
|
||||||
aps.push(xs, ys);
|
|
||||||
});
|
|
||||||
return aps;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class platformInteraction extends GraphicInteractionPlugin<Platform> {
|
|
||||||
static Name = 'platform_transform';
|
|
||||||
constructor(app: IDrawApp) {
|
|
||||||
super(platformInteraction.Name, app);
|
|
||||||
}
|
|
||||||
static init(app: IDrawApp) {
|
|
||||||
return new platformInteraction(app);
|
|
||||||
}
|
|
||||||
filter(...grahpics: JlGraphic[]): Platform[] | undefined {
|
|
||||||
return grahpics
|
|
||||||
.filter((g) => g.type === Platform.Type)
|
|
||||||
.map((g) => g as Platform);
|
|
||||||
}
|
|
||||||
bind(g: Platform): void {
|
|
||||||
g.eventMode = 'static';
|
|
||||||
g.cursor = 'pointer';
|
|
||||||
g.scalable = true;
|
|
||||||
g.rotatable = true;
|
|
||||||
g.on('selected', this.onSelected, this);
|
|
||||||
}
|
|
||||||
unbind(g: Platform): void {
|
|
||||||
g.eventMode = 'none';
|
|
||||||
g.scalable = false;
|
|
||||||
g.rotatable = false;
|
|
||||||
g.off('selected', this.onSelected, this);
|
|
||||||
}
|
|
||||||
onSelected(): void {
|
|
||||||
const platform = this.app.selectedGraphics[0] as Platform;
|
|
||||||
this.app.setOptions({
|
|
||||||
absorbablePositions: buildAbsorbablePositions(platform),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -244,25 +244,18 @@ export class SectionGraphicHitArea implements IHitArea {
|
|||||||
function buildAbsorbablePositions(section: Section): AbsorbablePosition[] {
|
function buildAbsorbablePositions(section: Section): AbsorbablePosition[] {
|
||||||
const aps: AbsorbablePosition[] = [];
|
const aps: AbsorbablePosition[] = [];
|
||||||
|
|
||||||
const [ps, pe] = [
|
const sections = section.queryStore.queryByType<Section>(Section.Type);
|
||||||
section.localToCanvasPoint(section.getStartPoint()),
|
sections.forEach((other) => {
|
||||||
section.localToCanvasPoint(section.getEndPoint()),
|
const [ps, pe] = [
|
||||||
];
|
other.localToCanvasPoint(other.getStartPoint()),
|
||||||
const { width, height } = section.getGraphicApp().canvas;
|
other.localToCanvasPoint(other.getEndPoint()),
|
||||||
const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y });
|
];
|
||||||
const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height });
|
const { width, height } = section.getGraphicApp().canvas;
|
||||||
const xe = new AbsorbableLine({ x: 0, y: pe.y }, { x: width, y: pe.y });
|
const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y });
|
||||||
const ye = new AbsorbableLine({ x: pe.x, y: 0 }, { x: pe.x, y: height });
|
const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height });
|
||||||
aps.push(xs, ys, xe, ye);
|
const xe = new AbsorbableLine({ x: 0, y: pe.y }, { x: width, y: pe.y });
|
||||||
const sections = section.queryStore
|
const ye = new AbsorbableLine({ x: pe.x, y: 0 }, { x: pe.x, y: height });
|
||||||
.queryByType<Section>(Section.Type)
|
aps.push(xs, ys, xe, ye);
|
||||||
.filter((g) => g.datas.sectionType == SectionType.Physical);
|
|
||||||
sections.forEach((item) => {
|
|
||||||
if (item.id !== section.id) {
|
|
||||||
item.localToCanvasPoints(...item.datas.points).forEach((p) => {
|
|
||||||
aps.push(new AbsorbablePoint(p));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const turnouts = section.queryStore.queryByType<Turnout>(Turnout.Type);
|
const turnouts = section.queryStore.queryByType<Turnout>(Turnout.Type);
|
||||||
|
@ -1,94 +1,8 @@
|
|||||||
import { Color, Graphics } from 'pixi.js';
|
import { Separator } from 'rt-graphic-component/components/packages/Separator/Separator';
|
||||||
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'jl-graphic';
|
import {
|
||||||
|
ISeparatorData,
|
||||||
|
separatorTypeEnum,
|
||||||
|
} from 'rt-graphic-component/components/packages/Separator/SeparatorConfig';
|
||||||
|
|
||||||
export interface ISeparatorData extends GraphicData {
|
export { Separator, separatorTypeEnum };
|
||||||
get code(): string; // 编号
|
export type { ISeparatorData };
|
||||||
set code(v: string);
|
|
||||||
get separatorType(): string; // 类型
|
|
||||||
set separatorType(v: string);
|
|
||||||
clone(): ISeparatorData;
|
|
||||||
copyFrom(data: ISeparatorData): void;
|
|
||||||
eq(other: ISeparatorData): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum separatorTypeEnum {
|
|
||||||
turnout = 'turnout', // 道岔分隔符
|
|
||||||
endA = 'endA', // A端尽头分隔符
|
|
||||||
endB = 'endB', // B端尽头分隔符
|
|
||||||
section = 'section', // 区段分隔符
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SeparatorConsts = {
|
|
||||||
height: 12,
|
|
||||||
lineWidth: 2,
|
|
||||||
lineColor: '0x617799',
|
|
||||||
circleColor: '0xEF0200',
|
|
||||||
radius: 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class Separator extends JlGraphic {
|
|
||||||
static Type = 'Separator';
|
|
||||||
rectGraphic: Graphics = new Graphics();
|
|
||||||
circleGraphic: Graphics = new Graphics();
|
|
||||||
constructor() {
|
|
||||||
super(Separator.Type);
|
|
||||||
this.addChild(this.rectGraphic);
|
|
||||||
this.addChild(this.circleGraphic);
|
|
||||||
}
|
|
||||||
get datas(): ISeparatorData {
|
|
||||||
return this.getDatas<ISeparatorData>();
|
|
||||||
}
|
|
||||||
clear() {
|
|
||||||
this.rectGraphic.clear();
|
|
||||||
this.circleGraphic.clear();
|
|
||||||
}
|
|
||||||
doRepaint(): void {
|
|
||||||
this.clear();
|
|
||||||
const rectGraphic = this.rectGraphic;
|
|
||||||
if (!this.datas.separatorType) {
|
|
||||||
this.datas.separatorType = separatorTypeEnum.endA;
|
|
||||||
}
|
|
||||||
const typeArr = ['section', 'turnout'];
|
|
||||||
if (typeArr.includes(this.datas.separatorType)) {
|
|
||||||
rectGraphic.lineStyle(
|
|
||||||
SeparatorConsts.lineWidth,
|
|
||||||
new Color(SeparatorConsts.lineColor)
|
|
||||||
);
|
|
||||||
rectGraphic.moveTo(0, -SeparatorConsts.height / 2);
|
|
||||||
rectGraphic.lineTo(0, SeparatorConsts.height / 2);
|
|
||||||
if (this.datas.separatorType == 'turnout') {
|
|
||||||
this.circleGraphic.lineStyle(1, SeparatorConsts.circleColor);
|
|
||||||
this.circleGraphic.drawCircle(0, 0, SeparatorConsts.radius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const endTypeArr = ['endA', 'endB'];
|
|
||||||
if (endTypeArr.includes(this.datas.separatorType)) {
|
|
||||||
let d = SeparatorConsts.radius;
|
|
||||||
if (this.datas.separatorType == 'endB') {
|
|
||||||
d = -d;
|
|
||||||
}
|
|
||||||
rectGraphic.lineStyle(
|
|
||||||
SeparatorConsts.lineWidth,
|
|
||||||
new Color(SeparatorConsts.lineColor)
|
|
||||||
);
|
|
||||||
rectGraphic.moveTo(0, 0);
|
|
||||||
rectGraphic.lineTo(-d, 0);
|
|
||||||
rectGraphic.lineTo(-d, -d);
|
|
||||||
rectGraphic.lineTo(-d * 3, -d);
|
|
||||||
rectGraphic.moveTo(-d, 0);
|
|
||||||
rectGraphic.lineTo(-d, d);
|
|
||||||
rectGraphic.lineTo(-d * 3, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SeparatorTemplate extends JlGraphicTemplate<Separator> {
|
|
||||||
constructor(dataTemplate: ISeparatorData) {
|
|
||||||
super(Separator.Type, {
|
|
||||||
dataTemplate,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
new(): Separator {
|
|
||||||
return new Separator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,56 +1,18 @@
|
|||||||
import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
|
import { Point } from 'pixi.js';
|
||||||
import {
|
import { GraphicIdGenerator, GraphicRelationParam, IDrawApp } from 'jl-graphic';
|
||||||
GraphicDrawAssistant,
|
|
||||||
GraphicIdGenerator,
|
|
||||||
GraphicInteractionPlugin,
|
|
||||||
GraphicRelationParam,
|
|
||||||
IDrawApp,
|
|
||||||
JlGraphic,
|
|
||||||
linePoint,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
import { Section, SectionType } from '../section/Section';
|
import { Section, SectionType } from '../section/Section';
|
||||||
import {
|
import { Separator, separatorTypeEnum } from './Separator';
|
||||||
ISeparatorData,
|
|
||||||
Separator,
|
|
||||||
SeparatorConsts,
|
|
||||||
SeparatorTemplate,
|
|
||||||
separatorTypeEnum,
|
|
||||||
} from './Separator';
|
|
||||||
import { SeparatorData } from 'src/drawApp/graphics/SeparatorInteraction';
|
import { SeparatorData } from 'src/drawApp/graphics/SeparatorInteraction';
|
||||||
import { Turnout } from '../turnout/Turnout';
|
import { Turnout } from '../turnout/Turnout';
|
||||||
import { LogicSection } from '../logicSection/LogicSection';
|
import { LogicSection } from '../logicSection/LogicSection';
|
||||||
|
import { SeparatorTemplate } from 'rt-graphic-component/components/packages/Separator/Separator';
|
||||||
|
import { SeparatorDraw as XaSeparatorDraw } from 'rt-graphic-component/components/packages/Separator/SeparatorDrawAssistant';
|
||||||
|
|
||||||
export class SeparatorDraw extends GraphicDrawAssistant<
|
export class SeparatorDraw extends XaSeparatorDraw {
|
||||||
SeparatorTemplate,
|
|
||||||
ISeparatorData
|
|
||||||
> {
|
|
||||||
SeparatorGraph: Separator;
|
|
||||||
constructor(app: IDrawApp, template: SeparatorTemplate) {
|
constructor(app: IDrawApp, template: SeparatorTemplate) {
|
||||||
super(app, template, 'sym_o_square', '分隔符Separator');
|
super(app, template);
|
||||||
this.SeparatorGraph = this.graphicTemplate.new();
|
|
||||||
this.container.addChild(this.SeparatorGraph);
|
|
||||||
SeparatorInteraction.init(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(): void {
|
|
||||||
super.bind();
|
|
||||||
this.SeparatorGraph.loadData(this.graphicTemplate.datas);
|
|
||||||
this.SeparatorGraph.doRepaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
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: ISeparatorData): boolean {
|
|
||||||
data.transform = this.container.saveTransform();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
oneGenerates() {
|
oneGenerates() {
|
||||||
const SeparatorAll = this.app.queryStore.queryByType<Separator>(
|
const SeparatorAll = this.app.queryStore.queryByType<Separator>(
|
||||||
Separator.Type
|
Separator.Type
|
||||||
@ -76,7 +38,7 @@ export class SeparatorDraw extends GraphicDrawAssistant<
|
|||||||
allR.forEach((relation, index) => {
|
allR.forEach((relation, index) => {
|
||||||
const r = relation.getRelationParam(section);
|
const r = relation.getRelationParam(section);
|
||||||
const other = relation.getOtherRelationParam(section);
|
const other = relation.getOtherRelationParam(section);
|
||||||
if (!section.datas.children.includes(other.g.id + '')) {
|
if (!section.datas.children.includes(other.g.id)) {
|
||||||
// 排除物理区段和自身逻辑区段的关联关系
|
// 排除物理区段和自身逻辑区段的关联关系
|
||||||
port.push(r.param);
|
port.push(r.param);
|
||||||
}
|
}
|
||||||
@ -216,69 +178,3 @@ export class SeparatorDraw extends GraphicDrawAssistant<
|
|||||||
this.storeGraphic(separator);
|
this.storeGraphic(separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//碰撞检测
|
|
||||||
export class SeparatorGraphicHitArea implements IHitArea {
|
|
||||||
separator: Separator;
|
|
||||||
constructor(separator: Separator) {
|
|
||||||
this.separator = separator;
|
|
||||||
}
|
|
||||||
contains(x: number, y: number): boolean {
|
|
||||||
let contains = false;
|
|
||||||
const p = new Point(x, y);
|
|
||||||
const typeArr = ['section', 'turnout'];
|
|
||||||
const endTypeArr = ['endA', 'endB'];
|
|
||||||
let d = SeparatorConsts.radius;
|
|
||||||
if (typeArr.includes(this.separator.datas.separatorType)) {
|
|
||||||
const tolerance = SeparatorConsts.lineWidth;
|
|
||||||
const p1 = new Point(0, -SeparatorConsts.height / 2);
|
|
||||||
const p2 = new Point(0, SeparatorConsts.height / 2);
|
|
||||||
contains = contains || linePoint(p1, p2, p, tolerance);
|
|
||||||
return contains;
|
|
||||||
} else if (endTypeArr.includes(this.separator.datas.separatorType)) {
|
|
||||||
if (this.separator.datas.separatorType == 'endB') {
|
|
||||||
d = -d;
|
|
||||||
}
|
|
||||||
const tolerance = SeparatorConsts.lineWidth;
|
|
||||||
const p1 = new Point(0, 0);
|
|
||||||
const p2 = new Point(-d, 0);
|
|
||||||
const p3 = new Point(-d, -d);
|
|
||||||
const p4 = new Point(-d * 3, -d);
|
|
||||||
const p5 = new Point(-d, d);
|
|
||||||
const p6 = new Point(-d * 3, d);
|
|
||||||
contains = contains || linePoint(p1, p2, p, tolerance);
|
|
||||||
contains = contains || linePoint(p2, p3, p, tolerance);
|
|
||||||
contains = contains || linePoint(p3, p4, p, tolerance);
|
|
||||||
contains = contains || linePoint(p2, p5, p, tolerance);
|
|
||||||
contains = contains || linePoint(p5, p6, p, tolerance);
|
|
||||||
}
|
|
||||||
return contains;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SeparatorInteraction extends GraphicInteractionPlugin<Separator> {
|
|
||||||
static Name = 'Separator_transform';
|
|
||||||
constructor(app: IDrawApp) {
|
|
||||||
super(SeparatorInteraction.Name, app);
|
|
||||||
}
|
|
||||||
static init(app: IDrawApp) {
|
|
||||||
return new SeparatorInteraction(app);
|
|
||||||
}
|
|
||||||
filter(...grahpics: JlGraphic[]): Separator[] | undefined {
|
|
||||||
return grahpics
|
|
||||||
.filter((g) => g.type === Separator.Type)
|
|
||||||
.map((g) => g as Separator);
|
|
||||||
}
|
|
||||||
bind(g: Separator): void {
|
|
||||||
g.eventMode = 'static';
|
|
||||||
g.cursor = 'pointer';
|
|
||||||
g.scalable = true;
|
|
||||||
g.rotatable = true;
|
|
||||||
g.rectGraphic.hitArea = new SeparatorGraphicHitArea(g);
|
|
||||||
}
|
|
||||||
unbind(g: Separator): void {
|
|
||||||
g.eventMode = 'none';
|
|
||||||
g.scalable = false;
|
|
||||||
g.rotatable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
101
src/graphics/signal/Lamp.ts
Normal file
101
src/graphics/signal/Lamp.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { Container } from '@pixi/display';
|
||||||
|
import { Graphics } from 'pixi.js';
|
||||||
|
|
||||||
|
const lampConsts = {
|
||||||
|
lampRadius: 8,
|
||||||
|
logicModeLineWidth: 2,
|
||||||
|
logicModeDistance: 5,
|
||||||
|
logicModeColor: '0x000000',
|
||||||
|
lampLineWidth: 1,
|
||||||
|
lampLineColor: '0x3149c3',
|
||||||
|
lampBadColor: '0xFF0000',
|
||||||
|
badStart: 10,
|
||||||
|
badEnd: 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Lamp extends Container {
|
||||||
|
circleLamp: Graphics = new Graphics();
|
||||||
|
logicMode: Graphics = new Graphics();
|
||||||
|
lampBad: Graphics = new Graphics();
|
||||||
|
radiusX = 0;
|
||||||
|
radiusY = 0;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.addChild(this.circleLamp);
|
||||||
|
this.addChild(this.logicMode);
|
||||||
|
this.addChild(this.lampBad);
|
||||||
|
}
|
||||||
|
paint(radiusX: number, radiusY: number) {
|
||||||
|
this.radiusX = radiusX;
|
||||||
|
this.radiusY = radiusY;
|
||||||
|
this.createLamp();
|
||||||
|
}
|
||||||
|
createLampBad() {
|
||||||
|
this.lampBad.clear();
|
||||||
|
this.lampBad.lineStyle(lampConsts.lampLineWidth, lampConsts.lampBadColor);
|
||||||
|
this.lampBad.moveTo(this.radiusX + lampConsts.badStart, this.radiusY);
|
||||||
|
this.lampBad.lineTo(this.radiusX + lampConsts.badEnd, this.radiusY);
|
||||||
|
this.lampBad.moveTo(this.radiusX - lampConsts.badStart, this.radiusY);
|
||||||
|
this.lampBad.lineTo(this.radiusX - lampConsts.badEnd, this.radiusY);
|
||||||
|
this.lampBad.moveTo(this.radiusX, this.radiusY + lampConsts.badStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX, this.radiusY + lampConsts.badEnd);
|
||||||
|
this.lampBad.moveTo(this.radiusX, this.radiusY - lampConsts.badStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX, this.radiusY - lampConsts.badEnd);
|
||||||
|
const xieStart = Math.sin(Math.PI / 4) * lampConsts.badStart;
|
||||||
|
const xieEnd = Math.sin(Math.PI / 4) * lampConsts.badEnd;
|
||||||
|
this.lampBad.moveTo(this.radiusX + xieStart, this.radiusY + xieStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX + xieEnd, this.radiusY + xieEnd);
|
||||||
|
this.lampBad.moveTo(this.radiusX + xieStart, this.radiusY - xieStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX + xieEnd, this.radiusY - xieEnd);
|
||||||
|
|
||||||
|
this.lampBad.moveTo(this.radiusX - xieStart, this.radiusY - xieStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX - xieEnd, this.radiusY - xieEnd);
|
||||||
|
this.lampBad.moveTo(this.radiusX - xieStart, this.radiusY + xieStart);
|
||||||
|
this.lampBad.lineTo(this.radiusX - xieEnd, this.radiusY + xieEnd);
|
||||||
|
}
|
||||||
|
createLamp(color?: string) {
|
||||||
|
this.circleLamp.clear();
|
||||||
|
this.circleLamp.lineStyle(
|
||||||
|
lampConsts.lampLineWidth,
|
||||||
|
lampConsts.lampLineColor
|
||||||
|
);
|
||||||
|
if (!color) {
|
||||||
|
color = '0X' + this.getCanvas().backgroundColor.substring(1);
|
||||||
|
}
|
||||||
|
this.circleLamp.beginFill(color, 1);
|
||||||
|
this.circleLamp.drawCircle(
|
||||||
|
this.radiusX,
|
||||||
|
this.radiusY,
|
||||||
|
lampConsts.lampRadius
|
||||||
|
);
|
||||||
|
this.circleLamp.endFill();
|
||||||
|
}
|
||||||
|
createLogicMode() {
|
||||||
|
this.logicMode
|
||||||
|
.clear()
|
||||||
|
.lineStyle(lampConsts.logicModeLineWidth, lampConsts.logicModeColor)
|
||||||
|
.moveTo(
|
||||||
|
this.radiusX - lampConsts.logicModeDistance,
|
||||||
|
this.radiusY + lampConsts.logicModeDistance
|
||||||
|
)
|
||||||
|
.lineTo(
|
||||||
|
this.radiusX + lampConsts.logicModeDistance,
|
||||||
|
this.radiusY - lampConsts.logicModeDistance
|
||||||
|
)
|
||||||
|
.moveTo(
|
||||||
|
this.radiusX - lampConsts.logicModeDistance,
|
||||||
|
this.radiusY - lampConsts.logicModeDistance
|
||||||
|
)
|
||||||
|
.lineTo(
|
||||||
|
this.radiusX + lampConsts.logicModeDistance,
|
||||||
|
this.radiusY + lampConsts.logicModeDistance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
logicModeClear() {
|
||||||
|
this.logicMode.clear();
|
||||||
|
}
|
||||||
|
lampClear() {
|
||||||
|
this.circleLamp.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { Graphics, Point } from 'pixi.js';
|
import { Graphics, Point } from 'pixi.js';
|
||||||
import { calculateMirrorPoint, GraphicAnimation, JlGraphic } from 'jl-graphic';
|
import { calculateMirrorPoint, GraphicAnimation, JlGraphic } from 'jl-graphic';
|
||||||
|
import { Lamp } from './Lamp';
|
||||||
import { ISignalState } from './Signal';
|
import { ISignalState } from './Signal';
|
||||||
|
|
||||||
export enum LampEnum {
|
export enum LampEnum {
|
||||||
@ -9,7 +10,6 @@ export enum LampEnum {
|
|||||||
yellowLamp = '0XFFFF00',
|
yellowLamp = '0XFFFF00',
|
||||||
whiteLamp = '0XFFFFFF',
|
whiteLamp = '0XFFFFFF',
|
||||||
blueLamp = '0x3149c3',
|
blueLamp = '0x3149c3',
|
||||||
closeLamp = '0x000000',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const lampConsts = {
|
const lampConsts = {
|
||||||
@ -17,14 +17,6 @@ const lampConsts = {
|
|||||||
levelLampPostLength: 4,
|
levelLampPostLength: 4,
|
||||||
postLineWidth: 3,
|
postLineWidth: 3,
|
||||||
lampRadius: 8,
|
lampRadius: 8,
|
||||||
logicModeLineWidth: 2,
|
|
||||||
logicModeDistance: 5,
|
|
||||||
logicModeColor: '0x000000',
|
|
||||||
lampLineWidth: 1,
|
|
||||||
lampLineColor: '0x3149c3',
|
|
||||||
lampBadColor: '0xFF0000',
|
|
||||||
badStart: 10,
|
|
||||||
badEnd: 15,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const anmiationNameConst = {
|
const anmiationNameConst = {
|
||||||
@ -39,31 +31,23 @@ export class LampMainBody extends JlGraphic {
|
|||||||
static Type = 'LampMainBody';
|
static Type = 'LampMainBody';
|
||||||
lampNum = 1;
|
lampNum = 1;
|
||||||
lampPost: Graphics = new Graphics();
|
lampPost: Graphics = new Graphics();
|
||||||
// lamps: Lamp[] = [];
|
lamps: Lamp[] = [];
|
||||||
lamps: Graphics = new Graphics();
|
|
||||||
logicMode: Graphics = new Graphics();
|
|
||||||
mirror = false;
|
mirror = false;
|
||||||
deltaTime = 0;
|
deltaTime = 0;
|
||||||
states: ISignalState | null = null;
|
states: ISignalState | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(LampMainBody.Type);
|
super(LampMainBody.Type);
|
||||||
this.addChild(this.lampPost);
|
|
||||||
this.addChild(this.lamps);
|
|
||||||
this.addChild(this.logicMode);
|
|
||||||
}
|
}
|
||||||
paint(lampNum: number, mirror: boolean, states: ISignalState) {
|
paint(lampNum: number, mirror: boolean, states: ISignalState) {
|
||||||
this.lampPost.clear();
|
|
||||||
|
|
||||||
this.logicMode.clear();
|
|
||||||
this.mirror = mirror;
|
this.mirror = mirror;
|
||||||
this.states = states;
|
this.states = states;
|
||||||
if (lampNum < 1) {
|
if (lampNum < 1) {
|
||||||
throw new Error('信号机灯数量异常');
|
throw new Error('信号机灯数量异常');
|
||||||
}
|
}
|
||||||
this.lampNum = lampNum;
|
this.lampNum = lampNum;
|
||||||
// this.removeChildren(0);
|
this.removeChildren(0);
|
||||||
// this.lampPost = new Graphics();
|
this.lampPost = new Graphics();
|
||||||
let lpp = new Point(lampConsts.levelLampPostLength, 0);
|
let lpp = new Point(lampConsts.levelLampPostLength, 0);
|
||||||
if (mirror) {
|
if (mirror) {
|
||||||
lpp = calculateMirrorPoint(new Point(0, 0), lpp);
|
lpp = calculateMirrorPoint(new Point(0, 0), lpp);
|
||||||
@ -74,81 +58,39 @@ export class LampMainBody extends JlGraphic {
|
|||||||
.lineTo(0, lampConsts.verticalLampPostLength / 2)
|
.lineTo(0, lampConsts.verticalLampPostLength / 2)
|
||||||
.moveTo(0, 0)
|
.moveTo(0, 0)
|
||||||
.lineTo(lpp.x, lpp.y);
|
.lineTo(lpp.x, lpp.y);
|
||||||
// this.addChild(this.lampPost);
|
this.addChild(this.lampPost);
|
||||||
|
|
||||||
// this.lamps = [];
|
this.lamps = [];
|
||||||
// for (let i = 0; i < this.lampNum; i++) {
|
for (let i = 0; i < this.lampNum; i++) {
|
||||||
// const lamp = new Lamp();
|
const lamp = new Lamp();
|
||||||
// // this.addChild(lamp);
|
this.addChild(lamp);
|
||||||
// const radiusX =
|
|
||||||
// (1 + i * 2) * lampConsts.lampRadius + lampConsts.levelLampPostLength;
|
|
||||||
// let lrp = new Point(radiusX, 0);
|
|
||||||
// if (mirror) {
|
|
||||||
// lrp = calculateMirrorPoint(new Point(0, 0), lrp);
|
|
||||||
// }
|
|
||||||
// lamp.paint(lrp.x, lrp.y);
|
|
||||||
// // this.lamps.push(lamp);
|
|
||||||
// }
|
|
||||||
this.chagneState(this.states);
|
|
||||||
}
|
|
||||||
paintLamp(colors: string[], lampNum?: number) {
|
|
||||||
this.lamps.clear();
|
|
||||||
this.lamps.lineStyle(
|
|
||||||
lampConsts.lampLineWidth,
|
|
||||||
lampConsts.lampLineColor
|
|
||||||
);
|
|
||||||
const number = lampNum || this.lampNum
|
|
||||||
for (let i = 0; i < number; i++) {
|
|
||||||
const radiusX =
|
const radiusX =
|
||||||
(1 + i * 2) * lampConsts.lampRadius +
|
(1 + i * 2) * lampConsts.lampRadius + lampConsts.levelLampPostLength;
|
||||||
lampConsts.levelLampPostLength;
|
|
||||||
let lrp = new Point(radiusX, 0);
|
let lrp = new Point(radiusX, 0);
|
||||||
if (this.mirror) {
|
if (mirror) {
|
||||||
lrp = calculateMirrorPoint(new Point(0, 0), lrp);
|
lrp = calculateMirrorPoint(new Point(0, 0), lrp);
|
||||||
}
|
}
|
||||||
const color = colors[i] ? colors[i] : LampEnum.closeLamp;
|
lamp.paint(lrp.x, lrp.y);
|
||||||
this.lamps.beginFill(color, 1);
|
this.lamps.push(lamp);
|
||||||
this.lamps.drawCircle(
|
|
||||||
lrp.x,
|
|
||||||
lrp.y,
|
|
||||||
lampConsts.lampRadius
|
|
||||||
);
|
|
||||||
this.lamps.endFill();
|
|
||||||
if (this.states?.extinguish) {
|
|
||||||
this.logicMode
|
|
||||||
.lineStyle(lampConsts.logicModeLineWidth, lampConsts.logicModeColor)
|
|
||||||
.moveTo(
|
|
||||||
lrp.x - lampConsts.logicModeDistance,
|
|
||||||
lrp.y + lampConsts.logicModeDistance
|
|
||||||
)
|
|
||||||
.lineTo(
|
|
||||||
lrp.x + lampConsts.logicModeDistance,
|
|
||||||
lrp.y - lampConsts.logicModeDistance
|
|
||||||
)
|
|
||||||
.moveTo(
|
|
||||||
lrp.x - lampConsts.logicModeDistance,
|
|
||||||
lrp.y - lampConsts.logicModeDistance
|
|
||||||
)
|
|
||||||
.lineTo(
|
|
||||||
lrp.x + lampConsts.logicModeDistance,
|
|
||||||
lrp.y + lampConsts.logicModeDistance
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this.chagneState(this.states);
|
||||||
}
|
}
|
||||||
setBlueShow() {
|
setBlueShow() {
|
||||||
this.stopAnmiation();
|
this.stopAnmiation();
|
||||||
this.paintLamp([LampEnum.blueLamp, LampEnum.blueLamp, LampEnum.blueLamp]);
|
this.lamps.forEach((lamp) => {
|
||||||
|
lamp.createLamp(LampEnum.blueLamp);
|
||||||
|
lamp.logicModeClear();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
doRepaint() {
|
doRepaint() {
|
||||||
// this.paint(this.lampNum, this.mirror, this.states);
|
// this.paint(this.lampNum, this.mirror, this.states);
|
||||||
}
|
}
|
||||||
stopAnmiation() {
|
stopAnmiation() {
|
||||||
const redFlashA = this.animation(anmiationNameConst.signaRedFlash + this.states?.code);
|
const redFlashA = this.animation(anmiationNameConst.signaRedFlash);
|
||||||
const greenFlashA = this.animation(anmiationNameConst.signalGreenFlash + this.states?.code);
|
const greenFlashA = this.animation(anmiationNameConst.signalGreenFlash);
|
||||||
const blueFlashA = this.animation(anmiationNameConst.signalBlueFlash + this.states?.code);
|
const blueFlashA = this.animation(anmiationNameConst.signalBlueFlash);
|
||||||
const yellowFlashA = this.animation(anmiationNameConst.signalYellowFlash + this.states?.code);
|
const yellowFlashA = this.animation(anmiationNameConst.signalYellowFlash);
|
||||||
const whiteFlashA = this.animation(anmiationNameConst.signalWhiteFlash + this.states?.code);
|
const whiteFlashA = this.animation(anmiationNameConst.signalWhiteFlash);
|
||||||
if (redFlashA) {
|
if (redFlashA) {
|
||||||
redFlashA.pause();
|
redFlashA.pause();
|
||||||
}
|
}
|
||||||
@ -167,13 +109,18 @@ export class LampMainBody extends JlGraphic {
|
|||||||
}
|
}
|
||||||
chagneState(states: ISignalState) {
|
chagneState(states: ISignalState) {
|
||||||
this.stopAnmiation();
|
this.stopAnmiation();
|
||||||
|
if (states.extinguish) {
|
||||||
|
this.lamps.forEach((lamp) => lamp.createLogicMode());
|
||||||
|
} else {
|
||||||
|
this.lamps.forEach((lamp) => lamp.logicModeClear());
|
||||||
|
}
|
||||||
if (states.redOpen) {
|
if (states.redOpen) {
|
||||||
this.paintLamp([LampEnum.redLamp]);
|
this.lamps[0].createLamp(LampEnum.redLamp);
|
||||||
} else if (states.redFlash) {
|
} else if (states.redFlash) {
|
||||||
let redFlashA = this.animation(anmiationNameConst.signaRedFlash + states.code);
|
let redFlashA = this.animation(anmiationNameConst.signaRedFlash);
|
||||||
if (!redFlashA) {
|
if (!redFlashA) {
|
||||||
redFlashA = this.createFlashAnmiation(
|
redFlashA = this.createFlashAnmiation(
|
||||||
anmiationNameConst.signaRedFlash + states.code,
|
anmiationNameConst.signaRedFlash,
|
||||||
LampEnum.redLamp,
|
LampEnum.redLamp,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
@ -181,12 +128,12 @@ export class LampMainBody extends JlGraphic {
|
|||||||
this.addAnimation(redFlashA);
|
this.addAnimation(redFlashA);
|
||||||
redFlashA.resume();
|
redFlashA.resume();
|
||||||
} else if (states.greenOpen) {
|
} else if (states.greenOpen) {
|
||||||
this.paintLamp([LampEnum.closeLamp, LampEnum.greenLamp]);
|
this.lamps[1].createLamp(LampEnum.greenLamp);
|
||||||
} else if (states.greenFlash) {
|
} else if (states.greenFlash) {
|
||||||
let greenFlashA = this.animation(anmiationNameConst.signalGreenFlash + states.code);
|
let greenFlashA = this.animation(anmiationNameConst.signalGreenFlash);
|
||||||
if (!greenFlashA) {
|
if (!greenFlashA) {
|
||||||
greenFlashA = this.createFlashAnmiation(
|
greenFlashA = this.createFlashAnmiation(
|
||||||
anmiationNameConst.signalGreenFlash + states.code,
|
anmiationNameConst.signalGreenFlash,
|
||||||
LampEnum.greenLamp,
|
LampEnum.greenLamp,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
@ -194,12 +141,12 @@ export class LampMainBody extends JlGraphic {
|
|||||||
this.addAnimation(greenFlashA);
|
this.addAnimation(greenFlashA);
|
||||||
greenFlashA.resume();
|
greenFlashA.resume();
|
||||||
} else if (states.yellowOpen) {
|
} else if (states.yellowOpen) {
|
||||||
this.paintLamp([LampEnum.closeLamp, LampEnum.yellowLamp]);
|
this.lamps[1].createLamp(LampEnum.yellowLamp);
|
||||||
} else if (states.yellowFlash) {
|
} else if (states.yellowFlash) {
|
||||||
let yellowFlashA = this.animation(anmiationNameConst.signalYellowFlash + states.code);
|
let yellowFlashA = this.animation(anmiationNameConst.signalYellowFlash);
|
||||||
if (!yellowFlashA) {
|
if (!yellowFlashA) {
|
||||||
yellowFlashA = this.createFlashAnmiation(
|
yellowFlashA = this.createFlashAnmiation(
|
||||||
anmiationNameConst.signalYellowFlash + states.code,
|
anmiationNameConst.signalYellowFlash,
|
||||||
LampEnum.yellowLamp,
|
LampEnum.yellowLamp,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
@ -207,12 +154,12 @@ export class LampMainBody extends JlGraphic {
|
|||||||
this.addAnimation(yellowFlashA);
|
this.addAnimation(yellowFlashA);
|
||||||
yellowFlashA.resume();
|
yellowFlashA.resume();
|
||||||
} else if (states.blueOpen) {
|
} else if (states.blueOpen) {
|
||||||
this.paintLamp([LampEnum.blueLamp, LampEnum.blueLamp, LampEnum.blueLamp]);
|
this.lamps.forEach((lamp) => lamp.createLamp(LampEnum.blueLamp));
|
||||||
} else if (states.blueFlash) {
|
} else if (states.blueFlash) {
|
||||||
let blueFlashA = this.animation(anmiationNameConst.signalBlueFlash + states.code);
|
let blueFlashA = this.animation(anmiationNameConst.signalBlueFlash);
|
||||||
if (!blueFlashA) {
|
if (!blueFlashA) {
|
||||||
blueFlashA = this.createFlashAnmiation(
|
blueFlashA = this.createFlashAnmiation(
|
||||||
anmiationNameConst.signalBlueFlash + states.code,
|
anmiationNameConst.signalBlueFlash,
|
||||||
LampEnum.blueLamp,
|
LampEnum.blueLamp,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
@ -220,12 +167,13 @@ export class LampMainBody extends JlGraphic {
|
|||||||
this.addAnimation(blueFlashA);
|
this.addAnimation(blueFlashA);
|
||||||
blueFlashA.resume();
|
blueFlashA.resume();
|
||||||
} else if (states.whiteOpen) {
|
} else if (states.whiteOpen) {
|
||||||
this.paintLamp([LampEnum.whiteLamp], 1);
|
this.lamps[0].createLamp(LampEnum.whiteLamp);
|
||||||
|
this.lamps[1].visible = false;
|
||||||
} else if (states.whiteFlash) {
|
} else if (states.whiteFlash) {
|
||||||
let whiteFlashA = this.animation(anmiationNameConst.signalWhiteFlash + states.code);
|
let whiteFlashA = this.animation(anmiationNameConst.signalWhiteFlash);
|
||||||
if (!whiteFlashA) {
|
if (!whiteFlashA) {
|
||||||
whiteFlashA = this.createFlashAnmiation(
|
whiteFlashA = this.createFlashAnmiation(
|
||||||
anmiationNameConst.signalWhiteFlash + states.code,
|
anmiationNameConst.signalWhiteFlash,
|
||||||
LampEnum.whiteLamp,
|
LampEnum.whiteLamp,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
@ -233,15 +181,16 @@ export class LampMainBody extends JlGraphic {
|
|||||||
this.addAnimation(whiteFlashA);
|
this.addAnimation(whiteFlashA);
|
||||||
whiteFlashA.resume();
|
whiteFlashA.resume();
|
||||||
} else if (states.callon) {
|
} else if (states.callon) {
|
||||||
this.paintLamp([LampEnum.redLamp, LampEnum.yellowLamp]);
|
this.lamps[0].createLamp(LampEnum.redLamp);
|
||||||
|
this.lamps[1].createLamp(LampEnum.yellowLamp);
|
||||||
} else if (states.yellowYellow) {
|
} else if (states.yellowYellow) {
|
||||||
this.paintLamp([LampEnum.yellowLamp, LampEnum.yellowLamp]);
|
this.lamps[0].createLamp(LampEnum.yellowLamp);
|
||||||
|
this.lamps[1].createLamp(LampEnum.yellowLamp);
|
||||||
} else if (states.yellowGreen) {
|
} else if (states.yellowGreen) {
|
||||||
this.paintLamp([LampEnum.yellowLamp, LampEnum.greenLamp]);
|
this.lamps[0].createLamp(LampEnum.yellowLamp);
|
||||||
|
this.lamps[1].createLamp(LampEnum.greenLamp);
|
||||||
} else if (states.lampFailure) {
|
} else if (states.lampFailure) {
|
||||||
this.paintLamp([LampEnum.redLamp]);
|
this.lamps[0].createLamp(LampEnum.redLamp);
|
||||||
} else {
|
|
||||||
this.paintLamp([]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createFlashAnmiation(
|
createFlashAnmiation(
|
||||||
@ -249,17 +198,18 @@ export class LampMainBody extends JlGraphic {
|
|||||||
color: string,
|
color: string,
|
||||||
lampIndex: number
|
lampIndex: number
|
||||||
): GraphicAnimation {
|
): GraphicAnimation {
|
||||||
|
const bgColor = '0X' + this.getCanvas().backgroundColor.substring(1);
|
||||||
const flashAnmiation = GraphicAnimation.init({
|
const flashAnmiation = GraphicAnimation.init({
|
||||||
name: name,
|
name: name,
|
||||||
run: (dt: number) => {
|
run: (dt: number) => {
|
||||||
this.deltaTime += dt;
|
this.deltaTime += dt;
|
||||||
if (this.deltaTime > 60) {
|
if (this.deltaTime > 60) {
|
||||||
const colors = ['', '', ''];
|
|
||||||
this.deltaTime = 0;
|
this.deltaTime = 0;
|
||||||
colors[lampIndex] = color;
|
this.lamps[lampIndex].createLamp(color);
|
||||||
this.paintLamp(colors);
|
|
||||||
} else if (this.deltaTime > 30) {
|
} else if (this.deltaTime > 30) {
|
||||||
this.paintLamp([]);
|
this.lamps.forEach((lamp) => {
|
||||||
|
lamp.createLamp(bgColor);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,280 +1,8 @@
|
|||||||
import { Color, Container, Graphics } from 'pixi.js';
|
import { THStation as Station } from 'rt-graphic-component/components/packages/Station/THStation';
|
||||||
import {
|
import { IStationData } from 'rt-graphic-component/components/packages/Station/common/StationConfig';
|
||||||
GraphicData,
|
import { ITHStationState as IStationState } from 'rt-graphic-component/components/packages/Station/THStation';
|
||||||
GraphicState,
|
import { StationTemplate } from 'rt-graphic-component/components/packages/Station/common/StationTemplate';
|
||||||
JlGraphic,
|
import { StationDraw } from 'rt-graphic-component/components/packages/Station/common/StationDrawAssistant';
|
||||||
JlGraphicTemplate,
|
|
||||||
VectorText,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
import { LogicSection } from '../logicSection/LogicSection';
|
|
||||||
import { Platform } from '../platform/Platform';
|
|
||||||
import { KilometerSystem, Signal } from '../signal/Signal';
|
|
||||||
import { Train } from '../train/Train';
|
|
||||||
import { Turnout } from '../turnout/Turnout';
|
|
||||||
|
|
||||||
export interface IStationData extends GraphicData {
|
export { Station, StationTemplate, StationDraw };
|
||||||
get code(): string; // 车站索引
|
export type { IStationState, IStationData };
|
||||||
set code(v: string);
|
|
||||||
get kilometerSystem(): KilometerSystem;
|
|
||||||
set kilometerSystem(v: KilometerSystem);
|
|
||||||
get hasControl(): boolean; //是否有控制
|
|
||||||
set hasControl(v: boolean);
|
|
||||||
get concentrationStations(): boolean; //是否集中站
|
|
||||||
set concentrationStations(v: boolean);
|
|
||||||
get name(): string; //车站名称
|
|
||||||
set name(v: string);
|
|
||||||
get manageStations(): number[]; //集中站管理的车站
|
|
||||||
set manageStations(v: number[]);
|
|
||||||
get depots(): boolean; //是否车辆段
|
|
||||||
set depots(v: boolean);
|
|
||||||
clone(): IStationData;
|
|
||||||
copyFrom(data: IStationData): void;
|
|
||||||
eq(other: IStationData): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStationState extends GraphicState {
|
|
||||||
get ipRtuStusDown(): boolean; //通信终端---是否允许转到中控
|
|
||||||
set ipRtuStusDown(v: boolean);
|
|
||||||
get ipRtuStusInLocalCtrl(): boolean; //站控
|
|
||||||
set ipRtuStusInLocalCtrl(v: boolean);
|
|
||||||
get ipRtuStusInCentralCtrl(): boolean; //遥控
|
|
||||||
set ipRtuStusInCentralCtrl(v: boolean);
|
|
||||||
get ipRtuStusInEmergencyCtrl(): boolean; //紧急站控
|
|
||||||
set ipRtuStusInEmergencyCtrl(v: boolean);
|
|
||||||
get rtuId(): number; // 集中站站号
|
|
||||||
set rtuId(v: number);
|
|
||||||
}
|
|
||||||
|
|
||||||
const stationConsts = {
|
|
||||||
radius: 3,
|
|
||||||
borderWidth: 1,
|
|
||||||
circleColorGrey: '0x808080',
|
|
||||||
circleColorBlue: '0x08F80D',
|
|
||||||
circleColorYellow: '0xFFFA0C',
|
|
||||||
codeColor: '0xF48815',
|
|
||||||
codeFontSize: 22,
|
|
||||||
codeControlFontSize: 12,
|
|
||||||
codeOffsetY: 30,
|
|
||||||
circleOffsetY: 20,
|
|
||||||
circleBetweenOffset: 40,
|
|
||||||
kilometerCodeColor: '0xFFFFFF',
|
|
||||||
kilometerCodeFontSize: 8,
|
|
||||||
kilometerCodeOffsetY: -25,
|
|
||||||
};
|
|
||||||
class constrolGraphic extends Container {
|
|
||||||
circleA: Graphics = new Graphics();
|
|
||||||
codeGraphA: VectorText = new VectorText(''); //控制名--站控
|
|
||||||
circleB: Graphics = new Graphics();
|
|
||||||
codeGraphB: VectorText = new VectorText(''); //控制名--中控
|
|
||||||
arrow: Graphics = new Graphics();
|
|
||||||
inArrow: Graphics = new Graphics();
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.addChild(this.circleA);
|
|
||||||
this.addChild(this.codeGraphA);
|
|
||||||
this.addChild(this.circleB);
|
|
||||||
this.addChild(this.codeGraphB);
|
|
||||||
this.addChild(this.arrow);
|
|
||||||
this.addChild(this.inArrow);
|
|
||||||
this.codeGraphA.setVectorFontSize(stationConsts.codeFontSize);
|
|
||||||
this.codeGraphB.setVectorFontSize(stationConsts.codeFontSize);
|
|
||||||
}
|
|
||||||
draw(states: IStationState): void {
|
|
||||||
let StationControlFillColor = stationConsts.circleColorGrey;
|
|
||||||
let centralControlFillColor = stationConsts.circleColorBlue;
|
|
||||||
let inArrowFillColor = stationConsts.circleColorGrey;
|
|
||||||
if (states.ipRtuStusInLocalCtrl) {
|
|
||||||
StationControlFillColor = stationConsts.circleColorYellow;
|
|
||||||
centralControlFillColor = stationConsts.circleColorGrey;
|
|
||||||
if (!states.ipRtuStusDown) {
|
|
||||||
inArrowFillColor = stationConsts.circleColorBlue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.drawCircleCode(
|
|
||||||
this.circleA,
|
|
||||||
this.codeGraphA,
|
|
||||||
'站控',
|
|
||||||
StationControlFillColor
|
|
||||||
);
|
|
||||||
this.circleA.position.set(
|
|
||||||
stationConsts.circleBetweenOffset / 2,
|
|
||||||
stationConsts.circleOffsetY
|
|
||||||
);
|
|
||||||
this.codeGraphA.position.set(
|
|
||||||
stationConsts.circleBetweenOffset / 2,
|
|
||||||
stationConsts.codeOffsetY
|
|
||||||
);
|
|
||||||
this.drawCircleCode(
|
|
||||||
this.circleB,
|
|
||||||
this.codeGraphB,
|
|
||||||
'中控',
|
|
||||||
centralControlFillColor
|
|
||||||
);
|
|
||||||
this.circleB.position.set(
|
|
||||||
-stationConsts.circleBetweenOffset / 2,
|
|
||||||
stationConsts.circleOffsetY
|
|
||||||
);
|
|
||||||
this.codeGraphB.position.set(
|
|
||||||
-stationConsts.circleBetweenOffset / 2,
|
|
||||||
stationConsts.codeOffsetY
|
|
||||||
);
|
|
||||||
const arrow = this.arrow;
|
|
||||||
arrow.clear();
|
|
||||||
arrow.lineStyle(stationConsts.borderWidth, new Color('0xFFFFFF'));
|
|
||||||
const points = [0, 0, 2, 2, 2, 1, 14, 1, 14, -1, 2, -1, 2, -2];
|
|
||||||
arrow.beginFill('0xFFFFFF');
|
|
||||||
arrow.drawPolygon(points);
|
|
||||||
arrow.endFill();
|
|
||||||
arrow.scale.set(1.1, 1.1);
|
|
||||||
arrow.position.set(-7, stationConsts.circleOffsetY);
|
|
||||||
const inArrow = this.inArrow;
|
|
||||||
inArrow.beginFill(inArrowFillColor);
|
|
||||||
inArrow.drawPolygon(points);
|
|
||||||
inArrow.endFill();
|
|
||||||
inArrow.position.set(-6.5, stationConsts.circleOffsetY);
|
|
||||||
}
|
|
||||||
drawCircleCode(
|
|
||||||
circle: Graphics,
|
|
||||||
codeGraph: VectorText,
|
|
||||||
code: string,
|
|
||||||
fillcolor: string
|
|
||||||
): void {
|
|
||||||
circle.clear();
|
|
||||||
circle.lineStyle(stationConsts.borderWidth, new Color(fillcolor));
|
|
||||||
circle.beginFill(fillcolor, 1);
|
|
||||||
circle.drawCircle(0, 0, stationConsts.radius);
|
|
||||||
circle.endFill;
|
|
||||||
codeGraph.text = code;
|
|
||||||
codeGraph.style.fill = fillcolor;
|
|
||||||
codeGraph.setVectorFontSize(stationConsts.codeControlFontSize);
|
|
||||||
codeGraph.anchor.set(0.5);
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.circleA.clear();
|
|
||||||
this.circleB.clear();
|
|
||||||
this.codeGraphA.text = '';
|
|
||||||
this.codeGraphB.text = '';
|
|
||||||
this.arrow.clear();
|
|
||||||
this.inArrow.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export class Station extends JlGraphic {
|
|
||||||
static Type = 'station';
|
|
||||||
codeGraph: VectorText = new VectorText(''); //车站名
|
|
||||||
kilometerGraph: VectorText = new VectorText(''); //公里标
|
|
||||||
controlGraphic: constrolGraphic = new constrolGraphic();
|
|
||||||
_ipRtuStusDown = false;
|
|
||||||
constructor() {
|
|
||||||
super(Station.Type);
|
|
||||||
this.addChild(this.codeGraph);
|
|
||||||
this.addChild(this.kilometerGraph);
|
|
||||||
this.addChild(this.controlGraphic);
|
|
||||||
this.kilometerGraph.name = 'kilometer';
|
|
||||||
this.controlGraphic.name = 'trainControl';
|
|
||||||
}
|
|
||||||
|
|
||||||
get datas(): IStationData {
|
|
||||||
return this.getDatas<IStationData>();
|
|
||||||
}
|
|
||||||
get states(): IStationState {
|
|
||||||
return this.getStates<IStationState>();
|
|
||||||
}
|
|
||||||
get code(): string {
|
|
||||||
return this.datas.code;
|
|
||||||
}
|
|
||||||
doRepaint(): void {
|
|
||||||
const codeGraph = this.codeGraph;
|
|
||||||
const kilometerGraph = this.kilometerGraph;
|
|
||||||
const controlGraphic = this.controlGraphic;
|
|
||||||
controlGraphic.clear();
|
|
||||||
codeGraph.text = this.datas?.code
|
|
||||||
? `${this.datas?.name}(${this.datas?.code})`
|
|
||||||
: `${this.datas?.name}`;
|
|
||||||
codeGraph.style.fill = stationConsts.codeColor;
|
|
||||||
codeGraph.setVectorFontSize(stationConsts.codeFontSize);
|
|
||||||
codeGraph.anchor.set(0.5);
|
|
||||||
const kilometerCode = this.datas.kilometerSystem?.kilometer || 12345678;
|
|
||||||
if (Math.floor(kilometerCode * 1000).toString().length > 3) {
|
|
||||||
const kiloBit = Math.floor(Number(kilometerCode) / 1000000).toString();
|
|
||||||
kilometerGraph.text =
|
|
||||||
'K' +
|
|
||||||
kiloBit +
|
|
||||||
'+' +
|
|
||||||
(
|
|
||||||
Number(kilometerCode.toString().substring(kiloBit.length)) / 1000
|
|
||||||
).toFixed(3);
|
|
||||||
} else {
|
|
||||||
kilometerGraph.text = (kilometerCode * 1000).toFixed(3);
|
|
||||||
}
|
|
||||||
kilometerGraph.style.fill = stationConsts.kilometerCodeColor;
|
|
||||||
kilometerGraph.setVectorFontSize(stationConsts.kilometerCodeFontSize);
|
|
||||||
kilometerGraph.anchor.set(0.5);
|
|
||||||
kilometerGraph.position.set(0, stationConsts.kilometerCodeOffsetY);
|
|
||||||
if (this.datas.childTransforms?.length) {
|
|
||||||
this.datas.childTransforms.forEach((child) => {
|
|
||||||
if (child.name == 'kilometer') {
|
|
||||||
const pos = child.transform.position;
|
|
||||||
kilometerGraph.position.set(pos.x, pos.y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.datas.hasControl) {
|
|
||||||
controlGraphic.draw(this.states);
|
|
||||||
}
|
|
||||||
if (this.states.ipRtuStusDown !== this._ipRtuStusDown) {
|
|
||||||
this._ipRtuStusDown = this.states.ipRtuStusDown;
|
|
||||||
this.handleBlueShow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleBlueShow() {
|
|
||||||
const signals = this.queryStore.queryByType<Signal>(Signal.Type);
|
|
||||||
const logicSections = this.queryStore.queryByType<LogicSection>(
|
|
||||||
LogicSection.Type
|
|
||||||
);
|
|
||||||
const turnouts = this.queryStore.queryByType<Turnout>(Turnout.Type);
|
|
||||||
const platfroms = this.queryStore.queryByType<Platform>(Platform.Type);
|
|
||||||
const trains = this.queryStore.queryByType<Train>(Train.Type);
|
|
||||||
signals.forEach((signal) => {
|
|
||||||
if (signal.states.rtuId === this.states.rtuId) {
|
|
||||||
signal.doRepaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
logicSections.forEach((logicSection) => {
|
|
||||||
if (logicSection.states.rtuId === this.states.rtuId) {
|
|
||||||
logicSection.doRepaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
turnouts.forEach((turnout) => {
|
|
||||||
if (turnout.states.rtuId === this.states.rtuId) {
|
|
||||||
turnout.doRepaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
platfroms.forEach((platform) => {
|
|
||||||
if (platform.states.rtuId === this.states.rtuId) {
|
|
||||||
platform.doRepaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
trains.forEach((train) => {
|
|
||||||
if (train.states.rtuId === this.states.rtuId) {
|
|
||||||
train.doRepaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class StationTemplate extends JlGraphicTemplate<Station> {
|
|
||||||
hasControl: boolean;
|
|
||||||
constructor(dataTemplate: IStationData, stateTemplate: IStationState) {
|
|
||||||
super(Station.Type, {
|
|
||||||
dataTemplate,
|
|
||||||
stateTemplate,
|
|
||||||
});
|
|
||||||
this.hasControl = true;
|
|
||||||
}
|
|
||||||
new(): Station {
|
|
||||||
const station = new Station();
|
|
||||||
station.loadData(this.datas);
|
|
||||||
station.loadState(this.states);
|
|
||||||
return station;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,123 +0,0 @@
|
|||||||
import { FederatedPointerEvent, Point } from 'pixi.js';
|
|
||||||
import {
|
|
||||||
AbsorbableLine,
|
|
||||||
AbsorbablePosition,
|
|
||||||
GraphicDrawAssistant,
|
|
||||||
GraphicInteractionPlugin,
|
|
||||||
IDrawApp,
|
|
||||||
JlGraphic,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
|
|
||||||
import { IStationData, Station, StationTemplate } from './Station';
|
|
||||||
|
|
||||||
export interface IStationDrawOptions {
|
|
||||||
newData: () => IStationData;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class StationDraw extends GraphicDrawAssistant<
|
|
||||||
StationTemplate,
|
|
||||||
IStationData
|
|
||||||
> {
|
|
||||||
codeGraph: Station;
|
|
||||||
constructor(app: IDrawApp, template: StationTemplate) {
|
|
||||||
super(
|
|
||||||
app,
|
|
||||||
template,
|
|
||||||
'svguse:../../drawIcon.svg#icon-station',
|
|
||||||
'车站Station'
|
|
||||||
);
|
|
||||||
this.codeGraph = this.graphicTemplate.new();
|
|
||||||
this.container.addChild(this.codeGraph);
|
|
||||||
stationInteraction.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: IStationData): boolean {
|
|
||||||
data.transform = this.container.saveTransform();
|
|
||||||
data.hasControl = this.graphicTemplate.hasControl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAbsorbablePositions(station: Station): AbsorbablePosition[] {
|
|
||||||
const aps: AbsorbablePosition[] = [];
|
|
||||||
const stations = station.queryStore.queryByType<Station>(Station.Type);
|
|
||||||
const { width } = station.getGraphicApp().canvas;
|
|
||||||
stations.forEach((other) => {
|
|
||||||
if (other.id == station.id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ps = other.datas.transform.position;
|
|
||||||
const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y });
|
|
||||||
aps.push(xs);
|
|
||||||
});
|
|
||||||
return aps;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class stationInteraction extends GraphicInteractionPlugin<Station> {
|
|
||||||
static Name = 'station_transform';
|
|
||||||
constructor(app: IDrawApp) {
|
|
||||||
super(stationInteraction.Name, app);
|
|
||||||
}
|
|
||||||
static init(app: IDrawApp) {
|
|
||||||
return new stationInteraction(app);
|
|
||||||
}
|
|
||||||
filter(...grahpics: JlGraphic[]): Station[] | undefined {
|
|
||||||
return grahpics
|
|
||||||
.filter((g) => g.type === Station.Type)
|
|
||||||
.map((g) => g as Station);
|
|
||||||
}
|
|
||||||
bind(g: Station): void {
|
|
||||||
g.eventMode = 'static';
|
|
||||||
g.cursor = 'pointer';
|
|
||||||
g.scalable = true;
|
|
||||||
g.rotatable = true;
|
|
||||||
g.controlGraphic.eventMode = 'static';
|
|
||||||
g.controlGraphic.cursor = 'pointer';
|
|
||||||
g.controlGraphic.draggable = true;
|
|
||||||
g.controlGraphic.selectable = true;
|
|
||||||
g.controlGraphic.transformSave = true;
|
|
||||||
g.kilometerGraph.eventMode = 'static';
|
|
||||||
g.kilometerGraph.cursor = 'pointer';
|
|
||||||
g.kilometerGraph.draggable = true;
|
|
||||||
g.kilometerGraph.selectable = true;
|
|
||||||
g.kilometerGraph.transformSave = true;
|
|
||||||
g.on('selected', this.onSelected, this);
|
|
||||||
}
|
|
||||||
unbind(g: Station): void {
|
|
||||||
g.eventMode = 'none';
|
|
||||||
g.scalable = false;
|
|
||||||
g.rotatable = false;
|
|
||||||
g.controlGraphic.eventMode = 'none';
|
|
||||||
g.controlGraphic.draggable = false;
|
|
||||||
g.controlGraphic.selectable = false;
|
|
||||||
g.controlGraphic.transformSave = false;
|
|
||||||
g.kilometerGraph.eventMode = 'none';
|
|
||||||
g.kilometerGraph.draggable = false;
|
|
||||||
g.kilometerGraph.selectable = false;
|
|
||||||
g.kilometerGraph.transformSave = false;
|
|
||||||
g.off('selected', this.onSelected, this);
|
|
||||||
}
|
|
||||||
onSelected(): void {
|
|
||||||
const station = this.app.selectedGraphics[0] as Station;
|
|
||||||
this.app.setOptions({
|
|
||||||
absorbablePositions: buildAbsorbablePositions(station),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,8 @@
|
|||||||
import { Graphics, Container, Point } from 'pixi.js';
|
|
||||||
import {
|
import {
|
||||||
GraphicData,
|
GraphicData,
|
||||||
GraphicIdGenerator,
|
GraphicIdGenerator,
|
||||||
GraphicState,
|
GraphicState,
|
||||||
JlGraphic,
|
|
||||||
JlGraphicTemplate,
|
JlGraphicTemplate,
|
||||||
VectorText,
|
|
||||||
calculateMirrorPoint,
|
|
||||||
} from 'jl-graphic';
|
} from 'jl-graphic';
|
||||||
import { train } from 'src/protos/train';
|
import { train } from 'src/protos/train';
|
||||||
import { state } from 'src/protos/device_status';
|
import { state } from 'src/protos/device_status';
|
||||||
@ -14,6 +10,13 @@ import { TrainWindow } from '../trainWindow/TrainWindow';
|
|||||||
import { LogicSection } from '../logicSection/LogicSection';
|
import { LogicSection } from '../logicSection/LogicSection';
|
||||||
import { Section } from '../section/Section';
|
import { Section } from '../section/Section';
|
||||||
import { Station } from '../station/Station';
|
import { Station } from '../station/Station';
|
||||||
|
import { Train as XaTrain } from 'rt-graphic-component/components/packages/Train/Train';
|
||||||
|
import {
|
||||||
|
EnumDiriveModel,
|
||||||
|
EnumStatusText,
|
||||||
|
EnumTrainType,
|
||||||
|
UpdateTrainConsts,
|
||||||
|
} from 'rt-graphic-component/components/packages/Train/TrainConfig';
|
||||||
|
|
||||||
export interface ITrainData extends GraphicData {
|
export interface ITrainData extends GraphicData {
|
||||||
get code(): string; // 车号
|
get code(): string; // 车号
|
||||||
@ -72,285 +75,13 @@ export interface ITrainState extends GraphicState {
|
|||||||
set record(v: train.TrainRecord);
|
set record(v: train.TrainRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface bodyWH {
|
|
||||||
width: number; // 宽
|
|
||||||
height: number; // 高
|
|
||||||
}
|
|
||||||
|
|
||||||
// 列车颜色
|
|
||||||
export enum TrainColorEnum {
|
|
||||||
headColor = '0xFFCE4D', // 箭头颜色
|
|
||||||
bodyColor = '0xA388B1', // 背景色
|
|
||||||
codeColor = '0xffffff', // 车号颜色
|
|
||||||
borderColor = '0xA3E198', // 边框的颜色
|
|
||||||
directionColor = '0x00FF00', // 方向箭头颜色
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DiriveModelColorEnum { // 驾驶模式对应颜色
|
|
||||||
AM = '0x00FF00', // ATO自动驾驶
|
|
||||||
SM = '0xFFFF00', // ATP 监控下的人工驾驶模式
|
|
||||||
RM = '0xFFC837', // 限制人工驾驶模式
|
|
||||||
NRM = '0xA0522D', // 非限制人工驾驶模式
|
|
||||||
red = '0xF80103', // 红色表示通信中断
|
|
||||||
}
|
|
||||||
enum BBBColorEnum { // 识别号颜色
|
|
||||||
accuracy = '0xffffff', // 准点
|
|
||||||
early = '0x00FF00', // 早点
|
|
||||||
late = '0xFFFF00', // 晚点
|
|
||||||
schedule = '0xffffff', // 计划车
|
|
||||||
head = '0xE9FC01', // 头码车
|
|
||||||
manual = '0xE9FC01', // 人工车
|
|
||||||
special = '0xE9FC01', // 特殊车
|
|
||||||
}
|
|
||||||
|
|
||||||
enum statusTextColor {
|
|
||||||
H = '0xFFFF00', // H扣车
|
|
||||||
S = '0x6260F3', // S跳停
|
|
||||||
D = '0x00FF00', // D开门
|
|
||||||
A = '0xFF0000', // A报警
|
|
||||||
}
|
|
||||||
|
|
||||||
const deviceTypeString = new Map();
|
const deviceTypeString = new Map();
|
||||||
deviceTypeString.set(state.DeviceType.TRACK, LogicSection.Type);
|
deviceTypeString.set(state.DeviceType.TRACK, LogicSection.Type);
|
||||||
deviceTypeString.set(state.DeviceType.SWITCH_TRACK, Section.Type);
|
deviceTypeString.set(state.DeviceType.SWITCH_TRACK, Section.Type);
|
||||||
|
|
||||||
export const trainConsts = {
|
export class Train extends XaTrain {
|
||||||
codeWidth: 120,
|
constructor(data?: UpdateTrainConsts) {
|
||||||
codeHeight: 40,
|
super(data);
|
||||||
codePadding: 5,
|
|
||||||
borderWidth: 1,
|
|
||||||
codeFontSize: 22,
|
|
||||||
textFontSize: 16, // 状态字母大小
|
|
||||||
textMarginY: 10, // 状态字母与列车距离
|
|
||||||
statusTextList: ['H', 'S', 'D', 'A'],
|
|
||||||
marginX: 4, // 图形x轴边距
|
|
||||||
pauseW: 4, // 停止框宽度
|
|
||||||
};
|
|
||||||
|
|
||||||
export class TrainHead extends Container {
|
|
||||||
arrow: Graphics; // 箭头
|
|
||||||
pause: Graphics; // 停止
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.arrow = new Graphics();
|
|
||||||
this.pause = new Graphics();
|
|
||||||
this.addChild(this.arrow);
|
|
||||||
this.addChild(this.pause);
|
|
||||||
}
|
|
||||||
clear() {
|
|
||||||
this.arrow.clear();
|
|
||||||
this.pause.clear();
|
|
||||||
}
|
|
||||||
doRepaint(states: ITrainState, bodyWH?: bodyWH) {
|
|
||||||
let direction = '';
|
|
||||||
if (states.mode?.ipModeTrainDirDown) {
|
|
||||||
direction = 'left';
|
|
||||||
}
|
|
||||||
if (states.mode?.ipModeTrainDirUp) {
|
|
||||||
direction = 'right';
|
|
||||||
}
|
|
||||||
this.clear();
|
|
||||||
if (!direction) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const marginX = trainConsts.marginX;
|
|
||||||
const pauseW = trainConsts.pauseW;
|
|
||||||
const codeWidth = bodyWH ? bodyWH.width : trainConsts.codeWidth;
|
|
||||||
const codeHeight = bodyWH ? bodyWH.height : trainConsts.codeHeight;
|
|
||||||
let arrowPoint = [
|
|
||||||
-codeHeight * 0.4 - marginX - codeWidth / 2,
|
|
||||||
0,
|
|
||||||
-marginX - codeWidth / 2,
|
|
||||||
codeHeight / 2,
|
|
||||||
-marginX - codeWidth / 2,
|
|
||||||
-codeHeight / 2,
|
|
||||||
];
|
|
||||||
let pausePoint = [
|
|
||||||
-marginX - pauseW / 2 - codeWidth / 2,
|
|
||||||
-codeHeight / 2,
|
|
||||||
-marginX - pauseW / 2 - codeWidth / 2,
|
|
||||||
codeHeight / 2,
|
|
||||||
];
|
|
||||||
if (direction != 'left') {
|
|
||||||
const aP: Array<number> = [];
|
|
||||||
arrowPoint.forEach((item, index) => {
|
|
||||||
if (index % 2 == 1) {
|
|
||||||
const p = new Point(arrowPoint[index - 1], item);
|
|
||||||
const newP = calculateMirrorPoint(new Point(0, 0), p);
|
|
||||||
aP.push(newP.x, newP.y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
arrowPoint = aP;
|
|
||||||
const pP: Array<number> = [];
|
|
||||||
pausePoint.forEach((item, index) => {
|
|
||||||
if (index % 2 == 1) {
|
|
||||||
const p = new Point(pausePoint[index - 1], item);
|
|
||||||
const newP = calculateMirrorPoint(new Point(0, 0), p);
|
|
||||||
pP.push(newP.x, newP.y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pausePoint = pP;
|
|
||||||
}
|
|
||||||
let aColor = DiriveModelColorEnum.AM;
|
|
||||||
let pColor = DiriveModelColorEnum.SM;
|
|
||||||
if (states.mode?.ipModeTrainDriveModeCm) {
|
|
||||||
aColor = DiriveModelColorEnum.SM;
|
|
||||||
pColor = DiriveModelColorEnum.SM;
|
|
||||||
} else if (
|
|
||||||
states.mode?.ipModeTrainDriveModeRmf ||
|
|
||||||
states.mode?.ipModeTrainDriveModeRmr
|
|
||||||
) {
|
|
||||||
aColor = DiriveModelColorEnum.RM;
|
|
||||||
pColor = DiriveModelColorEnum.RM;
|
|
||||||
}
|
|
||||||
if (states.mode?.ipModeTrainStoped) {
|
|
||||||
this.pause.lineStyle(pauseW, pColor, 1);
|
|
||||||
this.pause.moveTo(pausePoint[0], pausePoint[1]);
|
|
||||||
this.pause.lineTo(pausePoint[2], pausePoint[3]);
|
|
||||||
} else {
|
|
||||||
const arrow = this.arrow;
|
|
||||||
arrow.beginFill(aColor, 1);
|
|
||||||
arrow.drawPolygon(arrowPoint);
|
|
||||||
arrow.endFill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TrainBody extends Container {
|
|
||||||
// codeRact: Graphics;
|
|
||||||
codeAGraph: VectorText = new VectorText(''); //识别号AA
|
|
||||||
codeBGraph: VectorText = new VectorText(''); //识别号BBB
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
// this.codeRact = new Graphics();
|
|
||||||
// this.addChild(this.codeRact);
|
|
||||||
this.addChild(this.codeAGraph);
|
|
||||||
this.addChild(this.codeBGraph);
|
|
||||||
this.codeAGraph.setVectorFontSize(trainConsts.codeFontSize);
|
|
||||||
this.codeBGraph.setVectorFontSize(trainConsts.codeFontSize);
|
|
||||||
}
|
|
||||||
clear() {
|
|
||||||
// this.codeRact.clear();
|
|
||||||
this.codeAGraph.text = '';
|
|
||||||
this.codeBGraph.text = '';
|
|
||||||
}
|
|
||||||
getBodyWH(): bodyWH {
|
|
||||||
const bodyAWH = this.codeAGraph.localBoundsToCanvasPoints();
|
|
||||||
const bodyBWH = this.codeBGraph.localBoundsToCanvasPoints();
|
|
||||||
return {
|
|
||||||
width: bodyAWH[1].x - bodyAWH[0].x + bodyBWH[1].x - bodyBWH[0].x,
|
|
||||||
height: bodyAWH[2].y - bodyAWH[1].y,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
doRepaint(states: ITrainState): void {
|
|
||||||
this.clear();
|
|
||||||
const codeAGraph = this.codeAGraph;
|
|
||||||
const codeBGraph = this.codeBGraph;
|
|
||||||
// const codeRact = this.codeRact;
|
|
||||||
let codeA = states.trainId;
|
|
||||||
// let codeA = states?.groupId;
|
|
||||||
// const firstChar = codeA.substring(0, 1); // 获取首字符
|
|
||||||
// if (+firstChar == states.lineId) {
|
|
||||||
// codeA = codeA.substring(1); // 删除首字符是线路号的字符
|
|
||||||
// }
|
|
||||||
const fillAColor = BBBColorEnum.schedule;
|
|
||||||
let fillBColor = BBBColorEnum.schedule;
|
|
||||||
if (states.mode?.ipModeTrainTypeSchedule) {
|
|
||||||
if (states.mode?.ipModeTrainSchdLate) {
|
|
||||||
fillBColor = BBBColorEnum.late;
|
|
||||||
} else if (states.mode?.ipModeTrainSchdEarly) {
|
|
||||||
fillBColor = BBBColorEnum.early;
|
|
||||||
}
|
|
||||||
} else if (states.mode?.ipModeTrainTypeHead) {
|
|
||||||
codeA = states?.destinationId + '';
|
|
||||||
fillBColor = BBBColorEnum.head;
|
|
||||||
} else if (states.mode?.ipModeTrainTypeManual) {
|
|
||||||
codeA = 'MM';
|
|
||||||
fillBColor = BBBColorEnum.manual;
|
|
||||||
} else if (states.mode?.ipModeTrainTypeSpecial) {
|
|
||||||
codeA = '';
|
|
||||||
}
|
|
||||||
const codeB = states?.globalId;
|
|
||||||
codeAGraph.text = codeA || '01';
|
|
||||||
codeBGraph.text = codeB || '222';
|
|
||||||
codeAGraph.anchor.set(0.5);
|
|
||||||
codeBGraph.anchor.set(0.5);
|
|
||||||
const styleA = {
|
|
||||||
fill: fillAColor,
|
|
||||||
fontSize: trainConsts.codeFontSize,
|
|
||||||
};
|
|
||||||
const styleB = {
|
|
||||||
fill: fillBColor,
|
|
||||||
fontSize: trainConsts.codeFontSize,
|
|
||||||
};
|
|
||||||
codeAGraph.style = styleA;
|
|
||||||
codeBGraph.style = styleB;
|
|
||||||
const bodyAWH = codeAGraph.getLocalBounds();
|
|
||||||
const bodyBWH = codeBGraph.getLocalBounds();
|
|
||||||
codeAGraph.position.set(-bodyBWH.width / 2, 0);
|
|
||||||
codeBGraph.position.set(bodyAWH.width / 2, 0);
|
|
||||||
codeAGraph.updateOnScaled();
|
|
||||||
codeBGraph.updateOnScaled();
|
|
||||||
// const { width: codeWidth, height: codeHeight } = this.getBodyWH();
|
|
||||||
// codeRact.beginFill(new Color(TrainColorEnum.bodyColor));
|
|
||||||
// codeRact.drawRect(-codeWidth / 2, -codeHeight / 2, codeWidth, codeHeight);
|
|
||||||
// codeRact.endFill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StatusText extends Container {
|
|
||||||
sText: VectorText = new VectorText('');
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.addChild(this.sText);
|
|
||||||
}
|
|
||||||
doRepaint(text: string, bodyWH: bodyWH): void {
|
|
||||||
this.sText.text = text;
|
|
||||||
this.sText.anchor.set(0.5);
|
|
||||||
const c = (statusTextColor as never)[text] || statusTextColor.D;
|
|
||||||
const style = {
|
|
||||||
fill: c,
|
|
||||||
fontSize: trainConsts.textFontSize,
|
|
||||||
};
|
|
||||||
this.sText.style = style;
|
|
||||||
const { width: codeWidth, height: codeHeight } = bodyWH;
|
|
||||||
const { width: textHWidth, height: textHeight } =
|
|
||||||
this.sText.getLocalBounds();
|
|
||||||
const num = trainConsts.statusTextList.length;
|
|
||||||
let index = trainConsts.statusTextList.findIndex((item) => {
|
|
||||||
return item == text;
|
|
||||||
});
|
|
||||||
if (index < 0) {
|
|
||||||
index = (num - 1) / 2; // 中间
|
|
||||||
}
|
|
||||||
const textMargin = (codeWidth - textHWidth * num) / (num - 1);
|
|
||||||
this.sText.position.set(
|
|
||||||
-codeWidth / 2 + (textHWidth * (index * 2 + 1)) / 2 + textMargin * index,
|
|
||||||
-codeHeight / 2 - textHeight / 2 - trainConsts.textMarginY
|
|
||||||
);
|
|
||||||
}
|
|
||||||
clear(): void {
|
|
||||||
this.sText.text = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Train extends JlGraphic {
|
|
||||||
static Type = 'Train';
|
|
||||||
|
|
||||||
trainHead: TrainHead;
|
|
||||||
trainbody: TrainBody;
|
|
||||||
statusTextMap: Map<string, StatusText> = new Map();
|
|
||||||
constructor() {
|
|
||||||
super(Train.Type);
|
|
||||||
this.trainbody = new TrainBody();
|
|
||||||
this.trainHead = new TrainHead();
|
|
||||||
this.addChild(this.trainHead);
|
|
||||||
this.addChild(this.trainbody);
|
|
||||||
}
|
|
||||||
|
|
||||||
get datas(): ITrainData {
|
|
||||||
return this.getDatas<ITrainData>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get states(): ITrainState {
|
get states(): ITrainState {
|
||||||
@ -371,52 +102,78 @@ export class Train extends JlGraphic {
|
|||||||
this.trainbody.clear();
|
this.trainbody.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.trainbody.doRepaint(this.states);
|
let direction = '';
|
||||||
const bodyWH = this.trainbody.getBodyWH();
|
if (this.states.mode?.ipModeTrainDirDown) {
|
||||||
this.trainHead.doRepaint(this.states, bodyWH);
|
direction = 'left';
|
||||||
if (this.states.mode?.ipModeTrainHolded) {
|
}
|
||||||
this.showStatus('H');
|
if (this.states.mode?.ipModeTrainDirUp) {
|
||||||
|
direction = 'right';
|
||||||
|
}
|
||||||
|
this.isRightRoTop = direction != 'left';
|
||||||
|
if (!direction) {
|
||||||
|
this.trainHead.clear();
|
||||||
|
}
|
||||||
|
let dModel = EnumDiriveModel.AM;
|
||||||
|
if (this.states.mode?.ipModeTrainDriveModeCm) {
|
||||||
|
dModel = EnumDiriveModel.SM;
|
||||||
|
} else if (
|
||||||
|
this.states.mode?.ipModeTrainDriveModeRmf ||
|
||||||
|
this.states.mode?.ipModeTrainDriveModeRmr
|
||||||
|
) {
|
||||||
|
dModel = EnumDiriveModel.RM;
|
||||||
|
}
|
||||||
|
this.setDiriveModelColor(dModel);
|
||||||
|
let codeA = this.states.trainId;
|
||||||
|
let tType = EnumTrainType.schedule;
|
||||||
|
if (this.states.mode?.ipModeTrainTypeSchedule) {
|
||||||
|
if (this.states.mode?.ipModeTrainSchdLate) {
|
||||||
|
tType = EnumTrainType.late;
|
||||||
|
} else if (this.states.mode?.ipModeTrainSchdEarly) {
|
||||||
|
tType = EnumTrainType.early;
|
||||||
|
}
|
||||||
|
} else if (this.states.mode?.ipModeTrainTypeHead) {
|
||||||
|
codeA = this.states?.destinationId + '';
|
||||||
|
tType = EnumTrainType.head;
|
||||||
|
} else if (this.states.mode?.ipModeTrainTypeManual) {
|
||||||
|
codeA = 'MM';
|
||||||
|
tType = EnumTrainType.manual;
|
||||||
|
} else if (this.states.mode?.ipModeTrainTypeSpecial) {
|
||||||
|
codeA = '';
|
||||||
|
}
|
||||||
|
this.setTrainTypeColor(tType);
|
||||||
|
const codeB = this.states?.globalId;
|
||||||
|
this.setCodeAText(codeA);
|
||||||
|
this.setCodeBText(codeB);
|
||||||
|
this.trainbody.doRepaint();
|
||||||
|
this.trainHead.doRepaint();
|
||||||
|
if (this.states.mode?.ipModeTrainStoped) {
|
||||||
|
this.stop();
|
||||||
} else {
|
} else {
|
||||||
this.hideStatus('H');
|
this.run();
|
||||||
|
}
|
||||||
|
if (this.states.mode?.ipModeTrainHolded) {
|
||||||
|
this.showStatus(EnumStatusText.H);
|
||||||
|
} else {
|
||||||
|
this.hideStatus(EnumStatusText.H);
|
||||||
}
|
}
|
||||||
if (this.states.mode?.ipModeTrainSkipstop) {
|
if (this.states.mode?.ipModeTrainSkipstop) {
|
||||||
this.showStatus('S');
|
this.showStatus(EnumStatusText.S);
|
||||||
} else {
|
} else {
|
||||||
this.hideStatus('S');
|
this.hideStatus(EnumStatusText.S);
|
||||||
}
|
}
|
||||||
if (this.states.mode?.ipModeTrainDoorOpen) {
|
if (this.states.mode?.ipModeTrainDoorOpen) {
|
||||||
this.showStatus('D');
|
this.showStatus(EnumStatusText.D);
|
||||||
} else {
|
} else {
|
||||||
this.hideStatus('D');
|
this.hideStatus(EnumStatusText.D);
|
||||||
}
|
}
|
||||||
if (this.states.mode?.ipModeTrainRsAlarm) {
|
if (this.states.mode?.ipModeTrainRsAlarm) {
|
||||||
this.showStatus('A');
|
this.showStatus(EnumStatusText.A);
|
||||||
} else {
|
} else {
|
||||||
this.hideStatus('A');
|
this.hideStatus(EnumStatusText.A);
|
||||||
}
|
}
|
||||||
this.setPosition();
|
this.setPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
showStatus(s: string) {
|
|
||||||
if (this.statusTextMap.has(s)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const bodyWH = this.trainbody.getBodyWH();
|
|
||||||
const textD = new StatusText();
|
|
||||||
textD.doRepaint(s, bodyWH);
|
|
||||||
this.addChild(textD);
|
|
||||||
this.statusTextMap.set(s, textD);
|
|
||||||
}
|
|
||||||
hideStatus(s: string) {
|
|
||||||
if (!this.statusTextMap.has(s)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const textD = this.statusTextMap.get(s);
|
|
||||||
if (textD) {
|
|
||||||
textD.clear();
|
|
||||||
this.statusTextMap.delete(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setPosition(): void {
|
setPosition(): void {
|
||||||
if (deviceTypeString.get(this.states.devType)) {
|
if (deviceTypeString.get(this.states.devType)) {
|
||||||
const dev = this.queryStore.queryByCodeAndType<LogicSection | Section>(
|
const dev = this.queryStore.queryByCodeAndType<LogicSection | Section>(
|
||||||
@ -455,12 +212,22 @@ export class Train extends JlGraphic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updataConsts: UpdateTrainConsts = {
|
||||||
|
arrowPauseOnlyOne: true,
|
||||||
|
hasBodyRact: false,
|
||||||
|
textMarginY: 10, // 状态字母与列车距离
|
||||||
|
marginX: 4, // 图形x轴边距
|
||||||
|
borderColor: '0xA3E198', // 边框的颜色
|
||||||
|
arrowDefaultColor: '0x00FF00', // 箭头默认颜色
|
||||||
|
pauseDefaultColor: '0xFFCE4D', // 停止默认颜色
|
||||||
|
};
|
||||||
|
|
||||||
export class TrainTemplate extends JlGraphicTemplate<Train> {
|
export class TrainTemplate extends JlGraphicTemplate<Train> {
|
||||||
constructor(dataTemplate: ITrainData, stateTemplate: ITrainState) {
|
constructor(dataTemplate: ITrainData, stateTemplate: ITrainState) {
|
||||||
super(Train.Type, { dataTemplate, stateTemplate });
|
super(Train.Type, { dataTemplate, stateTemplate });
|
||||||
}
|
}
|
||||||
new(): Train {
|
new(): Train {
|
||||||
const train = new Train();
|
const train = new Train(updataConsts);
|
||||||
train.id = GraphicIdGenerator.next();
|
train.id = GraphicIdGenerator.next();
|
||||||
train.loadState(this.states);
|
train.loadState(this.states);
|
||||||
return train;
|
return train;
|
||||||
|
@ -1,732 +1,15 @@
|
|||||||
import { Graphics, IPointData } from 'pixi.js';
|
import { THTurnout as Turnout } from 'rt-graphic-component/components/packages/Turnout/THTurnout';
|
||||||
import {
|
|
||||||
GraphicAnimation,
|
|
||||||
GraphicData,
|
|
||||||
GraphicRelationParam,
|
|
||||||
GraphicState,
|
|
||||||
JlGraphic,
|
|
||||||
JlGraphicTemplate,
|
|
||||||
VectorText,
|
|
||||||
angleOfIncludedAngle,
|
|
||||||
distance2,
|
|
||||||
getParallelOfPolyline,
|
|
||||||
epsilon,
|
|
||||||
Vector2,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
import { Section, SectionPort, SectionType } from '../section/Section';
|
|
||||||
import {
|
|
||||||
IRelatedRefData,
|
|
||||||
createRelatedRefProto,
|
|
||||||
protoPort2Data,
|
|
||||||
} from '../CommonGraphics';
|
|
||||||
import { KilometerSystem } from '../signal/Signal';
|
|
||||||
import { Station } from '../station/Station';
|
|
||||||
|
|
||||||
export interface ITurnoutData extends GraphicData {
|
import { ITurnoutData } from 'rt-graphic-component/components/packages/Turnout/common/TurnoutConfig';
|
||||||
get code(): string;
|
import { TurnoutTemplate } from 'rt-graphic-component/components/packages/Turnout/common/TurnoutTemplate';
|
||||||
set code(code: string);
|
import { ITHTurnoutState as ITurnoutState } from 'rt-graphic-component/components/packages/Turnout/THTurnout';
|
||||||
get pointA(): IPointData[]; //A端点列表(从岔心向外)
|
import { TurnoutDraw } from 'rt-graphic-component/components/packages/Turnout/common/TurnoutDrawAssistant';
|
||||||
set pointA(point: IPointData[]);
|
|
||||||
get pointB(): IPointData[];
|
|
||||||
set pointB(point: IPointData[]);
|
|
||||||
get pointC(): IPointData[];
|
|
||||||
set pointC(point: IPointData[]);
|
|
||||||
get paRef(): IRelatedRefData | undefined;
|
|
||||||
set paRef(ref: IRelatedRefData | undefined);
|
|
||||||
get pbRef(): IRelatedRefData | undefined;
|
|
||||||
set pbRef(ref: IRelatedRefData | undefined);
|
|
||||||
get pcRef(): IRelatedRefData | undefined;
|
|
||||||
set pcRef(ref: IRelatedRefData | undefined);
|
|
||||||
get kilometerSystem(): KilometerSystem[];
|
|
||||||
set kilometerSystem(v: KilometerSystem[]);
|
|
||||||
get centralizedStation(): number; //所属集中站
|
|
||||||
set centralizedStation(v: number);
|
|
||||||
clone(): ITurnoutData;
|
|
||||||
copyFrom(data: ITurnoutData): void;
|
|
||||||
eq(other: ITurnoutData): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TurnoutConsts = {
|
export { Turnout, TurnoutTemplate, TurnoutDraw };
|
||||||
lineColor: '#5578b6',
|
export type { ITurnoutState, ITurnoutData };
|
||||||
idleColor: '#888', //空闲
|
|
||||||
jammedLineColor: '#f00', //挤岔
|
|
||||||
ciOccupiedColor: '#f00', //非通信车占用
|
|
||||||
cbtcOccupiedColor: '#f49', //通信车占用
|
|
||||||
lockedColor: '#fff', //锁闭 && 故障锁闭
|
|
||||||
atcInvalidColor: '#954', //atc报告失效
|
|
||||||
overlapColor: '#ff0', //overlap
|
|
||||||
blueShowColor: '0x3149c3',
|
|
||||||
lineWidth: 5,
|
|
||||||
forkLenth: 20,
|
|
||||||
labelFontSize: 12,
|
|
||||||
};
|
|
||||||
|
|
||||||
const TurnoutLabelColor = {
|
|
||||||
GREEN: '#0f0',
|
|
||||||
YELLOW: '#ff0',
|
|
||||||
RED: '#f00',
|
|
||||||
WHITE: '#fff',
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum TurnoutPosition {
|
|
||||||
NORMAL = 0,
|
|
||||||
REVERSE = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TurnoutPort {
|
export enum TurnoutPort {
|
||||||
A = 'A',
|
A = 0,
|
||||||
B = 'B',
|
B = 1,
|
||||||
C = 'C',
|
C = 2,
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITurnoutState extends GraphicState {
|
|
||||||
ipSingleSwitchStusCiOccupied: boolean;
|
|
||||||
ipSingleSwitchStusCbtcOccupied: boolean;
|
|
||||||
ipSingleSwitchStusLocked: boolean;
|
|
||||||
ipSingleSwitchStusFailLocked: boolean;
|
|
||||||
ipSingleSwitchStusNormal: boolean;
|
|
||||||
ipSingleSwitchStusReverse: boolean;
|
|
||||||
ipSingleSwitchStusBlocked1: boolean;
|
|
||||||
ipSingleSwitchStusJammed: boolean;
|
|
||||||
ipSingleSwitchStusCut: boolean;
|
|
||||||
ipSingleSwitchStusAtcInvalid: boolean;
|
|
||||||
ipSingleSwitchStusOverlap: boolean;
|
|
||||||
ipSingleSwitchStusTsrCbtcMain: boolean;
|
|
||||||
ipSingleSwitchStusTsrCbtcNormal: boolean;
|
|
||||||
ipSingleSwitchStusTsrCbtcReverse: boolean;
|
|
||||||
ipSingleSwitchStusTsrBmMain: boolean;
|
|
||||||
ipSingleSwitchStusTsrBmNormal: boolean;
|
|
||||||
ipSingleSwitchStusTsrBmReverse: boolean;
|
|
||||||
ipSingleSwitchStusBlocked2: boolean;
|
|
||||||
ipSingleSwitchStusLostIndication: boolean;
|
|
||||||
id: string;
|
|
||||||
speedLimit: number;
|
|
||||||
rtuId: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getForkPoint(r: number, p: IPointData): IPointData {
|
|
||||||
if (r === 0) return { x: 0, y: 0 };
|
|
||||||
const len = Math.sqrt((-p.x) ** 2 + (-p.y) ** 2);
|
|
||||||
const scale = r / len;
|
|
||||||
return { x: scale * p.x, y: scale * p.y };
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TurnoutSection extends Graphics {
|
|
||||||
turnout: Turnout;
|
|
||||||
port: TurnoutPort;
|
|
||||||
constructor(turnout: Turnout, port: TurnoutPort) {
|
|
||||||
super();
|
|
||||||
this.turnout = turnout;
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
paint() {
|
|
||||||
let pList: IPointData[] = [];
|
|
||||||
let lineColor = this.turnout.lineColor;
|
|
||||||
switch (this.port) {
|
|
||||||
case TurnoutPort.A:
|
|
||||||
pList = this.turnout.datas.pointA;
|
|
||||||
break;
|
|
||||||
case TurnoutPort.B:
|
|
||||||
pList = this.turnout.datas.pointB;
|
|
||||||
if (!this.turnout.states.ipSingleSwitchStusNormal) {
|
|
||||||
lineColor = TurnoutConsts.idleColor;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TurnoutPort.C:
|
|
||||||
pList = this.turnout.datas.pointC;
|
|
||||||
if (!this.turnout.states.ipSingleSwitchStusReverse) {
|
|
||||||
lineColor = TurnoutConsts.idleColor;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const station = this.turnout.queryStore.queryByCodeAndType<Station>(
|
|
||||||
this.turnout.states.rtuId > 9
|
|
||||||
? '' + this.turnout.states.rtuId
|
|
||||||
: '0' + this.turnout.states.rtuId,
|
|
||||||
Station.Type
|
|
||||||
);
|
|
||||||
if (station?.states.ipRtuStusDown) {
|
|
||||||
lineColor = TurnoutConsts.blueShowColor;
|
|
||||||
}
|
|
||||||
const gap = this.port === TurnoutPort.A ? 0 : TurnoutConsts.forkLenth;
|
|
||||||
const start = getForkPoint(gap, pList[0]);
|
|
||||||
this.clear()
|
|
||||||
.lineStyle(TurnoutConsts.lineWidth, lineColor)
|
|
||||||
.moveTo(start.x, start.y);
|
|
||||||
|
|
||||||
pList.forEach((p) => {
|
|
||||||
const { x, y } = p;
|
|
||||||
this.lineTo(x, y);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ForkGraphic extends Graphics {
|
|
||||||
turnout: Turnout;
|
|
||||||
dt = 0;
|
|
||||||
lostIndicationSquare: Graphics = new Graphics();
|
|
||||||
constructor(turnout: Turnout) {
|
|
||||||
super();
|
|
||||||
this.turnout = turnout;
|
|
||||||
this.addChild(this.lostIndicationSquare);
|
|
||||||
}
|
|
||||||
|
|
||||||
paint() {
|
|
||||||
this.clear();
|
|
||||||
this.lostIndicationSquare.clear();
|
|
||||||
if (
|
|
||||||
this.turnout.states.ipSingleSwitchStusJammed /* ||
|
|
||||||
this.turnout.states.ipSingleSwitchStusLostIndication */
|
|
||||||
) {
|
|
||||||
let x: number, y: number;
|
|
||||||
const w = 24,
|
|
||||||
h = 24;
|
|
||||||
if (this.turnout.datas.pointA[0].x > this.turnout.datas.pointB[0].x) {
|
|
||||||
x = -22;
|
|
||||||
} else {
|
|
||||||
x = -2;
|
|
||||||
}
|
|
||||||
if (this.turnout.datas.pointC[0].y > 0) {
|
|
||||||
y = -2;
|
|
||||||
} else {
|
|
||||||
y = -20;
|
|
||||||
}
|
|
||||||
this.lostIndicationSquare.lineStyle(2, '#f00').drawRect(x, y, w, h);
|
|
||||||
const flashAnimation = this.bindFlashAnimation(this.lostIndicationSquare);
|
|
||||||
flashAnimation.resume();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.turnout.states.ipSingleSwitchStusNormal) {
|
|
||||||
this.paintForkLine('B');
|
|
||||||
this.turnout.removeAllAnimation();
|
|
||||||
} else if (this.turnout.states.ipSingleSwitchStusReverse) {
|
|
||||||
this.paintForkLine('C');
|
|
||||||
this.turnout.removeAllAnimation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
paintForkLine(position: 'B' | 'C' | 'BOTH') {
|
|
||||||
this.clear().lineStyle(TurnoutConsts.lineWidth, this.turnout.lineColor);
|
|
||||||
|
|
||||||
const targetB = getForkPoint(
|
|
||||||
TurnoutConsts.forkLenth,
|
|
||||||
this.turnout.datas.pointB[0]
|
|
||||||
);
|
|
||||||
const targetC = getForkPoint(
|
|
||||||
TurnoutConsts.forkLenth,
|
|
||||||
this.turnout.datas.pointC[0]
|
|
||||||
);
|
|
||||||
if (position === 'B') {
|
|
||||||
this.moveTo(0, 0).lineTo(targetB.x, targetB.y);
|
|
||||||
} else if (position === 'C') {
|
|
||||||
this.moveTo(0, 0).lineTo(targetC.x, targetC.y);
|
|
||||||
} else if (position === 'BOTH') {
|
|
||||||
this.moveTo(targetB.x, targetB.y)
|
|
||||||
.lineTo(0, 0)
|
|
||||||
.lineTo(targetC.x, targetC.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bindFlashAnimation(g: Graphics) {
|
|
||||||
const flashAnimation = GraphicAnimation.init({
|
|
||||||
name: 'lostIndicationFlash',
|
|
||||||
run: (dt: number) => {
|
|
||||||
this.dt += dt;
|
|
||||||
if (this.dt > 60) {
|
|
||||||
this.dt = 0;
|
|
||||||
g.visible = true;
|
|
||||||
} else if (this.dt > 30) {
|
|
||||||
g.visible = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.turnout.addAnimation(flashAnimation);
|
|
||||||
return flashAnimation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Turnout extends JlGraphic {
|
|
||||||
static Type = 'Turnout';
|
|
||||||
graphics: {
|
|
||||||
fork: ForkGraphic;
|
|
||||||
sections: [TurnoutSection, TurnoutSection, TurnoutSection];
|
|
||||||
label: VectorText;
|
|
||||||
labelRect: Graphics;
|
|
||||||
speedLimit: Graphics;
|
|
||||||
};
|
|
||||||
lineColor: string;
|
|
||||||
dt = 0;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(Turnout.Type);
|
|
||||||
this.name = 'turnout';
|
|
||||||
this.lineColor = TurnoutConsts.lineColor;
|
|
||||||
this.graphics = {
|
|
||||||
fork: new ForkGraphic(this),
|
|
||||||
sections: [
|
|
||||||
new TurnoutSection(this, TurnoutPort.A),
|
|
||||||
new TurnoutSection(this, TurnoutPort.B),
|
|
||||||
new TurnoutSection(this, TurnoutPort.C),
|
|
||||||
],
|
|
||||||
label: new VectorText(),
|
|
||||||
labelRect: new Graphics(),
|
|
||||||
speedLimit: new Graphics(),
|
|
||||||
};
|
|
||||||
this.addChild(this.graphics.sections[0]);
|
|
||||||
this.addChild(this.graphics.sections[1]);
|
|
||||||
this.addChild(this.graphics.sections[2]);
|
|
||||||
this.addChild(this.graphics.fork);
|
|
||||||
this.graphics.label.anchor.set(0.5);
|
|
||||||
this.graphics.label.style.fill = '#0f0';
|
|
||||||
this.graphics.label.setVectorFontSize(TurnoutConsts.labelFontSize);
|
|
||||||
this.graphics.label.position.set(20, 20);
|
|
||||||
this.graphics.label.transformSave = true;
|
|
||||||
this.graphics.label.name = 'label';
|
|
||||||
this.addChild(this.graphics.label);
|
|
||||||
this.addChild(this.graphics.labelRect);
|
|
||||||
this.addChild(this.graphics.speedLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
get code(): string {
|
|
||||||
return this.datas.code;
|
|
||||||
}
|
|
||||||
|
|
||||||
set code(code: string) {
|
|
||||||
this.datas.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
get datas(): ITurnoutData {
|
|
||||||
return this.getDatas<ITurnoutData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
get states(): ITurnoutState {
|
|
||||||
return this.getStates<ITurnoutState>();
|
|
||||||
}
|
|
||||||
|
|
||||||
getSpeedLimitLinePoints(conf: 'normal' | 'reverse' | 'main'): IPointData[][] {
|
|
||||||
const [pa, pb, pc] = [
|
|
||||||
this.datas.pointA[0],
|
|
||||||
this.datas.pointB[0],
|
|
||||||
this.datas.pointC[0],
|
|
||||||
];
|
|
||||||
const [va, vb, vc] = [
|
|
||||||
new Vector2([pa.x, pa.y]),
|
|
||||||
new Vector2([pb.x, pb.y]),
|
|
||||||
new Vector2([pc.x, pc.y]),
|
|
||||||
];
|
|
||||||
const [vab, vbc] = [vb.subtract(va), vc.subtract(vb)];
|
|
||||||
const cpd = vab.x * vbc.y - vab.y * vbc.x;
|
|
||||||
const side = cpd > 0 ? 'L' : 'R'; //计算三个分支的手性
|
|
||||||
|
|
||||||
const offset = 10;
|
|
||||||
if (conf === 'main') {
|
|
||||||
return [
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'L'
|
|
||||||
),
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'R'
|
|
||||||
),
|
|
||||||
];
|
|
||||||
} else if (conf === 'normal') {
|
|
||||||
return [
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
...this.datas.pointB.map((p) => ({ x: p.x, y: p.y })),
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'L'
|
|
||||||
),
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
...this.datas.pointB.map((p) => ({ x: p.x, y: p.y })),
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'R'
|
|
||||||
),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
...this.datas.pointC.map((p) => ({ x: p.x, y: p.y })),
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'L'
|
|
||||||
),
|
|
||||||
getParallelOfPolyline(
|
|
||||||
[
|
|
||||||
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
...this.datas.pointC.map((p) => ({ x: p.x, y: p.y })),
|
|
||||||
],
|
|
||||||
offset,
|
|
||||||
'R'
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getPortPoints() {
|
|
||||||
return [this.datas.pointA, this.datas.pointB, this.datas.pointC];
|
|
||||||
}
|
|
||||||
|
|
||||||
doRepaint(): void {
|
|
||||||
//线条颜色
|
|
||||||
const station = this.queryStore.queryByCodeAndType<Station>(
|
|
||||||
this.states.rtuId > 9 ? '' + this.states.rtuId : '0' + this.states.rtuId,
|
|
||||||
Station.Type
|
|
||||||
);
|
|
||||||
if (station?.states.ipRtuStusDown) {
|
|
||||||
this.lineColor = TurnoutConsts.blueShowColor;
|
|
||||||
} else if (this.states.ipSingleSwitchStusCbtcOccupied) {
|
|
||||||
this.lineColor = TurnoutConsts.cbtcOccupiedColor;
|
|
||||||
} else if (this.states.ipSingleSwitchStusCiOccupied) {
|
|
||||||
this.lineColor = TurnoutConsts.ciOccupiedColor;
|
|
||||||
} else if (
|
|
||||||
this.states.ipSingleSwitchStusLocked ||
|
|
||||||
this.states.ipSingleSwitchStusFailLocked
|
|
||||||
) {
|
|
||||||
this.lineColor = TurnoutConsts.lockedColor;
|
|
||||||
} else if (this.states.ipSingleSwitchStusAtcInvalid) {
|
|
||||||
this.lineColor = TurnoutConsts.atcInvalidColor;
|
|
||||||
} else if (this.states.ipSingleSwitchStusOverlap) {
|
|
||||||
this.lineColor = TurnoutConsts.overlapColor;
|
|
||||||
} else {
|
|
||||||
this.lineColor = TurnoutConsts.idleColor;
|
|
||||||
}
|
|
||||||
this.graphics.sections.forEach((sectionGraphic) => sectionGraphic.paint());
|
|
||||||
|
|
||||||
this.graphics.fork.paint();
|
|
||||||
|
|
||||||
this.graphics.label.text = this.datas.code;
|
|
||||||
|
|
||||||
//文字颜色
|
|
||||||
if (this.states.ipSingleSwitchStusBlocked1) {
|
|
||||||
this.graphics.label.style.fill = TurnoutLabelColor.RED;
|
|
||||||
} else if (this.states.ipSingleSwitchStusNormal) {
|
|
||||||
this.graphics.label.style.fill = TurnoutLabelColor.GREEN;
|
|
||||||
} else if (this.states.ipSingleSwitchStusReverse) {
|
|
||||||
this.graphics.label.style.fill = TurnoutLabelColor.YELLOW;
|
|
||||||
} else if (
|
|
||||||
this.states.ipSingleSwitchStusJammed ||
|
|
||||||
this.states.ipSingleSwitchStusLostIndication
|
|
||||||
) {
|
|
||||||
this.graphics.label.style.fill = TurnoutLabelColor.WHITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.graphics.labelRect.clear();
|
|
||||||
this.graphics.speedLimit.clear();
|
|
||||||
this.graphics.fork.visible = true;
|
|
||||||
this.graphics.sections.forEach((s) => (s.visible = true));
|
|
||||||
this.removeAnimation('flash');
|
|
||||||
|
|
||||||
//文字框
|
|
||||||
if (this.states.ipSingleSwitchStusBlocked2) {
|
|
||||||
this.graphics.labelRect.clear().lineStyle(1, '#f00');
|
|
||||||
const { width, height } = this.graphics.label.getLocalBounds();
|
|
||||||
const { x, y } = this.graphics.label.transform.position;
|
|
||||||
this.graphics.labelRect.drawRect(
|
|
||||||
x - width / 2,
|
|
||||||
y - height / 2,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (station?.states.ipRtuStusDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(this.states.speedLimit && this.states.speedLimit > 0) ||
|
|
||||||
this.states.ipSingleSwitchStusTsrBmMain ||
|
|
||||||
this.states.ipSingleSwitchStusTsrBmNormal ||
|
|
||||||
this.states.ipSingleSwitchStusTsrBmReverse ||
|
|
||||||
this.states.ipSingleSwitchStusTsrCbtcMain ||
|
|
||||||
this.states.ipSingleSwitchStusTsrCbtcNormal ||
|
|
||||||
this.states.ipSingleSwitchStusTsrCbtcReverse
|
|
||||||
) {
|
|
||||||
let limitConf: Parameters<
|
|
||||||
typeof Turnout.prototype.getSpeedLimitLinePoints
|
|
||||||
>[0];
|
|
||||||
if (
|
|
||||||
this.states.ipSingleSwitchStusTsrBmReverse ||
|
|
||||||
this.states.ipSingleSwitchStusTsrCbtcReverse
|
|
||||||
) {
|
|
||||||
limitConf = 'reverse';
|
|
||||||
} else if (
|
|
||||||
this.states.ipSingleSwitchStusTsrBmNormal ||
|
|
||||||
this.states.ipSingleSwitchStusTsrCbtcNormal
|
|
||||||
) {
|
|
||||||
limitConf = 'normal';
|
|
||||||
} else {
|
|
||||||
limitConf = 'main';
|
|
||||||
}
|
|
||||||
const points = this.getSpeedLimitLinePoints(limitConf);
|
|
||||||
this.graphics.speedLimit.lineStyle(1, '#ff0');
|
|
||||||
points.forEach((ps) => {
|
|
||||||
this.graphics.speedLimit.moveTo(ps[0].x, ps[0].y);
|
|
||||||
for (let i = 1; i < ps.length; i++) {
|
|
||||||
this.graphics.speedLimit.lineTo(ps[i].x, ps[i].y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.states.ipSingleSwitchStusCut) {
|
|
||||||
if (this.states.ipSingleSwitchStusNormal) {
|
|
||||||
this.bindFlashAnimation([
|
|
||||||
this.graphics.fork,
|
|
||||||
this.graphics.sections[0],
|
|
||||||
this.graphics.sections[1],
|
|
||||||
]);
|
|
||||||
} else if (this.states.ipSingleSwitchStusReverse) {
|
|
||||||
this.bindFlashAnimation([
|
|
||||||
this.graphics.fork,
|
|
||||||
this.graphics.sections[0],
|
|
||||||
this.graphics.sections[2],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
this.animation('flash')?.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bindFlashAnimation(gList: Graphics[]) {
|
|
||||||
const flashAnimation = GraphicAnimation.init({
|
|
||||||
name: 'flash',
|
|
||||||
run: (dt: number) => {
|
|
||||||
this.dt += dt;
|
|
||||||
if (this.dt > 60) {
|
|
||||||
this.dt = 0;
|
|
||||||
gList.forEach((g) => (g.visible = true));
|
|
||||||
} else if (this.dt > 30) {
|
|
||||||
gList.forEach((g) => (g.visible = false));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.addAnimation(flashAnimation);
|
|
||||||
return flashAnimation;
|
|
||||||
}
|
|
||||||
|
|
||||||
getGraphicOfPort(port: TurnoutPort) {
|
|
||||||
return this.relationManage
|
|
||||||
.getRelationsOfGraphic(this)
|
|
||||||
.filter(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this).getParam<TurnoutPort>() === port
|
|
||||||
)
|
|
||||||
.map((relation) => {
|
|
||||||
return relation.getOtherGraphic(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
buildRelation(): void {
|
|
||||||
this.relationManage.deleteRelationOfGraphic(this);
|
|
||||||
|
|
||||||
|
|
||||||
/** 道岔和区段 */
|
|
||||||
this.queryStore.queryByType<Section>(Section.Type)
|
|
||||||
.forEach((section) => {
|
|
||||||
if (section.datas.sectionType === SectionType.TurnoutPhysical) {
|
|
||||||
if (section.datas.children.includes(this.datas.id)) {
|
|
||||||
this.relationManage.addRelation(this, section)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.getPortPoints().forEach((port, i) => {
|
|
||||||
if (
|
|
||||||
distance2(
|
|
||||||
section.localToCanvasPoint(section.getStartPoint()),
|
|
||||||
this.localToCanvasPoint(port[port.length - 1])
|
|
||||||
) <= epsilon
|
|
||||||
) {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this,
|
|
||||||
[TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i]
|
|
||||||
),
|
|
||||||
new GraphicRelationParam(section, SectionPort.A)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
distance2(
|
|
||||||
section.localToCanvasPoint(section.getEndPoint()),
|
|
||||||
this.localToCanvasPoint(port[port.length - 1])
|
|
||||||
) <= epsilon
|
|
||||||
) {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this,
|
|
||||||
[TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i]
|
|
||||||
),
|
|
||||||
new GraphicRelationParam(section, SectionPort.B)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/** 道岔和道岔 */
|
|
||||||
this.getPortPoints().forEach((thisPort, i) => {
|
|
||||||
let params: GraphicRelationParam[] = [],
|
|
||||||
deflection = 180;
|
|
||||||
this.queryStore.queryByType<Turnout>(Turnout.Type).forEach((turnout) => {
|
|
||||||
if (turnout.id === this.id) return;
|
|
||||||
turnout.getPortPoints().forEach((otherPort, j) => {
|
|
||||||
if (
|
|
||||||
distance2(
|
|
||||||
this.localToCanvasPoint(thisPort[thisPort.length - 1]),
|
|
||||||
turnout.localToCanvasPoint(otherPort[otherPort.length - 1])
|
|
||||||
) <= epsilon
|
|
||||||
) {
|
|
||||||
const angle = angleOfIncludedAngle(
|
|
||||||
this.localToCanvasPoint(thisPort[thisPort.length - 1]) /* 交点 */,
|
|
||||||
thisPort[thisPort.length - 2]
|
|
||||||
? this.localToCanvasPoint(thisPort[thisPort.length - 2])
|
|
||||||
: this.position,
|
|
||||||
otherPort[otherPort.length - 2]
|
|
||||||
? turnout.localToCanvasPoint(otherPort[otherPort.length - 2])
|
|
||||||
: turnout.position
|
|
||||||
);
|
|
||||||
if (180 - Math.abs(angle) <= deflection) {
|
|
||||||
deflection = 180 - Math.abs(angle);
|
|
||||||
params = [
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this,
|
|
||||||
[TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i]
|
|
||||||
),
|
|
||||||
new GraphicRelationParam(
|
|
||||||
turnout,
|
|
||||||
[TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][j]
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (params.length === 2) {
|
|
||||||
this.relationManage.addRelation(params[0], params[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
saveRelations() {
|
|
||||||
const paRelation = this.relationManage
|
|
||||||
.getRelationsOfGraphic(this)
|
|
||||||
.find(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this).param === TurnoutPort.A &&
|
|
||||||
(relation.getOtherGraphic(this) instanceof Section ||
|
|
||||||
relation.getOtherGraphic(this) instanceof Turnout)
|
|
||||||
);
|
|
||||||
const paDevice = paRelation?.getOtherGraphic<Section | Turnout>(this);
|
|
||||||
if (paDevice) {
|
|
||||||
this.datas.paRef = createRelatedRefProto(
|
|
||||||
paDevice.type,
|
|
||||||
paDevice.id,
|
|
||||||
paRelation?.getOtherRelationParam(this).param
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.datas.paRef = undefined;
|
|
||||||
}
|
|
||||||
const pbRelation = this.relationManage
|
|
||||||
.getRelationsOfGraphic(this)
|
|
||||||
.find(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this).param === TurnoutPort.B &&
|
|
||||||
(relation.getOtherGraphic(this) instanceof Section ||
|
|
||||||
relation.getOtherGraphic(this) instanceof Turnout)
|
|
||||||
);
|
|
||||||
const pbDevice = pbRelation?.getOtherGraphic<Section | Turnout>(this);
|
|
||||||
if (pbDevice) {
|
|
||||||
this.datas.pbRef = createRelatedRefProto(
|
|
||||||
pbDevice.type,
|
|
||||||
pbDevice.id,
|
|
||||||
pbRelation?.getOtherRelationParam(this).param
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.datas.pbRef = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pcRelation = this.relationManage
|
|
||||||
.getRelationsOfGraphic(this)
|
|
||||||
.find(
|
|
||||||
(relation) => relation.getRelationParam(this).param === TurnoutPort.C
|
|
||||||
&& (!(relation.getOtherGraphic(this) instanceof Section
|
|
||||||
&& relation.getOtherGraphic<Section>(this).datas.sectionType !== SectionType.TurnoutPhysical))
|
|
||||||
);
|
|
||||||
const pcDevice = pcRelation?.getOtherGraphic<Section | Turnout>(this);
|
|
||||||
if (pcDevice) {
|
|
||||||
this.datas.pcRef = createRelatedRefProto(
|
|
||||||
pcDevice.type,
|
|
||||||
pcDevice.id,
|
|
||||||
pcRelation?.getOtherRelationParam(this).param
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.datas.pcRef = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadRelations() {
|
|
||||||
if (this.datas.paRef?.id) {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(this, TurnoutPort.A),
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this.queryStore.queryById(this.datas.paRef.id),
|
|
||||||
protoPort2Data(this.datas.paRef.devicePort)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this.datas.pbRef?.id) {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(this, TurnoutPort.B),
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this.queryStore.queryById(this.datas.pbRef.id),
|
|
||||||
protoPort2Data(this.datas.pbRef.devicePort)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this.datas.pcRef?.id) {
|
|
||||||
this.relationManage.addRelation(
|
|
||||||
new GraphicRelationParam(this, TurnoutPort.C),
|
|
||||||
new GraphicRelationParam(
|
|
||||||
this.queryStore.queryById(this.datas.pcRef.id),
|
|
||||||
protoPort2Data(this.datas.pcRef.devicePort)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TurnoutTemplate extends JlGraphicTemplate<Turnout> {
|
|
||||||
constructor(dataTemplate: ITurnoutData, stateTemplate?: ITurnoutState) {
|
|
||||||
super(Turnout.Type, {
|
|
||||||
dataTemplate,
|
|
||||||
stateTemplate,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
new() {
|
|
||||||
const g = new Turnout();
|
|
||||||
g.loadData(this.datas);
|
|
||||||
g.loadState(this.states);
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,493 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
AbsorbablePosition,
|
ForkHitArea,
|
||||||
DraggablePoint,
|
TurnoutSectionHitArea,
|
||||||
IGraphicApp,
|
} from 'rt-graphic-component/components/packages/Turnout/common/TurnoutDrawAssistant';
|
||||||
GraphicDrawAssistant,
|
|
||||||
GraphicInteractionPlugin,
|
|
||||||
GraphicRelation,
|
|
||||||
GraphicTransformEvent,
|
|
||||||
IDrawApp,
|
|
||||||
JlGraphic,
|
|
||||||
VectorText,
|
|
||||||
linePoint,
|
|
||||||
polylinePoint,
|
|
||||||
GraphicEditPlugin,
|
|
||||||
getWaypointRangeIndex,
|
|
||||||
AbsorbablePoint,
|
|
||||||
AbsorbableLine,
|
|
||||||
ContextMenu,
|
|
||||||
MenuItemOptions,
|
|
||||||
} from 'jl-graphic';
|
|
||||||
import {
|
|
||||||
ITurnoutData,
|
|
||||||
Turnout,
|
|
||||||
TurnoutConsts,
|
|
||||||
TurnoutPort,
|
|
||||||
TurnoutSection,
|
|
||||||
TurnoutTemplate,
|
|
||||||
getForkPoint,
|
|
||||||
} from './Turnout';
|
|
||||||
import {
|
|
||||||
DisplayObject,
|
|
||||||
FederatedMouseEvent,
|
|
||||||
IHitArea,
|
|
||||||
IPointData,
|
|
||||||
Point,
|
|
||||||
} from 'pixi.js';
|
|
||||||
import { Section, SectionPort } from '../section/Section';
|
|
||||||
|
|
||||||
export class TurnoutDraw extends GraphicDrawAssistant<
|
export { ForkHitArea, TurnoutSectionHitArea };
|
||||||
TurnoutTemplate,
|
|
||||||
ITurnoutData
|
|
||||||
> {
|
|
||||||
turnout: Turnout;
|
|
||||||
constructor(app: IDrawApp, template: TurnoutTemplate) {
|
|
||||||
super(app, template, 'sym_o_ramp_left', '道岔Turnout');
|
|
||||||
|
|
||||||
this.turnout = this.graphicTemplate.new();
|
|
||||||
this.container.addChild(this.turnout);
|
|
||||||
|
|
||||||
TurnoutPointsInteractionPlugin.init(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
onLeftUp(e: FederatedMouseEvent): void {
|
|
||||||
this.turnout.position.copyFrom(this.toCanvasCoordinates(e.global));
|
|
||||||
this.createAndStore(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareData(data: ITurnoutData): boolean {
|
|
||||||
data.transform = this.turnout.saveTransform();
|
|
||||||
data.code = 'A000000';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw(cp: Point): void {
|
|
||||||
this.turnout.position.copyFrom(cp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ForkHitArea implements IHitArea {
|
|
||||||
turnout: Turnout;
|
|
||||||
constructor(turnout: Turnout) {
|
|
||||||
this.turnout = turnout;
|
|
||||||
}
|
|
||||||
contains(x: number, y: number): boolean {
|
|
||||||
const intersectPointB = getForkPoint(
|
|
||||||
TurnoutConsts.forkLenth,
|
|
||||||
this.turnout.datas.pointB[0]
|
|
||||||
);
|
|
||||||
const intersectPointC = getForkPoint(
|
|
||||||
TurnoutConsts.forkLenth,
|
|
||||||
this.turnout.datas.pointC[0]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
linePoint(
|
|
||||||
intersectPointB,
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
{ x, y },
|
|
||||||
TurnoutConsts.lineWidth
|
|
||||||
) ||
|
|
||||||
linePoint(
|
|
||||||
intersectPointC,
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
{ x, y },
|
|
||||||
TurnoutConsts.lineWidth
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TurnoutSectionHitArea implements IHitArea {
|
|
||||||
section: TurnoutSection;
|
|
||||||
constructor(section: TurnoutSection) {
|
|
||||||
this.section = section;
|
|
||||||
}
|
|
||||||
contains(x: number, y: number): boolean {
|
|
||||||
let points: IPointData[];
|
|
||||||
let start: IPointData;
|
|
||||||
switch (this.section.port) {
|
|
||||||
case TurnoutPort.A:
|
|
||||||
points = this.section.turnout.datas.pointA;
|
|
||||||
start = { x: 0, y: 0 };
|
|
||||||
break;
|
|
||||||
case TurnoutPort.B:
|
|
||||||
points = this.section.turnout.datas.pointB;
|
|
||||||
start = getForkPoint(TurnoutConsts.forkLenth, points[0]);
|
|
||||||
break;
|
|
||||||
case TurnoutPort.C:
|
|
||||||
points = this.section.turnout.datas.pointC;
|
|
||||||
start = getForkPoint(TurnoutConsts.forkLenth, points[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return polylinePoint([start, ...points], { x, y }, TurnoutConsts.lineWidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAbsorbablePositions(turnout: Turnout): AbsorbablePosition[] {
|
|
||||||
const aps: AbsorbablePosition[] = [];
|
|
||||||
|
|
||||||
const sections = turnout.queryStore.queryByType<Section>(Section.Type);
|
|
||||||
sections.forEach((section) => {
|
|
||||||
const ps = new AbsorbablePoint(
|
|
||||||
section.localToCanvasPoint(section.getStartPoint())
|
|
||||||
);
|
|
||||||
const pe = new AbsorbablePoint(
|
|
||||||
section.localToCanvasPoint(section.getEndPoint())
|
|
||||||
);
|
|
||||||
aps.push(ps, pe); //区段端点
|
|
||||||
});
|
|
||||||
|
|
||||||
const turnouts = turnout.queryStore.queryByType<Turnout>(Turnout.Type);
|
|
||||||
turnouts.forEach((otherTurnout) => {
|
|
||||||
const {
|
|
||||||
pointA: [A],
|
|
||||||
pointB: [B],
|
|
||||||
pointC: [C],
|
|
||||||
} = otherTurnout.datas;
|
|
||||||
|
|
||||||
[A, B, C].forEach((p) => {
|
|
||||||
aps.push(
|
|
||||||
new AbsorbablePoint(otherTurnout.localToCanvasPoint(p)), //道岔端点
|
|
||||||
new AbsorbableLine(
|
|
||||||
otherTurnout.localToCanvasPoint({ x: -5 * p.x, y: -5 * p.y }),
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 5 * p.x, y: 5 * p.y })
|
|
||||||
) //道岔延长线
|
|
||||||
);
|
|
||||||
});
|
|
||||||
aps.push(
|
|
||||||
new AbsorbableLine(
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 0, y: -500 }),
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 0, y: 500 })
|
|
||||||
), //岔心垂直线
|
|
||||||
new AbsorbableLine(
|
|
||||||
otherTurnout.localToCanvasPoint({ x: -500, y: 0 }),
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 500, y: 0 })
|
|
||||||
), //岔心水平线
|
|
||||||
new AbsorbableLine(
|
|
||||||
otherTurnout.localToCanvasPoint({ x: -500, y: 500 }),
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 500, y: -500 })
|
|
||||||
), //岔心/
|
|
||||||
new AbsorbableLine(
|
|
||||||
otherTurnout.localToCanvasPoint({ x: -500, y: -500 }),
|
|
||||||
otherTurnout.localToCanvasPoint({ x: 500, y: 500 })
|
|
||||||
) //岔心\
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return aps;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditPointCreate(turnout: Turnout, dp: DraggablePoint) {
|
|
||||||
dp.on('transformstart', (e: GraphicTransformEvent) => {
|
|
||||||
if (e.isShift()) {
|
|
||||||
turnout.getGraphicApp().setOptions({
|
|
||||||
absorbablePositions: buildAbsorbablePositions(turnout),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const addPointConfig: MenuItemOptions = { name: '添加路径点' };
|
|
||||||
const clearPointConfig: MenuItemOptions = { name: '清除路径点' };
|
|
||||||
|
|
||||||
const turnoutSectionEditMenu: ContextMenu = ContextMenu.init({
|
|
||||||
name: '道岔区段路径编辑',
|
|
||||||
groups: [
|
|
||||||
{
|
|
||||||
items: [addPointConfig, clearPointConfig],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Turnout> {
|
|
||||||
static Name = 'TurnoutPointsDrag';
|
|
||||||
static init(app: IDrawApp) {
|
|
||||||
return new TurnoutPointsInteractionPlugin(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(app: IGraphicApp) {
|
|
||||||
super(TurnoutPointsInteractionPlugin.Name, app);
|
|
||||||
app.registerMenu(turnoutSectionEditMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSectionContextMenu(e: FederatedMouseEvent, section: TurnoutSection) {
|
|
||||||
let points: IPointData[];
|
|
||||||
if (section.port === TurnoutPort.A) points = section.turnout.datas.pointA;
|
|
||||||
if (section.port === TurnoutPort.B) points = section.turnout.datas.pointB;
|
|
||||||
if (section.port === TurnoutPort.C) points = section.turnout.datas.pointC;
|
|
||||||
const p = section.turnout.screenToLocalPoint(e.global);
|
|
||||||
addPointConfig.handler = () => {
|
|
||||||
if (section.port === TurnoutPort.A) {
|
|
||||||
const { start } = getWaypointRangeIndex(
|
|
||||||
[{ x: 0, y: 0 }, ...section.turnout.datas.pointA],
|
|
||||||
false,
|
|
||||||
p,
|
|
||||||
TurnoutConsts.lineWidth
|
|
||||||
);
|
|
||||||
const points = section.turnout.datas.pointA;
|
|
||||||
const ps = points.slice(0, start);
|
|
||||||
ps.push(new Point(p.x, p.y));
|
|
||||||
ps.push(...points.slice(start));
|
|
||||||
section.turnout.datas.pointA = ps;
|
|
||||||
}
|
|
||||||
if (section.port === TurnoutPort.B) {
|
|
||||||
const { start } = getWaypointRangeIndex(
|
|
||||||
[{ x: 0, y: 0 }, ...section.turnout.datas.pointB],
|
|
||||||
false,
|
|
||||||
p,
|
|
||||||
TurnoutConsts.lineWidth
|
|
||||||
);
|
|
||||||
const points = section.turnout.datas.pointB;
|
|
||||||
const ps = points.slice(0, start);
|
|
||||||
ps.push(new Point(p.x, p.y));
|
|
||||||
ps.push(...points.slice(start));
|
|
||||||
section.turnout.datas.pointB = ps;
|
|
||||||
}
|
|
||||||
if (section.port === TurnoutPort.C) {
|
|
||||||
const { start } = getWaypointRangeIndex(
|
|
||||||
[{ x: 0, y: 0 }, ...section.turnout.datas.pointC],
|
|
||||||
false,
|
|
||||||
p,
|
|
||||||
TurnoutConsts.lineWidth
|
|
||||||
);
|
|
||||||
const points = section.turnout.datas.pointC;
|
|
||||||
const ps = points.slice(0, start);
|
|
||||||
ps.push(new Point(p.x, p.y));
|
|
||||||
ps.push(...points.slice(start));
|
|
||||||
section.turnout.datas.pointC = ps;
|
|
||||||
}
|
|
||||||
this.onSelected(section.turnout);
|
|
||||||
};
|
|
||||||
clearPointConfig.handler = () => {
|
|
||||||
if (points.length <= 1) return;
|
|
||||||
points.splice(0, points.length - 1);
|
|
||||||
section.turnout.repaint();
|
|
||||||
};
|
|
||||||
turnoutSectionEditMenu.open(e.global);
|
|
||||||
}
|
|
||||||
|
|
||||||
bind(g: Turnout): void {
|
|
||||||
g.graphics.fork.eventMode = 'static';
|
|
||||||
g.graphics.fork.cursor = 'pointer';
|
|
||||||
g.graphics.fork.hitArea = new ForkHitArea(g);
|
|
||||||
g.graphics.sections.forEach((sectionGraphic) => {
|
|
||||||
sectionGraphic.eventMode = 'static';
|
|
||||||
sectionGraphic.cursor = 'pointer';
|
|
||||||
sectionGraphic.hitArea = new TurnoutSectionHitArea(sectionGraphic);
|
|
||||||
sectionGraphic.on(
|
|
||||||
'rightclick',
|
|
||||||
(e) => this.onSectionContextMenu(e, sectionGraphic),
|
|
||||||
sectionGraphic
|
|
||||||
);
|
|
||||||
});
|
|
||||||
g.graphics.label.eventMode = 'static';
|
|
||||||
g.graphics.label.cursor = 'pointer';
|
|
||||||
g.graphics.label.draggable = true;
|
|
||||||
g.graphics.label.selectable = true;
|
|
||||||
g.graphics.label.name = 'label';
|
|
||||||
g.graphics.label.transformSave = true;
|
|
||||||
g.transformSave = true;
|
|
||||||
g.on('selected', this.onSelected, this);
|
|
||||||
g.on('unselected', this.onUnSelected, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
unbind(g: Turnout): void {
|
|
||||||
g.off('selected', this.onSelected, this);
|
|
||||||
g.off('unselected', this.onUnSelected, this);
|
|
||||||
g.graphics.sections.forEach((sectionGraphic) => {
|
|
||||||
sectionGraphic.off('rightclick');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelected(g: DisplayObject) {
|
|
||||||
const turnout = g as Turnout;
|
|
||||||
let tep = turnout.getAssistantAppend<TurnoutEditPlugin>(
|
|
||||||
TurnoutEditPlugin.Name
|
|
||||||
);
|
|
||||||
if (!tep) {
|
|
||||||
tep = new TurnoutEditPlugin(turnout, { onEditPointCreate });
|
|
||||||
turnout.addAssistantAppend(tep);
|
|
||||||
}
|
|
||||||
// tep.reset();
|
|
||||||
tep.showAll();
|
|
||||||
tep.setRelatedDrag();
|
|
||||||
}
|
|
||||||
|
|
||||||
onUnSelected(g: DisplayObject) {
|
|
||||||
const turnout = g as Turnout;
|
|
||||||
const tep = turnout.getAssistantAppend<TurnoutEditPlugin>(
|
|
||||||
TurnoutEditPlugin.Name
|
|
||||||
);
|
|
||||||
if (tep) {
|
|
||||||
tep.hideAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filter(...grahpics: JlGraphic[]): Turnout[] | undefined {
|
|
||||||
return grahpics.filter((g) => g.type == Turnout.Type) as Turnout[];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type onTurnoutEditPointCreate = (turnout: Turnout, dp: DraggablePoint) => void;
|
|
||||||
|
|
||||||
export interface ITurnoutEditOptions {
|
|
||||||
onEditPointCreate?: onTurnoutEditPointCreate;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TurnoutEditPlugin extends GraphicEditPlugin<Turnout> {
|
|
||||||
static Name = 'TurnoutEdit';
|
|
||||||
options: ITurnoutEditOptions;
|
|
||||||
editPoints: DraggablePoint[][] = [[], [], []];
|
|
||||||
labels: VectorText[] = [];
|
|
||||||
|
|
||||||
constructor(graphic: Turnout, options?: ITurnoutEditOptions) {
|
|
||||||
super(graphic);
|
|
||||||
this.name = TurnoutEditPlugin.Name;
|
|
||||||
this.options = Object.assign({}, options);
|
|
||||||
this.initEditPoints();
|
|
||||||
}
|
|
||||||
reset(): void {
|
|
||||||
this.destoryEditPoints();
|
|
||||||
this.removeChildren();
|
|
||||||
this.initEditPoints();
|
|
||||||
}
|
|
||||||
hideAll(): void {
|
|
||||||
super.hideAll();
|
|
||||||
}
|
|
||||||
setRelatedDrag() {
|
|
||||||
this.editPoints.forEach((eps, i) => {
|
|
||||||
const ep = eps[eps.length - 1];
|
|
||||||
let relations: GraphicRelation[];
|
|
||||||
if (i === 0) {
|
|
||||||
relations = this.graphic.relationManage
|
|
||||||
.getRelationsOfGraphic(this.graphic)
|
|
||||||
.filter(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this.graphic).param === TurnoutPort.A
|
|
||||||
);
|
|
||||||
} else if (i === 1) {
|
|
||||||
relations = this.graphic.relationManage
|
|
||||||
.getRelationsOfGraphic(this.graphic)
|
|
||||||
.filter(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this.graphic).param === TurnoutPort.B
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
relations = this.graphic.relationManage
|
|
||||||
.getRelationsOfGraphic(this.graphic)
|
|
||||||
.filter(
|
|
||||||
(relation) =>
|
|
||||||
relation.getRelationParam(this.graphic).param === TurnoutPort.C
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!relations.length) return;
|
|
||||||
const otherGraphics = relations.map((relation) =>
|
|
||||||
relation.getOtherGraphic(this.graphic)
|
|
||||||
);
|
|
||||||
console.log(otherGraphics);
|
|
||||||
const otherPorts = relations.map(
|
|
||||||
(relation) => relation.getOtherRelationParam(this.graphic).param
|
|
||||||
);
|
|
||||||
|
|
||||||
const point: IPointData[] = [];
|
|
||||||
otherGraphics.map((otherGraphic, i) => {
|
|
||||||
const otherPort = otherPorts[i];
|
|
||||||
if (otherGraphic instanceof Turnout) {
|
|
||||||
if (otherPort === TurnoutPort.A) {
|
|
||||||
point.push(
|
|
||||||
otherGraphic.datas.pointA[otherGraphic.datas.pointA.length - 1]
|
|
||||||
);
|
|
||||||
} else if (otherPort === TurnoutPort.B) {
|
|
||||||
point.push(
|
|
||||||
otherGraphic.datas.pointB[otherGraphic.datas.pointB.length - 1]
|
|
||||||
);
|
|
||||||
} else if (otherPort === TurnoutPort.C) {
|
|
||||||
point.push(
|
|
||||||
otherGraphic.datas.pointC[otherGraphic.datas.pointC.length - 1]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (otherGraphic instanceof Section) {
|
|
||||||
if (otherPort === SectionPort.A) {
|
|
||||||
point.push(otherGraphic.datas.points[0]);
|
|
||||||
} else if (otherPort === SectionPort.B) {
|
|
||||||
point.push(
|
|
||||||
otherGraphic.datas.points[otherGraphic.datas.points.length - 1]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const transformingHandler = () => {
|
|
||||||
otherGraphics.forEach((otherGraphic, i) => {
|
|
||||||
const p = otherGraphic.canvasToLocalPoint(ep);
|
|
||||||
point[i].x = p.x;
|
|
||||||
point[i].y = p.y;
|
|
||||||
otherGraphic.repaint();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
ep.on('transforming', transformingHandler);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initEditPoints() {
|
|
||||||
const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA);
|
|
||||||
const cpB = this.graphic.localToCanvasPoints(...this.graphic.datas.pointB);
|
|
||||||
const cpC = this.graphic.localToCanvasPoints(...this.graphic.datas.pointC);
|
|
||||||
const cpMap: Map<Point[], IPointData[]> = new Map([
|
|
||||||
[cpA, this.graphic.datas.pointA],
|
|
||||||
[cpB, this.graphic.datas.pointB],
|
|
||||||
[cpC, this.graphic.datas.pointC],
|
|
||||||
]);
|
|
||||||
Array.from(cpMap.entries()).forEach(([cpDatas, dataPoints], i) => {
|
|
||||||
cpDatas.forEach((cpData, j) => {
|
|
||||||
const dp = new DraggablePoint(cpData);
|
|
||||||
dp.on('transforming', (e: GraphicTransformEvent) => {
|
|
||||||
const localPoint = this.graphic.canvasToLocalPoint(dp.position);
|
|
||||||
dataPoints[j].x = localPoint.x;
|
|
||||||
dataPoints[j].y = localPoint.y;
|
|
||||||
|
|
||||||
this.graphic.repaint();
|
|
||||||
});
|
|
||||||
if (this.options.onEditPointCreate) {
|
|
||||||
this.options.onEditPointCreate(this.graphic, dp);
|
|
||||||
}
|
|
||||||
this.editPoints[i].push(dp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.editPoints.forEach((cps) => {
|
|
||||||
this.addChild(...cps);
|
|
||||||
});
|
|
||||||
this.labels = ['A', 'B', 'C'].map((str) => {
|
|
||||||
const vc = new VectorText(str);
|
|
||||||
vc.setVectorFontSize(14);
|
|
||||||
vc.anchor.set(0.5);
|
|
||||||
return vc;
|
|
||||||
});
|
|
||||||
this.addChild(...this.labels);
|
|
||||||
}
|
|
||||||
|
|
||||||
destoryEditPoints() {
|
|
||||||
this.editPoints.forEach((dps) => {
|
|
||||||
dps.forEach((dp) => {
|
|
||||||
dp.off('transforming');
|
|
||||||
dp.destroy();
|
|
||||||
this.removeChild(dp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.editPoints = [[], [], []];
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEditedPointsPosition() {
|
|
||||||
const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA);
|
|
||||||
const cpB = this.graphic.localToCanvasPoints(...this.graphic.datas.pointB);
|
|
||||||
const cpC = this.graphic.localToCanvasPoints(...this.graphic.datas.pointC);
|
|
||||||
[cpA, cpB, cpC].forEach((cps, i) => {
|
|
||||||
cps.forEach((cp, j) => {
|
|
||||||
this.editPoints[i][j].position.copyFrom(cp);
|
|
||||||
if (j === cps.length - 1) {
|
|
||||||
this.labels[i].position.copyFrom({ x: cp.x, y: cp.y + 12 });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user