直接存储Proto的Message;创建仿真时由仿真模块构建模型;发给动力学的数据从仿真模块返回的Repository构建
This commit is contained in:
parent
25a8b6e47b
commit
4a910aa08f
@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"joylink.club/rtsssimulation/repository"
|
|
||||||
"joylink.club/rtsssimulation/repository/model/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Repo *repository.Repository
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
link := repository.NewLink("1")
|
|
||||||
fmt.Println(link)
|
|
||||||
|
|
||||||
lp := repository.NewLinkPort(link, proto.Port_A)
|
|
||||||
fmt.Println(lp)
|
|
||||||
|
|
||||||
Repo = repository.NewRepository("1" /* id */, "0.1" /* version */)
|
|
||||||
section := repository.NewPhysicalSection("s1")
|
|
||||||
fmt.Println(section)
|
|
||||||
Repo.AddPhysicalSection(section)
|
|
||||||
fmt.Println(Repo)
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
}
|
|
7
go.mod
7
go.mod
@ -2,4 +2,9 @@ module joylink.club/rtsssimulation
|
|||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require google.golang.org/protobuf v1.31.0
|
require (
|
||||||
|
github.com/yohamta/donburi v1.3.8
|
||||||
|
google.golang.org/protobuf v1.31.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require github.com/google/go-cmp v0.5.9 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -1,7 +1,7 @@
|
|||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/yohamta/donburi v1.3.8 h1:ca4NuhzJ8Jeb6GAEf6ecksa+l8JWaAnr0WLqG20TimU=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/ebitengine/purego v0.1.0/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
|
github.com/ebitengine/purego v0.1.0/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/hajimehoshi/ebiten/v2 v2.4.13/go.mod h1:BZcqCU4XHmScUi+lsKexocWcf4offMFwfp8dVGIB/G4=
|
github.com/hajimehoshi/ebiten/v2 v2.4.13/go.mod h1:BZcqCU4XHmScUi+lsKexocWcf4offMFwfp8dVGIB/G4=
|
||||||
github.com/hajimehoshi/file2byteslice v1.0.0/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
github.com/hajimehoshi/file2byteslice v1.0.0/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
||||||
github.com/jezek/xgb v1.0.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
github.com/jezek/xgb v1.0.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit adb9cf9a0005fc74565da8753f4f7577834d27d4
|
Subproject commit c3b9d965c607a2f29e0bdc586aba6851d4f29f13
|
@ -35,11 +35,18 @@ message CheckPoint{
|
|||||||
|
|
||||||
//道岔
|
//道岔
|
||||||
message Turnout {
|
message Turnout {
|
||||||
|
enum SwitchMachineType {
|
||||||
|
Unknown = 0;
|
||||||
|
ZDJ9_Single = 1;
|
||||||
|
ZDJ9_Double = 2;
|
||||||
|
}
|
||||||
string id = 1;
|
string id = 1;
|
||||||
Kilometer km = 2;
|
Kilometer km = 2;
|
||||||
DevicePort aDevicePort = 3;
|
DevicePort aDevicePort = 3;
|
||||||
DevicePort bDevicePort = 4;
|
DevicePort bDevicePort = 4;
|
||||||
DevicePort cDevicePort = 5;
|
DevicePort cDevicePort = 5;
|
||||||
|
SwitchMachineType switchMachineType = 6;
|
||||||
|
repeated string relayIds = 7; //道岔关联的继电器
|
||||||
}
|
}
|
||||||
|
|
||||||
//信号机
|
//信号机
|
||||||
@ -85,7 +92,7 @@ enum DeviceType {
|
|||||||
DeviceType_CheckPoint = 2;
|
DeviceType_CheckPoint = 2;
|
||||||
DeviceType_Turnout = 3;
|
DeviceType_Turnout = 3;
|
||||||
DeviceType_Signal = 4;
|
DeviceType_Signal = 4;
|
||||||
DeviceType_Responder = 5;
|
DeviceType_Transponder = 5;
|
||||||
DeviceType_Slope = 6;
|
DeviceType_Slope = 6;
|
||||||
DeviceType_SectionalCurvature = 7;
|
DeviceType_SectionalCurvature = 7;
|
||||||
DeviceType_Link = 8;
|
DeviceType_Link = 8;
|
||||||
@ -125,3 +132,12 @@ enum CheckPointType{
|
|||||||
AxleCounter = 1; //计轴器
|
AxleCounter = 1; //计轴器
|
||||||
InsulatedJoint = 2; //绝缘节
|
InsulatedJoint = 2; //绝缘节
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Relay {
|
||||||
|
enum Type {
|
||||||
|
Unknown = 0;
|
||||||
|
}
|
||||||
|
string id = 1;
|
||||||
|
string code = 2;
|
||||||
|
Type type = 3;
|
||||||
|
}
|
@ -8,15 +8,20 @@ type Transponder struct {
|
|||||||
km *proto.Kilometer
|
km *proto.Kilometer
|
||||||
//section *PhysicalSection
|
//section *PhysicalSection
|
||||||
//turnoutPort TurnoutPort
|
//turnoutPort TurnoutPort
|
||||||
|
linkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransponder(id string, km *proto.Kilometer) *Transponder {
|
func NewTransponder(id string, km *proto.Kilometer) *Transponder {
|
||||||
return &Transponder{
|
return &Transponder{
|
||||||
Identity: identity{id, proto.DeviceType_DeviceType_Responder},
|
Identity: identity{id, proto.DeviceType_DeviceType_Transponder},
|
||||||
km: km,
|
km: km,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Transponder) bindLinkPosition(position *LinkPosition) {
|
||||||
|
t.linkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
//func (r *Transponder) bindSection(section *PhysicalSection) {
|
//func (r *Transponder) bindSection(section *PhysicalSection) {
|
||||||
// r.section = section
|
// r.section = section
|
||||||
//}
|
//}
|
||||||
|
@ -9,6 +9,7 @@ type CheckPoint struct {
|
|||||||
km *proto.Kilometer
|
km *proto.Kilometer
|
||||||
pointType proto.CheckPointType //检测点类型
|
pointType proto.CheckPointType //检测点类型
|
||||||
devicePorts []DevicePort //检测点关联的设备及其端口
|
devicePorts []DevicePort //检测点关联的设备及其端口
|
||||||
|
linkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCheckPoint(id string, km *proto.Kilometer, pointType proto.CheckPointType) *CheckPoint {
|
func NewCheckPoint(id string, km *proto.Kilometer, pointType proto.CheckPointType) *CheckPoint {
|
||||||
@ -22,3 +23,7 @@ func NewCheckPoint(id string, km *proto.Kilometer, pointType proto.CheckPointTyp
|
|||||||
func (c *CheckPoint) bindDevicePort(devicePort DevicePort) {
|
func (c *CheckPoint) bindDevicePort(devicePort DevicePort) {
|
||||||
c.devicePorts = append(c.devicePorts, devicePort)
|
c.devicePorts = append(c.devicePorts, devicePort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CheckPoint) bindLinkPosition(position *LinkPosition) {
|
||||||
|
c.linkPosition = position
|
||||||
|
}
|
||||||
|
@ -11,14 +11,17 @@ type Link struct {
|
|||||||
|
|
||||||
length int64
|
length int64
|
||||||
|
|
||||||
aRelation *LinkNodePort
|
aRelation *TurnoutPort
|
||||||
bRelation *LinkNodePort
|
bRelation *TurnoutPort
|
||||||
|
|
||||||
aKm *proto.Kilometer
|
aKm *proto.Kilometer
|
||||||
bKm *proto.Kilometer
|
bKm *proto.Kilometer
|
||||||
|
|
||||||
//Link关联的模型,包含LinkNode
|
//Link上的模型((非区段边界)检测点、应答器、信号机、区段(为了位置换算方便))
|
||||||
devicePositions []*DeviceLinkPosition
|
devices []Identity
|
||||||
|
|
||||||
|
////Link关联的模型,包含LinkNode
|
||||||
|
//devicePositions []*DeviceLinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Identity = &Link{}
|
var _ Identity = &Link{}
|
||||||
@ -29,23 +32,40 @@ func NewLink(id string) *Link {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Link) Length() int64 {
|
||||||
|
return l.length
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Link) ARelation() *TurnoutPort {
|
||||||
|
return l.aRelation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Link) BRelation() *TurnoutPort {
|
||||||
|
return l.bRelation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Link) Devices() []Identity {
|
||||||
|
return l.devices
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Link) PortNum() int {
|
func (l *Link) PortNum() int {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
func (l *Link) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
||||||
linkNodePort, isLinkNodePort := devicePort.(*LinkNodePort)
|
turnoutPort, isTurnoutPort := devicePort.(*TurnoutPort)
|
||||||
if !isLinkNodePort {
|
if !isTurnoutPort {
|
||||||
return errors.New(fmt.Sprintf("Link不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
return errors.New(fmt.Sprintf("Link不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
||||||
}
|
}
|
||||||
switch port {
|
switch port {
|
||||||
case proto.Port_A:
|
case proto.Port_A:
|
||||||
l.aRelation = linkNodePort
|
l.aRelation = turnoutPort
|
||||||
case proto.Port_B:
|
case proto.Port_B:
|
||||||
l.bRelation = linkNodePort
|
l.bRelation = turnoutPort
|
||||||
default:
|
default:
|
||||||
return errors.New(fmt.Sprintf("Link没有端口[%s]", port))
|
return errors.New(fmt.Sprintf("Link没有端口[%s]", port))
|
||||||
}
|
}
|
||||||
|
l.bindKm(turnoutPort.turnout.km, port)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +78,9 @@ func (l *Link) bindKm(km *proto.Kilometer, port proto.Port) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) bindDevicesLinkPositions(dlps ...*DeviceLinkPosition) {
|
func (l *Link) bindDevices(devices ...Identity) {
|
||||||
for _, dlp := range dlps {
|
for _, device := range devices {
|
||||||
l.devicePositions = append(l.devicePositions, dlp)
|
l.devices = append(l.devices, device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,58 +111,12 @@ type LinkPosition struct {
|
|||||||
offset int64
|
offset int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeviceLinkPosition device在link上的位置
|
func (l *LinkPosition) Link() *Link {
|
||||||
type DeviceLinkPosition struct {
|
return l.link
|
||||||
device Identity
|
|
||||||
position LinkPosition
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SlopeLinkSegment Slope在Link上的区间
|
func (l *LinkPosition) Offset() int64 {
|
||||||
type SlopeLinkSegment struct {
|
return l.offset
|
||||||
slope *Slope
|
|
||||||
start *LinkPosition
|
|
||||||
end *LinkPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectionalCurvatureLinkSegment struct {
|
|
||||||
sectionalCurvature *SectionalCurvature
|
|
||||||
start *LinkPosition
|
|
||||||
end *LinkPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinkNode link节点
|
|
||||||
type LinkNode struct {
|
|
||||||
Identity
|
|
||||||
turnout *Turnout
|
|
||||||
aRelation LinkPort
|
|
||||||
bRelation LinkPort
|
|
||||||
cRelation LinkPort
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln LinkNode) Id() string {
|
|
||||||
return ln.turnout.Id()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln LinkNode) PortNum() int {
|
|
||||||
return 3
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln LinkNode) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
|
||||||
linkPort, isLinkPort := devicePort.(*LinkPort)
|
|
||||||
if !isLinkPort {
|
|
||||||
return errors.New(fmt.Sprintf("Link节点不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
|
||||||
}
|
|
||||||
switch port {
|
|
||||||
case proto.Port_A:
|
|
||||||
ln.aRelation = *linkPort
|
|
||||||
case proto.Port_B:
|
|
||||||
ln.bRelation = *linkPort
|
|
||||||
case proto.Port_C:
|
|
||||||
ln.cRelation = *linkPort
|
|
||||||
default:
|
|
||||||
return errors.New(fmt.Sprintf("Link节点没有端口[%s]", port))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// link端口
|
// link端口
|
||||||
@ -166,22 +140,88 @@ func (l *LinkPort) Device() PortedDevice {
|
|||||||
return l.link
|
return l.link
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinkNodePort struct {
|
//// DeviceLinkPosition device在link上的位置
|
||||||
node *LinkNode
|
//type DeviceLinkPosition struct {
|
||||||
port proto.Port
|
// device Identity
|
||||||
}
|
// position LinkPosition
|
||||||
|
//}
|
||||||
func NewLinkNodePort(node *LinkNode, port proto.Port) *LinkNodePort {
|
//
|
||||||
return &LinkNodePort{
|
//// SlopeLinkSegment Slope在Link上的区间
|
||||||
node: node,
|
//type SlopeLinkSegment struct {
|
||||||
port: port,
|
// slope *Slope
|
||||||
}
|
// start *LinkPosition
|
||||||
}
|
// end *LinkPosition
|
||||||
|
//}
|
||||||
func (lp *LinkNodePort) Port() proto.Port {
|
//
|
||||||
return lp.port
|
//func (s *SlopeLinkSegment) Slope() *Slope {
|
||||||
}
|
// return s.slope
|
||||||
|
//}
|
||||||
func (lp *LinkNodePort) Device() PortedDevice {
|
//
|
||||||
return lp.node
|
//func (s *SlopeLinkSegment) Start() *LinkPosition {
|
||||||
}
|
// return s.start
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (s *SlopeLinkSegment) End() *LinkPosition {
|
||||||
|
// return s.end
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type SectionalCurvatureLinkSegment struct {
|
||||||
|
// sectionalCurvature *SectionalCurvature
|
||||||
|
// start *LinkPosition
|
||||||
|
// end *LinkPosition
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// LinkNode link节点
|
||||||
|
//type LinkNode struct {
|
||||||
|
// Identity
|
||||||
|
// turnout *Turnout
|
||||||
|
// aRelation LinkPort
|
||||||
|
// bRelation LinkPort
|
||||||
|
// cRelation LinkPort
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (ln LinkNode) Id() string {
|
||||||
|
// return ln.turnout.Id()
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (ln LinkNode) PortNum() int {
|
||||||
|
// return 3
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (ln LinkNode) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
||||||
|
// linkPort, isLinkPort := devicePort.(*LinkPort)
|
||||||
|
// if !isLinkPort {
|
||||||
|
// return errors.New(fmt.Sprintf("Link节点不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
||||||
|
// }
|
||||||
|
// switch port {
|
||||||
|
// case proto.Port_A:
|
||||||
|
// ln.aRelation = *linkPort
|
||||||
|
// case proto.Port_B:
|
||||||
|
// ln.bRelation = *linkPort
|
||||||
|
// case proto.Port_C:
|
||||||
|
// ln.cRelation = *linkPort
|
||||||
|
// default:
|
||||||
|
// return errors.New(fmt.Sprintf("Link节点没有端口[%s]", port))
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type LinkNodePort struct {
|
||||||
|
// node *LinkNode
|
||||||
|
// port proto.Port
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func NewLinkNodePort(node *LinkNode, port proto.Port) *LinkNodePort {
|
||||||
|
// return &LinkNodePort{
|
||||||
|
// node: node,
|
||||||
|
// port: port,
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (lp *LinkNodePort) Port() proto.Port {
|
||||||
|
// return lp.port
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (lp *LinkNodePort) Device() PortedDevice {
|
||||||
|
// return lp.node
|
||||||
|
//}
|
||||||
|
@ -28,7 +28,7 @@ const (
|
|||||||
DeviceType_DeviceType_CheckPoint DeviceType = 2
|
DeviceType_DeviceType_CheckPoint DeviceType = 2
|
||||||
DeviceType_DeviceType_Turnout DeviceType = 3
|
DeviceType_DeviceType_Turnout DeviceType = 3
|
||||||
DeviceType_DeviceType_Signal DeviceType = 4
|
DeviceType_DeviceType_Signal DeviceType = 4
|
||||||
DeviceType_DeviceType_Responder DeviceType = 5
|
DeviceType_DeviceType_Transponder DeviceType = 5
|
||||||
DeviceType_DeviceType_Slope DeviceType = 6
|
DeviceType_DeviceType_Slope DeviceType = 6
|
||||||
DeviceType_DeviceType_SectionalCurvature DeviceType = 7
|
DeviceType_DeviceType_SectionalCurvature DeviceType = 7
|
||||||
DeviceType_DeviceType_Link DeviceType = 8
|
DeviceType_DeviceType_Link DeviceType = 8
|
||||||
@ -43,7 +43,7 @@ var (
|
|||||||
2: "DeviceType_CheckPoint",
|
2: "DeviceType_CheckPoint",
|
||||||
3: "DeviceType_Turnout",
|
3: "DeviceType_Turnout",
|
||||||
4: "DeviceType_Signal",
|
4: "DeviceType_Signal",
|
||||||
5: "DeviceType_Responder",
|
5: "DeviceType_Transponder",
|
||||||
6: "DeviceType_Slope",
|
6: "DeviceType_Slope",
|
||||||
7: "DeviceType_SectionalCurvature",
|
7: "DeviceType_SectionalCurvature",
|
||||||
8: "DeviceType_Link",
|
8: "DeviceType_Link",
|
||||||
@ -55,7 +55,7 @@ var (
|
|||||||
"DeviceType_CheckPoint": 2,
|
"DeviceType_CheckPoint": 2,
|
||||||
"DeviceType_Turnout": 3,
|
"DeviceType_Turnout": 3,
|
||||||
"DeviceType_Signal": 4,
|
"DeviceType_Signal": 4,
|
||||||
"DeviceType_Responder": 5,
|
"DeviceType_Transponder": 5,
|
||||||
"DeviceType_Slope": 6,
|
"DeviceType_Slope": 6,
|
||||||
"DeviceType_SectionalCurvature": 7,
|
"DeviceType_SectionalCurvature": 7,
|
||||||
"DeviceType_Link": 8,
|
"DeviceType_Link": 8,
|
||||||
@ -239,6 +239,98 @@ func (CheckPointType) EnumDescriptor() ([]byte, []int) {
|
|||||||
return file_model_proto_rawDescGZIP(), []int{3}
|
return file_model_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Turnout_SwitchMachineType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Turnout_Unknown Turnout_SwitchMachineType = 0
|
||||||
|
Turnout_ZDJ9_Single Turnout_SwitchMachineType = 1
|
||||||
|
Turnout_ZDJ9_Double Turnout_SwitchMachineType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for Turnout_SwitchMachineType.
|
||||||
|
var (
|
||||||
|
Turnout_SwitchMachineType_name = map[int32]string{
|
||||||
|
0: "Unknown",
|
||||||
|
1: "ZDJ9_Single",
|
||||||
|
2: "ZDJ9_Double",
|
||||||
|
}
|
||||||
|
Turnout_SwitchMachineType_value = map[string]int32{
|
||||||
|
"Unknown": 0,
|
||||||
|
"ZDJ9_Single": 1,
|
||||||
|
"ZDJ9_Double": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x Turnout_SwitchMachineType) Enum() *Turnout_SwitchMachineType {
|
||||||
|
p := new(Turnout_SwitchMachineType)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Turnout_SwitchMachineType) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Turnout_SwitchMachineType) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_model_proto_enumTypes[4].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Turnout_SwitchMachineType) Type() protoreflect.EnumType {
|
||||||
|
return &file_model_proto_enumTypes[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Turnout_SwitchMachineType) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Turnout_SwitchMachineType.Descriptor instead.
|
||||||
|
func (Turnout_SwitchMachineType) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_model_proto_rawDescGZIP(), []int{3, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Relay_Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Relay_Unknown Relay_Type = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for Relay_Type.
|
||||||
|
var (
|
||||||
|
Relay_Type_name = map[int32]string{
|
||||||
|
0: "Unknown",
|
||||||
|
}
|
||||||
|
Relay_Type_value = map[string]int32{
|
||||||
|
"Unknown": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x Relay_Type) Enum() *Relay_Type {
|
||||||
|
p := new(Relay_Type)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Relay_Type) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Relay_Type) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_model_proto_enumTypes[5].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Relay_Type) Type() protoreflect.EnumType {
|
||||||
|
return &file_model_proto_enumTypes[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Relay_Type) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Relay_Type.Descriptor instead.
|
||||||
|
func (Relay_Type) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_model_proto_rawDescGZIP(), []int{11, 0}
|
||||||
|
}
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -513,6 +605,8 @@ type Turnout struct {
|
|||||||
ADevicePort *DevicePort `protobuf:"bytes,3,opt,name=aDevicePort,proto3" json:"aDevicePort,omitempty"`
|
ADevicePort *DevicePort `protobuf:"bytes,3,opt,name=aDevicePort,proto3" json:"aDevicePort,omitempty"`
|
||||||
BDevicePort *DevicePort `protobuf:"bytes,4,opt,name=bDevicePort,proto3" json:"bDevicePort,omitempty"`
|
BDevicePort *DevicePort `protobuf:"bytes,4,opt,name=bDevicePort,proto3" json:"bDevicePort,omitempty"`
|
||||||
CDevicePort *DevicePort `protobuf:"bytes,5,opt,name=cDevicePort,proto3" json:"cDevicePort,omitempty"`
|
CDevicePort *DevicePort `protobuf:"bytes,5,opt,name=cDevicePort,proto3" json:"cDevicePort,omitempty"`
|
||||||
|
SwitchMachineType Turnout_SwitchMachineType `protobuf:"varint,6,opt,name=switchMachineType,proto3,enum=model.Turnout_SwitchMachineType" json:"switchMachineType,omitempty"`
|
||||||
|
RelayIds []string `protobuf:"bytes,7,rep,name=relayIds,proto3" json:"relayIds,omitempty"` //道岔关联的继电器
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Turnout) Reset() {
|
func (x *Turnout) Reset() {
|
||||||
@ -582,6 +676,20 @@ func (x *Turnout) GetCDevicePort() *DevicePort {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Turnout) GetSwitchMachineType() Turnout_SwitchMachineType {
|
||||||
|
if x != nil {
|
||||||
|
return x.SwitchMachineType
|
||||||
|
}
|
||||||
|
return Turnout_Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Turnout) GetRelayIds() []string {
|
||||||
|
if x != nil {
|
||||||
|
return x.RelayIds
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 信号机
|
// 信号机
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
@ -1046,6 +1154,69 @@ func (x *KilometerConvert) GetSameTrend() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Relay struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
|
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
|
||||||
|
Type Relay_Type `protobuf:"varint,3,opt,name=type,proto3,enum=model.Relay_Type" json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) Reset() {
|
||||||
|
*x = Relay{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_model_proto_msgTypes[11]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Relay) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Relay) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_model_proto_msgTypes[11]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Relay.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Relay) Descriptor() ([]byte, []int) {
|
||||||
|
return file_model_proto_rawDescGZIP(), []int{11}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) GetId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) GetCode() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Code
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) GetType() Relay_Type {
|
||||||
|
if x != nil {
|
||||||
|
return x.Type
|
||||||
|
}
|
||||||
|
return Relay_Unknown
|
||||||
|
}
|
||||||
|
|
||||||
var File_model_proto protoreflect.FileDescriptor
|
var File_model_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_model_proto_rawDesc = []byte{
|
var file_model_proto_rawDesc = []byte{
|
||||||
@ -1102,7 +1273,7 @@ var file_model_proto_rawDesc = []byte{
|
|||||||
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63,
|
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63,
|
||||||
0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d,
|
0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d,
|
||||||
0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52,
|
0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52,
|
||||||
0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0xda, 0x01, 0x0a,
|
0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x8a, 0x03, 0x0a,
|
||||||
0x07, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x75, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
0x07, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x75, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x02, 0x6b, 0x6d, 0x18, 0x02,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x02, 0x6b, 0x6d, 0x18, 0x02,
|
||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4b, 0x69, 0x6c,
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4b, 0x69, 0x6c,
|
||||||
@ -1116,7 +1287,18 @@ var file_model_proto_rawDesc = []byte{
|
|||||||
0x50, 0x6f, 0x72, 0x74, 0x12, 0x33, 0x0a, 0x0b, 0x63, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50,
|
0x50, 0x6f, 0x72, 0x74, 0x12, 0x33, 0x0a, 0x0b, 0x63, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50,
|
||||||
0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65,
|
0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65,
|
||||||
0x6c, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x63, 0x44,
|
0x6c, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x63, 0x44,
|
||||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x06, 0x53, 0x69,
|
0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x77, 0x69,
|
||||||
|
0x74, 0x63, 0x68, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06,
|
||||||
|
0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x54, 0x75, 0x72,
|
||||||
|
0x6e, 0x6f, 0x75, 0x74, 0x2e, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x63, 0x68, 0x69,
|
||||||
|
0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x11, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x4d, 0x61,
|
||||||
|
0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c,
|
||||||
|
0x61, 0x79, 0x49, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c,
|
||||||
|
0x61, 0x79, 0x49, 0x64, 0x73, 0x22, 0x42, 0x0a, 0x11, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x4d,
|
||||||
|
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e,
|
||||||
|
0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x44, 0x4a, 0x39, 0x5f,
|
||||||
|
0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x44, 0x4a, 0x39,
|
||||||
|
0x5f, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x10, 0x02, 0x22, 0x8d, 0x01, 0x0a, 0x06, 0x53, 0x69,
|
||||||
0x67, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
0x67, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x02, 0x6b, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x02, 0x6b, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||||
0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74,
|
0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74,
|
||||||
@ -1169,35 +1351,42 @@ var file_model_proto_rawDesc = []byte{
|
|||||||
0x42, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e,
|
0x42, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e,
|
||||||
0x4b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x03, 0x6b, 0x6d, 0x42, 0x12, 0x1c,
|
0x4b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x03, 0x6b, 0x6d, 0x42, 0x12, 0x1c,
|
||||||
0x0a, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
|
0x0a, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||||
0x08, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x2a, 0x8f, 0x02, 0x0a,
|
0x08, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x22, 0x67, 0x0a, 0x05,
|
||||||
0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44,
|
0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
|
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x6e, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70,
|
0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x74, 0x79, 0x70,
|
||||||
0x65, 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e,
|
||||||
0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70,
|
0x52, 0x65, 0x6c, 0x61, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||||
0x65, 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16,
|
0x22, 0x13, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e,
|
||||||
0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72,
|
0x6f, 0x77, 0x6e, 0x10, 0x00, 0x2a, 0x91, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||||
0x6e, 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x18, 0x0a,
|
0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a,
|
||||||
0x14, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x70,
|
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69,
|
||||||
0x6f, 0x6e, 0x64, 0x65, 0x72, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63,
|
0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15,
|
||||||
0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, 0x21, 0x0a,
|
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b,
|
||||||
0x1d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x63, 0x74,
|
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63,
|
||||||
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x07,
|
0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12,
|
||||||
0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c,
|
0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69,
|
||||||
0x69, 0x6e, 0x6b, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54,
|
0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||||
0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x25,
|
0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72,
|
||||||
0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00,
|
0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65,
|
||||||
0x12, 0x05, 0x0a, 0x01, 0x41, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05,
|
0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x65, 0x76, 0x69,
|
||||||
0x0a, 0x01, 0x43, 0x10, 0x03, 0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
|
0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
|
||||||
0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x45, 0x46, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
|
0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x44,
|
||||||
0x52, 0x49, 0x47, 0x48, 0x54, 0x10, 0x01, 0x2a, 0x43, 0x0a, 0x0e, 0x43, 0x68, 0x65, 0x63, 0x6b,
|
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x08,
|
||||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x75,
|
0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c,
|
||||||
0x6e, 0x64, 0x61, 0x72, 0x79, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x78, 0x6c, 0x65, 0x43,
|
0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x25, 0x0a, 0x04, 0x50, 0x6f, 0x72,
|
||||||
0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x75,
|
0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x05, 0x0a, 0x01, 0x41,
|
||||||
0x6c, 0x61, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x42, 0x1a, 0x5a, 0x18,
|
0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05, 0x0a, 0x01, 0x43, 0x10, 0x03,
|
||||||
0x2e, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x6f, 0x64,
|
0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a,
|
||||||
0x65, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x04, 0x4c, 0x45, 0x46, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54,
|
||||||
|
0x10, 0x01, 0x2a, 0x43, 0x0a, 0x0e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74,
|
||||||
|
0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79,
|
||||||
|
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x78, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
|
||||||
|
0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64,
|
||||||
|
0x4a, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x72, 0x65, 0x70,
|
||||||
|
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x70, 0x72,
|
||||||
|
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -1212,59 +1401,64 @@ func file_model_proto_rawDescGZIP() []byte {
|
|||||||
return file_model_proto_rawDescData
|
return file_model_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
|
||||||
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||||
var file_model_proto_goTypes = []interface{}{
|
var file_model_proto_goTypes = []interface{}{
|
||||||
(DeviceType)(0), // 0: model.DeviceType
|
(DeviceType)(0), // 0: model.DeviceType
|
||||||
(Port)(0), // 1: model.Port
|
(Port)(0), // 1: model.Port
|
||||||
(Direction)(0), // 2: model.Direction
|
(Direction)(0), // 2: model.Direction
|
||||||
(CheckPointType)(0), // 3: model.CheckPointType
|
(CheckPointType)(0), // 3: model.CheckPointType
|
||||||
(*Repository)(nil), // 4: model.Repository
|
(Turnout_SwitchMachineType)(0), // 4: model.Turnout.SwitchMachineType
|
||||||
(*PhysicalSection)(nil), // 5: model.PhysicalSection
|
(Relay_Type)(0), // 5: model.Relay.Type
|
||||||
(*CheckPoint)(nil), // 6: model.CheckPoint
|
(*Repository)(nil), // 6: model.Repository
|
||||||
(*Turnout)(nil), // 7: model.Turnout
|
(*PhysicalSection)(nil), // 7: model.PhysicalSection
|
||||||
(*Signal)(nil), // 8: model.Signal
|
(*CheckPoint)(nil), // 8: model.CheckPoint
|
||||||
(*Transponder)(nil), // 9: model.Transponder
|
(*Turnout)(nil), // 9: model.Turnout
|
||||||
(*Slope)(nil), // 10: model.Slope
|
(*Signal)(nil), // 10: model.Signal
|
||||||
(*SectionalCurvature)(nil), // 11: model.SectionalCurvature
|
(*Transponder)(nil), // 11: model.Transponder
|
||||||
(*DevicePort)(nil), // 12: model.DevicePort
|
(*Slope)(nil), // 12: model.Slope
|
||||||
(*Kilometer)(nil), // 13: model.Kilometer
|
(*SectionalCurvature)(nil), // 13: model.SectionalCurvature
|
||||||
(*KilometerConvert)(nil), // 14: model.KilometerConvert
|
(*DevicePort)(nil), // 14: model.DevicePort
|
||||||
|
(*Kilometer)(nil), // 15: model.Kilometer
|
||||||
|
(*KilometerConvert)(nil), // 16: model.KilometerConvert
|
||||||
|
(*Relay)(nil), // 17: model.Relay
|
||||||
}
|
}
|
||||||
var file_model_proto_depIdxs = []int32{
|
var file_model_proto_depIdxs = []int32{
|
||||||
5, // 0: model.Repository.physicalSections:type_name -> model.PhysicalSection
|
7, // 0: model.Repository.physicalSections:type_name -> model.PhysicalSection
|
||||||
6, // 1: model.Repository.checkPoints:type_name -> model.CheckPoint
|
8, // 1: model.Repository.checkPoints:type_name -> model.CheckPoint
|
||||||
7, // 2: model.Repository.turnouts:type_name -> model.Turnout
|
9, // 2: model.Repository.turnouts:type_name -> model.Turnout
|
||||||
8, // 3: model.Repository.signals:type_name -> model.Signal
|
10, // 3: model.Repository.signals:type_name -> model.Signal
|
||||||
9, // 4: model.Repository.transponders:type_name -> model.Transponder
|
11, // 4: model.Repository.transponders:type_name -> model.Transponder
|
||||||
10, // 5: model.Repository.slopes:type_name -> model.Slope
|
12, // 5: model.Repository.slopes:type_name -> model.Slope
|
||||||
11, // 6: model.Repository.sectionalCurvatures:type_name -> model.SectionalCurvature
|
13, // 6: model.Repository.sectionalCurvatures:type_name -> model.SectionalCurvature
|
||||||
14, // 7: model.Repository.kilometerConverts:type_name -> model.KilometerConvert
|
16, // 7: model.Repository.kilometerConverts:type_name -> model.KilometerConvert
|
||||||
12, // 8: model.PhysicalSection.aDevicePort:type_name -> model.DevicePort
|
14, // 8: model.PhysicalSection.aDevicePort:type_name -> model.DevicePort
|
||||||
12, // 9: model.PhysicalSection.bDevicePort:type_name -> model.DevicePort
|
14, // 9: model.PhysicalSection.bDevicePort:type_name -> model.DevicePort
|
||||||
13, // 10: model.CheckPoint.km:type_name -> model.Kilometer
|
15, // 10: model.CheckPoint.km:type_name -> model.Kilometer
|
||||||
3, // 11: model.CheckPoint.type:type_name -> model.CheckPointType
|
3, // 11: model.CheckPoint.type:type_name -> model.CheckPointType
|
||||||
12, // 12: model.CheckPoint.devicePorts:type_name -> model.DevicePort
|
14, // 12: model.CheckPoint.devicePorts:type_name -> model.DevicePort
|
||||||
13, // 13: model.Turnout.km:type_name -> model.Kilometer
|
15, // 13: model.Turnout.km:type_name -> model.Kilometer
|
||||||
12, // 14: model.Turnout.aDevicePort:type_name -> model.DevicePort
|
14, // 14: model.Turnout.aDevicePort:type_name -> model.DevicePort
|
||||||
12, // 15: model.Turnout.bDevicePort:type_name -> model.DevicePort
|
14, // 15: model.Turnout.bDevicePort:type_name -> model.DevicePort
|
||||||
12, // 16: model.Turnout.cDevicePort:type_name -> model.DevicePort
|
14, // 16: model.Turnout.cDevicePort:type_name -> model.DevicePort
|
||||||
13, // 17: model.Signal.km:type_name -> model.Kilometer
|
4, // 17: model.Turnout.switchMachineType:type_name -> model.Turnout.SwitchMachineType
|
||||||
12, // 18: model.Signal.turnoutPort:type_name -> model.DevicePort
|
15, // 18: model.Signal.km:type_name -> model.Kilometer
|
||||||
13, // 19: model.Transponder.km:type_name -> model.Kilometer
|
14, // 19: model.Signal.turnoutPort:type_name -> model.DevicePort
|
||||||
12, // 20: model.Transponder.turnoutPort:type_name -> model.DevicePort
|
15, // 20: model.Transponder.km:type_name -> model.Kilometer
|
||||||
13, // 21: model.Slope.kms:type_name -> model.Kilometer
|
14, // 21: model.Transponder.turnoutPort:type_name -> model.DevicePort
|
||||||
13, // 22: model.SectionalCurvature.kms:type_name -> model.Kilometer
|
15, // 22: model.Slope.kms:type_name -> model.Kilometer
|
||||||
0, // 23: model.DevicePort.deviceType:type_name -> model.DeviceType
|
15, // 23: model.SectionalCurvature.kms:type_name -> model.Kilometer
|
||||||
1, // 24: model.DevicePort.port:type_name -> model.Port
|
0, // 24: model.DevicePort.deviceType:type_name -> model.DeviceType
|
||||||
2, // 25: model.Kilometer.direction:type_name -> model.Direction
|
1, // 25: model.DevicePort.port:type_name -> model.Port
|
||||||
13, // 26: model.KilometerConvert.kmA:type_name -> model.Kilometer
|
2, // 26: model.Kilometer.direction:type_name -> model.Direction
|
||||||
13, // 27: model.KilometerConvert.kmB:type_name -> model.Kilometer
|
15, // 27: model.KilometerConvert.kmA:type_name -> model.Kilometer
|
||||||
28, // [28:28] is the sub-list for method output_type
|
15, // 28: model.KilometerConvert.kmB:type_name -> model.Kilometer
|
||||||
28, // [28:28] is the sub-list for method input_type
|
5, // 29: model.Relay.type:type_name -> model.Relay.Type
|
||||||
28, // [28:28] is the sub-list for extension type_name
|
30, // [30:30] is the sub-list for method output_type
|
||||||
28, // [28:28] is the sub-list for extension extendee
|
30, // [30:30] is the sub-list for method input_type
|
||||||
0, // [0:28] is the sub-list for field type_name
|
30, // [30:30] is the sub-list for extension type_name
|
||||||
|
30, // [30:30] is the sub-list for extension extendee
|
||||||
|
0, // [0:30] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_model_proto_init() }
|
func init() { file_model_proto_init() }
|
||||||
@ -1405,14 +1599,26 @@ func file_model_proto_init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_model_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Relay); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_model_proto_rawDesc,
|
RawDescriptor: file_model_proto_rawDesc,
|
||||||
NumEnums: 4,
|
NumEnums: 6,
|
||||||
NumMessages: 11,
|
NumMessages: 12,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
@ -17,7 +17,7 @@ type PhysicalSection struct {
|
|||||||
aRelation DevicePort
|
aRelation DevicePort
|
||||||
bRelation DevicePort
|
bRelation DevicePort
|
||||||
|
|
||||||
// 非道岔物理区段A/B端区段边界的公里标
|
// 非道岔物理区段A/B端的公里标
|
||||||
aKm *proto.Kilometer
|
aKm *proto.Kilometer
|
||||||
bKm *proto.Kilometer
|
bKm *proto.Kilometer
|
||||||
|
|
||||||
@ -25,6 +25,10 @@ type PhysicalSection struct {
|
|||||||
|
|
||||||
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
|
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
|
||||||
devices []Identity
|
devices []Identity
|
||||||
|
|
||||||
|
//在Link上的区间(根据aKm和bKm计算出的)
|
||||||
|
startLinkPosition *LinkPosition
|
||||||
|
endLinkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPhysicalSection(id string) *PhysicalSection {
|
func NewPhysicalSection(id string) *PhysicalSection {
|
||||||
@ -87,6 +91,14 @@ func (s *PhysicalSection) bindDevices(devices ...Identity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PhysicalSection) bindStartLinkPosition(position *LinkPosition) {
|
||||||
|
s.startLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PhysicalSection) bindEndLinkPosition(position *LinkPosition) {
|
||||||
|
s.endLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PhysicalSection) ARelation() DevicePort {
|
func (s *PhysicalSection) ARelation() DevicePort {
|
||||||
return s.aRelation
|
return s.aRelation
|
||||||
}
|
}
|
||||||
@ -125,6 +137,14 @@ func (s *PhysicalSection) findBoundaryKmByPort(port proto.Port) *proto.Kilometer
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PhysicalSection) StartLinkPosition() *LinkPosition {
|
||||||
|
return s.startLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PhysicalSection) EndLinkPosition() *LinkPosition {
|
||||||
|
return s.endLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
type PhysicalSectionPort struct {
|
type PhysicalSectionPort struct {
|
||||||
section *PhysicalSection
|
section *PhysicalSection
|
||||||
port proto.Port
|
port proto.Port
|
||||||
|
@ -17,10 +17,16 @@ type Repository struct {
|
|||||||
slopeMap map[string]*Slope
|
slopeMap map[string]*Slope
|
||||||
sectionalCurvatureMap map[string]*SectionalCurvature
|
sectionalCurvatureMap map[string]*SectionalCurvature
|
||||||
|
|
||||||
|
linkMap map[string]*Link
|
||||||
|
//devicePositionMap map[string]*DeviceLinkPosition //key为device的id
|
||||||
|
//linkNodeMap map[string]*LinkNode //LinkNode的id应该没什么意义,所以此处key用LinkNode中Turnout的id
|
||||||
|
//slopeLinkSegmentMap map[string]*SlopeLinkSegment
|
||||||
|
//sectionalCurvatureLinkSegmentMap map[string]*SectionalCurvatureLinkSegment
|
||||||
|
|
||||||
kilometerConvertMap map[string]*proto.KilometerConvert
|
kilometerConvertMap map[string]*proto.KilometerConvert
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(id string, version string) *Repository {
|
func newRepository(id string, version string) *Repository {
|
||||||
return &Repository{
|
return &Repository{
|
||||||
id: id,
|
id: id,
|
||||||
version: version,
|
version: version,
|
||||||
@ -32,10 +38,79 @@ func NewRepository(id string, version string) *Repository {
|
|||||||
responderMap: make(map[string]*Transponder),
|
responderMap: make(map[string]*Transponder),
|
||||||
slopeMap: make(map[string]*Slope),
|
slopeMap: make(map[string]*Slope),
|
||||||
sectionalCurvatureMap: make(map[string]*SectionalCurvature),
|
sectionalCurvatureMap: make(map[string]*SectionalCurvature),
|
||||||
|
linkMap: make(map[string]*Link),
|
||||||
|
//devicePositionMap: make(map[string]*DeviceLinkPosition),
|
||||||
|
//linkNodeMap: make(map[string]*LinkNode),
|
||||||
|
//slopeLinkSegmentMap: make(map[string]*SlopeLinkSegment),
|
||||||
|
//sectionalCurvatureLinkSegmentMap: make(map[string]*SectionalCurvatureLinkSegment),
|
||||||
kilometerConvertMap: make(map[string]*proto.KilometerConvert),
|
kilometerConvertMap: make(map[string]*proto.KilometerConvert),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) PhysicalSectionList() []*PhysicalSection {
|
||||||
|
var list []*PhysicalSection
|
||||||
|
for _, model := range repo.physicalSectionMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) CheckPointList() []*CheckPoint {
|
||||||
|
var list []*CheckPoint
|
||||||
|
for _, model := range repo.checkPointMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) TurnoutList() []*Turnout {
|
||||||
|
var list []*Turnout
|
||||||
|
for _, model := range repo.turnoutMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) SignalList() []*Signal {
|
||||||
|
var list []*Signal
|
||||||
|
for _, model := range repo.signalMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) ResponderList() []*Transponder {
|
||||||
|
var list []*Transponder
|
||||||
|
for _, model := range repo.responderMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) SlopeList() []*Slope {
|
||||||
|
var list []*Slope
|
||||||
|
for _, model := range repo.slopeMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) SectionalCurvatureList() []*SectionalCurvature {
|
||||||
|
var list []*SectionalCurvature
|
||||||
|
for _, model := range repo.sectionalCurvatureMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) LinkList() []*Link {
|
||||||
|
var list []*Link
|
||||||
|
for _, model := range repo.linkMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func (repo *Repository) KilometerConvertList() []*proto.KilometerConvert {
|
||||||
|
var list []*proto.KilometerConvert
|
||||||
|
for _, model := range repo.kilometerConvertMap {
|
||||||
|
list = append(list, model)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *Repository) getModel(deviceId string, deviceType proto.DeviceType) (Identity, error) {
|
func (repo *Repository) getModel(deviceId string, deviceType proto.DeviceType) (Identity, error) {
|
||||||
switch deviceType {
|
switch deviceType {
|
||||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||||
@ -46,73 +121,25 @@ func (repo *Repository) getModel(deviceId string, deviceType proto.DeviceType) (
|
|||||||
return repo.turnoutMap[deviceId], nil
|
return repo.turnoutMap[deviceId], nil
|
||||||
case proto.DeviceType_DeviceType_Signal:
|
case proto.DeviceType_DeviceType_Signal:
|
||||||
return repo.signalMap[deviceId], nil
|
return repo.signalMap[deviceId], nil
|
||||||
case proto.DeviceType_DeviceType_Responder:
|
case proto.DeviceType_DeviceType_Transponder:
|
||||||
return repo.responderMap[deviceId], nil
|
return repo.responderMap[deviceId], nil
|
||||||
case proto.DeviceType_DeviceType_Slope:
|
case proto.DeviceType_DeviceType_Slope:
|
||||||
return repo.slopeMap[deviceId], nil
|
return repo.slopeMap[deviceId], nil
|
||||||
case proto.DeviceType_DeviceType_SectionalCurvature:
|
case proto.DeviceType_DeviceType_SectionalCurvature:
|
||||||
return repo.sectionalCurvatureMap[deviceId], nil
|
return repo.sectionalCurvatureMap[deviceId], nil
|
||||||
|
case proto.DeviceType_DeviceType_Link:
|
||||||
|
return repo.linkMap[deviceId], nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New(fmt.Sprintf("仓库中不存在[%s]类型的模型", deviceType))
|
return nil, errors.New(fmt.Sprintf("仓库中不存在[%s]类型的模型", deviceType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) PhysicalSectionList() []*PhysicalSection {
|
func (repo *Repository) FindLink(id string) *Link {
|
||||||
list := make([]*PhysicalSection, len(repo.physicalSectionMap))
|
return repo.linkMap[id]
|
||||||
for _, m := range repo.physicalSectionMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repository) TurnoutList() []*Turnout {
|
|
||||||
list := make([]*Turnout, 0)
|
|
||||||
for _, m := range repo.turnoutMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repository) SignalList() []*Signal {
|
|
||||||
list := make([]*Signal, len(repo.signalMap))
|
|
||||||
for _, m := range repo.signalMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repository) ResponderList() []*Transponder {
|
|
||||||
list := make([]*Transponder, len(repo.responderMap))
|
|
||||||
for _, m := range repo.responderMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repository) SlopeList() []*Slope {
|
|
||||||
list := make([]*Slope, len(repo.slopeMap))
|
|
||||||
for _, m := range repo.slopeMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repository) SectionalCurvatureList() []*SectionalCurvature {
|
|
||||||
list := make([]*SectionalCurvature, len(repo.sectionalCurvatureMap))
|
|
||||||
for _, m := range repo.sectionalCurvatureMap {
|
|
||||||
list = append(list, m)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) AddPhysicalSection(section *PhysicalSection) {
|
func (repo *Repository) AddPhysicalSection(section *PhysicalSection) {
|
||||||
repo.physicalSectionMap[section.Id()] = section
|
repo.physicalSectionMap[section.Id()] = section
|
||||||
//repo.modelMap[section.Id()] = section
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildKilometerConvertKey(cs1 string, cs2 string, dir1 proto.Direction, dir2 proto.Direction) string {
|
|
||||||
return cs1 + dir1.String() + cs2 + dir2.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) addKilometerConvert(kc *proto.KilometerConvert) {
|
func (repo *Repository) addKilometerConvert(kc *proto.KilometerConvert) {
|
||||||
@ -127,3 +154,7 @@ func (repo *Repository) getKilometerConvert(cs1, cs2 string, dir1, dir2 proto.Di
|
|||||||
}
|
}
|
||||||
return convert, nil
|
return convert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildKilometerConvertKey(cs1 string, cs2 string, dir1 proto.Direction, dir2 proto.Direction) string {
|
||||||
|
return cs1 + dir1.String() + cs2 + dir2.String()
|
||||||
|
}
|
||||||
|
@ -1,336 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"joylink.club/rtsssimulation/repository/model/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
var repositoryMap = make(map[string]*Repository)
|
|
||||||
|
|
||||||
func BuildRepository(source *proto.Repository) (*Repository, error) {
|
|
||||||
repository := NewRepository(source.Id, source.Version)
|
|
||||||
buildModels(source, repository)
|
|
||||||
err := buildModelRelationship(source, repository)
|
|
||||||
if err == nil {
|
|
||||||
repositoryMap[buildRepositoryKey(source.Id, source.Version)] = repository
|
|
||||||
}
|
|
||||||
return repository, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildRepositoryKey(id string, version string) string {
|
|
||||||
return id + "_" + version
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRepository(id string, version string) (*Repository, error) {
|
|
||||||
repository := repositoryMap[buildRepositoryKey(id, version)]
|
|
||||||
if repository == nil {
|
|
||||||
return repository, errors.New(fmt.Sprintf("%s-%s的仓库未找到", id, version))
|
|
||||||
}
|
|
||||||
return repository, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildModels(source *proto.Repository, repository *Repository) {
|
|
||||||
for _, protoData := range source.KilometerConverts {
|
|
||||||
repository.addKilometerConvert(protoData)
|
|
||||||
}
|
|
||||||
for _, protoData := range source.PhysicalSections {
|
|
||||||
m := NewPhysicalSection(protoData.Id)
|
|
||||||
repository.physicalSectionMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.CheckPoints {
|
|
||||||
m := NewCheckPoint(protoData.Id, protoData.Km, protoData.Type)
|
|
||||||
repository.checkPointMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.Turnouts {
|
|
||||||
m := NewTurnout(protoData.Id, protoData.Km)
|
|
||||||
repository.turnoutMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.Signals {
|
|
||||||
m := NewSignal(protoData.Id, protoData.Km)
|
|
||||||
repository.signalMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.Transponders {
|
|
||||||
m := NewTransponder(protoData.Id, protoData.Km)
|
|
||||||
repository.responderMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.Slopes {
|
|
||||||
m := NewSlope(protoData.Id, protoData.Kms, protoData.Degree)
|
|
||||||
repository.slopeMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
for _, protoData := range source.SectionalCurvatures {
|
|
||||||
m := NewSectionalCurvature(protoData.Id, protoData.Kms, protoData.Radius)
|
|
||||||
repository.sectionalCurvatureMap[m.Id()] = m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildModelRelationship(source *proto.Repository, repository *Repository) error {
|
|
||||||
err := buildCheckPointRelationShip(source, repository)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildPhysicalSectionRelationShip(source, repository)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildTurnoutRelationShip(source, repository)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildSignalRelationShip(source, repository)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildResponderRelationShip(source, repository)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildCheckPointRelationShip(source *proto.Repository, repo *Repository) error {
|
|
||||||
for _, protoData := range source.CheckPoints {
|
|
||||||
cp := repo.checkPointMap[protoData.Id]
|
|
||||||
isBoundary := protoData.Type == proto.CheckPointType_Boundary
|
|
||||||
for _, protoDp := range protoData.DevicePorts {
|
|
||||||
switch protoDp.DeviceType {
|
|
||||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
|
||||||
section := repo.physicalSectionMap[protoDp.DeviceId]
|
|
||||||
if isBoundary { //是区段边界
|
|
||||||
err := section.bindBoundaryKm(cp.km, protoDp.Port)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//检测点关联区段端口
|
|
||||||
cp.bindDevicePort(&PhysicalSectionPort{
|
|
||||||
section: section,
|
|
||||||
port: protoDp.Port,
|
|
||||||
})
|
|
||||||
//区段关联检测点
|
|
||||||
section.bindDevices(cp)
|
|
||||||
//如果区段边界未设置
|
|
||||||
if section.findBoundaryKmByPort(protoDp.Port) == nil {
|
|
||||||
if err := section.bindBoundaryKm(cp.km, protoDp.Port); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case proto.DeviceType_DeviceType_Turnout:
|
|
||||||
turnout := repo.turnoutMap[protoDp.DeviceId]
|
|
||||||
if isBoundary { //是区段边界
|
|
||||||
err := turnout.bindBoundaryKm(cp.km, protoDp.Port)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//检测点关联道岔端口
|
|
||||||
cp.bindDevicePort(&TurnoutPort{
|
|
||||||
turnout: turnout,
|
|
||||||
port: protoDp.Port,
|
|
||||||
})
|
|
||||||
//道岔关联检测点
|
|
||||||
turnout.bindDevice(cp, protoDp.Port)
|
|
||||||
//如果区段边界未设置
|
|
||||||
if turnout.findBoundaryKmByPort(protoDp.Port) == nil {
|
|
||||||
if err := turnout.bindBoundaryKm(cp.km, protoDp.Port); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildResponderRelationShip(source *proto.Repository, repository *Repository) error {
|
|
||||||
for _, protoData := range source.Transponders {
|
|
||||||
responder := repository.responderMap[protoData.Id]
|
|
||||||
//应答器和区段相互关联
|
|
||||||
if protoData.SectionId != "" {
|
|
||||||
interrelateResponderAndPhysicalSection(responder, repository.physicalSectionMap[protoData.SectionId])
|
|
||||||
}
|
|
||||||
//应答器和道岔相互关联
|
|
||||||
tp := protoData.TurnoutPort
|
|
||||||
if tp != nil {
|
|
||||||
if tp.DeviceType != proto.DeviceType_DeviceType_Turnout {
|
|
||||||
return errors.New(fmt.Sprintf("应答器[%s]关联的[%s-%s-%s]并非道岔端口",
|
|
||||||
responder.Id(), tp.DeviceId, tp.DeviceType, tp.Port))
|
|
||||||
}
|
|
||||||
interrelateResponderAndTurnout(responder, repository.turnoutMap[tp.DeviceId], tp.Port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildSignalRelationShip(source *proto.Repository, repository *Repository) error {
|
|
||||||
for _, protoData := range source.Signals {
|
|
||||||
signal := repository.signalMap[protoData.Id]
|
|
||||||
//信号机和区段相互关联
|
|
||||||
if protoData.SectionId != "" {
|
|
||||||
interrelateSignalAndPhysicalSection(signal, repository.physicalSectionMap[protoData.SectionId])
|
|
||||||
}
|
|
||||||
//信号机和道岔相互关联
|
|
||||||
tp := protoData.TurnoutPort
|
|
||||||
if tp != nil {
|
|
||||||
if tp.DeviceType != proto.DeviceType_DeviceType_Turnout {
|
|
||||||
return errors.New(fmt.Sprintf("信号机[%s]关联的[%s-%s-%s]并非道岔端口",
|
|
||||||
signal.Id(), tp.DeviceId, tp.DeviceType, tp.Port))
|
|
||||||
}
|
|
||||||
interrelateSignalAndTurnout(signal, repository.turnoutMap[tp.DeviceId], tp.Port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTurnoutRelationShip(source *proto.Repository, repo *Repository) error {
|
|
||||||
for _, protoData := range source.Turnouts {
|
|
||||||
turnout := repo.turnoutMap[protoData.Id]
|
|
||||||
err := buildTurnoutPortRelation(repo, turnout, proto.Port_A, protoData.ADevicePort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildTurnoutPortRelation(repo, turnout, proto.Port_B, protoData.BDevicePort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = buildTurnoutPortRelation(repo, turnout, proto.Port_C, protoData.CDevicePort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTurnoutPortRelation(repo *Repository, turnout *Turnout, port proto.Port, protoDp *proto.DevicePort) error {
|
|
||||||
model, err := repo.getModel(protoDp.DeviceId, protoDp.DeviceType)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dp, err := buildDevicePort(model, protoDp.Port)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = turnout.bindDevicePort(port, dp)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildPhysicalSectionRelationShip(source *proto.Repository, repository *Repository) error {
|
|
||||||
for _, protoData := range source.PhysicalSections {
|
|
||||||
section := repository.physicalSectionMap[protoData.Id]
|
|
||||||
//A端关联
|
|
||||||
if protoData.ADevicePort != nil {
|
|
||||||
err := buildSectionPortRelation(repository, section, proto.Port_A, protoData.ADevicePort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//B端关联
|
|
||||||
if protoData.BDevicePort != nil {
|
|
||||||
err := buildSectionPortRelation(repository, section, proto.Port_B, protoData.BDevicePort)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//道岔关联
|
|
||||||
for _, turnoutId := range protoData.TurnoutIds {
|
|
||||||
turnout := repository.turnoutMap[turnoutId]
|
|
||||||
if turnout == nil {
|
|
||||||
return errors.New(fmt.Sprintf("id[%s]的道岔不存在", turnoutId))
|
|
||||||
}
|
|
||||||
section.bindTurnouts(turnout)
|
|
||||||
turnout.section = section
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建物理区段指定端口的关联关系。区段{section}的{port}端口关联{protoDp}
|
|
||||||
func buildSectionPortRelation(repo *Repository, section *PhysicalSection, port proto.Port, protoDp *proto.DevicePort) error {
|
|
||||||
model, err := repo.getModel(protoDp.DeviceId, protoDp.DeviceType)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dp, err := buildDevicePort(model, protoDp.Port)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = section.bindDevicePort(port, dp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildDevicePort(device Identity, port proto.Port) (DevicePort, error) {
|
|
||||||
var dp DevicePort
|
|
||||||
switch device.Type() {
|
|
||||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
|
||||||
section := device.(*PhysicalSection)
|
|
||||||
dp = &PhysicalSectionPort{
|
|
||||||
section: section,
|
|
||||||
port: port,
|
|
||||||
}
|
|
||||||
case proto.DeviceType_DeviceType_Turnout:
|
|
||||||
turnout := device.(*Turnout)
|
|
||||||
dp = &TurnoutPort{
|
|
||||||
turnout: turnout,
|
|
||||||
port: port,
|
|
||||||
}
|
|
||||||
case proto.DeviceType_DeviceType_Link:
|
|
||||||
link := device.(*Link)
|
|
||||||
dp = &LinkPort{
|
|
||||||
link: link,
|
|
||||||
port: port,
|
|
||||||
}
|
|
||||||
case proto.DeviceType_DeviceType_LinkNode:
|
|
||||||
linkNode := device.(*LinkNode)
|
|
||||||
dp = &LinkNodePort{
|
|
||||||
node: linkNode,
|
|
||||||
port: port,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, errors.New(fmt.Sprintf("[%s]类型设备没有端口", device.Type()))
|
|
||||||
}
|
|
||||||
return dp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相互关联道岔和检测点
|
|
||||||
func interrelateTurnoutAndCheckPoints(turnout *Turnout, point *CheckPoint, port proto.Port) {
|
|
||||||
turnout.bindDevice(point, port)
|
|
||||||
point.bindDevicePort(&TurnoutPort{
|
|
||||||
turnout: turnout,
|
|
||||||
port: port,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相互关联物理区段和信号机
|
|
||||||
func interrelateSignalAndPhysicalSection(signal *Signal, section *PhysicalSection) {
|
|
||||||
section.bindDevices(signal)
|
|
||||||
//signal.bindSection(section)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相互关联信号机和道岔
|
|
||||||
func interrelateSignalAndTurnout(signal *Signal, turnout *Turnout, port proto.Port) {
|
|
||||||
//signal.bindTurnoutPort(TurnoutPort{
|
|
||||||
// turnout: turnout,
|
|
||||||
// port: port,
|
|
||||||
//})
|
|
||||||
turnout.bindDevice(signal, port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相互关联应答器和物理区段
|
|
||||||
func interrelateResponderAndPhysicalSection(responder *Transponder, section *PhysicalSection) {
|
|
||||||
//responder.bindSection(section)
|
|
||||||
section.bindDevices(responder)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相互关联应答器和道岔
|
|
||||||
func interrelateResponderAndTurnout(responder *Transponder, turnout *Turnout, port proto.Port) {
|
|
||||||
//responder.bindTurnoutPort(TurnoutPort{
|
|
||||||
// turnout: turnout,
|
|
||||||
// port: port,
|
|
||||||
//})
|
|
||||||
turnout.bindDevice(responder, port)
|
|
||||||
}
|
|
661
repository/repository_manager.go
Normal file
661
repository/repository_manager.go
Normal file
@ -0,0 +1,661 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"joylink.club/rtsssimulation/repository/model/proto"
|
||||||
|
"joylink.club/rtsssimulation/util/number"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repositoryMap = make(map[string]*Repository)
|
||||||
|
|
||||||
|
func BuildRepository(source *proto.Repository) (*Repository, error) {
|
||||||
|
repository := newRepository(source.Id, source.Version)
|
||||||
|
buildModels(source, repository)
|
||||||
|
err := buildModelRelationship(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = buildLinksAndRelate(repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repositoryMap[buildRepositoryKey(source.Id, source.Version)] = repository
|
||||||
|
return repository, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindRepository(id string, version string) *Repository {
|
||||||
|
return repositoryMap[buildRepositoryKey(id, version)]
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildRepositoryKey(id string, version string) string {
|
||||||
|
return id + "_" + version
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildModels(source *proto.Repository, repository *Repository) {
|
||||||
|
for _, protoData := range source.KilometerConverts {
|
||||||
|
repository.addKilometerConvert(protoData)
|
||||||
|
}
|
||||||
|
for _, protoData := range source.PhysicalSections {
|
||||||
|
m := NewPhysicalSection(protoData.Id)
|
||||||
|
repository.physicalSectionMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.CheckPoints {
|
||||||
|
m := NewCheckPoint(protoData.Id, protoData.Km, protoData.Type)
|
||||||
|
repository.checkPointMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.Turnouts {
|
||||||
|
m := NewTurnout(protoData.Id, protoData.Km)
|
||||||
|
repository.turnoutMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.Signals {
|
||||||
|
m := NewSignal(protoData.Id, protoData.Km)
|
||||||
|
repository.signalMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.Transponders {
|
||||||
|
m := NewTransponder(protoData.Id, protoData.Km)
|
||||||
|
repository.responderMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.Slopes {
|
||||||
|
m := NewSlope(protoData.Id, protoData.Kms, protoData.Degree)
|
||||||
|
repository.slopeMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
for _, protoData := range source.SectionalCurvatures {
|
||||||
|
m := NewSectionalCurvature(protoData.Id, protoData.Kms, protoData.Radius)
|
||||||
|
repository.sectionalCurvatureMap[m.Id()] = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildModelRelationship(source *proto.Repository, repository *Repository) error {
|
||||||
|
err := buildCheckPointRelationShip(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildPhysicalSectionRelationShip(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildTurnoutRelationShip(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildSignalRelationShip(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildResponderRelationShip(source, repository)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildCheckPointRelationShip(source *proto.Repository, repo *Repository) error {
|
||||||
|
for _, protoData := range source.CheckPoints {
|
||||||
|
cp := repo.checkPointMap[protoData.Id]
|
||||||
|
isBoundary := protoData.Type == proto.CheckPointType_Boundary
|
||||||
|
for _, protoDp := range protoData.DevicePorts {
|
||||||
|
switch protoDp.DeviceType {
|
||||||
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||||
|
section := repo.physicalSectionMap[protoDp.DeviceId]
|
||||||
|
if isBoundary { //是区段边界
|
||||||
|
err := section.bindBoundaryKm(cp.km, protoDp.Port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//检测点关联区段端口
|
||||||
|
cp.bindDevicePort(&PhysicalSectionPort{
|
||||||
|
section: section,
|
||||||
|
port: protoDp.Port,
|
||||||
|
})
|
||||||
|
//区段关联检测点
|
||||||
|
section.bindDevices(cp)
|
||||||
|
//如果区段边界未设置
|
||||||
|
if section.findBoundaryKmByPort(protoDp.Port) == nil {
|
||||||
|
if err := section.bindBoundaryKm(cp.km, protoDp.Port); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case proto.DeviceType_DeviceType_Turnout:
|
||||||
|
turnout := repo.turnoutMap[protoDp.DeviceId]
|
||||||
|
if isBoundary { //是区段边界
|
||||||
|
err := turnout.bindBoundaryKm(cp.km, protoDp.Port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//检测点关联道岔端口
|
||||||
|
cp.bindDevicePort(&TurnoutPort{
|
||||||
|
turnout: turnout,
|
||||||
|
port: protoDp.Port,
|
||||||
|
})
|
||||||
|
//道岔关联检测点
|
||||||
|
turnout.bindDevice(cp, protoDp.Port)
|
||||||
|
//如果区段边界未设置
|
||||||
|
if turnout.findBoundaryKmByPort(protoDp.Port) == nil {
|
||||||
|
if err := turnout.bindBoundaryKm(cp.km, protoDp.Port); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildResponderRelationShip(source *proto.Repository, repository *Repository) error {
|
||||||
|
for _, protoData := range source.Transponders {
|
||||||
|
responder := repository.responderMap[protoData.Id]
|
||||||
|
//应答器和区段相互关联
|
||||||
|
if protoData.SectionId != "" {
|
||||||
|
interrelateResponderAndPhysicalSection(responder, repository.physicalSectionMap[protoData.SectionId])
|
||||||
|
}
|
||||||
|
//应答器和道岔相互关联
|
||||||
|
tp := protoData.TurnoutPort
|
||||||
|
if tp != nil {
|
||||||
|
if tp.DeviceType != proto.DeviceType_DeviceType_Turnout {
|
||||||
|
return errors.New(fmt.Sprintf("应答器[%s]关联的[%s-%s-%s]并非道岔端口",
|
||||||
|
responder.Id(), tp.DeviceId, tp.DeviceType, tp.Port))
|
||||||
|
}
|
||||||
|
interrelateResponderAndTurnout(responder, repository.turnoutMap[tp.DeviceId], tp.Port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSignalRelationShip(source *proto.Repository, repository *Repository) error {
|
||||||
|
for _, protoData := range source.Signals {
|
||||||
|
signal := repository.signalMap[protoData.Id]
|
||||||
|
//信号机和区段相互关联
|
||||||
|
if protoData.SectionId != "" {
|
||||||
|
interrelateSignalAndPhysicalSection(signal, repository.physicalSectionMap[protoData.SectionId])
|
||||||
|
}
|
||||||
|
//信号机和道岔相互关联
|
||||||
|
tp := protoData.TurnoutPort
|
||||||
|
if tp != nil {
|
||||||
|
if tp.DeviceType != proto.DeviceType_DeviceType_Turnout {
|
||||||
|
return errors.New(fmt.Sprintf("信号机[%s]关联的[%s-%s-%s]并非道岔端口",
|
||||||
|
signal.Id(), tp.DeviceId, tp.DeviceType, tp.Port))
|
||||||
|
}
|
||||||
|
interrelateSignalAndTurnout(signal, repository.turnoutMap[tp.DeviceId], tp.Port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildTurnoutRelationShip(source *proto.Repository, repo *Repository) error {
|
||||||
|
for _, protoData := range source.Turnouts {
|
||||||
|
turnout := repo.turnoutMap[protoData.Id]
|
||||||
|
err := buildTurnoutPortRelation(repo, turnout, proto.Port_A, protoData.ADevicePort)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildTurnoutPortRelation(repo, turnout, proto.Port_B, protoData.BDevicePort)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = buildTurnoutPortRelation(repo, turnout, proto.Port_C, protoData.CDevicePort)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildTurnoutPortRelation(repo *Repository, turnout *Turnout, port proto.Port, protoDp *proto.DevicePort) error {
|
||||||
|
model, err := repo.getModel(protoDp.DeviceId, protoDp.DeviceType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dp, err := buildDevicePort(model, protoDp.Port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = turnout.bindDevicePort(port, dp)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildPhysicalSectionRelationShip(source *proto.Repository, repository *Repository) error {
|
||||||
|
for _, protoData := range source.PhysicalSections {
|
||||||
|
section := repository.physicalSectionMap[protoData.Id]
|
||||||
|
//A端关联
|
||||||
|
if protoData.ADevicePort != nil {
|
||||||
|
err := buildSectionPortRelation(repository, section, proto.Port_A, protoData.ADevicePort)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//B端关联
|
||||||
|
if protoData.BDevicePort != nil {
|
||||||
|
err := buildSectionPortRelation(repository, section, proto.Port_B, protoData.BDevicePort)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//道岔关联
|
||||||
|
for _, turnoutId := range protoData.TurnoutIds {
|
||||||
|
turnout := repository.turnoutMap[turnoutId]
|
||||||
|
if turnout == nil {
|
||||||
|
return errors.New(fmt.Sprintf("id[%s]的道岔不存在", turnoutId))
|
||||||
|
}
|
||||||
|
section.bindTurnouts(turnout)
|
||||||
|
turnout.section = section
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建物理区段指定端口的关联关系。区段{section}的{port}端口关联{protoDp}
|
||||||
|
func buildSectionPortRelation(repo *Repository, section *PhysicalSection, port proto.Port, protoDp *proto.DevicePort) error {
|
||||||
|
model, err := repo.getModel(protoDp.DeviceId, protoDp.DeviceType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dp, err := buildDevicePort(model, protoDp.Port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = section.bindDevicePort(port, dp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildDevicePort(device Identity, port proto.Port) (DevicePort, error) {
|
||||||
|
var dp DevicePort
|
||||||
|
switch device.Type() {
|
||||||
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||||
|
section := device.(*PhysicalSection)
|
||||||
|
dp = &PhysicalSectionPort{
|
||||||
|
section: section,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
case proto.DeviceType_DeviceType_Turnout:
|
||||||
|
turnout := device.(*Turnout)
|
||||||
|
dp = &TurnoutPort{
|
||||||
|
turnout: turnout,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
case proto.DeviceType_DeviceType_Link:
|
||||||
|
link := device.(*Link)
|
||||||
|
dp = &LinkPort{
|
||||||
|
link: link,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New(fmt.Sprintf("[%s]类型设备没有端口", device.Type()))
|
||||||
|
}
|
||||||
|
return dp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相互关联道岔和检测点
|
||||||
|
func interrelateTurnoutAndCheckPoints(turnout *Turnout, point *CheckPoint, port proto.Port) {
|
||||||
|
turnout.bindDevice(point, port)
|
||||||
|
point.bindDevicePort(&TurnoutPort{
|
||||||
|
turnout: turnout,
|
||||||
|
port: port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相互关联物理区段和信号机
|
||||||
|
func interrelateSignalAndPhysicalSection(signal *Signal, section *PhysicalSection) {
|
||||||
|
section.bindDevices(signal)
|
||||||
|
//signal.bindSection(section)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相互关联信号机和道岔
|
||||||
|
func interrelateSignalAndTurnout(signal *Signal, turnout *Turnout, port proto.Port) {
|
||||||
|
//signal.bindTurnoutPort(TurnoutPort{
|
||||||
|
// turnout: turnout,
|
||||||
|
// port: port,
|
||||||
|
//})
|
||||||
|
turnout.bindDevice(signal, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相互关联应答器和物理区段
|
||||||
|
func interrelateResponderAndPhysicalSection(responder *Transponder, section *PhysicalSection) {
|
||||||
|
//responder.bindSection(section)
|
||||||
|
section.bindDevices(responder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相互关联应答器和道岔
|
||||||
|
func interrelateResponderAndTurnout(responder *Transponder, turnout *Turnout, port proto.Port) {
|
||||||
|
//responder.bindTurnoutPort(TurnoutPort{
|
||||||
|
// turnout: turnout,
|
||||||
|
// port: port,
|
||||||
|
//})
|
||||||
|
turnout.bindDevice(responder, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildLinksAndRelate(repo *Repository) error {
|
||||||
|
//构建link
|
||||||
|
err := buildLinks(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//Slope关联Link
|
||||||
|
err = slopeRelateLink(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//SectionalCurvature关联Link
|
||||||
|
err = sectionalCurvatureRelateLink(repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//PhysicalSection关联Link
|
||||||
|
err = physicalSectionRelateLink(repo)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildLinks(repo *Repository) error {
|
||||||
|
visitedTurnoutPortMap := make(map[string]bool)
|
||||||
|
allTurnouts := repo.TurnoutList()
|
||||||
|
linkIdGenerator := 10000
|
||||||
|
for {
|
||||||
|
//找一个未遍历过的道岔端口
|
||||||
|
startTp := getATurnoutPort(allTurnouts, visitedTurnoutPortMap)
|
||||||
|
if startTp == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
//以始端道岔的公里标作为公里标换算的基准
|
||||||
|
baseKm := startTp.turnout.km
|
||||||
|
//创建基础Link
|
||||||
|
link := &Link{
|
||||||
|
Identity: identity{
|
||||||
|
id: strconv.Itoa(linkIdGenerator), //由于发给动力学的link的id是数字,所以这里也用数字
|
||||||
|
deviceType: proto.DeviceType_DeviceType_Link,
|
||||||
|
}}
|
||||||
|
linkIdGenerator++
|
||||||
|
//以此道岔端口作为Link的A端节点
|
||||||
|
err := interrelateLinkAndTurnout(startTp, &LinkPort{link, proto.Port_A})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//沿着道岔端口方向,一直寻找到轨道尽头或者下一个道岔端口。构建并关联中间的设备在link上的位置
|
||||||
|
endTp, endKm, err := findEndTurnoutPortOrEndKm(repo, link, startTp, baseKm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//以下一个道岔端口作为Link的B端节点
|
||||||
|
if endTp != nil {
|
||||||
|
visitedTurnoutPortMap[buildTurnoutPortKey(endTp)] = true
|
||||||
|
endKm = endTp.turnout.km
|
||||||
|
err = interrelateLinkAndTurnout(endTp, &LinkPort{link, proto.Port_B})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
link.bindKm(endKm, proto.Port_B)
|
||||||
|
}
|
||||||
|
//计算Link长度
|
||||||
|
convertedKm, err := convertKilometer(repo, endKm, baseKm.CoordinateSystem, baseKm.Direction)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
link.length = int64(math.Abs(float64(convertedKm.Value - baseKm.Value)))
|
||||||
|
|
||||||
|
repo.linkMap[link.Id()] = link
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findEndTurnoutPortOrEndKm(repo *Repository, link *Link, startTp *TurnoutPort,
|
||||||
|
baseKm *proto.Kilometer) (*TurnoutPort, *proto.Kilometer, error) {
|
||||||
|
|
||||||
|
var endTp *TurnoutPort
|
||||||
|
var endKm *proto.Kilometer
|
||||||
|
var err error
|
||||||
|
|
||||||
|
visitedModelMap := make(map[string]bool)
|
||||||
|
var currentDp DevicePort = startTp
|
||||||
|
devices := startTp.turnout.getDevicesByPort(startTp.port)
|
||||||
|
for {
|
||||||
|
//遍历设备并构建、关联其在Link上的位置
|
||||||
|
err = buildAndRelateDeviceLinkPositions(repo, link, baseKm, visitedModelMap, devices...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
//顺着端口寻找下一个设备端口
|
||||||
|
var nextDp DevicePort
|
||||||
|
switch currentDp.Device().Type() {
|
||||||
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||||
|
section := currentDp.Device().(*PhysicalSection)
|
||||||
|
nextDp = section.findOtherDevicePort(currentDp.Port())
|
||||||
|
if nextDp == nil {
|
||||||
|
endKm = section.findOtherBoundaryKmByPort(currentDp.Port())
|
||||||
|
}
|
||||||
|
case proto.DeviceType_DeviceType_Turnout:
|
||||||
|
turnout := currentDp.Device().(*Turnout)
|
||||||
|
nextDp = turnout.getDevicePortByPort(currentDp.Port())
|
||||||
|
if nextDp == nil {
|
||||||
|
endKm = turnout.findBoundaryKmByPort(currentDp.Port())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//根据下一个端口设备的信息决定是否结束循环
|
||||||
|
if nextDp == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
currentDp = nextDp
|
||||||
|
var nextIsTp bool
|
||||||
|
switch nextDp.Device().Type() {
|
||||||
|
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||||
|
devices = nextDp.Device().(*PhysicalSection).devices
|
||||||
|
case proto.DeviceType_DeviceType_Turnout:
|
||||||
|
nextIsTp = true
|
||||||
|
endTp = nextDp.(*TurnoutPort)
|
||||||
|
devices = nextDp.Device().(*Turnout).getDevicesByPort(nextDp.Port())
|
||||||
|
err = buildAndRelateDeviceLinkPositions(repo, link, baseKm, visitedModelMap, devices...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nextIsTp {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endTp, endKm, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getATurnoutPort(turnouts []*Turnout, visitedTurnoutMap map[string]bool) *TurnoutPort {
|
||||||
|
portSlice := []proto.Port{proto.Port_A, proto.Port_B, proto.Port_C}
|
||||||
|
for _, turnout := range turnouts {
|
||||||
|
for _, port := range portSlice {
|
||||||
|
tp := &TurnoutPort{
|
||||||
|
turnout: turnout,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
key := buildTurnoutPortKey(tp)
|
||||||
|
if !visitedTurnoutMap[key] {
|
||||||
|
visitedTurnoutMap[key] = true
|
||||||
|
return tp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildTurnoutPortKey(tp *TurnoutPort) string {
|
||||||
|
return fmt.Sprintf("%v-%s", tp.turnout, tp.port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildAndRelateDeviceLinkPositions(repo *Repository, link *Link, startKm *proto.Kilometer, visitedModelMap map[string]bool, devices ...Identity) error {
|
||||||
|
for _, device := range devices {
|
||||||
|
if visitedModelMap[device.Id()] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
km := findModelKm(device)
|
||||||
|
if km == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
link.bindDevices(device)
|
||||||
|
convertedKm, err := convertKilometer(repo, km, startKm.CoordinateSystem, startKm.Direction)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
offset := int64(math.Abs(float64(convertedKm.Value - startKm.Value)))
|
||||||
|
linkPosition := &LinkPosition{
|
||||||
|
link: link,
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
switch device.Type() {
|
||||||
|
case proto.DeviceType_DeviceType_CheckPoint:
|
||||||
|
device.(*CheckPoint).bindLinkPosition(linkPosition)
|
||||||
|
case proto.DeviceType_DeviceType_Signal:
|
||||||
|
device.(*Signal).bindLinkPosition(linkPosition)
|
||||||
|
case proto.DeviceType_DeviceType_Transponder:
|
||||||
|
device.(*Transponder).bindLinkPosition(linkPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func interrelateLinkAndTurnout(tp *TurnoutPort, linkPort *LinkPort) error {
|
||||||
|
tp.turnout.bindLinkPort(tp.port, linkPort)
|
||||||
|
return linkPort.link.bindDevicePort(linkPort.port, tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func findModelKm(model Identity) *proto.Kilometer {
|
||||||
|
switch model.Type() {
|
||||||
|
case proto.DeviceType_DeviceType_Signal:
|
||||||
|
return model.(*Signal).km
|
||||||
|
case proto.DeviceType_DeviceType_Transponder:
|
||||||
|
return model.(*Transponder).km
|
||||||
|
case proto.DeviceType_DeviceType_CheckPoint:
|
||||||
|
return model.(*CheckPoint).km
|
||||||
|
case proto.DeviceType_DeviceType_Turnout:
|
||||||
|
return model.(*Turnout).km
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func slopeRelateLink(repo *Repository) error {
|
||||||
|
slopeMap := repo.slopeMap
|
||||||
|
for _, slope := range slopeMap {
|
||||||
|
start, end, err := calculateLinkSegment(repo, slope.kms[0], slope.kms[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
slope.bindStartLinkPosition(start)
|
||||||
|
slope.bindEndLinkPosition(end)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateLinkSegment(repo *Repository, startKm *proto.Kilometer,
|
||||||
|
endKm *proto.Kilometer) (*LinkPosition, *LinkPosition, error) {
|
||||||
|
|
||||||
|
endKm, err := convertKilometer(repo, endKm, startKm.CoordinateSystem, startKm.Direction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var start *LinkPosition
|
||||||
|
var end *LinkPosition
|
||||||
|
var minKmValue float64
|
||||||
|
var minKmLink *Link
|
||||||
|
var maxKmValue float64
|
||||||
|
var maxKmLink *Link
|
||||||
|
for _, link := range repo.linkMap {
|
||||||
|
//将link两端的公里标转为aKm同坐标系的公里标
|
||||||
|
linkAKm, err := convertKilometer(repo, link.aKm, startKm.CoordinateSystem, startKm.Direction)
|
||||||
|
if err != nil || linkAKm.Direction != startKm.Direction {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
linkBKm, err := convertKilometer(repo, link.bKm, startKm.CoordinateSystem, startKm.Direction)
|
||||||
|
if err != nil || linkBKm.Direction != startKm.Direction {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//记录公里标最小/最大的Link
|
||||||
|
newMinKmValue := math.Min(float64(linkAKm.Value), float64(linkBKm.Value))
|
||||||
|
newMaxKmValue := math.Max(float64(linkAKm.Value), float64(linkBKm.Value))
|
||||||
|
if minKmLink == nil || newMinKmValue < minKmValue {
|
||||||
|
minKmValue = newMinKmValue
|
||||||
|
minKmLink = link
|
||||||
|
}
|
||||||
|
if maxKmLink == nil || newMaxKmValue > maxKmValue {
|
||||||
|
maxKmValue = newMaxKmValue
|
||||||
|
maxKmLink = link
|
||||||
|
}
|
||||||
|
//若start/end公里标落在link上,构建LinkPosition
|
||||||
|
if number.IsBetween(startKm.Value, linkAKm.Value, linkBKm.Value) {
|
||||||
|
start = &LinkPosition{
|
||||||
|
link: link,
|
||||||
|
offset: int64(math.Abs(float64(startKm.Value - linkAKm.Value))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if number.IsBetween(endKm.Value, linkAKm.Value, linkBKm.Value) {
|
||||||
|
end = &LinkPosition{
|
||||||
|
link: link,
|
||||||
|
offset: int64(math.Abs(float64(endKm.Value - linkAKm.Value))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if start != nil && end != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//处理start/end公里标没落在Link上的情况
|
||||||
|
if start == nil {
|
||||||
|
if startKm.Value < endKm.Value {
|
||||||
|
offset, _ := minKmLink.findEndOffset()
|
||||||
|
start = &LinkPosition{
|
||||||
|
link: minKmLink,
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset, _ := maxKmLink.findEndOffset()
|
||||||
|
start = &LinkPosition{
|
||||||
|
link: maxKmLink,
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if end == nil {
|
||||||
|
if endKm.Value < startKm.Value {
|
||||||
|
offset, _ := minKmLink.findEndOffset()
|
||||||
|
end = &LinkPosition{
|
||||||
|
link: minKmLink,
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset, _ := maxKmLink.findEndOffset()
|
||||||
|
end = &LinkPosition{
|
||||||
|
link: maxKmLink,
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return start, end, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sectionalCurvatureRelateLink(repo *Repository) error {
|
||||||
|
for _, curvature := range repo.sectionalCurvatureMap {
|
||||||
|
start, end, err := calculateLinkSegment(repo, curvature.kms[0], curvature.kms[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
curvature.bindStartLinkPosition(start)
|
||||||
|
curvature.bindEndLinkPosition(end)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func physicalSectionRelateLink(repo *Repository) error {
|
||||||
|
for _, section := range repo.physicalSectionMap {
|
||||||
|
start, end, err := calculateLinkSegment(repo, section.aKm, section.bKm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
section.bindStartLinkPosition(start)
|
||||||
|
section.bindEndLinkPosition(end)
|
||||||
|
section.startLinkPosition.link.bindDevices(section)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import "joylink.club/rtsssimulation/repository/model/proto"
|
|
||||||
|
|
||||||
type Responder struct {
|
|
||||||
Identity
|
|
||||||
|
|
||||||
km *proto.Kilometer
|
|
||||||
section *PhysicalSection
|
|
||||||
turnoutPort TurnoutPort
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewResponder(id string, km *proto.Kilometer) *Responder {
|
|
||||||
return &Responder{
|
|
||||||
Identity: identity{id, proto.DeviceType_DeviceType_Responder},
|
|
||||||
km: km,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Responder) bindSection(section *PhysicalSection) {
|
|
||||||
r.section = section
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Responder) bindTurnoutPort(turnoutPort TurnoutPort) {
|
|
||||||
r.turnoutPort = turnoutPort
|
|
||||||
}
|
|
@ -6,6 +6,8 @@ type SectionalCurvature struct {
|
|||||||
Identity
|
Identity
|
||||||
kms []*proto.Kilometer
|
kms []*proto.Kilometer
|
||||||
radius int32 //半径 mm
|
radius int32 //半径 mm
|
||||||
|
startLinkPosition *LinkPosition
|
||||||
|
endLinkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSectionalCurvature(id string, kms []*proto.Kilometer, radius int32) *SectionalCurvature {
|
func NewSectionalCurvature(id string, kms []*proto.Kilometer, radius int32) *SectionalCurvature {
|
||||||
@ -15,3 +17,23 @@ func NewSectionalCurvature(id string, kms []*proto.Kilometer, radius int32) *Sec
|
|||||||
radius: radius,
|
radius: radius,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SectionalCurvature) bindStartLinkPosition(position *LinkPosition) {
|
||||||
|
s.startLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SectionalCurvature) bindEndLinkPosition(position *LinkPosition) {
|
||||||
|
s.endLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SectionalCurvature) StartLinkPosition() *LinkPosition {
|
||||||
|
return s.startLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SectionalCurvature) EndLinkPosition() *LinkPosition {
|
||||||
|
return s.endLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SectionalCurvature) Radius() int32 {
|
||||||
|
return s.radius
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ type Signal struct {
|
|||||||
km *proto.Kilometer
|
km *proto.Kilometer
|
||||||
//section *PhysicalSection
|
//section *PhysicalSection
|
||||||
//turnoutPort TurnoutPort
|
//turnoutPort TurnoutPort
|
||||||
|
linkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSignal(id string, km *proto.Kilometer) *Signal {
|
func NewSignal(id string, km *proto.Kilometer) *Signal {
|
||||||
@ -17,6 +18,10 @@ func NewSignal(id string, km *proto.Kilometer) *Signal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Signal) bindLinkPosition(position *LinkPosition) {
|
||||||
|
s.linkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
//func (s *Signal) bindSection(section *PhysicalSection) {
|
//func (s *Signal) bindSection(section *PhysicalSection) {
|
||||||
// s.section = section
|
// s.section = section
|
||||||
//}
|
//}
|
||||||
|
@ -1,387 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"joylink.club/rtsssimulation/repository/model/proto"
|
|
||||||
"joylink.club/rtsssimulation/util"
|
|
||||||
"math"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var simId = 1
|
|
||||||
|
|
||||||
func BuildSimulation(id string, version string) (*Simulation, error) {
|
|
||||||
repository, err := getRepository(id, version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
simulation := newSimulation(repository)
|
|
||||||
//构建link
|
|
||||||
err = buildLinks(simulation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//构建Slope的Link区间
|
|
||||||
err = buildSlopeLinkSegments(simulation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//构建SectionalCurvature的Link区间
|
|
||||||
err = buildSectionalCurvatureLinkSegments(simulation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return simulation, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getASimulationId() string {
|
|
||||||
id := strconv.Itoa(simId)
|
|
||||||
simId++
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
type Simulation struct {
|
|
||||||
id string
|
|
||||||
idGenerator int
|
|
||||||
repository *Repository
|
|
||||||
linkMap map[string]*Link
|
|
||||||
devicePositionMap map[string]*DeviceLinkPosition //key为device的id
|
|
||||||
linkNodeMap map[string]*LinkNode //LinkNode的id应该没什么意义,所以此处key用LinkNode中Turnout的id
|
|
||||||
slopeLinkSegmentMap map[string]SlopeLinkSegment
|
|
||||||
sectionalCurvatureLinkSegmentMap map[string]SectionalCurvatureLinkSegment
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSimulation(repository *Repository) *Simulation {
|
|
||||||
return &Simulation{
|
|
||||||
id: getASimulationId(),
|
|
||||||
idGenerator: 1,
|
|
||||||
repository: repository,
|
|
||||||
linkMap: make(map[string]*Link),
|
|
||||||
devicePositionMap: make(map[string]*DeviceLinkPosition),
|
|
||||||
linkNodeMap: make(map[string]*LinkNode),
|
|
||||||
slopeLinkSegmentMap: make(map[string]SlopeLinkSegment),
|
|
||||||
sectionalCurvatureLinkSegmentMap: make(map[string]SectionalCurvatureLinkSegment),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Simulation) getAId() string {
|
|
||||||
id := strconv.Itoa(s.idGenerator)
|
|
||||||
s.idGenerator++
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildLinks(sim *Simulation) error {
|
|
||||||
visitedTurnoutPortMap := make(map[string]bool)
|
|
||||||
allTurnouts := sim.repository.TurnoutList()
|
|
||||||
for {
|
|
||||||
//找一个未遍历过的道岔端口
|
|
||||||
startTp := getATurnoutPort(allTurnouts, visitedTurnoutPortMap)
|
|
||||||
if startTp == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
//以始端道岔的公里标作为公里标换算的基准
|
|
||||||
baseKm := startTp.turnout.km
|
|
||||||
//创建基础Link
|
|
||||||
link := &Link{Identity: identity{sim.getAId(), proto.DeviceType_DeviceType_Link}}
|
|
||||||
//以此道岔端口作为Link的A端节点
|
|
||||||
err := buildAndRelateLinkNode(sim, startTp, link, proto.Port_A)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//沿着道岔端口方向,一直寻找到轨道尽头或者下一个道岔端口。构建并关联中间的设备在link上的位置
|
|
||||||
endTp, endKm, err := findEndTurnoutPortOrEndKm(sim, link, startTp, baseKm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//以下一个道岔端口作为Link的B端节点
|
|
||||||
if endTp != nil {
|
|
||||||
visitedTurnoutPortMap[buildTurnoutPortKey(endTp)] = true
|
|
||||||
endKm = endTp.turnout.km
|
|
||||||
err = buildAndRelateLinkNode(sim, endTp, link, proto.Port_B)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//计算Link长度
|
|
||||||
convertedKm, err := convertKilometer(sim.repository, endKm, baseKm.CoordinateSystem, baseKm.Direction)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
link.length = int64(math.Abs(float64(convertedKm.Value - baseKm.Value)))
|
|
||||||
|
|
||||||
sim.linkMap[link.Id()] = link
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findEndTurnoutPortOrEndKm(sim *Simulation, link *Link, startTp *TurnoutPort,
|
|
||||||
baseKm *proto.Kilometer) (*TurnoutPort, *proto.Kilometer, error) {
|
|
||||||
|
|
||||||
var endTp *TurnoutPort
|
|
||||||
var endKm *proto.Kilometer
|
|
||||||
var err error
|
|
||||||
|
|
||||||
visitedModelMap := make(map[string]bool)
|
|
||||||
var currentDp DevicePort = startTp
|
|
||||||
devices := startTp.turnout.getDevicesByPort(startTp.port)
|
|
||||||
for {
|
|
||||||
//遍历设备并构建、关联其在Link上的位置
|
|
||||||
err = buildAndRelateDeviceLinkPositions(sim, link, baseKm, visitedModelMap, devices...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
//顺着端口寻找下一个设备端口
|
|
||||||
var nextDp DevicePort
|
|
||||||
switch currentDp.Device().Type() {
|
|
||||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
|
||||||
section := currentDp.Device().(*PhysicalSection)
|
|
||||||
nextDp = section.findOtherDevicePort(currentDp.Port())
|
|
||||||
if nextDp == nil {
|
|
||||||
endKm = section.findOtherBoundaryKmByPort(currentDp.Port())
|
|
||||||
}
|
|
||||||
case proto.DeviceType_DeviceType_Turnout:
|
|
||||||
turnout := currentDp.Device().(*Turnout)
|
|
||||||
nextDp = turnout.getDevicePortByPort(currentDp.Port())
|
|
||||||
if nextDp == nil {
|
|
||||||
endKm = turnout.findBoundaryKmByPort(currentDp.Port())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//根据下一个端口设备的信息决定是否结束循环
|
|
||||||
if nextDp == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
currentDp = nextDp
|
|
||||||
var nextIsTp bool
|
|
||||||
switch nextDp.Device().Type() {
|
|
||||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
|
||||||
devices = nextDp.Device().(*PhysicalSection).devices
|
|
||||||
case proto.DeviceType_DeviceType_Turnout:
|
|
||||||
nextIsTp = true
|
|
||||||
endTp = nextDp.(*TurnoutPort)
|
|
||||||
devices = nextDp.Device().(*Turnout).getDevicesByPort(nextDp.Port())
|
|
||||||
err = buildAndRelateDeviceLinkPositions(sim, link, baseKm, visitedModelMap, devices...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nextIsTp {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return endTp, endKm, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getATurnoutPort(turnouts []*Turnout, visitedTurnoutMap map[string]bool) *TurnoutPort {
|
|
||||||
portSlice := []proto.Port{proto.Port_A, proto.Port_B, proto.Port_C}
|
|
||||||
for _, turnout := range turnouts {
|
|
||||||
for _, port := range portSlice {
|
|
||||||
tp := &TurnoutPort{
|
|
||||||
turnout: turnout,
|
|
||||||
port: port,
|
|
||||||
}
|
|
||||||
key := buildTurnoutPortKey(tp)
|
|
||||||
if !visitedTurnoutMap[key] {
|
|
||||||
visitedTurnoutMap[key] = true
|
|
||||||
return tp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTurnoutPortKey(tp *TurnoutPort) string {
|
|
||||||
return fmt.Sprintf("%v-%s", tp.turnout, tp.port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAndRelateDeviceLinkPositions(sim *Simulation, link *Link, startKm *proto.Kilometer, visitedModelMap map[string]bool, devices ...Identity) error {
|
|
||||||
|
|
||||||
for _, device := range devices {
|
|
||||||
if visitedModelMap[device.Id()] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
km := findModelKm(device)
|
|
||||||
if km == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
convertedKm, err := convertKilometer(sim.repository, km, startKm.CoordinateSystem, startKm.Direction)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
offset := int64(math.Abs(float64(convertedKm.Value - startKm.Value)))
|
|
||||||
dlps := &DeviceLinkPosition{
|
|
||||||
device: device,
|
|
||||||
position: LinkPosition{
|
|
||||||
link: link,
|
|
||||||
offset: offset,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
sim.devicePositionMap[dlps.device.Id()] = dlps
|
|
||||||
link.bindDevicesLinkPositions(dlps)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAndRelateLinkNode(sim *Simulation, tp *TurnoutPort, link *Link, port proto.Port) error {
|
|
||||||
ln := sim.linkNodeMap[tp.turnout.Id()]
|
|
||||||
if ln == nil {
|
|
||||||
ln = &LinkNode{
|
|
||||||
Identity: identity{sim.getAId(), proto.DeviceType_DeviceType_LinkNode},
|
|
||||||
turnout: tp.turnout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//LinkNode关联Link
|
|
||||||
err := ln.bindDevicePort(port, &LinkPort{
|
|
||||||
link: link,
|
|
||||||
port: port,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//Link关联LinkNode
|
|
||||||
err = link.bindDevicePort(port, &LinkNodePort{
|
|
||||||
node: ln,
|
|
||||||
port: tp.port,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func findModelKm(model Identity) *proto.Kilometer {
|
|
||||||
signal, ok := model.(*Signal)
|
|
||||||
if ok {
|
|
||||||
return signal.km
|
|
||||||
}
|
|
||||||
responder, ok := model.(*Responder)
|
|
||||||
if ok {
|
|
||||||
return responder.km
|
|
||||||
}
|
|
||||||
cp, ok := model.(*CheckPoint)
|
|
||||||
if ok {
|
|
||||||
return cp.km
|
|
||||||
}
|
|
||||||
turnout, ok := model.(*Turnout)
|
|
||||||
if ok {
|
|
||||||
return turnout.km
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildSlopeLinkSegments(simulation *Simulation) error {
|
|
||||||
repo := simulation.repository
|
|
||||||
slopeMap := repo.slopeMap
|
|
||||||
for _, slope := range slopeMap {
|
|
||||||
start, end, err := calculateLinkSegment(simulation, slope.kms[0], slope.kms[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
simulation.slopeLinkSegmentMap[slope.Id()] = SlopeLinkSegment{
|
|
||||||
slope: slope,
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func calculateLinkSegment(simulation *Simulation, startKm *proto.Kilometer,
|
|
||||||
endKm *proto.Kilometer) (*LinkPosition, *LinkPosition, error) {
|
|
||||||
|
|
||||||
repo := simulation.repository
|
|
||||||
endKm, err := convertKilometer(repo, endKm, startKm.CoordinateSystem, startKm.Direction)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
var start *LinkPosition
|
|
||||||
var end *LinkPosition
|
|
||||||
var minKmValue float64
|
|
||||||
var minKmLink *Link
|
|
||||||
var maxKmValue float64
|
|
||||||
var maxKmLink *Link
|
|
||||||
for _, link := range simulation.linkMap {
|
|
||||||
//将link两端的公里标转为aKm同坐标系的公里标
|
|
||||||
linkAKm, err := convertKilometer(repo, link.aKm, startKm.CoordinateSystem, startKm.Direction)
|
|
||||||
if err != nil || linkAKm.Direction != startKm.Direction {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
linkBKm, err := convertKilometer(repo, link.bKm, startKm.CoordinateSystem, startKm.Direction)
|
|
||||||
if err != nil || linkBKm.Direction != startKm.Direction {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
//记录公里标最小/最大的Link
|
|
||||||
newMinKmValue := math.Min(float64(linkAKm.Value), float64(linkBKm.Value))
|
|
||||||
newMaxKmValue := math.Max(float64(linkAKm.Value), float64(linkBKm.Value))
|
|
||||||
if minKmLink == nil || newMinKmValue < minKmValue {
|
|
||||||
minKmValue = newMinKmValue
|
|
||||||
minKmLink = link
|
|
||||||
}
|
|
||||||
if maxKmLink == nil || newMaxKmValue > maxKmValue {
|
|
||||||
maxKmValue = newMaxKmValue
|
|
||||||
maxKmLink = link
|
|
||||||
}
|
|
||||||
//若start/end公里标落在link上,构建LinkPosition
|
|
||||||
if util.IsBetween(startKm.Value, linkAKm.Value, linkBKm.Value) {
|
|
||||||
start = &LinkPosition{
|
|
||||||
link: link,
|
|
||||||
offset: int64(math.Abs(float64(startKm.Value - linkAKm.Value))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if util.IsBetween(endKm.Value, linkAKm.Value, linkBKm.Value) {
|
|
||||||
end = &LinkPosition{
|
|
||||||
link: link,
|
|
||||||
offset: int64(math.Abs(float64(endKm.Value - linkAKm.Value))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if start != nil && end != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//处理start/end公里标没落在Link上的情况
|
|
||||||
if start == nil {
|
|
||||||
if startKm.Value < endKm.Value {
|
|
||||||
offset, _ := minKmLink.findEndOffset()
|
|
||||||
start = &LinkPosition{
|
|
||||||
link: minKmLink,
|
|
||||||
offset: offset,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offset, _ := maxKmLink.findEndOffset()
|
|
||||||
start = &LinkPosition{
|
|
||||||
link: maxKmLink,
|
|
||||||
offset: offset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if end == nil {
|
|
||||||
if endKm.Value < startKm.Value {
|
|
||||||
offset, _ := minKmLink.findEndOffset()
|
|
||||||
end = &LinkPosition{
|
|
||||||
link: minKmLink,
|
|
||||||
offset: offset,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
offset, _ := maxKmLink.findEndOffset()
|
|
||||||
end = &LinkPosition{
|
|
||||||
link: maxKmLink,
|
|
||||||
offset: offset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return start, end, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildSectionalCurvatureLinkSegments(sim *Simulation) error {
|
|
||||||
repo := sim.repository
|
|
||||||
for _, curvature := range repo.sectionalCurvatureMap {
|
|
||||||
start, end, err := calculateLinkSegment(sim, curvature.kms[0], curvature.kms[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sim.sectionalCurvatureLinkSegmentMap[curvature.Id()] = SectionalCurvatureLinkSegment{
|
|
||||||
sectionalCurvature: curvature,
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -7,6 +7,8 @@ type Slope struct {
|
|||||||
|
|
||||||
kms []*proto.Kilometer
|
kms []*proto.Kilometer
|
||||||
degree int32
|
degree int32
|
||||||
|
startLinkPosition *LinkPosition
|
||||||
|
endLinkPosition *LinkPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSlope(id string, kms []*proto.Kilometer, degree int32) *Slope {
|
func NewSlope(id string, kms []*proto.Kilometer, degree int32) *Slope {
|
||||||
@ -16,3 +18,23 @@ func NewSlope(id string, kms []*proto.Kilometer, degree int32) *Slope {
|
|||||||
degree: degree,
|
degree: degree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Slope) bindStartLinkPosition(position *LinkPosition) {
|
||||||
|
s.startLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slope) bindEndLinkPosition(position *LinkPosition) {
|
||||||
|
s.endLinkPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slope) StartLinkPosition() *LinkPosition {
|
||||||
|
return s.startLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slope) EndLinkPosition() *LinkPosition {
|
||||||
|
return s.endLinkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Slope) Degree() int32 {
|
||||||
|
return s.degree
|
||||||
|
}
|
||||||
|
@ -15,11 +15,16 @@ type Turnout struct {
|
|||||||
// 道岔关联的道岔物理区段
|
// 道岔关联的道岔物理区段
|
||||||
section *PhysicalSection
|
section *PhysicalSection
|
||||||
|
|
||||||
// A/B/C端口关联的设备端口
|
// A/B/C端口关联的设备端口(区段/道岔)
|
||||||
aDevicePort DevicePort
|
aDevicePort DevicePort
|
||||||
bDevicePort DevicePort
|
bDevicePort DevicePort
|
||||||
cDevicePort DevicePort
|
cDevicePort DevicePort
|
||||||
|
|
||||||
|
// A/B/C端口关联的Link端口
|
||||||
|
aLinkPort *LinkPort
|
||||||
|
bLinkPort *LinkPort
|
||||||
|
cLinkPort *LinkPort
|
||||||
|
|
||||||
// A/B/C端口的区段边界的公里标
|
// A/B/C端口的区段边界的公里标
|
||||||
aKm *proto.Kilometer
|
aKm *proto.Kilometer
|
||||||
bKm *proto.Kilometer
|
bKm *proto.Kilometer
|
||||||
@ -65,6 +70,17 @@ func (t *Turnout) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Turnout) bindLinkPort(port proto.Port, linkPort *LinkPort) {
|
||||||
|
switch port {
|
||||||
|
case proto.Port_A:
|
||||||
|
t.aLinkPort = linkPort
|
||||||
|
case proto.Port_B:
|
||||||
|
t.aLinkPort = linkPort
|
||||||
|
case proto.Port_C:
|
||||||
|
t.aLinkPort = linkPort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Turnout) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
|
func (t *Turnout) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
|
||||||
switch port {
|
switch port {
|
||||||
case proto.Port_A:
|
case proto.Port_A:
|
||||||
|
41
simulation/simulation.go
Normal file
41
simulation/simulation.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package simulation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"joylink.club/ecs"
|
||||||
|
"joylink.club/rtsssimulation/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
simulationManager = make(map[ecs.WorldId]*Simulation)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Simulation struct {
|
||||||
|
world ecs.World
|
||||||
|
repo *repository.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simulation) getWorld() ecs.World {
|
||||||
|
return s.world
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simulation) getRepo() *repository.Repository {
|
||||||
|
return s.repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSimulation(repo *repository.Repository, config *WorldConfig) int {
|
||||||
|
world := InitializeWorld(config)
|
||||||
|
sim := &Simulation{
|
||||||
|
world: world,
|
||||||
|
repo: repo,
|
||||||
|
}
|
||||||
|
simulationManager[world.Id()] = sim
|
||||||
|
return int(world.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
func DestroySimulation(id ecs.WorldId) {
|
||||||
|
delete(simulationManager, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindSimulation(id ecs.WorldId) *Simulation {
|
||||||
|
return simulationManager[id]
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package util
|
package number
|
||||||
|
|
||||||
type Number interface {
|
type Number interface {
|
||||||
~int | ~int8 | ~int16 | ~int32 | int64 |
|
~int | ~int8 | ~int16 | ~int32 | int64 |
|
||||||
@ -13,3 +13,17 @@ func IsBetween[T Number](n T, a T, b T) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Min[T Number](a T, b T) T {
|
||||||
|
if a <= b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func Max[T Number](a T, b T) T {
|
||||||
|
if a >= b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user