package main import ( "fmt" "log/slog" "joylink.club/rtss-core/example/data_proto" modelimpl "joylink.club/rtss-core/example/model_impl" "joylink.club/rtss-core/example/repository" "joylink.club/rtss-core/model" ) func main() { slog.SetLogLoggerLevel(slog.LevelDebug) // slog.SetLogLoggerLevel(slog.LevelInfo) repo1 := repository.NewRepository("test1") rtssGraphicStorage := data_proto.GetXian6STYG() dataMapping := repository.NewDataMapping("1", rtssGraphicStorage) repo1.DataMapping["1"] = dataMapping basicDataMappingAndModelBuild(dataMapping, repo1) // 构建公里标转换器 buildKilometerMarkConverters(dataMapping, repo1) // 构建区段关系 buildSectionRelationships(dataMapping, repo1) // 构建道岔关系 buildTurnoutRelationships(dataMapping, repo1) // 检查区段、道岔通道连接关系 err := repo1.CheckSectionAndTurnoutPipeLink() if err != nil { slog.Error("区段道岔连接关系检查错误", "errMsg", err) return } else { slog.Info("区段、道岔连接关系检查通过") } // 构建区段、道岔公里标 buildKilometerMark(dataMapping, repo1) err = repo1.CheckSectionAndTurnoutPortKms() if err != nil { slog.Error("区段道岔公里标检查错误", "errMsg", err) return } // 构建link/linknode repo1.BuildLinks() // 检查link/linknode err = repo1.CheckLinkAndLinkNodePipeLink() if err != nil { slog.Error("link/linknode连接关系检查错误", "errMsg", err) return } else { slog.Info("link/linknode连接关系检查通过") } } func basicDataMappingAndModelBuild(dataMapping *repository.DataMapping, repo1 *repository.Repository) { // 车站 for _, station := range dataMapping.Stations { 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 dataMapping.Section { if section.CentralizedStations == nil || len(section.CentralizedStations) == 0 { continue } belongStation := dataMapping.StationDataMap[section.CentralizedStations[0]] if belongStation == nil { continue } dataMapping.SectionDataMap[section.Common.Id] = section uid := getSectionUid(section, belongStation, dataMapping.GetLineInfo()) dataMapping.AddIdMapping(repository.NewIdMapping(section.Common.Id, uid)) if section.SectionType == data_proto.Section_Physical { sectionModel := model.NewPhysicalSection(uid) repo1.PhysicalSectionMap[uid] = &modelimpl.PhysicalSection{PhysicalSectionImpl: sectionModel} } else { tsModel := model.NewTurnoutSection(uid) repo1.TurnoutSectionMap[uid] = tsModel } } // 道岔 for _, turnout := range dataMapping.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.GetLineInfo()) dataMapping.AddIdMapping(repository.NewIdMapping(turnout.Common.Id, uid)) turnoutModel := model.NewTurnout(uid) repo1.TurnoutMap[uid] = &modelimpl.Turnout{TurnoutImpl: turnoutModel} } // 区段检测点 for _, axleCounting := range dataMapping.AxleCountings { dataMapping.SectionCheckPointMap[axleCounting.Common.Id] = axleCounting } } func buildKilometerMarkConverters(dataMapping *repository.DataMapping, repo1 *repository.Repository) { if dataMapping.KilometerConvertList == nil || len(dataMapping.KilometerConvertList) == 0 { slog.Info("没有公里标转换数据") return } for _, kmConverter := range dataMapping.KilometerConvertList { km1 := convertKs2Km(kmConverter.KmA) km2 := convertKs2Km(kmConverter.KmB) repo1.KilometerMarkConverters = append(repo1.KilometerMarkConverters, model.NewKilometerMarkConverter(km1, km2, kmConverter.SameTrend)) } } func convertKs2Km(ks *data_proto.KilometerSystem) *model.KilometerMark { return model.NewKilometerMark(ks.CoordinateSystem, ks.Kilometer) } // 构建区段、道岔公里标 func buildKilometerMark(dataMapping *repository.DataMapping, repo1 *repository.Repository) { for _, turnout := range dataMapping.TurnoutDataMap { if len(turnout.KilometerSystem) == 0 { repo1.BuildErrorInfos = append(repo1.BuildErrorInfos, fmt.Errorf("构建区段、道岔公里标数据错误:道岔[id=%d]未关联任何公里标", turnout.Common.Id)) } else { km := convertKs2Km(turnout.KilometerSystem[0]) turnoutModel := repo1.TurnoutMap[dataMapping.IdMappingMap[turnout.Common.Id].Uid] turnoutModel.(*modelimpl.Turnout).Km = km } } for _, checkpoint := range dataMapping.AxleCountings { if checkpoint.AxleCountingRef == nil || len(checkpoint.AxleCountingRef) == 0 { repo1.BuildErrorInfos = append(repo1.BuildErrorInfos, fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]未关联任何区段、道岔", checkpoint.Common.Id)) } for _, linkship := range checkpoint.AxleCountingRef { slog.Debug("区段检测点关联数据", "code", checkpoint.Code, "linkship", fmt.Sprintf("{type=%s, id=%d, port=%s}", linkship.DeviceType, linkship.Id, linkship.DevicePort)) idmapping := dataMapping.IdMappingMap[linkship.Id] if idmapping == nil { repo1.BuildErrorInfos = append(repo1.BuildErrorInfos, fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]关联的{type=%s,id=%d}不存在", checkpoint.Common.Id, linkship.DeviceType, linkship.Id)) continue } if linkship.DeviceType == data_proto.RelatedRef_Section { sectionModel, ok := repo1.PhysicalSectionMap[idmapping.Uid] if !ok { panic(fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]关联的区段模型[uid=%s]不存在", checkpoint.Common.Id, idmapping.Uid)) } km := convertKs2Km(checkpoint.KilometerSystem) if linkship.DevicePort == data_proto.RelatedRef_A { sectionModel.(*modelimpl.PhysicalSection).PaKm = km } else if linkship.DevicePort == data_proto.RelatedRef_B { sectionModel.(*modelimpl.PhysicalSection).PbKm = km } else { panic(fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]关联的区段模型[uid=%s]未知的端口类型: %v", checkpoint.Common.Id, idmapping.Uid, linkship.DevicePort)) } } else if linkship.DeviceType == data_proto.RelatedRef_Turnout { turnoutModel, ok := repo1.TurnoutMap[idmapping.Uid] if !ok { panic(fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]关联的道岔模型[uid=%s]不存在", checkpoint.Common.Id, idmapping.Uid)) } km := convertKs2Km(checkpoint.KilometerSystem) if linkship.DevicePort == data_proto.RelatedRef_A { turnoutModel.(*modelimpl.Turnout).PaKm = km } else if linkship.DevicePort == data_proto.RelatedRef_B { turnoutModel.(*modelimpl.Turnout).PbKm = km } else if linkship.DevicePort == data_proto.RelatedRef_C { turnoutModel.(*modelimpl.Turnout).PcKm = km } else { panic(fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]关联的道岔模型[uid=%s]未知的端口类型: %v", checkpoint.Common.Id, idmapping.Uid, linkship.DevicePort)) } } else { panic(fmt.Errorf("构建区段、道岔公里标数据错误:检测点[id=%d]未知的关联设备类型: %v", checkpoint.Common.Id, linkship.DeviceType)) } } } } 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] buildTurnoutPortLinkship(turnout.PaRef, turnoutModel, model.PipePortA, repo1, dataMapping) buildTurnoutPortLinkship(turnout.PbRef, turnoutModel, model.PipePortB, repo1, dataMapping) buildTurnoutPortLinkship(turnout.PcRef, turnoutModel, model.PipePortC, repo1, dataMapping) } } func buildSectionRelationships(dataMapping *repository.DataMapping, repo1 *repository.Repository) { for _, section := range dataMapping.SectionDataMap { idmapping := dataMapping.GetIdMapping(section.Common.Id) if section.SectionType == data_proto.Section_Physical { sectionModel := repo1.PhysicalSectionMap[idmapping.Uid] buildSectionPortLinkRelation(section.PaRef, sectionModel, model.PipePortA, repo1, dataMapping) buildSectionPortLinkRelation(section.PbRef, sectionModel, model.PipePortB, repo1, dataMapping) } else { tsModel := repo1.TurnoutSectionMap[idmapping.Uid] turnoutPorts := make(map[uint32]map[model.PipePort]struct{}) for _, axleId := range section.AxleCountings { slog.Debug("区段关联检测点", "sectionId", section.Common.Id, "axleId", axleId) axleCounting := dataMapping.SectionCheckPointMap[axleId] if axleCounting == nil { repo1.BuildErrorInfos = append(repo1.BuildErrorInfos, fmt.Errorf("构建区段关系错误:区段[id=%d]关联的检测点[id=%d]不存在", section.Common.Id, axleId)) continue } for _, ref := range axleCounting.AxleCountingRef { if ref.DeviceType == data_proto.RelatedRef_Turnout { portMap := turnoutPorts[ref.Id] if portMap == nil { portMap = make(map[model.PipePort]struct{}) turnoutPorts[ref.Id] = portMap } portMap[convertPort(ref.DevicePort)] = struct{}{} } } } slog.Debug("区段关联检测点关联道岔", "sectionId", section.Common.Id, "turnoutPorts", turnoutPorts) for turnoutId, portMap := range turnoutPorts { if len(portMap) == 3 { turnoutModel := repo1.TurnoutMap[dataMapping.GetIdMapping(turnoutId).Uid] tsModel.AddTurnout(turnoutModel.(*modelimpl.Turnout)) } } } } } func buildTurnoutPortLinkship(pref *data_proto.RelatedRef, sourceModel model.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.PhysicalSectionMap[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 model.PhysicalSection, 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.PhysicalSectionMap[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, lineInfo string) string { return fmt.Sprintf("%s/%s/%s", lineInfo, belongStation.Code, section.Code) } func getTurnoutUid(turnout *data_proto.Turnout, belongStation *data_proto.Station, lineInfo string) string { return fmt.Sprintf("%s/%s/%s", lineInfo, belongStation.Code, turnout.Code) }