This commit is contained in:
fan 2023-07-12 13:05:50 +08:00
commit 9db9816ef7
22 changed files with 787 additions and 370 deletions

@ -1 +1 @@
Subproject commit 0a0cb0a77afd9783081c2dc6ba19687b0b3aa0f7 Subproject commit f89c8eb48de7b2e39a93c4aab9b4e5ff1a9e91b4

View File

@ -77,6 +77,10 @@
drawStore.selectedGraphicType === AxleCountingSection.Type drawStore.selectedGraphicType === AxleCountingSection.Type
" "
></axle-counting-section-property> ></axle-counting-section-property>
<LogicSectionProperty
v-else-if="drawStore.selectedGraphicType === LogicSection.Type"
>
</LogicSectionProperty>
<separator-property <separator-property
v-else-if="drawStore.selectedGraphicType === Separator.Type" v-else-if="drawStore.selectedGraphicType === Separator.Type"
></separator-property> ></separator-property>
@ -104,6 +108,7 @@ import StationProperty from './properties/StationProperty.vue';
import TrainWindowProperty from './properties/TrainWindowProperty.vue'; import TrainWindowProperty from './properties/TrainWindowProperty.vue';
import AxleCountingProperty from './properties/AxleCountingProperty.vue'; import AxleCountingProperty from './properties/AxleCountingProperty.vue';
import AxleCountingSectionProperty from './properties/AxleCountingSectionProperty.vue'; import AxleCountingSectionProperty from './properties/AxleCountingSectionProperty.vue';
import LogicSectionProperty from './properties/LogicSectionProperty.vue';
import SignalProperty from './properties/SignalProperty.vue'; import SignalProperty from './properties/SignalProperty.vue';
import TurnoutProperty from './properties/TurnoutProperty.vue'; import TurnoutProperty from './properties/TurnoutProperty.vue';
import SectionProperty from './properties/SectionProperty.vue'; import SectionProperty from './properties/SectionProperty.vue';
@ -121,6 +126,7 @@ import { Section } from 'src/graphics/section/Section';
import { TrainWindow } from 'src/graphics/trainWindow/TrainWindow'; import { TrainWindow } from 'src/graphics/trainWindow/TrainWindow';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting'; import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection'; import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
import { Separator } from 'src/graphics/separator/Separator'; import { Separator } from 'src/graphics/separator/Separator';
import { SectionLink } from 'src/graphics/sectionLink/SectionLink'; import { SectionLink } from 'src/graphics/sectionLink/SectionLink';

View File

@ -6,6 +6,15 @@
v-model="axleCountingModel.id" v-model="axleCountingModel.id"
label="id" label="id"
hint="" hint=""
/>
<q-input
outlined
label="计轴索引编号"
type="textarea"
@blur="onUpdate"
v-model="axleCountingModel.indexNumber"
lazy-rules
autogrow
/> />
<q-input <q-input
outlined outlined

View File

@ -7,6 +7,15 @@
label="id" label="id"
hint="" hint=""
/> />
<q-input
outlined
label="计轴区段索引编号"
type="textarea"
@blur="onUpdate"
v-model="axleCountingSectionModel.indexNumber"
lazy-rules
autogrow
/>
<q-input <q-input
outlined outlined
label="计轴区段名称" label="计轴区段名称"
@ -16,31 +25,30 @@
lazy-rules lazy-rules
autogrow autogrow
/> />
<q-select
outlined
style="margin-top: 10px"
v-model="kilometerSystem.coordinateSystem"
:options="CoordinateSystemOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="坐标系"
></q-select>
<q-input
outlined
style="margin-top: 10px"
v-model.number="kilometerSystem.kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-list bordered separator class="rounded-borders"> <q-list bordered separator class="rounded-borders">
<q-item> <q-item>
<q-item-section no-wrap class="q-gutter-y-sm column"> <q-item-section no-wrap class="q-gutter-y-sm column">
<q-item-label> 关联的计轴 </q-item-label> <q-item-label> 关联的计轴 </q-item-label>
<div class="q-gutter-sm row"> <div class="q-gutter-sm row">
<q-chip <q-chip
v-for="item in sectionRelations" v-for="item in axleCountingRelations"
:key="item"
square
color="primary"
text-color="white"
>
{{ item }}
</q-chip>
</div>
</q-item-section>
</q-item>
<q-item>
<q-item-section no-wrap class="q-gutter-y-sm column">
<q-item-label> 关联道岔的位置关系 </q-item-label>
<div class="q-gutter-sm row">
<q-chip
v-for="item in turnoutRelations"
:key="item" :key="item"
square square
color="primary" color="primary"
@ -59,19 +67,17 @@
import { AxleCountingSectionData } from 'src/drawApp/graphics/AxleCountingSectionInteraction'; import { AxleCountingSectionData } from 'src/drawApp/graphics/AxleCountingSectionInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting'; import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection'; import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue'; import { computed, onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const axleCountingSectionModel = reactive(new AxleCountingSectionData()); const axleCountingSectionModel = reactive(new AxleCountingSectionData());
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
const CoordinateSystemOptions = [ enum turoutPos {
{ label: '车辆段', value: 'DEPOT' }, '定位',
{ label: '停车场', value: 'PARKING_LOT' }, '反位',
{ label: '正线', value: 'MAIN_LINE' }, }
{ label: '换线', value: 'TRANSFER' },
];
drawStore.$subscribe; drawStore.$subscribe;
watch( watch(
@ -101,7 +107,7 @@ function onUpdate() {
} }
} }
const sectionRelations = computed(() => { const axleCountingRelations = computed(() => {
const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection; const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection;
const sectionRelations = const sectionRelations =
axleCountingSection?.relationManage.getRelationsOfGraphicAndOtherType( axleCountingSection?.relationManage.getRelationsOfGraphicAndOtherType(
@ -112,7 +118,22 @@ const sectionRelations = computed(() => {
(relation) => (relation) =>
`${ `${
relation.getOtherGraphic<AxleCounting>(axleCountingSection).datas.code relation.getOtherGraphic<AxleCounting>(axleCountingSection).datas.code
}(${relation.getOtherRelationParam(axleCountingSection).param})` }`
);
return Array.from(new Set(ref));
});
const turnoutRelations = computed(() => {
const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection;
const refTurnoutAndPos: { turnout: Turnout; pos: number }[] = [];
axleCountingSection?.datas.turnoutPosRef.forEach((ref) => {
const refTurout = axleCountingSection.queryStore.queryById(
ref.id
) as Turnout;
refTurnoutAndPos.push({ turnout: refTurout, pos: ref.position });
});
const ref = refTurnoutAndPos.map(
(ref) => `${ref.turnout.datas.code}:${turoutPos[ref.pos]}`
); );
return Array.from(new Set(ref)); return Array.from(new Set(ref));
}); });

View File

@ -0,0 +1,92 @@
<template>
<q-form class="q-gutter-sm">
<q-input
outlined
readonly
v-model="logicSectionModel.id"
label="id"
hint=""
/>
<q-input
outlined
label="索引编号"
type="textarea"
@blur="onUpdate"
v-model="logicSectionModel.indexNumber"
lazy-rules
autogrow
/>
<q-input
outlined
label="逻辑区段名称"
type="textarea"
@blur="onUpdate"
v-model="logicSectionModel.code"
lazy-rules
autogrow
/>
<q-list bordered separator class="rounded-borders">
<q-item>
<q-item-section no-wrap class="q-gutter-y-sm column">
<q-item-label> 关联的计轴区段 </q-item-label>
<div class="q-gutter-sm row">
<q-chip
v-for="item in logicSectionRelations"
:key="item"
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 { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore();
const logicSectionModel = reactive(new LogicSectionData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == LogicSection.Type) {
logicSectionModel.copyFrom(val.saveData() as LogicSectionData);
}
}
);
onMounted(() => {
const logicSection = drawStore.selectedGraphic as LogicSection;
if (logicSection) {
logicSectionModel.copyFrom(logicSection.saveData());
}
});
function onUpdate() {
const logicSection = drawStore.selectedGraphic as LogicSection;
if (logicSection) {
drawStore
.getDrawApp()
.updateGraphicAndRecord(logicSection, logicSectionModel);
}
}
const logicSectionRelations = computed(() => {
const logicSection = drawStore.selectedGraphic as LogicSection;
const axleCountingSection = logicSection.queryStore.queryById(
logicSection.datas.axleSectionId
) as AxleCountingSection;
return [axleCountingSection.datas.code];
});
</script>

View File

@ -3,11 +3,35 @@
<q-input outlined readonly v-model="sectionModel.id" label="id" hint="" /> <q-input outlined readonly v-model="sectionModel.id" label="id" hint="" />
<q-input <q-input
outlined outlined
readonly
v-model="sectionTypeText"
@blur="onUpdate"
label="区段类型"
/>
<q-input
outlined
class="q-mt-lg"
v-model="sectionModel.code" v-model="sectionModel.code"
@blur="onUpdate" @blur="onUpdate"
label="编号" label="编号"
/> />
<q-field class="q-mt-lg" outlined label="关联区段" readonly stack-label> <q-input
outlined
class="q-mt-lg"
v-model.number="sectionModel.index"
@blur="onUpdate"
label="索引"
/>
<q-field
v-if="
sectionModel.sectionType === graphicData.Section.SectionType.Physical
"
class="q-mt-lg"
outlined
label="关联区段"
readonly
stack-label
>
<template #control> <template #control>
<q-chip <q-chip
color="primary" color="primary"
@ -19,7 +43,16 @@
> >
</template> </template>
</q-field> </q-field>
<q-field class="q-mt-lg" outlined label="关联道岔" readonly stack-label> <q-field
v-if="
sectionModel.sectionType === graphicData.Section.SectionType.Physical
"
class="q-mt-lg"
outlined
label="关联道岔"
readonly
stack-label
>
<template #control> <template #control>
<q-chip <q-chip
color="primary" color="primary"
@ -31,13 +64,37 @@
> >
</template> </template>
</q-field> </q-field>
<q-field
v-if="
sectionModel.sectionType ===
graphicData.Section.SectionType.TurnoutPhysical
"
class="q-mt-lg"
outlined
label="计轴"
readonly
stack-label
>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in axleCountingRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
</q-form> </q-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { SectionData } from 'src/drawApp/graphics/SectionInteraction'; import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { Section } from 'src/graphics/section/Section'; import { Section } from 'src/graphics/section/Section';
import { Turnout } from 'src/graphics/turnout/Turnout'; import { Turnout } from 'src/graphics/turnout/Turnout';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { computed, shallowRef, watchEffect } from 'vue'; import { computed, shallowRef, watchEffect } from 'vue';
@ -45,11 +102,15 @@ const drawStore = useDrawStore();
const sectionModel = shallowRef(new SectionData()); const sectionModel = shallowRef(new SectionData());
const sectionTypeText = computed(() => {
return ['物理区段', '', '道岔物理区段'][sectionModel.value.sectionType];
});
const sectionRelations = computed(() => { const sectionRelations = computed(() => {
const section = drawStore.selectedGraphic as Section; const section = drawStore.selectedGraphic as Section;
const sectionRelations = const sectionRelations =
section?.relationManage.getRelationsOfGraphicAndOtherType( section.relationManage.getRelationsOfGraphicAndOtherType(
section, section,
Section.Type Section.Type
); );
@ -65,7 +126,7 @@ const turnoutRelations = computed(() => {
const section = drawStore.selectedGraphic as Section; const section = drawStore.selectedGraphic as Section;
const turnoutRelations = const turnoutRelations =
section?.relationManage.getRelationsOfGraphicAndOtherType( section.relationManage.getRelationsOfGraphicAndOtherType(
section, section,
Turnout.Type Turnout.Type
); );
@ -77,6 +138,20 @@ const turnoutRelations = computed(() => {
); );
}); });
const axleCountingRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const axleCountingRelations =
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
AxleCounting.Type
);
console.log(section.relationManage.getRelationsOfGraphic(section));
return axleCountingRelations.map(
(relation) => relation.getOtherGraphic<AxleCounting>(section).datas.code
);
});
watchEffect(() => { watchEffect(() => {
const section = drawStore.selectedGraphic; const section = drawStore.selectedGraphic;
if (section && section instanceof Section) { if (section && section instanceof Section) {

View File

@ -44,6 +44,12 @@ export class AxleCountingData
set axleCountingRef(points: graphicData.RelatedRef[]) { set axleCountingRef(points: graphicData.RelatedRef[]) {
this.data.axleCountingRef = points; this.data.axleCountingRef = points;
} }
get indexNumber(): number {
return this.data.indexNumber;
}
set indexNumber(v: number) {
this.data.indexNumber = v;
}
clone(): AxleCountingData { clone(): AxleCountingData {
return new AxleCountingData(this.data.cloneMessage()); return new AxleCountingData(this.data.cloneMessage());
} }

View File

@ -3,6 +3,7 @@ import { GraphicDataBase } from './GraphicDataBase';
import { import {
IAxleCountingSectionData, IAxleCountingSectionData,
AxleCountingSection, AxleCountingSection,
ITurnoutPosRefData,
} from 'src/graphics/axleCountingSection/AxleCountingSection'; } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
import { IPointData } from 'pixi.js'; import { IPointData } from 'pixi.js';
@ -51,6 +52,18 @@ export class AxleCountingSectionData
set pbRef(ref: graphicData.RelatedRef) { set pbRef(ref: graphicData.RelatedRef) {
this.data.pbRef = ref; this.data.pbRef = ref;
} }
get turnoutPosRef(): ITurnoutPosRefData[] {
return this.data.turnoutPos;
}
set turnoutPosRef(points: ITurnoutPosRefData[]) {
this.data.turnoutPos = points.map((p) => new graphicData.TurnoutPosRef(p));
}
get indexNumber(): number {
return this.data.indexNumber;
}
set indexNumber(v: number) {
this.data.indexNumber = v;
}
clone(): AxleCountingSectionData { clone(): AxleCountingSectionData {
return new AxleCountingSectionData(this.data.cloneMessage()); return new AxleCountingSectionData(this.data.cloneMessage());
} }

View File

@ -11,7 +11,7 @@ export class LogicSectionData
extends GraphicDataBase extends GraphicDataBase
implements ILogicSectionData implements ILogicSectionData
{ {
constructor(data?: graphicData.AxleCountingSection) { constructor(data?: graphicData.LogicSection) {
let logicSection; let logicSection;
if (!data) { if (!data) {
logicSection = new graphicData.AxleCountingSection({ logicSection = new graphicData.AxleCountingSection({
@ -22,8 +22,8 @@ export class LogicSectionData
} }
super(logicSection); super(logicSection);
} }
public get data(): graphicData.AxleCountingSection { public get data(): graphicData.LogicSection {
return this.getData<graphicData.AxleCountingSection>(); return this.getData<graphicData.LogicSection>();
} }
get code(): string { get code(): string {
return this.data.code; return this.data.code;
@ -39,17 +39,17 @@ export class LogicSectionData
(p) => new graphicData.Point({ x: p.x, y: p.y }) (p) => new graphicData.Point({ x: p.x, y: p.y })
); );
} }
get paRef(): graphicData.RelatedRef { get axleSectionId(): string {
return this.data.paRef; return this.data.axleSectionId;
} }
set paRef(ref: graphicData.RelatedRef) { set axleSectionId(v: string) {
this.data.paRef = ref; this.data.axleSectionId = v;
} }
get pbRef(): graphicData.RelatedRef { get indexNumber(): number {
return this.data.pbRef; return this.data.indexNumber;
} }
set pbRef(ref: graphicData.RelatedRef) { set indexNumber(v: number) {
this.data.pbRef = ref; this.data.indexNumber = v;
} }
clone(): LogicSectionData { clone(): LogicSectionData {
return new LogicSectionData(this.data.cloneMessage()); return new LogicSectionData(this.data.cloneMessage());

View File

@ -25,6 +25,12 @@ export class SectionData extends GraphicDataBase implements ISectionData {
set code(v: string) { set code(v: string) {
this.data.code = v; this.data.code = v;
} }
get index(): number {
return this.data.index;
}
set index(index: number) {
this.data.index = index;
}
get points(): IPointData[] { get points(): IPointData[] {
return this.data.points; return this.data.points;
} }
@ -51,11 +57,11 @@ export class SectionData extends GraphicDataBase implements ISectionData {
set sectionType(type: graphicData.Section.SectionType) { set sectionType(type: graphicData.Section.SectionType) {
this.data.sectionType = type; this.data.sectionType = type;
} }
get children(): string[] { get axleCountings(): string[] {
return this.data.children; return this.data.axleCountings;
} }
set children(children: string[]) { set axleCountings(axleCountings: string[]) {
this.data.children = children; this.data.axleCountings = axleCountings;
} }
clone(): SectionData { clone(): SectionData {
return new SectionData(this.data.cloneMessage()); return new SectionData(this.data.cloneMessage());

View File

@ -16,6 +16,8 @@ export interface IAxleCountingData extends GraphicData {
set kilometerSystem(v: KilometerSystem); set kilometerSystem(v: KilometerSystem);
get axleCountingRef(): IRelatedRefData[]; //关联的设备 get axleCountingRef(): IRelatedRefData[]; //关联的设备
set axleCountingRef(ref: IRelatedRefData[]); set axleCountingRef(ref: IRelatedRefData[]);
get indexNumber(): number; // 索引编号
set indexNumber(v: number);
clone(): IAxleCountingData; clone(): IAxleCountingData;
copyFrom(data: IAxleCountingData): void; copyFrom(data: IAxleCountingData): void;
eq(other: IAxleCountingData): boolean; eq(other: IAxleCountingData): boolean;

View File

@ -118,7 +118,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
} }
axleCounting.id = GraphicIdGenerator.next(); axleCounting.id = GraphicIdGenerator.next();
axleCounting.datas.axleCountingRef = [refData2, refData1]; axleCounting.datas.axleCountingRef = [refData2, refData1];
axleCounting.datas.code = `${graphic.datas.code}-${port}+${refGraphic.datas.code}-${refPort}`; axleCounting.datas.code = `${graphic.datas.code}-${port}\\${refGraphic.datas.code}-${refPort}`;
this.storeGraphic(axleCounting); this.storeGraphic(axleCounting);
axleCounting.loadRelations(); axleCounting.loadRelations();
} }

View File

@ -9,15 +9,26 @@ import {
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics'; import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
import { SectionPort } from '../section/Section'; import { SectionPort } from '../section/Section';
export interface ITurnoutPosRefData {
get id(): string; //道岔的ID
set id(v: string);
get position(): number; //道岔的正反为0是正位1是反位
set position(v: number);
}
export interface IAxleCountingSectionData extends GraphicData { export interface IAxleCountingSectionData extends GraphicData {
get code(): string; // 编号 get code(): string; // 编号
set code(v: string); set code(v: string);
get points(): IPointData[]; // 线坐标点 get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]); set points(points: IPointData[]);
get paRef(): IRelatedRefData | undefined; get paRef(): IRelatedRefData | undefined; //区段A端关联的设备
set paRef(ref: IRelatedRefData | undefined); set paRef(ref: IRelatedRefData | undefined);
get pbRef(): IRelatedRefData | undefined; get pbRef(): IRelatedRefData | undefined; //区段B端关联的设备
set pbRef(ref: IRelatedRefData | undefined); set pbRef(ref: IRelatedRefData | undefined);
get turnoutPosRef(): ITurnoutPosRefData[]; //关联道岔的定反位--0是定位1是反位
set turnoutPosRef(ref: ITurnoutPosRefData[]);
get indexNumber(): number; // 索引编号
set indexNumber(v: number);
clone(): IAxleCountingSectionData; clone(): IAxleCountingSectionData;
copyFrom(data: IAxleCountingSectionData): void; copyFrom(data: IAxleCountingSectionData): void;
eq(other: IAxleCountingSectionData): boolean; eq(other: IAxleCountingSectionData): boolean;
@ -105,6 +116,17 @@ export class AxleCountingSection extends JlGraphic {
) )
); );
} }
if (this.datas?.turnoutPosRef.length) {
this.datas.turnoutPosRef.forEach((ref) => {
this.relationManage.addRelation(
this,
new GraphicRelationParam(
this.queryStore.queryById(ref.id),
ref.position
)
);
});
}
} }
} }

View File

@ -1,4 +1,11 @@
import { FederatedPointerEvent, IHitArea, IPointData, Point } from 'pixi.js'; import {
DisplayObject,
FederatedMouseEvent,
FederatedPointerEvent,
IHitArea,
IPointData,
Point,
} from 'pixi.js';
import { import {
GraphicDrawAssistant, GraphicDrawAssistant,
GraphicIdGenerator, GraphicIdGenerator,
@ -6,6 +13,7 @@ import {
JlDrawApp, JlDrawApp,
JlGraphic, JlGraphic,
linePoint, linePoint,
splitLineEvenly,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { import {
@ -13,10 +21,18 @@ import {
AxleCountingSection, AxleCountingSection,
AxleCountingSectionTemplate, AxleCountingSectionTemplate,
AxleCountingSectionConsts, AxleCountingSectionConsts,
ITurnoutPosRefData,
} from './AxleCountingSection'; } from './AxleCountingSection';
import { AxleCounting } from '../axleCounting/AxleCounting'; import { AxleCounting } from '../axleCounting/AxleCounting';
import { Turnout } from '../turnout/Turnout'; import { Turnout } from '../turnout/Turnout';
import { createRelatedRefProto } from '../CommonGraphics'; import { createRelatedRefProto } from '../CommonGraphics';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import { Dialog } from 'quasar';
import { LogicSection } from '../logicSection/LogicSection';
import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue';
function hasCommonElements(arr1: string[], arr2: string[]) { function hasCommonElements(arr1: string[], arr2: string[]) {
for (let i = 0; i < arr1.length; i++) { for (let i = 0; i < arr1.length; i++) {
@ -50,7 +66,7 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
super(app, template, 'sym_o_circle', '不展示'); super(app, template, 'sym_o_circle', '不展示');
this.codeGraph = this.graphicTemplate.new(); this.codeGraph = this.graphicTemplate.new();
this.container.addChild(this.codeGraph); this.container.addChild(this.codeGraph);
AxleCountingSectionInteraction.init(app); AxleCountingSectionInteraction.init(app, this);
} }
bind(): void { bind(): void {
@ -74,7 +90,12 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
data.transform = this.container.saveTransform(); data.transform = this.container.saveTransform();
return true; return true;
} }
draw(graphics: AxleCounting[], map: Map<string, number>) { draw(
graphics: AxleCounting[],
commonElement: JlGraphic[],
map: Map<string, number>,
turoutPos?: number
) {
if ( if (
map.has(`${graphics[0].id}+${graphics[1].id}`) || map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`) map.has(`${graphics[1].id}+${graphics[0].id}`)
@ -89,8 +110,32 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
axleCountingSection.id = GraphicIdGenerator.next(); axleCountingSection.id = GraphicIdGenerator.next();
const paRef = createRelatedRefProto(graphics[0].type, graphics[0].id); const paRef = createRelatedRefProto(graphics[0].type, graphics[0].id);
const pbRef = createRelatedRefProto(graphics[1].type, graphics[1].id); const pbRef = createRelatedRefProto(graphics[1].type, graphics[1].id);
const turnoutPosData: ITurnoutPosRefData[] = [];
if (commonElement[0].type == 'Turnout') {
commonElement.forEach((Turnout) => {
if (commonElement.length > 1) {
turnoutPosData.push({
id: Turnout.id,
position: 0,
});
} else {
if (turoutPos == 0) {
turnoutPosData.push({
id: Turnout.id,
position: 0,
});
} else {
turnoutPosData.push({
id: Turnout.id,
position: 1,
});
}
}
});
}
axleCountingSection.datas.paRef = paRef; axleCountingSection.datas.paRef = paRef;
axleCountingSection.datas.pbRef = pbRef; axleCountingSection.datas.pbRef = pbRef;
axleCountingSection.datas.turnoutPosRef = turnoutPosData;
this.storeGraphic(axleCountingSection); this.storeGraphic(axleCountingSection);
axleCountingSection.loadRelations(); axleCountingSection.loadRelations();
} }
@ -124,6 +169,8 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
if (commonElementId) { if (commonElementId) {
const commonElement = this.app.queryStore.queryById(commonElementId); const commonElement = this.app.queryStore.queryById(commonElementId);
let draw = true; let draw = true;
let turoutPos = 0;
//道岔BC端处的计轴不构成计轴区段
if (commonElement.type == 'Turnout') { if (commonElement.type == 'Turnout') {
let targetPort, port; let targetPort, port;
axleCounting.datas.axleCountingRef.forEach((ref) => { axleCounting.datas.axleCountingRef.forEach((ref) => {
@ -142,9 +189,17 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
) { ) {
draw = false; draw = false;
} }
if (targetPort == 2 || port == 2) {
turoutPos = 1;
}
} }
if (draw) { if (draw) {
this.draw([axleCounting, axleCountings[i]], map); this.draw(
[axleCounting, axleCountings[i]],
[commonElement],
map,
turoutPos
);
} }
} }
if (hasSamePosition(axleCounting, axleCountings[i])) { if (hasSamePosition(axleCounting, axleCountings[i])) {
@ -152,7 +207,11 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
} }
} }
}); });
const fourAxleCounting: AxleCounting[] = []; //补4个道岔处的BB连接处的计轴区段
const fourAxleCounting: {
axleCounting: AxleCounting;
refTurout: Turnout;
}[] = [];
hasfourTurnout.forEach((axleCountings) => { hasfourTurnout.forEach((axleCountings) => {
axleCountings.forEach((axleCounting) => { axleCountings.forEach((axleCounting) => {
//计轴关联的道岔 //计轴关联的道岔
@ -176,7 +235,10 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
refAxleCounting.id !== axleCountings[0].id && refAxleCounting.id !== axleCountings[0].id &&
refAxleCounting.id !== axleCountings[1].id refAxleCounting.id !== axleCountings[1].id
) { ) {
fourAxleCounting.push(refAxleCounting); fourAxleCounting.push({
axleCounting: refAxleCounting,
refTurout: refTurnout,
});
} }
}); });
}); });
@ -185,16 +247,40 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
for (let x = 0; x < fourAxleCounting.length; x += 4) { for (let x = 0; x < fourAxleCounting.length; x += 4) {
const AxleCountings = fourAxleCounting.slice(x, x + 4); const AxleCountings = fourAxleCounting.slice(x, x + 4);
for (let y = 0; y < 4; y++) { for (let y = 0; y < 4; y++) {
if (fourAxleCounting[x].id == AxleCountings[y].id) continue; if (
if (fourAxleCounting[x].y == AxleCountings[y].y) { fourAxleCounting[x].axleCounting.id ==
this.draw([fourAxleCounting[x], AxleCountings[y]], map); AxleCountings[y].axleCounting.id
)
continue;
if (
fourAxleCounting[x].axleCounting.y == AxleCountings[y].axleCounting.y
) {
this.draw(
[fourAxleCounting[x].axleCounting, AxleCountings[y].axleCounting],
[fourAxleCounting[x].refTurout, AxleCountings[y].refTurout],
map
);
break; break;
} }
} }
for (let y = 0; y < 4; y++) { for (let y = 0; y < 4; y++) {
if (fourAxleCounting[x + 1].id == AxleCountings[y].id) continue; if (
if (fourAxleCounting[x + 1].y == AxleCountings[y].y) { fourAxleCounting[x + 1].axleCounting.id ==
this.draw([fourAxleCounting[x + 1], AxleCountings[y]], map); AxleCountings[y].axleCounting.id
)
continue;
if (
fourAxleCounting[x + 1].axleCounting.y ==
AxleCountings[y].axleCounting.y
) {
this.draw(
[
fourAxleCounting[x + 1].axleCounting,
AxleCountings[y].axleCounting,
],
[fourAxleCounting[x + 1].refTurout, AxleCountings[y].refTurout],
map
);
break; break;
} }
} }
@ -218,13 +304,28 @@ class AxleCountingSectionGraphicHitArea implements IHitArea {
} }
} }
export const splitSectionConfig: MenuItemOptions = {
name: '拆分计轴区段',
};
const SectionEditMenu: ContextMenu = ContextMenu.init({
name: '区段编辑菜单',
groups: [
{
items: [splitSectionConfig],
},
],
});
export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<AxleCountingSection> { export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<AxleCountingSection> {
static Name = 'AxleCountingSection_transform'; static Name = 'AxleCountingSection_transform';
constructor(app: JlDrawApp) { drawAssistant: AxleCountingSectionDraw;
constructor(app: JlDrawApp, da: AxleCountingSectionDraw) {
super(AxleCountingSectionInteraction.Name, app); super(AxleCountingSectionInteraction.Name, app);
this.drawAssistant = da;
app.registerMenu(SectionEditMenu);
} }
static init(app: JlDrawApp) { static init(app: JlDrawApp, da: AxleCountingSectionDraw) {
return new AxleCountingSectionInteraction(app); return new AxleCountingSectionInteraction(app, da);
} }
filter(...grahpics: JlGraphic[]): AxleCountingSection[] | undefined { filter(...grahpics: JlGraphic[]): AxleCountingSection[] | undefined {
return grahpics return grahpics
@ -243,6 +344,7 @@ export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<Axl
g.labelGraphic.cursor = 'pointer'; g.labelGraphic.cursor = 'pointer';
g.labelGraphic.selectable = true; g.labelGraphic.selectable = true;
g.labelGraphic.draggable = true; g.labelGraphic.draggable = true;
g.on('_rightclick', this.onContextMenu, this);
} }
unbind(g: AxleCountingSection): void { unbind(g: AxleCountingSection): void {
g.eventMode = 'none'; g.eventMode = 'none';
@ -256,5 +358,71 @@ export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<Axl
g.labelGraphic.draggable = false; g.labelGraphic.draggable = false;
g.labelGraphic.selectable = false; g.labelGraphic.selectable = false;
g.labelGraphic.transformSave = false; g.labelGraphic.transformSave = false;
g.off('_rightclick', this.onContextMenu, this);
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const axleCountingSection = target.getGraphic() as AxleCountingSection;
this.app.updateSelected(axleCountingSection);
splitSectionConfig.handler = () => {
Dialog.create({
title: '拆分逻辑区段',
message: '请选择生成数量和方向',
component: SectionSplitDialog,
cancel: true,
persistent: true,
}).onOk((data: { num: number; dir: 'ltr' | 'rtl' }) => {
const logicSections = this.app.queryStore.queryByType<LogicSection>(
LogicSection.Type
);
logicSections.forEach((logicSection) => {
if (logicSection.datas.axleSectionId == axleCountingSection.id) {
this.app.deleteGraphics(logicSection);
}
});
const { num, dir } = data;
const axleCountingSectionData = axleCountingSection.datas;
const points = splitLineEvenly(
axleCountingSection.localToCanvasPoint(
axleCountingSectionData.points[0]
),
axleCountingSection.localToCanvasPoint(
axleCountingSectionData.points[
axleCountingSectionData.points.length - 1
]
),
num
);
// let codeAppend = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.slice(0, num);
if (
(dir === 'ltr' &&
axleCountingSectionData.points[0].x >
axleCountingSectionData.points[
axleCountingSectionData.points.length - 1
].x) ||
(dir === 'rtl' &&
axleCountingSectionData.points[0].x <
axleCountingSectionData.points[
axleCountingSectionData.points.length - 1
].x)
) {
// codeAppend = codeAppend.split('').reverse().join('');
}
points.forEach((ps, i) => {
const data = new LogicSectionData();
data.id = GraphicIdGenerator.next();
data.axleSectionId = axleCountingSection.id;
// data.code = `${codeAppend.charAt(i % 26)}`;
data.points = ps.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
const g = new LogicSection();
g.loadData(data);
this.drawAssistant.storeGraphic(g);
});
});
};
SectionEditMenu.open(e.global);
} }
} }

View File

@ -6,18 +6,16 @@ import {
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
import { SectionPort } from '../section/Section';
export interface ILogicSectionData extends GraphicData { export interface ILogicSectionData extends GraphicData {
get code(): string; // 编号 get code(): string; // 编号
set code(v: string); set code(v: string);
get points(): IPointData[]; // 线坐标点 get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]); set points(points: IPointData[]);
get paRef(): IRelatedRefData | undefined; get axleSectionId(): string; // 计轴区段ID
set paRef(ref: IRelatedRefData | undefined); set axleSectionId(v: string);
get pbRef(): IRelatedRefData | undefined; get indexNumber(): number; // 索引编号
set pbRef(ref: IRelatedRefData | undefined); set indexNumber(v: number);
clone(): ILogicSectionData; clone(): ILogicSectionData;
copyFrom(data: ILogicSectionData): void; copyFrom(data: ILogicSectionData): void;
eq(other: ILogicSectionData): boolean; eq(other: ILogicSectionData): boolean;
@ -87,22 +85,12 @@ export class LogicSection extends JlGraphic {
this.updateData(old); this.updateData(old);
} }
loadRelations() { loadRelations() {
if (this.datas?.paRef?.id) { if (this.datas?.axleSectionId) {
const axleSection = this.queryStore.queryById(this.datas.axleSectionId);
axleSection &&
this.relationManage.addRelation( this.relationManage.addRelation(
new GraphicRelationParam(this, SectionPort.A), new GraphicRelationParam(this),
new GraphicRelationParam( new GraphicRelationParam(axleSection)
this.queryStore.queryById(this.datas.paRef.id),
protoPort2Data(this.datas.paRef.devicePort)
)
);
}
if (this.datas?.pbRef?.id) {
this.relationManage.addRelation(
new GraphicRelationParam(this, SectionPort.B),
new GraphicRelationParam(
this.queryStore.queryById(this.datas.pbRef.id),
protoPort2Data(this.datas.pbRef.devicePort)
)
); );
} }
} }

View File

@ -1,7 +1,5 @@
import { FederatedPointerEvent, IHitArea, IPointData, Point } from 'pixi.js'; import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
import { import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant, GraphicDrawAssistant,
GraphicIdGenerator, GraphicIdGenerator,
GraphicInteractionPlugin, GraphicInteractionPlugin,
@ -16,28 +14,9 @@ import {
LogicSectionTemplate, LogicSectionTemplate,
LogicSectionConsts, LogicSectionConsts,
} from './LogicSection'; } from './LogicSection';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { Turnout } from '../turnout/Turnout'; import { Turnout } from '../turnout/Turnout';
import { createRelatedRefProto } from '../CommonGraphics'; import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { AxleCountingSection } from '../axleCountingSection/AxleCountingSection';
function hasCommonElements(arr1: string[], arr2: string[]) {
for (let i = 0; i < arr1.length; i++) {
if (arr2.includes(arr1[i])) {
return arr1[i];
}
}
return false;
}
function hasSamePosition(point1: IPointData, point2: IPointData): boolean {
if (
Math.abs(point1.x - point2.x) < 20 &&
Math.abs(point1.y - point2.y) < 20
) {
return true;
}
return false;
}
export interface ILogicSectionDrawOptions { export interface ILogicSectionDrawOptions {
newData: () => ILogicSectionData; newData: () => ILogicSectionData;
@ -76,20 +55,10 @@ export class LogicSectionDraw extends GraphicDrawAssistant<
data.transform = this.container.saveTransform(); data.transform = this.container.saveTransform();
return true; return true;
} }
draw(graphics: JlGraphic[], map: Map<string, number>) { draw(data: ILogicSectionData) {
if (
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`)
)
return;
const logicSection = new LogicSection(); const logicSection = new LogicSection();
logicSection.loadData(this.graphicTemplate.datas); logicSection.loadData(data);
logicSection.datas.points = [graphics[0].position, graphics[1].position];
logicSection.id = GraphicIdGenerator.next(); logicSection.id = GraphicIdGenerator.next();
const paRef = createRelatedRefProto(graphics[0].type, graphics[0].id);
const pbRef = createRelatedRefProto(graphics[1].type, graphics[1].id);
logicSection.datas.paRef = paRef;
logicSection.datas.pbRef = pbRef;
this.storeGraphic(logicSection); this.storeGraphic(logicSection);
logicSection.loadRelations(); logicSection.loadRelations();
} }
@ -99,118 +68,39 @@ export class LogicSectionDraw extends GraphicDrawAssistant<
const logicSections = this.app.queryStore.queryByType<LogicSection>( const logicSections = this.app.queryStore.queryByType<LogicSection>(
LogicSection.Type LogicSection.Type
); );
// this.app.deleteGraphics(...logicSections);
// return;
logicSections.forEach((logicSection) => { logicSections.forEach((logicSection) => {
map.set( map.set(`${logicSection.datas.axleSectionId}`, 1);
`${logicSection.datas.paRef?.id}+${logicSection.datas.pbRef?.id}`, });
1 const axleCountingSections =
this.app.queryStore.queryByType<AxleCountingSection>(
AxleCountingSection.Type
); );
}); axleCountingSections.forEach((axleCountingSection) => {
const axleCountings = this.app.queryStore.queryByType<AxleCounting>( const turnoutPosRef = axleCountingSection.datas.turnoutPosRef;
AxleCounting.Type if (turnoutPosRef.length > 0) {
); turnoutPosRef.forEach((turnout) => {
const hasfourTurnout: AxleCounting[][] = []; if (turnout.position == 1 && !map.has(`${turnout.id}`)) {
axleCountings.forEach((axleCounting) => { map.set(`${turnout.id}`, 1);
const refDeviceTarget = axleCounting.datas.axleCountingRef.map( const t = this.app.queryStore.queryById(turnout.id) as Turnout;
(ref) => ref.id const data = new LogicSectionData();
); data.points = [
for (let i = 0; i < axleCountings.length - 1; i++) { t.position,
if (axleCountings[i].id == axleCounting.id) return; ...t.localToCanvasPoints(...t.datas.pointC),
const refDevice = axleCountings[i].datas.axleCountingRef.map( ];
(ref) => ref.id data.axleSectionId = axleCountingSection.id;
); this.draw(data);
const commonElementId = hasCommonElements(refDeviceTarget, refDevice);
if (commonElementId) {
const commonElement = this.app.queryStore.queryById(commonElementId);
let draw = true;
if (commonElement.type == 'Turnout') {
let targetPort, port;
axleCounting.datas.axleCountingRef.forEach((ref) => {
if (ref.id == commonElementId) {
targetPort = ref.devicePort;
} }
}); });
axleCountings[i].datas.axleCountingRef.forEach((ref) => {
if (ref.id == commonElementId) {
port = ref.devicePort;
} }
}); if (!map.has(`${axleCountingSection.id}`)) {
if ( map.set(`${axleCountingSection.id}`, 1);
(targetPort == 1 && port == 2) || const data = new LogicSectionData();
(targetPort == 2 && port == 1) data.points = axleCountingSection.datas.points;
) { data.axleSectionId = axleCountingSection.id;
draw = false; this.draw(data);
} }
}
if (draw) {
this.draw([axleCounting, axleCountings[i]], map);
}
}
if (hasSamePosition(axleCounting, axleCountings[i])) {
hasfourTurnout.push([axleCounting, axleCountings[i]]);
}
}
});
const fourAxleCounting: AxleCounting[] = [];
hasfourTurnout.forEach((axleCountings) => {
axleCountings.forEach((axleCounting) => {
//计轴关联的道岔
const axleCountingRelations =
axleCounting.relationManage.getRelationsOfGraphicAndOtherType(
axleCounting,
Turnout.Type
);
axleCountingRelations.forEach((relation) => {
const refTurnout = relation.getOtherGraphic<Turnout>(axleCounting);
//道岔关联的计轴
const turnoutRelations =
refTurnout.relationManage.getRelationsOfGraphicAndOtherType(
refTurnout,
AxleCounting.Type
);
turnoutRelations.forEach((relation) => {
const refAxleCounting =
relation.getOtherGraphic<AxleCounting>(refTurnout);
if (
refAxleCounting.id !== axleCountings[0].id &&
refAxleCounting.id !== axleCountings[1].id
) {
fourAxleCounting.push(refAxleCounting);
}
});
});
});
});
for (let x = 0; x < fourAxleCounting.length; x += 4) {
const AxleCountings = fourAxleCounting.slice(x, x + 4);
for (let y = 0; y < 4; y++) {
if (fourAxleCounting[x].id == AxleCountings[y].id) continue;
if (fourAxleCounting[x].y == AxleCountings[y].y) {
this.draw([fourAxleCounting[x], AxleCountings[y]], map);
break;
}
}
for (let y = 0; y < 4; y++) {
if (fourAxleCounting[x + 1].id == AxleCountings[y].id) continue;
if (fourAxleCounting[x + 1].y == AxleCountings[y].y) {
this.draw([fourAxleCounting[x + 1], AxleCountings[y]], map);
break;
}
}
}
const turnouts = this.app.queryStore.queryByType<Turnout>(Turnout.Type);
turnouts.forEach((turnout) => {
const turnoutRelations =
turnout.relationManage.getRelationsOfGraphicAndOtherType(
turnout,
AxleCounting.Type
);
turnoutRelations.forEach((ref) => {
const t = ref.getRelationParam(turnout);
const other = ref.getOtherGraphic(turnout) as AxleCounting;
if (t.param == 'C') {
this.draw([turnout, other], map);
}
});
}); });
} }
} }

View File

@ -17,6 +17,7 @@ import {
} from '../CommonGraphics'; } from '../CommonGraphics';
import { Turnout } from '../turnout/Turnout'; import { Turnout } from '../turnout/Turnout';
import Vector2 from 'src/jl-graphic/math/Vector2'; import Vector2 from 'src/jl-graphic/math/Vector2';
import { AxleCounting } from '../axleCounting/AxleCounting';
export enum SectionType { export enum SectionType {
Physical = 0, Physical = 0,
@ -40,8 +41,10 @@ export interface ISectionData extends GraphicData {
set pbRef(ref: IRelatedRefData | undefined); set pbRef(ref: IRelatedRefData | undefined);
get sectionType(): SectionType; get sectionType(): SectionType;
set sectionType(type: SectionType); set sectionType(type: SectionType);
get children(): string[]; get axleCountings(): string[]; //计轴id列表
set children(children: string[]); set axleCountings(axleCountings: string[]);
get index(): number; // 索引
set index(v: number);
clone(): ISectionData; clone(): ISectionData;
copyFrom(data: ISectionData): void; copyFrom(data: ISectionData): void;
eq(other: ISectionData): boolean; eq(other: ISectionData): boolean;
@ -73,16 +76,15 @@ export class Section extends JlGraphic implements ILineGraphic {
} }
doRepaint() { doRepaint() {
if (this.datas.points.length < 2) { if (
this.datas.sectionType === SectionType.Physical &&
this.datas.points.length < 2
) {
throw new Error('Link坐标数据异常'); throw new Error('Link坐标数据异常');
} }
this.lineGraphic.clear(); this.lineGraphic.clear();
if ( if (this.datas.sectionType === SectionType.Physical) {
(this.datas.sectionType === SectionType.Physical &&
this.datas.children.length === 0) /* 未拆分的物理区段 */ ||
this.datas.sectionType === SectionType.Logic /* 逻辑区段 */
) {
this.lineGraphic.lineStyle( this.lineGraphic.lineStyle(
SectionConsts.lineWidth, SectionConsts.lineWidth,
SectionConsts.lineColor SectionConsts.lineColor
@ -180,7 +182,8 @@ export class Section extends JlGraphic implements ILineGraphic {
buildRelation() { buildRelation() {
this.relationManage.deleteRelationOfGraphicAndOtherType(this, Section.Type); this.relationManage.deleteRelationOfGraphicAndOtherType(this, Section.Type);
/** 区段与区段 */
if (this.datas.sectionType === SectionType.Physical) {
this.queryStore.queryByType<Section>(Section.Type).forEach((section) => { this.queryStore.queryByType<Section>(Section.Type).forEach((section) => {
if (section.id === this.id) return; if (section.id === this.id) return;
@ -225,6 +228,7 @@ export class Section extends JlGraphic implements ILineGraphic {
} }
}); });
} }
}
saveRelations() { saveRelations() {
const paRelation = this.relationManage const paRelation = this.relationManage
@ -284,6 +288,14 @@ export class Section extends JlGraphic implements ILineGraphic {
) )
); );
} }
if (this.datas.axleCountings) {
this.datas.axleCountings.forEach((acId) => {
this.relationManage.addRelation(
this,
this.queryStore.queryById<AxleCounting>(acId)
);
});
}
} }
} }

View File

@ -10,6 +10,7 @@ import {
JlDrawApp, JlDrawApp,
JlGraphic, JlGraphic,
VectorText, VectorText,
calculateLineMidpoint,
linePoint, linePoint,
} from 'src/jl-graphic'; } from 'src/jl-graphic';
import { import {
@ -43,10 +44,11 @@ import AbsorbablePoint, {
import { Turnout, TurnoutPort } from '../turnout/Turnout'; import { Turnout, TurnoutPort } from '../turnout/Turnout';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu'; import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu'; import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import { Dialog } from 'quasar'; import { Dialog, date } from 'quasar';
import { SectionData } from 'src/drawApp/graphics/SectionInteraction'; import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue'; import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue';
import { AxleCounting } from '../axleCounting/AxleCounting';
export class SectionDraw extends GraphicDrawAssistant< export class SectionDraw extends GraphicDrawAssistant<
SectionTemplate, SectionTemplate,
@ -124,6 +126,78 @@ export class SectionDraw extends GraphicDrawAssistant<
this.points = []; this.points = [];
this.graphic.clear(); this.graphic.clear();
} }
generateTurnoutSection() {
const turnoutIds: string[] = []; /* 已遍历的道岔id列表 */
const dfs = (turnout: Turnout) => {
const axleCountings: AxleCounting[] = [];
const turnouts: Turnout[] = [];
if (turnoutIds.includes(turnout.datas.id)) return;
turnoutIds.push(turnout.datas.id);
turnouts.push(turnout);
Object.values(TurnoutPort).forEach((port) => {
const currentPortRelated = turnout.getGraphicOfPort(port);
if (
currentPortRelated.some((graphic) => graphic instanceof AxleCounting)
) {
const axleCounting = currentPortRelated.find(
(graphic) => graphic instanceof AxleCounting
) as AxleCounting;
axleCountings.push(axleCounting);
} else {
const nextTurnout = currentPortRelated.find(
(graphic) => graphic instanceof Turnout
) as Turnout;
const result = dfs(nextTurnout);
if (result?.axleCountings) {
axleCountings.push(...result.axleCountings);
turnouts.push(...result.turnouts);
}
}
});
return { axleCountings, turnouts };
};
this.app.queryStore
.queryByType<Turnout>(Turnout.Type)
.forEach((turnout) => {
const result = dfs(turnout);
if (!result || !result.axleCountings.length) {
return;
}
const turnoutPhysicalSectionData = new SectionData();
turnoutPhysicalSectionData.id = this.nextId();
turnoutPhysicalSectionData.sectionType =
graphicData.Section.SectionType.TurnoutPhysical;
turnoutPhysicalSectionData.points = result.axleCountings.map((ac) => {
return new Point(ac.position.x, ac.position.y);
});
turnoutPhysicalSectionData.axleCountings = result.axleCountings.map(
(ac) => ac.datas.id
);
turnoutPhysicalSectionData.code = result.turnouts
.map((t) => t.datas.code)
.join('-');
const labelPosition = calculateLineMidpoint(
result.turnouts[0].position,
result.turnouts[1].position
);
labelPosition.y += 20;
const labelTransform = GraphicTransform.default();
labelTransform.position = labelPosition;
turnoutPhysicalSectionData.childTransforms = [
new ChildTransform('label', labelTransform),
];
const g = this.graphicTemplate.new();
g.position.set(turnout.datas.pointC[0].x, turnout.datas.pointC[0].y);
g.loadData(turnoutPhysicalSectionData);
this.storeGraphic(g);
console.log(g);
g.loadRelations();
});
}
} }
class SectionGraphicHitArea implements IHitArea { class SectionGraphicHitArea implements IHitArea {
@ -132,6 +206,9 @@ class SectionGraphicHitArea implements IHitArea {
this.section = section; this.section = section;
} }
contains(x: number, y: number): boolean { contains(x: number, y: number): boolean {
if (this.section.datas.sectionType === SectionType.TurnoutPhysical) {
return false;
}
for (let i = 1; i < this.section.datas.points.length; i++) { for (let i = 1; i < this.section.datas.points.length; i++) {
const p1 = this.section.datas.points[i - 1]; const p1 = this.section.datas.points[i - 1];
const p2 = this.section.datas.points[i]; const p2 = this.section.datas.points[i];
@ -345,8 +422,10 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
const target = e.target as DisplayObject; const target = e.target as DisplayObject;
const section = target.getGraphic() as Section; const section = target.getGraphic() as Section;
this.app.updateSelected(section); this.app.updateSelected(section);
if (section.datas.sectionType === SectionType.TurnoutPhysical) {
return;
}
const p = section.screenToLocalPoint(e.global); const p = section.screenToLocalPoint(e.global);
addWaypointConfig.handler = () => { addWaypointConfig.handler = () => {
const linePoints = section.linePoints; const linePoints = section.linePoints;
const { start, end } = getWaypointRangeIndex( const { start, end } = getWaypointRangeIndex(
@ -360,11 +439,6 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
clearWaypointsConfig.handler = () => { clearWaypointsConfig.handler = () => {
clearWayPoint(section, false); clearWayPoint(section, false);
}; };
if (
section.datas.children &&
section.datas.sectionType === SectionType.Physical
) {
splitSectionConfig.disabled = false; splitSectionConfig.disabled = false;
splitSectionConfig.handler = () => { splitSectionConfig.handler = () => {
Dialog.create({ Dialog.create({
@ -393,7 +467,7 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
const data = new SectionData(); const data = new SectionData();
data.id = this.drawAssistant.nextId(); data.id = this.drawAssistant.nextId();
data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`; data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`;
data.sectionType = SectionType.Logic; // data.sectionType = SectionType.Logic;
data.points = ps.map( data.points = ps.map(
(p) => new graphicData.Point({ x: p.x, y: p.y }) (p) => new graphicData.Point({ x: p.x, y: p.y })
); );
@ -422,7 +496,7 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
this.drawAssistant.storeGraphic(g); this.drawAssistant.storeGraphic(g);
children.push(g); children.push(g);
}); });
sectionData.children = children.map((g) => g.datas.id); // sectionData.children = children.map((g) => g.datas.id);
section.repaint(); section.repaint();
section.buildRelation(); section.buildRelation();
section.draggable = false; section.draggable = false;
@ -430,19 +504,12 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
this.app.updateSelected(...children); this.app.updateSelected(...children);
}); });
}; };
} else {
splitSectionConfig.disabled = true;
}
SectionEditMenu.open(e.global); SectionEditMenu.open(e.global);
} }
onSelected(g: DisplayObject): void { onSelected(g: DisplayObject): void {
const section = g as Section; const section = g as Section;
if ( if (section.datas.sectionType === SectionType.TurnoutPhysical) {
section.datas.children.length > 0 &&
section.datas.sectionType === SectionType.Physical
) {
return; return;
} }
let lep = section.getAssistantAppend<SectionPolylineEditPlugin>( let lep = section.getAssistantAppend<SectionPolylineEditPlugin>(

View File

@ -375,6 +375,18 @@ export class Turnout extends JlGraphic {
); );
} }
} }
getGraphicOfPort(port: TurnoutPort) {
return this.relationManage
.getRelationsOfGraphic(this)
.filter(
(relation) =>
relation.getRelationParam(this).getParam<TurnoutPort>() === port
)
.map((relation) => {
return relation.getOtherGraphic(this);
});
}
} }
export class TurnoutTemplate extends JlGraphicTemplate<Turnout> { export class TurnoutTemplate extends JlGraphicTemplate<Turnout> {

View File

@ -456,13 +456,13 @@ export class JlDrawApp extends GraphicApp {
* *
*/ */
deleteSelectedGraphics() { deleteSelectedGraphics() {
const deletes = this.selectedGraphics.slice( const deletes = this.deleteGraphics(...this.selectedGraphics);
0, if (deletes.length > 0) {
this.selectedGraphics.length
);
this.deleteGraphics(...this.selectedGraphics);
// 删除图形对象操作记录 // 删除图形对象操作记录
this.opRecord.record(new GraphicDeleteOperation(this, deletes)); this.opRecord.record(new GraphicDeleteOperation(this, deletes));
} else {
console.debug('没有删除元素,不记录');
}
} }
updateCanvasAndRecord(data: ICanvasProperties) { updateCanvasAndRecord(data: ICanvasProperties) {

View File

@ -320,6 +320,11 @@ export interface IGraphicAppConfig {
* true * true
*/ */
cullable?: boolean; cullable?: boolean;
/**
*
*/
isSupportDeletion?: (g: JlGraphic) => boolean;
} }
/** /**
@ -729,8 +734,19 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
* *
* @param graphics * @param graphics
*/ */
deleteGraphics(...graphics: JlGraphic[]) { deleteGraphics(...graphics: JlGraphic[]): JlGraphic[] {
graphics.forEach((g) => this.doDeleteGraphics(g)); const dels = graphics.filter((g) => {
if (
this._options?.isSupportDeletion &&
this._options.isSupportDeletion(g)
) {
this.doDeleteGraphics(g);
return true;
}
console.debug(`type=${g.type},id=${g.id}的图形不支持删除`);
return false;
});
return dels;
} }
/** /**

View File

@ -27,6 +27,9 @@
<q-item clickable v-close-popup @click="oneClickLink"> <q-item clickable v-close-popup @click="oneClickLink">
<q-item-section>一键生成Link</q-item-section> <q-item-section>一键生成Link</q-item-section>
</q-item> </q-item>
<q-item clickable v-close-popup @click="oneClickTurnoutSection">
<q-item-section>一键生成道岔区段</q-item-section>
</q-item>
<q-item <q-item
clickable clickable
v-close-popup v-close-popup
@ -204,6 +207,8 @@ import { SectionLinkDraw } from 'src/graphics/sectionLink/SectionLinkDrawAssista
import { store } from 'quasar/wrappers'; import { store } from 'quasar/wrappers';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection'; import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { AxleCountingSectionDraw } from 'src/graphics/axleCountingSection/AxleCountingSectionAssistant'; import { AxleCountingSectionDraw } from 'src/graphics/axleCountingSection/AxleCountingSectionAssistant';
import { SectionDraw } from 'src/graphics/section/SectionDrawAssistant';
import { Section } from 'src/graphics/section/Section';
import { LogicSection } from 'src/graphics/logicSection/LogicSection'; import { LogicSection } from 'src/graphics/logicSection/LogicSection';
import { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant'; import { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
@ -370,10 +375,17 @@ function oneClickLink() {
drawStore.getDrawApp().deleteGraphics(...linkList); drawStore.getDrawApp().deleteGraphics(...linkList);
const draw = drawStore const draw = drawStore
.getDrawApp() .getDrawApp()
.getDrawAssistant(SectionLink.Type) as SectionLinkDraw; .getDrawAssistant<SectionLinkDraw>(SectionLink.Type);
draw.oneGenerates(); draw.oneGenerates();
} }
function oneClickTurnoutSection() {
const SDA = drawStore
.getDrawApp()
.getDrawAssistant<SectionDraw>(Section.Type);
SDA.generateTurnoutSection();
}
function backConfirm() { function backConfirm() {
router.go(-1); router.go(-1);
} }