添加公里标及公里标转换相关model及逻辑
This commit is contained in:
parent
8e20a049a4
commit
5a18ea69fe
79
model/kilometer_mark.go
Normal file
79
model/kilometer_mark.go
Normal file
@ -0,0 +1,79 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 运营方向(上行/下行)
|
||||
type OperationDirection int8
|
||||
|
||||
const (
|
||||
// 上行
|
||||
OperationDirectionUp OperationDirection = 1
|
||||
// 下行
|
||||
OperationDirectionDown OperationDirection = 0
|
||||
)
|
||||
|
||||
type KilometerMark struct {
|
||||
// 公里标坐标系
|
||||
coordinate string
|
||||
// 公里标上下行方向
|
||||
direction OperationDirection
|
||||
// 公里标值
|
||||
value int64
|
||||
}
|
||||
|
||||
func NewKilometerMark(coordinate string, direction OperationDirection, value int64) *KilometerMark {
|
||||
return &KilometerMark{
|
||||
coordinate: coordinate,
|
||||
direction: direction,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (km *KilometerMark) Coordinate() string {
|
||||
return km.coordinate
|
||||
}
|
||||
|
||||
// 是否为同一坐标系
|
||||
func (km *KilometerMark) IsCoordinateEqual(coordinate string) bool {
|
||||
return km.coordinate == coordinate
|
||||
}
|
||||
|
||||
// 公里标转换配置
|
||||
type KilometerMarkConverter struct {
|
||||
km1 KilometerMark
|
||||
km2 KilometerMark
|
||||
// 趋势是否相同
|
||||
trendSame bool
|
||||
}
|
||||
|
||||
func (kmc *KilometerMarkConverter) Debug() string {
|
||||
return fmt.Sprintf("{%s<->%s(%s)}", kmc.km1.coordinate, kmc.km2.coordinate, strconv.FormatBool(kmc.trendSame))
|
||||
}
|
||||
|
||||
func (kmc *KilometerMarkConverter) IsMatch(km *KilometerMark, coordinate2 string) bool {
|
||||
coordinate1 := km.coordinate
|
||||
return kmc.km1.coordinate == coordinate1 && kmc.km2.coordinate == coordinate2 ||
|
||||
kmc.km1.coordinate == coordinate2 && kmc.km2.coordinate == coordinate1
|
||||
}
|
||||
|
||||
// 将源公里标km转换为目标坐标系targetCoordinate的公里标值
|
||||
func (kmc *KilometerMarkConverter) Convert(km *KilometerMark, targetCoordinate string) int64 {
|
||||
var tvalue int64 = 0
|
||||
if kmc.km1.IsCoordinateEqual(km.coordinate) {
|
||||
if kmc.trendSame {
|
||||
tvalue = km.value - kmc.km1.value + kmc.km2.value
|
||||
} else {
|
||||
tvalue = kmc.km1.value - km.value + kmc.km2.value
|
||||
}
|
||||
} else {
|
||||
if kmc.trendSame {
|
||||
tvalue = km.value - kmc.km2.value + kmc.km1.value
|
||||
} else {
|
||||
tvalue = kmc.km2.value - km.value + kmc.km1.value
|
||||
}
|
||||
}
|
||||
return tvalue
|
||||
}
|
48
model/kilometer_mark_test.go
Normal file
48
model/kilometer_mark_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertKilometerMark(t *testing.T) {
|
||||
// 1. 配置公里标转换关系
|
||||
km1 := NewKilometerMark("DBCSK", OperationDirectionUp, 0)
|
||||
km2 := NewKilometerMark("DCSK", OperationDirectionUp, 200)
|
||||
kmc1 := &KilometerMarkConverter{
|
||||
km1: *km1,
|
||||
km2: *km2,
|
||||
trendSame: true,
|
||||
}
|
||||
t.Log(kmc1.Debug())
|
||||
kmc2 := &KilometerMarkConverter{
|
||||
km1: *km1,
|
||||
km2: *km2,
|
||||
trendSame: false,
|
||||
}
|
||||
t.Log(kmc2.Debug())
|
||||
|
||||
// 2. 验证公里标转换关系
|
||||
tests := []struct {
|
||||
km *KilometerMark
|
||||
coordinate string
|
||||
expect1 int64
|
||||
expect2 int64
|
||||
}{
|
||||
{km: NewKilometerMark("DBCSK", OperationDirectionUp, 0), coordinate: km2.Coordinate(), expect1: 200, expect2: 200},
|
||||
{km: NewKilometerMark("DBCSK", OperationDirectionUp, 100), coordinate: km2.Coordinate(), expect1: 300, expect2: 100},
|
||||
{km: NewKilometerMark("DBCSK", OperationDirectionUp, -100), coordinate: km2.Coordinate(), expect1: 100, expect2: 300},
|
||||
{km: NewKilometerMark("DCSK", OperationDirectionUp, 200), coordinate: km1.Coordinate(), expect1: 0, expect2: 0},
|
||||
{km: NewKilometerMark("DCSK", OperationDirectionUp, 300), coordinate: km1.Coordinate(), expect1: 100, expect2: -100},
|
||||
{km: NewKilometerMark("DCSK", OperationDirectionUp, 100), coordinate: km1.Coordinate(), expect1: -100, expect2: 100},
|
||||
}
|
||||
for _, test := range tests {
|
||||
result1 := kmc1.Convert(test.km, test.coordinate)
|
||||
if result1 != test.expect1 {
|
||||
t.Errorf("expect1: %d, but got: %d", test.expect1, result1)
|
||||
}
|
||||
result2 := kmc2.Convert(test.km, test.coordinate)
|
||||
if result2 != test.expect2 {
|
||||
t.Errorf("expect2: %d, but got: %d", test.expect2, result2)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,10 +3,15 @@ package model
|
||||
// 区段
|
||||
type Section interface {
|
||||
TwoPortsPipeElement
|
||||
// 获取A端和B端的公里标
|
||||
GetPaKm() KilometerMark
|
||||
GetPbKm() KilometerMark
|
||||
}
|
||||
|
||||
type SectionImpl struct {
|
||||
*TwoPortsPipeElementImpl
|
||||
PaKm KilometerMark
|
||||
PbKm KilometerMark
|
||||
}
|
||||
|
||||
var _ Section = (*SectionImpl)(nil)
|
||||
@ -18,3 +23,11 @@ func NewSection(uid string) *SectionImpl {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SectionImpl) GetPaKm() KilometerMark {
|
||||
return s.PaKm
|
||||
}
|
||||
|
||||
func (s *SectionImpl) GetPbKm() KilometerMark {
|
||||
return s.PbKm
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package model
|
||||
|
||||
type SectionCheckPoint interface {
|
||||
RtssModel
|
||||
}
|
@ -7,12 +7,24 @@ import (
|
||||
// 道岔
|
||||
type Turnout interface {
|
||||
ThreePortsPipeElement
|
||||
// 获取道岔岔心公里标
|
||||
GetKm() KilometerMark
|
||||
// 获取道岔A端公里标
|
||||
GetPaKm() KilometerMark
|
||||
// 获取道岔B端公里标
|
||||
GetPbKm() KilometerMark
|
||||
// 获取道岔C端公里标
|
||||
GetPcKm() KilometerMark
|
||||
}
|
||||
|
||||
var _ Turnout = (*TurnoutImpl)(nil)
|
||||
|
||||
type TurnoutImpl struct {
|
||||
*ThreePortsPipeElementImpl
|
||||
Km KilometerMark
|
||||
PaKm KilometerMark
|
||||
PbKm KilometerMark
|
||||
PcKm KilometerMark
|
||||
}
|
||||
|
||||
func NewTurnout(uid string) *TurnoutImpl {
|
||||
@ -25,3 +37,19 @@ func NewTurnout(uid string) *TurnoutImpl {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) GetKm() KilometerMark {
|
||||
return t.Km
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) GetPaKm() KilometerMark {
|
||||
return t.PaKm
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) GetPbKm() KilometerMark {
|
||||
return t.PbKm
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) GetPcKm() KilometerMark {
|
||||
return t.PcKm
|
||||
}
|
||||
|
47
repo/repo.go
47
repo/repo.go
@ -2,7 +2,9 @@ package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"joylink.club/rtss-core/model"
|
||||
)
|
||||
@ -15,31 +17,48 @@ type Repo interface {
|
||||
GetTurnoutByUid(uid string) model.Turnout
|
||||
// 检查通道连接关系
|
||||
CheckPipeLink() error
|
||||
// 转换公里标
|
||||
ConvertKilometerMark(km *model.KilometerMark, targetCoordinate string) (int64, error)
|
||||
}
|
||||
|
||||
var _ Repo = (*RepoImpl)(nil)
|
||||
|
||||
type RepoImpl struct {
|
||||
id string
|
||||
BuildErrorInfos []error
|
||||
StationMap map[string]model.Station
|
||||
SectionMap map[string]model.Section
|
||||
TurnoutMap map[string]model.Turnout
|
||||
LinkNodeMap map[string]model.LinkNode
|
||||
LinkMap map[string]model.Link
|
||||
id string
|
||||
BuildErrorInfos []error
|
||||
StationMap map[string]model.Station
|
||||
SectionMap map[string]model.Section
|
||||
TurnoutMap map[string]model.Turnout
|
||||
LinkNodeMap map[string]model.LinkNode
|
||||
LinkMap map[string]model.Link
|
||||
KilometerMarkConverters []model.KilometerMarkConverter
|
||||
}
|
||||
|
||||
func NewRepo(id string) *RepoImpl {
|
||||
return &RepoImpl{
|
||||
id: id,
|
||||
StationMap: make(map[string]model.Station),
|
||||
SectionMap: make(map[string]model.Section),
|
||||
TurnoutMap: make(map[string]model.Turnout),
|
||||
LinkNodeMap: make(map[string]model.LinkNode),
|
||||
LinkMap: make(map[string]model.Link),
|
||||
id: id,
|
||||
StationMap: make(map[string]model.Station),
|
||||
SectionMap: make(map[string]model.Section),
|
||||
TurnoutMap: make(map[string]model.Turnout),
|
||||
LinkNodeMap: make(map[string]model.LinkNode),
|
||||
LinkMap: make(map[string]model.Link),
|
||||
KilometerMarkConverters: make([]model.KilometerMarkConverter, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RepoImpl) ConvertKilometerMark(km *model.KilometerMark, targetCoordinate string) (int64, error) {
|
||||
for _, converter := range r.KilometerMarkConverters {
|
||||
if converter.IsMatch(km, targetCoordinate) {
|
||||
return converter.Convert(km, targetCoordinate), nil
|
||||
}
|
||||
}
|
||||
existConfigs := make([]string, 0)
|
||||
for _, converter := range r.KilometerMarkConverters {
|
||||
existConfigs = append(existConfigs, converter.Debug())
|
||||
}
|
||||
return 0, fmt.Errorf("未找到公里标转换配置: %s<->%s, 全部配置项为: %s", km.Coordinate(), targetCoordinate, strings.Join(existConfigs, ","))
|
||||
}
|
||||
|
||||
// CheckPipeLink implements Repo.
|
||||
func (r *RepoImpl) CheckPipeLink() error {
|
||||
for _, section := range r.SectionMap {
|
||||
@ -128,7 +147,7 @@ func walkFromTurnoutPortToNextAndBuildLink(turnout model.Turnout, port model.Pip
|
||||
return nil
|
||||
}
|
||||
if ple.Pipe.IsThreePorts() {
|
||||
nextTurnout := ple.Pipe
|
||||
nextTurnout := ple.Pipe.(model.Turnout)
|
||||
nextPort := ple.Port
|
||||
link, exist := NewLinkNodeAndLinkAndBuildLinkship(turnout, port, nextTurnout, nextPort, repo1)
|
||||
if exist {
|
||||
|
Loading…
Reference in New Issue
Block a user