【坡度、曲度生成逻辑;增加列车BUG修复】

This commit is contained in:
weizhihong 2023-08-11 09:59:27 +08:00
parent fa8631c5e0
commit 9c57620f22
2 changed files with 214 additions and 75 deletions

View File

@ -12,6 +12,8 @@ import (
"joylink.club/bj-rtsts-server/dto"
)
// 参与计算的坡度与曲度均为正线公里标,如果有其他坐标系需要转换
// 参与计算结构体信息
type buildCalcStruct struct {
AxlePointMap map[string]*graphicData.AxleCounting
@ -26,15 +28,19 @@ type buildCalcSectionStruct struct {
stopPositions []*graphicData.StopPosition // 停车位
transponders []*graphicData.Transponder // 应答器
signals []*graphicData.Signal // 信号机
slopes map[string]*graphicData.KilometerSystem // 坡度公里标
curvatures map[string]*graphicData.KilometerSystem // 曲度公里标
}
// 参与计算的
type buildCalcTurnoutStruct struct {
Data *graphicData.Turnout
axlePoints map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting // 关联计轴map
CrossKilometerSystem *graphicData.KilometerSystem // 道岔岔心位置
transponders map[graphicData.RelatedRef_DevicePort][]*graphicData.Transponder // 应答器
signals map[graphicData.RelatedRef_DevicePort]*graphicData.Signal // 对应位置信号机
axlePoints map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting // 关联计轴map
CrossKilometerSystem *graphicData.KilometerSystem // 道岔岔心位置
transponders map[graphicData.RelatedRef_DevicePort][]*graphicData.Transponder // 应答器
signals map[graphicData.RelatedRef_DevicePort]*graphicData.Signal // 对应位置信号机
slopes map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem // 坡度公里标
curvatures map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem // 曲度公里标
}
// 根据地图信息生成calcLink数据
@ -49,6 +55,7 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
Common: &graphicData.CommonInfo{},
Index: int32(id),
Points: []*graphicData.Point{},
Length: 0,
DevicePositions: []*graphicData.CalculateLink_DevicePosition{},
}
allTurnout := true
@ -57,11 +64,13 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
for index, refVal := range pathArr {
if refVal.DeviceType == graphicData.RelatedRef_Section {
allTurnout = false
// 连接点是A端
item.Ab = refVal.DevicePort == graphicData.RelatedRef_A
section := gm.SectionMap[refVal.Id]
// 计算长度
item.Length = item.Length + calcGraphicLenBySection(section)
// 放入设备偏移
offset, prevKm = getGraphicSectionRefDevices(devicePosistionMap, section, offset, prevKm)
offset, prevKm = getGraphicSectionRefDevices(refVal, devicePosistionMap, section, offset, prevKm)
// 区段时A点取小端B点取大端没有的话赋值 refVal
if index == 0 {
item.ARelatedRef = getGraphicSectionPointRef(section, true, refVal)
@ -93,7 +102,7 @@ func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.C
if allTurnout {
tk1 := gm.TurnoutMap[pathArr[0].Id].CrossKilometerSystem.Kilometer
tk2 := gm.TurnoutMap[pathArr[len(pathArr)-1].Id].CrossKilometerSystem.Kilometer
item.Length = int32(tk2 - tk1)
item.Length = int32(math.Abs(float64(tk2 - tk1)))
}
resultArr = append(resultArr, item)
}
@ -129,15 +138,12 @@ func calcGraphicLenByTurnout(turnout *buildCalcTurnoutStruct, p graphicData.Rela
}
start := turnout.CrossKilometerSystem.Kilometer
end := endPoint.KilometerSystem.Kilometer
if end > start {
return int32(end - start)
} else {
return int32(start - end)
}
return int32(math.Abs(float64(end - start)))
}
// 获取关于区段的设备信息
func getGraphicSectionRefDevices(deviceMap map[string]*graphicData.CalculateLink_DevicePosition, section *buildCalcSectionStruct, offset int32, prevKm int64) (int32, int64) {
func getGraphicSectionRefDevices(refVal *graphicData.RelatedRef, deviceMap map[string]*graphicData.CalculateLink_DevicePosition,
section *buildCalcSectionStruct, offset int32, prevKm int64) (int32, int64) {
dealFunc := func(p *graphicData.AxleCounting, d map[string]*graphicData.CalculateLink_DevicePosition, o int32, pk int64) (int32, int64) {
if p != nil && deviceMap[p.Common.Id] == nil {
resultOff := o + int32(math.Abs(float64(p.KilometerSystem.Kilometer-pk)))
@ -152,14 +158,18 @@ func getGraphicSectionRefDevices(deviceMap map[string]*graphicData.CalculateLink
return o, pk
}
// 查看连接点
point := section.axlePoints[graphicData.RelatedRef_A]
point := section.axlePoints[refVal.DevicePort]
offsetCalc, prevKmCalc := offset, prevKm
offsetCalc, prevKmCalc = dealFunc(point, deviceMap, offsetCalc, prevKmCalc)
// 获取另一个连接点
point = section.axlePoints[graphicData.RelatedRef_B]
nextPoint := graphicData.RelatedRef_B
if refVal.DevicePort == nextPoint {
nextPoint = graphicData.RelatedRef_A
}
point = section.axlePoints[nextPoint]
offsetCalc, prevKmCalc = dealFunc(point, deviceMap, offsetCalc, prevKmCalc)
// 处理区段上的设备
startPoint := section.axlePoints[graphicData.RelatedRef_A]
startPoint := section.axlePoints[refVal.DevicePort]
if startPoint != nil {
sppk := startPoint.KilometerSystem.Kilometer // 相对起点的公里标
spof := deviceMap[startPoint.Common.Id].Offset // 相对的起点offset
@ -193,6 +203,26 @@ func getGraphicSectionRefDevices(deviceMap map[string]*graphicData.CalculateLink
}
}
}
// 坡度
for id, s := range section.slopes {
if judgeKilometerIsVaild(s) && deviceMap[id] == nil {
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
DeviceId: id,
Offset: spof + int32(math.Abs(float64(s.Kilometer-sppk))),
DeviceType: "slopes",
}
}
}
// 曲度
for id, c := range section.curvatures {
if judgeKilometerIsVaild(c) && deviceMap[id] == nil {
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
DeviceId: id,
Offset: spof + int32(math.Abs(float64(c.Kilometer-sppk))),
DeviceType: "curvatures",
}
}
}
}
return offsetCalc, prevKmCalc
}
@ -239,13 +269,41 @@ func getGraphicTurnoutRefDevices(refVal *graphicData.RelatedRef, deviceMap map[s
}
}
}
// 坡度
sm := turnout.slopes[refVal.DevicePort]
if sm != nil {
for id, s := range sm {
if judgeKilometerIsVaild(s) && deviceMap[id] == nil {
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
DeviceId: id,
Offset: offset + int32(math.Abs(float64(s.Kilometer-prevKm))),
DeviceType: "slopes",
}
}
}
}
// 曲度
cm := turnout.curvatures[refVal.DevicePort]
if cm != nil {
for id, c := range cm {
if judgeKilometerIsVaild(c) && deviceMap[id] == nil {
deviceMap[id] = &graphicData.CalculateLink_DevicePosition{
DeviceId: id,
Offset: offset + int32(math.Abs(float64(c.Kilometer-prevKm))),
DeviceType: "curvatures",
}
}
}
}
return offsetCalc, prevKmCalc
}
return offset, prevKm
}
// 获取区段的对应端
func getGraphicSectionPointRef(section *buildCalcSectionStruct, b bool, defaultRelateRef *graphicData.RelatedRef) *graphicData.RelatedRef {
func getGraphicSectionPointRef(section *buildCalcSectionStruct, isStart bool, defaultRelateRef *graphicData.RelatedRef) *graphicData.RelatedRef {
if len(section.axlePoints) == 0 {
return defaultRelateRef
}
@ -258,10 +316,14 @@ func getGraphicSectionPointRef(section *buildCalcSectionStruct, b bool, defaultR
} else if apoint == nil && bpoint != nil {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_AxleCounting, Id: bpoint.Common.Id}
}
if b {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_AxleCounting, Id: apoint.Common.Id}
startPoint, endPoint := apoint, bpoint
if defaultRelateRef.DevicePort == graphicData.RelatedRef_B {
startPoint, endPoint = bpoint, apoint
}
if isStart {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_AxleCounting, Id: startPoint.Common.Id}
} else {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_AxleCounting, Id: bpoint.Common.Id}
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_AxleCounting, Id: endPoint.Common.Id}
}
}
@ -297,6 +359,8 @@ func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStru
axlePoints: make(map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting),
transponders: make(map[graphicData.RelatedRef_DevicePort][]*graphicData.Transponder),
signals: make(map[graphicData.RelatedRef_DevicePort]*graphicData.Signal),
slopes: make(map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem),
curvatures: make(map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem),
}
}
// 区段列表
@ -304,6 +368,8 @@ func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStru
gm.SectionMap[s.Common.Id] = &buildCalcSectionStruct{
Data: s,
axlePoints: make(map[graphicData.RelatedRef_DevicePort]*graphicData.AxleCounting),
slopes: make(map[string]*graphicData.KilometerSystem),
curvatures: make(map[string]*graphicData.KilometerSystem),
}
}
// 计轴点关联到对应的区段,道岔上
@ -354,6 +420,48 @@ func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStru
gm.SectionMap[s.RefDev.Id].stopPositions = append(gm.SectionMap[s.RefDev.Id].stopPositions, s)
}
}
// 坡度Map
slopeMap := make(map[graphicData.Direction]map[string]*graphicData.KilometerSystem)
for _, s := range gd.SlopeKiloMarker {
handleSlopeCurvaturesMap(s.Common.Id, s.KilometerSystem, slopeMap)
}
// 曲度Map
curvatureMap := make(map[graphicData.Direction]map[string]*graphicData.KilometerSystem)
for _, c := range gd.CurvatureKiloMarker {
handleSlopeCurvaturesMap(c.Common.Id, c.KilometerSystem, curvatureMap)
}
if len(slopeMap) != 0 || len(curvatureMap) != 0 {
for _, s := range gm.SectionMap {
handleSectionSlopeCurvaturesMap(s, slopeMap, func(sec *buildCalcSectionStruct) map[string]*graphicData.KilometerSystem { return sec.slopes })
handleSectionSlopeCurvaturesMap(s, curvatureMap, func(sec *buildCalcSectionStruct) map[string]*graphicData.KilometerSystem { return sec.curvatures })
}
for _, t := range gm.TurnoutMap {
if !judgeKilometerIsVaild(t.CrossKilometerSystem) {
continue
}
// A点坡度
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_A, t, slopeMap,
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
return sw.slopes
})
// B点坡度
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_B, t, slopeMap,
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
return sw.slopes
})
// A点曲度
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_A, t, curvatureMap,
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
return sw.curvatures
})
// B点曲度
handleTurnoutSlopeCurvaturesMap(graphicData.RelatedRef_B, t, curvatureMap,
func(sw *buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem {
return sw.curvatures
})
}
}
return gm, startPoints
}
@ -387,17 +495,11 @@ func getGraphicLinkPath(gm *buildCalcStruct, startPointQueue *list.List) map[int
continue
}
handleMap[handleId] = true
// 追加函数存在问题,表示数据存在问题
appendFunc := getRelateAppendMethod(gm, refInfo, relatedRef)
if appendFunc == nil {
zap.S().Warnf("link设备【%s】追加方式不确定", relatedRef.Id)
continue
}
pathRefArr := []*graphicData.RelatedRef{refInfo}
// 循环查找结束点
loopRelateRef := relatedRef
for loopRelateRef != nil {
pathRefArr = appendFunc(loopRelateRef, pathRefArr)
pathRefArr = append(pathRefArr, loopRelateRef)
switch loopRelateRef.DeviceType {
case graphicData.RelatedRef_Section:
section := gm.SectionMap[loopRelateRef.Id]
@ -437,49 +539,6 @@ func getRelatePointInfo(v reflect.Value, p graphicData.RelatedRef_DevicePort) *g
return relateInfo.Interface().(*graphicData.RelatedRef)
}
// 确定接点追加方法
func getRelateAppendMethod(gm *buildCalcStruct, sRef, eRef *graphicData.RelatedRef) func(*graphicData.RelatedRef, []*graphicData.RelatedRef) []*graphicData.RelatedRef {
start, sOK := handleFunc(gm, sRef)
if !sOK {
return nil
}
end, eOk := handleFunc(gm, eRef)
if !eOk {
return nil
}
if start > end {
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
return append([]*graphicData.RelatedRef{refInfo}, linkArr...)
}
} else {
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
return append(linkArr, refInfo)
}
}
}
// 处理函数
func handleFunc(gm *buildCalcStruct, ref *graphicData.RelatedRef) (int, bool) {
switch ref.DeviceType {
case graphicData.RelatedRef_Section:
section := gm.SectionMap[ref.Id]
point := section.axlePoints[ref.DevicePort]
if point == nil || !judgeKilometerIsVaild(point.KilometerSystem) {
zap.S().Warnf("区段【%s】【%s】端缺少关联计轴信息", ref.Id, ref.DevicePort.String())
} else {
return int(point.KilometerSystem.Kilometer), true
}
case graphicData.RelatedRef_Turnout:
turnout := gm.TurnoutMap[ref.Id]
if !judgeKilometerIsVaild(turnout.CrossKilometerSystem) {
zap.S().Warnf("道岔【%s】缺少岔心公里标数据", ref.Id)
} else {
return int(turnout.CrossKilometerSystem.Kilometer), true
}
}
return 0, false
}
// 获取起始端的
func getStartKilometer(gm *buildCalcStruct, ref *graphicData.RelatedRef) (int64, int32) {
switch ref.DeviceType {
@ -509,3 +568,73 @@ func getStartKilometer(gm *buildCalcStruct, ref *graphicData.RelatedRef) (int64,
func judgeKilometerIsVaild(k *graphicData.KilometerSystem) bool {
return k != nil && k.CoordinateSystem == "MAIN_LINE" && k.Kilometer != 0
}
// 判断公里标k1 是否在这k2,k3个范围内
func judgeKilometerInRange(k1, k2, k3 *graphicData.KilometerSystem) bool {
if judgeKilometerIsVaild(k1) && judgeKilometerIsVaild(k2) && judgeKilometerIsVaild(k3) {
start, end := k2, k3
if k2.Kilometer > k3.Kilometer {
start, end = k3, k2
}
return k1.Kilometer > start.Kilometer && k1.Kilometer < end.Kilometer
}
return false
}
// 处理道岔坡度、曲度信息
func handleSlopeCurvaturesMap(id string, kms []*graphicData.KilometerSystem, m map[graphicData.Direction]map[string]*graphicData.KilometerSystem) {
for _, k := range kms {
if judgeKilometerIsVaild(k) {
kmMap := m[k.Direction]
if kmMap == nil {
kmMap = make(map[string]*graphicData.KilometerSystem)
m[k.Direction] = kmMap
}
kmMap[id] = k
}
}
}
func handleTurnoutSlopeCurvaturesMap(port graphicData.RelatedRef_DevicePort,
t *buildCalcTurnoutStruct,
scmap map[graphicData.Direction]map[string]*graphicData.KilometerSystem,
f func(*buildCalcTurnoutStruct) map[graphicData.RelatedRef_DevicePort]map[string]*graphicData.KilometerSystem) {
point := t.axlePoints[port]
if point != nil {
m := f(t)
m[port] = make(map[string]*graphicData.KilometerSystem)
kmMap := scmap[point.KilometerSystem.Direction]
idArr := []string{}
for k, v := range kmMap {
if judgeKilometerInRange(v, point.KilometerSystem, t.CrossKilometerSystem) {
m[port][k] = v
idArr = append(idArr, k)
}
}
for _, id := range idArr {
delete(kmMap, id)
}
}
}
func handleSectionSlopeCurvaturesMap(s *buildCalcSectionStruct,
scmap map[graphicData.Direction]map[string]*graphicData.KilometerSystem,
f func(*buildCalcSectionStruct) map[string]*graphicData.KilometerSystem) {
pointA := s.axlePoints[graphicData.RelatedRef_A]
pointB := s.axlePoints[graphicData.RelatedRef_B]
if pointA == nil || pointB == nil {
return
}
m := f(s)
kmMap := scmap[pointA.KilometerSystem.Direction]
idArr := []string{}
for k, v := range kmMap {
if judgeKilometerInRange(v, pointA.KilometerSystem, pointB.KilometerSystem) {
m[k] = v
idArr = append(idArr, k)
}
}
for _, id := range idArr {
delete(kmMap, id)
}
}

View File

@ -110,8 +110,13 @@ func QueryMapVerifyStructure(mapId int32) *VerifyStructure {
// 根据区段道岔偏移量返回linkID和link相对偏移量
func QueryMapCalcLinkByDeviceInfo(mapId int32, id string, devicePort string, offset int64) (int32, int64) {
vm := QueryMapVerifyStructure(mapId)
sm := vm.PhysicalSectionModelMap[id]
tm := vm.SwitchDeviceModelMap[id]
var tm face.SwitchDeviceModeller
var sm face.PhysicalSectionModeller
if devicePort == "" {
sm = vm.PhysicalSectionModelMap[id]
} else {
tm = vm.SwitchDeviceModelMap[id]
}
if sm == nil && tm == nil {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在ID【%s】的设备", id)})
}
@ -219,13 +224,18 @@ func QueryDeviceByCalcLink(vm *VerifyStructure, id int32, offset int64) (string,
devicePosition = v
}
}
sm := vm.PhysicalSectionModelMap[devicePosition.Device.GetIndex()]
var sectionModel *section.PhysicalSectionModel
for _, s := range vm.PhysicalSectionModelMap {
sectionModel = s.(*section.PhysicalSectionModel)
if sectionModel.AxlePoints[devicePosition.Device.GetIndex()] != nil {
break
}
}
tm := vm.SwitchDeviceModelMap[devicePosition.Device.GetIndex()]
if sm == nil && tm == nil {
if sectionModel == nil && tm == nil {
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("不存在ID【%s】的设备", devicePosition.Device.GetIndex())})
}
if sm != nil {
sectionModel := sm.(*section.PhysicalSectionModel)
if sectionModel != nil {
// 判断AB走向
pointA := sectionModel.PortAxlePoints[face.A.Name()]
pointB := sectionModel.PortAxlePoints[face.B.Name()]