2023-08-01 14:54:11 +08:00
|
|
|
|
package memory
|
|
|
|
|
|
2023-08-01 17:08:45 +08:00
|
|
|
|
import (
|
2023-10-26 15:06:26 +08:00
|
|
|
|
"encoding/json"
|
2023-09-20 15:14:40 +08:00
|
|
|
|
"fmt"
|
2023-10-19 09:33:40 +08:00
|
|
|
|
"log/slog"
|
|
|
|
|
"math"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
"sort"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
2023-09-22 11:29:56 +08:00
|
|
|
|
"sync"
|
2023-10-19 14:44:10 +08:00
|
|
|
|
"time"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
|
2023-10-26 15:06:26 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/config"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/dto"
|
2023-10-20 15:08:47 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/sys_error"
|
2023-10-19 14:44:10 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/dynamics"
|
2023-10-19 09:33:40 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
2023-10-19 14:44:10 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/semi_physical_train"
|
2023-10-26 17:16:07 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/ts/protos/graphicData"
|
|
|
|
|
"joylink.club/bj-rtsts-server/ts/protos/state"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
"joylink.club/ecs"
|
2023-10-24 10:57:04 +08:00
|
|
|
|
"joylink.club/rtsssimulation/fi"
|
2023-09-20 15:14:40 +08:00
|
|
|
|
"joylink.club/rtsssimulation/repository"
|
|
|
|
|
"joylink.club/rtsssimulation/repository/model/proto"
|
2023-08-01 17:08:45 +08:00
|
|
|
|
)
|
|
|
|
|
|
2023-08-01 14:54:11 +08:00
|
|
|
|
// 轨旁仿真定义
|
|
|
|
|
type VerifySimulation struct {
|
|
|
|
|
//地图id
|
2023-09-19 11:02:50 +08:00
|
|
|
|
MapIds []int32
|
2023-08-30 13:25:57 +08:00
|
|
|
|
// 项目ID
|
|
|
|
|
ProjectId int32
|
2023-08-01 14:54:11 +08:00
|
|
|
|
//仿真id
|
|
|
|
|
SimulationId string
|
|
|
|
|
//仿真内存数据
|
|
|
|
|
Memory *WaysideMemory
|
2023-09-20 15:14:40 +08:00
|
|
|
|
//模型仓库
|
|
|
|
|
Repo *repository.Repository
|
2023-10-26 15:06:26 +08:00
|
|
|
|
//Rtss仿真世界的
|
|
|
|
|
World ecs.World
|
2023-09-25 17:05:17 +08:00
|
|
|
|
//设备UID映射
|
|
|
|
|
uidMap map[string]*elementIdStructure
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 运行环境配置
|
|
|
|
|
runConfig *config.ThridPartyConfig
|
2023-10-27 14:57:37 +08:00
|
|
|
|
// 运行状态
|
|
|
|
|
runState state.SimulationStatus_SimulationState
|
2023-08-01 14:54:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 11:29:56 +08:00
|
|
|
|
// 轨旁仿真内存模型
|
|
|
|
|
type WaysideMemory struct {
|
|
|
|
|
//可变状态数据:轨旁仿真模型状态(全量数据)
|
|
|
|
|
Status *VerifyStatus
|
|
|
|
|
// 要变更的状态:用户操作过的状态记录在这里,增量推送次数据
|
|
|
|
|
ChangeStatus *ChangeVerifyStatus
|
|
|
|
|
//状态保护锁
|
|
|
|
|
rwLock *sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 轨旁仿真模型状态
|
|
|
|
|
type VerifyStatus struct {
|
|
|
|
|
//道岔状态,key为道岔id即索引 state.SwitchState
|
|
|
|
|
SwitchStateMap sync.Map
|
|
|
|
|
//轨道状态,key为轨道id即索引 state.LinkState
|
|
|
|
|
LinkStateMap sync.Map
|
|
|
|
|
//列车状态,key为列车id即索引 state.TrainState
|
|
|
|
|
TrainStateMap sync.Map
|
|
|
|
|
//计轴区段状态,key为计轴区段的id即索引 state.SectionState
|
|
|
|
|
AxleSectionStateMap sync.Map
|
|
|
|
|
//物理区段状态,key为物理区段id即索引 state.SectionState
|
|
|
|
|
PhysicalSectionStateMap sync.Map
|
|
|
|
|
//逻辑区段状态,key为逻辑区段id即索引 state.SectionState
|
|
|
|
|
LogicSectionStateMap sync.Map
|
|
|
|
|
//信号机状态,key为信号机id,即索引 state.SignalState
|
|
|
|
|
SignalStateMap sync.Map
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 轨旁仿真模型状态(变更)
|
|
|
|
|
type ChangeVerifyStatus struct {
|
|
|
|
|
VerifyStatus
|
|
|
|
|
//删除的列车ID列表
|
|
|
|
|
RemoveTrainId []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewWaysideMemory() *WaysideMemory {
|
|
|
|
|
return &WaysideMemory{
|
|
|
|
|
Status: &VerifyStatus{},
|
|
|
|
|
ChangeStatus: &ChangeVerifyStatus{},
|
|
|
|
|
rwLock: &sync.RWMutex{},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-01 14:54:11 +08:00
|
|
|
|
// 创建仿真对象
|
2023-10-26 18:09:09 +08:00
|
|
|
|
func CreateSimulation(projectId int32, mapIds []int32, runConfig *dto.ProjectRunConfigDto) (*VerifySimulation, error) {
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 地图信息
|
2023-09-20 15:14:40 +08:00
|
|
|
|
sort.Slice(mapIds, func(i, j int) bool {
|
2023-10-27 15:45:43 +08:00
|
|
|
|
return QueryOnlyGiType(mapIds[i]) < QueryOnlyGiType(mapIds[j])
|
2023-09-20 15:14:40 +08:00
|
|
|
|
})
|
2023-10-27 14:57:37 +08:00
|
|
|
|
verifySimulation := &VerifySimulation{
|
|
|
|
|
ProjectId: projectId,
|
|
|
|
|
MapIds: mapIds,
|
|
|
|
|
runState: state.SimulationStatus_PAUSE,
|
|
|
|
|
}
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 设置运行环境
|
|
|
|
|
err := verifySimulation.initRunConfig(runConfig)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 构建Repository
|
|
|
|
|
err = verifySimulation.initRepository()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
return verifySimulation, nil
|
2023-08-01 14:54:11 +08:00
|
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
// 启动
|
|
|
|
|
func (s *VerifySimulation) Start() {
|
|
|
|
|
s.runState = state.SimulationStatus_START
|
2023-10-17 14:35:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
// 销毁
|
|
|
|
|
func (s *VerifySimulation) Destroy() {
|
|
|
|
|
s.runState = state.SimulationStatus_DESTROY
|
2023-08-01 17:08:45 +08:00
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
|
2023-10-30 11:13:36 +08:00
|
|
|
|
// 暂停
|
|
|
|
|
func (s *VerifySimulation) Pause() {
|
|
|
|
|
s.runState = state.SimulationStatus_PAUSE
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
// 获取状态
|
|
|
|
|
func (s *VerifySimulation) GetRunState() state.SimulationStatus_SimulationState {
|
|
|
|
|
return s.runState
|
2023-08-01 17:08:45 +08:00
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
|
2023-09-25 17:05:17 +08:00
|
|
|
|
// 获取仿真世界信息
|
|
|
|
|
func (s *VerifySimulation) GetComIdByUid(uid string) string {
|
|
|
|
|
es := s.uidMap
|
|
|
|
|
if es == nil {
|
|
|
|
|
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无映射信息"})
|
|
|
|
|
}
|
|
|
|
|
if es[uid] == nil {
|
|
|
|
|
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: "无【uid】映射信息"})
|
|
|
|
|
}
|
|
|
|
|
return es[uid].CommonId
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 09:33:40 +08:00
|
|
|
|
// 采集动力学道岔状态
|
|
|
|
|
func (s *VerifySimulation) CollectDynamicsTurnoutInfo() []*message.DynamicsTurnoutInfo {
|
|
|
|
|
stateSlice := GetAllTurnoutState(s)
|
|
|
|
|
var turnoutStates []*message.DynamicsTurnoutInfo
|
|
|
|
|
for _, sta := range stateSlice {
|
|
|
|
|
code64, err := strconv.ParseUint(sta.Id, 10, 16)
|
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Error("id转uint16报错", err)
|
|
|
|
|
}
|
|
|
|
|
info := message.DynamicsTurnoutInfo{
|
|
|
|
|
Code: uint16(code64),
|
|
|
|
|
NPosition: sta.Dw,
|
|
|
|
|
RPosition: sta.Fw,
|
|
|
|
|
}
|
|
|
|
|
turnoutStates = append(turnoutStates, &info)
|
|
|
|
|
}
|
|
|
|
|
return turnoutStates
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理动力学列车速度消息
|
|
|
|
|
func (s *VerifySimulation) HandleDynamicsTrainInfo(info *message.DynamicsTrainInfo) {
|
|
|
|
|
sta, ok := s.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number)))
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// 给半实物仿真发送速度
|
2023-10-19 14:44:10 +08:00
|
|
|
|
semi_physical_train.Default().SendTrainControlMessage(info)
|
2023-10-19 09:33:40 +08:00
|
|
|
|
// 更新列车状态
|
2023-10-19 14:44:10 +08:00
|
|
|
|
UpdateTrainState(s, convert(info, sta.(*state.TrainState), s))
|
2023-10-19 09:33:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convert(info *message.DynamicsTrainInfo, sta *state.TrainState, simulation *VerifySimulation) *state.TrainState {
|
2023-10-19 14:44:10 +08:00
|
|
|
|
delayTime := time.Now().UnixMilli() - sta.VobcState.UpdateTime
|
|
|
|
|
sta.ControlDelayTime = (int64(sta.VobcState.LifeSignal)-int64(info.VobcLifeSignal))*20 + delayTime
|
2023-10-19 09:33:40 +08:00
|
|
|
|
slog.Debug("收到动力学原始消息", "Number", info.Number, "Link", info.Link, "LinkOffset", info.LinkOffset)
|
|
|
|
|
id, port, offset, runDirection, pointTo, kilometer := QueryDeviceByCalcLink(simulation.Repo, strconv.Itoa(int(info.Link)), int64(info.LinkOffset), info.Up)
|
2023-10-19 14:44:10 +08:00
|
|
|
|
slog.Debug("处理动力学转换后的消息", "number", info.Number, "车头位置", id, "偏移", offset, "是否上行", runDirection, "是否ab", pointTo)
|
2023-11-01 16:55:16 +08:00
|
|
|
|
sta.HeadDeviceUId = id
|
2023-10-19 09:33:40 +08:00
|
|
|
|
sta.HeadDeviceId = simulation.GetComIdByUid(id)
|
|
|
|
|
sta.DevicePort = port
|
|
|
|
|
sta.HeadOffset = offset
|
|
|
|
|
sta.PointTo = pointTo
|
|
|
|
|
sta.TrainKilometer = kilometer
|
|
|
|
|
sta.RunDirection = runDirection
|
|
|
|
|
//判定车头方向
|
|
|
|
|
sta.HeadDirection = runDirection
|
|
|
|
|
if sta.VobcState != nil {
|
|
|
|
|
if sta.VobcState.DirectionForward {
|
|
|
|
|
sta.HeadDirection = runDirection
|
|
|
|
|
} else if sta.VobcState.DirectionBackward {
|
|
|
|
|
sta.HeadDirection = !runDirection
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if info.Speed < 0 {
|
|
|
|
|
sta.RunDirection = !sta.RunDirection
|
|
|
|
|
}
|
|
|
|
|
// 赋值动力学信息
|
|
|
|
|
sta.DynamicState.Heartbeat = int32(info.LifeSignal)
|
|
|
|
|
sta.DynamicState.HeadLinkId = strconv.Itoa(int(info.Link))
|
|
|
|
|
sta.DynamicState.HeadLinkOffset = int64(info.LinkOffset)
|
|
|
|
|
sta.DynamicState.Slope = int32(info.Slope)
|
|
|
|
|
sta.DynamicState.Upslope = info.UpSlope
|
|
|
|
|
sta.DynamicState.RunningUp = info.Up
|
|
|
|
|
sta.DynamicState.RunningResistanceSum = float32(info.TotalResistance) / 1000
|
|
|
|
|
sta.DynamicState.AirResistance = float32(info.AirResistance) / 1000
|
|
|
|
|
sta.DynamicState.RampResistance = float32(info.SlopeResistance) / 1000
|
|
|
|
|
sta.DynamicState.CurveResistance = float32(info.CurveResistance) / 1000
|
|
|
|
|
sta.DynamicState.Speed = speedParse(info.Speed)
|
|
|
|
|
sta.DynamicState.HeadSensorSpeed1 = speedParse(info.HeadSpeed1)
|
|
|
|
|
sta.DynamicState.HeadSensorSpeed2 = speedParse(info.HeadSpeed2)
|
|
|
|
|
sta.DynamicState.TailSensorSpeed1 = speedParse(info.TailSpeed1)
|
|
|
|
|
sta.DynamicState.TailSensorSpeed2 = speedParse(info.TailSpeed2)
|
|
|
|
|
sta.DynamicState.HeadRadarSpeed = speedParse(info.HeadRadarSpeed)
|
|
|
|
|
sta.DynamicState.TailRadarSpeed = speedParse(info.TailRadarSpeed)
|
|
|
|
|
sta.DynamicState.Acceleration = info.Acceleration
|
|
|
|
|
return sta
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 获取动力学配置信息
|
|
|
|
|
func (s *VerifySimulation) GetDynamicsRunConfig() *config.DynamicsConfig {
|
|
|
|
|
return &s.runConfig.Dynamics
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取动力学运行资源
|
|
|
|
|
func (s *VerifySimulation) GetDynamicsRunRepository() *message.LineBaseInfo {
|
|
|
|
|
info := &message.LineBaseInfo{}
|
|
|
|
|
for _, model := range s.Repo.LinkList() {
|
|
|
|
|
id, _ := strconv.Atoi(model.Id())
|
|
|
|
|
link := &message.Link{
|
|
|
|
|
ID: int32(id),
|
|
|
|
|
Len: int32(model.Length()),
|
|
|
|
|
}
|
|
|
|
|
info.LinkList = append(info.LinkList, link)
|
|
|
|
|
if model.ARelation() != nil {
|
|
|
|
|
turnoutId, _ := strconv.Atoi(s.GetComIdByUid(model.ARelation().Device().Id()))
|
|
|
|
|
link.ARelTurnoutId = int32(turnoutId)
|
|
|
|
|
switch model.ARelation().Port() {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
link.ARelTurnoutPoint = "A"
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
link.ARelTurnoutPoint = "B"
|
|
|
|
|
case proto.Port_C:
|
|
|
|
|
link.ARelTurnoutPoint = "C"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if model.BRelation() != nil {
|
|
|
|
|
turnoutId, _ := strconv.Atoi(s.GetComIdByUid(model.BRelation().Device().Id()))
|
|
|
|
|
link.BRelTurnoutId = int32(turnoutId)
|
|
|
|
|
switch model.BRelation().Port() {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
link.BRelTurnoutPoint = "A"
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
link.BRelTurnoutPoint = "B"
|
|
|
|
|
case proto.Port_C:
|
|
|
|
|
link.BRelTurnoutPoint = "C"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, model := range s.Repo.SlopeList() {
|
|
|
|
|
id, _ := strconv.Atoi(s.GetComIdByUid(model.Id()))
|
|
|
|
|
slope := &message.Slope{
|
|
|
|
|
ID: int32(id),
|
|
|
|
|
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
|
|
|
|
|
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
|
|
|
|
|
DegreeTrig: model.Degree(),
|
|
|
|
|
}
|
|
|
|
|
info.SlopeList = append(info.SlopeList, slope)
|
|
|
|
|
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
|
|
|
|
|
slope.StartLinkId = int32(startLinkId)
|
|
|
|
|
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
|
|
|
|
slope.EndLinkId = int32(endLinkId)
|
|
|
|
|
}
|
|
|
|
|
for _, model := range s.Repo.SectionalCurvatureList() {
|
|
|
|
|
id, _ := strconv.Atoi(s.GetComIdByUid(model.Id()))
|
|
|
|
|
curve := &message.Curve{
|
|
|
|
|
ID: int32(id),
|
|
|
|
|
StartLinkOffset: int32(model.StartLinkPosition().Offset()),
|
|
|
|
|
EndLinkOffset: int32(model.EndLinkPosition().Offset()),
|
|
|
|
|
Curvature: model.Radius(),
|
|
|
|
|
}
|
|
|
|
|
info.CurveList = append(info.CurveList, curve)
|
|
|
|
|
startLinkId, _ := strconv.Atoi(model.StartLinkPosition().Link().Id())
|
|
|
|
|
curve.StartLinkId = int32(startLinkId)
|
|
|
|
|
endLinkId, _ := strconv.Atoi(model.EndLinkPosition().Link().Id())
|
|
|
|
|
curve.EndLinkId = int32(endLinkId)
|
|
|
|
|
}
|
|
|
|
|
return info
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 09:33:40 +08:00
|
|
|
|
// 发送给前端的速度格式化
|
|
|
|
|
func speedParse(speed float32) int32 {
|
|
|
|
|
return int32(math.Abs(float64(speed * 3.6 * 100)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理半实物仿真列车控制消息
|
2023-10-19 14:44:10 +08:00
|
|
|
|
func (s *VerifySimulation) HandleSemiPhysicalTrainControlMsg(b []byte) {
|
|
|
|
|
s.Memory.Status.TrainStateMap.Range(func(_, value any) bool {
|
|
|
|
|
train := value.(*state.TrainState)
|
|
|
|
|
if !train.Show { // 下线列车
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
trainId, err := strconv.Atoi(train.Id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
|
|
|
|
}
|
|
|
|
|
d := append(b, uint8(trainId))
|
|
|
|
|
// 发送给动力学
|
|
|
|
|
dynamics.Default().SendTrainControlMessage(d)
|
|
|
|
|
// 存放至列车中
|
|
|
|
|
controlMessage := &message.TrainControlMsg{}
|
|
|
|
|
controlMessage.Decode(b)
|
|
|
|
|
train.VobcState = controlMessage.ControlInfo
|
|
|
|
|
return true
|
|
|
|
|
})
|
2023-10-19 09:33:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 获取半实物运行配置信息
|
|
|
|
|
func (s *VerifySimulation) GetSemiPhysicalRunConfig() *config.VobcConfig {
|
|
|
|
|
return &s.runConfig.Vobc
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 15:23:29 +08:00
|
|
|
|
// 获取所有联锁配置唯一Code
|
|
|
|
|
func (s *VerifySimulation) GetInterlockCodes() []*config.InterlockConfig {
|
|
|
|
|
stationMap := make(map[string]string)
|
|
|
|
|
for _, station := range s.Repo.StationList() {
|
|
|
|
|
stationMap[station.GetCode()] = station.Id()
|
|
|
|
|
}
|
|
|
|
|
var configs []*config.InterlockConfig
|
|
|
|
|
for _, c := range s.runConfig.Interlocks {
|
|
|
|
|
if stationMap[c.Code] == "" || !c.Open {
|
|
|
|
|
continue
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
configs = append(configs, &config.InterlockConfig{
|
|
|
|
|
Code: stationMap[c.Code],
|
|
|
|
|
Ip: c.Ip,
|
|
|
|
|
LocalPort: c.LocalPort,
|
|
|
|
|
RemotePort: c.RemotePort,
|
|
|
|
|
Open: c.Open,
|
|
|
|
|
})
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
return configs
|
2023-10-24 09:03:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 15:23:29 +08:00
|
|
|
|
// 处理接到的联锁消息
|
|
|
|
|
func (s *VerifySimulation) HandleInterlockDriverInfo(code string, b []byte) {
|
|
|
|
|
for _, m := range s.Repo.CentralizedList() { // 获取继电器地图信息
|
|
|
|
|
if m.StationId != code {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-11-01 16:55:16 +08:00
|
|
|
|
driverMsg := message.NewInterlockReceiveMsgPkg(0, len(m.QdList), len(m.TransponderId))
|
2023-10-31 15:23:29 +08:00
|
|
|
|
driverMsg.Decode(b)
|
|
|
|
|
driveState := driverMsg.DriveInfo
|
|
|
|
|
for i, r := range m.QdList {
|
|
|
|
|
ds := driveState[i]
|
|
|
|
|
for _, b := range r.RefRelays {
|
|
|
|
|
slog.Debug("继电器位【%s】获取到驱动状态【%v】", b, ds)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-01 16:55:16 +08:00
|
|
|
|
return
|
2023-10-31 15:23:29 +08:00
|
|
|
|
}
|
2023-10-26 15:06:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 10:57:04 +08:00
|
|
|
|
// 采集联锁中的继电器消息
|
2023-10-31 15:23:29 +08:00
|
|
|
|
func (s *VerifySimulation) CollectInterlockRelayInfo(code string) *message.InterlockSendMsgPkg {
|
2023-10-31 09:39:40 +08:00
|
|
|
|
for _, m := range s.Repo.CentralizedList() { // 获取继电器地图信息
|
2023-10-31 15:23:29 +08:00
|
|
|
|
if m.StationId != code {
|
2023-10-27 17:57:12 +08:00
|
|
|
|
continue
|
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
if len(m.CjList) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-10-31 09:39:40 +08:00
|
|
|
|
collectInfo := make([]bool, len(m.CjList))
|
|
|
|
|
for i, l := range m.CjList {
|
|
|
|
|
if l == nil || len(l.RefRelays) == 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
rs := true
|
|
|
|
|
for _, j := range l.RefRelays {
|
|
|
|
|
if j.Position == proto.CjDataItem_Q {
|
|
|
|
|
rs = rs && fi.CollectXQCircuitState(s.World, j.RelayId)
|
|
|
|
|
} else {
|
|
|
|
|
rs = rs && fi.CollectLXCircuitState(s.World, j.RelayId)
|
2023-10-27 17:57:12 +08:00
|
|
|
|
}
|
2023-11-01 16:55:16 +08:00
|
|
|
|
if !rs {
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-10-27 17:57:12 +08:00
|
|
|
|
}
|
2023-10-31 09:39:40 +08:00
|
|
|
|
collectInfo[i] = rs
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
return &message.InterlockSendMsgPkg{Info: collectInfo}
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
return nil
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
2023-10-24 09:03:38 +08:00
|
|
|
|
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 初始化仿真运行配置
|
2023-10-26 18:09:09 +08:00
|
|
|
|
func (s *VerifySimulation) initRunConfig(runConfig *dto.ProjectRunConfigDto) error {
|
|
|
|
|
if runConfig == nil || runConfig.ConfigContent == "" {
|
2023-10-26 15:06:26 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
var configMap config.ThridPartyConfig
|
2023-10-26 18:09:09 +08:00
|
|
|
|
err := json.Unmarshal([]byte(runConfig.ConfigContent), &configMap)
|
2023-10-26 15:06:26 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return sys_error.New("配置信息格式错误", err)
|
|
|
|
|
}
|
|
|
|
|
s.runConfig = &configMap
|
2023-10-26 18:09:09 +08:00
|
|
|
|
s.runConfig.Id = runConfig.Id
|
2023-10-26 15:06:26 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 09:12:40 +08:00
|
|
|
|
// 获取仿真运行参数ID
|
|
|
|
|
func (s *VerifySimulation) GetRunConfigId() int32 {
|
|
|
|
|
if s.runConfig == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
return s.runConfig.Id
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-26 15:06:26 +08:00
|
|
|
|
// 初始化运行资源
|
|
|
|
|
func (s *VerifySimulation) initRepository() error {
|
|
|
|
|
// 构建Repository
|
|
|
|
|
var mapIdStrSlice []string
|
|
|
|
|
for _, id := range s.MapIds {
|
|
|
|
|
mapIdStrSlice = append(mapIdStrSlice, strconv.Itoa(int(id)))
|
|
|
|
|
}
|
|
|
|
|
repoId := strings.Join(mapIdStrSlice, "|")
|
|
|
|
|
repoVersion := "0.1"
|
|
|
|
|
repo := repository.FindRepository(repoId, repoVersion)
|
|
|
|
|
if repo == nil {
|
|
|
|
|
protoRepo, err := buildProtoRepository(s.MapIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return sys_error.New("数据错误", err)
|
|
|
|
|
}
|
|
|
|
|
protoRepo.Id, protoRepo.Version = repoId, repoVersion
|
|
|
|
|
newRepo, err := repository.BuildRepository(protoRepo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return sys_error.New("数据错误", err)
|
|
|
|
|
}
|
|
|
|
|
repo = newRepo
|
|
|
|
|
}
|
|
|
|
|
s.Repo = repo
|
|
|
|
|
s.Memory = NewWaysideMemory()
|
|
|
|
|
// 构建所有UID映射关系,
|
|
|
|
|
s.uidMap = buildRepositoryAllUidsMap(s.MapIds, s.Repo)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 15:13:25 +08:00
|
|
|
|
func buildProtoRepository(mapIds []int32) (*proto.Repository, error) {
|
2023-09-20 15:14:40 +08:00
|
|
|
|
repo := &proto.Repository{}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
var exceptStationGiMapIds []int32
|
|
|
|
|
//创建设备
|
|
|
|
|
for _, mapId := range mapIds {
|
|
|
|
|
giType := QueryGiType(mapId)
|
|
|
|
|
if giType == graphicData.PictureType_StationLayout {
|
|
|
|
|
stationGi := QueryGiData[*graphicData.RtssGraphicStorage](mapId)
|
|
|
|
|
fillProtoRepository(repo, stationGi, mapId)
|
|
|
|
|
} else {
|
|
|
|
|
exceptStationGiMapIds = append(exceptStationGiMapIds, mapId)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-28 14:10:20 +08:00
|
|
|
|
//构建并关联电子元件
|
2023-09-22 15:13:25 +08:00
|
|
|
|
for _, mapId := range exceptStationGiMapIds {
|
|
|
|
|
giType := QueryGiType(mapId)
|
|
|
|
|
if giType == graphicData.PictureType_RelayCabinetLayout {
|
|
|
|
|
relayGi := QueryGiData[*graphicData.RelayCabinetGraphicStorage](mapId)
|
2023-09-28 14:10:20 +08:00
|
|
|
|
buildAndRelateElectronicComponent(repo, relayGi, mapId)
|
2023-09-22 15:13:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return repo, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 14:10:20 +08:00
|
|
|
|
func buildAndRelateElectronicComponent(repo *proto.Repository, relayGi *graphicData.RelayCabinetGraphicStorage, mapId int32) {
|
2023-10-27 14:57:37 +08:00
|
|
|
|
uidsMap := QueryUidStructure[*RelayUidStructure](mapId)
|
2023-09-22 15:13:25 +08:00
|
|
|
|
city := relayGi.UniqueIdPrefix.City
|
|
|
|
|
lineId := relayGi.UniqueIdPrefix.LineId
|
|
|
|
|
station := relayGi.UniqueIdPrefix.BelongsConcentrationStation
|
2023-11-02 15:54:26 +08:00
|
|
|
|
stationUid := GenerateElementUid(city, lineId, nil, station)
|
2023-10-19 17:09:57 +08:00
|
|
|
|
relayMap := make(map[string]*proto.Relay)
|
2023-09-22 15:13:25 +08:00
|
|
|
|
for _, relay := range relayGi.Relays {
|
2023-10-19 17:09:57 +08:00
|
|
|
|
repoRelay := &proto.Relay{
|
2023-11-02 15:54:26 +08:00
|
|
|
|
Id: uidsMap.RelayIds[relay.Common.Id].Uid,
|
|
|
|
|
Code: relay.Code,
|
|
|
|
|
Model: convertRelayModel(relay.NewModel),
|
|
|
|
|
StationId: stationUid,
|
2023-10-19 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
repo.Relays = append(repo.Relays, repoRelay)
|
|
|
|
|
relayMap[repoRelay.Id] = repoRelay
|
2023-09-28 14:10:20 +08:00
|
|
|
|
}
|
|
|
|
|
for _, pfp := range relayGi.PhaseFailureProtectors {
|
|
|
|
|
repo.PhaseFailureProtectors = append(repo.PhaseFailureProtectors, &proto.PhaseFailureProtector{
|
|
|
|
|
Id: uidsMap.RelayIds[pfp.Common.Id].Uid,
|
|
|
|
|
Code: pfp.Code,
|
2023-09-22 15:13:25 +08:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
turnoutMap := make(map[string]*proto.Turnout)
|
|
|
|
|
for _, turnout := range repo.Turnouts {
|
|
|
|
|
turnoutMap[turnout.Id] = turnout
|
|
|
|
|
}
|
|
|
|
|
signalMap := make(map[string]*proto.Signal)
|
|
|
|
|
for _, signal := range repo.Signals {
|
|
|
|
|
signalMap[signal.Id] = signal
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
stationMap := make(map[string]*proto.Station)
|
|
|
|
|
for _, station := range repo.Stations {
|
|
|
|
|
stationMap[station.Id] = station
|
|
|
|
|
}
|
2023-10-19 17:09:57 +08:00
|
|
|
|
psdMap := make(map[string]*proto.Psd)
|
|
|
|
|
for _, psd := range repo.Psds {
|
|
|
|
|
psdMap[psd.Id] = psd
|
|
|
|
|
}
|
|
|
|
|
platformMap := make(map[string]*proto.Platform)
|
|
|
|
|
for _, platform := range repo.Platforms {
|
|
|
|
|
platformMap[platform.Id] = platform
|
|
|
|
|
}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
for _, relationship := range relayGi.DeviceRelateRelayList {
|
2023-09-26 09:34:23 +08:00
|
|
|
|
switch relationship.DeviceType {
|
|
|
|
|
case graphicData.RelatedRef_Turnout:
|
2023-09-22 15:13:25 +08:00
|
|
|
|
turnout := turnoutMap[GenerateElementUid(city, lineId, []string{station}, relationship.Code)]
|
2023-09-26 10:25:01 +08:00
|
|
|
|
if turnout == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
for _, group := range relationship.Combinationtypes {
|
2023-09-28 14:10:20 +08:00
|
|
|
|
var componentIds []string
|
2023-09-26 13:45:01 +08:00
|
|
|
|
for _, relayId := range group.RefRelays {
|
2023-09-27 14:15:11 +08:00
|
|
|
|
if uidsMap.RelayIds[relayId] == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-09-28 14:10:20 +08:00
|
|
|
|
componentIds = append(componentIds, uidsMap.RelayIds[relayId].Uid)
|
2023-09-26 13:45:01 +08:00
|
|
|
|
}
|
2023-09-28 14:10:20 +08:00
|
|
|
|
turnout.ElectronicComponentGroups = append(turnout.ElectronicComponentGroups,
|
|
|
|
|
&proto.ElectronicComponentGroup{
|
|
|
|
|
Code: group.Code,
|
|
|
|
|
ComponentIds: componentIds,
|
|
|
|
|
})
|
2023-09-22 15:13:25 +08:00
|
|
|
|
}
|
2023-09-26 09:34:23 +08:00
|
|
|
|
case graphicData.RelatedRef_signal:
|
2023-09-22 15:13:25 +08:00
|
|
|
|
signal := signalMap[GenerateElementUid(city, lineId, []string{station}, relationship.Code)]
|
2023-09-26 10:25:01 +08:00
|
|
|
|
if signal == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-10-16 14:06:47 +08:00
|
|
|
|
//信号机只有一个组合类型
|
|
|
|
|
if len(relationship.Combinationtypes) != 1 {
|
|
|
|
|
panic(fmt.Sprintf("信号机[%s]须有一个组合类型", signal.Id))
|
|
|
|
|
}
|
|
|
|
|
group := relationship.Combinationtypes[0]
|
|
|
|
|
var componentIds []string
|
|
|
|
|
for _, relayId := range group.RefRelays {
|
|
|
|
|
if uidsMap.RelayIds[relayId] == nil {
|
|
|
|
|
continue
|
2023-09-26 13:45:01 +08:00
|
|
|
|
}
|
2023-10-16 14:06:47 +08:00
|
|
|
|
componentIds = append(componentIds, uidsMap.RelayIds[relayId].Uid)
|
2023-09-22 15:13:25 +08:00
|
|
|
|
}
|
2023-10-16 14:06:47 +08:00
|
|
|
|
signal.Code = group.Code
|
|
|
|
|
signal.ElectronicComponentGroups = append(signal.ElectronicComponentGroups,
|
|
|
|
|
&proto.ElectronicComponentGroup{
|
|
|
|
|
Code: group.Code,
|
|
|
|
|
ComponentIds: componentIds,
|
|
|
|
|
})
|
2023-10-16 14:52:58 +08:00
|
|
|
|
case graphicData.RelatedRef_station:
|
|
|
|
|
station := stationMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
|
|
|
|
|
if station == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
for _, group := range relationship.Combinationtypes {
|
2023-10-16 14:52:58 +08:00
|
|
|
|
d := &proto.ElectronicGroup{Code: group.Code}
|
2023-09-26 13:45:01 +08:00
|
|
|
|
for _, relayId := range group.RefRelays {
|
2023-09-27 14:15:11 +08:00
|
|
|
|
if uidsMap.RelayIds[relayId] == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
d.Components = append(d.Components, &proto.ElectronicComponent{
|
|
|
|
|
Id: uidsMap.RelayIds[relayId].Uid,
|
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Relay,
|
2023-09-28 14:10:20 +08:00
|
|
|
|
})
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
|
|
|
|
station.ElectronicGroup = append(station.ElectronicGroup, d)
|
2023-09-22 15:13:25 +08:00
|
|
|
|
}
|
2023-10-19 17:09:57 +08:00
|
|
|
|
case graphicData.RelatedRef_ScreenDoor:
|
|
|
|
|
psd, ok := psdMap[GenerateElementUid(city, lineId, nil, relationship.Code)]
|
|
|
|
|
if !ok {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
for _, group := range relationship.Combinationtypes {
|
|
|
|
|
var componentIds []string
|
|
|
|
|
for _, relayId := range group.RefRelays {
|
|
|
|
|
if uidsMap.RelayIds[relayId] == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
componentIds = append(componentIds, uidsMap.RelayIds[relayId].Uid)
|
|
|
|
|
}
|
|
|
|
|
psd.ElectronicComponentGroups = append(psd.ElectronicComponentGroups,
|
|
|
|
|
&proto.ElectronicComponentGroup{
|
|
|
|
|
Code: group.Code,
|
|
|
|
|
ComponentIds: componentIds,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//门控箱
|
|
|
|
|
for _, mkx := range repo.Mkxs {
|
|
|
|
|
platform := platformMap[psdMap[mkx.PsdId].GetPlatformId()]
|
|
|
|
|
station := stationMap[platform.GetStationId()]
|
|
|
|
|
var s string
|
|
|
|
|
if strings.Contains(platform.GetCode(), "上行") {
|
|
|
|
|
s = "S"
|
|
|
|
|
} else if strings.Contains(platform.GetCode(), "下行") {
|
|
|
|
|
s = "X"
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
for _, group := range station.ElectronicGroup {
|
|
|
|
|
if group.Code == "MKX" {
|
|
|
|
|
for _, component := range group.Components {
|
|
|
|
|
relay := relayMap[component.Id]
|
|
|
|
|
if strings.Contains(relay.GetCode(), s) {
|
2023-11-01 16:52:08 +08:00
|
|
|
|
if strings.Contains(relay.GetCode(), "PCB") {
|
|
|
|
|
mkx.PcbjId = relay.Id
|
|
|
|
|
} else if strings.Contains(relay.GetCode(), "POB") {
|
|
|
|
|
mkx.PobjId = relay.Id
|
|
|
|
|
} else if strings.Contains(relay.GetCode(), "PAB") {
|
|
|
|
|
mkx.PabjId = relay.Id
|
|
|
|
|
}
|
2023-10-19 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-10-31 09:39:40 +08:00
|
|
|
|
// 处理该集中站采集、驱动配置信息
|
|
|
|
|
centralizedStationId := GenerateElementUid(city, lineId, nil, station)
|
|
|
|
|
ref := queryCentralizedStationRef(centralizedStationId, repo)
|
|
|
|
|
ref.CjList = append(ref.CjList, handlerRelayGiCj(uidsMap, centralizedStationId, relayGi.CiCjList)...)
|
|
|
|
|
ref.QdList = append(ref.QdList, handlerRelayGiQd(uidsMap, centralizedStationId, relayGi.CiQdList)...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询集中站配置信息
|
|
|
|
|
func queryCentralizedStationRef(stationId string, repo *proto.Repository) *proto.CentralizedStationRef {
|
|
|
|
|
var ref *proto.CentralizedStationRef
|
|
|
|
|
for _, r := range repo.CentralizedStationRefs {
|
|
|
|
|
if r.StationId == stationId {
|
|
|
|
|
ref = r
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ref == nil {
|
|
|
|
|
ref = &proto.CentralizedStationRef{StationId: stationId}
|
|
|
|
|
repo.CentralizedStationRefs = append(repo.CentralizedStationRefs, ref)
|
|
|
|
|
}
|
|
|
|
|
return ref
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理继电器采集信息
|
|
|
|
|
func handlerRelayGiCj(uidsMap *RelayUidStructure, stationId string, ciCj *graphicData.CiCj) []*proto.CjData {
|
|
|
|
|
if ciCj == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
// 采集信息
|
|
|
|
|
dataLenght := len(ciCj.CjList) * int(ciCj.DsCount)
|
|
|
|
|
if dataLenght == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
cjList := make([]*proto.CjData, dataLenght)
|
|
|
|
|
index := 0
|
|
|
|
|
for ci, col := range ciCj.CjList {
|
|
|
|
|
for ri, row := range col.BitList {
|
|
|
|
|
if len(row.RefRelays) == 0 {
|
|
|
|
|
index++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
r := &proto.CjData{Row: int32(ri), Col: int32(ci)}
|
|
|
|
|
for _, j := range row.RefRelays {
|
|
|
|
|
u := uidsMap.RelayIds[j.RelayId]
|
|
|
|
|
if u == nil {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%s】UID映射关系", stationId, j.RelayId)))
|
|
|
|
|
}
|
|
|
|
|
d := &proto.CjDataItem{RelayId: u.Uid}
|
|
|
|
|
if j.Position == graphicData.CjDataItem_H {
|
|
|
|
|
d.Position = proto.CjDataItem_H
|
|
|
|
|
} else {
|
|
|
|
|
d.Position = proto.CjDataItem_Q
|
|
|
|
|
}
|
|
|
|
|
r.RefRelays = append(r.RefRelays, d)
|
|
|
|
|
}
|
|
|
|
|
cjList[index] = r
|
|
|
|
|
index++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cjList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理继电器驱动信息
|
|
|
|
|
func handlerRelayGiQd(uidsMap *RelayUidStructure, stationId string, ciQd *graphicData.CiQd) []*proto.QdData {
|
|
|
|
|
if ciQd == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
// 驱动信息
|
|
|
|
|
dataLenght := len(ciQd.QdList) * int(ciQd.DsCount)
|
|
|
|
|
if dataLenght == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
qdList := make([]*proto.QdData, dataLenght)
|
|
|
|
|
index := 0
|
|
|
|
|
for ci, col := range ciQd.QdList {
|
|
|
|
|
for ri, row := range col.BitList {
|
|
|
|
|
if len(row.RefRelays) == 0 {
|
|
|
|
|
index++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
r := &proto.QdData{Row: int32(ri), Col: int32(ci)}
|
|
|
|
|
for _, j := range row.RefRelays {
|
|
|
|
|
u := uidsMap.RelayIds[j]
|
|
|
|
|
if u == nil {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("集中站【id:%s】不存在继电器的【comId:%s】UID映射关系", stationId, j)))
|
|
|
|
|
}
|
|
|
|
|
r.RefRelays = append(r.RefRelays, u.Uid)
|
|
|
|
|
}
|
|
|
|
|
qdList[index] = r
|
|
|
|
|
index++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return qdList
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 14:10:20 +08:00
|
|
|
|
func convertRelayModel(modelType graphicData.Relay_ModelType) proto.Relay_Model {
|
|
|
|
|
switch modelType {
|
|
|
|
|
case graphicData.Relay_Unknown:
|
|
|
|
|
return proto.Relay_Unknown
|
|
|
|
|
case graphicData.Relay_JPXC_1000:
|
|
|
|
|
return proto.Relay_JPXC_1000
|
|
|
|
|
case graphicData.Relay_JPXC_1700:
|
|
|
|
|
return proto.Relay_JPXC_1700
|
|
|
|
|
case graphicData.Relay_JWJXC_480:
|
|
|
|
|
return proto.Relay_JWJXC_480
|
|
|
|
|
case graphicData.Relay_JWJXC_H125_80:
|
|
|
|
|
return proto.Relay_JWJXC_H125_80
|
|
|
|
|
case graphicData.Relay_JWXC_1700:
|
|
|
|
|
return proto.Relay_JWXC_1700
|
|
|
|
|
case graphicData.Relay_JWXC_H340:
|
|
|
|
|
return proto.Relay_JWXC_H340
|
|
|
|
|
case graphicData.Relay_JYJXC_160_260:
|
|
|
|
|
return proto.Relay_JYJXC_160_260
|
|
|
|
|
case graphicData.Relay_JZXC_H18:
|
|
|
|
|
return proto.Relay_JZXC_H18
|
|
|
|
|
default:
|
|
|
|
|
panic(fmt.Sprintf("意料之外的继电器型号:%s", modelType))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 14:54:27 +08:00
|
|
|
|
func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphicStorage, mapId int32) {
|
2023-10-19 18:04:21 +08:00
|
|
|
|
repo.MainCoordinateSystem = storage.UniqueIdPrefix.MainCoordinateSystem
|
2023-09-20 15:14:40 +08:00
|
|
|
|
axleCountingMap := make(map[string]*graphicData.AxleCounting)
|
2023-10-27 14:57:37 +08:00
|
|
|
|
uidsMap := QueryUidStructure[*StationUidStructure](mapId)
|
2023-09-20 15:14:40 +08:00
|
|
|
|
for _, data := range storage.AxleCountings {
|
|
|
|
|
axleCountingMap[data.Common.Id] = data
|
|
|
|
|
cpType := proto.CheckPointType_AxleCounter
|
2023-09-21 14:54:27 +08:00
|
|
|
|
if data.Type == graphicData.AxleCounting_SectionBoundary {
|
2023-09-20 15:14:40 +08:00
|
|
|
|
cpType = proto.CheckPointType_Boundary
|
|
|
|
|
}
|
|
|
|
|
cp := &proto.CheckPoint{
|
2023-09-21 17:57:50 +08:00
|
|
|
|
Id: data.Common.Id,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
Km: convertKm(data.KilometerSystem),
|
|
|
|
|
Type: cpType,
|
|
|
|
|
DevicePorts: convertDevicePorts(data.AxleCountingRef),
|
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.CheckPoints = append(repo.CheckPoints, converCheckPointUid(cp, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.Section {
|
|
|
|
|
var turnoutIds []string
|
|
|
|
|
if data.SectionType == graphicData.Section_TurnoutPhysical {
|
|
|
|
|
turnoutIds = findTurnoutIds(axleCountingMap, data.AxleCountings)
|
|
|
|
|
}
|
2023-10-31 16:53:39 +08:00
|
|
|
|
centralizedStation := ""
|
|
|
|
|
if len(data.CentralizedStations) > 0 {
|
|
|
|
|
centralizedStation = data.CentralizedStations[0]
|
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
physicalSection := &proto.PhysicalSection{
|
2023-10-31 16:53:39 +08:00
|
|
|
|
Id: data.Common.Id,
|
|
|
|
|
ADevicePort: convertDevicePort(data.PaRef),
|
|
|
|
|
BDevicePort: convertDevicePort(data.PbRef),
|
|
|
|
|
TurnoutIds: turnoutIds,
|
|
|
|
|
CentralizedStation: centralizedStation,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.PhysicalSections = append(repo.PhysicalSections, converSectionUid(physicalSection, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.Turnouts {
|
|
|
|
|
var km *proto.Kilometer
|
|
|
|
|
for _, ks := range data.KilometerSystem {
|
|
|
|
|
if ks.Kilometer != 0 {
|
|
|
|
|
km = convertKm(ks)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-28 17:45:08 +08:00
|
|
|
|
var switchMachineType proto.Turnout_SwitchMachineType
|
|
|
|
|
switch data.SwitchMachineType {
|
|
|
|
|
case graphicData.Turnout_ZDJ9_Single:
|
|
|
|
|
switchMachineType = proto.Turnout_ZDJ9_Single
|
|
|
|
|
case graphicData.Turnout_ZDJ9_Double:
|
|
|
|
|
switchMachineType = proto.Turnout_ZDJ9_Double
|
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
turnout := &proto.Turnout{
|
2023-09-28 17:45:08 +08:00
|
|
|
|
Id: data.Common.Id,
|
|
|
|
|
Km: km,
|
|
|
|
|
ADevicePort: convertDevicePort(data.PaRef),
|
|
|
|
|
BDevicePort: convertDevicePort(data.PbRef),
|
|
|
|
|
CDevicePort: convertDevicePort(data.PcRef),
|
|
|
|
|
SwitchMachineType: switchMachineType,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.Turnouts = append(repo.Turnouts, converTurnoutUid(turnout, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.Signals {
|
|
|
|
|
var sectionId string
|
|
|
|
|
var turnoutPort *proto.DevicePort
|
|
|
|
|
switch data.RefDev.DeviceType {
|
|
|
|
|
case graphicData.RelatedRef_Section:
|
|
|
|
|
sectionId = data.RefDev.Id
|
|
|
|
|
case graphicData.RelatedRef_Turnout:
|
|
|
|
|
turnoutPort = convertDevicePort(data.RefDev)
|
|
|
|
|
}
|
|
|
|
|
signal := &proto.Signal{
|
2023-09-21 17:57:50 +08:00
|
|
|
|
Id: data.Common.Id,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
Km: convertKm(data.KilometerSystem),
|
|
|
|
|
SectionId: sectionId,
|
|
|
|
|
TurnoutPort: turnoutPort,
|
2023-10-20 09:38:23 +08:00
|
|
|
|
Model: convertToProtoSignalModel(data.Mt),
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.Signals = append(repo.Signals, converSignalUid(signal, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-10-31 09:39:40 +08:00
|
|
|
|
stm := make(map[string][]string)
|
2023-09-20 15:14:40 +08:00
|
|
|
|
for _, data := range storage.Transponders {
|
|
|
|
|
var sectionId string
|
|
|
|
|
var turnoutPort *proto.DevicePort
|
|
|
|
|
switch data.TransponderRef.DeviceType {
|
|
|
|
|
case graphicData.RelatedRef_Section:
|
|
|
|
|
sectionId = data.TransponderRef.Id
|
|
|
|
|
case graphicData.RelatedRef_Turnout:
|
|
|
|
|
turnoutPort = convertDevicePort(data.TransponderRef)
|
|
|
|
|
}
|
|
|
|
|
responder := &proto.Transponder{
|
2023-09-21 17:57:50 +08:00
|
|
|
|
Id: data.Common.Id,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
Km: convertKm(data.KilometerSystem),
|
|
|
|
|
SectionId: sectionId,
|
|
|
|
|
TurnoutPort: turnoutPort,
|
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.Transponders = append(repo.Transponders, converTransponderUid(responder, uidsMap))
|
2023-10-31 09:39:40 +08:00
|
|
|
|
for _, stationName := range data.CentralizedStations {
|
|
|
|
|
if stm[stationName] == nil {
|
|
|
|
|
stm[stationName] = []string{responder.Id}
|
|
|
|
|
} else {
|
|
|
|
|
stm[stationName] = append(stm[stationName], responder.Id)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
slopeKsMap := make(map[string]*graphicData.SlopeKiloMarker)
|
|
|
|
|
for _, data := range storage.SlopeKiloMarker {
|
|
|
|
|
slopeKsMap[data.Common.Id] = data
|
|
|
|
|
}
|
|
|
|
|
curveKsMap := make(map[string]*graphicData.CurvatureKiloMarker)
|
|
|
|
|
for _, data := range storage.CurvatureKiloMarker {
|
|
|
|
|
curveKsMap[data.Common.Id] = data
|
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.Slopes {
|
|
|
|
|
var kms []*proto.Kilometer
|
|
|
|
|
for _, id := range data.RefDeviceId {
|
|
|
|
|
kms = append(kms, convertKm(slopeKsMap[id].KilometerSystem[0]))
|
|
|
|
|
}
|
|
|
|
|
slope := &proto.Slope{
|
2023-09-21 17:57:50 +08:00
|
|
|
|
Id: data.Common.Id,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
Kms: kms,
|
|
|
|
|
Degree: data.SlopeNumber,
|
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.Slopes = append(repo.Slopes, converSlopeUid(slope, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.Curvatures {
|
|
|
|
|
var kms []*proto.Kilometer
|
|
|
|
|
for _, id := range data.RefDeviceId {
|
|
|
|
|
kms = append(kms, convertKm(curveKsMap[id].KilometerSystem[0]))
|
|
|
|
|
}
|
|
|
|
|
slope := &proto.SectionalCurvature{
|
2023-09-21 17:57:50 +08:00
|
|
|
|
Id: data.Common.Id,
|
2023-09-20 15:14:40 +08:00
|
|
|
|
Kms: kms,
|
|
|
|
|
Radius: data.CurvatureNumber,
|
|
|
|
|
}
|
2023-09-21 17:57:50 +08:00
|
|
|
|
repo.SectionalCurvatures = append(repo.SectionalCurvatures, converCurvatureUid(slope, uidsMap))
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-09-26 09:34:23 +08:00
|
|
|
|
for _, data := range storage.KilometerConvertList {
|
|
|
|
|
repo.KilometerConverts = append(repo.KilometerConverts, &proto.KilometerConvert{
|
|
|
|
|
KmA: convertKm(data.KmA),
|
|
|
|
|
KmB: convertKm(data.KmB),
|
|
|
|
|
SameTrend: data.SameTrend,
|
|
|
|
|
})
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
// 初始化站场图按钮
|
|
|
|
|
for _, data := range storage.EsbButtons {
|
|
|
|
|
repo.Buttons = append(repo.Buttons, &proto.Button{
|
|
|
|
|
Id: uidsMap.ButtonIds[data.Common.Id].Uid,
|
|
|
|
|
Code: data.Code,
|
|
|
|
|
ButtonType: proto.Button_Reset_Press,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// 车站关联关系
|
|
|
|
|
relateMap := make(map[string]*graphicData.StationRelateDevice)
|
|
|
|
|
for _, data := range storage.StationRelateDeviceList {
|
|
|
|
|
relateMap[data.Code] = data
|
|
|
|
|
}
|
|
|
|
|
// 处理车站信息
|
|
|
|
|
for _, data := range storage.Stations {
|
|
|
|
|
station := &proto.Station{
|
|
|
|
|
Id: uidsMap.StationIds[data.Common.Id].Uid,
|
2023-10-20 10:59:27 +08:00
|
|
|
|
Code: data.StationName,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
|
|
|
|
// 关联车站的设备
|
|
|
|
|
refs, ok := relateMap[data.Code]
|
|
|
|
|
if ok {
|
|
|
|
|
for _, c := range refs.Combinationtypes {
|
|
|
|
|
group := &proto.ElectronicGroup{Code: c.Code}
|
|
|
|
|
for _, d := range c.RefDevices {
|
|
|
|
|
var comp *proto.ElectronicComponent
|
|
|
|
|
if uidsMap.ButtonIds[d] != nil { // 目前只处理按钮
|
|
|
|
|
comp = &proto.ElectronicComponent{
|
|
|
|
|
Id: uidsMap.ButtonIds[d].Uid,
|
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Button,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
group.Components = append(group.Components, comp)
|
|
|
|
|
}
|
|
|
|
|
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 处理车站关联IBP的设备
|
2023-10-20 10:59:27 +08:00
|
|
|
|
handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
|
2023-10-16 14:52:58 +08:00
|
|
|
|
repo.Stations = append(repo.Stations, station)
|
2023-10-31 09:39:40 +08:00
|
|
|
|
// 处理集中站的信息
|
|
|
|
|
if stm[station.Code] != nil {
|
|
|
|
|
ref := queryCentralizedStationRef(station.Id, repo)
|
|
|
|
|
ref.TransponderId = append(ref.TransponderId, stm[station.Code]...)
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
2023-10-19 17:09:57 +08:00
|
|
|
|
//门控箱
|
|
|
|
|
for _, data := range storage.GateBoxs {
|
2023-11-01 16:52:08 +08:00
|
|
|
|
mkx := &proto.Mkx{
|
|
|
|
|
Id: uidsMap.GateBoxIds[data.Common.Id].Uid,
|
|
|
|
|
PsdId: uidsMap.PsdIds[data.RefScreenDoor].Uid,
|
2023-10-19 17:09:57 +08:00
|
|
|
|
}
|
2023-11-01 16:52:08 +08:00
|
|
|
|
repo.Mkxs = append(repo.Mkxs, mkx)
|
2023-10-19 17:09:57 +08:00
|
|
|
|
pslMapId := QueryGiId(data.RefGatedBoxMapCode)
|
|
|
|
|
pslStorage := QueryGiData[*graphicData.PslGraphicStorage](pslMapId)
|
|
|
|
|
for _, button := range pslStorage.PslButtons {
|
|
|
|
|
repoButton := &proto.Button{
|
2023-10-20 16:12:47 +08:00
|
|
|
|
Id: uidsMap.GateBoxIds[data.Common.Id].Uid + "_" + button.Code,
|
2023-10-19 17:09:57 +08:00
|
|
|
|
Code: button.Code,
|
|
|
|
|
ButtonType: proto.Button_Reset_Press,
|
|
|
|
|
HasLight: true,
|
|
|
|
|
}
|
|
|
|
|
repo.Buttons = append(repo.Buttons, repoButton)
|
|
|
|
|
switch button.Code {
|
|
|
|
|
case "PCB":
|
2023-11-01 16:52:08 +08:00
|
|
|
|
mkx.PcbButtonId = repoButton.Id
|
2023-10-19 17:09:57 +08:00
|
|
|
|
case "POB":
|
2023-11-01 16:52:08 +08:00
|
|
|
|
mkx.PobButtonId = repoButton.Id
|
2023-10-19 17:09:57 +08:00
|
|
|
|
case "PAB":
|
2023-11-01 16:52:08 +08:00
|
|
|
|
mkx.PabButtonId = repoButton.Id
|
2023-10-19 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//站台
|
|
|
|
|
platformMap := make(map[string]*graphicData.Platform)
|
|
|
|
|
for _, data := range storage.Platforms {
|
|
|
|
|
platformMap[data.Common.Id] = data
|
|
|
|
|
platform := &proto.Platform{
|
|
|
|
|
Id: uidsMap.PlatformIds[data.Common.Id].Uid,
|
|
|
|
|
Code: data.Code,
|
|
|
|
|
}
|
|
|
|
|
repo.Platforms = append(repo.Platforms, platform)
|
|
|
|
|
platform.StationId = uidsMap.StationIds[data.RefStationId].Uid
|
|
|
|
|
platform.PhysicalSectionId = uidsMap.PhysicalSectionIds[data.RefSectionId].Uid
|
|
|
|
|
}
|
|
|
|
|
//屏蔽门
|
|
|
|
|
for _, data := range storage.ScreenDoors {
|
2023-11-01 16:52:08 +08:00
|
|
|
|
var asdGroups []*proto.AsdGroup
|
|
|
|
|
for _, group := range data.ScreenDoorGroupList {
|
|
|
|
|
asdGroups = append(asdGroups, &proto.AsdGroup{
|
|
|
|
|
Group: group.TrainGroupAmount,
|
|
|
|
|
Start: group.StartSmallDoor,
|
|
|
|
|
End: group.EndSmallDoor,
|
|
|
|
|
})
|
|
|
|
|
}
|
2023-10-19 17:09:57 +08:00
|
|
|
|
psd := &proto.Psd{
|
|
|
|
|
Id: uidsMap.PsdIds[data.Common.Id].Uid,
|
2023-11-01 16:52:08 +08:00
|
|
|
|
AsdAmount: data.SonDoorAmount,
|
|
|
|
|
AsdGroups: asdGroups,
|
2023-10-19 17:09:57 +08:00
|
|
|
|
PlatformId: uidsMap.PlatformIds[data.RefPlatformId].Uid,
|
|
|
|
|
}
|
|
|
|
|
repo.Psds = append(repo.Psds, psd)
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将IBP的设备关联到车站中
|
2023-10-20 10:59:27 +08:00
|
|
|
|
func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, ibpMap string) {
|
2023-10-27 14:57:37 +08:00
|
|
|
|
storage := GetStorageIBPMapData(ibpMap)
|
2023-10-16 14:52:58 +08:00
|
|
|
|
if storage == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-10-20 10:59:27 +08:00
|
|
|
|
deviceMap := make(map[string]*proto.ElectronicComponent) // 对应的设备类型
|
|
|
|
|
for _, data := range storage.IbpButtons { // 处理按钮
|
2023-10-16 14:52:58 +08:00
|
|
|
|
buttonType := proto.Button_NO_Reset_Press
|
|
|
|
|
if data.IsSelfReset {
|
|
|
|
|
buttonType = proto.Button_Reset_Press
|
|
|
|
|
}
|
|
|
|
|
b := &proto.Button{
|
2023-10-20 15:52:50 +08:00
|
|
|
|
Id: station.Id + "_button_" + data.Code,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
Code: data.Code,
|
|
|
|
|
ButtonType: buttonType,
|
2023-10-18 14:09:36 +08:00
|
|
|
|
HasLight: data.HasLight,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
2023-10-20 10:59:27 +08:00
|
|
|
|
deviceMap[data.Common.Id] = &proto.ElectronicComponent{
|
|
|
|
|
Id: b.Id,
|
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Button,
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
repo.Buttons = append(repo.Buttons, b)
|
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.IbpKeys { // 钥匙
|
2023-10-20 13:50:22 +08:00
|
|
|
|
b := &proto.Key{
|
2023-10-20 15:52:50 +08:00
|
|
|
|
Id: station.Id + "_key_" + data.Code,
|
2023-10-20 13:50:22 +08:00
|
|
|
|
Code: data.Code,
|
|
|
|
|
Gear: 2,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
2023-10-20 10:59:27 +08:00
|
|
|
|
deviceMap[data.Common.Id] = &proto.ElectronicComponent{
|
|
|
|
|
Id: b.Id,
|
2023-10-20 13:50:22 +08:00
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Key,
|
2023-10-20 10:59:27 +08:00
|
|
|
|
}
|
2023-10-20 13:50:22 +08:00
|
|
|
|
repo.Keys = append(repo.Keys, b)
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
|
|
|
|
for _, data := range storage.IbpAlarms { // 报警器
|
|
|
|
|
b := &proto.Alarm{
|
2023-10-20 15:52:50 +08:00
|
|
|
|
Id: station.Id + "_alarm_" + data.Code,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
Code: data.Code,
|
|
|
|
|
}
|
2023-10-20 10:59:27 +08:00
|
|
|
|
deviceMap[data.Common.Id] = &proto.ElectronicComponent{
|
|
|
|
|
Id: b.Id,
|
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Alarm,
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
repo.Alarms = append(repo.Alarms, b)
|
|
|
|
|
}
|
2023-10-20 15:52:50 +08:00
|
|
|
|
empGroup := &proto.ElectronicGroup{Code: "EMP"}
|
|
|
|
|
spksGroup := &proto.ElectronicGroup{Code: "SPKS"}
|
|
|
|
|
for _, data := range storage.IbpLights { // 指示灯,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
b := &proto.Light{
|
2023-10-20 15:52:50 +08:00
|
|
|
|
Id: station.Id + "_light_" + data.Code,
|
|
|
|
|
Code: data.Code,
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
2023-10-20 15:52:50 +08:00
|
|
|
|
repo.Lights = append(repo.Lights, b)
|
|
|
|
|
// 存入组合类型的
|
|
|
|
|
c := &proto.ElectronicComponent{
|
2023-10-20 10:59:27 +08:00
|
|
|
|
Id: b.Id,
|
|
|
|
|
DeviceType: proto.DeviceType_DeviceType_Light,
|
|
|
|
|
}
|
2023-10-20 15:52:50 +08:00
|
|
|
|
switch data.Code {
|
|
|
|
|
case "X紧急关闭", "S紧急关闭":
|
|
|
|
|
empGroup.Components = append(empGroup.Components, c)
|
|
|
|
|
case "启用状态_SPKS1", "启用状态_SPKS3", "启用状态_SPKS2", "启用状态_SPKS4":
|
|
|
|
|
spksGroup.Components = append(spksGroup.Components, c)
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
2023-10-20 15:52:50 +08:00
|
|
|
|
for _, data := range storage.IbpRelatedDevices { // 组信息
|
2023-10-16 14:52:58 +08:00
|
|
|
|
for _, c := range data.Combinationtypes {
|
2023-10-20 15:52:50 +08:00
|
|
|
|
var group *proto.ElectronicGroup
|
|
|
|
|
switch c.Code {
|
|
|
|
|
case "EMP":
|
|
|
|
|
group = empGroup
|
|
|
|
|
case "SPKS":
|
|
|
|
|
group = spksGroup
|
|
|
|
|
default:
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-10-16 14:52:58 +08:00
|
|
|
|
for _, d := range c.RefDevices {
|
2023-10-20 10:59:27 +08:00
|
|
|
|
deviceType, ok := deviceMap[d]
|
2023-10-16 14:52:58 +08:00
|
|
|
|
if !ok {
|
|
|
|
|
slog.Debug("IBP组合类型类型不确定id:%s", d)
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-10-20 10:59:27 +08:00
|
|
|
|
group.Components = append(group.Components, deviceType)
|
2023-10-16 14:52:58 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-20 15:52:50 +08:00
|
|
|
|
station.ElectronicGroup = append(station.ElectronicGroup, empGroup, spksGroup)
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converCheckPointUid(data *proto.CheckPoint, uidsMap *StationUidStructure) *proto.CheckPoint {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.AxlePointIds[data.Id].Uid
|
|
|
|
|
for _, c := range data.DevicePorts {
|
|
|
|
|
c.DeviceId = converRefUid(c.DeviceId, c.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converSectionUid(data *proto.PhysicalSection, uidsMap *StationUidStructure) *proto.PhysicalSection {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.PhysicalSectionIds[data.Id].Uid
|
|
|
|
|
if data.ADevicePort != nil {
|
|
|
|
|
data.ADevicePort.DeviceId = converRefUid(data.ADevicePort.DeviceId, data.ADevicePort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
if data.BDevicePort != nil {
|
|
|
|
|
data.BDevicePort.DeviceId = converRefUid(data.BDevicePort.DeviceId, data.BDevicePort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
tids := make([]string, len(data.TurnoutIds))
|
|
|
|
|
for i, tid := range data.TurnoutIds {
|
|
|
|
|
tids[i] = converRefUid(tid, proto.DeviceType_DeviceType_Turnout, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
data.TurnoutIds = tids
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converTurnoutUid(data *proto.Turnout, uidsMap *StationUidStructure) *proto.Turnout {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.TurnoutIds[data.Id].Uid
|
|
|
|
|
if data.ADevicePort != nil {
|
|
|
|
|
data.ADevicePort.DeviceId = converRefUid(data.ADevicePort.DeviceId, data.ADevicePort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
if data.BDevicePort != nil {
|
|
|
|
|
data.BDevicePort.DeviceId = converRefUid(data.BDevicePort.DeviceId, data.BDevicePort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
if data.CDevicePort != nil {
|
|
|
|
|
data.CDevicePort.DeviceId = converRefUid(data.CDevicePort.DeviceId, data.CDevicePort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converSignalUid(data *proto.Signal, uidsMap *StationUidStructure) *proto.Signal {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.SignalIds[data.Id].Uid
|
|
|
|
|
if data.SectionId != "" {
|
|
|
|
|
data.SectionId = converRefUid(data.SectionId, proto.DeviceType_DeviceType_PhysicalSection, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
if data.TurnoutPort != nil {
|
|
|
|
|
data.TurnoutPort.DeviceId = converRefUid(data.TurnoutPort.DeviceId, data.TurnoutPort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converTransponderUid(data *proto.Transponder, uidsMap *StationUidStructure) *proto.Transponder {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.TransponderIds[data.Id].Uid
|
|
|
|
|
if data.SectionId != "" {
|
|
|
|
|
data.SectionId = converRefUid(data.SectionId, proto.DeviceType_DeviceType_PhysicalSection, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
if data.TurnoutPort != nil {
|
|
|
|
|
data.TurnoutPort.DeviceId = converRefUid(data.TurnoutPort.DeviceId, data.TurnoutPort.DeviceType, uidsMap)
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converSlopeUid(data *proto.Slope, uidsMap *StationUidStructure) *proto.Slope {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.SlopeIds[data.Id].Uid
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converCurvatureUid(data *proto.SectionalCurvature, uidsMap *StationUidStructure) *proto.SectionalCurvature {
|
2023-09-21 17:57:50 +08:00
|
|
|
|
data.Id = uidsMap.CurvatureIds[data.Id].Uid
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func converRefUid(id string, d proto.DeviceType, uidsMap *StationUidStructure) string {
|
2023-09-22 15:15:04 +08:00
|
|
|
|
var elementId *elementIdStructure
|
2023-09-21 17:57:50 +08:00
|
|
|
|
switch d {
|
|
|
|
|
case proto.DeviceType_DeviceType_CheckPoint:
|
|
|
|
|
elementId = uidsMap.AxlePointIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
|
|
|
|
elementId = uidsMap.PhysicalSectionIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_SectionalCurvature:
|
|
|
|
|
elementId = uidsMap.CurvatureIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_Signal:
|
|
|
|
|
elementId = uidsMap.SignalIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_Slope:
|
|
|
|
|
elementId = uidsMap.SlopeIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_Transponder:
|
|
|
|
|
elementId = uidsMap.TransponderIds[id]
|
|
|
|
|
case proto.DeviceType_DeviceType_Turnout:
|
|
|
|
|
elementId = uidsMap.TurnoutIds[id]
|
|
|
|
|
default:
|
|
|
|
|
panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "异常的设备类型-" + d.String()})
|
|
|
|
|
}
|
|
|
|
|
return elementId.Uid
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:40 +08:00
|
|
|
|
func convertKm(ks *graphicData.KilometerSystem) *proto.Kilometer {
|
|
|
|
|
var dir proto.Direction
|
|
|
|
|
switch ks.Direction {
|
|
|
|
|
case graphicData.Direction_LEFT:
|
|
|
|
|
dir = proto.Direction_LEFT
|
|
|
|
|
case graphicData.Direction_RIGHT:
|
|
|
|
|
dir = proto.Direction_RIGHT
|
|
|
|
|
}
|
|
|
|
|
return &proto.Kilometer{
|
|
|
|
|
Value: ks.Kilometer,
|
|
|
|
|
CoordinateSystem: ks.CoordinateSystem,
|
|
|
|
|
Direction: dir,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertDevicePort(ref *graphicData.RelatedRef) *proto.DevicePort {
|
|
|
|
|
if ref == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
var deviceType proto.DeviceType
|
|
|
|
|
var port proto.Port
|
|
|
|
|
switch ref.DevicePort {
|
|
|
|
|
case graphicData.RelatedRef_A:
|
|
|
|
|
port = proto.Port_A
|
|
|
|
|
case graphicData.RelatedRef_B:
|
|
|
|
|
port = proto.Port_B
|
|
|
|
|
case graphicData.RelatedRef_C:
|
|
|
|
|
port = proto.Port_C
|
|
|
|
|
}
|
|
|
|
|
switch ref.DeviceType {
|
|
|
|
|
case graphicData.RelatedRef_Section:
|
|
|
|
|
deviceType = proto.DeviceType_DeviceType_PhysicalSection
|
|
|
|
|
case graphicData.RelatedRef_Turnout:
|
|
|
|
|
deviceType = proto.DeviceType_DeviceType_Turnout
|
|
|
|
|
default:
|
|
|
|
|
panic(fmt.Sprintf("异常的设备类型-%s", ref.DeviceType))
|
|
|
|
|
}
|
|
|
|
|
return &proto.DevicePort{
|
|
|
|
|
DeviceId: ref.Id,
|
|
|
|
|
DeviceType: deviceType,
|
|
|
|
|
Port: port,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertDevicePorts(refList []*graphicData.RelatedRef) []*proto.DevicePort {
|
|
|
|
|
var dps []*proto.DevicePort
|
|
|
|
|
for _, ref := range refList {
|
|
|
|
|
dps = append(dps, convertDevicePort(ref))
|
|
|
|
|
}
|
|
|
|
|
return dps
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func findTurnoutIds(axleCountingMap map[string]*graphicData.AxleCounting, axleIds []string) []string {
|
|
|
|
|
if len(axleIds) <= 2 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
turnoutMap := make(map[string]bool)
|
|
|
|
|
for _, axleId := range axleIds {
|
|
|
|
|
axle := axleCountingMap[axleId]
|
|
|
|
|
relTurnoutCount := 0
|
|
|
|
|
var turnoutId string
|
|
|
|
|
for _, ref := range axle.AxleCountingRef {
|
|
|
|
|
if ref.DeviceType == graphicData.RelatedRef_Turnout {
|
|
|
|
|
relTurnoutCount++
|
|
|
|
|
turnoutId = ref.Id
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if relTurnoutCount == 1 {
|
|
|
|
|
turnoutMap[turnoutId] = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var turnoutIds []string
|
2023-09-21 14:54:27 +08:00
|
|
|
|
for id := range turnoutMap {
|
2023-09-20 15:14:40 +08:00
|
|
|
|
turnoutIds = append(turnoutIds, id)
|
|
|
|
|
}
|
|
|
|
|
return turnoutIds
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-20 09:38:23 +08:00
|
|
|
|
func convertToProtoSignalModel(gSmt graphicData.Signal_Model) proto.Signal_Model {
|
|
|
|
|
switch gSmt {
|
|
|
|
|
case graphicData.Signal_HLU:
|
|
|
|
|
return proto.Signal_HLU
|
|
|
|
|
case graphicData.Signal_HL:
|
|
|
|
|
return proto.Signal_HL
|
|
|
|
|
case graphicData.Signal_HLU_FU:
|
|
|
|
|
return proto.Signal_HLU_FU
|
|
|
|
|
case graphicData.Signal_HLU_FL:
|
|
|
|
|
return proto.Signal_HLU_FL
|
|
|
|
|
case graphicData.Signal_AB:
|
|
|
|
|
return proto.Signal_AB
|
|
|
|
|
case graphicData.Signal_HBU:
|
|
|
|
|
return proto.Signal_HBU
|
|
|
|
|
default:
|
|
|
|
|
panic(fmt.Sprintf("graphicData.Signal_Model[%d]无法映射到proto.Signal_Model", gSmt))
|
|
|
|
|
}
|
|
|
|
|
}
|