source: ntrip/trunk/BNC/bncrinex.cpp@ 157

Last change on this file since 157 was 157, checked in by mervart, 18 years ago

* empty log message *

File size: 10.3 KB
Line 
1
2/* -------------------------------------------------------------------------
3 * BKG NTRIP Client
4 * -------------------------------------------------------------------------
5 *
6 * Class: bncRinex
7 *
8 * Purpose: writes RINEX files
9 *
10 * Author: L. Mervart
11 *
12 * Created: 27-Aug-2006
13 *
14 * Changes:
15 *
16 * -----------------------------------------------------------------------*/
17
18#include <QSettings>
19#include <QDir>
20#include <QUrl>
21#include <QDate>
22#include <QFile>
23#include <QTextStream>
24#include <iomanip>
25
26#include "bncrinex.h"
27#include "bncapp.h"
28#include "bncutils.h"
29#include "bncconst.h"
30
31using namespace std;
32
33// Constructor
34////////////////////////////////////////////////////////////////////////////
35bncRinex::bncRinex(const char* StatID) {
36 _statID = StatID;
37 _headerWritten = false;
38 readSkeleton();
39
40 QSettings settings;
41 _rnxScriptName = settings.value("rnxScript").toString();
42 expandEnvVar(_rnxScriptName);
43
44 // Find the corresponding mountPoint
45 // ---------------------------------
46 QListIterator<QString> it(settings.value("mountPoints").toStringList());
47 while (it.hasNext()) {
48 QString hlp = it.next();
49 if (hlp.indexOf(_statID) != -1) {
50 QUrl url(hlp);
51 _mountPoint = url.host() + url.path();
52 break;
53 }
54 }
55
56 _pgmName = ((bncApp*)qApp)->bncVersion().leftJustified(20, ' ', true);
57 _userName = QString("${USER}").leftJustified(20, ' ', true);
58 expandEnvVar(_userName);
59}
60
61// Destructor
62////////////////////////////////////////////////////////////////////////////
63bncRinex::~bncRinex() {
64 _out.close();
65}
66
67// Read Skeleton Header File
68////////////////////////////////////////////////////////////////////////////
69void bncRinex::readSkeleton() {
70
71 // Resolve Skeleton File Name
72 // --------------------------
73 QSettings settings;
74 QString sklName = settings.value("rnxPath").toString();
75 expandEnvVar(sklName);
76 if ( sklName[sklName.length()-1] != QDir::separator() ) {
77 sklName += QDir::separator();
78 }
79 sklName += _statID.left(4) + "." + settings.value("rnxSkel").toString();
80
81 // Read the File
82 // -------------
83 QFile skl(sklName);
84 if ( skl.exists() && skl.open(QIODevice::ReadOnly) ) {
85 QTextStream in(&skl);
86 while ( !in.atEnd() ) {
87 _headerLines.append( in.readLine() );
88 if (_headerLines.last().indexOf("END OF HEADER") != -1) {
89 break;
90 }
91 }
92 }
93}
94
95// File Name according to RINEX Standards
96////////////////////////////////////////////////////////////////////////////
97void bncRinex::resolveFileName(const QDateTime& datTim) {
98
99 QSettings settings;
100 QString path = settings.value("rnxPath").toString();
101 expandEnvVar(path);
102
103 if ( path[path.length()-1] != QDir::separator() ) {
104 path += QDir::separator();
105 }
106
107 QString intStr = settings.value("rnxIntr").toString();
108 QString hlpStr;
109
110 QTime nextTime;
111 QDate nextDate;
112
113 if (intStr == "15 min") {
114 char ch = 'A' + datTim.time().hour();
115 hlpStr = ch;
116 if (datTim.time().minute() < 15) {
117 hlpStr += "00";
118 nextTime.setHMS(datTim.time().hour(), 15, 0);
119 nextDate = datTim.date();
120 }
121 else if (datTim.time().minute() < 30) {
122 hlpStr += "15";
123 nextTime.setHMS(datTim.time().hour(), 30, 0);
124 nextDate = datTim.date();
125 }
126 else if (datTim.time().minute() < 45) {
127 hlpStr += "30";
128 nextTime.setHMS(datTim.time().hour(), 45, 0);
129 nextDate = datTim.date();
130 }
131 else {
132 hlpStr += "45";
133 if (datTim.time().hour() < 23) {
134 nextTime.setHMS(datTim.time().hour() + 1 , 0, 0);
135 nextDate = datTim.date();
136 }
137 else {
138 nextTime.setHMS(0, 0, 0);
139 nextDate = datTim.date().addDays(1);
140 }
141 }
142 }
143 else if (intStr == "1 hour") {
144 char ch = 'A' + datTim.time().hour();
145 hlpStr = ch;
146 if (datTim.time().hour() < 23) {
147 nextTime.setHMS(datTim.time().hour() + 1 , 0, 0);
148 nextDate = datTim.date();
149 }
150 else {
151 nextTime.setHMS(0, 0, 0);
152 nextDate = datTim.date().addDays(1);
153 }
154 }
155 else {
156 hlpStr = "0";
157 nextTime.setHMS(0, 0, 0);
158 nextDate = datTim.date().addDays(1);
159 }
160 _nextCloseEpoch = QDateTime(nextDate, nextTime);
161
162 path += _statID.left(4) +
163 QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0')) +
164 hlpStr +
165 datTim.toString(".yyO");
166
167 _fName = path.toAscii();
168}
169
170// Write RINEX Header
171////////////////////////////////////////////////////////////////////////////
172void bncRinex::writeHeader(const QDateTime& datTim) {
173
174 // Open the Output File
175 // --------------------
176 resolveFileName(datTim);
177 _out.open(_fName.data());
178 _out.setf(ios::showpoint | ios::fixed);
179
180 // Copy Skeleton Header
181 // --------------------
182 if (_headerLines.size() > 0) {
183 QStringListIterator it(_headerLines);
184 while (it.hasNext()) {
185 QString line = it.next();
186 if (line.indexOf("PGM / RUN BY / DATE") != -1) {
187 QString hlp = QDate::currentDate().toString("dd-MMM-yyyy ");
188 _out << _pgmName.toAscii().data() << _userName.toAscii().data()
189 << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
190 }
191 else if (line.indexOf("# / TYPES OF OBSERV") != -1) {
192 _out << " 4 P1 P2 L1 L2"
193 " # / TYPES OF OBSERV" << endl;
194 }
195 else if (line.indexOf("TIME OF FIRST OBS") != -1) {
196 _out << datTim.toString(" yyyy MM dd"
197 " hh mm ss.zzz0000").toAscii().data();
198 _out << " TIME OF FIRST OBS" << endl;
199 QString hlp = QString("GENERATED FROM STREAM %1").arg(_mountPoint)
200 .leftJustified(60, ' ', true);
201 _out << hlp.toAscii().data() << "COMMENT" << endl;
202 }
203 else {
204 _out << line.toAscii().data() << endl;
205 }
206 }
207 }
208
209 // Write Dummy Header
210 // ------------------
211 else {
212 double approxPos[3]; approxPos[0] = approxPos[1] = approxPos[2] = 0.0;
213 double antennaNEU[3]; antennaNEU[0] = antennaNEU[1] = antennaNEU[2] = 0.0;
214
215 _out << " 2.10 OBSERVATION DATA G (GPS) RINEX VERSION / TYPE" << endl;
216 QString hlp = QDate::currentDate().toString("dd-MMM-yyyy ");
217 _out << _pgmName.toAscii().data() << _userName.toAscii().data()
218 << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
219 _out.setf(ios::left);
220 _out << setw(60) << _statID.data() << "MARKER NAME" << endl;
221 _out << setw(60) << "BKG" << "OBSERVER / AGENCY" << endl;
222 _out << setw(20) << "unknown"
223 << setw(20) << "unknown"
224 << setw(20) << "unknown" << "REC # / TYPE / VERS" << endl;
225 _out << setw(20) << "unknown"
226 << setw(20) << "unknown"
227 << setw(20) << " " << "ANT # / TYPE" << endl;
228 _out.unsetf(ios::left);
229 _out << setw(14) << setprecision(4) << approxPos[0]
230 << setw(14) << setprecision(4) << approxPos[1]
231 << setw(14) << setprecision(4) << approxPos[2]
232 << " " << "APPROX POSITION XYZ" << endl;
233 _out << setw(14) << setprecision(4) << antennaNEU[0]
234 << setw(14) << setprecision(4) << antennaNEU[1]
235 << setw(14) << setprecision(4) << antennaNEU[2]
236 << " " << "ANTENNA: DELTA H/E/N" << endl;
237 _out << " 1 1 WAVELENGTH FACT L1/2" << endl;
238 _out << " 4 P1 P2 L1 L2 # / TYPES OF OBSERV" << endl;
239 _out << datTim.toString(" yyyy MM dd"
240 " hh mm ss.zzz0000").toAscii().data();
241 _out << " " << "TIME OF FIRST OBS" << endl;
242 hlp = QString("GENERATED FROM STREAM %1").arg(_mountPoint)
243 .leftJustified(60, ' ', true);
244 _out << hlp.toAscii().data() << "COMMENT" << endl;
245 _out << " END OF HEADER" << endl;
246 }
247
248 _headerWritten = true;
249}
250
251// Stores Observation into Internal Array
252////////////////////////////////////////////////////////////////////////////
253void bncRinex::deepCopy(const Observation* obs) {
254 Observation* newObs = new Observation();
255 memcpy(newObs, obs, sizeof(*obs));
256 _obs.push_back(newObs);
257}
258
259// Write One Epoch into the RINEX File
260////////////////////////////////////////////////////////////////////////////
261void bncRinex::dumpEpoch() {
262
263 // Easy Return
264 // -----------
265 if (_obs.isEmpty()) {
266 return;
267 }
268
269 // Time of Epoch
270 // -------------
271 Observation* firstObs = *_obs.begin();
272
273 QDateTime datTim = dateAndTimeFromGPSweek( firstObs->GPSWeek,
274 firstObs->GPSWeeks +
275 fmod(firstObs->sec, 1.0) );
276
277 // Close the file
278 // --------------
279 if (_nextCloseEpoch.isValid() && datTim >= _nextCloseEpoch) {
280 closeFile();
281 _headerWritten = false;
282 }
283
284 // Write RINEX Header
285 // ------------------
286 if (!_headerWritten) {
287 writeHeader(datTim);
288 }
289
290 _out << datTim.toString(" yy MM dd hh mm ss.zzz0000").toAscii().data()
291 << " " << 0 << setw(3) << _obs.size();
292
293 QListIterator<Observation*> it(_obs); int iSat = 0;
294 while (it.hasNext()) {
295 iSat++;
296 Observation* ob = it.next();
297 _out << " " << setw(2) << int(ob->SVPRN);
298 if (iSat == 12 && it.hasNext()) {
299 _out << endl << " ";
300 iSat = 0;
301 }
302 }
303 _out << endl;
304
305 it.toFront();
306 while (it.hasNext()) {
307 Observation* ob = it.next();
308
309 char lli = ' ';
310 char snr = ' ';
311 _out << setw(14) << setprecision(3) << ob->C1 << lli << snr;
312 _out << setw(14) << setprecision(3) << ob->P2 << lli << snr;
313 _out << setw(14) << setprecision(3) << ob->L1 / t_CST::lambda1 << lli << snr;
314 _out << setw(14) << setprecision(3) << ob->L2 / t_CST::lambda2 << lli << snr;
315 _out << endl;
316
317 delete ob;
318 }
319
320 _out.flush();
321 _obs.clear();
322}
323
324// Close the Old RINEX File
325////////////////////////////////////////////////////////////////////////////
326void bncRinex::closeFile() {
327 _out.close();
328 if (!_rnxScriptName.isEmpty()) {
329 _rnxScript.start(_rnxScriptName, QStringList() << _fName);
330 }
331}
Note: See TracBrowser for help on using the repository browser.