diff --git a/repository/link.go b/repository/link.go index fd186a9..4dca630 100644 --- a/repository/link.go +++ b/repository/link.go @@ -11,7 +11,7 @@ type Link struct { aRelation *TurnoutPort bRelation *TurnoutPort - //组成Link的物理区段(按在link上偏移量从小到大排列) + //组成Link的非道岔物理区段(按在link上偏移量从小到大排列) physicalSections []*PhysicalSection aKm *proto.Kilometer diff --git a/repository/physical_section.go b/repository/physical_section.go index 83ea850..2f8277a 100644 --- a/repository/physical_section.go +++ b/repository/physical_section.go @@ -3,8 +3,8 @@ package repository import ( "errors" "fmt" - "joylink.club/rtsssimulation/repository/model/proto" + "joylink.club/rtsssimulation/util/number" ) // 物理区段 @@ -30,10 +30,7 @@ type PhysicalSection struct { //aKm/bKm对应的LinkPosition aLinkPosition *LinkPosition bLinkPosition *LinkPosition - //在Link上的区间(根据aKm和bKm计算出的,start的offset一定小于end的offset) - startLinkPosition *LinkPosition - endLinkPosition *LinkPosition - //在Link上的区间 + //在Link上的区间(start小于end) linkRanges []*LinkRange //物理区段所属集中站 @@ -46,6 +43,14 @@ func NewPhysicalSection(id string) *PhysicalSection { } } +func (p *PhysicalSection) bindLinkRange(link *Link, one int64, two int64) { + p.linkRanges = append(p.linkRanges, &LinkRange{ + link: link, + start: number.Min(one, two), + end: number.Max(one, two), + }) +} + func (s *PhysicalSection) PortNum() int { return 2 } diff --git a/repository/repository_manager.go b/repository/repository_manager.go index e70b572..731fc68 100644 --- a/repository/repository_manager.go +++ b/repository/repository_manager.go @@ -574,8 +574,8 @@ func buildLinks(repo *Repository) error { if startTp == nil { break } - //以始端道岔的公里标作为公里标换算的基准 - baseKm := startTp.turnout.km + //以始端道岔的公里标作为Link零点的公里标 + linkZeroKm := startTp.turnout.km //创建基础Link link := &Link{ Identity: identity{ @@ -584,9 +584,9 @@ func buildLinks(repo *Repository) error { }} linkIdGenerator++ //以此道岔端口作为Link的A端节点 - interrelateLinkAndTurnout(repo, baseKm, startTp, &LinkPort{link, proto.Port_A}) + interrelateLinkAndTurnout(repo, linkZeroKm, startTp, &LinkPort{link, proto.Port_A}) //沿着道岔端口方向,一直寻找到轨道尽头或者下一个道岔端口。构建并关联中间的设备在link上的位置 - endTp, endKm, err := findEndTurnoutPortOrEndKm(repo, link, startTp, baseKm) + endTp, endKm, err := findEndTurnoutPortOrEndKm(repo, link, startTp, linkZeroKm) if err != nil { return err } @@ -594,16 +594,18 @@ func buildLinks(repo *Repository) error { if endTp != nil { visitedTurnoutPortMap[buildTurnoutPortKey(endTp)] = true endKm = endTp.turnout.km - interrelateLinkAndTurnout(repo, baseKm, endTp, &LinkPort{link, proto.Port_B}) + interrelateLinkAndTurnout(repo, linkZeroKm, endTp, &LinkPort{link, proto.Port_B}) } else { link.bindKm(endKm, proto.Port_B) } //计算Link长度 - convertedKm, err := convertKilometer(repo, endKm, baseKm.CoordinateSystem) + convertedKm, err := convertKilometer(repo, endKm, linkZeroKm.CoordinateSystem) if err != nil { return err } - link.length = int64(math.Abs(float64(convertedKm.Value - baseKm.Value))) + link.length = int64(math.Abs(float64(convertedKm.Value - linkZeroKm.Value))) + //构建Link两端物理道岔区段在Link上的范围 + buildLinkRangeOfTurnoutPhysicalSection(link) repo.linkMap[link.Id()] = link } @@ -669,6 +671,7 @@ func findEndTurnoutPortOrEndKm(repo *Repository, link *Link, startTp *TurnoutPor return endTp, endKm, err } +// 关联正常(非道岔)物理区段与Link func relatePhysicalSectionAndLink(repo *Repository, section *PhysicalSection, link *Link, baseKm *proto.Kilometer) { link.bindPhysicalSections(section) aKm, _ := convertKilometer(repo, section.aKm, baseKm.CoordinateSystem) @@ -683,13 +686,7 @@ func relatePhysicalSectionAndLink(repo *Repository, section *PhysicalSection, li link: link, offset: bOffset, } - if aOffset <= bOffset { - section.startLinkPosition = section.aLinkPosition - section.endLinkPosition = section.bLinkPosition - } else { - section.startLinkPosition = section.bLinkPosition - section.endLinkPosition = section.aLinkPosition - } + section.bindLinkRange(link, aOffset, bOffset) } func getATurnoutPort(turnouts []*Turnout, visitedTurnoutMap map[string]bool) *TurnoutPort { @@ -744,18 +741,41 @@ func relateDevicesAndLink(repo *Repository, link *Link, startKm *proto.Kilometer return nil } -func interrelateLinkAndTurnout(repo *Repository, baseKm *proto.Kilometer, tp *TurnoutPort, linkPort *LinkPort) { +// 互相关联Link和道岔及道岔区段 +func interrelateLinkAndTurnout(repo *Repository, linkZeroKm *proto.Kilometer, tp *TurnoutPort, linkPort *LinkPort) { + //关联Link和道岔 tp.turnout.bindLinkPort(tp.port, linkPort) linkPort.link.bindTurnoutPort(linkPort.port, tp) tpKm := tp.turnout.findBoundaryKmByPort(tp.port) - tpKm, _ = convertKilometer(repo, tpKm, baseKm.CoordinateSystem) - offset := number.Abs(tpKm.Value - baseKm.Value) + tpKm, _ = convertKilometer(repo, tpKm, linkZeroKm.CoordinateSystem) + offset := number.Abs(tpKm.Value - linkZeroKm.Value) tp.turnout.bindLinkPosition(tp.port, &LinkPosition{ link: linkPort.link, offset: offset, }) } +// 构建Link关联道岔物理区段在Link上的范围 +func buildLinkRangeOfTurnoutPhysicalSection(link *Link) { + //解决[两道岔的道岔物理区段,两道岔间的Link会产生两个LinkRange]的问题 + if link.aRelation != nil && link.bRelation != nil && link.aRelation.turnout.section == link.bRelation.turnout.section { + section := link.aRelation.turnout.section + section.bindLinkRange(link, 0, link.length) + return + } + + if link.aRelation != nil { + aSection := link.aRelation.turnout.section //Link A端的关联的道岔物理区段 + aLinkPosition := link.aRelation.turnout.FindLinkPositionByPort(link.aRelation.port) //Link A端道岔端点在Link上的位置 + aSection.bindLinkRange(link, 0, aLinkPosition.offset) + } + if link.bRelation != nil { + bSection := link.bRelation.turnout.section //Link A端的关联的道岔物理区段 + bLinkPosition := link.bRelation.turnout.FindLinkPositionByPort(link.bRelation.port) //Link A端道岔端点在Link上的位置 + bSection.bindLinkRange(link, bLinkPosition.offset, link.length) + } +} + func findModelKm(model Identity) *proto.Kilometer { switch model.Type() { case proto.DeviceType_DeviceType_Signal: