rtss-core/example/build_repo_example/main.go
soul-walker 1a610c01ba 调整公里标概念,添加注释说明
完善道岔区段与道岔关系构建检查
添加Link位置和link范围工具类
完善example道岔区段关系构建
2024-07-10 18:09:16 +08:00

299 lines
12 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}