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

View File

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

View File

@ -7,6 +7,15 @@
label="id"
hint=""
/>
<q-input
outlined
label="计轴区段索引编号"
type="textarea"
@blur="onUpdate"
v-model="axleCountingSectionModel.indexNumber"
lazy-rules
autogrow
/>
<q-input
outlined
label="计轴区段名称"
@ -16,31 +25,30 @@
lazy-rules
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-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 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"
square
color="primary"
@ -59,19 +67,17 @@
import { AxleCountingSectionData } from 'src/drawApp/graphics/AxleCountingSectionInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
const drawStore = useDrawStore();
const axleCountingSectionModel = reactive(new AxleCountingSectionData());
const kilometerSystem = reactive({ coordinateSystem: '', kilometer: 0 });
const CoordinateSystemOptions = [
{ label: '车辆段', value: 'DEPOT' },
{ label: '停车场', value: 'PARKING_LOT' },
{ label: '正线', value: 'MAIN_LINE' },
{ label: '换线', value: 'TRANSFER' },
];
enum turoutPos {
'定位',
'反位',
}
drawStore.$subscribe;
watch(
@ -101,7 +107,7 @@ function onUpdate() {
}
}
const sectionRelations = computed(() => {
const axleCountingRelations = computed(() => {
const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection;
const sectionRelations =
axleCountingSection?.relationManage.getRelationsOfGraphicAndOtherType(
@ -112,7 +118,22 @@ const sectionRelations = computed(() => {
(relation) =>
`${
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));
});

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="sectionTypeText"
@blur="onUpdate"
label="区段类型"
/>
<q-input
outlined
class="q-mt-lg"
v-model="sectionModel.code"
@blur="onUpdate"
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>
<q-chip
color="primary"
@ -19,7 +43,16 @@
>
</template>
</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>
<q-chip
color="primary"
@ -31,13 +64,37 @@
>
</template>
</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>
</template>
<script setup lang="ts">
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { Section } from 'src/graphics/section/Section';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, shallowRef, watchEffect } from 'vue';
@ -45,11 +102,15 @@ const drawStore = useDrawStore();
const sectionModel = shallowRef(new SectionData());
const sectionTypeText = computed(() => {
return ['物理区段', '', '道岔物理区段'][sectionModel.value.sectionType];
});
const sectionRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const sectionRelations =
section?.relationManage.getRelationsOfGraphicAndOtherType(
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
Section.Type
);
@ -65,7 +126,7 @@ const turnoutRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const turnoutRelations =
section?.relationManage.getRelationsOfGraphicAndOtherType(
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
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(() => {
const section = drawStore.selectedGraphic;
if (section && section instanceof Section) {

View File

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

View File

@ -3,6 +3,7 @@ import { GraphicDataBase } from './GraphicDataBase';
import {
IAxleCountingSectionData,
AxleCountingSection,
ITurnoutPosRefData,
} from 'src/graphics/axleCountingSection/AxleCountingSection';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { IPointData } from 'pixi.js';
@ -51,6 +52,18 @@ export class AxleCountingSectionData
set pbRef(ref: graphicData.RelatedRef) {
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 {
return new AxleCountingSectionData(this.data.cloneMessage());
}

View File

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

View File

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

View File

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

View File

@ -118,7 +118,7 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
}
axleCounting.id = GraphicIdGenerator.next();
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);
axleCounting.loadRelations();
}

View File

@ -9,15 +9,26 @@ import {
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
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 {
get code(): string; // 编号
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
get paRef(): IRelatedRefData | undefined;
get paRef(): IRelatedRefData | undefined; //区段A端关联的设备
set paRef(ref: IRelatedRefData | undefined);
get pbRef(): IRelatedRefData | undefined;
get pbRef(): IRelatedRefData | undefined; //区段B端关联的设备
set pbRef(ref: IRelatedRefData | undefined);
get turnoutPosRef(): ITurnoutPosRefData[]; //关联道岔的定反位--0是定位1是反位
set turnoutPosRef(ref: ITurnoutPosRefData[]);
get indexNumber(): number; // 索引编号
set indexNumber(v: number);
clone(): IAxleCountingSectionData;
copyFrom(data: IAxleCountingSectionData): void;
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 {
GraphicDrawAssistant,
GraphicIdGenerator,
@ -6,6 +13,7 @@ import {
JlDrawApp,
JlGraphic,
linePoint,
splitLineEvenly,
} from 'src/jl-graphic';
import {
@ -13,10 +21,18 @@ import {
AxleCountingSection,
AxleCountingSectionTemplate,
AxleCountingSectionConsts,
ITurnoutPosRefData,
} from './AxleCountingSection';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { Turnout } from '../turnout/Turnout';
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[]) {
for (let i = 0; i < arr1.length; i++) {
@ -50,7 +66,7 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
super(app, template, 'sym_o_circle', '不展示');
this.codeGraph = this.graphicTemplate.new();
this.container.addChild(this.codeGraph);
AxleCountingSectionInteraction.init(app);
AxleCountingSectionInteraction.init(app, this);
}
bind(): void {
@ -74,7 +90,12 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
data.transform = this.container.saveTransform();
return true;
}
draw(graphics: AxleCounting[], map: Map<string, number>) {
draw(
graphics: AxleCounting[],
commonElement: JlGraphic[],
map: Map<string, number>,
turoutPos?: number
) {
if (
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`)
@ -89,8 +110,32 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
axleCountingSection.id = GraphicIdGenerator.next();
const paRef = createRelatedRefProto(graphics[0].type, graphics[0].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.pbRef = pbRef;
axleCountingSection.datas.turnoutPosRef = turnoutPosData;
this.storeGraphic(axleCountingSection);
axleCountingSection.loadRelations();
}
@ -124,6 +169,8 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
if (commonElementId) {
const commonElement = this.app.queryStore.queryById(commonElementId);
let draw = true;
let turoutPos = 0;
//道岔BC端处的计轴不构成计轴区段
if (commonElement.type == 'Turnout') {
let targetPort, port;
axleCounting.datas.axleCountingRef.forEach((ref) => {
@ -142,9 +189,17 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
) {
draw = false;
}
if (targetPort == 2 || port == 2) {
turoutPos = 1;
}
}
if (draw) {
this.draw([axleCounting, axleCountings[i]], map);
this.draw(
[axleCounting, axleCountings[i]],
[commonElement],
map,
turoutPos
);
}
}
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) => {
axleCountings.forEach((axleCounting) => {
//计轴关联的道岔
@ -176,7 +235,10 @@ export class AxleCountingSectionDraw extends GraphicDrawAssistant<
refAxleCounting.id !== axleCountings[0].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) {
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);
if (
fourAxleCounting[x].axleCounting.id ==
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;
}
}
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);
if (
fourAxleCounting[x + 1].axleCounting.id ==
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;
}
}
@ -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> {
static Name = 'AxleCountingSection_transform';
constructor(app: JlDrawApp) {
drawAssistant: AxleCountingSectionDraw;
constructor(app: JlDrawApp, da: AxleCountingSectionDraw) {
super(AxleCountingSectionInteraction.Name, app);
this.drawAssistant = da;
app.registerMenu(SectionEditMenu);
}
static init(app: JlDrawApp) {
return new AxleCountingSectionInteraction(app);
static init(app: JlDrawApp, da: AxleCountingSectionDraw) {
return new AxleCountingSectionInteraction(app, da);
}
filter(...grahpics: JlGraphic[]): AxleCountingSection[] | undefined {
return grahpics
@ -243,6 +344,7 @@ export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<Axl
g.labelGraphic.cursor = 'pointer';
g.labelGraphic.selectable = true;
g.labelGraphic.draggable = true;
g.on('_rightclick', this.onContextMenu, this);
}
unbind(g: AxleCountingSection): void {
g.eventMode = 'none';
@ -256,5 +358,71 @@ export class AxleCountingSectionInteraction extends GraphicInteractionPlugin<Axl
g.labelGraphic.draggable = false;
g.labelGraphic.selectable = 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,
VectorText,
} from 'src/jl-graphic';
import { IRelatedRefData, protoPort2Data } from '../CommonGraphics';
import { SectionPort } from '../section/Section';
export interface ILogicSectionData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
get paRef(): IRelatedRefData | undefined;
set paRef(ref: IRelatedRefData | undefined);
get pbRef(): IRelatedRefData | undefined;
set pbRef(ref: IRelatedRefData | undefined);
get axleSectionId(): string; // 计轴区段ID
set axleSectionId(v: string);
get indexNumber(): number; // 索引编号
set indexNumber(v: number);
clone(): ILogicSectionData;
copyFrom(data: ILogicSectionData): void;
eq(other: ILogicSectionData): boolean;
@ -87,23 +85,13 @@ export class LogicSection extends JlGraphic {
this.updateData(old);
}
loadRelations() {
if (this.datas?.paRef?.id) {
this.relationManage.addRelation(
new GraphicRelationParam(this, SectionPort.A),
new GraphicRelationParam(
this.queryStore.queryById(this.datas.paRef.id),
protoPort2Data(this.datas.paRef.devicePort)
)
);
}
if (this.datas?.pbRef?.id) {
this.relationManage.addRelation(
new GraphicRelationParam(this, SectionPort.B),
new GraphicRelationParam(
this.queryStore.queryById(this.datas.pbRef.id),
protoPort2Data(this.datas.pbRef.devicePort)
)
);
if (this.datas?.axleSectionId) {
const axleSection = this.queryStore.queryById(this.datas.axleSectionId);
axleSection &&
this.relationManage.addRelation(
new GraphicRelationParam(this),
new GraphicRelationParam(axleSection)
);
}
}
}

View File

@ -1,7 +1,5 @@
import { FederatedPointerEvent, IHitArea, IPointData, Point } from 'pixi.js';
import { FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant,
GraphicIdGenerator,
GraphicInteractionPlugin,
@ -16,28 +14,9 @@ import {
LogicSectionTemplate,
LogicSectionConsts,
} from './LogicSection';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { Turnout } from '../turnout/Turnout';
import { createRelatedRefProto } from '../CommonGraphics';
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;
}
import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { AxleCountingSection } from '../axleCountingSection/AxleCountingSection';
export interface ILogicSectionDrawOptions {
newData: () => ILogicSectionData;
@ -76,20 +55,10 @@ export class LogicSectionDraw extends GraphicDrawAssistant<
data.transform = this.container.saveTransform();
return true;
}
draw(graphics: JlGraphic[], map: Map<string, number>) {
if (
map.has(`${graphics[0].id}+${graphics[1].id}`) ||
map.has(`${graphics[1].id}+${graphics[0].id}`)
)
return;
draw(data: ILogicSectionData) {
const logicSection = new LogicSection();
logicSection.loadData(this.graphicTemplate.datas);
logicSection.datas.points = [graphics[0].position, graphics[1].position];
logicSection.loadData(data);
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);
logicSection.loadRelations();
}
@ -99,118 +68,39 @@ export class LogicSectionDraw extends GraphicDrawAssistant<
const logicSections = this.app.queryStore.queryByType<LogicSection>(
LogicSection.Type
);
// this.app.deleteGraphics(...logicSections);
// return;
logicSections.forEach((logicSection) => {
map.set(
`${logicSection.datas.paRef?.id}+${logicSection.datas.pbRef?.id}`,
1
);
map.set(`${logicSection.datas.axleSectionId}`, 1);
});
const axleCountings = this.app.queryStore.queryByType<AxleCounting>(
AxleCounting.Type
);
const hasfourTurnout: AxleCounting[][] = [];
axleCountings.forEach((axleCounting) => {
const refDeviceTarget = axleCounting.datas.axleCountingRef.map(
(ref) => ref.id
const axleCountingSections =
this.app.queryStore.queryByType<AxleCountingSection>(
AxleCountingSection.Type
);
for (let i = 0; i < axleCountings.length - 1; i++) {
if (axleCountings[i].id == axleCounting.id) return;
const refDevice = axleCountings[i].datas.axleCountingRef.map(
(ref) => ref.id
);
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 (
(targetPort == 1 && port == 2) ||
(targetPort == 2 && port == 1)
) {
draw = false;
}
axleCountingSections.forEach((axleCountingSection) => {
const turnoutPosRef = axleCountingSection.datas.turnoutPosRef;
if (turnoutPosRef.length > 0) {
turnoutPosRef.forEach((turnout) => {
if (turnout.position == 1 && !map.has(`${turnout.id}`)) {
map.set(`${turnout.id}`, 1);
const t = this.app.queryStore.queryById(turnout.id) as Turnout;
const data = new LogicSectionData();
data.points = [
t.position,
...t.localToCanvasPoints(...t.datas.pointC),
];
data.axleSectionId = axleCountingSection.id;
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;
}
if (!map.has(`${axleCountingSection.id}`)) {
map.set(`${axleCountingSection.id}`, 1);
const data = new LogicSectionData();
data.points = axleCountingSection.datas.points;
data.axleSectionId = axleCountingSection.id;
this.draw(data);
}
}
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';
import { Turnout } from '../turnout/Turnout';
import Vector2 from 'src/jl-graphic/math/Vector2';
import { AxleCounting } from '../axleCounting/AxleCounting';
export enum SectionType {
Physical = 0,
@ -40,8 +41,10 @@ export interface ISectionData extends GraphicData {
set pbRef(ref: IRelatedRefData | undefined);
get sectionType(): SectionType;
set sectionType(type: SectionType);
get children(): string[];
set children(children: string[]);
get axleCountings(): string[]; //计轴id列表
set axleCountings(axleCountings: string[]);
get index(): number; // 索引
set index(v: number);
clone(): ISectionData;
copyFrom(data: ISectionData): void;
eq(other: ISectionData): boolean;
@ -73,16 +76,15 @@ export class Section extends JlGraphic implements ILineGraphic {
}
doRepaint() {
if (this.datas.points.length < 2) {
if (
this.datas.sectionType === SectionType.Physical &&
this.datas.points.length < 2
) {
throw new Error('Link坐标数据异常');
}
this.lineGraphic.clear();
if (
(this.datas.sectionType === SectionType.Physical &&
this.datas.children.length === 0) /* 未拆分的物理区段 */ ||
this.datas.sectionType === SectionType.Logic /* 逻辑区段 */
) {
if (this.datas.sectionType === SectionType.Physical) {
this.lineGraphic.lineStyle(
SectionConsts.lineWidth,
SectionConsts.lineColor
@ -180,50 +182,52 @@ export class Section extends JlGraphic implements ILineGraphic {
buildRelation() {
this.relationManage.deleteRelationOfGraphicAndOtherType(this, Section.Type);
/** 区段与区段 */
this.queryStore.queryByType<Section>(Section.Type).forEach((section) => {
if (section.id === this.id) return;
let param: SectionPort[] = [];
if (
distance2(
this.localToCanvasPoint(this.getStartPoint()),
section.localToCanvasPoint(section.getStartPoint())
) <= epsilon
) {
param = [SectionPort.A, SectionPort.A];
}
if (
distance2(
this.localToCanvasPoint(this.getEndPoint()),
section.localToCanvasPoint(section.getStartPoint())
) <= epsilon
) {
param = [SectionPort.B, SectionPort.A];
}
if (
distance2(
this.localToCanvasPoint(this.getStartPoint()),
section.localToCanvasPoint(section.getEndPoint())
) <= epsilon
) {
param = [SectionPort.A, SectionPort.B];
}
if (
distance2(
this.localToCanvasPoint(this.getEndPoint()),
section.localToCanvasPoint(section.getEndPoint())
) <= epsilon
) {
param = [SectionPort.B, SectionPort.B];
}
if (param.length) {
this.relationManage.addRelation(
new GraphicRelationParam(this, param[0]),
new GraphicRelationParam(section, param[1])
);
}
});
if (this.datas.sectionType === SectionType.Physical) {
this.queryStore.queryByType<Section>(Section.Type).forEach((section) => {
if (section.id === this.id) return;
let param: SectionPort[] = [];
if (
distance2(
this.localToCanvasPoint(this.getStartPoint()),
section.localToCanvasPoint(section.getStartPoint())
) <= epsilon
) {
param = [SectionPort.A, SectionPort.A];
}
if (
distance2(
this.localToCanvasPoint(this.getEndPoint()),
section.localToCanvasPoint(section.getStartPoint())
) <= epsilon
) {
param = [SectionPort.B, SectionPort.A];
}
if (
distance2(
this.localToCanvasPoint(this.getStartPoint()),
section.localToCanvasPoint(section.getEndPoint())
) <= epsilon
) {
param = [SectionPort.A, SectionPort.B];
}
if (
distance2(
this.localToCanvasPoint(this.getEndPoint()),
section.localToCanvasPoint(section.getEndPoint())
) <= epsilon
) {
param = [SectionPort.B, SectionPort.B];
}
if (param.length) {
this.relationManage.addRelation(
new GraphicRelationParam(this, param[0]),
new GraphicRelationParam(section, param[1])
);
}
});
}
}
saveRelations() {
@ -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,
JlGraphic,
VectorText,
calculateLineMidpoint,
linePoint,
} from 'src/jl-graphic';
import {
@ -43,10 +44,11 @@ import AbsorbablePoint, {
import { Turnout, TurnoutPort } from '../turnout/Turnout';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
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 { graphicData } from 'src/protos/stationLayoutGraphics';
import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue';
import { AxleCounting } from '../axleCounting/AxleCounting';
export class SectionDraw extends GraphicDrawAssistant<
SectionTemplate,
@ -124,6 +126,78 @@ export class SectionDraw extends GraphicDrawAssistant<
this.points = [];
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 {
@ -132,6 +206,9 @@ class SectionGraphicHitArea implements IHitArea {
this.section = section;
}
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++) {
const p1 = this.section.datas.points[i - 1];
const p2 = this.section.datas.points[i];
@ -345,8 +422,10 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
const target = e.target as DisplayObject;
const section = target.getGraphic() as Section;
this.app.updateSelected(section);
if (section.datas.sectionType === SectionType.TurnoutPhysical) {
return;
}
const p = section.screenToLocalPoint(e.global);
addWaypointConfig.handler = () => {
const linePoints = section.linePoints;
const { start, end } = getWaypointRangeIndex(
@ -360,89 +439,77 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
clearWaypointsConfig.handler = () => {
clearWayPoint(section, false);
};
if (
section.datas.children &&
section.datas.sectionType === SectionType.Physical
) {
splitSectionConfig.disabled = false;
splitSectionConfig.handler = () => {
Dialog.create({
title: '拆分区段',
message: '请选择生成数量和方向',
component: SectionSplitDialog,
cancel: true,
persistent: true,
}).onOk((data: { num: number; dir: 'ltr' | 'rtl' }) => {
const { num, dir } = data;
const sectionData = section.datas;
const points = section.getSplitPoints(num);
const children: Section[] = [];
let codeAppend = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.slice(0, num);
if (
(dir === 'ltr' &&
sectionData.points[0].x >
sectionData.points[sectionData.points.length - 1].x) ||
(dir === 'rtl' &&
sectionData.points[0].x <
sectionData.points[sectionData.points.length - 1].x)
) {
codeAppend = codeAppend.split('').reverse().join('');
}
points.forEach((ps, i) => {
const data = new SectionData();
data.id = this.drawAssistant.nextId();
data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`;
data.sectionType = SectionType.Logic;
data.points = ps.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
data.id = this.drawAssistant.nextId();
data.childTransforms = [
new ChildTransform(
'label',
new GraphicTransform(
{
x:
data.points[0].x +
(data.points[1].x - data.points[0].x) / 2,
y:
data.points[0].y +
(data.points[1].y - data.points[0].y) / 2 +
20,
},
{ x: 0, y: 0 },
0,
{ x: 0, y: 0 }
)
),
];
const g = this.drawAssistant.graphicTemplate.new();
g.loadData(data);
this.drawAssistant.storeGraphic(g);
children.push(g);
});
sectionData.children = children.map((g) => g.datas.id);
section.repaint();
section.buildRelation();
section.draggable = false;
children.forEach((c) => c.buildRelation());
this.app.updateSelected(...children);
splitSectionConfig.disabled = false;
splitSectionConfig.handler = () => {
Dialog.create({
title: '拆分区段',
message: '请选择生成数量和方向',
component: SectionSplitDialog,
cancel: true,
persistent: true,
}).onOk((data: { num: number; dir: 'ltr' | 'rtl' }) => {
const { num, dir } = data;
const sectionData = section.datas;
const points = section.getSplitPoints(num);
const children: Section[] = [];
let codeAppend = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.slice(0, num);
if (
(dir === 'ltr' &&
sectionData.points[0].x >
sectionData.points[sectionData.points.length - 1].x) ||
(dir === 'rtl' &&
sectionData.points[0].x <
sectionData.points[sectionData.points.length - 1].x)
) {
codeAppend = codeAppend.split('').reverse().join('');
}
points.forEach((ps, i) => {
const data = new SectionData();
data.id = this.drawAssistant.nextId();
data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`;
// data.sectionType = SectionType.Logic;
data.points = ps.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
data.id = this.drawAssistant.nextId();
data.childTransforms = [
new ChildTransform(
'label',
new GraphicTransform(
{
x:
data.points[0].x +
(data.points[1].x - data.points[0].x) / 2,
y:
data.points[0].y +
(data.points[1].y - data.points[0].y) / 2 +
20,
},
{ x: 0, y: 0 },
0,
{ x: 0, y: 0 }
)
),
];
const g = this.drawAssistant.graphicTemplate.new();
g.loadData(data);
this.drawAssistant.storeGraphic(g);
children.push(g);
});
};
} else {
splitSectionConfig.disabled = true;
}
// sectionData.children = children.map((g) => g.datas.id);
section.repaint();
section.buildRelation();
section.draggable = false;
children.forEach((c) => c.buildRelation());
this.app.updateSelected(...children);
});
};
SectionEditMenu.open(e.global);
}
onSelected(g: DisplayObject): void {
const section = g as Section;
if (
section.datas.children.length > 0 &&
section.datas.sectionType === SectionType.Physical
) {
if (section.datas.sectionType === SectionType.TurnoutPhysical) {
return;
}
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> {

View File

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

View File

@ -320,6 +320,11 @@ export interface IGraphicAppConfig {
* true
*/
cullable?: boolean;
/**
*
*/
isSupportDeletion?: (g: JlGraphic) => boolean;
}
/**
@ -729,8 +734,19 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
*
* @param graphics
*/
deleteGraphics(...graphics: JlGraphic[]) {
graphics.forEach((g) => this.doDeleteGraphics(g));
deleteGraphics(...graphics: JlGraphic[]): JlGraphic[] {
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-section>一键生成Link</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="oneClickTurnoutSection">
<q-item-section>一键生成道岔区段</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@ -204,6 +207,8 @@ import { SectionLinkDraw } from 'src/graphics/sectionLink/SectionLinkDrawAssista
import { store } from 'quasar/wrappers';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
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 { LogicSectionDraw } from 'src/graphics/logicSection/LogicSectionDrawAssistant';
@ -370,10 +375,17 @@ function oneClickLink() {
drawStore.getDrawApp().deleteGraphics(...linkList);
const draw = drawStore
.getDrawApp()
.getDrawAssistant(SectionLink.Type) as SectionLinkDraw;
.getDrawAssistant<SectionLinkDraw>(SectionLink.Type);
draw.oneGenerates();
}
function oneClickTurnoutSection() {
const SDA = drawStore
.getDrawApp()
.getDrawAssistant<SectionDraw>(Section.Type);
SDA.generateTurnoutSection();
}
function backConfirm() {
router.go(-1);
}