section 和 turnout模型关系构建和检查
This commit is contained in:
parent
5d8b8cf1ea
commit
58754c2b04
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"joylink.club/rtss-core/example/data_proto"
|
||||
modelimpl "joylink.club/rtss-core/example/model_impl"
|
||||
"joylink.club/rtss-core/example/repository"
|
||||
@ -8,27 +10,148 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
repo := repository.NewRepository("test1").(*repository.Repository)
|
||||
repo1 := repository.NewRepository("test1")
|
||||
rtssGraphicStorage := data_proto.GetLineSytle1()
|
||||
dataMapping := repository.NewDataMapping("1", rtssGraphicStorage)
|
||||
repo1.DataMapping["1"] = dataMapping
|
||||
// log.Println(rtssGraphicStorage.Stations)
|
||||
// log.Println(rtssGraphicStorage.Section)
|
||||
// log.Println(rtssGraphicStorage.Turnouts)
|
||||
for _, station := range rtssGraphicStorage.Stations {
|
||||
repo.StationDataMap[station.Common.Id] = station
|
||||
dataMapping.StationDataMap[station.Common.Id] = station
|
||||
uid := station.Code
|
||||
dataMapping.AddIdMapping(repository.NewIdMapping(station.Common.Id, uid))
|
||||
stationModel := model.NewStation(uid, station.ConcentrationStations)
|
||||
repo1.StationMap[uid] = &modelimpl.Station{StationImpl: stationModel}
|
||||
}
|
||||
for _, section := range rtssGraphicStorage.Section {
|
||||
belongStation := repo.SectionDataMap[section.CentralizedStations[0]]
|
||||
if section.CentralizedStations == nil || len(section.CentralizedStations) == 0 || repo.SectionDataMap[section.CentralizedStations[0]] == nil {
|
||||
if section.CentralizedStations == nil || len(section.CentralizedStations) == 0 {
|
||||
continue
|
||||
}
|
||||
repo.SectionDataMap[section.Common.Id] = section
|
||||
belongStation := dataMapping.StationDataMap[section.CentralizedStations[0]]
|
||||
if belongStation == nil {
|
||||
continue
|
||||
}
|
||||
dataMapping.SectionDataMap[section.Common.Id] = section
|
||||
uid := getSectionUid(section, belongStation)
|
||||
repo.IpMapping = append(repo.IpMapping, repository.NewIdMapping(section.Common.Id, uid))
|
||||
dataMapping.AddIdMapping(repository.NewIdMapping(section.Common.Id, uid))
|
||||
sectionModel := model.NewSection(uid)
|
||||
repo.SectionMap[uid] = &modelimpl.Section{SectionImpl: sectionModel}
|
||||
repo1.SectionMap[uid] = &modelimpl.Section{SectionImpl: sectionModel}
|
||||
}
|
||||
for _, turnout := range rtssGraphicStorage.Turnouts {
|
||||
if turnout.CentralizedStations == nil || len(turnout.CentralizedStations) == 0 {
|
||||
continue
|
||||
}
|
||||
belongStation := dataMapping.StationDataMap[turnout.CentralizedStations[0]]
|
||||
if belongStation == nil {
|
||||
continue
|
||||
}
|
||||
dataMapping.TurnoutDataMap[turnout.Common.Id] = turnout
|
||||
uid := getTurnoutUid(turnout, belongStation)
|
||||
dataMapping.AddIdMapping(repository.NewIdMapping(turnout.Common.Id, uid))
|
||||
turnoutModel := model.NewTurnout(uid)
|
||||
repo1.TurnoutMap[uid] = &modelimpl.Turnout{TurnoutImpl: turnoutModel}
|
||||
}
|
||||
|
||||
// 构建区段关系
|
||||
buildSectionRelationships(dataMapping, repo1)
|
||||
// 构建道岔关系
|
||||
buildTurnoutRelationships(dataMapping, repo1)
|
||||
// 检查通道连接关系
|
||||
err := repo1.CheckPipeLink()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func getSectionUid(section *data_proto.Section, belongStation *data_proto.Section) string {
|
||||
func buildTurnoutRelationships(dataMapping *repository.DataMapping, repo1 *repository.Repository) {
|
||||
for _, turnout := range dataMapping.TurnoutDataMap {
|
||||
idmapping := dataMapping.IdMappingMap[turnout.Common.Id]
|
||||
if idmapping == nil {
|
||||
panic(fmt.Errorf("构建道岔关系错误:idmapping异常为空"))
|
||||
}
|
||||
turnoutModel := repo1.TurnoutMap[idmapping.Uid]
|
||||
buildTurnoutPortLinkRelation(turnout.PaRef, turnoutModel, model.PipePortA, repo1, dataMapping)
|
||||
buildTurnoutPortLinkRelation(turnout.PbRef, turnoutModel, model.PipePortB, repo1, dataMapping)
|
||||
buildTurnoutPortLinkRelation(turnout.PcRef, turnoutModel, model.PipePortC, repo1, dataMapping)
|
||||
}
|
||||
}
|
||||
|
||||
func buildSectionRelationships(dataMapping *repository.DataMapping, repo1 *repository.Repository) {
|
||||
for _, section := range dataMapping.SectionDataMap {
|
||||
idmapping := dataMapping.IdMappingMap[section.Common.Id]
|
||||
if idmapping == nil {
|
||||
panic(fmt.Errorf("构建区段关系错误:idmapping异常为空"))
|
||||
}
|
||||
sectionModel := repo1.SectionMap[idmapping.Uid]
|
||||
buildSectionPortLinkRelation(section.PaRef, sectionModel, model.PipePortA, repo1, dataMapping)
|
||||
buildSectionPortLinkRelation(section.PbRef, sectionModel, model.PipePortB, repo1, dataMapping)
|
||||
}
|
||||
}
|
||||
|
||||
func buildTurnoutPortLinkRelation(pref *data_proto.RelatedRef, sourceModel *modelimpl.Turnout, port model.PipePort, repo1 *repository.Repository, dataMapping *repository.DataMapping) {
|
||||
if pref == nil {
|
||||
return
|
||||
}
|
||||
if pref.DeviceType == data_proto.RelatedRef_Section {
|
||||
idmapping2 := dataMapping.IdMappingMap[pref.Id]
|
||||
if idmapping2 != nil {
|
||||
sectionModel := repo1.SectionMap[idmapping2.Uid]
|
||||
if sectionModel != nil {
|
||||
sourceModel.SetLinkedElement(port, model.NewPipeLink(sectionModel, convertPort(pref.DevicePort)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if pref.DeviceType == data_proto.RelatedRef_Turnout {
|
||||
idmapping2 := dataMapping.IdMappingMap[pref.Id]
|
||||
if idmapping2 != nil {
|
||||
turnoutModel2 := repo1.TurnoutMap[idmapping2.Uid]
|
||||
if turnoutModel2 != nil {
|
||||
sourceModel.SetLinkedElement(port, model.NewPipeLink(turnoutModel2, convertPort(pref.DevicePort)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildSectionPortLinkRelation(pref *data_proto.RelatedRef, sourceModel *modelimpl.Section, port model.PipePort, repo1 *repository.Repository, dataMapping *repository.DataMapping) {
|
||||
if pref == nil {
|
||||
return
|
||||
}
|
||||
if pref.DeviceType == data_proto.RelatedRef_Section {
|
||||
idmapping2 := dataMapping.IdMappingMap[pref.Id]
|
||||
if idmapping2 != nil {
|
||||
sectionModel := repo1.SectionMap[idmapping2.Uid]
|
||||
if sectionModel != nil {
|
||||
sourceModel.SetLinkedElement(port, model.NewPipeLink(sectionModel, convertPort(pref.DevicePort)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if pref.DeviceType == data_proto.RelatedRef_Turnout {
|
||||
idmapping2 := dataMapping.IdMappingMap[pref.Id]
|
||||
if idmapping2 != nil {
|
||||
turnoutModel := repo1.TurnoutMap[idmapping2.Uid]
|
||||
if turnoutModel != nil {
|
||||
sourceModel.SetLinkedElement(port, model.NewPipeLink(turnoutModel, convertPort(pref.DevicePort)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convertPort(port data_proto.RelatedRef_DevicePort) model.PipePort {
|
||||
if port == data_proto.RelatedRef_A {
|
||||
return model.PipePortA
|
||||
} else if port == data_proto.RelatedRef_B {
|
||||
return model.PipePortB
|
||||
} else if port == data_proto.RelatedRef_C {
|
||||
return model.PipePortC
|
||||
}
|
||||
panic(fmt.Errorf("未知的数据关联端口类型: %v", port))
|
||||
}
|
||||
|
||||
func getSectionUid(section *data_proto.Section, belongStation *data_proto.Station) string {
|
||||
return belongStation.Code + "-" + section.Code
|
||||
}
|
||||
|
||||
func getTurnoutUid(turnout *data_proto.Turnout, belongStation *data_proto.Station) string {
|
||||
return belongStation.Code + "-" + turnout.Code
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package modelimpl
|
||||
import "joylink.club/rtss-core/model"
|
||||
|
||||
type Station struct {
|
||||
model.StationImpl
|
||||
*model.StationImpl
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package modelimpl
|
||||
import "joylink.club/rtss-core/model"
|
||||
|
||||
type Turnout struct {
|
||||
model.TurnoutImpl
|
||||
*model.TurnoutImpl
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"joylink.club/rtss-core/example/data_proto"
|
||||
modelimpl "joylink.club/rtss-core/example/model_impl"
|
||||
"joylink.club/rtss-core/model"
|
||||
@ -20,27 +22,52 @@ func NewIdMapping(graphicId uint32, uid string) *IdMapping {
|
||||
}
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
id string
|
||||
type DataMapping struct {
|
||||
id string
|
||||
*data_proto.RtssGraphicStorage
|
||||
StationDataMap map[uint32]*data_proto.Station
|
||||
SectionDataMap map[uint32]*data_proto.Section
|
||||
TurnoutDataMap map[uint32]*data_proto.Turnout
|
||||
IpMapping []*IdMapping
|
||||
StationMap map[string]*modelimpl.Station
|
||||
SectionMap map[string]*modelimpl.Section
|
||||
TurnoutMap map[string]*modelimpl.Turnout
|
||||
IdMappingMap map[uint32]*IdMapping
|
||||
UidMappingMap map[string]*IdMapping
|
||||
}
|
||||
|
||||
func NewRepository(id string) repo.Repo {
|
||||
func (d *DataMapping) AddIdMapping(idMapping *IdMapping) {
|
||||
d.IdMappingMap[idMapping.GraphicId] = idMapping
|
||||
d.UidMappingMap[idMapping.Uid] = idMapping
|
||||
}
|
||||
|
||||
func NewDataMapping(id string, storage *data_proto.RtssGraphicStorage) *DataMapping {
|
||||
return &DataMapping{
|
||||
id: id,
|
||||
RtssGraphicStorage: storage,
|
||||
StationDataMap: make(map[uint32]*data_proto.Station),
|
||||
SectionDataMap: make(map[uint32]*data_proto.Section),
|
||||
TurnoutDataMap: make(map[uint32]*data_proto.Turnout),
|
||||
IdMappingMap: make(map[uint32]*IdMapping),
|
||||
UidMappingMap: make(map[string]*IdMapping),
|
||||
}
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
id string
|
||||
BuildErrorInfos []error
|
||||
DataMapping map[string]*DataMapping
|
||||
StationMap map[string]*modelimpl.Station
|
||||
SectionMap map[string]*modelimpl.Section
|
||||
TurnoutMap map[string]*modelimpl.Turnout
|
||||
}
|
||||
|
||||
var _ repo.Repo = &Repository{}
|
||||
|
||||
func NewRepository(id string) *Repository {
|
||||
return &Repository{
|
||||
id: id,
|
||||
StationDataMap: make(map[uint32]*data_proto.Station),
|
||||
SectionDataMap: make(map[uint32]*data_proto.Section),
|
||||
TurnoutDataMap: make(map[uint32]*data_proto.Turnout),
|
||||
IpMapping: make([]*IdMapping, 0),
|
||||
StationMap: make(map[string]*modelimpl.Station),
|
||||
SectionMap: make(map[string]*modelimpl.Section),
|
||||
TurnoutMap: make(map[string]*modelimpl.Turnout),
|
||||
id: id,
|
||||
BuildErrorInfos: make([]error, 0),
|
||||
DataMapping: make(map[string]*DataMapping),
|
||||
StationMap: make(map[string]*modelimpl.Station),
|
||||
SectionMap: make(map[string]*modelimpl.Section),
|
||||
TurnoutMap: make(map[string]*modelimpl.Turnout),
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,3 +86,22 @@ func (r *Repository) GetSectionByUid(uid string) model.Section {
|
||||
func (r *Repository) GetTurnoutByUid(uid string) model.Turnout {
|
||||
return r.TurnoutMap[uid]
|
||||
}
|
||||
|
||||
func (r *Repository) CheckPipeLink() error {
|
||||
for _, section := range r.SectionMap {
|
||||
err := section.CheckPipeLink()
|
||||
if err != nil {
|
||||
r.BuildErrorInfos = append(r.BuildErrorInfos, err)
|
||||
}
|
||||
}
|
||||
for _, turnout := range r.TurnoutMap {
|
||||
err := turnout.CheckPipeLink()
|
||||
if err != nil {
|
||||
r.BuildErrorInfos = append(r.BuildErrorInfos, err)
|
||||
}
|
||||
}
|
||||
if len(r.BuildErrorInfos) > 0 {
|
||||
return errors.Join(r.BuildErrorInfos...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ type RR = io.Writer
|
||||
|
||||
// 轨道
|
||||
type Link interface {
|
||||
RtssModel
|
||||
PipeElement
|
||||
}
|
||||
|
||||
@ -62,6 +61,10 @@ func (l *LinkImpl) GetLinkedElement(port PipePort) *PipeLink {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *LinkNodeImpl) Uid() string {
|
||||
return n.turnout.Uid()
|
||||
}
|
||||
|
||||
func (n *LinkNodeImpl) Turnout() Turnout {
|
||||
return n.turnout
|
||||
}
|
||||
|
@ -30,10 +30,48 @@ type PipeLink struct {
|
||||
Port PipePort
|
||||
}
|
||||
|
||||
func NewPipeLink(pipe PipeElement, port PipePort) *PipeLink {
|
||||
if pipe == nil {
|
||||
panic("pipe is nil")
|
||||
}
|
||||
return &PipeLink{
|
||||
Pipe: pipe,
|
||||
Port: port,
|
||||
}
|
||||
}
|
||||
|
||||
func (pl *PipeLink) Debug() string {
|
||||
return "{" + "\"pipeUid\":" + pl.Pipe.Uid() + ", \"port\":" + pl.Port + "}"
|
||||
}
|
||||
|
||||
// 通道元素
|
||||
type PipeElement interface {
|
||||
RtssModel
|
||||
// 获取通道端口
|
||||
Ports() []PipePort
|
||||
// 获取指定端口连接的通道连接关系
|
||||
GetLinkedElement(port PipePort) *PipeLink
|
||||
}
|
||||
|
||||
type TwoPortsPipeElement struct {
|
||||
uid string
|
||||
paPipeLink *PipeLink
|
||||
pbPipeLink *PipeLink
|
||||
}
|
||||
|
||||
func (t *TwoPortsPipeElement) Ports() []PipePort {
|
||||
return twoPorts
|
||||
}
|
||||
|
||||
func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) PipeLink {
|
||||
if port == PipePortA {
|
||||
return *t.pbPipeLink
|
||||
}
|
||||
return *t.paPipeLink
|
||||
}
|
||||
|
||||
type ThreePortsPipeElement struct{}
|
||||
|
||||
func (t *ThreePortsPipeElement) Ports() []PipePort {
|
||||
return threePorts
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 区段
|
||||
type Section interface {
|
||||
RtssModel
|
||||
PipeElement
|
||||
}
|
||||
|
||||
@ -20,6 +23,32 @@ func NewSection(uid string) *SectionImpl {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SectionImpl) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
|
||||
if port == PipePortA {
|
||||
if s.paPipeLink != nil {
|
||||
return fmt.Errorf("区段uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", s.uid, s.paPipeLink.Pipe.Uid(), s.paPipeLink.Port)
|
||||
}
|
||||
s.paPipeLink = pipeLink
|
||||
} else if port == PipePortB {
|
||||
if s.pbPipeLink != nil {
|
||||
return fmt.Errorf("区段uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", s.uid, s.pbPipeLink.Pipe.Uid(), s.pbPipeLink.Port)
|
||||
}
|
||||
s.pbPipeLink = pipeLink
|
||||
} else {
|
||||
return fmt.Errorf("区段uid=%s设置关联元素端口错误,不支持C端口", s.uid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SectionImpl) CheckPipeLink() error {
|
||||
err := checkPipePortLink(s, PipePortA, s.paPipeLink)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = checkPipePortLink(s, PipePortB, s.pbPipeLink)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *SectionImpl) Uid() string {
|
||||
return s.uid
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ type StationImpl struct {
|
||||
centralized bool
|
||||
}
|
||||
|
||||
func NewStation(uid string, centralized bool) Station {
|
||||
func NewStation(uid string, centralized bool) *StationImpl {
|
||||
return &StationImpl{
|
||||
uid: uid,
|
||||
centralized: centralized,
|
||||
|
@ -1,10 +1,12 @@
|
||||
package model
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 道岔
|
||||
type Turnout interface {
|
||||
RtssModel
|
||||
PipeElement
|
||||
}
|
||||
|
||||
@ -26,6 +28,53 @@ func NewTurnout(uid string) *TurnoutImpl {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
|
||||
if port == PipePortA {
|
||||
if t.paPipeLink != nil {
|
||||
return fmt.Errorf("道岔uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", t.uid, t.paPipeLink.Pipe.Uid(), t.paPipeLink.Port)
|
||||
}
|
||||
t.paPipeLink = pipeLink
|
||||
} else if port == PipePortB {
|
||||
if t.pbPipeLink != nil {
|
||||
return fmt.Errorf("道岔uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pbPipeLink.Pipe.Uid(), t.pbPipeLink.Port)
|
||||
}
|
||||
t.pbPipeLink = pipeLink
|
||||
} else if port == PipePortC {
|
||||
if t.pcPipeLink != nil {
|
||||
return fmt.Errorf("道岔uid=%s端口C已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pcPipeLink.Pipe.Uid(), t.pcPipeLink.Port)
|
||||
}
|
||||
t.pcPipeLink = pipeLink
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) CheckPipeLink() error {
|
||||
err := checkPipePortLink(t, PipePortA, t.paPipeLink)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = checkPipePortLink(t, PipePortB, t.pbPipeLink)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = checkPipePortLink(t, PipePortC, t.pcPipeLink)
|
||||
return err
|
||||
}
|
||||
|
||||
func checkPipePortLink(pe PipeElement, port PipePort, pipeLink *PipeLink) error {
|
||||
if pipeLink == nil {
|
||||
return nil
|
||||
}
|
||||
plink := pipeLink.Pipe.GetLinkedElement(pipeLink.Port)
|
||||
if plink == nil {
|
||||
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却未关联通道端口", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port)
|
||||
} else if plink.Pipe.Uid() != pe.Uid() || plink.Port != port {
|
||||
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却关联了其他通道端口: {uid=%s, port=%s}", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port,
|
||||
plink.Pipe.Uid(), plink.Port)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TurnoutImpl) Uid() string {
|
||||
return t.uid
|
||||
}
|
||||
|
@ -8,4 +8,6 @@ type Repo interface {
|
||||
GetStationByUid(uid string) model.Station
|
||||
GetSectionByUid(uid string) model.Section
|
||||
GetTurnoutByUid(uid string) model.Turnout
|
||||
// 检查通道连接关系
|
||||
CheckPipeLink() error
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user