/
t808_0x8604.go
172 lines (145 loc) · 3.36 KB
/
t808_0x8604.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package protocol
import (
"github.com/shopspring/decimal"
"math"
"time"
)
// 顶点
type Vertex struct {
// 顶点纬度
Lat decimal.Decimal
// 顶点经度
Lng decimal.Decimal
}
// 设置多边形区域
type T808_0x8604 struct {
// 区域 ID
ID uint32
// 区域属性
Attribute AreaAttribute
// 起始时间
StartTime time.Time
// 结束时间
EndTime time.Time
// 最高速度
MaxSpeed uint16
// 超速持续时间
Duration byte
// 顶点项
Vertexes []Vertex
}
func (entity *T808_0x8604) MsgID() MsgID {
return MsgT808_0x8604
}
func (entity *T808_0x8604) Encode() ([]byte, error) {
writer := NewWriter()
// 写入区域ID
writer.WriteUint32(entity.ID)
// 计算经纬度
mul := decimal.NewFromFloat(1000000)
vertexes := make([]Vertex, 0, len(entity.Vertexes))
for j := range entity.Vertexes {
vertex := &entity.Vertexes[j]
lat := vertex.Lat.Mul(mul)
if lat.Cmp(decimal.Zero) < 0 {
entity.Attribute.SetSouthLatitude(true)
}
lng := vertex.Lng.Mul(mul)
if lng.Cmp(decimal.Zero) < 0 {
entity.Attribute.SetWestLongitude(true)
}
vertexes = append(vertexes, Vertex{
Lat: lat,
Lng: lng,
})
}
// 写入区域属性
writer.WriteUint16(uint16(entity.Attribute))
// 写入时间参数
if entity.Attribute&1 == 1 {
// 写入开始时间
writer.WriteBcdTime(entity.StartTime)
// 写入结束时间
writer.WriteBcdTime(entity.EndTime)
// 写入最高速度
writer.WriteUint16(entity.MaxSpeed)
// 写入持续时间
writer.WriteByte(entity.Duration)
}
// 写入顶点总数
writer.WriteUint16(uint16(len(entity.Vertexes)))
// 写入顶点信息
for _, vertex := range vertexes {
// 写入纬度
writer.WriteUint32(uint32(math.Abs(float64(vertex.Lat.IntPart()))))
// 写入经度
writer.WriteUint32(uint32(math.Abs(float64(vertex.Lng.IntPart()))))
}
return writer.Bytes(), nil
}
func (entity *T808_0x8604) Decode(data []byte) (int, error) {
if len(data) < 16 {
return 0, ErrInvalidBody
}
reader := NewReader(data)
// 读取区域ID
var err error
entity.ID, err = reader.ReadUint32()
if err != nil {
return 0, err
}
// 读取区域属性
attribute, err := reader.ReadUint16()
if err != nil {
return 0, err
}
entity.Attribute = AreaAttribute(attribute)
// 读取时间参数
if entity.Attribute&1 == 1 {
// 读取开始时间
entity.StartTime, err = reader.ReadBcdTime()
if err != nil {
return 0, err
}
// 读取结束时间
entity.EndTime, err = reader.ReadBcdTime()
if err != nil {
return 0, err
}
// 读取最高速度
entity.MaxSpeed, err = reader.ReadUint16()
if err != nil {
return 0, err
}
// 读取持续时间
entity.Duration, err = reader.ReadByte()
if err != nil {
return 0, err
}
}
// 读取顶点总数
vertexes, err := reader.ReadUint16()
if err != nil {
return 0, err
}
entity.Vertexes = make([]Vertex, 0, int(vertexes))
// 读取顶点列表
for j := 0; j < int(vertexes); j++ {
var vertex Vertex
// 读取纬度
lat, err := reader.ReadUint32()
if err != nil {
return 0, err
}
// 读取经度
lng, err := reader.ReadUint32()
if err != nil {
return 0, err
}
vertex.Lat, vertex.Lng = getGeoPoint(
lat, entity.Attribute.GetLatitudeType() == SouthLatitudeType,
lng, entity.Attribute.GetLongitudeType() == WestLongitudeType)
entity.Vertexes = append(entity.Vertexes, vertex)
}
return len(data) - reader.Len(), nil
}