diff --git a/src/api/AlertMock.ts b/src/api/AlertMock.ts index 9e31f90..3823b34 100644 --- a/src/api/AlertMock.ts +++ b/src/api/AlertMock.ts @@ -9,7 +9,6 @@ export function mockLocalDemoTestSet( alertType: string, data: { lineId: number; - rtuId: number; deviceInfos: { deviceName: string; deviceType: string }[]; status: string; groupId?: string; diff --git a/src/components/alarm/alarmInfoEnum.ts b/src/components/alarm/alarmInfoEnum.ts index eaeed2f..51150f1 100644 --- a/src/components/alarm/alarmInfoEnum.ts +++ b/src/components/alarm/alarmInfoEnum.ts @@ -114,7 +114,8 @@ export const GuardConfigTypeData = { }, }; -export function isArraysEqual(arr1: string[], arr2: string[]) { +type findType = string | number; +export function isArraysEqual(arr1: findType[], arr2: findType[]) { if (arr1.length !== arr2.length) { return false; } diff --git a/src/components/alarm/setAlarmText.vue b/src/components/alarm/setAlarmText.vue index 585165c..d0f3ae6 100644 --- a/src/components/alarm/setAlarmText.vue +++ b/src/components/alarm/setAlarmText.vue @@ -19,14 +19,6 @@ lazy-rules :rules="[(val) => val || '请输入线路ID!']" /> - ({ lineId: '', - rtuId: '', alertType: '', deviceInfos: [], status: '', @@ -221,7 +211,6 @@ async function onSubmit() { try { const params = { lineId: +setAlartTextData.value.lineId, - rtuId: +setAlartTextData.value.rtuId, deviceInfos: setAlartTextData.value.deviceInfos, status: setAlartTextData.value.status, groupId: setAlartTextData.value.groupId, @@ -266,7 +255,6 @@ function clearSelect() { function onReset() { setAlartTextData.value = { lineId: lineStore.lineId as unknown as string, - rtuId: '', alertType: '', deviceInfos: [], status: '', diff --git a/src/components/draw-app/DrawProperties.vue b/src/components/draw-app/DrawProperties.vue index b8b0662..ffeaaba 100644 --- a/src/components/draw-app/DrawProperties.vue +++ b/src/components/draw-app/DrawProperties.vue @@ -81,6 +81,11 @@ + @@ -90,6 +95,8 @@ diff --git a/src/components/draw-app/properties/PlatformProperty.vue b/src/components/draw-app/properties/PlatformProperty.vue index f94a60e..c89bb31 100644 --- a/src/components/draw-app/properties/PlatformProperty.vue +++ b/src/components/draw-app/properties/PlatformProperty.vue @@ -1,6 +1,6 @@ @@ -69,7 +78,7 @@ import { Platform } from 'src/graphics/platform/Platform'; import { Section } from 'src/graphics/section/Section'; import { Station } from 'src/graphics/station/Station'; import { useDrawStore } from 'src/stores/draw-store'; -import { computed, ref } from 'vue'; +import { computed, onMounted, ref } from 'vue'; const drawStore = useDrawStore(); const { data: platformModel, onUpdate } = useFormData( @@ -108,4 +117,20 @@ const optionsUpAndDown = [ { label: '上行', value: true }, { label: '下行', value: false }, ]; +const centralizedStations = ref<{ label: string; value: number }[]>([]); + +onMounted(() => { + const stations = drawStore + .getDrawApp() + .queryStore.queryByType(Station.Type); + centralizedStations.value = [{ label: '', value: 0 }]; + stations.forEach((station) => { + if (station.datas.concentrationStations || station.datas.depots) { + centralizedStations.value.push({ + label: station.datas.name, + value: station.datas.id, + }); + } + }); +}); diff --git a/src/components/draw-app/properties/SectionProperty.vue b/src/components/draw-app/properties/SectionProperty.vue index 19ab547..5413f25 100644 --- a/src/components/draw-app/properties/SectionProperty.vue +++ b/src/components/draw-app/properties/SectionProperty.vue @@ -1,6 +1,6 @@ + @@ -77,9 +83,10 @@ import { useFormData } from 'src/components/DrawAppFormUtils'; import { SectionData } from 'src/drawApp/graphics/SectionInteraction'; import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting'; import { Section, SectionType } from 'src/graphics/section/Section'; +import { Station } from 'src/graphics/station/Station'; import { Turnout } from 'src/graphics/turnout/Turnout'; import { useDrawStore } from 'src/stores/draw-store'; -import { computed } from 'vue'; +import { computed, onMounted, ref } from 'vue'; const drawStore = useDrawStore(); const { data: sectionModel, onUpdate } = useFormData( @@ -140,4 +147,21 @@ const axleCountingRelations = computed(() => { (relation) => relation.getOtherGraphic(section).datas.code ); }); + +const centralizedStations = ref<{ label: string; value: number }[]>([]); + +onMounted(() => { + const stations = drawStore + .getDrawApp() + .queryStore.queryByType(Station.Type); + centralizedStations.value = [{ label: '', value: 0 }]; + stations.forEach((station) => { + if (station.datas.concentrationStations || station.datas.depots) { + centralizedStations.value.push({ + label: station.datas.name, + value: station.datas.id, + }); + } + }); +}); diff --git a/src/components/draw-app/properties/SignalProperty.vue b/src/components/draw-app/properties/SignalProperty.vue index 9f58746..c1da632 100644 --- a/src/components/draw-app/properties/SignalProperty.vue +++ b/src/components/draw-app/properties/SignalProperty.vue @@ -1,6 +1,6 @@ @@ -61,10 +70,11 @@ import { useFormData } from 'src/components/DrawAppFormUtils'; import { SignalData } from 'src/drawApp/graphics/SignalInteraction'; import { Section } from 'src/graphics/section/Section'; +import { Station } from 'src/graphics/station/Station'; import { Turnout } from 'src/graphics/turnout/Turnout'; import { graphicData } from 'src/protos/stationLayoutGraphics'; import { useDrawStore } from 'src/stores/draw-store'; -import { computed } from 'vue'; +import { computed, onMounted, ref } from 'vue'; const drawStore = useDrawStore(); const { data: signalModel, onUpdate } = useFormData( @@ -106,4 +116,20 @@ const CoordinateSystemOptions = [ { label: '正线', value: 'MAIN_LINE' }, { label: '换线', value: 'TRANSFER' }, ]; +const centralizedStations = ref<{ label: string; value: number }[]>([]); + +onMounted(() => { + const stations = drawStore + .getDrawApp() + .queryStore.queryByType(Station.Type); + centralizedStations.value = [{ label: '', value: 0 }]; + stations.forEach((station) => { + if (station.datas.concentrationStations || station.datas.depots) { + centralizedStations.value.push({ + label: station.datas.name, + value: station.datas.id, + }); + } + }); +}); diff --git a/src/components/draw-app/properties/StationProperty.vue b/src/components/draw-app/properties/StationProperty.vue index e834499..fea0c31 100644 --- a/src/components/draw-app/properties/StationProperty.vue +++ b/src/components/draw-app/properties/StationProperty.vue @@ -19,41 +19,57 @@ lazy-rules autogrow /> + + +
公里标配置
+ + +
+
- - - + @@ -61,17 +77,16 @@ diff --git a/src/components/draw-app/properties/TurnoutProperty.vue b/src/components/draw-app/properties/TurnoutProperty.vue index 4cdd50e..5a34933 100644 --- a/src/components/draw-app/properties/TurnoutProperty.vue +++ b/src/components/draw-app/properties/TurnoutProperty.vue @@ -1,48 +1,52 @@ @@ -74,9 +87,10 @@ import { useFormData } from 'src/components/DrawAppFormUtils'; import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction'; import { Section } from 'src/graphics/section/Section'; +import { Station } from 'src/graphics/station/Station'; import { Turnout } from 'src/graphics/turnout/Turnout'; import { useDrawStore } from 'src/stores/draw-store'; -import { computed } from 'vue'; +import { computed, onMounted, ref } from 'vue'; const drawStore = useDrawStore(); const { data: turnoutModel, onUpdate } = useFormData( @@ -124,4 +138,21 @@ const turnoutRelations = computed(() => { }(${relation.getOtherRelationParam(turnout).param})` ); }); + +const centralizedStations = ref<{ label: string; value: number }[]>([]); + +onMounted(() => { + const stations = drawStore + .getDrawApp() + .queryStore.queryByType(Station.Type); + centralizedStations.value = [{ label: '', value: 0 }]; + stations.forEach((station) => { + if (station.datas.concentrationStations || station.datas.depots) { + centralizedStations.value.push({ + label: station.datas.name, + value: station.datas.id, + }); + } + }); +}); diff --git a/src/drawApp/graphics/ConcentrationDividingLineInteraction.ts b/src/drawApp/graphics/ConcentrationDividingLineInteraction.ts new file mode 100644 index 0000000..b6bd21b --- /dev/null +++ b/src/drawApp/graphics/ConcentrationDividingLineInteraction.ts @@ -0,0 +1,77 @@ +import * as pb_1 from 'google-protobuf'; +import { GraphicDataBase } from './GraphicDataBase'; +import { + IConcentrationDividingLineData, + ConcentrationDividingLine, +} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine'; +import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { IPointData } from 'pixi.js'; + +export class ConcentrationDividingLineData + extends GraphicDataBase + implements IConcentrationDividingLineData +{ + constructor(data?: graphicData.ConcentrationDividingLine) { + let concentrationDividingLine; + if (!data) { + concentrationDividingLine = new graphicData.ConcentrationDividingLine({ + common: GraphicDataBase.defaultCommonInfo( + ConcentrationDividingLine.Type + ), + }); + } else { + concentrationDividingLine = data; + } + super(concentrationDividingLine); + } + public get data(): graphicData.ConcentrationDividingLine { + return this.getData(); + } + get code(): string { + return this.data.code; + } + set code(v: string) { + this.data.code = v; + } + get points(): IPointData[] { + return this.data.points; + } + set points(points: IPointData[]) { + this.data.points = points.map( + (p) => new graphicData.Point({ x: p.x, y: p.y }) + ); + } + get refLeftStationId(): number { + return this.data.refLeftStationId; + } + set refLeftStationId(v: number) { + this.data.refLeftStationId = v; + } + get refRightStationId(): number { + return this.data.refRightStationId; + } + set refRightStationId(v: number) { + this.data.refRightStationId = v; + } + get nodeConWithSecs(): graphicData.NodeConWithSec[] { + return this.data.nodeConWithSecs; + } + set nodeConWithSecs(nodes: graphicData.NodeConWithSec[]) { + this.data.nodeConWithSecs = nodes; + } + get isOtherLineConcentrationDividingLine(): boolean { + return this.data.isOtherLineConcentrationDividingLine; + } + set isOtherLineConcentrationDividingLine(v: boolean) { + this.data.isOtherLineConcentrationDividingLine = v; + } + clone(): ConcentrationDividingLineData { + return new ConcentrationDividingLineData(this.data.cloneMessage()); + } + copyFrom(data: ConcentrationDividingLineData): void { + pb_1.Message.copyInto(data.data, this.data); + } + eq(other: ConcentrationDividingLineData): boolean { + return pb_1.Message.equals(this.data, other.data); + } +} diff --git a/src/drawApp/graphics/PlatformInteraction.ts b/src/drawApp/graphics/PlatformInteraction.ts index 4fc37d6..19e0cdc 100644 --- a/src/drawApp/graphics/PlatformInteraction.ts +++ b/src/drawApp/graphics/PlatformInteraction.ts @@ -71,6 +71,12 @@ export class PlatformData extends GraphicDataBase implements IPlatformData { set refSectionId(v: number) { this.data.refSectionId = v; } + get centralizedStation(): number { + return this.data.centralizedStationId; + } + set centralizedStation(v: number) { + this.data.centralizedStationId = v; + } clone(): PlatformData { return new PlatformData(this.data.cloneMessage()); diff --git a/src/drawApp/graphics/SectionInteraction.ts b/src/drawApp/graphics/SectionInteraction.ts index 852978b..2906369 100644 --- a/src/drawApp/graphics/SectionInteraction.ts +++ b/src/drawApp/graphics/SectionInteraction.ts @@ -77,6 +77,12 @@ export class SectionData extends GraphicDataBase implements ISectionData { set turning(v: boolean) { this.data.turning = v; } + get centralizedStation(): number { + return this.data.centralizedStationId; + } + set centralizedStation(v: number) { + this.data.centralizedStationId = v; + } clone(): SectionData { return new SectionData(this.data.cloneMessage()); } diff --git a/src/drawApp/graphics/SignalInteraction.ts b/src/drawApp/graphics/SignalInteraction.ts index a5e6a0f..402a84d 100644 --- a/src/drawApp/graphics/SignalInteraction.ts +++ b/src/drawApp/graphics/SignalInteraction.ts @@ -62,6 +62,12 @@ export class SignalData extends GraphicDataBase implements ISignalData { set kilometerSystem(v: KilometerSystem) { this.data.kilometerSystem = new graphicData.KilometerSystem(v); } + get centralizedStation(): number { + return this.data.centralizedStationId; + } + set centralizedStation(v: number) { + this.data.centralizedStationId = v; + } clone(): SignalData { return new SignalData(this.data.cloneMessage()); } diff --git a/src/drawApp/graphics/StationInteraction.ts b/src/drawApp/graphics/StationInteraction.ts index 95fc6c1..7442d84 100644 --- a/src/drawApp/graphics/StationInteraction.ts +++ b/src/drawApp/graphics/StationInteraction.ts @@ -68,6 +68,18 @@ export class StationData extends GraphicDataBase implements IStationData { set name(v: string) { this.data.name = v; } + get manageStations(): number[] { + return this.data.manageStations; + } + set manageStations(v: number[]) { + this.data.manageStations = v; + } + get depots(): boolean { + return this.data.depots; + } + set depots(v: boolean) { + this.data.depots = v; + } clone(): StationData { return new StationData(this.data.cloneMessage()); } diff --git a/src/drawApp/graphics/TurnoutInteraction.ts b/src/drawApp/graphics/TurnoutInteraction.ts index 8e0fd4c..2a1b808 100644 --- a/src/drawApp/graphics/TurnoutInteraction.ts +++ b/src/drawApp/graphics/TurnoutInteraction.ts @@ -333,6 +333,12 @@ export class TurnoutData extends GraphicDataBase implements ITurnoutData { (v) => new graphicData.KilometerSystem(v) ); } + get centralizedStation(): number { + return this.data.centralizedStationId; + } + set centralizedStation(v: number) { + this.data.centralizedStationId = v; + } clone(): TurnoutData { return new TurnoutData(this.data.cloneMessage()); } diff --git a/src/drawApp/index.ts b/src/drawApp/index.ts index efeb577..2592cde 100644 --- a/src/drawApp/index.ts +++ b/src/drawApp/index.ts @@ -24,6 +24,12 @@ import { SignalState, } from './graphics/SignalInteraction'; import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { + ConcentrationDividingLine, + ConcentrationDividingLineTemplate, +} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine'; +import { ConcentrationDividingLineData } from './graphics/ConcentrationDividingLineInteraction'; +import { ConcentrationDividingLineDraw } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLineDrawAssistant'; import { Rect, RectTemplate } from 'src/graphics/rect/Rect'; import { RectDraw } from 'src/graphics/rect/RectDrawAssistant'; import { RectData } from './graphics/RectInteraction'; @@ -257,7 +263,13 @@ export function initDrawApp(): IDrawApp { new AxleCountingTemplate(new AxleCountingData()) ), new SeparatorDraw(app, new SeparatorTemplate(new SeparatorData())), - DrawSignalInteraction.init(app); + new ConcentrationDividingLineDraw( + app, + new ConcentrationDividingLineTemplate( + new ConcentrationDividingLineData() + ) + ); + DrawSignalInteraction.init(app); } else { new StationLineDraw(app, new StationLineTemplate(new StationLineData())), new RectDraw(app, new RectTemplate(new RectData())), @@ -364,6 +376,11 @@ export function saveDrawDatas(app: IDrawApp) { } else if (LogicSection.Type === g.type) { const logicSectionData = (g as LogicSection).saveData(); storage.logicSections.push((logicSectionData as LogicSectionData).data); + } else if (g instanceof ConcentrationDividingLine) { + const concentrationDividingLineData = g.saveData(); + storage.concentrationDividingLines.push( + (concentrationDividingLineData as ConcentrationDividingLineData).data + ); } }); // storage.Platforms.forEach((item) => { @@ -517,6 +534,9 @@ export async function loadDrawDatas(): Promise { storage.trainWindows.forEach((trainWindow) => { datas.push(new TrainWindowData(trainWindow)); }); + storage.concentrationDividingLines.forEach((concentrationDividingLine) => { + datas.push(new ConcentrationDividingLineData(concentrationDividingLine)); + }); return Promise.resolve({ canvasProperty: storage.canvas, datas: datas, diff --git a/src/graphics/axleCounting/AxleCountingDrawAssistant.ts b/src/graphics/axleCounting/AxleCountingDrawAssistant.ts index 42b2f94..519a30d 100644 --- a/src/graphics/axleCounting/AxleCountingDrawAssistant.ts +++ b/src/graphics/axleCounting/AxleCountingDrawAssistant.ts @@ -43,7 +43,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant< > { codeGraph: AxleCounting; constructor(app: IDrawApp, template: AxleCountingTemplate) { - super(app, template, 'sym_o_circle', '不展示'); + super(app, template, 'sym_o_circle', '计轴'); this.codeGraph = this.graphicTemplate.new(); this.container.addChild(this.codeGraph); AxleCountingInteraction.init(app); diff --git a/src/graphics/concentrationDividingLine/ConcentrationDividingLine.ts b/src/graphics/concentrationDividingLine/ConcentrationDividingLine.ts new file mode 100644 index 0000000..eb38268 --- /dev/null +++ b/src/graphics/concentrationDividingLine/ConcentrationDividingLine.ts @@ -0,0 +1,224 @@ +import { IPointData } from 'pixi.js'; +import { + GraphicData, + JlGraphic, + JlGraphicTemplate, + calculateDistanceFromPointToLine, + getRectangleCenter, + ILineGraphic, +} from 'jl-graphic'; +import { SectionGraphic } from './SectionGraphic'; +import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { Section, SectionType } from '../section/Section'; +import { arePolylinesIntersect } from './ConcentrationDividingLineUtils'; +import { createRelatedRefProto } from '../CommonGraphics'; +import { Turnout,TurnoutPort } from '../turnout/Turnout'; + +export interface IConcentrationDividingLineData extends GraphicData { + get code(): string; // 编号 + set code(v: string); + get points(): IPointData[]; // 线坐标点 + set points(points: IPointData[]); + get refLeftStationId(): number; //左边关联的集中站id + set refLeftStationId(v: number); + get refRightStationId(): number; //右边关联的集中站id + set refRightStationId(v: number); + get nodeConWithSecs(): graphicData.NodeConWithSec[]; // 集中区分割线与区段的交点 + set nodeConWithSecs(nodes: graphicData.NodeConWithSec[]); + get isOtherLineConcentrationDividingLine(): boolean; //集中区分割线绘制在其它线的边界处 + set isOtherLineConcentrationDividingLine(v: boolean); + clone(): IConcentrationDividingLineData; + copyFrom(data: IConcentrationDividingLineData): void; + eq(other: IConcentrationDividingLineData): boolean; +} + +export const ConcentrationDividingLineConsts = { + lineColor: '#f00', + lineWidth: 2, +}; + +enum devicePort { + 'A', + 'B', + 'C', +} + +export class ConcentrationDividingLine + extends JlGraphic + implements ILineGraphic +{ + static Type = 'ConcentrationDividingLine'; + lineGraphic: SectionGraphic; + + constructor() { + super(ConcentrationDividingLine.Type); + this.lineGraphic = new SectionGraphic(); + this.transformSave = true; + this.addChild(this.lineGraphic); + } + + get datas(): IConcentrationDividingLineData { + return this.getDatas(); + } + + get linePoints(): IPointData[] { + return this.datas.points; + } + set linePoints(points: IPointData[]) { + const old = this.datas.clone(); + old.points = points; + this.updateData(old); + } + + doRepaint() { + if (this.datas.points.length < 2) { + throw new Error('Link坐标数据异常'); + } + this.lineGraphic.clear(); + this.lineGraphic.points = this.datas.points; + this.lineGraphic.lineStyle( + ConcentrationDividingLineConsts.lineWidth, + ConcentrationDividingLineConsts.lineColor + ); + this.lineGraphic.paint(); + } + buildRelation() { + const nodeConWithSecs: graphicData.NodeConWithSec[] = []; + const sections = this.queryStore + .queryByType
(Section.Type) + .filter((g) => g.datas.sectionType == SectionType.Physical); + const hasNodeSection = new Map(); + sections.forEach((section) => { + const changeSectionData = section.datas.points.map((point) => + section.localToCanvasPoint(point) + ); + const changeConcentrationDividingLineData = this.datas.points.map( + (point) => this.localToCanvasPoint(point) + ); + const hasNode = arePolylinesIntersect( + changeSectionData, + changeConcentrationDividingLineData + ); + if (hasNode) { + const minA = calculateDistanceFromPointToLine( + hasNode.segment2[0], + hasNode.segment2[1], + section.localToCanvasPoint(section.getStartPoint()) + ); + const minB = calculateDistanceFromPointToLine( + hasNode.segment2[0], + hasNode.segment2[1], + section.localToCanvasPoint(section.getEndPoint()) + ); + const relationParam = minA > minB ? TurnoutPort.B : TurnoutPort.A; + const portRefOtherDevice = + relationParam == 'A' ? section.datas.paRef : section.datas.pbRef; + if ( + portRefOtherDevice?.id && + !hasNodeSection.get(section.id) && + !hasNodeSection.get(portRefOtherDevice.id) + ) { + const refDevice = this.queryStore.queryById( + portRefOtherDevice?.id + ); + const [leftDevice, rightDevice] = + refDevice.localToCanvasPoint( + getRectangleCenter(refDevice.getLocalBounds()) + ).x < + section.localToCanvasPoint( + getRectangleCenter(section.getLocalBounds()) + ).x + ? [ + { + device: refDevice, + port: devicePort[ + portRefOtherDevice.devicePort + ] as TurnoutPort, + }, + { device: section, port: relationParam }, + ] + : [ + { device: section, port: relationParam }, + { + device: refDevice, + port: devicePort[ + portRefOtherDevice.devicePort + ] as TurnoutPort, + }, + ]; + hasNodeSection.set(leftDevice.device.id, '1'); + hasNodeSection.set(rightDevice.device.id, '1'); + nodeConWithSecs.push( + new graphicData.NodeConWithSec({ + leftSection: createRelatedRefProto( + leftDevice.device.type, + leftDevice.device.id, + leftDevice.port + ), + rightSection: createRelatedRefProto( + rightDevice.device.type, + rightDevice.device.id, + rightDevice.port + ), + }) + ); + } else if (!hasNodeSection.get(section.id) && !portRefOtherDevice?.id) { + const [leftSectionId, rightSectionId] = + relationParam === 'A' + ? [undefined, section.id] + : [section.id, undefined]; + hasNodeSection.set(section.id, '1'); + if (leftSectionId == undefined) { + nodeConWithSecs.push( + new graphicData.NodeConWithSec({ + leftSection: undefined, + rightSection: createRelatedRefProto( + Section.Type, + rightSectionId, + TurnoutPort.A + ), + }) + ); + } else { + nodeConWithSecs.push( + new graphicData.NodeConWithSec({ + leftSection: createRelatedRefProto( + Section.Type, + leftSectionId, + TurnoutPort.B + ), + rightSection: undefined, + }) + ); + } + } + } + }); + nodeConWithSecs.sort((a, b) => { + const sectionAId = a.leftSection ? a.leftSection.id : a.rightSection.id; + const sectionA = this.queryStore.queryById
(sectionAId); + const sectionBId = b.leftSection ? b.leftSection.id : b.rightSection.id; + const sectionB = this.queryStore.queryById
(sectionBId); + return ( + sectionA.localToCanvasPoint( + getRectangleCenter(sectionA.getLocalBounds()) + ).y - + sectionB.localToCanvasPoint( + getRectangleCenter(sectionB.getLocalBounds()) + ).y + ); + }); + this.datas.nodeConWithSecs = nodeConWithSecs; + } +} + +export class ConcentrationDividingLineTemplate extends JlGraphicTemplate { + constructor(dataTemplate: IConcentrationDividingLineData) { + super(ConcentrationDividingLine.Type, { dataTemplate }); + } + new() { + const g = new ConcentrationDividingLine(); + g.loadData(this.datas); + return g; + } +} diff --git a/src/graphics/concentrationDividingLine/ConcentrationDividingLineDrawAssistant.ts b/src/graphics/concentrationDividingLine/ConcentrationDividingLineDrawAssistant.ts new file mode 100644 index 0000000..2245a2d --- /dev/null +++ b/src/graphics/concentrationDividingLine/ConcentrationDividingLineDrawAssistant.ts @@ -0,0 +1,212 @@ +import { + IGraphicApp, + GraphicDrawAssistant, + GraphicInteractionPlugin, + IDrawApp, + JlGraphic, + linePoint, + PolylineEditPlugin, + addWayPoint, + clearWayPoint, + MenuItemOptions, + ContextMenu +} from 'jl-graphic'; +import { + IConcentrationDividingLineData, + ConcentrationDividingLine, + ConcentrationDividingLineConsts, + ConcentrationDividingLineTemplate, +} from './ConcentrationDividingLine'; +import { + DisplayObject, + FederatedMouseEvent, + Graphics, + IHitArea, + Point, +} from 'pixi.js'; +import { getWayLineIndex } from '../polygon/PolygonUtils'; + +export class ConcentrationDividingLineDraw extends GraphicDrawAssistant< + ConcentrationDividingLineTemplate, + IConcentrationDividingLineData +> { + points: Point[] = []; + graphic = new Graphics(); + + constructor(app: IDrawApp, template: ConcentrationDividingLineTemplate) { + super(app, template, 'sym_o_timeline', '集中区分割线'); + this.container.addChild(this.graphic); + + ConcentrationDividingLinePointEditPlugin.init(app, this); + } + + bind(): void { + super.bind(); + } + unbind(): void { + super.unbind(); + } + + onLeftDown(e: FederatedMouseEvent): void { + const { x, y } = this.toCanvasCoordinates(e.global); + const p = new Point(x, y); + this.points.push(p); + } + + onRightClick(): void { + if (this.points.length < 2) { + this.finish(); + return; + } + this.createAndStore(true); + } + + onEsc(): void { + if (this.points.length < 2) { + this.finish(); + return; + } + this.createAndStore(true); + } + + redraw(p: Point): void { + if (this.points.length < 1) return; + this.graphic.clear(); + this.graphic.lineStyle( + ConcentrationDividingLineConsts.lineWidth, + ConcentrationDividingLineConsts.lineColor + ); + + const ps = [...this.points]; + ps.push(p); + ps.forEach((p, i) => { + if (i !== 0) { + this.graphic.lineTo(p.x, p.y); + } else { + this.graphic.moveTo(p.x, p.y); + } + }); + } + + prepareData(data: IConcentrationDividingLineData): boolean { + if (this.points.length < 2) { + console.log('ConcentrationDividingLine绘制因点不够取消绘制'); + return false; + } + data.points = this.points; + return true; + } + + clearCache(): void { + this.points = []; + this.graphic.clear(); + } +} + +export class ConcentrationDividingLineGraphicHitArea implements IHitArea { + concentrationDividingLine: ConcentrationDividingLine; + constructor(concentrationDividingLine: ConcentrationDividingLine) { + this.concentrationDividingLine = concentrationDividingLine; + } + contains(x: number, y: number): boolean { + for ( + let i = 1; + i < this.concentrationDividingLine.datas.points.length; + i++ + ) { + const p1 = this.concentrationDividingLine.datas.points[i - 1]; + const p2 = this.concentrationDividingLine.datas.points[i]; + if ( + linePoint(p1, p2, { x, y }, ConcentrationDividingLineConsts.lineWidth) + ) { + return true; + } + } + return false; + } +} + +const addWaypointConfig: MenuItemOptions = { + name: '添加路径点', +}; +const clearWaypointsConfig: MenuItemOptions = { + name: '清除所有路径点', +}; +const ConcentrationDividingLineEditMenu: ContextMenu = ContextMenu.init({ + name: '集中区分割线编辑菜单', + groups: [ + { + items: [addWaypointConfig, clearWaypointsConfig], + }, + ], +}); + +export class ConcentrationDividingLinePointEditPlugin extends GraphicInteractionPlugin { + static Name = 'ConcentrationDividingLinePointDrag'; + drawAssistant: ConcentrationDividingLineDraw; + + constructor(app: IGraphicApp, da: ConcentrationDividingLineDraw) { + super(ConcentrationDividingLinePointEditPlugin.Name, app); + this.drawAssistant = da; + app.registerMenu(ConcentrationDividingLineEditMenu); + } + static init(app: IGraphicApp, da: ConcentrationDividingLineDraw) { + return new ConcentrationDividingLinePointEditPlugin(app, da); + } + filter(...grahpics: JlGraphic[]): ConcentrationDividingLine[] | undefined { + return grahpics.filter( + (g) => g.type == ConcentrationDividingLine.Type + ) as ConcentrationDividingLine[]; + } + bind(g: ConcentrationDividingLine): void { + g.lineGraphic.eventMode = 'static'; + g.lineGraphic.cursor = 'pointer'; + g.lineGraphic.hitArea = new ConcentrationDividingLineGraphicHitArea(g); + g.transformSave = true; + g.on('selected', this.onSelected, this); + g.on('unselected', this.onUnselected, this); + g.on('_rightclick', this.onContextMenu, this); + } + unbind(g: ConcentrationDividingLine): void { + g.off('selected', this.onSelected, this); + g.off('unselected', this.onUnselected, this); + g.off('_rightclick', this.onContextMenu, this); + } + onContextMenu(e: FederatedMouseEvent) { + const target = e.target as DisplayObject; + const concentrationDividingLine = + target.getGraphic() as ConcentrationDividingLine; + this.app.updateSelected(concentrationDividingLine); + const p = concentrationDividingLine.screenToLocalPoint(e.global); + addWaypointConfig.handler = () => { + const linePoints = concentrationDividingLine.linePoints; + const { start, end } = getWayLineIndex(linePoints, p); + addWayPoint(concentrationDividingLine, false, start, end, p); + }; + clearWaypointsConfig.handler = () => { + clearWayPoint(concentrationDividingLine, false); + }; + ConcentrationDividingLineEditMenu.open(e.global); + } + onSelected(g: DisplayObject): void { + const concentrationDividingLine = g as ConcentrationDividingLine; + let lep = concentrationDividingLine.getAssistantAppend( + PolylineEditPlugin.Name + ); + if (!lep) { + lep = new PolylineEditPlugin(concentrationDividingLine); + concentrationDividingLine.addAssistantAppend(lep); + } + lep.showAll(); + } + onUnselected(g: DisplayObject): void { + const concentrationDividingLine = g as ConcentrationDividingLine; + const lep = + concentrationDividingLine.getAssistantAppend( + PolylineEditPlugin.Name + ); + if (lep) { + lep.hideAll(); + } + } +} diff --git a/src/graphics/concentrationDividingLine/ConcentrationDividingLineUtils.ts b/src/graphics/concentrationDividingLine/ConcentrationDividingLineUtils.ts new file mode 100644 index 0000000..ead0b28 --- /dev/null +++ b/src/graphics/concentrationDividingLine/ConcentrationDividingLineUtils.ts @@ -0,0 +1,195 @@ +import { IPointData } from 'pixi.js'; +import { Section } from '../section/Section'; +import { Turnout } from '../turnout/Turnout'; +import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { IDrawApp, JlGraphic } from 'jl-graphic'; +import { GraphicDataBase } from 'src/drawApp/graphics/GraphicDataBase'; +import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction'; +import { SectionData } from 'src/drawApp/graphics/SectionInteraction'; +import { SignalData } from 'src/drawApp/graphics/SignalInteraction'; +import { Signal } from '../signal/Signal'; +import { Platform } from '../platform/Platform'; +import { PlatformData } from 'src/drawApp/graphics/PlatformInteraction'; + +//判断线段与线段有木有交点 +export function isSegmentsIntersect( + segment1: IPointData[], + segment2: IPointData[] +) { + const [p1, p2] = segment1; + const [p3, p4] = segment2; + // 判断包围盒是否相交 + if ( + Math.max(p1.x, p2.x) < Math.min(p3.x, p4.x) || + Math.min(p1.x, p2.x) > Math.max(p3.x, p4.x) || + Math.max(p1.y, p2.y) < Math.min(p3.y, p4.y) || + Math.min(p1.y, p2.y) > Math.max(p3.y, p4.y) + ) { + return false; + } + // 计算向量叉积 + const cross1 = crossProduct(p3, p1, p4); + const cross2 = crossProduct(p3, p2, p4); + const cross3 = crossProduct(p1, p3, p2); + const cross4 = crossProduct(p1, p4, p2); + if (cross1 * cross2 < 0 && cross3 * cross4 < 0) { + return true; + } + + return false; +} + +function crossProduct(p1: IPointData, p2: IPointData, p3: IPointData) { + return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y); +} + +export function getSegmentsFromPolyline(polyline: IPointData[]) { + const segments = []; + + for (let i = 0; i < polyline.length - 1; i++) { + const segment = [polyline[i], polyline[i + 1]]; + segments.push(segment); + } + + return segments; +} + +//判断折线与折线有木有交点 +export function arePolylinesIntersect( + polyline1: IPointData[], + polyline2: IPointData[] +) { + const segments1 = getSegmentsFromPolyline(polyline1); + const segments2 = getSegmentsFromPolyline(polyline2); + + for (const segment1 of segments1) { + for (const segment2 of segments2) { + if (isSegmentsIntersect(segment1, segment2)) { + return { hasnode: true, segment1, segment2 }; + } + } + } + + return false; +} + +//获取指定区间内的物理区段和道岔 +export function findContainDevice( + refDevice: Section | Turnout, + refDevicePort: graphicData.RelatedRef.DevicePort, + containDeviceIds: number[], + drawApp: IDrawApp +) { + const devicePort = graphicData.RelatedRef.DevicePort; + containDeviceIds.push(refDevice.id); + switch (true) { + case refDevice instanceof Section: + const sectionPaorbRef = + refDevicePort == devicePort.B + ? refDevice.datas.paRef + : refDevice.datas.pbRef; + if (sectionPaorbRef && !containDeviceIds.includes(sectionPaorbRef.id)) { + const pbRefDevice = drawApp.queryStore.queryById
( + sectionPaorbRef.id + ); + findContainDevice( + pbRefDevice, + sectionPaorbRef.devicePort, + containDeviceIds, + drawApp + ); + } + break; + //道岔需要分路--实际的走向 + case refDevice instanceof Turnout: + const otherPorts = [devicePort.A, devicePort.B, devicePort.C].filter( + (port) => port !== refDevicePort + ); + otherPorts.forEach((port) => { + switch (port) { + case devicePort.A: + const turnoutPaRef = refDevice.datas.paRef; + if (turnoutPaRef && !containDeviceIds.includes(turnoutPaRef.id)) { + const paRefDevice = drawApp.queryStore.queryById< + Section | Turnout + >(turnoutPaRef.id); + findContainDevice( + paRefDevice, + turnoutPaRef.devicePort, + containDeviceIds, + drawApp + ); + } + break; + case devicePort.B: + const turnoutPbRef = refDevice.datas.pbRef; + if (turnoutPbRef && !containDeviceIds.includes(turnoutPbRef.id)) { + const pbRefDevice = drawApp.queryStore.queryById< + Section | Turnout + >(turnoutPbRef.id); + findContainDevice( + pbRefDevice, + turnoutPbRef.devicePort, + containDeviceIds, + drawApp + ); + } + break; + case devicePort.C: + const turnoutPcRef = (refDevice as Turnout).datas.pcRef; + if (turnoutPcRef && !containDeviceIds.includes(turnoutPcRef.id)) { + const pcRefDevice = drawApp.queryStore.queryById< + Section | Turnout + >(turnoutPcRef.id); + findContainDevice( + pcRefDevice, + turnoutPcRef.devicePort, + containDeviceIds, + drawApp + ); + } + break; + } + }); + break; + } +} + +export function handleCentralizedStationsData( + devices: JlGraphic[], + centralizedStation: number +) { + interface GraphicData { + centralizedStation: number; + } + const dataMap = new Map([ + [Turnout.Type, new TurnoutData()], + [Section.Type, new SectionData()], + [Signal.Type, new SignalData()], + [Platform.Type, new PlatformData()], + ]); + devices.forEach((device) => { + const data = dataMap.get(device.type); + if (data) { + data.copyFrom(device.saveData()); + const dataCopy = data as GraphicDataBase & GraphicData; + dataCopy.centralizedStation = centralizedStation; + device.updateData(data); + } + }); +} + +//找到公共的元素 +type findType = string | number; +export function findCommonElements(arrays: findType[][]) { + if (arrays.length === 0) { + return []; + } + const commonElements: findType[] = []; + arrays[0].forEach((element) => { + if (arrays.every((arr) => arr.includes(element))) { + commonElements.push(element); + } + }); + return commonElements; +} diff --git a/src/graphics/concentrationDividingLine/SectionGraphic.ts b/src/graphics/concentrationDividingLine/SectionGraphic.ts new file mode 100644 index 0000000..c0b13e0 --- /dev/null +++ b/src/graphics/concentrationDividingLine/SectionGraphic.ts @@ -0,0 +1,57 @@ +import { Graphics, IPointData } from 'pixi.js'; +import { assertBezierPoints, convertToBezierParams } from 'jl-graphic'; + +export enum DevicePort { + A = 'A', + B = 'B', + C = 'C', +} + +export class SectionGraphic extends Graphics { + static Type = 'SectionGraphic'; + private _points: IPointData[] = []; + public get points(): IPointData[] { + return this._points; + } + public set points(value: IPointData[]) { + if (!this.isCurve) { + if (value.length < 2) { + throw Error('Polyline must have at least 2 points'); + } + } else { + assertBezierPoints(value); + } + this._points = value; + } + + private _segmentsCount = 10; + public get segmentsCount(): number { + return this._segmentsCount; + } + public set segmentsCount(value: number) { + if (value < 1) { + throw Error('segmentsCount must be at least 1'); + } + this._segmentsCount = value; + } + + isCurve = false; + + constructor() { + super(); + } + + paint() { + if (this.isCurve) { + const bps = convertToBezierParams(this.points); + bps.forEach((bp) => { + this.drawBezierCurve(bp.p1, bp.p2, bp.cp1, bp.cp2, this.segmentsCount); + }); + } else { + this.moveTo(this.points[0].x, this.points[0].y); + for (let i = 1; i < this.points.length; i++) { + this.lineTo(this.points[i].x, this.points[i].y); + } + } + } +} diff --git a/src/graphics/logicSection/LogicSectionDrawAssistant.ts b/src/graphics/logicSection/LogicSectionDrawAssistant.ts index 1320f8c..88f70d6 100644 --- a/src/graphics/logicSection/LogicSectionDrawAssistant.ts +++ b/src/graphics/logicSection/LogicSectionDrawAssistant.ts @@ -18,7 +18,7 @@ export class LogicSectionDraw extends GraphicDrawAssistant< points: Point[] = []; graphic = new Graphics(); constructor(app: IDrawApp, template: LogicSectionTemplate) { - super(app, template, 'sym_o_timeline', '不展示'); + super(app, template, 'sym_o_timeline', '逻辑区段'); this.container.addChild(this.graphic); LogicSectionEditPlugin.init(app); } diff --git a/src/graphics/pathLine/PathLineDrawAssistant.ts b/src/graphics/pathLine/PathLineDrawAssistant.ts index 12e8f6f..9ea384b 100644 --- a/src/graphics/pathLine/PathLineDrawAssistant.ts +++ b/src/graphics/pathLine/PathLineDrawAssistant.ts @@ -38,7 +38,7 @@ export class PathLineDraw extends GraphicDrawAssistant< graphic: Graphics = new Graphics(); constructor(app: IDrawApp, template: PathLineTemplate) { - super(app, template, 'sym_o_horizontal_rule', '不展示'); + super(app, template, 'sym_o_horizontal_rule', 'PathLine'); this.container.addChild(this.graphic); PathLinePointsEditPlugin.init(app); } diff --git a/src/graphics/platform/Platform.ts b/src/graphics/platform/Platform.ts index b2b9d80..2311a5d 100644 --- a/src/graphics/platform/Platform.ts +++ b/src/graphics/platform/Platform.ts @@ -25,6 +25,8 @@ export interface IPlatformData extends GraphicData { 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; diff --git a/src/graphics/section/Section.ts b/src/graphics/section/Section.ts index 5cfcc9f..499121d 100644 --- a/src/graphics/section/Section.ts +++ b/src/graphics/section/Section.ts @@ -48,6 +48,8 @@ export interface ISectionData extends GraphicData { set destinationCode(destinationCode: string); get turning(): boolean; set turning(v: boolean); + get centralizedStation(): number; //所属集中站 + set centralizedStation(v: number); clone(): ISectionData; copyFrom(data: ISectionData): void; eq(other: ISectionData): boolean; diff --git a/src/graphics/separator/SeparatorDrawAssistant.ts b/src/graphics/separator/SeparatorDrawAssistant.ts index c477f42..0d0fd65 100644 --- a/src/graphics/separator/SeparatorDrawAssistant.ts +++ b/src/graphics/separator/SeparatorDrawAssistant.ts @@ -26,7 +26,7 @@ export class SeparatorDraw extends GraphicDrawAssistant< > { SeparatorGraph: Separator; constructor(app: IDrawApp, template: SeparatorTemplate) { - super(app, template, 'sym_o_square', '不展示'); + super(app, template, 'sym_o_square', '分隔符Separator'); this.SeparatorGraph = this.graphicTemplate.new(); this.container.addChild(this.SeparatorGraph); SeparatorInteraction.init(app); diff --git a/src/graphics/signal/Signal.ts b/src/graphics/signal/Signal.ts index 5825b59..9e5e174 100644 --- a/src/graphics/signal/Signal.ts +++ b/src/graphics/signal/Signal.ts @@ -36,6 +36,8 @@ export interface ISignalData extends GraphicData { set kilometerSystem(v: KilometerSystem); get refDevice(): IRelatedRefData | undefined; set refDevice(v: IRelatedRefData | undefined); + get centralizedStation(): number; //所属集中站 + set centralizedStation(v: number); clone(): ISignalData; copyFrom(data: ISignalData): void; eq(other: ISignalData): boolean; diff --git a/src/graphics/station/Station.ts b/src/graphics/station/Station.ts index e6935fe..12b2394 100644 --- a/src/graphics/station/Station.ts +++ b/src/graphics/station/Station.ts @@ -23,6 +23,10 @@ export interface IStationData extends GraphicData { 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; diff --git a/src/graphics/train/Train.ts b/src/graphics/train/Train.ts index 85f4797..31f92dc 100644 --- a/src/graphics/train/Train.ts +++ b/src/graphics/train/Train.ts @@ -110,9 +110,6 @@ enum statusTextColor { A = '0xFF0000', // A报警 } -console.log(LogicSection); -console.trace(1); - const deviceTypeString = new Map(); deviceTypeString.set(state.DeviceType.TRACK, LogicSection.Type); deviceTypeString.set(state.DeviceType.SWITCH_TRACK, Section.Type); diff --git a/src/graphics/train/TrainDrawAssistant.ts b/src/graphics/train/TrainDrawAssistant.ts index 16f42ef..a569c3c 100644 --- a/src/graphics/train/TrainDrawAssistant.ts +++ b/src/graphics/train/TrainDrawAssistant.ts @@ -16,7 +16,7 @@ export class TrainDraw extends GraphicDrawAssistant { _Train: Train | null = null; constructor(app: IDrawApp, template: TrainTemplate) { - super(app, template, 'directions_bus_filled', '不展示'); + super(app, template, 'directions_bus_filled', '车Train'); trainInteraction.init(app); } diff --git a/src/graphics/trainWindow/TrainWindowDrawAssistant.ts b/src/graphics/trainWindow/TrainWindowDrawAssistant.ts index 105a72c..c82cb7d 100644 --- a/src/graphics/trainWindow/TrainWindowDrawAssistant.ts +++ b/src/graphics/trainWindow/TrainWindowDrawAssistant.ts @@ -70,7 +70,7 @@ export class TrainWindowDraw extends GraphicDrawAssistant< > { trainWindowGraph: TrainWindow; constructor(app: IDrawApp, template: TrainWindowTemplate) { - super(app, template, 'sym_o_square', '不展示'); + super(app, template, 'sym_o_square', '车次窗'); this.trainWindowGraph = this.graphicTemplate.new(); this.container.addChild(this.trainWindowGraph); TrainWindowInteraction.init(app); diff --git a/src/graphics/trainWindow/oneClickDrawAssistant.ts b/src/graphics/trainWindow/oneClickDrawAssistant.ts index 9019a50..48ccda4 100644 --- a/src/graphics/trainWindow/oneClickDrawAssistant.ts +++ b/src/graphics/trainWindow/oneClickDrawAssistant.ts @@ -47,7 +47,7 @@ export class OneClickGenerateDraw extends GraphicDrawAssistant< > { lineGraph: OneClickGenerate; constructor(app: JlDrawApp, template: OneClickGenerateTemplate) { - super(app, template, 'sym_o_square', '不展示'); + super(app, template, 'sym_o_square', '辅助线'); this.lineGraph = this.graphicTemplate.new(); this.container.addChild(this.lineGraph); } diff --git a/src/graphics/turnout/Turnout.ts b/src/graphics/turnout/Turnout.ts index 6971f89..c938cb0 100644 --- a/src/graphics/turnout/Turnout.ts +++ b/src/graphics/turnout/Turnout.ts @@ -39,6 +39,8 @@ export interface ITurnoutData extends GraphicData { 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; diff --git a/src/layouts/DrawLayout.vue b/src/layouts/DrawLayout.vue index 4bb7d19..4419146 100644 --- a/src/layouts/DrawLayout.vue +++ b/src/layouts/DrawLayout.vue @@ -6,26 +6,14 @@ - - 保存 - - - 另存为 - - - 一键关联 - - - 一键生成车次窗 - - - 一键生成分隔符 - - - 一键生成计轴 - - - 一键生成道岔区段 + + {{ item.label }} @@ -195,6 +183,12 @@ import { TrainLine } from 'src/graphics/trainLine/TrainLine'; import { StationLine } from 'src/graphics/stationLine/StationLine'; import { RunLine } from 'src/graphics/runLine/RunLine'; import { PathLine } from 'src/graphics/pathLine/PathLine'; +import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine'; +import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { + findContainDevice, + handleCentralizedStationsData, +} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLineUtils'; const route = useRoute(); const router = useRouter(); @@ -243,6 +237,21 @@ class ControlItem { } } +//左侧功能按钮 +const leftMenuConfig = [ + { label: '保存', click: saveAllDrawDatas }, + { label: '另存为', click: () => (saveAsDialog.value = true) }, + { label: '一键关联', click: buildRelations }, + { label: '一键生成车次窗', click: oneClickGeneration }, + { label: '一键生成分隔符', click: oneClickSeparator }, + { label: '一键生成计轴', click: oneClickAxleCounting }, + { label: '一键生成道岔区段', click: oneClickTurnoutSection }, + { + label: '一键关联设备所属的集中站', + click: oneClickRelateCentralizedStation, + }, +]; + onMounted(() => { console.log('绘制应用layout mounted'); const dom = document.getElementById('draw-app-container'); @@ -265,6 +274,7 @@ onMounted(() => { Signal.Type, Section.Type, Turnout.Type, + ConcentrationDividingLine.Type, ]; } else { drawAssistantsTypes = [ @@ -279,7 +289,6 @@ onMounted(() => { drawAssistantsTypes.forEach((type) => { const drawAssistant = getDrawApp()?.getDrawAssistant(type); if (drawAssistant) { - if (drawAssistant.description === '不展示') return; utilsOption.push( new ControlItem( drawAssistant.name, @@ -334,7 +343,6 @@ function saveAllDrawDatas() { function buildRelations() { const app = getDrawApp(); app?.detectRelations(); - console.log(app); } function oneClickGeneration() { @@ -363,6 +371,173 @@ function oneClickTurnoutSection() { SDA.generateTurnoutSection(); } +function oneClickRelateCentralizedStation() { + const drawApp = drawStore.getDrawApp(); + const concentrationDividingLines = drawApp.queryStore + .queryByType(ConcentrationDividingLine.Type) + .filter((g) => !g.datas.isOtherLineConcentrationDividingLine) + .sort((a, b) => a.datas.points[0].x - b.datas.points[0].x); + const hasHandleStation: number[] = []; + for (let i = 0; i < concentrationDividingLines.length - 1; i++) { + let containDeviceIds: number[] = []; + //右边 + const rightDatas = concentrationDividingLines[i].datas; + if (hasHandleStation.includes(rightDatas.refRightStationId)) { + continue; + } else { + hasHandleStation.push(rightDatas.refRightStationId); + } + const rightSections: { + section: Section; + port: graphicData.RelatedRef.DevicePort; + }[] = []; + rightDatas.nodeConWithSecs.forEach((node) => { + if (node.rightSection.id) { + rightSections.push({ + section: drawApp.queryStore.queryById(node.rightSection.id), + port: node.rightSection.devicePort, + }); + } + }); + //左边 + const leftSections: number[] = []; + for (let j = i + 1; j < concentrationDividingLines.length; j++) { + const LeftDatas = concentrationDividingLines[j].datas; + if (LeftDatas.refLeftStationId == rightDatas.refRightStationId) { + LeftDatas.nodeConWithSecs.forEach((node) => { + if (node.leftSection.id) { + leftSections.push(node.leftSection.id); + } + }); + } + } + containDeviceIds = [ + ...rightSections.map((g) => g.section.id), + ...leftSections, + ]; + //递归从右边的设备开始找路径,找到左边相同的集中站停下来 + rightSections.forEach((rightSection) => { + findContainDevice( + rightSection.section, + rightSection.port, + containDeviceIds, + drawApp + ); + containDeviceIds = Array.from(new Set(containDeviceIds)); + }); + if (rightDatas.refRightStationId) { + handleContainDevices(containDeviceIds, rightDatas.refRightStationId); + } + } + //需要考虑是否绘制左右边界 + const leftBoundary = concentrationDividingLines[0]; + handleLeftBoundary(leftBoundary); + const rightBoundary = + concentrationDividingLines[concentrationDividingLines.length - 1]; + handleRightBoundary(rightBoundary); + + function handleContainDevices( + containDeviceIds: number[], + centralizedStation: number + ) { + const containDevices = containDeviceIds.map((id) => { + return drawApp.queryStore.queryById(id); + }); + const signals = drawApp.queryStore + .queryByType(Signal.Type) + .filter((g) => + containDeviceIds.includes(g.datas.refDevice?.id as number) + ); + let platforms: Platform[] = []; + if (centralizedStation !== 0) { + const station = drawApp.queryStore.queryById(centralizedStation); + platforms = drawApp.queryStore + .queryByType(Platform.Type) + .filter((g) => + station.datas.manageStations.includes(g.datas.refStation) + ); + } + const allSetCentralizedStationsDevice = [ + ...containDevices, + ...signals, + ...platforms, + ]; + allSetCentralizedStationsDevice.forEach( + (g) => ((g as Signal).datas.centralizedStation = 0) + ); + handleCentralizedStationsData( + allSetCentralizedStationsDevice, + centralizedStation + ); + } + function handleLeftBoundary(leftBoundary: ConcentrationDividingLine) { + let containDeviceIds: number[] = []; + const leftSections: { + section: Section; + port: graphicData.RelatedRef.DevicePort; + }[] = []; + leftBoundary.datas.nodeConWithSecs.forEach((node) => { + if (node.leftSection.id) { + leftSections.push({ + section: drawApp.queryStore.queryById(node.leftSection.id), + port: node.leftSection.devicePort, + }); + } + }); + containDeviceIds = [...leftSections.map((g) => g.section.id)]; + leftSections.forEach((leftSection) => { + findContainDevice( + leftSection.section, + leftSection.port, + containDeviceIds, + drawApp + ); + containDeviceIds = Array.from(new Set(containDeviceIds)); + }); + if (!leftBoundary.datas.refLeftStationId) { + handleContainDevices(containDeviceIds, 0); + } else { + handleContainDevices( + containDeviceIds, + leftBoundary.datas.refLeftStationId + ); + } + } + function handleRightBoundary(rightBoundary: ConcentrationDividingLine) { + let containDeviceIds: number[] = []; + const rightSections: { + section: Section; + port: graphicData.RelatedRef.DevicePort; + }[] = []; + rightBoundary.datas.nodeConWithSecs.forEach((node) => { + if (node.rightSection.id) { + rightSections.push({ + section: drawApp.queryStore.queryById(node.rightSection.id), + port: node.rightSection.devicePort, + }); + } + }); + containDeviceIds = [...rightSections.map((g) => g.section.id)]; + rightSections.forEach((rightSections) => { + findContainDevice( + rightSections.section, + rightSections.port, + containDeviceIds, + drawApp + ); + containDeviceIds = Array.from(new Set(containDeviceIds)); + }); + if (!rightBoundary.datas.refRightStationId) { + handleContainDevices(containDeviceIds, 0); + } else { + handleContainDevices( + containDeviceIds, + rightBoundary.datas.refRightStationId + ); + } + } +} + function backConfirm() { router.go(-1); } diff --git a/src/protos/stationLayoutGraphics.ts b/src/protos/stationLayoutGraphics.ts index 893e3ba..fcb12d2 100644 --- a/src/protos/stationLayoutGraphics.ts +++ b/src/protos/stationLayoutGraphics.ts @@ -27,9 +27,10 @@ export namespace graphicData { axleCountings?: AxleCounting[]; separators?: Separator[]; logicSections?: LogicSection[]; + concentrationDividingLines?: ConcentrationDividingLine[]; }) { super(); - pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], this.#one_of_decls); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], this.#one_of_decls); if (!Array.isArray(data) && typeof data == "object") { if ("canvas" in data && data.canvas != undefined) { this.canvas = data.canvas; @@ -88,6 +89,9 @@ export namespace graphicData { if ("logicSections" in data && data.logicSections != undefined) { this.logicSections = data.logicSections; } + if ("concentrationDividingLines" in data && data.concentrationDividingLines != undefined) { + this.concentrationDividingLines = data.concentrationDividingLines; + } } } get canvas() { @@ -207,6 +211,12 @@ export namespace graphicData { set logicSections(value: LogicSection[]) { pb_1.Message.setRepeatedWrapperField(this, 19, value); } + get concentrationDividingLines() { + return pb_1.Message.getRepeatedWrapperField(this, ConcentrationDividingLine, 20) as ConcentrationDividingLine[]; + } + set concentrationDividingLines(value: ConcentrationDividingLine[]) { + pb_1.Message.setRepeatedWrapperField(this, 20, value); + } static fromObject(data: { canvas?: ReturnType; links?: ReturnType[]; @@ -227,6 +237,7 @@ export namespace graphicData { axleCountings?: ReturnType[]; separators?: ReturnType[]; logicSections?: ReturnType[]; + concentrationDividingLines?: ReturnType[]; }): RtssGraphicStorage { const message = new RtssGraphicStorage({}); if (data.canvas != null) { @@ -286,6 +297,9 @@ export namespace graphicData { if (data.logicSections != null) { message.logicSections = data.logicSections.map(item => LogicSection.fromObject(item)); } + if (data.concentrationDividingLines != null) { + message.concentrationDividingLines = data.concentrationDividingLines.map(item => ConcentrationDividingLine.fromObject(item)); + } return message; } toObject() { @@ -309,6 +323,7 @@ export namespace graphicData { axleCountings?: ReturnType[]; separators?: ReturnType[]; logicSections?: ReturnType[]; + concentrationDividingLines?: ReturnType[]; } = {}; if (this.canvas != null) { data.canvas = this.canvas.toObject(); @@ -367,6 +382,9 @@ export namespace graphicData { if (this.logicSections != null) { data.logicSections = this.logicSections.map((item: LogicSection) => item.toObject()); } + if (this.concentrationDividingLines != null) { + data.concentrationDividingLines = this.concentrationDividingLines.map((item: ConcentrationDividingLine) => item.toObject()); + } return data; } serialize(): Uint8Array; @@ -411,6 +429,8 @@ export namespace graphicData { writer.writeRepeatedMessage(18, this.separators, (item: Separator) => item.serialize(writer)); if (this.logicSections.length) writer.writeRepeatedMessage(19, this.logicSections, (item: LogicSection) => item.serialize(writer)); + if (this.concentrationDividingLines.length) + writer.writeRepeatedMessage(20, this.concentrationDividingLines, (item: ConcentrationDividingLine) => item.serialize(writer)); if (!w) return writer.getResultBuffer(); } @@ -477,6 +497,9 @@ export namespace graphicData { case 19: reader.readMessage(message.logicSections, () => pb_1.Message.addToRepeatedWrapperField(message, 19, LogicSection.deserialize(reader), LogicSection)); break; + case 20: + reader.readMessage(message.concentrationDividingLines, () => pb_1.Message.addToRepeatedWrapperField(message, 20, ConcentrationDividingLine.deserialize(reader), ConcentrationDividingLine)); + break; default: reader.skipField(); } } @@ -1722,6 +1745,356 @@ export namespace graphicData { return Polygon.deserialize(bytes); } } + export class ConcentrationDividingLine extends pb_1.Message { + #one_of_decls: number[][] = []; + constructor(data?: any[] | { + common?: CommonInfo; + code?: string; + points?: Point[]; + oldrefLeftStationId?: string; + oldrefRightStationId?: string; + nodeConWithSecs?: NodeConWithSec[]; + isOtherLineConcentrationDividingLine?: boolean; + refLeftStationId?: number; + refRightStationId?: number; + }) { + super(); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [3, 6], this.#one_of_decls); + if (!Array.isArray(data) && typeof data == "object") { + if ("common" in data && data.common != undefined) { + this.common = data.common; + } + if ("code" in data && data.code != undefined) { + this.code = data.code; + } + if ("points" in data && data.points != undefined) { + this.points = data.points; + } + if ("oldrefLeftStationId" in data && data.oldrefLeftStationId != undefined) { + this.oldrefLeftStationId = data.oldrefLeftStationId; + } + if ("oldrefRightStationId" in data && data.oldrefRightStationId != undefined) { + this.oldrefRightStationId = data.oldrefRightStationId; + } + if ("nodeConWithSecs" in data && data.nodeConWithSecs != undefined) { + this.nodeConWithSecs = data.nodeConWithSecs; + } + if ("isOtherLineConcentrationDividingLine" in data && data.isOtherLineConcentrationDividingLine != undefined) { + this.isOtherLineConcentrationDividingLine = data.isOtherLineConcentrationDividingLine; + } + if ("refLeftStationId" in data && data.refLeftStationId != undefined) { + this.refLeftStationId = data.refLeftStationId; + } + if ("refRightStationId" in data && data.refRightStationId != undefined) { + this.refRightStationId = data.refRightStationId; + } + } + } + get common() { + return pb_1.Message.getWrapperField(this, CommonInfo, 1) as CommonInfo; + } + set common(value: CommonInfo) { + pb_1.Message.setWrapperField(this, 1, value); + } + get has_common() { + return pb_1.Message.getField(this, 1) != null; + } + get code() { + return pb_1.Message.getFieldWithDefault(this, 2, "") as string; + } + set code(value: string) { + pb_1.Message.setField(this, 2, value); + } + get points() { + return pb_1.Message.getRepeatedWrapperField(this, Point, 3) as Point[]; + } + set points(value: Point[]) { + pb_1.Message.setRepeatedWrapperField(this, 3, value); + } + get oldrefLeftStationId() { + return pb_1.Message.getFieldWithDefault(this, 4, "") as string; + } + set oldrefLeftStationId(value: string) { + pb_1.Message.setField(this, 4, value); + } + get oldrefRightStationId() { + return pb_1.Message.getFieldWithDefault(this, 5, "") as string; + } + set oldrefRightStationId(value: string) { + pb_1.Message.setField(this, 5, value); + } + get nodeConWithSecs() { + return pb_1.Message.getRepeatedWrapperField(this, NodeConWithSec, 6) as NodeConWithSec[]; + } + set nodeConWithSecs(value: NodeConWithSec[]) { + pb_1.Message.setRepeatedWrapperField(this, 6, value); + } + get isOtherLineConcentrationDividingLine() { + return pb_1.Message.getFieldWithDefault(this, 7, false) as boolean; + } + set isOtherLineConcentrationDividingLine(value: boolean) { + pb_1.Message.setField(this, 7, value); + } + get refLeftStationId() { + return pb_1.Message.getFieldWithDefault(this, 8, 0) as number; + } + set refLeftStationId(value: number) { + pb_1.Message.setField(this, 8, value); + } + get refRightStationId() { + return pb_1.Message.getFieldWithDefault(this, 9, 0) as number; + } + set refRightStationId(value: number) { + pb_1.Message.setField(this, 9, value); + } + static fromObject(data: { + common?: ReturnType; + code?: string; + points?: ReturnType[]; + oldrefLeftStationId?: string; + oldrefRightStationId?: string; + nodeConWithSecs?: ReturnType[]; + isOtherLineConcentrationDividingLine?: boolean; + refLeftStationId?: number; + refRightStationId?: number; + }): ConcentrationDividingLine { + const message = new ConcentrationDividingLine({}); + if (data.common != null) { + message.common = CommonInfo.fromObject(data.common); + } + if (data.code != null) { + message.code = data.code; + } + if (data.points != null) { + message.points = data.points.map(item => Point.fromObject(item)); + } + if (data.oldrefLeftStationId != null) { + message.oldrefLeftStationId = data.oldrefLeftStationId; + } + if (data.oldrefRightStationId != null) { + message.oldrefRightStationId = data.oldrefRightStationId; + } + if (data.nodeConWithSecs != null) { + message.nodeConWithSecs = data.nodeConWithSecs.map(item => NodeConWithSec.fromObject(item)); + } + if (data.isOtherLineConcentrationDividingLine != null) { + message.isOtherLineConcentrationDividingLine = data.isOtherLineConcentrationDividingLine; + } + if (data.refLeftStationId != null) { + message.refLeftStationId = data.refLeftStationId; + } + if (data.refRightStationId != null) { + message.refRightStationId = data.refRightStationId; + } + return message; + } + toObject() { + const data: { + common?: ReturnType; + code?: string; + points?: ReturnType[]; + oldrefLeftStationId?: string; + oldrefRightStationId?: string; + nodeConWithSecs?: ReturnType[]; + isOtherLineConcentrationDividingLine?: boolean; + refLeftStationId?: number; + refRightStationId?: number; + } = {}; + if (this.common != null) { + data.common = this.common.toObject(); + } + if (this.code != null) { + data.code = this.code; + } + if (this.points != null) { + data.points = this.points.map((item: Point) => item.toObject()); + } + if (this.oldrefLeftStationId != null) { + data.oldrefLeftStationId = this.oldrefLeftStationId; + } + if (this.oldrefRightStationId != null) { + data.oldrefRightStationId = this.oldrefRightStationId; + } + if (this.nodeConWithSecs != null) { + data.nodeConWithSecs = this.nodeConWithSecs.map((item: NodeConWithSec) => item.toObject()); + } + if (this.isOtherLineConcentrationDividingLine != null) { + data.isOtherLineConcentrationDividingLine = this.isOtherLineConcentrationDividingLine; + } + if (this.refLeftStationId != null) { + data.refLeftStationId = this.refLeftStationId; + } + if (this.refRightStationId != null) { + data.refRightStationId = this.refRightStationId; + } + return data; + } + serialize(): Uint8Array; + serialize(w: pb_1.BinaryWriter): void; + serialize(w?: pb_1.BinaryWriter): Uint8Array | void { + const writer = w || new pb_1.BinaryWriter(); + if (this.has_common) + writer.writeMessage(1, this.common, () => this.common.serialize(writer)); + if (this.code.length) + writer.writeString(2, this.code); + if (this.points.length) + writer.writeRepeatedMessage(3, this.points, (item: Point) => item.serialize(writer)); + if (this.oldrefLeftStationId.length) + writer.writeString(4, this.oldrefLeftStationId); + if (this.oldrefRightStationId.length) + writer.writeString(5, this.oldrefRightStationId); + if (this.nodeConWithSecs.length) + writer.writeRepeatedMessage(6, this.nodeConWithSecs, (item: NodeConWithSec) => item.serialize(writer)); + if (this.isOtherLineConcentrationDividingLine != false) + writer.writeBool(7, this.isOtherLineConcentrationDividingLine); + if (this.refLeftStationId != 0) + writer.writeUint32(8, this.refLeftStationId); + if (this.refRightStationId != 0) + writer.writeUint32(9, this.refRightStationId); + if (!w) + return writer.getResultBuffer(); + } + static deserialize(bytes: Uint8Array | pb_1.BinaryReader): ConcentrationDividingLine { + const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new ConcentrationDividingLine(); + while (reader.nextField()) { + if (reader.isEndGroup()) + break; + switch (reader.getFieldNumber()) { + case 1: + reader.readMessage(message.common, () => message.common = CommonInfo.deserialize(reader)); + break; + case 2: + message.code = reader.readString(); + break; + case 3: + reader.readMessage(message.points, () => pb_1.Message.addToRepeatedWrapperField(message, 3, Point.deserialize(reader), Point)); + break; + case 4: + message.oldrefLeftStationId = reader.readString(); + break; + case 5: + message.oldrefRightStationId = reader.readString(); + break; + case 6: + reader.readMessage(message.nodeConWithSecs, () => pb_1.Message.addToRepeatedWrapperField(message, 6, NodeConWithSec.deserialize(reader), NodeConWithSec)); + break; + case 7: + message.isOtherLineConcentrationDividingLine = reader.readBool(); + break; + case 8: + message.refLeftStationId = reader.readUint32(); + break; + case 9: + message.refRightStationId = reader.readUint32(); + break; + default: reader.skipField(); + } + } + return message; + } + serializeBinary(): Uint8Array { + return this.serialize(); + } + static deserializeBinary(bytes: Uint8Array): ConcentrationDividingLine { + return ConcentrationDividingLine.deserialize(bytes); + } + } + export class NodeConWithSec extends pb_1.Message { + #one_of_decls: number[][] = []; + constructor(data?: any[] | { + leftSection?: RelatedRef; + rightSection?: RelatedRef; + }) { + super(); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); + if (!Array.isArray(data) && typeof data == "object") { + if ("leftSection" in data && data.leftSection != undefined) { + this.leftSection = data.leftSection; + } + if ("rightSection" in data && data.rightSection != undefined) { + this.rightSection = data.rightSection; + } + } + } + get leftSection() { + return pb_1.Message.getWrapperField(this, RelatedRef, 1) as RelatedRef; + } + set leftSection(value: RelatedRef) { + pb_1.Message.setWrapperField(this, 1, value); + } + get has_leftSection() { + return pb_1.Message.getField(this, 1) != null; + } + get rightSection() { + return pb_1.Message.getWrapperField(this, RelatedRef, 2) as RelatedRef; + } + set rightSection(value: RelatedRef) { + pb_1.Message.setWrapperField(this, 2, value); + } + get has_rightSection() { + return pb_1.Message.getField(this, 2) != null; + } + static fromObject(data: { + leftSection?: ReturnType; + rightSection?: ReturnType; + }): NodeConWithSec { + const message = new NodeConWithSec({}); + if (data.leftSection != null) { + message.leftSection = RelatedRef.fromObject(data.leftSection); + } + if (data.rightSection != null) { + message.rightSection = RelatedRef.fromObject(data.rightSection); + } + return message; + } + toObject() { + const data: { + leftSection?: ReturnType; + rightSection?: ReturnType; + } = {}; + if (this.leftSection != null) { + data.leftSection = this.leftSection.toObject(); + } + if (this.rightSection != null) { + data.rightSection = this.rightSection.toObject(); + } + return data; + } + serialize(): Uint8Array; + serialize(w: pb_1.BinaryWriter): void; + serialize(w?: pb_1.BinaryWriter): Uint8Array | void { + const writer = w || new pb_1.BinaryWriter(); + if (this.has_leftSection) + writer.writeMessage(1, this.leftSection, () => this.leftSection.serialize(writer)); + if (this.has_rightSection) + writer.writeMessage(2, this.rightSection, () => this.rightSection.serialize(writer)); + if (!w) + return writer.getResultBuffer(); + } + static deserialize(bytes: Uint8Array | pb_1.BinaryReader): NodeConWithSec { + const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new NodeConWithSec(); + while (reader.nextField()) { + if (reader.isEndGroup()) + break; + switch (reader.getFieldNumber()) { + case 1: + reader.readMessage(message.leftSection, () => message.leftSection = RelatedRef.deserialize(reader)); + break; + case 2: + reader.readMessage(message.rightSection, () => message.rightSection = RelatedRef.deserialize(reader)); + break; + default: reader.skipField(); + } + } + return message; + } + serializeBinary(): Uint8Array { + return this.serialize(); + } + static deserializeBinary(bytes: Uint8Array): NodeConWithSec { + return NodeConWithSec.deserialize(bytes); + } + } export class Platform extends pb_1.Message { #one_of_decls: number[][] = []; constructor(data?: any[] | { @@ -1734,6 +2107,7 @@ export namespace graphicData { oldrefSectionId?: string; refStation?: number; refSectionId?: number; + centralizedStationId?: number; }) { super(); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); @@ -1765,6 +2139,9 @@ export namespace graphicData { if ("refSectionId" in data && data.refSectionId != undefined) { this.refSectionId = data.refSectionId; } + if ("centralizedStationId" in data && data.centralizedStationId != undefined) { + this.centralizedStationId = data.centralizedStationId; + } } } get common() { @@ -1824,6 +2201,12 @@ export namespace graphicData { set refSectionId(value: number) { pb_1.Message.setField(this, 10, value); } + get centralizedStationId() { + return pb_1.Message.getFieldWithDefault(this, 11, 0) as number; + } + set centralizedStationId(value: number) { + pb_1.Message.setField(this, 11, value); + } static fromObject(data: { common?: ReturnType; code?: string; @@ -1834,6 +2217,7 @@ export namespace graphicData { oldrefSectionId?: string; refStation?: number; refSectionId?: number; + centralizedStationId?: number; }): Platform { const message = new Platform({}); if (data.common != null) { @@ -1863,6 +2247,9 @@ export namespace graphicData { if (data.refSectionId != null) { message.refSectionId = data.refSectionId; } + if (data.centralizedStationId != null) { + message.centralizedStationId = data.centralizedStationId; + } return message; } toObject() { @@ -1876,6 +2263,7 @@ export namespace graphicData { oldrefSectionId?: string; refStation?: number; refSectionId?: number; + centralizedStationId?: number; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -1904,6 +2292,9 @@ export namespace graphicData { if (this.refSectionId != null) { data.refSectionId = this.refSectionId; } + if (this.centralizedStationId != null) { + data.centralizedStationId = this.centralizedStationId; + } return data; } serialize(): Uint8Array; @@ -1928,6 +2319,8 @@ export namespace graphicData { writer.writeUint32(9, this.refStation); if (this.refSectionId != 0) writer.writeUint32(10, this.refSectionId); + if (this.centralizedStationId != 0) + writer.writeUint32(11, this.centralizedStationId); if (!w) return writer.getResultBuffer(); } @@ -1964,6 +2357,9 @@ export namespace graphicData { case 10: message.refSectionId = reader.readUint32(); break; + case 11: + message.centralizedStationId = reader.readUint32(); + break; default: reader.skipField(); } } @@ -1985,9 +2381,11 @@ export namespace graphicData { concentrationStations?: boolean; kilometerSystem?: KilometerSystem; name?: string; + manageStations?: number[]; + depots?: boolean; }) { super(); - pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [8], this.#one_of_decls); if (!Array.isArray(data) && typeof data == "object") { if ("common" in data && data.common != undefined) { this.common = data.common; @@ -2007,6 +2405,12 @@ export namespace graphicData { if ("name" in data && data.name != undefined) { this.name = data.name; } + if ("manageStations" in data && data.manageStations != undefined) { + this.manageStations = data.manageStations; + } + if ("depots" in data && data.depots != undefined) { + this.depots = data.depots; + } } } get common() { @@ -2051,6 +2455,18 @@ export namespace graphicData { set name(value: string) { pb_1.Message.setField(this, 7, value); } + get manageStations() { + return pb_1.Message.getFieldWithDefault(this, 8, []) as number[]; + } + set manageStations(value: number[]) { + pb_1.Message.setField(this, 8, value); + } + get depots() { + return pb_1.Message.getFieldWithDefault(this, 9, false) as boolean; + } + set depots(value: boolean) { + pb_1.Message.setField(this, 9, value); + } static fromObject(data: { common?: ReturnType; code?: string; @@ -2058,6 +2474,8 @@ export namespace graphicData { concentrationStations?: boolean; kilometerSystem?: ReturnType; name?: string; + manageStations?: number[]; + depots?: boolean; }): Station { const message = new Station({}); if (data.common != null) { @@ -2078,6 +2496,12 @@ export namespace graphicData { if (data.name != null) { message.name = data.name; } + if (data.manageStations != null) { + message.manageStations = data.manageStations; + } + if (data.depots != null) { + message.depots = data.depots; + } return message; } toObject() { @@ -2088,6 +2512,8 @@ export namespace graphicData { concentrationStations?: boolean; kilometerSystem?: ReturnType; name?: string; + manageStations?: number[]; + depots?: boolean; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -2107,6 +2533,12 @@ export namespace graphicData { if (this.name != null) { data.name = this.name; } + if (this.manageStations != null) { + data.manageStations = this.manageStations; + } + if (this.depots != null) { + data.depots = this.depots; + } return data; } serialize(): Uint8Array; @@ -2125,6 +2557,10 @@ export namespace graphicData { writer.writeMessage(6, this.kilometerSystem, () => this.kilometerSystem.serialize(writer)); if (this.name.length) writer.writeString(7, this.name); + if (this.manageStations.length) + writer.writePackedUint32(8, this.manageStations); + if (this.depots != false) + writer.writeBool(9, this.depots); if (!w) return writer.getResultBuffer(); } @@ -2152,6 +2588,12 @@ export namespace graphicData { case 7: message.name = reader.readString(); break; + case 8: + message.manageStations = reader.readPackedUint32(); + break; + case 9: + message.depots = reader.readBool(); + break; default: reader.skipField(); } } @@ -2904,6 +3346,7 @@ export namespace graphicData { pbRef?: RelatedRef; pcRef?: RelatedRef; kilometerSystem?: KilometerSystem[]; + centralizedStationId?: number; }) { super(); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [6, 7, 8, 13], this.#one_of_decls); @@ -2935,6 +3378,9 @@ export namespace graphicData { if ("kilometerSystem" in data && data.kilometerSystem != undefined) { this.kilometerSystem = data.kilometerSystem; } + if ("centralizedStationId" in data && data.centralizedStationId != undefined) { + this.centralizedStationId = data.centralizedStationId; + } } } get common() { @@ -3003,6 +3449,12 @@ export namespace graphicData { set kilometerSystem(value: KilometerSystem[]) { pb_1.Message.setRepeatedWrapperField(this, 13, value); } + get centralizedStationId() { + return pb_1.Message.getFieldWithDefault(this, 14, 0) as number; + } + set centralizedStationId(value: number) { + pb_1.Message.setField(this, 14, value); + } static fromObject(data: { common?: ReturnType; code?: string; @@ -3013,6 +3465,7 @@ export namespace graphicData { pbRef?: ReturnType; pcRef?: ReturnType; kilometerSystem?: ReturnType[]; + centralizedStationId?: number; }): Turnout { const message = new Turnout({}); if (data.common != null) { @@ -3042,6 +3495,9 @@ export namespace graphicData { if (data.kilometerSystem != null) { message.kilometerSystem = data.kilometerSystem.map(item => KilometerSystem.fromObject(item)); } + if (data.centralizedStationId != null) { + message.centralizedStationId = data.centralizedStationId; + } return message; } toObject() { @@ -3055,6 +3511,7 @@ export namespace graphicData { pbRef?: ReturnType; pcRef?: ReturnType; kilometerSystem?: ReturnType[]; + centralizedStationId?: number; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -3083,6 +3540,9 @@ export namespace graphicData { if (this.kilometerSystem != null) { data.kilometerSystem = this.kilometerSystem.map((item: KilometerSystem) => item.toObject()); } + if (this.centralizedStationId != null) { + data.centralizedStationId = this.centralizedStationId; + } return data; } serialize(): Uint8Array; @@ -3107,6 +3567,8 @@ export namespace graphicData { writer.writeMessage(11, this.pcRef, () => this.pcRef.serialize(writer)); if (this.kilometerSystem.length) writer.writeRepeatedMessage(13, this.kilometerSystem, (item: KilometerSystem) => item.serialize(writer)); + if (this.centralizedStationId != 0) + writer.writeUint32(14, this.centralizedStationId); if (!w) return writer.getResultBuffer(); } @@ -3143,6 +3605,9 @@ export namespace graphicData { case 13: reader.readMessage(message.kilometerSystem, () => pb_1.Message.addToRepeatedWrapperField(message, 13, KilometerSystem.deserialize(reader), KilometerSystem)); break; + case 14: + message.centralizedStationId = reader.readUint32(); + break; default: reader.skipField(); } } @@ -3253,6 +3718,7 @@ export namespace graphicData { mirror?: boolean; kilometerSystem?: KilometerSystem; refDevice?: RelatedRef; + centralizedStationId?: number; }) { super(); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); @@ -3272,6 +3738,9 @@ export namespace graphicData { if ("refDevice" in data && data.refDevice != undefined) { this.refDevice = data.refDevice; } + if ("centralizedStationId" in data && data.centralizedStationId != undefined) { + this.centralizedStationId = data.centralizedStationId; + } } } get common() { @@ -3313,12 +3782,19 @@ export namespace graphicData { get has_refDevice() { return pb_1.Message.getField(this, 7) != null; } + get centralizedStationId() { + return pb_1.Message.getFieldWithDefault(this, 8, 0) as number; + } + set centralizedStationId(value: number) { + pb_1.Message.setField(this, 8, value); + } static fromObject(data: { common?: ReturnType; code?: string; mirror?: boolean; kilometerSystem?: ReturnType; refDevice?: ReturnType; + centralizedStationId?: number; }): Signal { const message = new Signal({}); if (data.common != null) { @@ -3336,6 +3812,9 @@ export namespace graphicData { if (data.refDevice != null) { message.refDevice = RelatedRef.fromObject(data.refDevice); } + if (data.centralizedStationId != null) { + message.centralizedStationId = data.centralizedStationId; + } return message; } toObject() { @@ -3345,6 +3824,7 @@ export namespace graphicData { mirror?: boolean; kilometerSystem?: ReturnType; refDevice?: ReturnType; + centralizedStationId?: number; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -3361,6 +3841,9 @@ export namespace graphicData { if (this.refDevice != null) { data.refDevice = this.refDevice.toObject(); } + if (this.centralizedStationId != null) { + data.centralizedStationId = this.centralizedStationId; + } return data; } serialize(): Uint8Array; @@ -3377,6 +3860,8 @@ export namespace graphicData { writer.writeMessage(6, this.kilometerSystem, () => this.kilometerSystem.serialize(writer)); if (this.has_refDevice) writer.writeMessage(7, this.refDevice, () => this.refDevice.serialize(writer)); + if (this.centralizedStationId != 0) + writer.writeUint32(8, this.centralizedStationId); if (!w) return writer.getResultBuffer(); } @@ -3401,6 +3886,9 @@ export namespace graphicData { case 7: reader.readMessage(message.refDevice, () => message.refDevice = RelatedRef.deserialize(reader)); break; + case 8: + message.centralizedStationId = reader.readUint32(); + break; default: reader.skipField(); } } @@ -3750,6 +4238,7 @@ export namespace graphicData { destinationCode?: string; turning?: boolean; children?: number[]; + centralizedStationId?: number; }) { super(); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [3, 7, 8, 11], this.#one_of_decls); @@ -3787,6 +4276,9 @@ export namespace graphicData { if ("children" in data && data.children != undefined) { this.children = data.children; } + if ("centralizedStationId" in data && data.centralizedStationId != undefined) { + this.centralizedStationId = data.centralizedStationId; + } } } get common() { @@ -3864,6 +4356,12 @@ export namespace graphicData { set children(value: number[]) { pb_1.Message.setField(this, 11, value); } + get centralizedStationId() { + return pb_1.Message.getFieldWithDefault(this, 12, 0) as number; + } + set centralizedStationId(value: number) { + pb_1.Message.setField(this, 12, value); + } static fromObject(data: { common?: ReturnType; code?: string; @@ -3876,6 +4374,7 @@ export namespace graphicData { destinationCode?: string; turning?: boolean; children?: number[]; + centralizedStationId?: number; }): Section { const message = new Section({}); if (data.common != null) { @@ -3911,6 +4410,9 @@ export namespace graphicData { if (data.children != null) { message.children = data.children; } + if (data.centralizedStationId != null) { + message.centralizedStationId = data.centralizedStationId; + } return message; } toObject() { @@ -3926,6 +4428,7 @@ export namespace graphicData { destinationCode?: string; turning?: boolean; children?: number[]; + centralizedStationId?: number; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -3960,6 +4463,9 @@ export namespace graphicData { if (this.children != null) { data.children = this.children; } + if (this.centralizedStationId != null) { + data.centralizedStationId = this.centralizedStationId; + } return data; } serialize(): Uint8Array; @@ -3988,6 +4494,8 @@ export namespace graphicData { writer.writeBool(10, this.turning); if (this.children.length) writer.writePackedUint32(11, this.children); + if (this.centralizedStationId != 0) + writer.writeUint32(12, this.centralizedStationId); if (!w) return writer.getResultBuffer(); } @@ -4030,6 +4538,9 @@ export namespace graphicData { case 11: message.children = reader.readPackedUint32(); break; + case 12: + message.centralizedStationId = reader.readUint32(); + break; default: reader.skipField(); } } diff --git a/src/stores/draw-store.ts b/src/stores/draw-store.ts index cdeadca..2967caf 100644 --- a/src/stores/draw-store.ts +++ b/src/stores/draw-store.ts @@ -29,7 +29,10 @@ export const useDrawStore = defineStore('draw', { if (state.selectedGraphics.length == 0) { return '画布'; } else if (state.selectedGraphics.length == 1) { - return state.selectedGraphics[0].type; + const name = getDrawApp()?.getDrawAssistant( + state.selectedGraphics[0].type + ).description; + return name || ''; } return '多选'; }