From 5a18ea69feb2a2278a1e8ac1e6194624cc396a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?walker-sheng=E2=80=9D?= Date: Thu, 4 Jul 2024 20:16:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=AC=E9=87=8C=E6=A0=87?= =?UTF-8?q?=E5=8F=8A=E5=85=AC=E9=87=8C=E6=A0=87=E8=BD=AC=E6=8D=A2=E7=9B=B8?= =?UTF-8?q?=E5=85=B3model=E5=8F=8A=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/kilometer_mark.go | 79 ++++++++++++++++++++++++++++++++++++ model/kilometer_mark_test.go | 48 ++++++++++++++++++++++ model/section.go | 13 ++++++ model/section_check_point.go | 5 --- model/turnout.go | 28 +++++++++++++ repo/repo.go | 47 ++++++++++++++------- 6 files changed, 201 insertions(+), 19 deletions(-) create mode 100644 model/kilometer_mark.go create mode 100644 model/kilometer_mark_test.go delete mode 100644 model/section_check_point.go diff --git a/model/kilometer_mark.go b/model/kilometer_mark.go new file mode 100644 index 0000000..0bc8b69 --- /dev/null +++ b/model/kilometer_mark.go @@ -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 +} diff --git a/model/kilometer_mark_test.go b/model/kilometer_mark_test.go new file mode 100644 index 0000000..423a67f --- /dev/null +++ b/model/kilometer_mark_test.go @@ -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) + } + } +} diff --git a/model/section.go b/model/section.go index 5f1099e..b37995f 100644 --- a/model/section.go +++ b/model/section.go @@ -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 +} diff --git a/model/section_check_point.go b/model/section_check_point.go deleted file mode 100644 index b5674ad..0000000 --- a/model/section_check_point.go +++ /dev/null @@ -1,5 +0,0 @@ -package model - -type SectionCheckPoint interface { - RtssModel -} diff --git a/model/turnout.go b/model/turnout.go index 2bb6e0f..b253cfa 100644 --- a/model/turnout.go +++ b/model/turnout.go @@ -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 +} diff --git a/repo/repo.go b/repo/repo.go index 1c9a0a3..c06c008 100644 --- a/repo/repo.go +++ b/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 {