一键生成继电器布置图

This commit is contained in:
joylink_zhaoerwei 2023-11-17 15:23:27 +08:00
parent feca14c57c
commit c793a6bf95
4 changed files with 475 additions and 170 deletions

View File

@ -34,18 +34,16 @@
<script setup lang="ts">
import DraggableDialog from 'src/components/common/DraggableDialog.vue';
import { RelayCabinetData } from 'src/drawApp/relayCabinetGraphics/RelayCabinetInteraction';
import {
RelayData,
RelayState,
} from 'src/drawApp/relayCabinetGraphics/RelayInteraction';
import { Relay } from 'src/graphics/relay/Relay';
import {
RelayCabinet,
relayCabinetConsts,
} from 'src/graphics/relayCabinet/RelayCabinet';
import { containBoth } from 'src/graphics/relayCabinet/RelayCabinetDrawAssistant';
import { GraphicIdGenerator } from 'src/jl-graphic';
import {
generateRelayCabinet,
generateRelays,
} from 'src/layouts/RelayCabinetLayout/GeneraterDevice';
import { useRelayCabinetStore } from 'src/stores/relayCabinet-store';
import { ref } from 'vue';
@ -60,19 +58,11 @@ function oneClickRelayCabinet(direction: number) {
if (direction == -1) {
offsetX = -offsetX;
}
const relayCabinets: RelayCabinet[] = [];
for (let i = 0; i < oneClickRelayCabinets.value; i++) {
const relayCabinet = new RelayCabinet();
relayCabinet.loadData(new RelayCabinetData());
relayCabinet.id = GraphicIdGenerator.next();
relayCabinet.position.set(
selectRelayCabinet.x + offsetX * (i + 1),
selectRelayCabinet.y
);
relayCabinets.push(relayCabinet);
}
const app = relayCabinetStore.getDrawApp();
app.addGraphicAndRecord(...relayCabinets);
generateRelayCabinet(
oneClickRelayCabinets.value,
{ x: selectRelayCabinet.x + offsetX, y: selectRelayCabinet.y },
direction
);
}
}
@ -100,31 +90,7 @@ function oneClickRelay() {
}
}
if (!containRelay) {
const numRows = 11;
const numCols = Math.ceil(oneClickRelays.value / numRows);
const remainder = oneClickRelays.value % numRows;
const relays: Relay[][] = new Array(numRows);
for (let i = 0; i < numRows; i++) {
relays[i] = new Array(numCols);
for (let j = 0; j < numCols; j++) {
if (j == numCols - 1 && remainder !== 0 && i >= remainder) break;
const relay = new Relay();
relay.loadData(new RelayData());
relay.loadState(new RelayState());
relay.id = GraphicIdGenerator.next();
relay.position.set(
relayCabinet.x -
relayCabinetConsts.width / 2 +
(i + 3 / 2) * relayCabinetConsts.cellWidth,
relayCabinet.y -
relayCabinetConsts.height / 2 +
(j + 3 / 2) * relayCabinetConsts.cellHeight
);
relays[i][j] = relay;
}
}
const app = relayCabinetStore.getDrawApp();
app.addGraphicAndRecord(...relays.flat());
generateRelays(oneClickRelays.value, relayCabinet);
}
}
}

View File

@ -0,0 +1,104 @@
import { RelayCabinetData } from 'src/drawApp/relayCabinetGraphics/RelayCabinetInteraction';
import {
RelayData,
RelayState,
} from 'src/drawApp/relayCabinetGraphics/RelayInteraction';
import { Relay } from 'src/graphics/relay/Relay';
import {
RelayCabinet,
relayCabinetConsts,
} from 'src/graphics/relayCabinet/RelayCabinet';
import { GraphicIdGenerator } from 'src/jl-graphic';
import { relayCabinetGraphicData } from 'src/protos/relayCabinetLayoutGraphics';
import { useRelayCabinetStore } from 'src/stores/relayCabinet-store';
const relayCabinetStore = useRelayCabinetStore();
export interface GenerateRelaysCongig {
id: string;
code: string;
model: relayCabinetGraphicData.Relay.ModelType;
}
export function generateRelayCabinet(
amount: number,
firstPosition = { x: 400, y: 450 },
direction = 1
): RelayCabinet[] {
let offsetX = relayCabinetConsts.width + 80;
if (direction == -1) {
offsetX = -offsetX;
}
const relayCabinets: RelayCabinet[] = [];
for (let i = 0; i < amount; i++) {
const relayCabinet = new RelayCabinet();
relayCabinet.loadData(new RelayCabinetData());
relayCabinet.id = GraphicIdGenerator.next();
relayCabinet.position.set(firstPosition.x + offsetX * i, firstPosition.y);
relayCabinet.datas.code = '组合柜';
relayCabinets.push(relayCabinet);
}
const app = relayCabinetStore.getDrawApp();
app.addGraphicAndRecord(...relayCabinets);
return relayCabinets;
}
export function generateRelays(
amount: number,
relayCabinet: RelayCabinet,
relaysInfos?: GenerateRelaysCongig[]
) {
const numRows = 11;
const numCols = Math.ceil(amount / numRows);
const remainder = amount % numRows;
const relays: Relay[][] = new Array(numRows);
for (let i = 0; i < numRows; i++) {
relays[i] = new Array(numCols);
for (let j = 0; j < numCols; j++) {
if (j == numCols - 1 && remainder !== 0 && i >= remainder) break;
const relay = new Relay();
relay.loadData(new RelayData());
relay.loadState(new RelayState());
if (relaysInfos) {
const relaysInfo = relaysInfos[0];
relay.id = relaysInfo.id;
relay.datas.code = relaysInfo.code;
relay.datas.newModel = relaysInfo.model;
relaysInfos.shift();
} else {
relay.id = GraphicIdGenerator.next();
}
relay.position.set(
relayCabinet.x -
relayCabinetConsts.width / 2 +
(i + 3 / 2) * relayCabinetConsts.cellWidth,
relayCabinet.y -
relayCabinetConsts.height / 2 +
(j + 3 / 2) * relayCabinetConsts.cellHeight
);
relays[i][j] = relay;
}
}
const app = relayCabinetStore.getDrawApp();
app.addGraphicAndRecord(...relays.flat());
app?.emit('postdataloaded');
}
export function generateRelayLayout(relays: GenerateRelaysCongig[]) {
const relayCabinet = generateRelayCabinet(relays.length / 110);
for (let i = 0; i < relayCabinet.length; i++) {
if (i < relayCabinet.length - 1) {
generateRelays(
110,
relayCabinet[i],
relays.slice(i * 110, 111 + i * 110)
);
} else {
generateRelays(
relays.length % 110,
relayCabinet[i],
relays.slice(i * 110, i * 110 + (relays.length % 110))
);
}
}
}

View File

@ -11,13 +11,48 @@ export interface Combinationtype {
}[];
}
const SingleTuroutCombinations = [
//道岔组合类型
const turoutRefDeviceCodesAndModel = [
{
code: '1DQJ',
model: RelayModelType.JWJXC_H125_80,
},
{
code: '1DQJF',
model: RelayModelType.JWJXC_480,
},
{
code: '2DQJ',
model: RelayModelType.JYJXC_160_260,
},
{
code: 'BHJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'DBJ',
model: RelayModelType.JPXC_1000,
},
{
code: 'FBJ',
model: RelayModelType.JPXC_1000,
},
{
code: 'QDJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'ZBHJ',
model: RelayModelType.JWXC_1700,
},
];
const singleTuroutCombinations = [
{
code: 'moban',
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
model: RelayModelType.Unknown,
},
],
},
@ -51,67 +86,90 @@ const doubleTuroutCombinations = [
},
{
code: 'TDFJ1',
refDeviceCodesAndModel: [
{
code: '1DQJ',
model: RelayModelType.JWJXC_H125_80,
},
{
code: '1DQJF',
model: RelayModelType.JWJXC_480,
},
{
code: '2DQJ',
model: RelayModelType.JYJXC_160_260,
},
{
code: 'BHJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'DBJ',
model: RelayModelType.JPXC_1000,
},
{
code: 'FBJ',
model: RelayModelType.JPXC_1000,
},
{
code: 'QDJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'ZBHJ',
model: RelayModelType.JWXC_1700,
},
],
refDeviceCodesAndModel: turoutRefDeviceCodesAndModel,
},
{
code: 'TDFJ2',
refDeviceCodesAndModel: turoutRefDeviceCodesAndModel.slice(0, 6),
},
];
//信号机组合类型
const signalRefDeviceCodesAndModel = [
{
code: '2DJ',
model: RelayModelType.JZXC_H18,
},
{
code: 'DJ',
model: RelayModelType.JZXC_H18,
},
{
code: 'DDJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'LXJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'YXJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'ZXJ',
model: RelayModelType.JWXC_1700,
},
];
const HLSignalCombinations = [
{
code: '2XH-1',
refDeviceCodesAndModel: signalRefDeviceCodesAndModel.slice(1, 4),
},
];
const HLU_FUSignalCombinations = HLSignalCombinations;
const HLU_DU_YYSignalCombinations = [
{
code: '3XH-1',
refDeviceCodesAndModel: signalRefDeviceCodesAndModel,
},
];
const HLU_YYSignalCombinations = [
{
code: '3XH-2',
refDeviceCodesAndModel: signalRefDeviceCodesAndModel.slice(0, 5),
},
];
const HLU_FL_DU_YYSignalCombinations = [
{
code: '3XH-3',
refDeviceCodesAndModel: signalRefDeviceCodesAndModel.slice(0, 5),
},
];
const HLU_DUSignalCombinations = [
{
code: '3XH-4',
refDeviceCodesAndModel: [
{
code: '1DQJ',
model: RelayModelType.JWJXC_H125_80,
code: 'DJ',
model: RelayModelType.JZXC_H18,
},
{
code: '1DQJF',
model: RelayModelType.JWJXC_480,
},
{
code: '2DQJ',
model: RelayModelType.JYJXC_160_260,
},
{
code: 'BHJ',
code: 'DDJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'DBJ',
model: RelayModelType.JPXC_1000,
code: 'LXJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'FBJ',
model: RelayModelType.JPXC_1000,
code: 'ZXJ',
model: RelayModelType.JWXC_1700,
},
],
},
@ -123,7 +181,7 @@ const ABSignalCombinations = [
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
model: RelayModelType.Unknown,
},
],
},
@ -135,78 +193,131 @@ const HBU_DUSignalCombinations = [
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
model: RelayModelType.Unknown,
},
],
},
];
const HLSignalCombinations = [
//车站组合类型
const stationCombinations = [
{
code: 'moban',
code: 'EMP',
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
code: 'XEMPJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'SEMPJ',
model: RelayModelType.JPXC_1700,
},
],
},
{
code: 'MKX',
refDeviceCodesAndModel: [
{
code: 'SPABJ',
model: RelayModelType.JWXC_H340,
},
{
code: 'SPCBJ',
model: RelayModelType.JWXC_H340,
},
{
code: 'SPOBJ',
model: RelayModelType.JWXC_H340,
},
{
code: 'XPABJ',
model: RelayModelType.JWXC_H340,
},
{
code: 'XPCBJ',
model: RelayModelType.JWXC_H340,
},
{
code: 'XPOBJ',
model: RelayModelType.JWXC_H340,
},
],
},
{
code: 'SPKS',
refDeviceCodesAndModel: [
{
code: 'SPKSS2J',
model: RelayModelType.JPXC_1700,
},
{
code: 'SPKSS4J',
model: RelayModelType.JPXC_1700,
},
{
code: 'SPKSSPLAJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'SPKSX1J',
model: RelayModelType.JPXC_1700,
},
{
code: 'SPKSX3J',
model: RelayModelType.JPXC_1700,
},
{
code: 'SPKSXPLAJ',
model: RelayModelType.JPXC_1700,
},
],
},
];
const HLU_DUSignalCombinations = [
//屏蔽门组合类型
const screenDoorCombinations = [
{
code: 'moban',
code: 'PSD',
refDeviceCodesAndModel: [
{
code: 'moban',
code: '4XKMJ',
model: RelayModelType.JZXC_H18,
},
{
code: '8XKMJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'XGMJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'XMGJ',
model: RelayModelType.JWXC_1700,
},
{
code: 'XMPLJ',
model: RelayModelType.JWXC_1700,
},
],
},
];
const HLU_DU_YYSignalCombinations = [
{
code: 'moban',
code: 'JXTC',
refDeviceCodesAndModel: [
{
code: 'moban',
code: 'XJXTCPLJ',
model: RelayModelType.JZXC_H18,
},
{
code: 'XQDTCJ',
model: RelayModelType.JPXC_1700,
},
{
code: 'XTZTCJ',
model: RelayModelType.JWXC_1700,
},
],
},
];
const HLU_FL_DU_YYSignalCombinations = [
{
code: 'moban',
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
},
],
},
];
const HLU_FUSignalCombinations = [
{
code: 'moban',
refDeviceCodesAndModel: [
{
code: 'moban',
model: RelayModelType.JWXC_1700,
},
],
},
];
const HLU_YYSignalCombinations = [
{
code: 'moban',
refDeviceCodesAndModel: [
{
code: 'moban',
code: 'XZAWJ',
model: RelayModelType.JWXC_1700,
},
],
@ -217,7 +328,7 @@ const DeviceType = graphicData.RelatedRef.DeviceType;
export const combinationsMap = new Map<string, Combinationtype[]>([
[
`${DeviceType.Turnout}+${graphicData.Turnout.SwitchMachineType.ZDJ9_Single}`,
SingleTuroutCombinations,
singleTuroutCombinations,
],
[
`${DeviceType.Turnout}+${graphicData.Turnout.SwitchMachineType.ZDJ9_Double}`,
@ -249,4 +360,6 @@ export const combinationsMap = new Map<string, Combinationtype[]>([
`${DeviceType.signal}+${graphicData.Signal.Model.HLU_YY}`,
HLU_YYSignalCombinations,
],
[`${DeviceType.station}`, stationCombinations],
[`${DeviceType.ScreenDoor}`, screenDoorCombinations],
]);

View File

@ -165,6 +165,45 @@
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog
v-model="generaterRelayLayoutDialog"
persistent
transition-show="scale"
transition-hide="scale"
>
<q-card style="width: 300px">
<q-card-section>
<div class="text-h6">一键生成继电器柜布置图</div>
</q-card-section>
<q-card-section class="q-gutter-md">
<q-select
outlined
v-model="generaterRelayLayout.publishId"
:options="publishIdOption"
map-options
emit-value
@update:model-value="onChoosePublishId"
label="线路图"
></q-select>
<q-select
outlined
v-model="generaterRelayLayout.centralizedStation"
:options="centralizedStationsOption"
label="集中站"
></q-select>
</q-card-section>
<q-card-actions align="right">
<q-btn
color="primary"
label="确定"
@click="oneClickGeneraterRelayLayout"
/>
<q-btn label="取消" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
</q-layout>
</template>
@ -193,7 +232,7 @@ import { useRelayCabinetStore } from 'src/stores/relayCabinet-store';
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
import { getDraft, saveAsDraft } from 'src/api/DraftApi';
import { saveAsDraft } from 'src/api/DraftApi';
import { ApiError } from 'src/boot/axios';
import { DialogChainObject, useQuasar } from 'quasar';
import { Relay } from 'src/graphics/relay/Relay';
@ -204,7 +243,8 @@ import { relayCabinetGraphicData } from 'src/protos/relayCabinetLayoutGraphics';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { toUint8Array } from 'js-base64';
import { Combinationtype, combinationsMap } from './GeneraterRelayLayoutConfig';
import { loadWebFont } from 'pixi.js';
import { generateRelayLayout, GenerateRelaysCongig } from './GeneraterDevice';
import { getPublishMapInfoById, pageQuery } from 'src/api/PublishApi';
const $q = useQuasar();
const route = useRoute();
@ -249,7 +289,10 @@ const leftMenuConfig = [
{ label: '数据校验', click: handleCheckData },
{ label: 'UniqueId配置', click: openUniqueIdPrefixDialog },
{ label: '批量生成继电器或继电器柜', click: batchBuild },
{ label: '一键生成继电器柜布置图', click: oneClickGeneraterRelayLayout },
{
label: '一键生成继电器柜布置图',
click: openGeneraterRelayLayoutDialog,
},
];
//
@ -405,32 +448,61 @@ function batchBuild() {
});
}
//
const generaterRelayLayoutDialog = ref(false);
const generaterRelayLayout = ref<{
publishId: string;
centralizedStation: string;
}>({ publishId: '', centralizedStation: '' });
let publishIdOption = ref<{ label: string; value: number }[]>();
let centralizedStationsOption = ref<string[]>([]);
async function openGeneraterRelayLayoutDialog() {
generaterRelayLayoutDialog.value = true;
const response = await pageQuery({
current: 1,
size: 50,
});
publishIdOption.value = response.records
.filter((item) => item.name.includes('号线'))
.map((item) => {
return { label: item.name, value: item.id };
});
}
let storage: graphicData.RtssGraphicStorage;
async function onChoosePublishId() {
const response = await getPublishMapInfoById(
+generaterRelayLayout.value.publishId
);
storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(response.proto)
);
storage.stations.forEach((station) => {
if (station.concentrationStations) {
centralizedStationsOption.value.push(station.stationName);
}
});
}
async function oneClickGeneraterRelayLayout() {
resetDeviceRelateRelayList();
const { proto: base64 } = await getDraft(334);
if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64)
);
const concentrationStations: string[] = [];
storage.stations.forEach((station) => {
if (station.concentrationStations) {
concentrationStations.push(station.stationName);
}
});
//
const generateRelays: {
id: string;
code: string;
model: relayCabinetGraphicData.Relay.ModelType;
}[] = [];
const drawApp = relayCabinetStore.getDrawApp();
drawApp.deleteGraphics(...drawApp.queryStore.getAllGraphics());
if (storage) {
//
const concentrationStation = generaterRelayLayout.value.centralizedStation;
const generateRelays: GenerateRelaysCongig[] = [];
const DeviceType = graphicData.RelatedRef.DeviceType;
storage.turnouts.forEach((turnout) => {
const deviceCombinations = combinationsMap.get(
`${DeviceType.Turnout}+${turnout.switchMachineType}`
);
if (
turnout.centralizedStations.includes('酒仙桥') &&
turnout.centralizedStations.includes(concentrationStation) &&
deviceCombinations
) {
creatDeviceRelateRelays(
@ -440,21 +512,72 @@ async function oneClickGeneraterRelayLayout() {
);
}
});
const signalCodes = storage.signals
.filter((g) => g.centralizedStations.includes(concentrationStation))
.map((g) => g.code);
storage.signals.forEach((signal) => {
if (signal.code == 'Z1') {
console.log(signal, 666666, signal.common.id);
}
const deviceCombinations = combinationsMap.get(
`${DeviceType.signal}+${signal.mt}`
);
if (signal.centralizedStations.includes('酒仙桥') && deviceCombinations) {
if (
signal.centralizedStations.includes(concentrationStation) &&
deviceCombinations
) {
const count = signalCodes.reduce((pre, cur) => {
if (cur === signal.code) {
return pre + 1;
} else {
return pre;
}
}, 0);
const code =
count > 1 ? `${signal.code}(${signal.belongStation})` : signal.code;
creatDeviceRelateRelays(deviceCombinations, code, DeviceType.signal);
}
});
storage.stations.forEach((station) => {
const deviceCombinations = combinationsMap.get(`${DeviceType.station}`);
if (station.stationName == concentrationStation && deviceCombinations) {
creatDeviceRelateRelays(
deviceCombinations,
signal.code,
station.code,
DeviceType.signal
);
}
});
storage.screenDoors.forEach((screenDoor) => {
const deviceCombinations = combinationsMap.get(
`${DeviceType.ScreenDoor}`
);
let screenDoorRefStation: graphicData.Station | undefined = undefined;
for (let i = 0; i < storage.Platforms.length; i++) {
if (storage.Platforms[i].common.id == screenDoor.refPlatformId) {
for (let j = 0; j < storage.stations.length; j++) {
if (
storage.Platforms[i].refStationId == storage.stations[j].common.id
) {
screenDoorRefStation = storage.stations[j];
break;
}
}
break;
}
}
if (
screenDoorRefStation?.stationName == concentrationStation &&
deviceCombinations
) {
creatDeviceRelateRelays(
deviceCombinations,
`${concentrationStation}_${screenDoor.code}`,
DeviceType.signal
);
}
});
generateRelayLayout(generateRelays);
generaterRelayLayoutDialog.value = false;
function creatDeviceRelateRelays(
deviceCombinations: Combinationtype[],
deviceCode: string,
@ -487,7 +610,6 @@ async function oneClickGeneraterRelayLayout() {
});
creatDeviceRelateRelay(deviceRelateRelay);
}
console.log(generateRelays, 66666);
}
}