package repository import ( "fmt" "math" "joylink.club/rtsssimulation/repository/model/proto" ) type Repository struct { id string version string coordinate *MapCoordinate // 基准坐标系类型,在列车画图时统一坐标系 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 phaseFailureProtectorMap map[string]*PhaseFailureProtector buttonMap map[string]*Button psdMap map[string]*Psd lightMap map[string]*Light alarmMap map[string]*Alarm stationMap map[string]*Station mkxMap map[string]*Mkx keyMap map[string]*Key linkMap map[string]*Link platformMap map[string]*Platform centralizedMap map[string]*proto.CentralizedStationRef } 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), phaseFailureProtectorMap: make(map[string]*PhaseFailureProtector), linkMap: make(map[string]*Link), buttonMap: make(map[string]*Button), psdMap: make(map[string]*Psd), lightMap: make(map[string]*Light), alarmMap: make(map[string]*Alarm), stationMap: make(map[string]*Station), mkxMap: make(map[string]*Mkx), keyMap: make(map[string]*Key), platformMap: make(map[string]*Platform), centralizedMap: make(map[string]*proto.CentralizedStationRef), } } // 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 } if md, ok := repo.physicalSectionMap[id]; ok { return md } if md, ok := repo.checkPointMap[id]; ok { return md } if md, ok := repo.responderMap[id]; ok { return md } if md, ok := repo.stationMap[id]; ok { return md } if md, ok := repo.platformMap[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) ButtonList() []*Button { var list []*Button for _, model := range repo.buttonMap { list = append(list, model) } return list } func (repo *Repository) PsdList() []*Psd { var list []*Psd for _, model := range repo.psdMap { list = append(list, model) } return list } func (repo *Repository) MkxList() []*Mkx { var list []*Mkx for _, model := range repo.mkxMap { list = append(list, model) } return list } func (repo *Repository) StationList() []*Station { var list []*Station for _, model := range repo.stationMap { list = append(list, model) } return list } func (repo *Repository) KeyList() []*Key { var list []*Key for _, model := range repo.keyMap { list = append(list, model) } return list } func (repo *Repository) CiQcList() []*proto.CentralizedStationRef { var list []*proto.CentralizedStationRef for _, model := range repo.centralizedMap { list = append(list, model) } return list } func (repo *Repository) GetCentralizedStationRef(centralizedStationId string) *proto.CentralizedStationRef { return repo.centralizedMap[centralizedStationId] } 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 case proto.DeviceType_DeviceType_Psd: return repo.psdMap[deviceId], nil default: return nil, fmt.Errorf("仓库中不存在[%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) FindPsd(id string) *Psd { return repo.psdMap[id] } func (repo *Repository) FindPlatfrom(id string) *Platform { return repo.platformMap[id] } func (repo *Repository) AddPhysicalSection(section *PhysicalSection) { repo.physicalSectionMap[section.Id()] = section } func (repo *Repository) ConvertKilometer(km *proto.Kilometer, cs string) (*proto.Kilometer, error) { if km.CoordinateSystem == cs { return km, nil } kc, err := repo.getKilometerConvert(km.CoordinateSystem, cs) if err != nil { return nil, err // 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 } value := targetCsKm.Value + (km.Value - sourceCsKm.Value) if value < 0 { panic(fmt.Sprintf("公里标[%v]转换为坐标系[%s]的公里标的值[%d]小于0", km, cs, value)) } return &proto.Kilometer{Value: value, CoordinateSystem: cs}, nil } 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, fmt.Errorf("没有[%s-%s]的公里标转换数据", cs1, cs2) } return convert, nil } // 获取地图坐标信息 func (repo *Repository) generateCoordinateInfo(coordinateSystem string) error { coordinate := &MapCoordinate{ Coordinate: "MAIN_LINE", MinCoordinate: int64(math.MaxInt64), MaxCoordinate: int64(math.MinInt64), } if coordinateSystem != "" { coordinate.Coordinate = coordinateSystem } for _, data := range repo.checkPointMap { if data.km == nil || data.km.CoordinateSystem == "" { continue } km, err := repo.ConvertKilometer(data.km, coordinate.Coordinate) if err != nil { return err } if km.Value < coordinate.MinCoordinate { coordinate.MinCoordinate = km.Value } if km.Value > coordinate.MaxCoordinate { coordinate.MaxCoordinate = km.Value } } if coordinate.Coordinate == "" { return fmt.Errorf("无计轴公里标信息") // panic("无计轴公里标信息") } repo.coordinate = coordinate return nil } func (repo Repository) GetCoordinateInfo() *MapCoordinate { return repo.coordinate } func buildKilometerConvertKey(cs1 string, cs2 string) string { return cs1 + cs2 }