集中站相关

This commit is contained in:
joylink_zhaoerwei 2023-12-21 13:42:22 +08:00
parent 2349f81149
commit 938559a0a9
33 changed files with 1840 additions and 71 deletions

View File

@ -81,6 +81,11 @@
<LogicSectionProperty
v-else-if="drawStore.selectedGraphicType === LogicSection.Type"
/>
<concentrationDividingLine-property
v-else-if="
drawStore.selectedGraphicType === ConcentrationDividingLine.Type
"
/>
</q-card-section>
</template>
</q-card>
@ -90,6 +95,8 @@
<script setup lang="ts">
import LinkTemplate from './templates/LinkTemplate.vue';
import RectTemplate from './templates/RectTemplate.vue';
import ConcentrationDividingLineProperty from './properties/ConcentrationDividingLineProperty.vue';
import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
import PlatformTemplate from './templates/PlatformTemplate.vue';
import StationTemplate from './templates/StationTemplate.vue';
// import TrainTemplate from './templates/TrainTemplate.vue';

View File

@ -0,0 +1,126 @@
<template>
<q-form class="q-gutter-sm">
<q-input
outlined
readonly
v-model="concentrationDividingLineModel.id"
label="id"
/>
<q-select
outlined
style="margin-top: 10px"
v-model="concentrationDividingLineModel.refLeftStationId"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="左边关联的集中站"
/>
<q-select
outlined
style="margin-top: 10px"
v-model="concentrationDividingLineModel.refRightStationId"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="右边关联的集中站"
/>
<q-toggle
v-model="
concentrationDividingLineModel.isOtherLineConcentrationDividingLine
"
label="是否与其它线的边界处"
emit-value
@update:model-value="onUpdate"
/>
<q-list bordered separator class="rounded-borders">
<q-item
v-for="sectionRelation in sectionRelations"
:key="sectionRelation.label"
>
<q-item-section no-wrap class="q-gutter-y-sm column">
<q-item-label> {{ sectionRelation.label }} </q-item-label>
<div class="q-gutter-sm row">
<q-chip
v-for="(item, index) in sectionRelation.refSectionInfo"
:key="index"
square
color="primary"
text-color="white"
>
{{ item }}
</q-chip>
</div>
</q-item-section>
</q-item>
</q-list>
</q-form>
</template>
<script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils';
import { ConcentrationDividingLineData } from 'src/drawApp/graphics/ConcentrationDividingLineInteraction';
import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
import { Section } from 'src/graphics/section/Section';
import { Station } from 'src/graphics/station/Station';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, ref } from 'vue';
const drawStore = useDrawStore();
const { data: concentrationDividingLineModel, onUpdate } = useFormData(
new ConcentrationDividingLineData(),
drawStore.getDrawApp()
);
const centralizedStations = ref<{ label: string; value: number }[]>([]);
const sectionRelations = computed(() => {
const refSectionInfo: { label: string; refSectionInfo: string[] }[] = [
{ label: '左边关联的设备', refSectionInfo: [] },
{ label: '右边关联的设备', refSectionInfo: [] },
];
enum devicePort {
'A',
'B',
'C',
}
const concentrationDividingLine =
drawStore.selectedGraphic as ConcentrationDividingLine;
concentrationDividingLine.datas.nodeConWithSecs.forEach((nodeConWithSec) => {
const refleftSection = nodeConWithSec.leftSection?.id
? `${
drawStore
.getDrawApp()
.queryStore.queryById<Section>(nodeConWithSec.leftSection.id).datas
.code
}(${devicePort[nodeConWithSec.leftSection.devicePort]})`
: '边界';
refSectionInfo[0].refSectionInfo.push(refleftSection);
const refRightSection = nodeConWithSec.rightSection?.id
? `${
drawStore
.getDrawApp()
.queryStore.queryById<Section>(nodeConWithSec.rightSection.id).datas
.code
}(${devicePort[nodeConWithSec.rightSection.devicePort]})`
: '边界';
refSectionInfo[1].refSectionInfo.push(refRightSection);
});
return refSectionInfo;
});
onMounted(() => {
const stations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type);
centralizedStations.value = [{ label: '', value: 0 }];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.name,
value: station.datas.id,
});
}
});
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="platformModel.id" label="id" hint="" />
<q-input outlined readonly v-model="platformModel.id" label="id" />
<q-input
outlined
label="站台名称"
@ -59,6 +59,15 @@
</q-item-section>
</q-item>
</q-list>
<q-select
outlined
v-model="platformModel.centralizedStation"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="关联的集中站"
/>
</q-form>
</template>
@ -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>(Station.Type);
centralizedStations.value = [{ label: '', value: 0 }];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.name,
value: station.datas.id,
});
}
});
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<q-form>
<q-input outlined readonly v-model="sectionModel.id" label="id" hint="" />
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="sectionModel.id" label="id" />
<q-input
outlined
v-model="sectionModel.code"
@ -9,7 +9,6 @@
/>
<q-input
outlined
class="q-mt-lg"
v-model="sectionModel.destinationCode"
@blur="onUpdate"
label="目的地码"
@ -21,7 +20,6 @@
></q-checkbox>
<q-field
v-if="!isTurnoutPhysicalSection"
class="q-mt-lg"
outlined
label="关联区段"
readonly
@ -40,7 +38,6 @@
</q-field>
<q-field
v-if="!isTurnoutPhysicalSection"
class="q-mt-lg"
outlined
label="关联道岔"
readonly
@ -69,6 +66,15 @@
>
</template>
</q-field>
<q-select
outlined
v-model="sectionModel.centralizedStation"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="关联的集中站"
/>
</q-form>
</template>
@ -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<AxleCounting>(section).datas.code
);
});
const centralizedStations = ref<{ label: string; value: number }[]>([]);
onMounted(() => {
const stations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type);
centralizedStations.value = [{ label: '', value: 0 }];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.name,
value: station.datas.id,
});
}
});
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<q-form>
<q-input outlined readonly v-model="signalModel.id" label="id" hint="" />
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="signalModel.id" label="id" />
<q-input
outlined
v-model.number="signalModel.code"
@ -9,7 +9,6 @@
/>
<q-select
outlined
class="q-mt-sm"
v-model="refDevData.deviceType"
:options="DeviceTypeOptions"
readonly
@ -19,7 +18,6 @@
></q-select>
<q-input
outlined
class="q-mt-sm"
v-model="refDevData.code"
:readonly="true"
label="关联设备:"
@ -27,7 +25,6 @@
<q-select
outlined
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Turnout"
class="q-mt-sm"
v-model="refDevData.devicePort"
:options="DevicePortOptions"
:readonly="true"
@ -38,7 +35,6 @@
></q-select>
<q-select
outlined
style="margin-top: 10px"
v-model="signalModel.kilometerSystem.coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
@ -48,12 +44,20 @@
></q-select>
<q-input
outlined
style="margin-top: 10px"
v-model.number="signalModel.kilometerSystem.kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
v-model="signalModel.centralizedStation"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="关联的集中站"
/>
</q-form>
</template>
@ -61,10 +65,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(
@ -107,4 +112,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>(Station.Type);
centralizedStations.value = [{ label: '', value: 0 }];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.name,
value: station.datas.id,
});
}
});
});
</script>

View File

@ -38,22 +38,27 @@
label="公里标(mm):"
/>
<q-select
v-if="stationModel.concentrationStations"
outlined
@blur="onUpdate"
v-model="stationModel.hasControl"
:options="optionsControl"
label="是否有控制"
v-model="stationModel.manageStations"
label="集中站管理的车站"
multiple
:options="optionsStations"
map-options
emit-value
@update:model-value="onUpdate"
/>
<q-select
outlined
@blur="onUpdate"
v-model="stationModel.concentrationStations"
:options="optionsControl"
label="是否集中站"
map-options
<q-toggle
v-model="stationModel.hasControl"
label="是否有控制"
emit-value
@update:model-value="onUpdate"
/>
<q-toggle
v-model="stationModel.concentrationStations"
label="是否集中站"
emit-value
@update:model-value="onUpdate"
/>
</q-form>
</template>
@ -61,17 +66,16 @@
<script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils';
import { StationData } from 'src/drawApp/graphics/StationInteraction';
import { Station } from 'src/graphics/station/Station';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, watchEffect } from 'vue';
const drawStore = useDrawStore();
const { data: stationModel, onUpdate } = useFormData(
new StationData(),
drawStore.getDrawApp()
);
const optionsControl = [
{ label: '是', value: true },
{ label: '否', value: false },
];
let optionsStations: { label: string; value: number }[] = [];
const CoordinateSystemOptions = [
{ label: '车辆段', value: 'DEPOT' },
@ -79,4 +83,23 @@ const CoordinateSystemOptions = [
{ label: '正线', value: 'MAIN_LINE' },
{ label: '换线', value: 'TRANSFER' },
];
watchEffect(() => {
if (
stationModel.concentrationStations &&
!stationModel.manageStations.includes(stationModel.id)
) {
stationModel.manageStations.push(stationModel.id);
onUpdate();
}
});
onMounted(() => {
optionsStations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type)
.map((g) => {
return { label: g.datas.name, value: g.datas.id };
});
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<q-form>
<q-input outlined readonly v-model="turnoutModel.id" label="id" hint="" />
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="turnoutModel.id" label="id" />
<q-input
outlined
v-model="turnoutModel.code"
@ -9,7 +9,6 @@
/>
<q-select
outlined
style="margin-top: 10px"
v-model="turnoutModel.kilometerSystem[0].coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
@ -19,7 +18,6 @@
></q-select>
<q-input
outlined
style="margin-top: 10px"
v-model.number="turnoutModel.kilometerSystem[0].kilometer"
type="number"
@blur="onUpdate"
@ -27,7 +25,6 @@
/>
<q-select
outlined
style="margin-top: 10px"
v-model="turnoutModel.kilometerSystem[1].coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
@ -37,7 +34,6 @@
></q-select>
<q-input
outlined
style="margin-top: 10px"
v-model.number="turnoutModel.kilometerSystem[1].kilometer"
type="number"
@blur="onUpdate"
@ -67,6 +63,15 @@
>
</template>
</q-field>
<q-select
outlined
v-model="turnoutModel.centralizedStation"
:options="centralizedStations"
emitValue
mapOptions
@update:model-value="onUpdate"
label="关联的集中站"
/>
</q-form>
</template>
@ -74,9 +79,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 +130,21 @@ const turnoutRelations = computed(() => {
}(${relation.getOtherRelationParam(turnout).param})`
);
});
const centralizedStations = ref<{ label: string; value: number }[]>([]);
onMounted(() => {
const stations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type);
centralizedStations.value = [{ label: '', value: 0 }];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.name,
value: station.datas.id,
});
}
});
});
</script>

View File

@ -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<graphicData.ConcentrationDividingLine>();
}
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);
}
}

View File

@ -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());

View File

@ -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());
}

View File

@ -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());
}

View File

@ -68,6 +68,12 @@ 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;
}
clone(): StationData {
return new StationData(this.data.cloneMessage());
}

View File

@ -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());
}

View File

@ -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<IGraphicStorage> {
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,

View File

@ -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);

View File

@ -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<IConcentrationDividingLineData>();
}
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>(Section.Type)
.filter((g) => g.datas.sectionType == SectionType.Physical);
const hasNodeSection = new Map<number, string>();
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<Turnout | Section>(
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<Section | Turnout>(sectionAId);
const sectionBId = b.leftSection ? b.leftSection.id : b.rightSection.id;
const sectionB = this.queryStore.queryById<Section | Turnout>(sectionBId);
return (
sectionA.localToCanvasPoint(
getRectangleCenter(sectionA.getLocalBounds())
).y -
sectionB.localToCanvasPoint(
getRectangleCenter(sectionB.getLocalBounds())
).y
);
});
this.datas.nodeConWithSecs = nodeConWithSecs;
}
}
export class ConcentrationDividingLineTemplate extends JlGraphicTemplate<ConcentrationDividingLine> {
constructor(dataTemplate: IConcentrationDividingLineData) {
super(ConcentrationDividingLine.Type, { dataTemplate });
}
new() {
const g = new ConcentrationDividingLine();
g.loadData(this.datas);
return g;
}
}

View File

@ -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<ConcentrationDividingLine> {
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>(
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>(
PolylineEditPlugin.Name
);
if (lep) {
lep.hideAll();
}
}
}

View File

@ -0,0 +1,192 @@
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';
//判断线段与线段有木有交点
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<Section | Turnout>(
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[],
centralizedStations: number[]
) {
interface GraphicData {
centralizedStations: number[];
}
const dataMap = new Map<string, GraphicDataBase>([
[Turnout.Type, new TurnoutData()],
[Section.Type, new SectionData()],
[Signal.Type, new SignalData()],
]);
devices.forEach((device) => {
const data = dataMap.get(device.type);
if (data) {
data.copyFrom(device.saveData());
const dataCopy = data as GraphicDataBase & GraphicData;
dataCopy.centralizedStations = centralizedStations;
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;
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -23,6 +23,8 @@ export interface IStationData extends GraphicData {
set concentrationStations(v: boolean);
get name(): string; //车站名称
set name(v: string);
get manageStations(): number[]; //集中站管理的车站
set manageStations(v: number[]);
clone(): IStationData;
copyFrom(data: IStationData): void;
eq(other: IStationData): boolean;

View File

@ -16,7 +16,7 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
_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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -6,26 +6,14 @@
<q-btn color="accent" label="功能菜单">
<q-menu>
<q-list style="min-width: 100px">
<q-item clickable v-close-popup @click="saveAllDrawDatas">
<q-item-section>保存</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="saveAsDialog = true">
<q-item-section>另存为</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="buildRelations">
<q-item-section>一键关联</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="oneClickGeneration">
<q-item-section>一键生成车次窗</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="oneClickSeparator">
<q-item-section>一键生成分隔符</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="oneClickAxleCounting">
<q-item-section>一键生成计轴</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="oneClickTurnoutSection">
<q-item-section>一键生成道岔区段</q-item-section>
<q-item
v-for="item in leftMenuConfig"
:key="item.label"
clickable
v-close-popup
@click="item.click"
>
<q-item-section>{{ item.label }}</q-item-section>
</q-item>
</q-list>
</q-menu>
@ -174,7 +162,7 @@
<script setup lang="ts">
import DrawProperties from 'src/components/draw-app/DrawProperties.vue';
import { getDrawApp, saveDrawDatas, saveDrawToServer } from 'src/drawApp';
import { IDrawApp } from 'jl-graphic';
import { distance2, IDrawApp } from 'jl-graphic';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
@ -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,
@ -363,6 +372,204 @@ function oneClickTurnoutSection() {
SDA.generateTurnoutSection();
}
/* function oneClickRelateCentralizedStation() {
const drawApp = drawStore.getDrawApp();
const concentrationDividingLines = drawApp.queryStore
.queryByType<ConcentrationDividingLine>(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);
//
const signals = drawApp.queryStore.queryByType<Signal>(Signal.Type);
concentrationDividingLines.forEach((concentrationDividingLine) => {
concentrationDividingLine.datas.nodeConWithSecs.forEach(
(nodeConWithSec) => {
const ids = [
nodeConWithSec.leftSection.id,
nodeConWithSec.rightSection.id,
];
if (ids[0] && ids[1]) {
if (
nodeConWithSec.leftSection.deviceType ==
graphicData.RelatedRef.DeviceType.Section
) {
handleNodeConWithSec(nodeConWithSec.leftSection, ids);
} else {
handleNodeConWithSec(nodeConWithSec.rightSection, ids);
}
}
}
);
});
function handleNodeConWithSec(
relatedRef: graphicData.RelatedRef,
ids: number[]
) {
const section = drawApp.queryStore.queryById<Section>(relatedRef.id);
const portPos =
relatedRef.devicePort == graphicData.RelatedRef.DevicePort.A
? section.localToCanvasPoint(section.getStartPoint())
: section.localToCanvasPoint(section.getEndPoint());
signals.forEach((signal) => {
if (
distance2(portPos, signal.position) < 100 &&
ids.includes(signal.datas.refDevice?.id as number)
) {
signal.datas.centralizedStation =
ids[0] == signal.datas.refDevice?.id
? drawApp.queryStore.queryById<Section>(ids[1]).datas
.centralizedStation
: drawApp.queryStore.queryById<Section>(ids[0]).datas
.centralizedStation;
}
});
}
function handleContainDevices(
containDeviceIds: number[],
centralizedStations: number
) {
const containDevices = containDeviceIds.map((id) => {
return drawApp.queryStore.queryById(id);
});
const signals = drawApp.queryStore
.queryByType<Signal>(Signal.Type)
.filter((g) =>
containDeviceIds.includes(g.datas.refDevice?.id as number)
);
const allSetCentralizedStationsDevice = [...containDevices, ...signals];
allSetCentralizedStationsDevice.forEach(
(g) => ((g as Signal).datas.centralizedStation = [])
);
handleCentralizedStationsData(
allSetCentralizedStationsDevice,
centralizedStations
);
}
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, []);
} 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, []);
} else {
handleContainDevices(containDeviceIds, [
rightBoundary.datas.refRightStationId,
]);
}
}
} */
function backConfirm() {
router.go(-1);
}

View File

@ -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<typeof Canvas.prototype.toObject>;
links?: ReturnType<typeof Link.prototype.toObject>[];
@ -227,6 +237,7 @@ export namespace graphicData {
axleCountings?: ReturnType<typeof AxleCounting.prototype.toObject>[];
separators?: ReturnType<typeof Separator.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
}): 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<typeof AxleCounting.prototype.toObject>[];
separators?: ReturnType<typeof Separator.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
} = {};
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<typeof CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof Point.prototype.toObject>[];
oldrefLeftStationId?: string;
oldrefRightStationId?: string;
nodeConWithSecs?: ReturnType<typeof NodeConWithSec.prototype.toObject>[];
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<typeof CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof Point.prototype.toObject>[];
oldrefLeftStationId?: string;
oldrefRightStationId?: string;
nodeConWithSecs?: ReturnType<typeof NodeConWithSec.prototype.toObject>[];
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<typeof RelatedRef.prototype.toObject>;
rightSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
}): 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<typeof RelatedRef.prototype.toObject>;
rightSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
} = {};
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<typeof CommonInfo.prototype.toObject>;
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,10 @@ export namespace graphicData {
concentrationStations?: boolean;
kilometerSystem?: KilometerSystem;
name?: string;
manageStations?: number[];
}) {
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 +2404,9 @@ 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;
}
}
}
get common() {
@ -2051,6 +2451,12 @@ 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);
}
static fromObject(data: {
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
code?: string;
@ -2058,6 +2464,7 @@ export namespace graphicData {
concentrationStations?: boolean;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>;
name?: string;
manageStations?: number[];
}): Station {
const message = new Station({});
if (data.common != null) {
@ -2078,6 +2485,9 @@ export namespace graphicData {
if (data.name != null) {
message.name = data.name;
}
if (data.manageStations != null) {
message.manageStations = data.manageStations;
}
return message;
}
toObject() {
@ -2088,6 +2498,7 @@ export namespace graphicData {
concentrationStations?: boolean;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>;
name?: string;
manageStations?: number[];
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -2107,6 +2518,9 @@ export namespace graphicData {
if (this.name != null) {
data.name = this.name;
}
if (this.manageStations != null) {
data.manageStations = this.manageStations;
}
return data;
}
serialize(): Uint8Array;
@ -2125,6 +2539,8 @@ 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 (!w)
return writer.getResultBuffer();
}
@ -2152,6 +2568,9 @@ export namespace graphicData {
case 7:
message.name = reader.readString();
break;
case 8:
message.manageStations = reader.readPackedUint32();
break;
default: reader.skipField();
}
}
@ -2904,6 +3323,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 +3355,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 +3426,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<typeof CommonInfo.prototype.toObject>;
code?: string;
@ -3013,6 +3442,7 @@ export namespace graphicData {
pbRef?: ReturnType<typeof RelatedRef.prototype.toObject>;
pcRef?: ReturnType<typeof RelatedRef.prototype.toObject>;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>[];
centralizedStationId?: number;
}): Turnout {
const message = new Turnout({});
if (data.common != null) {
@ -3042,6 +3472,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 +3488,7 @@ export namespace graphicData {
pbRef?: ReturnType<typeof RelatedRef.prototype.toObject>;
pcRef?: ReturnType<typeof RelatedRef.prototype.toObject>;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>[];
centralizedStationId?: number;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -3083,6 +3517,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 +3544,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 +3582,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 +3695,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 +3715,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 +3759,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<typeof CommonInfo.prototype.toObject>;
code?: string;
mirror?: boolean;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>;
refDevice?: ReturnType<typeof RelatedRef.prototype.toObject>;
centralizedStationId?: number;
}): Signal {
const message = new Signal({});
if (data.common != null) {
@ -3336,6 +3789,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 +3801,7 @@ export namespace graphicData {
mirror?: boolean;
kilometerSystem?: ReturnType<typeof KilometerSystem.prototype.toObject>;
refDevice?: ReturnType<typeof RelatedRef.prototype.toObject>;
centralizedStationId?: number;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -3361,6 +3818,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 +3837,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 +3863,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 +4215,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 +4253,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 +4333,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<typeof CommonInfo.prototype.toObject>;
code?: string;
@ -3876,6 +4351,7 @@ export namespace graphicData {
destinationCode?: string;
turning?: boolean;
children?: number[];
centralizedStationId?: number;
}): Section {
const message = new Section({});
if (data.common != null) {
@ -3911,6 +4387,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 +4405,7 @@ export namespace graphicData {
destinationCode?: string;
turning?: boolean;
children?: number[];
centralizedStationId?: number;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -3960,6 +4440,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 +4471,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 +4515,9 @@ export namespace graphicData {
case 11:
message.children = reader.readPackedUint32();
break;
case 12:
message.centralizedStationId = reader.readUint32();
break;
default: reader.skipField();
}
}

View File

@ -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 '多选';
}