rts-sim-module/repository/physical_section.go
2023-12-29 17:58:39 +08:00

210 lines
4.7 KiB
Go
Raw 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 repository
import (
"fmt"
"joylink.club/rtsssimulation/repository/model/proto"
"joylink.club/rtsssimulation/util/number"
)
// 物理区段
type PhysicalSection struct {
Identity
len int32 //长度 mm
checkPoints []*CheckPoint //将此区段分隔出来的所有(非区段边界)检测点
// A/B端关联的设备端口非道岔物理区段/道岔)
aRelation DevicePort
bRelation DevicePort
// 非道岔物理区段A/B端的公里标
aKm *proto.Kilometer
bKm *proto.Kilometer
turnouts []*Turnout //道岔物理区段关联的道岔
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
devices []Identity
//aKm/bKm对应的LinkPosition
aLinkPosition *LinkPosition
bLinkPosition *LinkPosition
//在Link上的区间start小于end
linkRanges []*LinkRange
//物理区段所属集中站
centralizedStation string
// 所属站台
platform *Platform
}
func NewPhysicalSection(id string) *PhysicalSection {
return &PhysicalSection{
Identity: identity{id, proto.DeviceType_DeviceType_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
}
func (s *PhysicalSection) ALinkPosition() *LinkPosition {
return s.aLinkPosition
}
func (s *PhysicalSection) BLinkPosition() *LinkPosition {
return s.bLinkPosition
}
func (s *PhysicalSection) ARelation() DevicePort {
return s.aRelation
}
func (s *PhysicalSection) BRelation() DevicePort {
return s.bRelation
}
func (s *PhysicalSection) AKilometer() *proto.Kilometer {
return s.aKm
}
func (s *PhysicalSection) BKilometer() *proto.Kilometer {
return s.bKm
}
// IsAxleSection 判断是否为计轴区段
func (s *PhysicalSection) IsAxleSection() (bool, error) {
if len(s.checkPoints) > 0 {
axleCount := 0
for _, cp := range s.checkPoints {
if cp.pointType == proto.CheckPointType_AxleCounter {
axleCount++
}
}
if axleCount == len(s.checkPoints) {
return true, nil
} else if axleCount == 0 {
return false, nil
} else { //axleCount>0&&axleCount<len(s.checkPoints)
return false, fmt.Errorf("物理区段中检测点不纯")
}
} else {
return false, fmt.Errorf("物理区段没有检测点")
}
}
func (s *PhysicalSection) CentralizedStation() string {
return s.centralizedStation
}
func (s *PhysicalSection) bindDevicePort(port proto.Port, devicePort DevicePort) error {
_, isSectionPort := devicePort.(*PhysicalSectionPort)
_, isTurnoutPort := devicePort.(*TurnoutPort)
if !isSectionPort && !isTurnoutPort {
return fmt.Errorf("物理区段不能与[%s]类型的设备端口关联", devicePort.Device().Type())
}
switch port {
case proto.Port_A:
s.aRelation = devicePort
case proto.Port_B:
s.bRelation = devicePort
default:
return fmt.Errorf("物理区段无端口[%s]", port)
}
return nil
}
// 绑定区段边界公里标。(仅限非道岔物理区段调用)
func (s *PhysicalSection) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
if km == nil || (km.CoordinateSystem == "" && km.Value == 0) {
return nil
}
switch port {
case proto.Port_A:
s.aKm = km
case proto.Port_B:
s.bKm = km
default:
return fmt.Errorf("区段无端口[%s]", port)
}
return nil
}
// 道岔物理区段绑定道岔
func (s *PhysicalSection) bindTurnouts(turnouts ...*Turnout) {
for _, turnout := range turnouts {
s.turnouts = append(s.turnouts, turnout)
for _, cp := range turnout.checkPoints() {
s.bindDevices(cp)
}
}
}
func (s *PhysicalSection) bindDevices(devices ...Identity) {
for _, device := range devices {
s.devices = append(s.devices, device)
cp, ok := device.(*CheckPoint)
if ok {
s.checkPoints = append(s.checkPoints, cp)
}
}
}
func (s *PhysicalSection) findOtherDevicePort(port proto.Port) DevicePort {
switch port {
case proto.Port_A:
return s.bRelation
case proto.Port_B:
return s.aRelation
}
return nil
}
func (s *PhysicalSection) findOtherBoundaryKmByPort(port proto.Port) *proto.Kilometer {
switch port {
case proto.Port_A:
return s.bKm
case proto.Port_B:
return s.aKm
}
return nil
}
func (s *PhysicalSection) findBoundaryKmByPort(port proto.Port) *proto.Kilometer {
switch port {
case proto.Port_A:
return s.aKm
case proto.Port_B:
return s.bKm
}
return nil
}
func (s *PhysicalSection) LinkRanges() []*LinkRange {
return s.linkRanges
}
func (p *PhysicalSection) Platform() *Platform {
return p.platform
}
type PhysicalSectionPort struct {
section *PhysicalSection
port proto.Port
}
func (p *PhysicalSectionPort) Port() proto.Port {
return p.port
}
func (p *PhysicalSectionPort) Device() PortedDevice {
return p.section
}