299 lines
12 KiB
Go
299 lines
12 KiB
Go
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)
|
||
}
|