直接存储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
|
||||
|
||||
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/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
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=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
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/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/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/file2byteslice v1.0.0/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
||||
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 {
|
||||
enum SwitchMachineType {
|
||||
Unknown = 0;
|
||||
ZDJ9_Single = 1;
|
||||
ZDJ9_Double = 2;
|
||||
}
|
||||
string id = 1;
|
||||
Kilometer km = 2;
|
||||
DevicePort aDevicePort = 3;
|
||||
DevicePort bDevicePort = 4;
|
||||
DevicePort cDevicePort = 5;
|
||||
SwitchMachineType switchMachineType = 6;
|
||||
repeated string relayIds = 7; //道岔关联的继电器
|
||||
}
|
||||
|
||||
//信号机
|
||||
@ -85,7 +92,7 @@ enum DeviceType {
|
||||
DeviceType_CheckPoint = 2;
|
||||
DeviceType_Turnout = 3;
|
||||
DeviceType_Signal = 4;
|
||||
DeviceType_Responder = 5;
|
||||
DeviceType_Transponder = 5;
|
||||
DeviceType_Slope = 6;
|
||||
DeviceType_SectionalCurvature = 7;
|
||||
DeviceType_Link = 8;
|
||||
@ -125,3 +132,12 @@ enum CheckPointType{
|
||||
AxleCounter = 1; //计轴器
|
||||
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
|
||||
//section *PhysicalSection
|
||||
//turnoutPort TurnoutPort
|
||||
linkPosition *LinkPosition
|
||||
}
|
||||
|
||||
func NewTransponder(id string, km *proto.Kilometer) *Transponder {
|
||||
return &Transponder{
|
||||
Identity: identity{id, proto.DeviceType_DeviceType_Responder},
|
||||
Identity: identity{id, proto.DeviceType_DeviceType_Transponder},
|
||||
km: km,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Transponder) bindLinkPosition(position *LinkPosition) {
|
||||
t.linkPosition = position
|
||||
}
|
||||
|
||||
//func (r *Transponder) bindSection(section *PhysicalSection) {
|
||||
// r.section = section
|
||||
//}
|
||||
|
@ -9,6 +9,7 @@ type CheckPoint struct {
|
||||
km *proto.Kilometer
|
||||
pointType proto.CheckPointType //检测点类型
|
||||
devicePorts []DevicePort //检测点关联的设备及其端口
|
||||
linkPosition *LinkPosition
|
||||
}
|
||||
|
||||
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) {
|
||||
c.devicePorts = append(c.devicePorts, devicePort)
|
||||
}
|
||||
|
||||
func (c *CheckPoint) bindLinkPosition(position *LinkPosition) {
|
||||
c.linkPosition = position
|
||||
}
|
||||
|
@ -11,14 +11,17 @@ type Link struct {
|
||||
|
||||
length int64
|
||||
|
||||
aRelation *LinkNodePort
|
||||
bRelation *LinkNodePort
|
||||
aRelation *TurnoutPort
|
||||
bRelation *TurnoutPort
|
||||
|
||||
aKm *proto.Kilometer
|
||||
bKm *proto.Kilometer
|
||||
|
||||
//Link关联的模型,包含LinkNode
|
||||
devicePositions []*DeviceLinkPosition
|
||||
//Link上的模型((非区段边界)检测点、应答器、信号机、区段(为了位置换算方便))
|
||||
devices []Identity
|
||||
|
||||
////Link关联的模型,包含LinkNode
|
||||
//devicePositions []*DeviceLinkPosition
|
||||
}
|
||||
|
||||
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 {
|
||||
return 2
|
||||
}
|
||||
|
||||
func (l *Link) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
||||
linkNodePort, isLinkNodePort := devicePort.(*LinkNodePort)
|
||||
if !isLinkNodePort {
|
||||
turnoutPort, isTurnoutPort := devicePort.(*TurnoutPort)
|
||||
if !isTurnoutPort {
|
||||
return errors.New(fmt.Sprintf("Link不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
||||
}
|
||||
switch port {
|
||||
case proto.Port_A:
|
||||
l.aRelation = linkNodePort
|
||||
l.aRelation = turnoutPort
|
||||
case proto.Port_B:
|
||||
l.bRelation = linkNodePort
|
||||
l.bRelation = turnoutPort
|
||||
default:
|
||||
return errors.New(fmt.Sprintf("Link没有端口[%s]", port))
|
||||
}
|
||||
l.bindKm(turnoutPort.turnout.km, port)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -58,9 +78,9 @@ func (l *Link) bindKm(km *proto.Kilometer, port proto.Port) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Link) bindDevicesLinkPositions(dlps ...*DeviceLinkPosition) {
|
||||
for _, dlp := range dlps {
|
||||
l.devicePositions = append(l.devicePositions, dlp)
|
||||
func (l *Link) bindDevices(devices ...Identity) {
|
||||
for _, device := range devices {
|
||||
l.devices = append(l.devices, device)
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,58 +111,12 @@ type LinkPosition struct {
|
||||
offset int64
|
||||
}
|
||||
|
||||
// DeviceLinkPosition device在link上的位置
|
||||
type DeviceLinkPosition struct {
|
||||
device Identity
|
||||
position LinkPosition
|
||||
func (l *LinkPosition) Link() *Link {
|
||||
return l.link
|
||||
}
|
||||
|
||||
// SlopeLinkSegment Slope在Link上的区间
|
||||
type SlopeLinkSegment struct {
|
||||
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
|
||||
func (l *LinkPosition) Offset() int64 {
|
||||
return l.offset
|
||||
}
|
||||
|
||||
// link端口
|
||||
@ -166,22 +140,88 @@ func (l *LinkPort) Device() PortedDevice {
|
||||
return l.link
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
//// DeviceLinkPosition device在link上的位置
|
||||
//type DeviceLinkPosition struct {
|
||||
// device Identity
|
||||
// position LinkPosition
|
||||
//}
|
||||
//
|
||||
//// SlopeLinkSegment Slope在Link上的区间
|
||||
//type SlopeLinkSegment struct {
|
||||
// slope *Slope
|
||||
// start *LinkPosition
|
||||
// end *LinkPosition
|
||||
//}
|
||||
//
|
||||
//func (s *SlopeLinkSegment) Slope() *Slope {
|
||||
// return s.slope
|
||||
//}
|
||||
//
|
||||
//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_Turnout DeviceType = 3
|
||||
DeviceType_DeviceType_Signal DeviceType = 4
|
||||
DeviceType_DeviceType_Responder DeviceType = 5
|
||||
DeviceType_DeviceType_Transponder DeviceType = 5
|
||||
DeviceType_DeviceType_Slope DeviceType = 6
|
||||
DeviceType_DeviceType_SectionalCurvature DeviceType = 7
|
||||
DeviceType_DeviceType_Link DeviceType = 8
|
||||
@ -43,7 +43,7 @@ var (
|
||||
2: "DeviceType_CheckPoint",
|
||||
3: "DeviceType_Turnout",
|
||||
4: "DeviceType_Signal",
|
||||
5: "DeviceType_Responder",
|
||||
5: "DeviceType_Transponder",
|
||||
6: "DeviceType_Slope",
|
||||
7: "DeviceType_SectionalCurvature",
|
||||
8: "DeviceType_Link",
|
||||
@ -55,7 +55,7 @@ var (
|
||||
"DeviceType_CheckPoint": 2,
|
||||
"DeviceType_Turnout": 3,
|
||||
"DeviceType_Signal": 4,
|
||||
"DeviceType_Responder": 5,
|
||||
"DeviceType_Transponder": 5,
|
||||
"DeviceType_Slope": 6,
|
||||
"DeviceType_SectionalCurvature": 7,
|
||||
"DeviceType_Link": 8,
|
||||
@ -239,6 +239,98 @@ func (CheckPointType) EnumDescriptor() ([]byte, []int) {
|
||||
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 {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -513,6 +605,8 @@ type Turnout struct {
|
||||
ADevicePort *DevicePort `protobuf:"bytes,3,opt,name=aDevicePort,proto3" json:"aDevicePort,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"`
|
||||
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() {
|
||||
@ -582,6 +676,20 @@ func (x *Turnout) GetCDevicePort() *DevicePort {
|
||||
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 {
|
||||
state protoimpl.MessageState
|
||||
@ -1046,6 +1154,69 @@ func (x *KilometerConvert) GetSameTrend() bool {
|
||||
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_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, 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,
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
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,
|
||||
0x08, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x2a, 0x8f, 0x02, 0x0a,
|
||||
0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44,
|
||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
|
||||
0x6e, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70,
|
||||
0x65, 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70,
|
||||
0x65, 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16,
|
||||
0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72,
|
||||
0x6e, 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x18, 0x0a,
|
||||
0x14, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x64, 0x65, 0x72, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63,
|
||||
0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, 0x21, 0x0a,
|
||||
0x1d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x07,
|
||||
0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c,
|
||||
0x69, 0x6e, 0x6b, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54,
|
||||
0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x25,
|
||||
0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00,
|
||||
0x12, 0x05, 0x0a, 0x01, 0x41, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05,
|
||||
0x0a, 0x01, 0x43, 0x10, 0x03, 0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x08, 0x0a, 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,
|
||||
0x08, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x72, 0x65, 0x6e, 0x64, 0x22, 0x67, 0x0a, 0x05,
|
||||
0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x74, 0x79, 0x70,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e,
|
||||
0x52, 0x65, 0x6c, 0x61, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x22, 0x13, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e,
|
||||
0x6f, 0x77, 0x6e, 0x10, 0x00, 0x2a, 0x91, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79,
|
||||
0x70, 0x65, 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a,
|
||||
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x68, 0x79, 0x73, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15,
|
||||
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x68, 0x65, 0x63, 0x6b,
|
||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63,
|
||||
0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x75, 0x72, 0x6e, 0x6f, 0x75, 0x74, 0x10, 0x03, 0x12,
|
||||
0x15, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72,
|
||||
0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65,
|
||||
0x5f, 0x53, 0x6c, 0x6f, 0x70, 0x65, 0x10, 0x06, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x65, 0x76, 0x69,
|
||||
0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
|
||||
0x43, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x44,
|
||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x08,
|
||||
0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c,
|
||||
0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x25, 0x0a, 0x04, 0x50, 0x6f, 0x72,
|
||||
0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x05, 0x0a, 0x01, 0x41,
|
||||
0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x02, 0x12, 0x05, 0x0a, 0x01, 0x43, 0x10, 0x03,
|
||||
0x2a, 0x20, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a,
|
||||
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 (
|
||||
@ -1212,59 +1401,64 @@ func file_model_proto_rawDescGZIP() []byte {
|
||||
return file_model_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
|
||||
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_model_proto_goTypes = []interface{}{
|
||||
(DeviceType)(0), // 0: model.DeviceType
|
||||
(Port)(0), // 1: model.Port
|
||||
(Direction)(0), // 2: model.Direction
|
||||
(CheckPointType)(0), // 3: model.CheckPointType
|
||||
(*Repository)(nil), // 4: model.Repository
|
||||
(*PhysicalSection)(nil), // 5: model.PhysicalSection
|
||||
(*CheckPoint)(nil), // 6: model.CheckPoint
|
||||
(*Turnout)(nil), // 7: model.Turnout
|
||||
(*Signal)(nil), // 8: model.Signal
|
||||
(*Transponder)(nil), // 9: model.Transponder
|
||||
(*Slope)(nil), // 10: model.Slope
|
||||
(*SectionalCurvature)(nil), // 11: model.SectionalCurvature
|
||||
(*DevicePort)(nil), // 12: model.DevicePort
|
||||
(*Kilometer)(nil), // 13: model.Kilometer
|
||||
(*KilometerConvert)(nil), // 14: model.KilometerConvert
|
||||
(Turnout_SwitchMachineType)(0), // 4: model.Turnout.SwitchMachineType
|
||||
(Relay_Type)(0), // 5: model.Relay.Type
|
||||
(*Repository)(nil), // 6: model.Repository
|
||||
(*PhysicalSection)(nil), // 7: model.PhysicalSection
|
||||
(*CheckPoint)(nil), // 8: model.CheckPoint
|
||||
(*Turnout)(nil), // 9: model.Turnout
|
||||
(*Signal)(nil), // 10: model.Signal
|
||||
(*Transponder)(nil), // 11: model.Transponder
|
||||
(*Slope)(nil), // 12: model.Slope
|
||||
(*SectionalCurvature)(nil), // 13: model.SectionalCurvature
|
||||
(*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{
|
||||
5, // 0: model.Repository.physicalSections:type_name -> model.PhysicalSection
|
||||
6, // 1: model.Repository.checkPoints:type_name -> model.CheckPoint
|
||||
7, // 2: model.Repository.turnouts:type_name -> model.Turnout
|
||||
8, // 3: model.Repository.signals:type_name -> model.Signal
|
||||
9, // 4: model.Repository.transponders:type_name -> model.Transponder
|
||||
10, // 5: model.Repository.slopes:type_name -> model.Slope
|
||||
11, // 6: model.Repository.sectionalCurvatures:type_name -> model.SectionalCurvature
|
||||
14, // 7: model.Repository.kilometerConverts:type_name -> model.KilometerConvert
|
||||
12, // 8: model.PhysicalSection.aDevicePort:type_name -> model.DevicePort
|
||||
12, // 9: model.PhysicalSection.bDevicePort:type_name -> model.DevicePort
|
||||
13, // 10: model.CheckPoint.km:type_name -> model.Kilometer
|
||||
7, // 0: model.Repository.physicalSections:type_name -> model.PhysicalSection
|
||||
8, // 1: model.Repository.checkPoints:type_name -> model.CheckPoint
|
||||
9, // 2: model.Repository.turnouts:type_name -> model.Turnout
|
||||
10, // 3: model.Repository.signals:type_name -> model.Signal
|
||||
11, // 4: model.Repository.transponders:type_name -> model.Transponder
|
||||
12, // 5: model.Repository.slopes:type_name -> model.Slope
|
||||
13, // 6: model.Repository.sectionalCurvatures:type_name -> model.SectionalCurvature
|
||||
16, // 7: model.Repository.kilometerConverts:type_name -> model.KilometerConvert
|
||||
14, // 8: model.PhysicalSection.aDevicePort:type_name -> model.DevicePort
|
||||
14, // 9: model.PhysicalSection.bDevicePort:type_name -> model.DevicePort
|
||||
15, // 10: model.CheckPoint.km:type_name -> model.Kilometer
|
||||
3, // 11: model.CheckPoint.type:type_name -> model.CheckPointType
|
||||
12, // 12: model.CheckPoint.devicePorts:type_name -> model.DevicePort
|
||||
13, // 13: model.Turnout.km:type_name -> model.Kilometer
|
||||
12, // 14: model.Turnout.aDevicePort:type_name -> model.DevicePort
|
||||
12, // 15: model.Turnout.bDevicePort:type_name -> model.DevicePort
|
||||
12, // 16: model.Turnout.cDevicePort:type_name -> model.DevicePort
|
||||
13, // 17: model.Signal.km:type_name -> model.Kilometer
|
||||
12, // 18: model.Signal.turnoutPort:type_name -> model.DevicePort
|
||||
13, // 19: model.Transponder.km:type_name -> model.Kilometer
|
||||
12, // 20: model.Transponder.turnoutPort:type_name -> model.DevicePort
|
||||
13, // 21: model.Slope.kms:type_name -> model.Kilometer
|
||||
13, // 22: model.SectionalCurvature.kms:type_name -> model.Kilometer
|
||||
0, // 23: model.DevicePort.deviceType:type_name -> model.DeviceType
|
||||
1, // 24: model.DevicePort.port:type_name -> model.Port
|
||||
2, // 25: model.Kilometer.direction:type_name -> model.Direction
|
||||
13, // 26: model.KilometerConvert.kmA:type_name -> model.Kilometer
|
||||
13, // 27: model.KilometerConvert.kmB:type_name -> model.Kilometer
|
||||
28, // [28:28] is the sub-list for method output_type
|
||||
28, // [28:28] is the sub-list for method input_type
|
||||
28, // [28:28] is the sub-list for extension type_name
|
||||
28, // [28:28] is the sub-list for extension extendee
|
||||
0, // [0:28] is the sub-list for field type_name
|
||||
14, // 12: model.CheckPoint.devicePorts:type_name -> model.DevicePort
|
||||
15, // 13: model.Turnout.km:type_name -> model.Kilometer
|
||||
14, // 14: model.Turnout.aDevicePort:type_name -> model.DevicePort
|
||||
14, // 15: model.Turnout.bDevicePort:type_name -> model.DevicePort
|
||||
14, // 16: model.Turnout.cDevicePort:type_name -> model.DevicePort
|
||||
4, // 17: model.Turnout.switchMachineType:type_name -> model.Turnout.SwitchMachineType
|
||||
15, // 18: model.Signal.km:type_name -> model.Kilometer
|
||||
14, // 19: model.Signal.turnoutPort:type_name -> model.DevicePort
|
||||
15, // 20: model.Transponder.km:type_name -> model.Kilometer
|
||||
14, // 21: model.Transponder.turnoutPort:type_name -> model.DevicePort
|
||||
15, // 22: model.Slope.kms:type_name -> model.Kilometer
|
||||
15, // 23: model.SectionalCurvature.kms:type_name -> model.Kilometer
|
||||
0, // 24: model.DevicePort.deviceType:type_name -> model.DeviceType
|
||||
1, // 25: model.DevicePort.port:type_name -> model.Port
|
||||
2, // 26: model.Kilometer.direction:type_name -> model.Direction
|
||||
15, // 27: model.KilometerConvert.kmA:type_name -> model.Kilometer
|
||||
15, // 28: model.KilometerConvert.kmB:type_name -> model.Kilometer
|
||||
5, // 29: model.Relay.type:type_name -> model.Relay.Type
|
||||
30, // [30:30] is the sub-list for method output_type
|
||||
30, // [30:30] is the sub-list for method input_type
|
||||
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() }
|
||||
@ -1405,14 +1599,26 @@ func file_model_proto_init() {
|
||||
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{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_model_proto_rawDesc,
|
||||
NumEnums: 4,
|
||||
NumMessages: 11,
|
||||
NumEnums: 6,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
@ -17,7 +17,7 @@ type PhysicalSection struct {
|
||||
aRelation DevicePort
|
||||
bRelation DevicePort
|
||||
|
||||
// 非道岔物理区段A/B端区段边界的公里标
|
||||
// 非道岔物理区段A/B端的公里标
|
||||
aKm *proto.Kilometer
|
||||
bKm *proto.Kilometer
|
||||
|
||||
@ -25,6 +25,10 @@ type PhysicalSection struct {
|
||||
|
||||
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
|
||||
devices []Identity
|
||||
|
||||
//在Link上的区间(根据aKm和bKm计算出的)
|
||||
startLinkPosition *LinkPosition
|
||||
endLinkPosition *LinkPosition
|
||||
}
|
||||
|
||||
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 {
|
||||
return s.aRelation
|
||||
}
|
||||
@ -125,6 +137,14 @@ func (s *PhysicalSection) findBoundaryKmByPort(port proto.Port) *proto.Kilometer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PhysicalSection) StartLinkPosition() *LinkPosition {
|
||||
return s.startLinkPosition
|
||||
}
|
||||
|
||||
func (s *PhysicalSection) EndLinkPosition() *LinkPosition {
|
||||
return s.endLinkPosition
|
||||
}
|
||||
|
||||
type PhysicalSectionPort struct {
|
||||
section *PhysicalSection
|
||||
port proto.Port
|
||||
|
@ -17,10 +17,16 @@ type Repository struct {
|
||||
slopeMap map[string]*Slope
|
||||
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
|
||||
}
|
||||
|
||||
func NewRepository(id string, version string) *Repository {
|
||||
func newRepository(id string, version string) *Repository {
|
||||
return &Repository{
|
||||
id: id,
|
||||
version: version,
|
||||
@ -32,10 +38,79 @@ func NewRepository(id string, version string) *Repository {
|
||||
responderMap: make(map[string]*Transponder),
|
||||
slopeMap: make(map[string]*Slope),
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
switch deviceType {
|
||||
case proto.DeviceType_DeviceType_PhysicalSection:
|
||||
@ -46,73 +121,25 @@ func (repo *Repository) getModel(deviceId string, deviceType proto.DeviceType) (
|
||||
return repo.turnoutMap[deviceId], nil
|
||||
case proto.DeviceType_DeviceType_Signal:
|
||||
return repo.signalMap[deviceId], nil
|
||||
case proto.DeviceType_DeviceType_Responder:
|
||||
case proto.DeviceType_DeviceType_Transponder:
|
||||
return repo.responderMap[deviceId], nil
|
||||
case proto.DeviceType_DeviceType_Slope:
|
||||
return repo.slopeMap[deviceId], nil
|
||||
case proto.DeviceType_DeviceType_SectionalCurvature:
|
||||
return repo.sectionalCurvatureMap[deviceId], nil
|
||||
case proto.DeviceType_DeviceType_Link:
|
||||
return repo.linkMap[deviceId], nil
|
||||
default:
|
||||
return nil, errors.New(fmt.Sprintf("仓库中不存在[%s]类型的模型", deviceType))
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *Repository) PhysicalSectionList() []*PhysicalSection {
|
||||
list := make([]*PhysicalSection, len(repo.physicalSectionMap))
|
||||
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) FindLink(id string) *Link {
|
||||
return repo.linkMap[id]
|
||||
}
|
||||
|
||||
func (repo *Repository) AddPhysicalSection(section *PhysicalSection) {
|
||||
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) {
|
||||
@ -127,3 +154,7 @@ func (repo *Repository) getKilometerConvert(cs1, cs2 string, dir1, dir2 proto.Di
|
||||
}
|
||||
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
|
||||
kms []*proto.Kilometer
|
||||
radius int32 //半径 mm
|
||||
startLinkPosition *LinkPosition
|
||||
endLinkPosition *LinkPosition
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
//section *PhysicalSection
|
||||
//turnoutPort TurnoutPort
|
||||
linkPosition *LinkPosition
|
||||
}
|
||||
|
||||
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) {
|
||||
// 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
|
||||
degree int32
|
||||
startLinkPosition *LinkPosition
|
||||
endLinkPosition *LinkPosition
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// A/B/C端口关联的设备端口
|
||||
// A/B/C端口关联的设备端口(区段/道岔)
|
||||
aDevicePort DevicePort
|
||||
bDevicePort DevicePort
|
||||
cDevicePort DevicePort
|
||||
|
||||
// A/B/C端口关联的Link端口
|
||||
aLinkPort *LinkPort
|
||||
bLinkPort *LinkPort
|
||||
cLinkPort *LinkPort
|
||||
|
||||
// A/B/C端口的区段边界的公里标
|
||||
aKm *proto.Kilometer
|
||||
bKm *proto.Kilometer
|
||||
@ -65,6 +70,17 @@ func (t *Turnout) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
||||
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 {
|
||||
switch port {
|
||||
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 {
|
||||
~int | ~int8 | ~int16 | ~int32 | int64 |
|
||||
@ -13,3 +13,17 @@ func IsBetween[T Number](n T, a T, b T) bool {
|
||||
}
|
||||
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