2023-08-01 14:54:11 +08:00
|
|
|
|
package memory
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2023-08-11 16:48:21 +08:00
|
|
|
|
"math"
|
2023-08-09 15:34:19 +08:00
|
|
|
|
"sort"
|
2023-09-22 17:51:07 +08:00
|
|
|
|
"strconv"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
"strings"
|
2023-08-01 14:54:11 +08:00
|
|
|
|
"sync"
|
|
|
|
|
|
2023-09-21 14:54:27 +08:00
|
|
|
|
"joylink.club/rtsssimulation/repository"
|
2023-09-21 14:57:57 +08:00
|
|
|
|
proto2 "joylink.club/rtsssimulation/repository/model/proto"
|
2023-09-21 14:54:27 +08:00
|
|
|
|
|
2023-08-01 14:54:11 +08:00
|
|
|
|
"google.golang.org/protobuf/proto"
|
2023-10-17 17:51:26 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/db/dbquery"
|
2023-08-01 14:54:11 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/db/model"
|
2023-08-10 14:18:55 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/dto"
|
2023-10-26 10:05:28 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/sys_error"
|
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-08-01 14:54:11 +08:00
|
|
|
|
)
|
|
|
|
|
|
2023-09-20 15:14:40 +08:00
|
|
|
|
var (
|
2023-09-22 15:15:04 +08:00
|
|
|
|
giTypeMap sync.Map
|
2023-10-16 14:52:58 +08:00
|
|
|
|
giNameMap sync.Map
|
2023-09-22 15:15:04 +08:00
|
|
|
|
giDataMap sync.Map
|
2023-09-20 15:14:40 +08:00
|
|
|
|
)
|
2023-08-01 14:54:11 +08:00
|
|
|
|
|
2023-08-02 15:50:46 +08:00
|
|
|
|
// 将发布的地图数据放入内存中
|
2023-09-21 14:54:27 +08:00
|
|
|
|
func PublishMapVerifyStructure(graphic *model.PublishedGi) {
|
2023-09-25 10:34:31 +08:00
|
|
|
|
giTypeMap.Store(graphic.ID, graphicData.PictureType(graphic.Type))
|
2023-10-16 14:52:58 +08:00
|
|
|
|
giNameMap.Store(graphic.Name, graphic.ID)
|
2023-09-22 10:29:42 +08:00
|
|
|
|
var message proto.Message
|
|
|
|
|
switch graphicData.PictureType(graphic.Type) {
|
|
|
|
|
case graphicData.PictureType_StationLayout:
|
|
|
|
|
message = &graphicData.RtssGraphicStorage{}
|
|
|
|
|
case graphicData.PictureType_RelayCabinetLayout:
|
|
|
|
|
message = &graphicData.RelayCabinetGraphicStorage{}
|
|
|
|
|
case graphicData.PictureType_Psl:
|
|
|
|
|
message = &graphicData.PslGraphicStorage{}
|
2023-10-13 15:19:17 +08:00
|
|
|
|
case graphicData.PictureType_IBP:
|
|
|
|
|
message = &graphicData.IBPGraphicStorage{}
|
2023-09-22 10:29:42 +08:00
|
|
|
|
}
|
|
|
|
|
err := proto.Unmarshal(graphic.Proto, message)
|
2023-09-20 15:14:40 +08:00
|
|
|
|
if err != nil {
|
2023-09-26 14:12:26 +08:00
|
|
|
|
panic(&dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("[id:%d]proto数据反序列化失败:%s", graphic.ID, err)})
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
2023-09-22 10:29:42 +08:00
|
|
|
|
giDataMap.Store(graphic.ID, message)
|
2023-08-02 15:50:46 +08:00
|
|
|
|
// 初始化地图结构
|
2023-09-22 15:15:04 +08:00
|
|
|
|
switch graphicData.PictureType(graphic.Type) {
|
|
|
|
|
case graphicData.PictureType_StationLayout:
|
2023-09-22 10:29:42 +08:00
|
|
|
|
graphicStorage := message.(*graphicData.RtssGraphicStorage)
|
2023-09-22 15:15:04 +08:00
|
|
|
|
giUidMap.Store(graphic.ID, initStationUid(graphicStorage))
|
|
|
|
|
case graphicData.PictureType_RelayCabinetLayout:
|
|
|
|
|
graphicStorage := message.(*graphicData.RelayCabinetGraphicStorage)
|
|
|
|
|
giUidMap.Store(graphic.ID, initRelayCabinetUid(graphicStorage))
|
2023-09-21 14:54:27 +08:00
|
|
|
|
}
|
2023-08-01 14:54:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 15:13:25 +08:00
|
|
|
|
func GenerateElementUid(city, lineId string, stationIndexList []string, code string) string {
|
|
|
|
|
sort.Strings(stationIndexList)
|
|
|
|
|
var idArr []string
|
|
|
|
|
idArr = append(idArr, city, lineId)
|
|
|
|
|
idArr = append(idArr, stationIndexList...)
|
2023-09-21 14:54:27 +08:00
|
|
|
|
idArr = append(idArr, code)
|
|
|
|
|
return strings.Join(idArr, "_")
|
2023-08-01 14:54:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移除内存中的地图信息
|
|
|
|
|
func DeleteMapVerifyStructure(mapId int32) {
|
2023-09-26 14:12:26 +08:00
|
|
|
|
giTypeMap.Delete(mapId)
|
|
|
|
|
giDataMap.Delete(mapId)
|
|
|
|
|
giUidMap.Delete(mapId)
|
2023-08-01 14:54:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 15:13:25 +08:00
|
|
|
|
func QueryGiType(mapId int32) graphicData.PictureType {
|
2023-09-26 14:12:26 +08:00
|
|
|
|
value, ok := giTypeMap.Load(mapId)
|
|
|
|
|
if !ok {
|
2023-10-17 17:51:26 +08:00
|
|
|
|
graphic, err := dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.ID.Eq(mapId)).First() // 当缓存缺失新地图时,查询一次
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(&dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("[mapId:%d]类型映射错误 :%v", mapId, value)})
|
|
|
|
|
}
|
|
|
|
|
PublishMapVerifyStructure(graphic)
|
|
|
|
|
return graphicData.PictureType(graphic.Type)
|
2023-09-26 14:12:26 +08:00
|
|
|
|
}
|
2023-09-22 15:13:25 +08:00
|
|
|
|
return value.(graphicData.PictureType)
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func QueryOnlyGiType(mapId int32) graphicData.PictureType {
|
|
|
|
|
value, ok := giTypeMap.Load(mapId)
|
|
|
|
|
if !ok {
|
|
|
|
|
panic(sys_error.New(fmt.Sprintf("[mapId:%d]不存在", mapId)))
|
|
|
|
|
}
|
|
|
|
|
return value.(graphicData.PictureType)
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 15:13:25 +08:00
|
|
|
|
func QueryGiData[T proto.Message](mapId int32) T {
|
|
|
|
|
value, _ := giDataMap.Load(mapId)
|
|
|
|
|
return value.(T)
|
2023-09-20 15:14:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-19 17:09:57 +08:00
|
|
|
|
func QueryGiId(name string) int32 {
|
|
|
|
|
value, _ := giNameMap.Load(name)
|
|
|
|
|
return value.(int32)
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 14:18:55 +08:00
|
|
|
|
// 根据区段,道岔偏移量返回linkID和link相对偏移量
|
2023-10-26 10:05:28 +08:00
|
|
|
|
func QueryEcsLinkByDeviceInfo(repo *repository.Repository, mapId int32, status *state.TrainState) (int32, int64, bool, bool, int64) {
|
|
|
|
|
id := status.HeadDeviceId
|
|
|
|
|
if status.DevicePort == "" {
|
2023-09-27 18:11:16 +08:00
|
|
|
|
uid := QueryUidByMidAndComId(mapId, id, &graphicData.Section{})
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return sectionMapToEcsLink(repo, uid, status)
|
2023-08-11 09:59:27 +08:00
|
|
|
|
} else {
|
2023-09-27 18:11:16 +08:00
|
|
|
|
uid := QueryUidByMidAndComId(mapId, id, &graphicData.Turnout{})
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return turnoutMapToEcsLink(repo, uid, status)
|
2023-08-11 09:59:27 +08:00
|
|
|
|
}
|
2023-08-11 16:48:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 14:57:37 +08:00
|
|
|
|
func GetStorageIBPMapData(mapCode string) *graphicData.IBPGraphicStorage {
|
2023-10-16 14:52:58 +08:00
|
|
|
|
// 处理关联的IBP盘信息
|
|
|
|
|
if mapCode == "" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
ibpId, ok := giNameMap.Load(mapCode)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
ibpMapData, ok := giDataMap.Load(ibpId)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return ibpMapData.(*graphicData.IBPGraphicStorage)
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-11 16:48:21 +08:00
|
|
|
|
// 根据物理区段上的偏移量(基于区段A端),找到所在link的linkId与偏移量
|
2023-10-26 10:05:28 +08:00
|
|
|
|
func sectionMapToEcsLink(repo *repository.Repository, id string, status *state.TrainState) (int32, int64, bool, bool, int64) {
|
|
|
|
|
runDirection := status.RunDirection
|
2023-09-28 09:29:04 +08:00
|
|
|
|
section := repo.FindPhysicalSection(id)
|
2023-09-22 17:51:07 +08:00
|
|
|
|
if section == nil {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("地图不存在uid:%s缓存", id)))
|
2023-08-11 16:48:21 +08:00
|
|
|
|
}
|
2023-09-22 17:51:07 +08:00
|
|
|
|
ao, bo := section.ALinkPosition().Offset(), section.BLinkPosition().Offset()
|
2023-10-26 15:48:17 +08:00
|
|
|
|
// 检查区段长度是否足够放下列车
|
2023-10-26 16:03:30 +08:00
|
|
|
|
status.HeadOffset = checkDeviceContainTrain(status.HeadOffset, status.TrainLength, bo-ao, id)
|
2023-10-26 15:48:17 +08:00
|
|
|
|
link := section.ALinkPosition().Link()
|
2023-10-19 17:42:01 +08:00
|
|
|
|
// 是否从A到B,统一坐标
|
|
|
|
|
ak, bk := convertRepoBaseKm(repo, section.AKilometer()), convertRepoBaseKm(repo, section.BKilometer())
|
|
|
|
|
akv, bkv := ak.Value, bk.Value
|
2023-09-27 18:02:07 +08:00
|
|
|
|
// 上行
|
|
|
|
|
var up, abDirection bool
|
|
|
|
|
if runDirection {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
abDirection = akv < bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
if abDirection {
|
|
|
|
|
up = ao < bo
|
|
|
|
|
} else {
|
|
|
|
|
up = ao > bo
|
|
|
|
|
}
|
2023-09-27 18:02:07 +08:00
|
|
|
|
} else {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
abDirection = akv > bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
if abDirection {
|
|
|
|
|
up = ao < bo
|
|
|
|
|
} else {
|
|
|
|
|
up = ao > bo
|
|
|
|
|
}
|
2023-09-22 17:51:07 +08:00
|
|
|
|
}
|
2023-10-26 10:05:28 +08:00
|
|
|
|
linkId, _ := strconv.Atoi(link.Identity.Id())
|
|
|
|
|
trainKilometer := concertTrainKilometer(akv, status.HeadOffset, up)
|
2023-10-09 15:03:01 +08:00
|
|
|
|
if ao < bo {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return int32(linkId), ao + status.HeadOffset, up, abDirection, trainKilometer
|
2023-08-10 14:18:55 +08:00
|
|
|
|
} else {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return int32(linkId), ao - status.HeadOffset, up, abDirection, trainKilometer
|
2023-08-11 16:48:21 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据道岔上的偏移量(基于岔心位置),找到所在link的linkId与偏移量
|
2023-10-26 10:05:28 +08:00
|
|
|
|
func turnoutMapToEcsLink(repo *repository.Repository, id string, status *state.TrainState) (int32, int64, bool, bool, int64) {
|
|
|
|
|
port, runDirection := status.DevicePort, status.RunDirection
|
2023-09-28 09:29:04 +08:00
|
|
|
|
turnout := repo.FindTurnout(id)
|
2023-09-22 17:51:07 +08:00
|
|
|
|
if turnout == nil {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("不存在道岔【uid:%s】", id)))
|
2023-09-22 17:51:07 +08:00
|
|
|
|
}
|
|
|
|
|
var portPosition *repository.LinkPosition
|
|
|
|
|
var crossKm, portKm *proto2.Kilometer
|
|
|
|
|
switch port {
|
|
|
|
|
case "A":
|
|
|
|
|
portPosition = turnout.FindLinkPositionByPort(proto2.Port_A)
|
|
|
|
|
portKm = turnout.GetTurnoutKm(proto2.Port_A)
|
|
|
|
|
case "B":
|
|
|
|
|
portPosition = turnout.FindLinkPositionByPort(proto2.Port_B)
|
|
|
|
|
portKm = turnout.GetTurnoutKm(proto2.Port_B)
|
|
|
|
|
case "C":
|
|
|
|
|
portPosition = turnout.FindLinkPositionByPort(proto2.Port_C)
|
|
|
|
|
portKm = turnout.GetTurnoutKm(proto2.Port_C)
|
|
|
|
|
default:
|
2023-10-26 10:05:28 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("无效端口【%s】偏移量", port)))
|
2023-09-22 17:51:07 +08:00
|
|
|
|
}
|
|
|
|
|
// 岔心公里标
|
|
|
|
|
crossKm = turnout.GetTurnoutKm(proto2.Port_None)
|
2023-10-20 15:08:47 +08:00
|
|
|
|
portKm, err := repo.ConvertKilometer(portKm, crossKm.CoordinateSystem)
|
|
|
|
|
if err != nil {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
panic(sys_error.New("公里标转换出错", err))
|
2023-10-20 15:08:47 +08:00
|
|
|
|
}
|
2023-10-26 15:48:17 +08:00
|
|
|
|
// 检查link偏移
|
2023-10-26 16:03:30 +08:00
|
|
|
|
status.HeadOffset = checkDeviceContainTrain(status.HeadOffset, status.TrainLength, crossKm.Value-portKm.Value, id)
|
2023-10-26 15:48:17 +08:00
|
|
|
|
// 关联link
|
|
|
|
|
link := portPosition.Link()
|
2023-09-22 17:51:07 +08:00
|
|
|
|
isStart := link.ARelation().Device().Id() == id
|
|
|
|
|
up := runDirection
|
|
|
|
|
if (portKm.Value > crossKm.Value) != isStart {
|
|
|
|
|
up = !runDirection
|
|
|
|
|
}
|
|
|
|
|
pointTo := (portKm.Value > crossKm.Value) == runDirection
|
2023-10-26 10:05:28 +08:00
|
|
|
|
trainKilometer := concertTrainKilometer(crossKm.Value, status.HeadOffset, pointTo)
|
2023-09-22 17:51:07 +08:00
|
|
|
|
linkId, _ := strconv.Atoi(link.Identity.Id())
|
|
|
|
|
if isStart {
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return int32(linkId), status.HeadOffset, up, pointTo, trainKilometer
|
2023-09-22 17:51:07 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 道岔长度
|
|
|
|
|
turnoutLen := int64(math.Abs(float64(portKm.Value - crossKm.Value)))
|
2023-10-26 10:05:28 +08:00
|
|
|
|
return int32(linkId), portPosition.Offset() + turnoutLen - status.HeadOffset, up, pointTo, trainKilometer
|
2023-08-10 14:18:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据linkID和link相对偏移量返回区段,道岔偏移量
|
2023-08-15 10:18:39 +08:00
|
|
|
|
// 设备ID、端口、偏移量、上下行、AB走向
|
2023-09-20 18:21:00 +08:00
|
|
|
|
func QueryDeviceByCalcLink(repo *repository.Repository, id string, offset int64, up bool) (
|
|
|
|
|
deviceId, port string, deviceOffset int64, runDirection, pointTo bool, km int64) {
|
|
|
|
|
link := repo.FindLink(id)
|
|
|
|
|
if link == nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到link【%s】", id)})
|
|
|
|
|
}
|
|
|
|
|
if offset > link.Length() {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("偏移【%d】超出link范围【%d】", offset, link.Length())})
|
|
|
|
|
}
|
2023-09-27 16:49:10 +08:00
|
|
|
|
// 判断是否在道岔上
|
|
|
|
|
onTurnout, isA := isOnLinkTurnout(link, offset)
|
|
|
|
|
if onTurnout {
|
2023-09-28 15:43:20 +08:00
|
|
|
|
return ecsLinkMapToTurnout(repo, isA, offset, up, link)
|
2023-09-27 16:49:10 +08:00
|
|
|
|
} else {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
return ecsLinkMapToSection(repo, offset, up, link)
|
2023-09-27 16:49:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 是否在link的道岔上
|
|
|
|
|
func isOnLinkTurnout(link *repository.Link, offset int64) (bool, bool) {
|
2023-09-20 18:21:00 +08:00
|
|
|
|
aTp := link.ARelation()
|
2023-09-27 16:49:10 +08:00
|
|
|
|
var turnoutOffset int64
|
|
|
|
|
if aTp != nil {
|
|
|
|
|
turnoutOffset = aTp.Turnout().FindLinkPositionByPort(aTp.Port()).Offset()
|
|
|
|
|
}
|
|
|
|
|
if offset <= turnoutOffset {
|
|
|
|
|
return true, true
|
|
|
|
|
}
|
2023-09-20 18:21:00 +08:00
|
|
|
|
bTp := link.BRelation()
|
2023-09-27 16:49:10 +08:00
|
|
|
|
if bTp != nil {
|
|
|
|
|
turnoutOffset = bTp.Turnout().FindLinkPositionByPort(bTp.Port()).Offset()
|
|
|
|
|
return offset >= turnoutOffset, false
|
|
|
|
|
}
|
|
|
|
|
return false, false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理在道岔上link映射
|
2023-09-28 15:43:20 +08:00
|
|
|
|
func ecsLinkMapToTurnout(repo *repository.Repository, isA bool, offset int64, up bool, link *repository.Link) (
|
2023-09-27 16:49:10 +08:00
|
|
|
|
deviceId, port string, deviceOffset int64, runDirection, pointTo bool, km int64) {
|
|
|
|
|
tp := link.ARelation()
|
|
|
|
|
if !isA {
|
|
|
|
|
tp = link.BRelation()
|
|
|
|
|
}
|
|
|
|
|
deviceId = tp.Turnout().Id()
|
|
|
|
|
tpOffset := tp.Turnout().FindLinkPositionByPort(tp.Port()).Offset()
|
2023-09-28 15:43:20 +08:00
|
|
|
|
crossKmInfo, portKmInfo := tp.Turnout().GetTurnoutKm(proto2.Port_None), tp.Turnout().GetTurnoutKm(tp.Port())
|
2023-10-20 15:08:47 +08:00
|
|
|
|
portKmInfo, err := repo.ConvertKilometer(portKmInfo, crossKmInfo.CoordinateSystem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2023-09-28 15:43:20 +08:00
|
|
|
|
crossKm, portKm := crossKmInfo.Value, portKmInfo.Value
|
2023-09-27 16:49:10 +08:00
|
|
|
|
if isA {
|
|
|
|
|
deviceOffset = tpOffset - (tpOffset - offset)
|
|
|
|
|
pointTo = !up
|
|
|
|
|
} else {
|
2023-09-20 18:21:00 +08:00
|
|
|
|
deviceOffset = link.Length() - offset
|
2023-09-27 16:49:10 +08:00
|
|
|
|
pointTo = up
|
|
|
|
|
}
|
|
|
|
|
// 查询公里标大于端口公里标
|
|
|
|
|
if crossKm > portKm {
|
|
|
|
|
km = crossKm - deviceOffset
|
|
|
|
|
} else {
|
|
|
|
|
km = crossKm + deviceOffset
|
2023-09-28 15:43:20 +08:00
|
|
|
|
}
|
2023-09-28 17:28:20 +08:00
|
|
|
|
if up && isA { // link offset 趋大,A端岔心 ---> 边界
|
|
|
|
|
runDirection = crossKm < portKm
|
|
|
|
|
} else if up && !isA { // link offset 趋大,B端边界 ---> 岔心
|
|
|
|
|
runDirection = crossKm > portKm
|
|
|
|
|
} else if !up && isA { // link offset 趋小,A端边界 ---> 岔心
|
|
|
|
|
runDirection = crossKm > portKm
|
|
|
|
|
} else { // link offset 趋小,B端岔心 ---> 边界
|
|
|
|
|
runDirection = crossKm < portKm
|
2023-09-27 16:49:10 +08:00
|
|
|
|
}
|
|
|
|
|
switch tp.Port() {
|
|
|
|
|
case proto2.Port_A:
|
|
|
|
|
port = "A"
|
|
|
|
|
case proto2.Port_B:
|
|
|
|
|
port = "B"
|
|
|
|
|
case proto2.Port_C:
|
|
|
|
|
port = "C"
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理在道岔上link映射
|
2023-10-19 17:42:01 +08:00
|
|
|
|
func ecsLinkMapToSection(repo *repository.Repository, offset int64, up bool, link *repository.Link) (
|
2023-09-27 16:49:10 +08:00
|
|
|
|
deviceId, port string, deviceOffset int64, runDirection, pointTo bool, km int64) {
|
|
|
|
|
var section *repository.PhysicalSection
|
|
|
|
|
for _, s := range link.PhysicalSections() {
|
|
|
|
|
ao, bo := s.ALinkPosition().Offset(), s.BLinkPosition().Offset()
|
2023-10-19 18:04:21 +08:00
|
|
|
|
if (ao < offset && offset <= bo) || (bo < offset && offset <= ao) {
|
2023-09-27 16:49:10 +08:00
|
|
|
|
section = s
|
|
|
|
|
break
|
2023-09-20 18:21:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-27 16:49:10 +08:00
|
|
|
|
if section == nil {
|
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("未找到link设备偏移【%d】", offset)})
|
|
|
|
|
}
|
|
|
|
|
// 元素ID
|
|
|
|
|
deviceId = section.Id()
|
|
|
|
|
// link偏移变大方向
|
|
|
|
|
ao, bo := section.ALinkPosition().Offset(), section.BLinkPosition().Offset()
|
2023-10-19 17:42:01 +08:00
|
|
|
|
ak, bk := convertRepoBaseKm(repo, section.AKilometer()), convertRepoBaseKm(repo, section.BKilometer())
|
|
|
|
|
akv, bkv := ak.Value, bk.Value
|
2023-09-27 16:49:10 +08:00
|
|
|
|
if up {
|
2023-10-07 15:59:22 +08:00
|
|
|
|
if ao < bo {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
runDirection = akv < bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
} else {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
runDirection = akv > bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
}
|
2023-09-27 16:49:10 +08:00
|
|
|
|
} else {
|
2023-10-07 15:59:22 +08:00
|
|
|
|
if ao > bo {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
runDirection = akv < bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
} else {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
runDirection = akv > bkv
|
2023-10-07 15:59:22 +08:00
|
|
|
|
}
|
2023-09-27 16:49:10 +08:00
|
|
|
|
}
|
2023-10-19 17:42:01 +08:00
|
|
|
|
pointTo = runDirection == (akv < bkv)
|
2023-09-27 16:49:10 +08:00
|
|
|
|
// a点偏移 大于 b点偏移
|
|
|
|
|
if ao > bo {
|
|
|
|
|
deviceOffset = ao - offset
|
|
|
|
|
} else {
|
|
|
|
|
deviceOffset = offset - ao
|
|
|
|
|
}
|
|
|
|
|
// a点公里标 大于 b点公里标
|
2023-10-19 17:42:01 +08:00
|
|
|
|
if akv > bkv {
|
|
|
|
|
km = akv - deviceOffset
|
2023-09-27 16:49:10 +08:00
|
|
|
|
} else {
|
2023-10-19 17:42:01 +08:00
|
|
|
|
km = akv + deviceOffset
|
2023-09-27 16:49:10 +08:00
|
|
|
|
}
|
2023-09-20 18:21:00 +08:00
|
|
|
|
return
|
2023-08-11 16:48:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-12 16:33:31 +08:00
|
|
|
|
// 查找列车的公里标
|
|
|
|
|
func concertTrainKilometer(kilometer, offset int64, tendTo bool) int64 {
|
|
|
|
|
if tendTo {
|
|
|
|
|
return kilometer - offset
|
|
|
|
|
} else {
|
|
|
|
|
return kilometer + offset
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-19 17:42:01 +08:00
|
|
|
|
|
|
|
|
|
// 转换成统一坐标公里标
|
|
|
|
|
func convertRepoBaseKm(r *repository.Repository, km *proto2.Kilometer) *proto2.Kilometer {
|
2023-10-20 15:13:29 +08:00
|
|
|
|
k, err := r.ConvertKilometer(km, r.GetCoordinateInfo().Coordinate)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
return k
|
2023-10-19 17:42:01 +08:00
|
|
|
|
}
|
2023-10-26 10:05:28 +08:00
|
|
|
|
|
2023-10-26 15:48:17 +08:00
|
|
|
|
// 检查列车是否可以放到设备上
|
2023-10-26 16:03:30 +08:00
|
|
|
|
func checkDeviceContainTrain(offset, trainLen, deviceLen int64, deviceName string) int64 {
|
2023-10-26 15:48:17 +08:00
|
|
|
|
l := int64(math.Abs(float64(deviceLen)))
|
|
|
|
|
if offset > l {
|
2023-10-26 16:03:30 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("偏移【%d】超出【%s】范围【%d】", offset, deviceName, l)))
|
2023-10-26 10:05:28 +08:00
|
|
|
|
}
|
|
|
|
|
if trainLen > offset { // 如果列车长度超过设置offset
|
|
|
|
|
offset = trainLen
|
|
|
|
|
}
|
2023-10-26 15:48:17 +08:00
|
|
|
|
if offset > l {
|
2023-10-26 16:03:30 +08:00
|
|
|
|
panic(sys_error.New(fmt.Sprintf("列车长度【%d】超出【%s】范围【%d】", trainLen, deviceName, l)))
|
2023-10-26 10:05:28 +08:00
|
|
|
|
}
|
|
|
|
|
return offset
|
|
|
|
|
}
|