rts-sim-module/repository/repository.go
2023-09-28 14:22:21 +08:00

213 lines
6.0 KiB
Go

package repository
import (
"errors"
"fmt"
"joylink.club/rtsssimulation/repository/model/proto"
)
type Repository struct {
id string
version string
physicalSectionMap map[string]*PhysicalSection
checkPointMap map[string]*CheckPoint
turnoutMap map[string]*Turnout
signalMap map[string]*Signal
responderMap map[string]*Transponder
slopeMap map[string]*Slope
sectionalCurvatureMap map[string]*SectionalCurvature
kilometerConvertMap map[string]*proto.KilometerConvert
relayMap map[string]*Relay
linkMap map[string]*Link
}
func newRepository(id string, version string) *Repository {
return &Repository{
id: id,
version: version,
physicalSectionMap: make(map[string]*PhysicalSection),
checkPointMap: make(map[string]*CheckPoint),
turnoutMap: make(map[string]*Turnout),
signalMap: make(map[string]*Signal),
responderMap: make(map[string]*Transponder),
slopeMap: make(map[string]*Slope),
sectionalCurvatureMap: make(map[string]*SectionalCurvature),
kilometerConvertMap: make(map[string]*proto.KilometerConvert),
relayMap: make(map[string]*Relay),
linkMap: make(map[string]*Link),
}
}
// FindById 根据模型的复合id获取模型数据
func (repo *Repository) FindById(id string) Identity {
if md, ok := repo.turnoutMap[id]; ok {
return md
}
if md, ok := repo.signalMap[id]; ok {
return md
}
if md, ok := repo.relayMap[id]; ok {
return md
}
return nil
}
func (repo *Repository) PhysicalSectionList() []*PhysicalSection {
var list []*PhysicalSection
for _, model := range repo.physicalSectionMap {
list = append(list, model)
}
return list
}
func (repo *Repository) CheckPointList() []*CheckPoint {
var list []*CheckPoint
for _, model := range repo.checkPointMap {
list = append(list, model)
}
return list
}
func (repo *Repository) TurnoutList() []*Turnout {
var list []*Turnout
for _, model := range repo.turnoutMap {
list = append(list, model)
}
return list
}
func (repo *Repository) SignalList() []*Signal {
var list []*Signal
for _, model := range repo.signalMap {
list = append(list, model)
}
return list
}
func (repo *Repository) ResponderList() []*Transponder {
var list []*Transponder
for _, model := range repo.responderMap {
list = append(list, model)
}
return list
}
func (repo *Repository) SlopeList() []*Slope {
var list []*Slope
for _, model := range repo.slopeMap {
list = append(list, model)
}
return list
}
func (repo *Repository) SectionalCurvatureList() []*SectionalCurvature {
var list []*SectionalCurvature
for _, model := range repo.sectionalCurvatureMap {
list = append(list, model)
}
return list
}
func (repo *Repository) LinkList() []*Link {
var list []*Link
for _, model := range repo.linkMap {
list = append(list, model)
}
return list
}
func (repo *Repository) KilometerConvertList() []*proto.KilometerConvert {
var list []*proto.KilometerConvert
for _, model := range repo.kilometerConvertMap {
list = append(list, model)
}
return list
}
func (repo *Repository) RelayList() []*Relay {
var list []*Relay
for _, model := range repo.relayMap {
list = append(list, model)
}
return list
}
func (repo *Repository) FindModel(deviceId string, deviceType proto.DeviceType) (Identity, error) {
switch deviceType {
case proto.DeviceType_DeviceType_PhysicalSection:
return repo.physicalSectionMap[deviceId], nil
case proto.DeviceType_DeviceType_CheckPoint:
return repo.checkPointMap[deviceId], nil
case proto.DeviceType_DeviceType_Turnout:
return repo.turnoutMap[deviceId], nil
case proto.DeviceType_DeviceType_Signal:
return repo.signalMap[deviceId], nil
case proto.DeviceType_DeviceType_Transponder:
return repo.responderMap[deviceId], nil
case proto.DeviceType_DeviceType_Slope:
return repo.slopeMap[deviceId], nil
case proto.DeviceType_DeviceType_SectionalCurvature:
return repo.sectionalCurvatureMap[deviceId], nil
case proto.DeviceType_DeviceType_Link:
return repo.linkMap[deviceId], nil
default:
return nil, errors.New(fmt.Sprintf("仓库中不存在[%s]类型的模型", deviceType))
}
}
func (repo *Repository) FindLink(id string) *Link {
return repo.linkMap[id]
}
func (repo *Repository) FindTurnout(id string) *Turnout {
return repo.turnoutMap[id]
}
func (repo *Repository) FindPhysicalSection(id string) *PhysicalSection {
return repo.physicalSectionMap[id]
}
func (repo *Repository) AddPhysicalSection(section *PhysicalSection) {
repo.physicalSectionMap[section.Id()] = section
}
func (repo *Repository) ConvertKilometer(km *proto.Kilometer, cs string) *proto.Kilometer {
if km.CoordinateSystem == cs {
return km
}
kc, err := repo.getKilometerConvert(km.CoordinateSystem, cs)
if err != nil {
panic(err)
}
var sourceCsKm *proto.Kilometer
var targetCsKm *proto.Kilometer
if kc.KmA.CoordinateSystem == km.CoordinateSystem {
sourceCsKm = kc.KmA
targetCsKm = kc.KmB
} else {
sourceCsKm = kc.KmB
targetCsKm = kc.KmA
}
offset := km.Value - sourceCsKm.Value
var value int64
if kc.SameTrend {
value = targetCsKm.Value + offset
} else {
value = targetCsKm.Value - offset
}
if value < 0 {
panic(fmt.Sprintf("公里标[%v]转换为坐标系[%s]的公里标的值[%d]小于0", km, cs, value))
}
return &proto.Kilometer{Value: value, CoordinateSystem: cs}
}
func (repo *Repository) addKilometerConvert(kc *proto.KilometerConvert) {
repo.kilometerConvertMap[buildKilometerConvertKey(kc.KmA.CoordinateSystem, kc.KmB.CoordinateSystem)] = kc
repo.kilometerConvertMap[buildKilometerConvertKey(kc.KmB.CoordinateSystem, kc.KmA.CoordinateSystem)] = kc
}
func (repo *Repository) getKilometerConvert(cs1, cs2 string) (*proto.KilometerConvert, error) {
convert := repo.kilometerConvertMap[buildKilometerConvertKey(cs1, cs2)]
if convert == nil {
return nil, errors.New(fmt.Sprintf("没有[%s-%s]的公里标转换数据", cs1, cs2))
}
return convert, nil
}
func buildKilometerConvertKey(cs1 string, cs2 string) string {
return cs1 + cs2
}