1 /**********************************************************************************************
2 Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************************************************************/
18
19 #include "CQlgtRoute.h"
20
21 struct rte_head_entry_t
22 {
rte_head_entry_trte_head_entry_t23 rte_head_entry_t() : type(CQlgtRoute::eEnd), offset(0)
24 {
25 }
26 qint32 type;
27 quint32 offset;
28 QByteArray data;
29 };
30
31
operator >>(QDataStream & s,CQlgtRoute & route)32 QDataStream& operator >>(QDataStream& s, CQlgtRoute& route)
33 {
34 quint32 nRtePts = 0;
35 QIODevice* dev = s.device();
36 qint64 pos = dev->pos();
37
38 char magic[9];
39 s.readRawData(magic, 9);
40
41 if(strncmp(magic, "QLRte ", 9))
42 {
43 dev->seek(pos);
44 return s;
45 }
46
47 QList<rte_head_entry_t> entries;
48
49 while(1)
50 {
51 rte_head_entry_t entry;
52 s >> entry.type >> entry.offset;
53 entries << entry;
54 if(entry.type == CQlgtRoute::eEnd)
55 {
56 break;
57 }
58 }
59
60 QList<rte_head_entry_t>::iterator entry = entries.begin();
61 while(entry != entries.end())
62 {
63 qint64 o = pos + entry->offset;
64 dev->seek(o);
65 s >> entry->data;
66
67 switch(entry->type)
68 {
69 case CQlgtRoute::eBase:
70 {
71 QDataStream s1(&entry->data, QIODevice::ReadOnly);
72 s1.setVersion(QDataStream::Qt_4_5);
73
74 s1 >> route.key;
75 s1 >> route.timestamp;
76 s1 >> route.name;
77 s1 >> route.iconString;
78 s1 >> route.ttime;
79 s1 >> route.parentWpt;
80
81 break;
82 }
83
84 case CQlgtRoute::eRtePts:
85 {
86 QDataStream s1(&entry->data, QIODevice::ReadOnly);
87 s1.setVersion(QDataStream::Qt_4_5);
88 quint32 n;
89
90 route.priRoute.clear();
91 s1 >> nRtePts;
92
93 for(n = 0; n < nRtePts; ++n)
94 {
95 CQlgtRoute::pt_t rtept;
96 float u, v;
97 QString action;
98
99 s1 >> u;
100 s1 >> v;
101 s1 >> action;
102
103 rtept.lon = u;
104 rtept.lat = v;
105 rtept.action = action;
106 route.priRoute << rtept;
107 }
108 break;
109 }
110 // case CQlgtRoute::eRteSec:
111 // {
112 // QDataStream s1(&entry->data, QIODevice::ReadOnly);
113 // s1.setVersion(QDataStream::Qt_4_5);
114 // quint32 n;
115
116 // route.secRoute.clear();
117 // s1 >> nRtePts;
118
119 // for(n = 0; n < nRtePts; ++n)
120 // {
121 // CQlgtRoute::pt_t rtept;
122 // float u, v;
123 // QString action;
124
125 // s1 >> u;
126 // s1 >> v;
127 // s1 >> action;
128
129 // rtept.lon = u;
130 // rtept.lat = v;
131 // rtept.action = action;
132 // route.secRoute << rtept;
133 // }
134 // break;
135 // }
136 default:
137 ;
138 }
139
140 ++entry;
141 }
142
143
144 return s;
145 }
146
operator <<(QDataStream & s,CQlgtRoute & route)147 QDataStream& operator <<(QDataStream& s, CQlgtRoute& route)
148 {
149 QList<rte_head_entry_t> entries;
150
151 //---------------------------------------
152 // prepare base data
153 //---------------------------------------
154 rte_head_entry_t entryBase;
155 entryBase.type = CQlgtRoute::eBase;
156 QDataStream s1(&entryBase.data, QIODevice::WriteOnly);
157 s1.setVersion(QDataStream::Qt_4_5);
158
159 s1 << route.key;
160 s1 << route.timestamp;
161 s1 << route.name;
162 s1 << route.iconString;
163 s1 << route.ttime;
164 s1 << route.parentWpt;
165
166 entries << entryBase;
167
168 //---------------------------------------
169 // prepare primary routepoint data
170 //---------------------------------------
171 rte_head_entry_t entryPriRtePts;
172 entryPriRtePts.type = CQlgtRoute::eRtePts;
173 QDataStream s2(&entryPriRtePts.data, QIODevice::WriteOnly);
174 s2.setVersion(QDataStream::Qt_4_5);
175
176 {
177 QVector<CQlgtRoute::pt_t>& rtepts = route.priRoute;
178 QVector<CQlgtRoute::pt_t>::iterator rtept = rtepts.begin();
179
180 s2 << (quint32)rtepts.size();
181 while(rtept != rtepts.end())
182 {
183 s2 << (float)rtept->lon;
184 s2 << (float)rtept->lat;
185 s2 << rtept->action;
186 ++rtept;
187 }
188 }
189 entries << entryPriRtePts;
190
191 // //---------------------------------------
192 // // prepare secondary routepoint data
193 // //---------------------------------------
194 // rte_head_entry_t entrySecRtePts;
195 // entrySecRtePts.type = CQlgtRoute::eRteSec;
196 // QDataStream s3(&entrySecRtePts.data, QIODevice::WriteOnly);
197 // s3.setVersion(QDataStream::Qt_4_5);
198
199 // {
200 // QVector<CQlgtRoute::pt_t>& rtepts = route.getSecRtePoints();
201 // QVector<CQlgtRoute::pt_t>::iterator rtept = rtepts.begin();
202
203 // if(!rtepts.isEmpty())
204 // {
205 // s3 << (quint32)rtepts.size();
206 // while(rtept != rtepts.end())
207 // {
208 // s3 << (float)rtept->lon;
209 // s3 << (float)rtept->lat;
210 // s3 << rtept->action;
211 // ++rtept;
212 // }
213 // entries << entrySecRtePts;
214 // }
215
216 // }
217
218 //---------------------------------------
219 // prepare terminator
220 //---------------------------------------
221 rte_head_entry_t entryEnd;
222 entryEnd.type = CQlgtRoute::eEnd;
223 entries << entryEnd;
224
225 //---------------------------------------
226 //---------------------------------------
227 // now start to actually write data;
228 //---------------------------------------
229 //---------------------------------------
230 // write magic key
231 s.writeRawData("QLRte ", 9);
232
233 // calculate offset table
234 quint32 offset = entries.count() * 8 + 9;
235
236 QList<rte_head_entry_t>::iterator entry = entries.begin();
237 while(entry != entries.end())
238 {
239 entry->offset = offset;
240 offset += entry->data.size() + sizeof(quint32);
241 ++entry;
242 }
243
244 // write offset table
245 entry = entries.begin();
246 while(entry != entries.end())
247 {
248 s << entry->type << entry->offset;
249 ++entry;
250 }
251
252 // write entry data
253 entry = entries.begin();
254 while(entry != entries.end())
255 {
256 s << entry->data;
257 ++entry;
258 }
259
260
261 return s;
262 }
263
CQlgtRoute(quint64 id,QObject * parent)264 CQlgtRoute::CQlgtRoute(quint64 id, QObject* parent)
265 : QObject(parent)
266 , IItem(id)
267 {
268 }
269
~CQlgtRoute()270 CQlgtRoute::~CQlgtRoute()
271 {
272 }
273
274