电子地图

This commit is contained in:
joylink_zhaoerwei 2024-11-19 16:39:41 +08:00
parent a4e63a4ab6
commit 013b907d13
30 changed files with 2686 additions and 403 deletions

@ -1 +1 @@
Subproject commit 64e48a0441eedd0b7bc926ca922b2fb58075467b
Subproject commit f09c8fb24492d99245119dae9e723fb609b19606

View File

@ -0,0 +1,67 @@
<!-- eslint-disable vue/no-mutating-props -->
<template>
<q-dialog ref="dialogRef">
<q-card style="width: 250px">
<q-card-section>
<q-form ref="myForm" @submit="onAdd" class="q-gutter-md">
<div class="text-h6">添加设备的集中站</div>
<q-select
v-model="stationName"
label="集中站"
dense
outlined
:options="centralizedStations"
emitValue
mapOptions
>
</q-select>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="取消" @click="onDialogCancel" v-close-popup />
<q-btn flat label="确认" type="submit" />
</q-card-actions>
</q-form>
</q-card-section>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
import { QForm, useDialogPluginComponent } from 'quasar';
import { Station } from 'src/graphics/electronicMap/station/Station';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, ref } from 'vue';
const stationName = ref(0);
const centralizedStations = ref<{ label: string; value: number }[]>([]);
defineEmits([...useDialogPluginComponent.emits]);
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
const drawStore = useDrawStore();
onMounted(() => {
const stations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type);
centralizedStations.value = [];
stations.forEach((station) => {
if (station.datas.concentrationStations) {
centralizedStations.value.push({
label: station.datas.stationName,
value: station.datas.id,
});
}
});
});
const myForm = ref<QForm | null>(null);
function onAdd() {
myForm.value?.validate().then(async (res) => {
if (res) {
onDialogOK(stationName.value);
}
});
}
</script>
<style scoped></style>

View File

@ -0,0 +1,54 @@
<template>
<q-dialog ref="dialogRef">
<q-card>
<q-card-section> <div class="text-h6">区段拆分</div> </q-card-section>
<q-card-section> <div>请选择要拆分的数量和方向</div> </q-card-section>
<q-card-section class="q-pt-none">
<q-input
type="number"
autofocus
dense
outlined
v-model="num"
:min="1"
:max="20"
/>
</q-card-section>
<q-card-section>
<q-select
v-model="dir"
dense
:options="dirOptions"
emitValue
mapOptions
>
</q-select>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="取消" @click="onDialogCancel" v-close-popup />
<q-btn
flat
label="确认"
@click="onDialogOK({ num: Number(num), dir })"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
import { useDialogPluginComponent } from 'quasar';
import { ref } from 'vue';
const num = ref<number>();
const dir = ref('ltr');
const dirOptions = [
{ label: '从左至右', value: 'ltr' },
{ label: '从右至左', value: 'rtl' },
];
defineEmits([...useDialogPluginComponent.emits]);
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
</script>

View File

@ -25,6 +25,15 @@
<platform-property
v-if="drawStore.selectedGraphicType === Platform.Type"
></platform-property>
<station-property
v-else-if="drawStore.selectedGraphicType === Station.Type"
></station-property>
<screenDoor-property
v-else-if="drawStore.selectedGraphicType === ScreenDoor.Type"
></screenDoor-property>
<section-property
v-else-if="drawStore.selectedGraphicType === Section.Type"
></section-property>
</q-card-section>
</template>
<!-- <template v-else-if="drawStore.selectedGraphics.length > 1">
@ -37,13 +46,14 @@
<script setup lang="ts">
import { useDrawStore } from 'src/stores/electronicMap-draw-store';
import CanvasProperty from './properties/CanvasElectronicMapProperty.vue';
import StationProperty from './properties/electronicMap/StationProperty.vue';
import { Station } from 'src/graphics/electronicMap/station/Station';
import PlatformProperty from './properties/electronicMap/PlatformProperty.vue';
import { Platform } from 'src/graphics/electronicMap/platform/Platform';
import { watch } from 'vue';
import ScreenDoorProperty from './properties/electronicMap/ScreenDoorProperty.vue';
import { ScreenDoor } from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
import SectionProperty from './properties/electronicMap/SectionProperty.vue';
import { Section } from 'src/graphics/electronicMap/section/Section';
const drawStore = useDrawStore();
watch(
() => drawStore.selectedGraphics,
() => {}
);
</script>

View File

@ -0,0 +1,55 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="screenDoorModel.id" label="id" />
<q-input
outlined
label="屏蔽门编号"
type="textarea"
@blur="onUpdate"
v-model="screenDoorModel.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 square color="primary" text-color="white">
{{ platformRelation }}
</q-chip>
</div>
</q-item-section>
</q-item>
</q-list>
</q-form>
</template>
<script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils';
import { useDrawStore } from 'src/stores/draw-store';
import { computed } from 'vue';
import { ScreenDoor } from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
import { ScreenDoorData } from 'src/drawApp/graphics/electronicMap/ScreenDoorInteraction';
import { Platform } from 'src/graphics/electronicMap/platform/Platform';
const drawStore = useDrawStore();
const { data: screenDoorModel, onUpdate } = useFormData(
new ScreenDoorData(),
drawStore.getDrawApp()
);
const platformRelation = computed(() => {
const screenDoor = drawStore.selectedGraphic as ScreenDoor;
const refStations = screenDoor?.relationManage
.getRelationsOfGraphicAndOtherType(screenDoor, Platform.Type)
.map(
(relation) => relation.getOtherGraphic<Platform>(screenDoor).datas.code
);
let refStation;
if (refStations) {
refStation = refStations[0];
}
return refStation;
});
</script>

View File

@ -0,0 +1,259 @@
<template>
<q-form>
<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"
@change="onUpdate"
label="编号"
/>
<q-input
outlined
type="number"
class="q-mt-lg"
v-model.number="sectionModel.segmentsCount"
v-if="sectionModel.isCurve"
@blur="onUpdate"
label="曲线分段数"
/>
<q-select
outlined
class="q-mt-lg"
v-model="sectionModel.normalRunningDirection"
:options="runningDirectionOptions"
emit-value
map-options
@blur="onUpdate"
label="常规运行方向"
></q-select>
<q-select
outlined
class="q-mt-lg"
v-model="sectionModel.direction"
:options="directionOptions"
emit-value
map-options
@blur="onUpdate"
label="上下行方向"
></q-select>
<q-checkbox
v-if="
sectionModel.sectionType === electronicMapGraphicData.Section.SectionType.Physical
"
label="是否折返区域"
class="q-mt-lg"
v-model="sectionModel.isTurnBackZone"
@update:model-value="onUpdate"
></q-checkbox>
<q-field
v-if="
sectionModel.sectionType === electronicMapGraphicData.Section.SectionType.Physical
"
class="q-mt-lg"
outlined
label="关联区段"
readonly
stack-label
>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in sectionRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
<q-field
v-if="
sectionModel.sectionType === electronicMapGraphicData.Section.SectionType.Physical
"
class="q-mt-lg"
outlined
label="关联道岔"
readonly
stack-label
>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in turnoutRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
<q-field
v-if="
sectionModel.sectionType ===
electronicMapGraphicData.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-field class="q-mt-lg" outlined label="所属集中站" stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="(id, index) in sectionModel.centralizedStations"
:key="index"
removable
@remove="removeStation(index)"
square
>{{ getName(id) }}</q-chip
>
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
</template>
</q-field>
</q-form>
</template>
<script setup lang="ts">
import { useDrawStore } from 'src/stores/electronicMap-draw-store';
import { useQuasar } from 'quasar';
import { computed } from 'vue';
import { useFormData } from 'src/components/DrawAppFormUtils';
import AddCentralizedStationDialog from 'src/components/draw-app/dialogs/AddCentralizedStationDialog.vue';
import { SectionData } from 'src/drawApp/graphics/electronicMap/SectionInteraction';
import { Section } from 'src/graphics/electronicMap/section/Section';
import { Turnout } from 'src/graphics/electronicMap/turnout/Turnout';
import { AxleCounting } from 'src/graphics/electronicMap/axleCounting/AxleCounting';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { Station } from 'src/graphics/electronicMap/station/Station';
const drawStore = useDrawStore();
const $q = useQuasar();
const { data: sectionModel, onUpdate } = useFormData(
new SectionData(),
drawStore.getDrawApp()
);
const sectionTypeText = computed(() => {
return ['物理区段', '', '道岔物理区段'][sectionModel.sectionType];
});
const runningDirectionOptions = [
{
label: 'A到B',
value: electronicMapGraphicData.Section.RunningDirection.AtoB,
},
{
label: 'B到A',
value: electronicMapGraphicData.Section.RunningDirection.BtoA,
},
{
label: '双向',
value: electronicMapGraphicData.Section.RunningDirection.BOTH,
},
];
const directionOptions = [
{
label: '上行',
value: electronicMapGraphicData.Direction.UP,
},
{
label: '下行',
value: electronicMapGraphicData.Direction.DOWN,
},
];
const sectionRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const sectionRelations =
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
Section.Type
);
return sectionRelations.map(
(relation) =>
`${relation.getRelationParam(section).param}: ${
relation.getOtherGraphic<Section>(section).datas.code
}(${relation.getOtherRelationParam(section).param})`
);
});
const turnoutRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const turnoutRelations =
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
Turnout.Type
);
return turnoutRelations.map(
(relation) =>
`${relation.getRelationParam(section).param}: ${
relation.getOtherGraphic<Turnout>(section).datas.code
}(${relation.getOtherRelationParam(section).param})`
);
});
const axleCountingRelations = computed(() => {
const section = drawStore.selectedGraphic as Section;
const axleCountingRelations =
section.relationManage.getRelationsOfGraphicAndOtherType(
section,
AxleCounting.Type
);
return axleCountingRelations.map(
(relation) => relation.getOtherGraphic<AxleCounting>(section).datas.code
);
});
function removeStation(index: number) {
sectionModel.centralizedStations.splice(index, 1);
onUpdate();
}
function addStation() {
$q.dialog({
title: '',
message: '',
component: AddCentralizedStationDialog,
cancel: true,
persistent: true,
}).onOk((data: number) => {
sectionModel.centralizedStations.push(data);
onUpdate();
});
}
function getName(id: number) {
try {
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
return station.datas.code;
} catch (error) {
return id;
}
}
</script>

View File

@ -0,0 +1,211 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="signalModel.id" label="id" />
<q-input
outlined
v-model="signalModel.code"
@blur="onUpdate"
label="编号"
/>
<q-select
outlined
class="q-mt-sm"
v-model="signalModel.mt"
:options="SignalTypeOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="信号机类型:"
></q-select>
<q-select
outlined
class="q-mt-sm"
v-model="signalModel.direction"
:options="upDownOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="上下行:"
></q-select>
<q-list bordered separator class="rounded-borders">
<q-item no-wrap class="q-gutter-y-sm column">
<div>公里标配置</div>
<q-input
outlined
class="q-mt-sm"
v-model="signalModel.kilometerSystem.coordinateSystem"
@blur="onUpdate"
label="坐标系"
></q-input>
<q-select
outlined
class="q-mt-sm"
v-model="signalModel.kilometerSystem.direction"
:options="directionOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="方向"
></q-select>
<q-input
outlined
class="q-mt-sm"
v-model.number="signalModel.kilometerSystem.kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
</q-item>
</q-list>
<q-select
outlined
class="q-mt-sm"
v-model="refDevData.deviceType"
:options="DeviceTypeOptions"
readonly
map-options
emit-value
label="关联设备类型:"
></q-select>
<q-input
outlined
class="q-mt-sm"
v-model="refDevData.code"
:readonly="true"
label="关联设备:"
></q-input>
<q-select
outlined
v-if="refDevData.deviceType === graphicData.RelatedRef.DeviceType.Turnout"
class="q-mt-sm"
v-model="refDevData.devicePort"
:options="DevicePortOptions"
:readonly="true"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="关联设备端口:"
></q-select>
<q-field class="q-mt-lg" outlined label="所属集中站" stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="(id, index) in signalModel.centralizedStations"
:key="index"
removable
@remove="removeStation(index)"
square
>{{ getName(id) }}</q-chip
>
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
</template>
</q-field>
</q-form>
</template>
<script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils';
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
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 { useQuasar } from 'quasar';
import { computed } from 'vue';
import AddCentralizedStationDialog from '../dialogs/AddCentralizedStationDialog.vue';
import { Station } from 'src/graphics/station/Station';
const drawStore = useDrawStore();
const $q = useQuasar();
const { data: signalModel, onUpdate } = useFormData(
new SignalData(),
drawStore.getDrawApp()
);
const refDevData = computed(() => {
return signalModel.refDev.id
? {
...signalModel.refDev.toObject(),
code: drawStore
.getDrawApp()
.queryStore.queryById<Section | Turnout>(signalModel.refDev.id).datas
.code,
}
: {
id: '',
deviceType: graphicData.RelatedRef.DeviceType.Section,
devicePort: graphicData.RelatedRef.DevicePort.A,
code: '',
};
});
const DeviceTypeOptions = [
{ label: '区段', value: graphicData.RelatedRef.DeviceType.Section },
{ label: '道岔', value: graphicData.RelatedRef.DeviceType.Turnout },
];
const upDownOptions = [
{ label: '上行', value: graphicData.Direction.UP },
{ label: '下行', value: graphicData.Direction.DOWN },
];
const SignalTypeOptions = [
{ label: '红绿', value: graphicData.Signal.Model.HL },
{ label: '红绿黄,封黄灯,无引导', value: graphicData.Signal.Model.HLU_FU },
{
label: '红绿黄,不封灯,有单黄,带引导',
value: graphicData.Signal.Model.HLU_DU_YY,
},
{
label: '红绿黄,不封灯,无单黄,带引导',
value: graphicData.Signal.Model.HLU_YY,
},
{
label: '红绿黄,封绿灯,有单黄,带引导',
value: graphicData.Signal.Model.HLU_FL_DU_YY,
},
{
label: '红绿黄,不封灯,有单黄,无引导',
value: graphicData.Signal.Model.HLU_DU,
},
{ label: '蓝白', value: graphicData.Signal.Model.AB },
{
label: '红白黄,不封灯,有单黄,无引导',
value: graphicData.Signal.Model.HBU_DU,
},
];
const DevicePortOptions = [
{ label: 'A端', value: graphicData.RelatedRef.DevicePort.A },
{ label: 'B端', value: graphicData.RelatedRef.DevicePort.B },
{ label: 'C端', value: graphicData.RelatedRef.DevicePort.C },
];
const directionOptions = [
{ label: '左行', value: 0 },
{ label: '右行', value: 1 },
];
function removeStation(index: number) {
signalModel.centralizedStations.splice(index, 1);
onUpdate();
}
function addStation() {
$q.dialog({
title: '',
message: '',
component: AddCentralizedStationDialog,
cancel: true,
persistent: true,
}).onOk((data: number) => {
signalModel.centralizedStations.push(data);
onUpdate();
});
}
function getName(id: number) {
try {
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
return station.datas.code;
} catch (error) {
return id;
}
}
</script>

View File

@ -0,0 +1,126 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="stationModel.id" label="id" />
<q-input
outlined
label="车站站名"
type="textarea"
@blur="onUpdate"
v-model="stationModel.code"
lazy-rules
autogrow
/>
<q-input
outlined
label="车站名"
type="textarea"
@blur="onUpdate"
v-model="stationModel.stationName"
lazy-rules
autogrow
/>
<q-input
outlined
label="车站名拼音简写"
type="textarea"
@blur="onUpdate"
v-model="stationModel.stationNameAcronym"
lazy-rules
autogrow
/>
<q-list bordered separator class="rounded-borders">
<q-item no-wrap class="q-gutter-y-sm column">
<template v-if="stationModel.kilometerSystem">
<div>公里标配置</div>
<q-input
outlined
class="q-mt-md"
v-model="stationModel.kilometerSystem.coordinateSystem"
@blur="onUpdate"
label="坐标系"
></q-input>
<q-input
outlined
class="q-mt-md"
v-model.number="stationModel.kilometerSystem.kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
class="q-mt-md"
v-model="stationModel.kilometerSystem.direction"
:options="directionOptions"
map-options
emit-value
@update:model-value="onUpdate"
label="方向"
></q-select>
</template>
</q-item>
</q-list>
<q-toggle
v-model="stationModel.concentrationStations"
label="是否集中站"
emit-value
@update:model-value="onUpdate"
/>
<q-toggle
v-model="stationModel.depots"
label="是否车辆段"
emit-value
@update:model-value="onUpdate"
/>
<q-select
v-if="stationModel.concentrationStations"
outlined
v-model="stationModel.manageStations"
label="集中站管理的车站"
multiple
:options="optionsStations"
map-options
emit-value
@update:model-value="onUpdate"
/>
</q-form>
</template>
<script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils';
import { StationData } from 'src/drawApp/graphics/electronicMap/StationInteraction';
import { Station } from 'src/graphics/electronicMap/station/Station';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, watchEffect } from 'vue';
const drawStore = useDrawStore();
const { data: stationModel, onUpdate } = useFormData(
new StationData(),
drawStore.getDrawApp()
);
const directionOptions = [
{ label: '左行', value: 0 },
{ label: '右行', value: 1 },
];
let optionsStations: { label: string; value: number }[] = [];
watchEffect(() => {
if (
stationModel.concentrationStations &&
!stationModel.manageStations.includes(stationModel.id)
) {
stationModel.manageStations.push(stationModel.id);
onUpdate();
}
});
onMounted(() => {
optionsStations = drawStore
.getDrawApp()
.queryStore.queryByType<Station>(Station.Type)
.map((g) => {
return { label: g.datas.code, value: g.datas.id };
});
});
</script>

View File

@ -0,0 +1,190 @@
<template>
<q-form class="q-gutter-sm">
<q-input outlined readonly v-model="turnoutModel.id" label="id" />
<q-input
outlined
v-model="turnoutModel.code"
@blur="onUpdate"
label="编号"
/>
<q-list bordered separator class="rounded-borders">
<q-item no-wrap class="q-gutter-y-sm column">
<div>公里标配置</div>
<q-input
outlined
class="q-mt-sm"
v-model="turnoutModel.kilometerSystem.coordinateSystem"
@blur="onUpdate"
label="坐标系"
></q-input>
<q-input
outlined
class="q-mt-sm"
v-model.number="turnoutModel.kilometerSystem.kilometer"
type="number"
@blur="onUpdate"
label="公里标(mm):"
/>
<q-select
outlined
class="q-mt-sm"
v-model="turnoutModel.kilometerSystem.direction"
:options="directionOptions"
:map-options="true"
:emit-value="true"
@update:model-value="onUpdate"
label="方向"
></q-select>
</q-item>
</q-list>
<q-select
outlined
class="q-mt-sm"
v-model="turnoutModel.switchMachineType"
:options="switchMachineTypeOptions"
:map-options="true"
:emit-value="true"
label="转辙机型号"
@update:model-value="onUpdate"
></q-select>
<q-field class="q-mt-sm" outlined label="关联区段" readonly stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in sectionRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
<q-field class="q-mt-sm" outlined label="关联道岔" readonly stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="code in turnoutRelations"
:key="code"
square
>{{ code }}</q-chip
>
</template>
</q-field>
<q-field class="q-mt-lg" outlined label="所属集中站" stack-label>
<template #control>
<q-chip
color="primary"
text-color="white"
v-for="(id, index) in turnoutModel.centralizedStations"
:key="index"
removable
@remove="removeStation(index)"
square
>{{ getName(id) }}</q-chip
>
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
</template>
</q-field>
</q-form>
</template>
<script setup lang="ts">
import { TurnoutData } from 'src/drawApp/graphics/TurnoutInteraction';
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 { useQuasar } from 'quasar';
import { computed } from 'vue';
import { useFormData } from 'src/components/DrawAppFormUtils';
import AddCentralizedStationDialog from '../dialogs/AddCentralizedStationDialog.vue';
import { Station } from 'src/graphics/station/Station';
const drawStore = useDrawStore();
const $q = useQuasar();
const { data: turnoutModel, onUpdate } = useFormData(
new TurnoutData(),
drawStore.getDrawApp()
);
const directionOptions = [
{ label: '左行', value: 0 },
{ label: '右行', value: 1 },
];
const switchMachineTypeOptions = [
{
label: '请选择',
value: graphicData.Turnout.SwitchMachineType.Unknown,
},
{
label: 'ZDJ9(单机牵引)',
value: graphicData.Turnout.SwitchMachineType.ZDJ9_Single,
},
{
label: 'ZDJ9(双机牵引)',
value: graphicData.Turnout.SwitchMachineType.ZDJ9_Double,
},
];
function removeStation(index: number) {
turnoutModel.centralizedStations.splice(index, 1);
onUpdate();
}
function addStation() {
$q.dialog({
title: '',
message: '',
component: AddCentralizedStationDialog,
cancel: true,
persistent: true,
}).onOk((data: number) => {
turnoutModel.centralizedStations.push(data);
onUpdate();
});
}
const sectionRelations = computed(() => {
const turnout = drawStore.selectedGraphic as Turnout;
const sectionRelations =
turnout.relationManage.getRelationsOfGraphicAndOtherType(
turnout,
Section.Type
);
return sectionRelations.map(
(relation) =>
`${relation.getRelationParam(turnout).param}: ${
relation.getOtherGraphic<Section>(turnout).datas.code
}(${relation.getOtherRelationParam(turnout).param})`
);
});
const turnoutRelations = computed(() => {
const turnout = drawStore.selectedGraphic as Turnout;
const turnoutRelations =
turnout?.relationManage.getRelationsOfGraphicAndOtherType(
turnout,
Turnout.Type
);
return turnoutRelations.map(
(relation) =>
`${relation.getRelationParam(turnout).param}: ${
relation.getOtherGraphic<Turnout>(turnout).datas.code
}(${relation.getOtherRelationParam(turnout).param})`
);
});
function getName(id: number) {
try {
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
return station.datas.code;
} catch (error) {
return id;
}
}
</script>

View File

@ -24,8 +24,28 @@ import { PlatformData } from './graphics/electronicMap/PlatformInteraction';
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
import { common } from 'src/protos/common';
import { toStorageTransform } from './graphics/GraphicDataBase';
import { Section } from 'src/graphics/electronicMap/section/Section';
import { OneClickGenerateDraw, OneClickGenerateTemplate } from 'src/graphics/electronicMap/trainWindow/oneClickDrawAssistant';
import {
Section,
SectionTemplate,
} from 'src/graphics/electronicMap/section/Section';
import {
OneClickGenerateDraw,
OneClickGenerateTemplate,
} from 'src/graphics/electronicMap/trainWindow/oneClickDrawAssistant';
import { StationDraw } from 'src/graphics/electronicMap/station/StationDrawAssistant';
import {
Station,
StationTemplate,
} from 'src/graphics/electronicMap/station/Station';
import { StationData } from './graphics/electronicMap/StationInteraction';
import { ScreenDoorDraw } from 'src/graphics/electronicMap/screenDoor/ScreenDoorDrawAssistant';
import {
ScreenDoor,
ScreenDoorTemplate,
} from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
import { ScreenDoorData } from './graphics/electronicMap/ScreenDoorInteraction';
import { SectionDraw } from 'src/graphics/electronicMap/section/SectionDrawAssistant';
import { SectionData } from './graphics/electronicMap/SectionInteraction';
let electronicMapDrawApp: IDrawApp | null = null;
@ -68,7 +88,10 @@ export function initElectronicMapDrawApp(): IDrawApp {
});
const app = electronicMapDrawApp;
new OneClickGenerateDraw(app, new OneClickGenerateTemplate()),
new StationDraw(app, new StationTemplate(new StationData()));
new PlatformDraw(app, new PlatformTemplate(new PlatformData()));
new ScreenDoorDraw(app, new ScreenDoorTemplate(new ScreenDoorData()));
new SectionDraw(app, new SectionTemplate(new SectionData()));
// 画布右键菜单
app.registerMenu(DefaultEmCanvasMenu);
@ -213,9 +236,18 @@ export async function loadElectronicMapDrawDatas(): Promise<IGraphicStorage> {
);
const datas: GraphicData[] = [];
generateAxleCountingConfig = storage.generateAxleCountingConfig;
storage.stations.forEach((station) => {
datas.push(new StationData(station));
});
storage.Platforms.forEach((platform) => {
datas.push(new PlatformData(platform));
});
storage.screenDoors.forEach((screenDoor) => {
datas.push(new ScreenDoorData(screenDoor));
});
storage.section.forEach((section) => {
datas.push(new SectionData(section));
});
console.log(storage, 'storage');
return Promise.resolve({
canvasProperty: storage.canvas,
@ -239,9 +271,18 @@ export function saveDrawDatas(app: IDrawApp) {
});
const graphics = app.queryStore.getAllGraphics();
graphics.forEach((g) => {
if (g instanceof Platform) {
if (g instanceof Station) {
const stationData = g.saveData();
storage.stations.push((stationData as StationData).data);
} else if (g instanceof Platform) {
const platformData = g.saveData();
storage.Platforms.push((platformData as PlatformData).data);
} else if (g instanceof ScreenDoor) {
const screenDoorData = g.saveData();
storage.screenDoors.push((screenDoorData as ScreenDoorData).data);
} else if (g instanceof Section) {
const sectionData = g.saveData();
storage.section.push((sectionData as SectionData).data);
}
});
storage.generateAxleCountingConfig = generateAxleCountingConfig;

View File

@ -0,0 +1,75 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from '../GraphicDataBase';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { IPointData } from 'pixi.js';
import { ConcentrationDividingLine, IConcentrationDividingLineData } from 'src/graphics/electronicMap/concentrationDividingLine/ConcentrationDividingLine';
import { common } from 'src/protos/common';
export class ConcentrationDividingLineData
extends GraphicDataBase
implements IConcentrationDividingLineData
{
constructor(data?: electronicMapGraphicData.ConcentrationDividingLine) {
let concentrationDividingLine;
if (!data) {
concentrationDividingLine = new electronicMapGraphicData.ConcentrationDividingLine({
common: GraphicDataBase.defaultCommonInfo(
ConcentrationDividingLine.Type
),
});
} else {
concentrationDividingLine = data;
}
super(concentrationDividingLine);
}
public get data(): electronicMapGraphicData.ConcentrationDividingLine {
return this.getData<electronicMapGraphicData.ConcentrationDividingLine>();
}
get code(): string {
return this.data.code;
}
set code(v: string) {
this.data.code = v;
}
get points(): IPointData[] {
return this.data.points;
}
set points(points: IPointData[]) {
this.data.points = points.map(
(p) => new common.Point({ x: p.x, y: p.y })
);
}
get refLeftStationId(): number {
return this.data.refLeftStationId;
}
set refLeftStationId(v: number) {
this.data.refLeftStationId = v;
}
get refRightStationId(): number {
return this.data.refRightStationId;
}
set refRightStationId(v: number) {
this.data.refRightStationId = v;
}
get nodeConWithSecs(): electronicMapGraphicData.NodeConWithSec[] {
return this.data.nodeConWithSecs;
}
set nodeConWithSecs(nodes: electronicMapGraphicData.NodeConWithSec[]) {
this.data.nodeConWithSecs = nodes;
}
get isOtherLineConcentrationDividingLine(): boolean {
return this.data.isOtherLineConcentrationDividingLine;
}
set isOtherLineConcentrationDividingLine(v: boolean) {
this.data.isOtherLineConcentrationDividingLine = v;
}
clone(): ConcentrationDividingLineData {
return new ConcentrationDividingLineData(this.data.cloneMessage());
}
copyFrom(data: ConcentrationDividingLineData): void {
pb_1.Message.copyInto(data.data, this.data);
}
eq(other: ConcentrationDividingLineData): boolean {
return pb_1.Message.equals(this.data, other.data);
}
}

View File

@ -0,0 +1,108 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from '../GraphicDataBase';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
import {
IGraphicApp,
GraphicInteractionPlugin,
JlGraphic,
ContextMenu,
MenuItemOptions,
} from 'jl-graphic';
import {
ILogicSectionData,
LogicSection,
} from 'src/graphics/electronicMap/logicSection/LogicSection';
import { common } from 'src/protos/common';
import { LogicSectionGraphicHitArea } from 'src/graphics/electronicMap/logicSection/LogicSectionDrawAssistant';
export class LogicSectionData
extends GraphicDataBase
implements ILogicSectionData
{
constructor(data?: electronicMapGraphicData.LogicSection) {
let section;
if (!data) {
section = new electronicMapGraphicData.LogicSection({
common: GraphicDataBase.defaultCommonInfo(LogicSection.Type),
});
} else {
section = data;
}
super(section);
}
public get data(): electronicMapGraphicData.LogicSection {
return this.getData<electronicMapGraphicData.LogicSection>();
}
get code(): string {
return this.data.code;
}
set code(v: string) {
this.data.code = v;
}
get points(): IPointData[] {
return this.data.points;
}
set points(points: IPointData[]) {
this.data.points = points.map((p) => new common.Point({ x: p.x, y: p.y }));
}
clone(): LogicSectionData {
return new LogicSectionData(this.data.cloneMessage());
}
copyFrom(data: LogicSectionData): void {
pb_1.Message.copyInto(data.data, this.data);
}
eq(other: LogicSectionData): boolean {
return pb_1.Message.equals(this.data, other.data);
}
}
const speedLimit: MenuItemOptions = {
name: '限速 - speedLimit',
handler: () => 'speedLimit',
};
const LogicSectionMenu = ContextMenu.init({
name: 'LogicSection菜单',
groups: [
{
items: [speedLimit],
},
],
});
export class LogicSectionOperationPlugin extends GraphicInteractionPlugin<LogicSection> {
static Name = 'logic_section_menu';
constructor(app: IGraphicApp) {
super(LogicSectionOperationPlugin.Name, app);
app.registerMenu(LogicSectionMenu);
}
filter(...grahpics: JlGraphic[]): LogicSection[] | undefined {
return grahpics.filter((g): g is LogicSection => g instanceof LogicSection);
}
static init(app: IGraphicApp) {
return new LogicSectionOperationPlugin(app);
}
bind(g: LogicSection): void {
g.eventMode = 'static';
g.cursor = 'pointer';
g.lineGraphic.hitArea = new LogicSectionGraphicHitArea(g);
g.on('_leftclick', this.onLeftClick, this);
g.on('rightclick', this.onContextMenu, this);
}
unbind(g: LogicSection): void {
g.off('_leftclick', this.onLeftClick, this);
g.off('rightclick', this.onContextMenu);
}
onLeftClick(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const section = target.getGraphic() as LogicSection;
this.app.updateSelected(section);
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const section = target.getGraphic() as LogicSection;
this.app.updateSelected(section);
LogicSectionMenu.open(e.global);
}
}

View File

@ -66,57 +66,6 @@ export class PlatformData extends GraphicDataBase implements IPlatformData {
}
}
/* export class PlatformState extends GraphicStateBase implements IPlatformState {
constructor(proto?: state.PlatformState) {
let states;
if (proto) {
states = proto;
} else {
states = new state.PlatformState();
}
super(states, Platform.Type);
}
get id(): number {
return this.states.id;
}
get code(): string {
return this.states.id + '';
}
get states(): state.PlatformState {
return this.getState<state.PlatformState>();
}
get empj(): boolean {
return this.states.empj;
}
get spksState(): state.ReplyState[] {
if (!this.states.spksState) {
this.states.spksState = [new state.ReplyState()];
}
return this.states.spksState;
}
set spksState(v: state.ReplyState[]) {
this.states.spksState = v;
}
get mkxJState(): state.MkxJState {
if (!this.states.mkxJState) {
this.states.mkxJState = new state.MkxJState();
}
return this.states.mkxJState;
}
set mkxJState(v: state.MkxJState) {
this.states.mkxJState = v;
}
clone(): PlatformState {
return new PlatformState(this.states.cloneMessage());
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
} */
export class PlatformOperateInteraction extends GraphicInteractionPlugin<Platform> {
static Name = 'platform_operate_menu';
constructor(app: IGraphicScene) {

View File

@ -1,13 +1,6 @@
import * as pb_1 from 'google-protobuf';
import {
IScreenDoorData,
IScreenDoorState,
ScreenDoor,
} from 'src/graphics/screenDoor/ScreenDoor';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import { state } from 'src/protos/device_state';
import { useLineStore } from 'src/stores/line-store';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { GraphicDataBase } from '../GraphicDataBase';
import {
ContextMenu,
GraphicInteractionPlugin,
@ -15,17 +8,15 @@ import {
JlGraphic,
MenuItemOptions,
} from 'jl-graphic';
import { loadScreenDoorConfig } from '../commonApp';
import { Dialog } from 'quasar';
import { DisplayObject, FederatedMouseEvent } from 'pixi.js';
import ScreenDoorOperation from 'src/components/draw-app/dialogs/ScreenDoorOperation.vue';
import { request } from 'src/protos/request';
import { IScreenDoorData, ScreenDoor } from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
export class ScreenDoorData extends GraphicDataBase implements IScreenDoorData {
constructor(data?: graphicData.ScreenDoor) {
constructor(data?: electronicMapGraphicData.ScreenDoor) {
let screenDoor;
if (!data) {
screenDoor = new graphicData.ScreenDoor({
screenDoor = new electronicMapGraphicData.ScreenDoor({
common: GraphicDataBase.defaultCommonInfo(ScreenDoor.Type),
});
} else {
@ -34,8 +25,8 @@ export class ScreenDoorData extends GraphicDataBase implements IScreenDoorData {
super(screenDoor);
}
public get data(): graphicData.ScreenDoor {
return this.getData<graphicData.ScreenDoor>();
public get data(): electronicMapGraphicData.ScreenDoor {
return this.getData<electronicMapGraphicData.ScreenDoor>();
}
get code(): string {
return this.data.code;
@ -50,7 +41,7 @@ export class ScreenDoorData extends GraphicDataBase implements IScreenDoorData {
this.data.refPlatformId = v;
}
get sonDoorAmount(): number {
return loadScreenDoorConfig()?.sonDoorAmount || 30;
return 30;
}
clone(): ScreenDoorData {
@ -64,65 +55,6 @@ export class ScreenDoorData extends GraphicDataBase implements IScreenDoorData {
}
}
export class ScreenDoorState
extends GraphicStateBase
implements IScreenDoorState
{
constructor(proto?: state.PsdState) {
let states;
if (proto) {
states = proto;
} else {
states = new state.PsdState();
}
super(states, ScreenDoor.Type);
}
get code(): string {
return this.states.id + '';
}
get id(): number {
return this.states.id;
}
set id(id: number) {
this.states.id = id;
}
get asdStates(): state.AsdState[] {
return this.states.asdStates;
}
set asdStates(v: state.AsdState[]) {
this.states.asdStates = v;
}
get mgj() {
return this.states.mgj;
}
set mgj(v: boolean) {
this.states.mgj = v;
}
get zaw() {
return this.states.zaw;
}
set zaw(v: boolean) {
this.states.zaw = v;
}
get param(): request.PsdParam {
return this.states.param;
}
set param(param: request.PsdParam) {
this.states.param = param;
}
get states(): state.PsdState {
return this.getState<state.PsdState>();
}
clone(): ScreenDoorState {
return new ScreenDoorState(this.states.cloneMessage());
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
}
const setSceenDoorParam: MenuItemOptions = { name: '设置参数' };
const sceenDoorOperateMenu: ContextMenu = ContextMenu.init({
@ -163,14 +95,14 @@ export class ScreenDoorOperateInteraction extends GraphicInteractionPlugin<Scree
g.off('rightclick', this.onContextMenu, this);
}
onLeftClick() {
useLineStore().stateProCountIncrease();
//useLineStore().stateProCountIncrease();
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const screenDoor = target.getGraphic<ScreenDoor>();
if (!screenDoor) return;
this.app.updateSelected(screenDoor);
const lineStore = useLineStore();
/* const lineStore = useLineStore();
setSceenDoorParam.handler = async () => {
if (lineStore.deviceOpreratDialogInstance) return;
lineStore.deviceOpreratDialogInstance = Dialog.create({
@ -186,7 +118,7 @@ export class ScreenDoorOperateInteraction extends GraphicInteractionPlugin<Scree
cancel: true,
persistent: true,
});
};
}; */
sceenDoorOperateMenu.open(e.global);
}
}

View File

@ -1,13 +1,7 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import {
ISectionData,
ISectionState,
Section,
SectionType,
} from 'src/graphics/section/Section';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
import { GraphicDataBase } from '../GraphicDataBase';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { IPointData } from 'pixi.js';
import {
GraphicInteractionPlugin,
IGraphicScene,
@ -15,23 +9,19 @@ import {
MenuItemOptions,
ContextMenu,
} from 'jl-graphic';
import { useLineStore } from 'src/stores/line-store';
import { SectionGraphicHitArea } from 'src/graphics/section/SectionDrawAssistant';
import { Dialog } from 'quasar';
import AddTrainDialog from '../../components/draw-app/dialogs/AddTrainDialog.vue';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { state } from 'src/protos/device_state';
import { getKmDistance } from '../lineScene';
import SectionOperation from 'src/components/draw-app/dialogs/SectionOperation.vue';
import { request } from 'src/protos/request';
import { setAxleSectionState } from 'src/api/Simulation';
import { errorNotify } from 'src/utils/CommonNotify';
import { common } from 'src/protos/common';
import {
ISectionData,
Section,
} from 'src/graphics/electronicMap/section/Section';
import { SectionGraphicHitArea } from 'src/graphics/electronicMap/section/SectionDrawAssistant';
export class SectionData extends GraphicDataBase implements ISectionData {
constructor(data?: graphicData.Section) {
constructor(data?: electronicMapGraphicData.Section) {
let section;
if (!data) {
section = new graphicData.Section({
section = new electronicMapGraphicData.Section({
common: GraphicDataBase.defaultCommonInfo(Section.Type),
});
} else {
@ -39,8 +29,8 @@ export class SectionData extends GraphicDataBase implements ISectionData {
}
super(section);
}
public get data(): graphicData.Section {
return this.getData<graphicData.Section>();
public get data(): electronicMapGraphicData.Section {
return this.getData<electronicMapGraphicData.Section>();
}
get code(): string {
return this.data.code;
@ -52,26 +42,24 @@ export class SectionData extends GraphicDataBase implements ISectionData {
return this.data.points;
}
set points(points: IPointData[]) {
this.data.points = points.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
);
this.data.points = points.map((p) => new common.Point({ x: p.x, y: p.y }));
}
get paRef(): graphicData.RelatedRef {
get paRef(): electronicMapGraphicData.RelatedRef {
return this.data.paRef;
}
set paRef(ref: graphicData.RelatedRef) {
set paRef(ref: electronicMapGraphicData.RelatedRef) {
this.data.paRef = ref;
}
get pbRef(): graphicData.RelatedRef {
get pbRef(): electronicMapGraphicData.RelatedRef {
return this.data.pbRef;
}
set pbRef(ref: graphicData.RelatedRef) {
set pbRef(ref: electronicMapGraphicData.RelatedRef) {
this.data.pbRef = ref;
}
get sectionType(): graphicData.Section.SectionType {
get sectionType(): electronicMapGraphicData.Section.SectionType {
return this.data.sectionType;
}
set sectionType(type: graphicData.Section.SectionType) {
set sectionType(type: electronicMapGraphicData.Section.SectionType) {
this.data.sectionType = type;
}
get axleCountings(): number[] {
@ -104,10 +92,12 @@ export class SectionData extends GraphicDataBase implements ISectionData {
set centralizedStations(v: number[]) {
this.data.centralizedStations = v;
}
get normalRunningDirection(): graphicData.Section.RunningDirection {
get normalRunningDirection(): electronicMapGraphicData.Section.RunningDirection {
return this.data.normalRunningDirection;
}
set normalRunningDirection(v: graphicData.Section.RunningDirection) {
set normalRunningDirection(
v: electronicMapGraphicData.Section.RunningDirection
) {
this.data.normalRunningDirection = v;
}
get isTurnBackZone(): boolean {
@ -116,10 +106,10 @@ export class SectionData extends GraphicDataBase implements ISectionData {
set isTurnBackZone(v: boolean) {
this.data.isTurnBackZone = v;
}
get direction(): graphicData.Direction {
get direction(): electronicMapGraphicData.Direction {
return this.data.direction;
}
set direction(v: graphicData.Direction) {
set direction(v: electronicMapGraphicData.Direction) {
this.data.direction = v;
}
clone(): SectionData {
@ -133,63 +123,6 @@ export class SectionData extends GraphicDataBase implements ISectionData {
}
}
export class SectionStates extends GraphicStateBase implements ISectionState {
constructor(proto?: state.SectionState) {
let states;
if (proto) {
states = proto;
} else {
states = new state.SectionState();
}
super(states, Section.Type);
}
get code(): string {
return this.states.id + '';
}
get id(): number {
return this.states.id;
}
set id(id: number) {
this.states.id = id;
}
get occupied(): boolean {
return this.states.occupied;
}
set occupied(occupied: boolean) {
this.states.occupied = occupied;
}
get axleFault(): boolean {
return this.states.axleFault;
}
set axleFault(axleFault: boolean) {
this.states.axleFault = axleFault;
}
get axleDrst(): boolean {
return this.states.axleDrst;
}
set axleDrst(axleDrst: boolean) {
this.states.axleDrst = axleDrst;
}
get axlePdrst(): boolean {
return this.states.axlePdrst;
}
set axlePdrst(axlePdrst: boolean) {
this.states.axlePdrst = axlePdrst;
}
get states(): state.SectionState {
return this.getState<state.SectionState>();
}
clone(): SectionStates {
return new SectionStates(this.states.cloneMessage());
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
}
const addTrainConfig: MenuItemOptions = {
name: '添加列车',
};
@ -228,7 +161,7 @@ export class SectionOperateInteraction extends GraphicInteractionPlugin<Section>
g.labelGraphic.cursor = 'pointer';
g.labelGraphic.selectable = true;
g.on('_leftclick', this.onLeftClick, this);
g.on('rightclick', this.onContextMenu, this);
//g.on('rightclick', this.onContextMenu, this);
}
unbind(g: Section): void {
@ -239,12 +172,12 @@ export class SectionOperateInteraction extends GraphicInteractionPlugin<Section>
g.labelGraphic.eventMode = 'none';
g.labelGraphic.selectable = false;
g.off('_leftclick', this.onLeftClick, this);
g.off('rightclick', this.onContextMenu, this);
//g.off('rightclick', this.onContextMenu, this);
}
onLeftClick() {
useLineStore().stateProCountIncrease();
//useLineStore().stateProCountIncrease();
}
onContextMenu(e: FederatedMouseEvent) {
/* onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const section = target.getGraphic<Section>();
if (!section || section.datas.sectionType != SectionType.Physical) return;
@ -290,7 +223,8 @@ export class SectionOperateInteraction extends GraphicInteractionPlugin<Section>
if (
(other.datas.axleCountingRef.length > 1 &&
other.datas.type ==
graphicData.AxleCounting.TypeDetectionPoint.AxleCounting) ||
electronicMapGraphicData.AxleCounting.TypeDetectionPoint
.AxleCounting) ||
other.datas.axleCountingRef.length == 1
) {
if (rp.getParam() == 'A') {
@ -313,5 +247,5 @@ export class SectionOperateInteraction extends GraphicInteractionPlugin<Section>
});
};
SectionOperateMenu.open(e.global);
}
} */
}

View File

@ -1,21 +1,18 @@
import * as pb_1 from 'google-protobuf';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { GraphicDataBase } from '../GraphicDataBase';
import { IGraphicScene, GraphicInteractionPlugin, JlGraphic } from 'jl-graphic';
import { KilometerSystem } from 'src/graphics/electronicMap/signal/Signal';
import {
IStationData,
IStationState,
Station,
} from 'src/graphics/station/Station';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import { state } from 'src/protos/device_state';
import { IGraphicScene, GraphicInteractionPlugin, JlGraphic } from 'jl-graphic';
import { KilometerSystem } from 'src/graphics/signal/Signal';
import { useLineStore } from 'src/stores/line-store';
} from 'src/graphics/electronicMap/station/Station';
export class StationData extends GraphicDataBase implements IStationData {
constructor(data?: graphicData.Station) {
constructor(data?: electronicMapGraphicData.Station) {
let station;
if (!data) {
station = new graphicData.Station({
station = new electronicMapGraphicData.Station({
common: GraphicDataBase.defaultCommonInfo(Station.Type),
});
} else {
@ -24,8 +21,8 @@ export class StationData extends GraphicDataBase implements IStationData {
super(station);
}
public get data(): graphicData.Station {
return this.getData<graphicData.Station>();
public get data(): electronicMapGraphicData.Station {
return this.getData<electronicMapGraphicData.Station>();
}
get code(): string {
return this.data.code;
@ -47,12 +44,13 @@ export class StationData extends GraphicDataBase implements IStationData {
}
get kilometerSystem(): KilometerSystem {
if (!this.data.kilometerSystem) {
this.data.kilometerSystem = new graphicData.KilometerSystem();
this.data.kilometerSystem =
new electronicMapGraphicData.KilometerSystem();
}
return this.data.kilometerSystem;
}
set kilometerSystem(v: KilometerSystem) {
this.data.kilometerSystem = new graphicData.KilometerSystem(v);
this.data.kilometerSystem = new electronicMapGraphicData.KilometerSystem(v);
}
get concentrationStations(): boolean {
return this.data.concentrationStations;
@ -83,60 +81,6 @@ export class StationData extends GraphicDataBase implements IStationData {
}
}
export class StationState extends GraphicStateBase implements IStationState {
constructor(proto?: state.StationState) {
let states;
if (proto) {
states = proto;
} else {
states = new state.StationState();
}
super(states, Station.Type);
}
get id(): number {
return this.states.id;
}
get code(): string {
return this.states.id + '';
}
// get ipRtuStusDown(): boolean {
// return this.states.ipRtuStusDown;
// }
// set ipRtuStusDown(v: boolean) {
// this.states.ipRtuStusDown = v;
// }
// get ipRtuStusInLocalCtrl(): boolean {
// return this.states.ipRtuStusInLocalCtrl;
// }
// set ipRtuStusInLocalCtrl(v: boolean) {
// this.states.ipRtuStusInLocalCtrl = v;
// }
// get ipRtuStusInCentralCtrl(): boolean {
// return this.states.ipRtuStusInCentralCtrl;
// }
// set ipRtuStusInCentralCtrl(v: boolean) {
// this.states.ipRtuStusInCentralCtrl = v;
// }
// get ipRtuStusInEmergencyCtrl(): boolean {
// return this.states.ipRtuStusInEmergencyCtrl;
// }
// set ipRtuStusInEmergencyCtrl(v: boolean) {
// this.states.ipRtuStusInEmergencyCtrl = v;
// }
get states(): state.StationState {
return this.getState<state.StationState>();
}
clone(): StationState {
return new StationState(this.states.cloneMessage());
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
}
export class StationOperateInteraction extends GraphicInteractionPlugin<Station> {
static Name = 'station_operate_menu';
constructor(app: IGraphicScene) {
@ -163,6 +107,6 @@ export class StationOperateInteraction extends GraphicInteractionPlugin<Station>
g.off('_leftclick', this.onLeftClick, this);
}
onLeftClick() {
useLineStore().stateProCountIncrease();
//useLineStore().stateProCountIncrease();
}
}

View File

@ -0,0 +1,224 @@
import { IPointData } from 'pixi.js';
import {
GraphicData,
JlGraphic,
JlGraphicTemplate,
calculateDistanceFromPointToLine,
getRectangleCenter, ILineGraphic
} from 'jl-graphic';
import { SectionGraphic } from '../sectionGraphic/SectionGraphic';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { Section, DevicePort, SectionType } from '../section/Section';
import { arePolylinesIntersect } from './ConcentrationDividingLineUtils';
import { createRelatedRefProto } from '../CommonGraphics';
import { Turnout } from '../turnout/Turnout';
export interface IConcentrationDividingLineData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
get refLeftStationId(): number; //左边关联的集中站id
set refLeftStationId(v: number);
get refRightStationId(): number; //右边关联的集中站id
set refRightStationId(v: number);
get nodeConWithSecs(): electronicMapGraphicData.NodeConWithSec[]; // 集中区分割线与区段的交点
set nodeConWithSecs(nodes: electronicMapGraphicData.NodeConWithSec[]);
get isOtherLineConcentrationDividingLine(): boolean; //集中区分割线绘制在其它线的边界处
set isOtherLineConcentrationDividingLine(v: boolean);
clone(): IConcentrationDividingLineData;
copyFrom(data: IConcentrationDividingLineData): void;
eq(other: IConcentrationDividingLineData): boolean;
}
export const ConcentrationDividingLineConsts = {
lineColor: '#f00',
lineWidth: 2,
};
enum devicePort {
'A',
'B',
'C',
}
export class ConcentrationDividingLine
extends JlGraphic
implements ILineGraphic {
static Type = 'ConcentrationDividingLine';
lineGraphic: SectionGraphic;
constructor() {
super(ConcentrationDividingLine.Type);
this.lineGraphic = new SectionGraphic();
this.transformSave = true;
this.addChild(this.lineGraphic);
}
get code(): string {
return this.datas.code;
}
get datas(): IConcentrationDividingLineData {
return this.getDatas<IConcentrationDividingLineData>();
}
get linePoints(): IPointData[] {
return this.datas.points;
}
set linePoints(points: IPointData[]) {
const old = this.datas.clone();
old.points = points;
this.updateData(old);
}
doRepaint() {
if (this.datas.points.length < 2) {
throw new Error('Link坐标数据异常');
}
this.lineGraphic.clear();
this.lineGraphic.points = this.datas.points;
this.lineGraphic.lineStyle(
ConcentrationDividingLineConsts.lineWidth,
ConcentrationDividingLineConsts.lineColor
);
this.lineGraphic.paint();
}
buildRelation() {
const nodeConWithSecs: electronicMapGraphicData.NodeConWithSec[] = [];
const sections = this.queryStore
.queryByType<Section>(Section.Type)
.filter((g) => g.datas.sectionType == SectionType.Physical);
const hasNodeSection = new Map<number, string>();
sections.forEach((section) => {
const changeSectionData = section.datas.points.map((point) =>
section.localToCanvasPoint(point)
);
const changeConcentrationDividingLineData = this.datas.points.map(
(point) => this.localToCanvasPoint(point)
);
const hasNode = arePolylinesIntersect(
changeSectionData,
changeConcentrationDividingLineData
);
if (hasNode) {
const minA = calculateDistanceFromPointToLine(
hasNode.segment2[0],
hasNode.segment2[1],
section.localToCanvasPoint(section.getStartPoint())
);
const minB = calculateDistanceFromPointToLine(
hasNode.segment2[0],
hasNode.segment2[1],
section.localToCanvasPoint(section.getEndPoint())
);
const relationParam = minA > minB ? DevicePort.B : DevicePort.A;
const portRefOtherDevice =
relationParam == 'A' ? section.datas.paRef : section.datas.pbRef;
if (
portRefOtherDevice?.id &&
!hasNodeSection.get(section.id) &&
!hasNodeSection.get(portRefOtherDevice.id)
) {
const refDevice = this.queryStore.queryById<Turnout | Section>(
portRefOtherDevice?.id
);
const [leftDevice, rightDevice] =
refDevice.localToCanvasPoint(
getRectangleCenter(refDevice.getLocalBounds())
).x <
section.localToCanvasPoint(
getRectangleCenter(section.getLocalBounds())
).x
? [
{
device: refDevice,
port: devicePort[
portRefOtherDevice.devicePort
] as DevicePort,
},
{ device: section, port: relationParam },
]
: [
{ device: section, port: relationParam },
{
device: refDevice,
port: devicePort[
portRefOtherDevice.devicePort
] as DevicePort,
},
];
hasNodeSection.set(leftDevice.device.id, '1');
hasNodeSection.set(rightDevice.device.id, '1');
nodeConWithSecs.push(
new electronicMapGraphicData.NodeConWithSec({
leftSection: createRelatedRefProto(
leftDevice.device.type,
leftDevice.device.id,
leftDevice.port
),
rightSection: createRelatedRefProto(
rightDevice.device.type,
rightDevice.device.id,
rightDevice.port
),
})
);
} else if (!hasNodeSection.get(section.id) && !portRefOtherDevice?.id) {
const [leftSectionId, rightSectionId] =
relationParam === 'A'
? [undefined, section.id]
: [section.id, undefined];
hasNodeSection.set(section.id, '1');
if (leftSectionId == undefined) {
nodeConWithSecs.push(
new electronicMapGraphicData.NodeConWithSec({
leftSection: undefined,
rightSection: createRelatedRefProto(
Section.Type,
rightSectionId,
DevicePort.A
),
})
);
} else {
nodeConWithSecs.push(
new electronicMapGraphicData.NodeConWithSec({
leftSection: createRelatedRefProto(
Section.Type,
leftSectionId,
DevicePort.B
),
rightSection: undefined,
})
);
}
}
}
});
nodeConWithSecs.sort((a, b) => {
const sectionAId = a.leftSection ? a.leftSection.id : a.rightSection.id;
const sectionA = this.queryStore.queryById<Section | Turnout>(sectionAId);
const sectionBId = b.leftSection ? b.leftSection.id : b.rightSection.id;
const sectionB = this.queryStore.queryById<Section | Turnout>(sectionBId);
return (
sectionA.localToCanvasPoint(
getRectangleCenter(sectionA.getLocalBounds())
).y -
sectionB.localToCanvasPoint(
getRectangleCenter(sectionB.getLocalBounds())
).y
);
});
this.datas.nodeConWithSecs = nodeConWithSecs;
}
}
export class ConcentrationDividingLineTemplate extends JlGraphicTemplate<ConcentrationDividingLine> {
constructor(dataTemplate: IConcentrationDividingLineData) {
super(ConcentrationDividingLine.Type, { dataTemplate });
}
new() {
const g = new ConcentrationDividingLine();
g.loadData(this.datas);
return g;
}
}

View File

@ -0,0 +1,215 @@
import {
IGraphicApp,
GraphicDrawAssistant,
GraphicInteractionPlugin,
IDrawApp,
JlGraphic,
linePoint,
PolylineEditPlugin,
addWayPoint,
clearWayPoint,
MenuItemOptions,
ContextMenu,
} from 'jl-graphic';
import {
IConcentrationDividingLineData,
ConcentrationDividingLine,
ConcentrationDividingLineConsts,
ConcentrationDividingLineTemplate,
} from './ConcentrationDividingLine';
import {
DisplayObject,
FederatedMouseEvent,
Graphics,
IHitArea,
Point,
} from 'pixi.js';
import { getWayLineIndex } from '../polygon/PolygonUtils';
import { onEditPointCreate } from '../section/SectionDrawAssistant';
export class ConcentrationDividingLineDraw extends GraphicDrawAssistant<
ConcentrationDividingLineTemplate,
IConcentrationDividingLineData
> {
points: Point[] = [];
graphic = new Graphics();
constructor(app: IDrawApp, template: ConcentrationDividingLineTemplate) {
super(app, template, 'sym_o_timeline', '集中区分割线');
this.container.addChild(this.graphic);
ConcentrationDividingLinePointEditPlugin.init(app, this);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
onLeftDown(e: FederatedMouseEvent): void {
const { x, y } = this.toCanvasCoordinates(e.global);
const p = new Point(x, y);
this.points.push(p);
}
onRightClick(): void {
if (this.points.length < 2) {
this.finish();
return;
}
this.createAndStore(true);
}
onEsc(): void {
if (this.points.length < 2) {
this.finish();
return;
}
this.createAndStore(true);
}
redraw(p: Point): void {
if (this.points.length < 1) return;
this.graphic.clear();
this.graphic.lineStyle(
ConcentrationDividingLineConsts.lineWidth,
ConcentrationDividingLineConsts.lineColor
);
const ps = [...this.points];
ps.push(p);
ps.forEach((p, i) => {
if (i !== 0) {
this.graphic.lineTo(p.x, p.y);
} else {
this.graphic.moveTo(p.x, p.y);
}
});
}
prepareData(data: IConcentrationDividingLineData): boolean {
if (this.points.length < 2) {
console.log('ConcentrationDividingLine绘制因点不够取消绘制');
return false;
}
data.points = this.points;
return true;
}
clearCache(): void {
this.points = [];
this.graphic.clear();
}
}
export class ConcentrationDividingLineGraphicHitArea implements IHitArea {
concentrationDividingLine: ConcentrationDividingLine;
constructor(concentrationDividingLine: ConcentrationDividingLine) {
this.concentrationDividingLine = concentrationDividingLine;
}
contains(x: number, y: number): boolean {
for (
let i = 1;
i < this.concentrationDividingLine.datas.points.length;
i++
) {
const p1 = this.concentrationDividingLine.datas.points[i - 1];
const p2 = this.concentrationDividingLine.datas.points[i];
if (
linePoint(p1, p2, { x, y }, ConcentrationDividingLineConsts.lineWidth)
) {
return true;
}
}
return false;
}
}
const addWaypointConfig: MenuItemOptions = {
name: '添加路径点',
};
const clearWaypointsConfig: MenuItemOptions = {
name: '清除所有路径点',
};
const ConcentrationDividingLineEditMenu: ContextMenu = ContextMenu.init({
name: '集中区分割线编辑菜单',
groups: [
{
items: [addWaypointConfig, clearWaypointsConfig],
},
],
});
export class ConcentrationDividingLinePointEditPlugin extends GraphicInteractionPlugin<ConcentrationDividingLine> {
static Name = 'ConcentrationDividingLinePointDrag';
drawAssistant: ConcentrationDividingLineDraw;
constructor(app: IGraphicApp, da: ConcentrationDividingLineDraw) {
super(ConcentrationDividingLinePointEditPlugin.Name, app);
this.drawAssistant = da;
app.registerMenu(ConcentrationDividingLineEditMenu);
}
static init(app: IGraphicApp, da: ConcentrationDividingLineDraw) {
return new ConcentrationDividingLinePointEditPlugin(app, da);
}
filter(...grahpics: JlGraphic[]): ConcentrationDividingLine[] | undefined {
return grahpics.filter(
(g) => g.type == ConcentrationDividingLine.Type
) as ConcentrationDividingLine[];
}
bind(g: ConcentrationDividingLine): void {
g.lineGraphic.eventMode = 'static';
g.lineGraphic.cursor = 'pointer';
g.lineGraphic.hitArea = new ConcentrationDividingLineGraphicHitArea(g);
g.transformSave = true;
g.on('selected', this.onSelected, this);
g.on('unselected', this.onUnselected, this);
g.on('_rightclick', this.onContextMenu, this);
}
unbind(g: ConcentrationDividingLine): void {
g.off('selected', this.onSelected, this);
g.off('unselected', this.onUnselected, this);
g.off('_rightclick', this.onContextMenu, this);
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const concentrationDividingLine =
target.getGraphic() as ConcentrationDividingLine;
this.app.updateSelected(concentrationDividingLine);
const p = concentrationDividingLine.screenToLocalPoint(e.global);
addWaypointConfig.handler = () => {
const linePoints = concentrationDividingLine.linePoints;
const { start, end } = getWayLineIndex(linePoints, p);
addWayPoint(concentrationDividingLine, false, start, end, p);
};
clearWaypointsConfig.handler = () => {
clearWayPoint(concentrationDividingLine, false);
};
ConcentrationDividingLineEditMenu.open(e.global);
}
onSelected(g: DisplayObject): void {
const concentrationDividingLine = g as ConcentrationDividingLine;
let lep = concentrationDividingLine.getAssistantAppend<PolylineEditPlugin>(
PolylineEditPlugin.Name
);
if (!lep) {
lep = new PolylineEditPlugin(concentrationDividingLine, {
onEditPointCreate,
});
concentrationDividingLine.addAssistantAppend(lep);
}
lep.showAll();
}
onUnselected(g: DisplayObject): void {
const concentrationDividingLine = g as ConcentrationDividingLine;
const lep =
concentrationDividingLine.getAssistantAppend<PolylineEditPlugin>(
PolylineEditPlugin.Name
);
if (lep) {
lep.hideAll();
}
}
}

View File

@ -0,0 +1,187 @@
import { IPointData } from 'pixi.js';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { IDrawApp, JlGraphic } from 'jl-graphic';
import { Section } from '../section/Section';
import { Turnout } from '../turnout/Turnout';
import { GraphicDataBase } from 'src/drawApp/graphics/GraphicDataBase';
import { SectionData } from 'src/drawApp/graphics/electronicMap/SectionInteraction';
//判断线段与线段有木有交点
export function isSegmentsIntersect(
segment1: IPointData[],
segment2: IPointData[]
) {
const [p1, p2] = segment1;
const [p3, p4] = segment2;
// 判断包围盒是否相交
if (
Math.max(p1.x, p2.x) < Math.min(p3.x, p4.x) ||
Math.min(p1.x, p2.x) > Math.max(p3.x, p4.x) ||
Math.max(p1.y, p2.y) < Math.min(p3.y, p4.y) ||
Math.min(p1.y, p2.y) > Math.max(p3.y, p4.y)
) {
return false;
}
// 计算向量叉积
const cross1 = crossProduct(p3, p1, p4);
const cross2 = crossProduct(p3, p2, p4);
const cross3 = crossProduct(p1, p3, p2);
const cross4 = crossProduct(p1, p4, p2);
if (cross1 * cross2 < 0 && cross3 * cross4 < 0) {
return true;
}
return false;
}
function crossProduct(p1: IPointData, p2: IPointData, p3: IPointData) {
return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
}
export function getSegmentsFromPolyline(polyline: IPointData[]) {
const segments = [];
for (let i = 0; i < polyline.length - 1; i++) {
const segment = [polyline[i], polyline[i + 1]];
segments.push(segment);
}
return segments;
}
//判断折线与折线有木有交点
export function arePolylinesIntersect(
polyline1: IPointData[],
polyline2: IPointData[]
) {
const segments1 = getSegmentsFromPolyline(polyline1);
const segments2 = getSegmentsFromPolyline(polyline2);
for (const segment1 of segments1) {
for (const segment2 of segments2) {
if (isSegmentsIntersect(segment1, segment2)) {
return { hasnode: true, segment1, segment2 };
}
}
}
return false;
}
//获取指定区间内的物理区段和道岔
export function findContainDevice(
refDevice: Section | Turnout,
refDevicePort: electronicMapGraphicData.RelatedRef.DevicePort,
containDeviceIds: number[],
drawApp: IDrawApp
) {
const devicePort = electronicMapGraphicData.RelatedRef.DevicePort;
containDeviceIds.push(refDevice.id);
switch (true) {
case refDevice instanceof Section:
const sectionPaorbRef =
refDevicePort == devicePort.B
? refDevice.datas.paRef
: refDevice.datas.pbRef;
if (sectionPaorbRef && !containDeviceIds.includes(sectionPaorbRef.id)) {
const pbRefDevice = drawApp.queryStore.queryById<Section | Turnout>(
sectionPaorbRef.id
);
findContainDevice(
pbRefDevice,
sectionPaorbRef.devicePort,
containDeviceIds,
drawApp
);
}
break;
//道岔需要分路--实际的走向
case refDevice instanceof Turnout:
const otherPorts = [devicePort.A, devicePort.B, devicePort.C].filter(
(port) => port !== refDevicePort
);
otherPorts.forEach((port) => {
switch (port) {
case devicePort.A:
const turnoutPaRef = refDevice.datas.paRef;
if (turnoutPaRef && !containDeviceIds.includes(turnoutPaRef.id)) {
const paRefDevice = drawApp.queryStore.queryById<
Section | Turnout
>(turnoutPaRef.id);
findContainDevice(
paRefDevice,
turnoutPaRef.devicePort,
containDeviceIds,
drawApp
);
}
break;
case devicePort.B:
const turnoutPbRef = refDevice.datas.pbRef;
if (turnoutPbRef && !containDeviceIds.includes(turnoutPbRef.id)) {
const pbRefDevice = drawApp.queryStore.queryById<
Section | Turnout
>(turnoutPbRef.id);
findContainDevice(
pbRefDevice,
turnoutPbRef.devicePort,
containDeviceIds,
drawApp
);
}
break;
case devicePort.C:
const turnoutPcRef = (refDevice as Turnout).datas.pcRef;
if (turnoutPcRef && !containDeviceIds.includes(turnoutPcRef.id)) {
const pcRefDevice = drawApp.queryStore.queryById<
Section | Turnout
>(turnoutPcRef.id);
findContainDevice(
pcRefDevice,
turnoutPcRef.devicePort,
containDeviceIds,
drawApp
);
}
break;
}
});
break;
}
}
export function handleCentralizedStationsData(
devices: JlGraphic[],
centralizedStations: number[]
) {
interface GraphicData {
centralizedStations: number[];
}
const dataMap = new Map<string, GraphicDataBase>([
[Section.Type, new SectionData()],
]);
devices.forEach((device) => {
const data = dataMap.get(device.type);
if (data) {
data.copyFrom(device.saveData());
const dataCopy = data as GraphicDataBase & GraphicData;
dataCopy.centralizedStations = centralizedStations;
device.updateData(data);
}
});
}
//找到公共的元素
type findType = string | number;
export function findCommonElements(arrays: findType[][]) {
if (arrays.length === 0) {
return [];
}
const commonElements: findType[] = [];
arrays[0].forEach((element) => {
if (arrays.every((arr) => arr.includes(element))) {
commonElements.push(element);
}
});
return commonElements;
}

View File

@ -0,0 +1,130 @@
import { Graphics, IPointData } from 'pixi.js';
import {
GraphicAnimation,
GraphicData,
JlGraphic,
JlGraphicTemplate,
VectorText,
getParallelOfPolyline,
ILineGraphic,
} from 'jl-graphic';
import { SectionConsts } from '../section/Section';
export interface ILogicSectionData extends GraphicData {
get code(): string; // 编号
set code(v: string);
get points(): IPointData[]; // 线坐标点
set points(points: IPointData[]);
clone(): ILogicSectionData;
copyFrom(data: ILogicSectionData): void;
eq(other: ILogicSectionData): boolean;
}
export class LogicSection extends JlGraphic implements ILineGraphic {
static Type = 'LogicSection';
lineGraphic: Graphics;
labelGraphic: VectorText;
speedLimitGraphic: Graphics;
dt = 0;
constructor() {
super(LogicSection.Type);
this.lineGraphic = new Graphics();
this.labelGraphic = new VectorText();
this.labelGraphic.setVectorFontSize(14);
this.labelGraphic.anchor.set(0.5);
this.labelGraphic.style.fill = '#0f0';
this.labelGraphic.transformSave = true;
this.labelGraphic.name = 'label';
this.transformSave = true;
this.speedLimitGraphic = new Graphics();
this.addChild(this.lineGraphic);
this.addChild(this.labelGraphic);
this.addChild(this.speedLimitGraphic);
}
get code(): string {
return this.datas.code;
}
set code(code: string) {
this.datas.code = code;
}
get datas(): ILogicSectionData {
return this.getDatas<ILogicSectionData>();
}
get linePoints(): IPointData[] {
return this.datas.points;
}
set linePoints(points: IPointData[]) {
const old = this.datas.clone();
old.points = points;
this.updateData(old);
}
doRepaint() {
if (this.datas.points.length < 2) {
throw new Error('Link坐标数据异常');
}
this.lineGraphic.visible = true;
this.removeAnimation('flash');
this.lineGraphic
.clear()
.lineStyle(SectionConsts.lineWidth, SectionConsts.idleColor);
this.datas.points.forEach((p, i) => {
if (i !== 0) {
this.lineGraphic.lineTo(p.x, p.y);
} else {
this.lineGraphic.moveTo(p.x, p.y);
}
});
this.speedLimitGraphic.clear();
this.labelGraphic.text = this.datas.code.split('-')[1];
const labelPosition = this.datas.childTransforms?.find(
(t) => t.name === this.labelGraphic.name
)?.transform.position;
if (labelPosition) {
this.labelGraphic.position.set(labelPosition.x, labelPosition.y);
} else {
this.labelGraphic.position.set(
this.datas.points[0].x,
this.datas.points[0].y + 20
);
}
}
getSpeedLimitPoints() {
return [
getParallelOfPolyline(this.datas.points, 10, 'L'),
getParallelOfPolyline(this.datas.points, 10, 'R'),
];
}
bindFlashAnimation(g: Graphics) {
const flashAnimation = GraphicAnimation.init({
name: 'flash',
run: (dt: number) => {
this.dt += dt;
if (this.dt > 60) {
this.dt = 0;
g.visible = true;
} else if (this.dt > 30) {
g.visible = false;
}
},
});
this.addAnimation(flashAnimation);
return flashAnimation;
}
}
export class LogicSectionTemplate extends JlGraphicTemplate<LogicSection> {
constructor(dataTemplate: ILogicSectionData) {
super(LogicSection.Type, { dataTemplate });
}
new() {
const g = new LogicSection();
g.loadData(this.datas);
return g;
}
}

View File

@ -0,0 +1,93 @@
import {
IGraphicApp,
GraphicDrawAssistant,
GraphicInteractionPlugin,
IDrawApp,
JlGraphic,
linePoint,
} from 'jl-graphic';
import { LogicSection, LogicSectionTemplate } from './LogicSection';
import { Graphics, IHitArea, Point } from 'pixi.js';
import { SectionConsts } from '../section/Section';
import { LogicSectionData } from 'src/drawApp/graphics/electronicMap/LogicSectionInteraction';
export class LogicSectionDraw extends GraphicDrawAssistant<
LogicSectionTemplate,
LogicSectionData
> {
points: Point[] = [];
graphic = new Graphics();
constructor(app: IDrawApp, template: LogicSectionTemplate) {
super(app, template, 'sym_o_timeline', '逻辑区段');
this.container.addChild(this.graphic);
LogicSectionEditPlugin.init(app);
}
redraw(cp: Point): void {
if (this.points.length < 1) return;
this.graphic.clear();
this.graphic.lineStyle(SectionConsts.lineWidth, SectionConsts.lineColor);
this.points.forEach((p, i) => {
if (i !== 0) {
this.graphic.lineTo(p.x, p.y);
} else {
this.graphic.moveTo(p.x, p.y);
}
});
this.graphic.lineTo(cp.x, cp.y);
}
prepareData(): boolean {
return true;
}
}
export class LogicSectionGraphicHitArea implements IHitArea {
section: LogicSection;
constructor(section: LogicSection) {
this.section = section;
}
contains(x: number, y: number): boolean {
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];
if (linePoint(p1, p2, { x, y }, SectionConsts.lineWidth)) {
return true;
}
}
return false;
}
}
export class LogicSectionEditPlugin extends GraphicInteractionPlugin<LogicSection> {
static Name = 'LogicSectionInteraction';
constructor(app: IGraphicApp) {
super(LogicSectionEditPlugin.Name, app);
}
static init(app: IGraphicApp) {
return new LogicSectionEditPlugin(app);
}
filter(...grahpics: JlGraphic[]): LogicSection[] | undefined {
return grahpics.filter(
(g) => g.type == LogicSection.Type
) as LogicSection[];
}
bind(g: LogicSection): void {
g.draggable = false;
g.lineGraphic.eventMode = 'static';
g.lineGraphic.cursor = 'pointer';
g.lineGraphic.hitArea = new LogicSectionGraphicHitArea(g);
g.transformSave = true;
g.labelGraphic.eventMode = 'static';
g.labelGraphic.cursor = 'pointer';
g.labelGraphic.selectable = true;
g.labelGraphic.draggable = true;
// g.on('selected', this.onSelected, this);
// g.on('unselected', this.onUnselected, this);
}
unbind(): void {
// g.off('selected', this.onSelected, this);
// g.off('unselected', this.onUnselected, this);
}
// onSelected() {}
// onUnselected() {}
}

View File

@ -1,7 +1,6 @@
import { Color, Container, Graphics, Rectangle } from 'pixi.js';
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
distance2,
@ -26,10 +25,6 @@ export interface IPlatformData extends GraphicData {
copyFrom(data: IPlatformData): void;
eq(other: IPlatformData): boolean;
}
export interface IPlatformState extends GraphicState {
id?: number;
empj?: boolean;
}
const platformConsts = {
width: 90,
@ -77,9 +72,6 @@ export class Platform extends JlGraphic {
get datas(): IPlatformData {
return this.getDatas<IPlatformData>();
}
get states(): IPlatformState {
return this.getStates<IPlatformState>();
}
doRepaint(): void {
this.rectGraphic.draw();
}

View File

@ -0,0 +1,71 @@
import { IPointData } from 'pixi.js';
import {
calculateDistanceFromPointToLine,
calculateFootPointFromPointToLine,
} from 'jl-graphic';
//获取所选线段的索引
export function getWayLineIndex(
points: IPointData[],
p: IPointData
): { start: number; end: number } {
let start = 0;
let end = 0;
let minDistance = 0;
for (let i = 1; i < points.length; i++) {
const sp = points[i - 1];
const ep = points[i];
let distance = calculateDistanceFromPointToLine(sp, ep, p);
distance = Math.round(distance * 100) / 100;
if (i == 1) {
minDistance = distance;
}
if (distance == minDistance) {
const minX = Math.min(sp.x, ep.x);
const maxX = Math.max(sp.x, ep.x);
const minY = Math.min(sp.y, ep.y);
const maxY = Math.max(sp.y, ep.y);
const point = calculateFootPointFromPointToLine(sp, ep, p);
if (
point.x >= minX &&
point.x <= maxX &&
point.y >= minY &&
point.y <= maxY
) {
start = i - 1;
}
}
if (distance < minDistance) {
minDistance = distance;
start = i - 1;
}
}
end = start + 1;
return { start, end };
}
//判断点是否在多边形的边上或内部--射线法(从该点向任意方向发射一条射线,统计该射线与多边形的交点个数)
export function isPointInPolygon(point: IPointData, polygon: IPointData[]) {
let intersections = 0;
for (let i = 0; i < polygon.length; i++) {
const startPoint = polygon[i];
const endPoint = polygon[(i + 1) % polygon.length];
if (startPoint.y == endPoint.y) {
continue;
}
if (point.y < Math.min(startPoint.y, endPoint.y)) {
continue;
}
if (point.y >= Math.max(startPoint.y, endPoint.y)) {
continue;
}
const x =
((point.y - startPoint.y) * (endPoint.x - startPoint.x)) /
(endPoint.y - startPoint.y) +
startPoint.x;
if (x > point.x) {
intersections++;
}
}
return intersections % 2 == 1;
}

View File

@ -1,7 +1,6 @@
import { Color, Container, Graphics, Rectangle } from 'pixi.js';
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
VectorText,
@ -9,8 +8,6 @@ import {
getRectangleCenter,
} from 'jl-graphic';
import { Platform } from '../platform/Platform';
import { state } from 'src/protos/device_state';
import { request } from 'src/protos/request';
export interface IScreenDoorData extends GraphicData {
get code(): string; // 编号
@ -23,16 +20,6 @@ export interface IScreenDoorData extends GraphicData {
eq(other: IScreenDoorData): boolean;
}
export interface IScreenDoorState extends GraphicState {
get asdStates(): state.AsdState[]; //所有子门的状态
set asdStates(v: state.AsdState[]);
get mgj(): boolean; //屏蔽门整体的关闭(继电器)状态
set mgj(v: boolean);
get zaw(): boolean; //是否有障碍物
set zaw(v: boolean);
param: request.PsdParam;
}
const screenDoorConsts = {
lineWidth: 3,
smallDoorWidth: 10,
@ -68,16 +55,16 @@ class smallDoorGraphic extends Container {
this.drawZaw();
this.drawForce();
}
draw(data: IScreenDoorData, i: number, state: state.AsdState): void {
draw(data: IScreenDoorData, i: number): void {
const start =
(-screenDoorConsts.smallDoorWidth * data.sonDoorAmount) / 2 +
screenDoorConsts.smallDoorWidth * i;
const smallDoorGraphic = this.smallDoorGraphic;
const lineColor = state?.mgj
? screenDoorConsts.doorClose
: screenDoorConsts.doorOpen;
smallDoorGraphic
.lineStyle(screenDoorConsts.lineWidth, new Color(lineColor))
.lineStyle(
screenDoorConsts.lineWidth,
new Color(screenDoorConsts.doorClose)
)
.moveTo(start, 0)
.lineTo(start + screenDoorConsts.smallDoorWidth - 3, 0);
this.labelGraphic.text = i + 1;
@ -91,8 +78,8 @@ class smallDoorGraphic extends Container {
this.zawGraphic.position.set(start + 4, 9);
this.forceGraphic.position.set(start + 4, -9);
}
this.zawGraphic.visible = state?.zaw ? true : false;
this.forceGraphic.visible = state?.force ? true : false;
this.zawGraphic.visible = false;
this.forceGraphic.visible = false;
}
drawZaw() {
this.zawGraphic
@ -145,10 +132,6 @@ export class ScreenDoor extends JlGraphic {
return this.getDatas<IScreenDoorData>();
}
get states(): IScreenDoorState {
return this.getStates<IScreenDoorState>();
}
doRepaint(): void {
const doorGraphic = this.doorGraphic;
doorGraphic.children.forEach((g) => {
@ -159,10 +142,7 @@ export class ScreenDoor extends JlGraphic {
});
for (let i = 0; i < this.datas.sonDoorAmount; i++) {
const smallDoor = new smallDoorGraphic();
const smallDoorState = this.states.asdStates.find(
(asdState) => +asdState.code == i + 1
);
smallDoor.draw(this.datas, i, smallDoorState as state.AsdState);
smallDoor.draw(this.datas, i);
doorGraphic.addChild(smallDoor);
}
}
@ -204,16 +184,14 @@ export class ScreenDoor extends JlGraphic {
}
export class ScreenDoorTemplate extends JlGraphicTemplate<ScreenDoor> {
constructor(dataTemplate: IScreenDoorData, stateTemplate?: IScreenDoorState) {
constructor(dataTemplate: IScreenDoorData) {
super(ScreenDoor.Type, {
dataTemplate,
stateTemplate,
});
}
new(): ScreenDoor {
const screenDoor = new ScreenDoor();
screenDoor.loadData(this.datas);
screenDoor.loadState(this.states);
return screenDoor;
}
}

View File

@ -9,7 +9,7 @@ import {
} from 'jl-graphic';
import { IScreenDoorData, ScreenDoor, ScreenDoorTemplate } from './ScreenDoor';
import { Platform } from 'src/graphics/platform/Platform';
import { Platform } from '../platform/Platform';
export interface IScreenDoorDrawOptions {
newData: () => IScreenDoorData;

View File

@ -2,7 +2,6 @@ import { IPointData } from 'pixi.js';
import {
GraphicData,
GraphicRelationParam,
GraphicState,
JlGraphic,
JlGraphicTemplate,
VectorText,
@ -10,10 +9,8 @@ import {
distance2,
splitLineEvenly,
ILineGraphic,
Vector2
} from 'jl-graphic';
import { Vector2 } from 'jl-graphic';
import {
IRelatedRefData,
createRelatedRefProto,
@ -21,7 +18,6 @@ import {
} from '../CommonGraphics';
import { Turnout } from '../turnout/Turnout';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { SectionGraphic } from '../sectionGraphic/SectionGraphic';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
@ -29,8 +25,7 @@ const tolerance = 0.01;
export enum SectionType {
Physical = 0,
Logic = 1,
TurnoutPhysical = 2,
TurnoutPhysical = 1,
}
export interface ISectionData extends GraphicData {
@ -55,7 +50,9 @@ export interface ISectionData extends GraphicData {
get centralizedStations(): number[];
set centralizedStations(v: number[]);
get normalRunningDirection(): electronicMapGraphicData.Section.RunningDirection;
set normalRunningDirection(v: electronicMapGraphicData.Section.RunningDirection);
set normalRunningDirection(
v: electronicMapGraphicData.Section.RunningDirection
);
get isTurnBackZone(): boolean;
set isTurnBackZone(v: boolean);
get direction(): electronicMapGraphicData.Direction;
@ -65,16 +62,9 @@ export interface ISectionData extends GraphicData {
eq(other: ISectionData): boolean;
}
export interface ISectionState extends GraphicState {
id: number;
occupied?: boolean; //区段占用
axleFault?: boolean; //计轴故障
axleDrst: boolean; // 计轴复位
axlePdrst: boolean; // 计轴预复位
}
export const SectionConsts = {
lineColor: '#5578b6',
idleColor: '#888', //空闲
occupiedColor: '#f00',
lineWidth: 5,
};
@ -122,9 +112,7 @@ export class Section extends JlGraphic implements ILineGraphic {
this.lineGraphic.points = this.datas.points;
this.lineGraphic.lineStyle(
SectionConsts.lineWidth,
this.states.occupied
? SectionConsts.occupiedColor
: SectionConsts.lineColor
SectionConsts.lineColor
);
//FIXME 依赖location.path不合适
if (location.pathname.includes('painting')) {
@ -182,10 +170,6 @@ export class Section extends JlGraphic implements ILineGraphic {
get datas(): ISectionData {
return this.getDatas<ISectionData>();
}
get states(): ISectionState {
return this.getStates<ISectionState>();
}
get linePoints(): IPointData[] {
return this.datas.points;
}
@ -395,13 +379,12 @@ export class SectionTemplate
{
isCurve = false;
segmentsCount = 10;
constructor(dataTemplate: ISectionData, stateTemplate?: ISectionState) {
super(Section.Type, { dataTemplate, stateTemplate });
constructor(dataTemplate: ISectionData) {
super(Section.Type, { dataTemplate });
}
new() {
const g = new Section();
g.loadData(this.datas);
g.loadState(this.states);
return g;
}
}

View File

@ -8,8 +8,6 @@ import {
} from 'pixi.js';
import { Dialog } from 'quasar';
import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue';
import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
import {
AppConsts,
ChildTransform,
@ -41,7 +39,7 @@ import {
AbsorbablePosition,
AbsorbablePoint,
} from 'jl-graphic';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { electronicMapGraphicData } from 'src/protos/electronicMap_graphic_data';
import { AxleCounting } from '../axleCounting/AxleCounting';
import { LogicSection } from '../logicSection/LogicSection';
import { LogicSectionDraw } from '../logicSection/LogicSectionDrawAssistant';
@ -56,6 +54,9 @@ import {
} from './Section';
import { ConcentrationDividingLine } from '../concentrationDividingLine/ConcentrationDividingLine';
import { buildDragMoveAbsorbablePositions } from '../turnout/TurnoutDrawAssistant';
import { common } from 'src/protos/common';
import { SectionData } from 'src/drawApp/graphics/electronicMap/SectionInteraction';
import { LogicSectionData } from 'src/drawApp/graphics/electronicMap/LogicSectionInteraction';
export class SectionDraw extends GraphicDrawAssistant<
SectionTemplate,
@ -266,7 +267,7 @@ export class SectionDraw extends GraphicDrawAssistant<
const turnoutPhysicalSectionData = new SectionData();
turnoutPhysicalSectionData.id = this.nextId();
turnoutPhysicalSectionData.sectionType =
graphicData.Section.SectionType.TurnoutPhysical;
electronicMapGraphicData.Section.SectionType.TurnoutPhysical;
turnoutPhysicalSectionData.points = result.axleCountings.map((ac) => {
return new Point(ac.position.x, ac.position.y);
});
@ -579,7 +580,7 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
data.id = logicSectionDraw.nextId();
data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`;
data.points = ps.map(
(p) => new graphicData.Point({ x: p.x, y: p.y })
(p) => new common.Point({ x: p.x, y: p.y })
);
data.id = this.drawAssistant.nextId();
data.childTransforms = [

View File

@ -1,6 +1,5 @@
import {
GraphicData,
GraphicState,
JlGraphic,
JlGraphicTemplate,
VectorText,
@ -28,9 +27,6 @@ export interface IStationData extends GraphicData {
eq(other: IStationData): boolean;
}
export interface IStationState extends GraphicState {
id: number;
}
const stationConsts = {
codeColor: '0xF48815',
@ -54,9 +50,6 @@ export class Station extends JlGraphic {
get datas(): IStationData {
return this.getDatas<IStationData>();
}
get states(): IStationState {
return this.getStates<IStationState>();
}
doRepaint(): void {
const codeGraph = this.codeGraph;
@ -95,17 +88,15 @@ export class Station extends JlGraphic {
export class StationTemplate extends JlGraphicTemplate<Station> {
hasControl: boolean;
constructor(dataTemplate: IStationData, stateTemplate: IStationState) {
constructor(dataTemplate: IStationData) {
super(Station.Type, {
dataTemplate,
stateTemplate,
});
this.hasControl = true;
}
new(): Station {
const station = new Station();
station.loadData(this.datas);
station.loadState(this.states);
return station;
}
}

View File

@ -131,11 +131,11 @@ import { onMounted, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import AxleCountingConfig from 'src/components/draw-app/properties/electronicMap/AxleCountingConfig.vue';
//import { Station } from 'src/graphics/electronicMap/station/Station';
import { Station } from 'src/graphics/electronicMap/station/Station';
import { Platform } from 'src/graphics/electronicMap/platform/Platform';
/* import { ScreenDoor } from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
import { ScreenDoor } from 'src/graphics/electronicMap/screenDoor/ScreenDoor';
import { Section } from 'src/graphics/electronicMap/section/Section';
import { Turnout } from 'src/graphics/electronicMap/turnout/Turnout';
/* import { Turnout } from 'src/graphics/electronicMap/turnout/Turnout';
import { Signal } from 'src/graphics/electronicMap/signal/Signal'; */
import { saveDrawDatas, saveDrawToServer } from 'src/drawApp/electronicMapApp';
import { saveAsDraft } from 'src/api/DraftApi';
@ -237,15 +237,12 @@ onMounted(() => {
} else {
drawStore.setDraftId(null);
}
/* const drawAssistantsTypes = [
const drawAssistantsTypes = [
Station.Type,
Platform.Type,
ScreenDoor.Type,
Section.Type,
Turnout.Type,
Signal.Type,
]; */
const drawAssistantsTypes = [Platform.Type];
];
drawAssistantsTypes.forEach((type) => {
const drawAssistant = drawStore.getDrawApp().getDrawAssistant(type);
if (drawAssistant) {

View File

@ -21,10 +21,12 @@ export namespace electronicMapGraphicData {
turnouts?: Turnout[];
signals?: Signal[];
axleCountings?: AxleCounting[];
logicSections?: LogicSection[];
concentrationDividingLines?: ConcentrationDividingLine[];
generateAxleCountingConfig?: GenerateAxleCountingConfig;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8], this.#one_of_decls);
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8, 9, 10], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("canvas" in data && data.canvas != undefined) {
this.canvas = data.canvas;
@ -50,6 +52,12 @@ export namespace electronicMapGraphicData {
if ("axleCountings" in data && data.axleCountings != undefined) {
this.axleCountings = data.axleCountings;
}
if ("logicSections" in data && data.logicSections != undefined) {
this.logicSections = data.logicSections;
}
if ("concentrationDividingLines" in data && data.concentrationDividingLines != undefined) {
this.concentrationDividingLines = data.concentrationDividingLines;
}
if ("generateAxleCountingConfig" in data && data.generateAxleCountingConfig != undefined) {
this.generateAxleCountingConfig = data.generateAxleCountingConfig;
}
@ -106,14 +114,26 @@ export namespace electronicMapGraphicData {
set axleCountings(value: AxleCounting[]) {
pb_1.Message.setRepeatedWrapperField(this, 8, value);
}
get logicSections() {
return pb_1.Message.getRepeatedWrapperField(this, LogicSection, 9) as LogicSection[];
}
set logicSections(value: LogicSection[]) {
pb_1.Message.setRepeatedWrapperField(this, 9, value);
}
get concentrationDividingLines() {
return pb_1.Message.getRepeatedWrapperField(this, ConcentrationDividingLine, 10) as ConcentrationDividingLine[];
}
set concentrationDividingLines(value: ConcentrationDividingLine[]) {
pb_1.Message.setRepeatedWrapperField(this, 10, value);
}
get generateAxleCountingConfig() {
return pb_1.Message.getWrapperField(this, GenerateAxleCountingConfig, 9) as GenerateAxleCountingConfig;
return pb_1.Message.getWrapperField(this, GenerateAxleCountingConfig, 11) as GenerateAxleCountingConfig;
}
set generateAxleCountingConfig(value: GenerateAxleCountingConfig) {
pb_1.Message.setWrapperField(this, 9, value);
pb_1.Message.setWrapperField(this, 11, value);
}
get has_generateAxleCountingConfig() {
return pb_1.Message.getField(this, 9) != null;
return pb_1.Message.getField(this, 11) != null;
}
static fromObject(data: {
canvas?: ReturnType<typeof dependency_1.common.Canvas.prototype.toObject>;
@ -124,6 +144,8 @@ export namespace electronicMapGraphicData {
turnouts?: ReturnType<typeof Turnout.prototype.toObject>[];
signals?: ReturnType<typeof Signal.prototype.toObject>[];
axleCountings?: ReturnType<typeof AxleCounting.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
generateAxleCountingConfig?: ReturnType<typeof GenerateAxleCountingConfig.prototype.toObject>;
}): ElectronicMapGraphicStorage {
const message = new ElectronicMapGraphicStorage({});
@ -151,6 +173,12 @@ export namespace electronicMapGraphicData {
if (data.axleCountings != null) {
message.axleCountings = data.axleCountings.map(item => AxleCounting.fromObject(item));
}
if (data.logicSections != null) {
message.logicSections = data.logicSections.map(item => LogicSection.fromObject(item));
}
if (data.concentrationDividingLines != null) {
message.concentrationDividingLines = data.concentrationDividingLines.map(item => ConcentrationDividingLine.fromObject(item));
}
if (data.generateAxleCountingConfig != null) {
message.generateAxleCountingConfig = GenerateAxleCountingConfig.fromObject(data.generateAxleCountingConfig);
}
@ -166,6 +194,8 @@ export namespace electronicMapGraphicData {
turnouts?: ReturnType<typeof Turnout.prototype.toObject>[];
signals?: ReturnType<typeof Signal.prototype.toObject>[];
axleCountings?: ReturnType<typeof AxleCounting.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
generateAxleCountingConfig?: ReturnType<typeof GenerateAxleCountingConfig.prototype.toObject>;
} = {};
if (this.canvas != null) {
@ -192,6 +222,12 @@ export namespace electronicMapGraphicData {
if (this.axleCountings != null) {
data.axleCountings = this.axleCountings.map((item: AxleCounting) => item.toObject());
}
if (this.logicSections != null) {
data.logicSections = this.logicSections.map((item: LogicSection) => item.toObject());
}
if (this.concentrationDividingLines != null) {
data.concentrationDividingLines = this.concentrationDividingLines.map((item: ConcentrationDividingLine) => item.toObject());
}
if (this.generateAxleCountingConfig != null) {
data.generateAxleCountingConfig = this.generateAxleCountingConfig.toObject();
}
@ -217,8 +253,12 @@ export namespace electronicMapGraphicData {
writer.writeRepeatedMessage(7, this.signals, (item: Signal) => item.serialize(writer));
if (this.axleCountings.length)
writer.writeRepeatedMessage(8, this.axleCountings, (item: AxleCounting) => item.serialize(writer));
if (this.logicSections.length)
writer.writeRepeatedMessage(9, this.logicSections, (item: LogicSection) => item.serialize(writer));
if (this.concentrationDividingLines.length)
writer.writeRepeatedMessage(10, this.concentrationDividingLines, (item: ConcentrationDividingLine) => item.serialize(writer));
if (this.has_generateAxleCountingConfig)
writer.writeMessage(9, this.generateAxleCountingConfig, () => this.generateAxleCountingConfig.serialize(writer));
writer.writeMessage(11, this.generateAxleCountingConfig, () => this.generateAxleCountingConfig.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
@ -253,6 +293,12 @@ export namespace electronicMapGraphicData {
reader.readMessage(message.axleCountings, () => pb_1.Message.addToRepeatedWrapperField(message, 8, AxleCounting.deserialize(reader), AxleCounting));
break;
case 9:
reader.readMessage(message.logicSections, () => pb_1.Message.addToRepeatedWrapperField(message, 9, LogicSection.deserialize(reader), LogicSection));
break;
case 10:
reader.readMessage(message.concentrationDividingLines, () => pb_1.Message.addToRepeatedWrapperField(message, 10, ConcentrationDividingLine.deserialize(reader), ConcentrationDividingLine));
break;
case 11:
reader.readMessage(message.generateAxleCountingConfig, () => message.generateAxleCountingConfig = GenerateAxleCountingConfig.deserialize(reader));
break;
default: reader.skipField();
@ -1195,6 +1241,122 @@ export namespace electronicMapGraphicData {
BOTH = 2
}
}
export class LogicSection extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
common?: dependency_1.common.CommonInfo;
code?: string;
points?: dependency_1.common.Point[];
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [3], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("common" in data && data.common != undefined) {
this.common = data.common;
}
if ("code" in data && data.code != undefined) {
this.code = data.code;
}
if ("points" in data && data.points != undefined) {
this.points = data.points;
}
}
}
get common() {
return pb_1.Message.getWrapperField(this, dependency_1.common.CommonInfo, 1) as dependency_1.common.CommonInfo;
}
set common(value: dependency_1.common.CommonInfo) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_common() {
return pb_1.Message.getField(this, 1) != null;
}
get code() {
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
}
set code(value: string) {
pb_1.Message.setField(this, 2, value);
}
get points() {
return pb_1.Message.getRepeatedWrapperField(this, dependency_1.common.Point, 3) as dependency_1.common.Point[];
}
set points(value: dependency_1.common.Point[]) {
pb_1.Message.setRepeatedWrapperField(this, 3, value);
}
static fromObject(data: {
common?: ReturnType<typeof dependency_1.common.CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof dependency_1.common.Point.prototype.toObject>[];
}): LogicSection {
const message = new LogicSection({});
if (data.common != null) {
message.common = dependency_1.common.CommonInfo.fromObject(data.common);
}
if (data.code != null) {
message.code = data.code;
}
if (data.points != null) {
message.points = data.points.map(item => dependency_1.common.Point.fromObject(item));
}
return message;
}
toObject() {
const data: {
common?: ReturnType<typeof dependency_1.common.CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof dependency_1.common.Point.prototype.toObject>[];
} = {};
if (this.common != null) {
data.common = this.common.toObject();
}
if (this.code != null) {
data.code = this.code;
}
if (this.points != null) {
data.points = this.points.map((item: dependency_1.common.Point) => item.toObject());
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.has_common)
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
if (this.code.length)
writer.writeString(2, this.code);
if (this.points.length)
writer.writeRepeatedMessage(3, this.points, (item: dependency_1.common.Point) => item.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): LogicSection {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new LogicSection();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.common, () => message.common = dependency_1.common.CommonInfo.deserialize(reader));
break;
case 2:
message.code = reader.readString();
break;
case 3:
reader.readMessage(message.points, () => pb_1.Message.addToRepeatedWrapperField(message, 3, dependency_1.common.Point.deserialize(reader), dependency_1.common.Point));
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): LogicSection {
return LogicSection.deserialize(bytes);
}
}
export class Turnout extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
@ -2023,6 +2185,310 @@ export namespace electronicMapGraphicData {
SectionBoundary = 1
}
}
export class ConcentrationDividingLine extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
common?: dependency_1.common.CommonInfo;
code?: string;
points?: dependency_1.common.Point[];
nodeConWithSecs?: NodeConWithSec[];
isOtherLineConcentrationDividingLine?: boolean;
refLeftStationId?: number;
refRightStationId?: number;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [3, 4], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("common" in data && data.common != undefined) {
this.common = data.common;
}
if ("code" in data && data.code != undefined) {
this.code = data.code;
}
if ("points" in data && data.points != undefined) {
this.points = data.points;
}
if ("nodeConWithSecs" in data && data.nodeConWithSecs != undefined) {
this.nodeConWithSecs = data.nodeConWithSecs;
}
if ("isOtherLineConcentrationDividingLine" in data && data.isOtherLineConcentrationDividingLine != undefined) {
this.isOtherLineConcentrationDividingLine = data.isOtherLineConcentrationDividingLine;
}
if ("refLeftStationId" in data && data.refLeftStationId != undefined) {
this.refLeftStationId = data.refLeftStationId;
}
if ("refRightStationId" in data && data.refRightStationId != undefined) {
this.refRightStationId = data.refRightStationId;
}
}
}
get common() {
return pb_1.Message.getWrapperField(this, dependency_1.common.CommonInfo, 1) as dependency_1.common.CommonInfo;
}
set common(value: dependency_1.common.CommonInfo) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_common() {
return pb_1.Message.getField(this, 1) != null;
}
get code() {
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
}
set code(value: string) {
pb_1.Message.setField(this, 2, value);
}
get points() {
return pb_1.Message.getRepeatedWrapperField(this, dependency_1.common.Point, 3) as dependency_1.common.Point[];
}
set points(value: dependency_1.common.Point[]) {
pb_1.Message.setRepeatedWrapperField(this, 3, value);
}
get nodeConWithSecs() {
return pb_1.Message.getRepeatedWrapperField(this, NodeConWithSec, 4) as NodeConWithSec[];
}
set nodeConWithSecs(value: NodeConWithSec[]) {
pb_1.Message.setRepeatedWrapperField(this, 4, value);
}
get isOtherLineConcentrationDividingLine() {
return pb_1.Message.getFieldWithDefault(this, 5, false) as boolean;
}
set isOtherLineConcentrationDividingLine(value: boolean) {
pb_1.Message.setField(this, 5, value);
}
get refLeftStationId() {
return pb_1.Message.getFieldWithDefault(this, 6, 0) as number;
}
set refLeftStationId(value: number) {
pb_1.Message.setField(this, 6, value);
}
get refRightStationId() {
return pb_1.Message.getFieldWithDefault(this, 7, 0) as number;
}
set refRightStationId(value: number) {
pb_1.Message.setField(this, 7, value);
}
static fromObject(data: {
common?: ReturnType<typeof dependency_1.common.CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof dependency_1.common.Point.prototype.toObject>[];
nodeConWithSecs?: ReturnType<typeof NodeConWithSec.prototype.toObject>[];
isOtherLineConcentrationDividingLine?: boolean;
refLeftStationId?: number;
refRightStationId?: number;
}): ConcentrationDividingLine {
const message = new ConcentrationDividingLine({});
if (data.common != null) {
message.common = dependency_1.common.CommonInfo.fromObject(data.common);
}
if (data.code != null) {
message.code = data.code;
}
if (data.points != null) {
message.points = data.points.map(item => dependency_1.common.Point.fromObject(item));
}
if (data.nodeConWithSecs != null) {
message.nodeConWithSecs = data.nodeConWithSecs.map(item => NodeConWithSec.fromObject(item));
}
if (data.isOtherLineConcentrationDividingLine != null) {
message.isOtherLineConcentrationDividingLine = data.isOtherLineConcentrationDividingLine;
}
if (data.refLeftStationId != null) {
message.refLeftStationId = data.refLeftStationId;
}
if (data.refRightStationId != null) {
message.refRightStationId = data.refRightStationId;
}
return message;
}
toObject() {
const data: {
common?: ReturnType<typeof dependency_1.common.CommonInfo.prototype.toObject>;
code?: string;
points?: ReturnType<typeof dependency_1.common.Point.prototype.toObject>[];
nodeConWithSecs?: ReturnType<typeof NodeConWithSec.prototype.toObject>[];
isOtherLineConcentrationDividingLine?: boolean;
refLeftStationId?: number;
refRightStationId?: number;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
}
if (this.code != null) {
data.code = this.code;
}
if (this.points != null) {
data.points = this.points.map((item: dependency_1.common.Point) => item.toObject());
}
if (this.nodeConWithSecs != null) {
data.nodeConWithSecs = this.nodeConWithSecs.map((item: NodeConWithSec) => item.toObject());
}
if (this.isOtherLineConcentrationDividingLine != null) {
data.isOtherLineConcentrationDividingLine = this.isOtherLineConcentrationDividingLine;
}
if (this.refLeftStationId != null) {
data.refLeftStationId = this.refLeftStationId;
}
if (this.refRightStationId != null) {
data.refRightStationId = this.refRightStationId;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.has_common)
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
if (this.code.length)
writer.writeString(2, this.code);
if (this.points.length)
writer.writeRepeatedMessage(3, this.points, (item: dependency_1.common.Point) => item.serialize(writer));
if (this.nodeConWithSecs.length)
writer.writeRepeatedMessage(4, this.nodeConWithSecs, (item: NodeConWithSec) => item.serialize(writer));
if (this.isOtherLineConcentrationDividingLine != false)
writer.writeBool(5, this.isOtherLineConcentrationDividingLine);
if (this.refLeftStationId != 0)
writer.writeUint32(6, this.refLeftStationId);
if (this.refRightStationId != 0)
writer.writeUint32(7, this.refRightStationId);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): ConcentrationDividingLine {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new ConcentrationDividingLine();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.common, () => message.common = dependency_1.common.CommonInfo.deserialize(reader));
break;
case 2:
message.code = reader.readString();
break;
case 3:
reader.readMessage(message.points, () => pb_1.Message.addToRepeatedWrapperField(message, 3, dependency_1.common.Point.deserialize(reader), dependency_1.common.Point));
break;
case 4:
reader.readMessage(message.nodeConWithSecs, () => pb_1.Message.addToRepeatedWrapperField(message, 4, NodeConWithSec.deserialize(reader), NodeConWithSec));
break;
case 5:
message.isOtherLineConcentrationDividingLine = reader.readBool();
break;
case 6:
message.refLeftStationId = reader.readUint32();
break;
case 7:
message.refRightStationId = reader.readUint32();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): ConcentrationDividingLine {
return ConcentrationDividingLine.deserialize(bytes);
}
}
export class NodeConWithSec extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
leftSection?: RelatedRef;
rightSection?: RelatedRef;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("leftSection" in data && data.leftSection != undefined) {
this.leftSection = data.leftSection;
}
if ("rightSection" in data && data.rightSection != undefined) {
this.rightSection = data.rightSection;
}
}
}
get leftSection() {
return pb_1.Message.getWrapperField(this, RelatedRef, 1) as RelatedRef;
}
set leftSection(value: RelatedRef) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_leftSection() {
return pb_1.Message.getField(this, 1) != null;
}
get rightSection() {
return pb_1.Message.getWrapperField(this, RelatedRef, 2) as RelatedRef;
}
set rightSection(value: RelatedRef) {
pb_1.Message.setWrapperField(this, 2, value);
}
get has_rightSection() {
return pb_1.Message.getField(this, 2) != null;
}
static fromObject(data: {
leftSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
rightSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
}): NodeConWithSec {
const message = new NodeConWithSec({});
if (data.leftSection != null) {
message.leftSection = RelatedRef.fromObject(data.leftSection);
}
if (data.rightSection != null) {
message.rightSection = RelatedRef.fromObject(data.rightSection);
}
return message;
}
toObject() {
const data: {
leftSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
rightSection?: ReturnType<typeof RelatedRef.prototype.toObject>;
} = {};
if (this.leftSection != null) {
data.leftSection = this.leftSection.toObject();
}
if (this.rightSection != null) {
data.rightSection = this.rightSection.toObject();
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.has_leftSection)
writer.writeMessage(1, this.leftSection, () => this.leftSection.serialize(writer));
if (this.has_rightSection)
writer.writeMessage(2, this.rightSection, () => this.rightSection.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): NodeConWithSec {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new NodeConWithSec();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.leftSection, () => message.leftSection = RelatedRef.deserialize(reader));
break;
case 2:
reader.readMessage(message.rightSection, () => message.rightSection = RelatedRef.deserialize(reader));
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): NodeConWithSec {
return NodeConWithSec.deserialize(bytes);
}
}
export class KilometerSystem extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {