列车调整

This commit is contained in:
dong 2023-06-21 10:07:16 +08:00
parent a3617b30a5
commit 0a209a963a
6 changed files with 381 additions and 148 deletions

View File

@ -19,9 +19,9 @@
<template v-if="drawStore.drawGraphicType === Station.Type">
<station-template></station-template>
</template>
<template v-if="drawStore.drawGraphicType === Train.Type">
<!-- <template v-if="drawStore.drawGraphicType === Train.Type">
<train-template></train-template>
</template>
</template> -->
</q-card-section>
</q-card>
</div>
@ -54,9 +54,9 @@
<station-line-property
v-if="drawStore.selectedGraphicType === StationLine.Type"
></station-line-property>
<train-property
<!-- <train-property
v-if="drawStore.selectedGraphicType === Train.Type"
></train-property>
></train-property> -->
<iscs-fan-property
v-else-if="drawStore.selectedGraphicType === IscsFan.Type"
></iscs-fan-property>
@ -86,14 +86,14 @@ import LinkTemplate from './templates/LinkTemplate.vue';
import RectTemplate from './templates/RectTemplate.vue';
import PlatformTemplate from './templates/PlatformTemplate.vue';
import StationTemplate from './templates/StationTemplate.vue';
import TrainTemplate from './templates/TrainTemplate.vue';
// import TrainTemplate from './templates/TrainTemplate.vue';
import CanvasProperty from './properties/CanvasProperty.vue';
import LinkProperty from './properties/LinkProperty.vue';
import RectProperty from './properties/RectProperty.vue';
import PlatformProperty from './properties/PlatformProperty.vue';
import StationProperty from './properties/StationProperty.vue';
import StationLineProperty from './properties/StationLineProperty.vue';
import TrainProperty from './properties/TrainProperty.vue';
// import TrainProperty from './properties/TrainProperty.vue';
import TrainWindowProperty from './properties/TrainWindowProperty.vue';
import IscsFanProperty from './properties/IscsFanProperty.vue';
import SignalProperty from './properties/SignalProperty.vue';

View File

@ -1,7 +1,8 @@
import * as pb_1 from 'google-protobuf';
import { ITrainData, Train } from 'src/graphics/train/Train';
import { ITrainData, ITrainState, Train } from 'src/graphics/train/Train';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import { state } from 'src/protos/device_status';
export class TrainData extends GraphicDataBase implements ITrainData {
constructor(data?: graphicData.Train) {
@ -25,18 +26,6 @@ export class TrainData extends GraphicDataBase implements ITrainData {
set code(v: string) {
this.data.code = v;
}
get trainDirection(): string {
return this.data.trainDirection;
}
set trainDirection(v: string) {
this.data.trainDirection = v;
}
get hasBorder(): boolean {
return this.data.hasBorder;
}
set hasBorder(v: boolean) {
this.data.hasBorder = v;
}
clone(): TrainData {
return new TrainData(this.data.cloneMessage());
}
@ -47,3 +36,186 @@ export class TrainData extends GraphicDataBase implements ITrainData {
return pb_1.Message.equals(this.data, other.data);
}
}
export class TrainState extends GraphicStateBase implements ITrainState {
constructor(proto?: StateTrain) {
let states;
if (proto) {
states = proto;
} else {
states = new StateTrain();
}
super(states, Train.Type);
}
get states(): StateTrain {
return this.getState<StateTrain>();
}
get trainId(): string {
return this.states.trainId;
}
set trainId(v: string) {
this.states.trainId = v;
}
get globalId(): string {
return this.states.globalId;
}
set globalId(v: string) {
this.states.globalId = v;
}
get groupId(): string {
return this.states.groupId;
}
set groupId(v: string) {
this.states.groupId = v;
}
get localSubId(): number {
return this.states.localSubId;
}
set localSubId(v: number) {
this.states.localSubId = v;
}
get trainType(): number {
return this.states.trainType;
}
set trainType(v: number) {
this.states.trainType = v;
}
get speed(): number {
return this.states.speed;
}
set speed(v: number) {
this.states.speed = v;
}
get direction(): number {
return this.states.direction;
}
set direction(v: number) {
this.states.direction = v;
}
get destinationId(): number {
return this.states.destinationId;
}
set destinationId(v: number) {
this.states.destinationId = v;
}
get stationId(): number {
return this.states.stationId;
}
set stationId(v: number) {
this.states.stationId = v;
}
get sideId(): number {
return this.states.sideId;
}
set sideId(v: number) {
this.states.sideId = v;
}
get trackName(): string {
return this.states.trackName;
}
set trackName(v: string) {
this.states.trackName = v;
}
get recordType(): boolean {
return this.states.recordType;
}
set recordType(v: boolean) {
this.states.recordType = v;
}
get recordTime(): number {
return this.states.recordTime;
}
set recordTime(v: number) {
this.states.recordTime = v;
}
get driverId(): string {
return this.states.driverId;
}
set driverId(v: string) {
this.states.driverId = v;
}
get routeId(): number {
return this.states.routeId;
}
set routeId(v: number) {
this.states.routeId = v;
}
get mode(): number {
return this.states.mode;
}
set mode(v: number) {
this.states.mode = v;
}
get nccWindow(): number {
return this.states.nccWindow;
}
set nccWindow(v: number) {
this.states.nccWindow = v;
}
get nccWindowOffset(): number {
return this.states.nccWindowOffset;
}
set nccWindowOffset(v: number) {
this.states.nccWindowOffset = v;
}
get rate(): number {
return this.states.rate;
}
set rate(v: number) {
this.states.rate = v;
}
get devType(): number {
return this.states.devType;
}
set devType(v: number) {
this.states.devType = v;
}
get devName(): string {
return this.states.devName;
}
set devName(v: string) {
this.states.devName = v;
}
get blockFlag(): number {
return this.states.blockFlag;
}
set blockFlag(v: number) {
this.states.blockFlag = v;
}
get show(): boolean {
return this.states.show;
}
set show(v: boolean) {
this.states.show = v;
}
get lineId(): number {
return this.states.lineId;
}
set lineId(v: number) {
this.states.lineId = v;
}
get id(): string {
return this.states.id;
}
set id(v: string) {
this.states.id = v;
}
clone(): TrainState {
return new TrainState(this.states.cloneMessage());
}
}
class StateTrain extends state.Train {
id: string;
constructor(data?: state.Train) {
super(data);
if (data?.trainIndex) {
this.id = data?.trainIndex;
} else {
this.id = '';
}
}
}

View File

@ -3,7 +3,7 @@ import { IPointData, Point } from 'pixi.js';
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
import { Link } from 'src/graphics/link/Link';
import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant';
import { Train } from 'src/graphics/train/Train';
import { Train, TrainTemplate } from 'src/graphics/train/Train';
import { TrainDraw } from 'src/graphics/train/TrainDrawAssistant';
import { Signal, SignalTemplate } from 'src/graphics/signal/Signal';
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
@ -19,7 +19,7 @@ import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { IscsFanData } from './graphics/IscsFanInteraction';
import { LinkData } from './graphics/LinkInteraction';
import { TrainData } from './graphics/TrainInteraction';
import { TrainData, TrainState } from './graphics/TrainInteraction';
import {
SignalData,
DrawSignalInteraction,
@ -152,6 +152,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
| TrainLineDraw
| PathLineDraw
| TrainWindowDraw
| TrainDraw
)[] = [];
if (draftType === 'Line') {
drawAssistants = [
@ -167,9 +168,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
app,
new SignalTemplate(new SignalData(), new SignalState())
),
// new TrainDraw(app, () => {
// return new TrainData();
// }),
new TrainDraw(app, new TrainTemplate(new TrainData(), new TrainState())),
new SectionDraw(app, new SectionTemplate(new SectionData())),
new TurnoutDraw(app, new TurnoutTemplate(new TurnoutData())),
new TrainWindowDraw(app, new TrainWindowTemplate(new TrainWindowData())),

View File

@ -1,23 +1,74 @@
import { Color, Graphics, Container } from 'pixi.js';
import { Color, Graphics, Container, Point } from 'pixi.js';
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
VectorText,
calculateMirrorPoint,
} from 'src/jl-graphic';
export interface ITrainData extends GraphicData {
get code(): string; // 车号
set code(v: string);
get trainDirection(): string; // 行驶方向
set trainDirection(v: string);
get hasBorder(): boolean; // 是否有边框
set hasBorder(v: boolean);
clone(): ITrainData;
copyFrom(data: ITrainData): void;
eq(other: ITrainData): boolean;
}
export interface ITrainState extends GraphicState {
get trainId(): string; // 列车表号
set trainId(v: string);
get globalId(): string; // 列车车次号
set globalId(v: string);
get groupId(): string; // 列车车组号
set groupId(v: string);
get localSubId(): number; // 局部序列号
set localSubId(v: number);
get trainType(): number; // 列车类型
set trainType(v: number);
get speed(): number; // 速度
set speed(v: number);
get direction(): number; // 运行方向
set direction(v: number);
get destinationId(): number; // 目的地ID
set destinationId(v: number);
get stationId(): number; // 行驶站号
set stationId(v: number);
get sideId(): number; // 站台号
set sideId(v: number);
get trackName(): string; // 轨道名称
set trackName(v: string);
get recordType(): boolean; // 到发点类型
set recordType(v: boolean);
get recordTime(): number; // 到发时间
set recordTime(v: number);
get driverId(): string; // 司机号
set driverId(v: string);
get routeId(): number; // 运行路径号
set routeId(v: number);
get mode(): number; // 列车状态
set mode(v: number);
get nccWindow(): number; // 车次窗编号
set nccWindow(v: number);
get nccWindowOffset(): number; // 车次窗位置
set nccWindowOffset(v: number);
get rate(): number; // 满载率
set rate(v: number);
get devType(): number; // 所在设备类型
set devType(v: number);
get devName(): string; // 所在设备名称
set devName(v: string);
get blockFlag(): number; // 阻塞标记
set blockFlag(v: number);
get show(): boolean; // 是否显示
set show(v: boolean);
get lineId(): number; // 线路id
set lineId(v: number);
get id(): string; // 设备唯一
set id(v: string);
}
interface bodyWH {
width: number; // 宽
height: number; // 高
@ -31,12 +82,22 @@ export enum TrainColorEnum {
borderColor = '0xA3E198', // 边框的颜色
}
enum statusTextColor {
H = '0xFFFF00', // H扣车
S = '0x6260F3', // S跳停
D = '0x00FF00', // D开门
A = '0xFF0000', // A报警
}
export const trainConsts = {
codeWidth: 120,
codeHeight: 40,
codePadding: 5,
borderWidth: 1,
codeFontSize: 22,
textFontSize: 16, // 状态字母大小
textMarginY: 10, // 状态字母与列车距离
statusTextList: ['H', 'S', 'D', 'A'],
marginX: 2, // 图形x轴边距
pauseW: 2, // 停止框宽度
};
@ -44,12 +105,10 @@ export const trainConsts = {
export class TrainHead extends Container {
arrow: Graphics; // 箭头
pause: Graphics; // 停止
isLeftDirection: boolean; // 是否向左
constructor(direction: string) {
constructor() {
super();
this.arrow = new Graphics();
this.pause = new Graphics();
this.isLeftDirection = direction == 'left';
this.addChild(this.arrow);
this.addChild(this.pause);
}
@ -57,7 +116,7 @@ export class TrainHead extends Container {
this.arrow.clear();
this.pause.clear();
}
doRepaint(bodyWH?: bodyWH) {
doRepaint(direction = 'left', bodyWH?: bodyWH) {
this.clear();
const marginX = trainConsts.marginX;
const pauseW = trainConsts.pauseW;
@ -71,26 +130,39 @@ export class TrainHead extends Container {
-marginX - pauseW - marginX - codeWidth / 2,
-codeHeight / 2,
];
let pausePoint = [-marginX - pauseW - codeWidth / 2, -codeHeight / 2];
if (!this.isLeftDirection) {
arrowPoint = [
codeWidth / 2 + marginX + pauseW + marginX + codeHeight * 0.4,
0,
codeWidth / 2 + marginX + pauseW + marginX,
codeHeight / 2,
codeWidth / 2 + marginX + pauseW + marginX,
let pausePoint = [
-marginX - pauseW / 2 - codeWidth / 2,
-codeHeight / 2,
-marginX - pauseW / 2 - codeWidth / 2,
codeHeight / 2,
];
pausePoint = [marginX + 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;
}
const arrow = this.arrow;
arrow.beginFill(TrainColorEnum.headColor, 1);
arrow.drawPolygon(arrowPoint);
arrow.endFill();
this.pause.beginFill(TrainColorEnum.headColor, 1);
this.pause.drawRect(0, 0, pauseW, codeHeight);
this.pause.endFill();
this.pause.position.set(...pausePoint);
this.pause.lineStyle(pauseW, TrainColorEnum.headColor, 1);
this.pause.moveTo(pausePoint[0], pausePoint[1]);
this.pause.lineTo(pausePoint[2], pausePoint[3]);
}
stop() {
this.arrow.visible = false;
@ -121,23 +193,20 @@ export class TrainBody extends Container {
};
}
doRepaint(datas?: ITrainData): void {
doRepaint(states?: ITrainState): void {
this.clear();
const codeGraph = this.codeGraph;
const codeRact = this.codeRact;
const code = datas?.code;
const code = states?.trainId;
codeGraph.text = code || '01110111';
codeGraph.setVectorFontSize(trainConsts.codeFontSize);
codeGraph.anchor.set(0.5);
const style = {
fill: TrainColorEnum.codeColor,
fontSize: trainConsts.codeFontSize,
padding: 5,
};
codeGraph.style = style;
const { width: codeWidth, height: codeHeight } = this.getBodyWH();
const hasBorder = datas ? datas.hasBorder : true;
if (hasBorder) {
codeRact.visible = true;
codeRact.lineStyle(
trainConsts.borderWidth,
new Color(TrainColorEnum.borderColor)
@ -145,25 +214,56 @@ export class TrainBody extends Container {
codeRact.beginFill(new Color(TrainColorEnum.bodyColor));
codeRact.drawRect(-codeWidth / 2, -codeHeight / 2, codeWidth, codeHeight);
codeRact.endFill();
} else {
codeRact.visible = false;
}
}
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 = 1.5; // 中间
}
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';
headLeft: TrainHead;
headRight: TrainHead;
trainHead: TrainHead;
trainbody: TrainBody;
statusTextMap: Map<string, StatusText> = new Map();
constructor() {
super(Train.Type);
this.trainbody = new TrainBody();
this.headLeft = new TrainHead('left');
this.headRight = new TrainHead('right');
this.addChild(this.headLeft);
this.addChild(this.headRight);
this.trainHead = new TrainHead();
this.addChild(this.trainHead);
this.addChild(this.trainbody);
}
@ -171,40 +271,52 @@ export class Train extends JlGraphic {
return this.getDatas<ITrainData>();
}
doRepaint(): void {
this.trainbody.doRepaint(this.datas);
const bodyWH = this.trainbody.getBodyWH();
this.headLeft.doRepaint(bodyWH);
this.headRight.doRepaint(bodyWH);
// 运行方向控制箭头停止显隐
if (this.datas.trainDirection == 'right') {
this.headLeft.visible = false;
this.headRight.visible = true;
} else {
this.headLeft.visible = true;
this.headRight.visible = false;
get states(): ITrainState {
return this.getStates<ITrainState>();
}
doRepaint(): void {
this.trainbody.doRepaint(this.states);
const bodyWH = this.trainbody.getBodyWH();
let direction = 'left';
if (this.states.direction) {
direction = 'right';
}
this.trainHead.doRepaint(direction, bodyWH);
// this.showStatus('H');
}
stop() {
this.headLeft.stop();
this.headRight.stop();
this.trainHead.stop();
}
run() {
this.headLeft.run();
this.headRight.run();
this.trainHead.run();
}
showStatus(s: string) {
const bodyWH = this.trainbody.getBodyWH();
const textD = new StatusText();
textD.doRepaint(s, bodyWH);
this.addChild(textD);
this.statusTextMap.set(s, textD);
}
hideStatus(s: string) {
const textD = this.statusTextMap.get(s);
if (textD) {
textD.clear();
this.statusTextMap.delete(s);
}
}
}
export class TrainTemplate extends JlGraphicTemplate<Train> {
trainDirection: string;
hasBorder: boolean;
constructor() {
super(Train.Type, {});
this.trainDirection = 'left';
this.hasBorder = true;
constructor(dataTemplate: ITrainData, stateTemplate: ITrainState) {
super(Train.Type, { dataTemplate, stateTemplate });
}
new(): Train {
return new Train();
const train = new Train();
train.loadData(this.datas);
train.loadState(this.states);
return train;
}
}

View File

@ -20,14 +20,14 @@ export interface ITrainDrawOptions {
export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
_Train: Train | null = null;
headLeft: TrainHead;
trainHead: TrainHead;
trainbody: TrainBody;
constructor(app: JlDrawApp) {
super(app, new TrainTemplate(), 'directions_bus_filled', '列车Train');
this.headLeft = new TrainHead('left');
constructor(app: JlDrawApp, template: TrainTemplate) {
super(app, template, 'directions_bus_filled', '不展示');
this.trainHead = new TrainHead();
this.trainbody = new TrainBody();
this.container.addChild(this.headLeft);
this.container.addChild(this.trainHead);
this.container.addChild(this.trainbody);
trainInteraction.init(app);
}
@ -40,11 +40,11 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
}
this.trainbody.doRepaint();
const bodyWH = this.trainbody.getBodyWH();
this.headLeft.doRepaint(bodyWH);
this.trainHead.doRepaint('left', bodyWH);
}
clearCache(): void {
this.headLeft.clear();
this.trainHead.clear();
this.trainbody.clear();
}
@ -66,10 +66,6 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
this.createAndStore(true);
}
prepareData(data: ITrainData): boolean {
const template = this.graphicTemplate;
data.code = '01110111';
data.hasBorder = template.hasBorder;
data.trainDirection = template.trainDirection;
data.transform = this.container.saveTransform();
return true;
}

View File

@ -2168,8 +2168,6 @@ export namespace graphicData {
constructor(data?: any[] | {
common?: CommonInfo;
code?: string;
trainDirection?: string;
hasBorder?: boolean;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
@ -2180,12 +2178,6 @@ export namespace graphicData {
if ("code" in data && data.code != undefined) {
this.code = data.code;
}
if ("trainDirection" in data && data.trainDirection != undefined) {
this.trainDirection = data.trainDirection;
}
if ("hasBorder" in data && data.hasBorder != undefined) {
this.hasBorder = data.hasBorder;
}
}
}
get common() {
@ -2203,23 +2195,9 @@ export namespace graphicData {
set code(value: string) {
pb_1.Message.setField(this, 2, value);
}
get trainDirection() {
return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
}
set trainDirection(value: string) {
pb_1.Message.setField(this, 3, value);
}
get hasBorder() {
return pb_1.Message.getFieldWithDefault(this, 4, false) as boolean;
}
set hasBorder(value: boolean) {
pb_1.Message.setField(this, 4, value);
}
static fromObject(data: {
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
code?: string;
trainDirection?: string;
hasBorder?: boolean;
}): Train {
const message = new Train({});
if (data.common != null) {
@ -2228,20 +2206,12 @@ export namespace graphicData {
if (data.code != null) {
message.code = data.code;
}
if (data.trainDirection != null) {
message.trainDirection = data.trainDirection;
}
if (data.hasBorder != null) {
message.hasBorder = data.hasBorder;
}
return message;
}
toObject() {
const data: {
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
code?: string;
trainDirection?: string;
hasBorder?: boolean;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -2249,12 +2219,6 @@ export namespace graphicData {
if (this.code != null) {
data.code = this.code;
}
if (this.trainDirection != null) {
data.trainDirection = this.trainDirection;
}
if (this.hasBorder != null) {
data.hasBorder = this.hasBorder;
}
return data;
}
serialize(): Uint8Array;
@ -2265,10 +2229,6 @@ export namespace graphicData {
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
if (this.code.length)
writer.writeString(2, this.code);
if (this.trainDirection.length)
writer.writeString(3, this.trainDirection);
if (this.hasBorder != false)
writer.writeBool(4, this.hasBorder);
if (!w)
return writer.getResultBuffer();
}
@ -2284,12 +2244,6 @@ export namespace graphicData {
case 2:
message.code = reader.readString();
break;
case 3:
message.trainDirection = reader.readString();
break;
case 4:
message.hasBorder = reader.readBool();
break;
default: reader.skipField();
}
}