source: ntrip/branches/BNC_2.12/src/rinex/rnxnavfile.cpp @ 8351

Last change on this file since 8351 was 8351, checked in by stuerze, 15 months ago

individual satellite system will be considerred now during concatenation of ephemeris files

File size: 9.9 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class:      t_rnxNavFile
30 *
31 * Purpose:    Reads RINEX Navigation File
32 *
33 * Author:     L. Mervart
34 *
35 * Created:    24-Jan-2012
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include <newmatio.h>
43#include "rnxnavfile.h"
44#include "bnccore.h"
45#include "bncutils.h"
46#include "ephemeris.h"
47
48using namespace std;
49
50// Constructor
51////////////////////////////////////////////////////////////////////////////
52t_rnxNavFile::t_rnxNavHeader::t_rnxNavHeader() {
53  _version = 0.0;
54  _glonass = false;
55}
56
57// Destructor
58////////////////////////////////////////////////////////////////////////////
59t_rnxNavFile::t_rnxNavHeader::~t_rnxNavHeader() {
60}
61
62// Read Header
63////////////////////////////////////////////////////////////////////////////
64t_irc t_rnxNavFile::t_rnxNavHeader::read(QTextStream* stream) {
65  while (stream->status() == QTextStream::Ok && !stream->atEnd()) {
66    QString line = stream->readLine();
67    if (line.isEmpty()) {
68      continue;
69    }
70    QString value = line.left(60).trimmed();
71    QString key   = line.mid(60).trimmed();
72    if      (key == "END OF HEADER") {
73      break;
74    }
75    else if (key == "RINEX VERSION / TYPE") {
76      QTextStream in(value.toAscii(), QIODevice::ReadOnly);
77      in >> _version;
78      if (value.indexOf("GLONASS") != -1) {
79        _glonass = true;
80      }
81    }
82    else if (key == "COMMENT") {
83      _comments.append(value.trimmed());
84    }
85  }
86
87  return success;
88}
89
90// Constructor
91////////////////////////////////////////////////////////////////////////////
92t_rnxNavFile::t_rnxNavFile(const QString& fileName, e_inpOut inpOut) {
93  _inpOut = inpOut;
94  _stream = 0;
95  _file   = 0;
96  if (_inpOut == input) {
97    openRead(fileName);
98  }
99  else {
100    openWrite(fileName);
101  }
102}
103
104// Open for input
105////////////////////////////////////////////////////////////////////////////
106void t_rnxNavFile::openRead(const QString& fileName) {
107
108  _fileName = fileName; expandEnvVar(_fileName);
109  _file     = new QFile(_fileName);
110  _file->open(QIODevice::ReadOnly | QIODevice::Text);
111  _stream = new QTextStream();
112  _stream->setDevice(_file);
113
114  _header.read(_stream);
115  this->read(_stream);
116}
117
118// Open for output
119////////////////////////////////////////////////////////////////////////////
120void t_rnxNavFile::openWrite(const QString& fileName) {
121
122  _fileName = fileName; expandEnvVar(_fileName);
123  _file     = new QFile(_fileName);
124  _file->open(QIODevice::WriteOnly | QIODevice::Text);
125  _stream = new QTextStream();
126  _stream->setDevice(_file);
127}
128
129// Destructor
130////////////////////////////////////////////////////////////////////////////
131t_rnxNavFile::~t_rnxNavFile() {
132  close();
133  for (unsigned ii = 0; ii < _ephs.size(); ii++) {
134    delete _ephs[ii];
135  }
136}
137
138// Close
139////////////////////////////////////////////////////////////////////////////
140void t_rnxNavFile::close() {
141  delete _stream; _stream = 0;
142  delete _file;   _file = 0;
143}
144
145// Read File Content
146////////////////////////////////////////////////////////////////////////////
147void t_rnxNavFile::read(QTextStream* stream) {
148
149  while (stream->status() == QTextStream::Ok && !stream->atEnd()) {
150    QString line = stream->readLine();
151    if (line.isEmpty()) {
152      continue;
153    }
154    QStringList hlp = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
155    QString prn;
156    if (version() >= 3.0) {
157      prn = hlp.at(0);
158    }
159    else {
160      if (glonass()) {
161        prn = QString("R%1_0").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
162      }
163      else {
164        prn = QString("G%1_0").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
165      }
166    }
167
168    t_eph* eph = 0;
169    QStringList lines; lines << line;
170    if      (prn[0] == 'G') {
171      for (int ii = 1; ii < 8; ii++) {
172        lines << stream->readLine();
173      }
174      eph = new t_ephGPS(version(), lines);
175    }
176    else if (prn[0] == 'R') {
177      for (int ii = 1; ii < 4; ii++) {
178        lines << stream->readLine();
179      }
180      eph = new t_ephGlo(version(), lines);
181    }
182    else if (prn[0] == 'E') {
183      for (int ii = 1; ii < 8; ii++) {
184        lines << stream->readLine();
185      }
186      eph = new t_ephGal(version(), lines);
187    }
188    else if (prn[0] == 'J') {
189      for (int ii = 1; ii < 8; ii++) {
190        lines << stream->readLine();
191      }
192      eph = new t_ephGPS(version(), lines);
193    }
194    else if (prn[0] == 'S') {
195      for (int ii = 1; ii < 4; ii++) {
196        lines << stream->readLine();
197      }
198      eph = new t_ephSBAS(version(), lines);
199    }
200    else if (prn[0] == 'C') {
201      for (int ii = 1; ii < 8; ii++) {
202        lines << stream->readLine();
203      }
204      eph = new t_ephBDS(version(), lines);
205    }
206    else if (prn[0] == 'I') {
207      for (int ii = 1; ii < 8; ii++) {
208        lines << stream->readLine();
209      }
210      eph = new t_ephGPS(version(), lines);
211    }
212    if (eph &&
213        eph->checkState() != t_eph::bad &&
214        eph->checkState() != t_eph::outdated) {
215      _ephs.push_back(eph);
216    }
217    else {
218      delete eph;
219    }
220  }
221}
222
223// Read Next Ephemeris
224////////////////////////////////////////////////////////////////////////////
225t_eph* t_rnxNavFile::getNextEph(const bncTime& tt,
226                                const QMap<QString, unsigned int>* corrIODs) {
227
228  // Get Ephemeris according to IOD
229  // ------------------------------
230  if (corrIODs) {
231    QMapIterator<QString, unsigned int> itIOD(*corrIODs);
232    while (itIOD.hasNext()) {
233      itIOD.next();
234      QString prn = itIOD.key();
235      unsigned int iod = itIOD.value();
236      vector<t_eph*>::iterator it = _ephs.begin();
237      while (it != _ephs.end()) {
238        t_eph* eph = *it;
239        double dt = eph->TOC() - tt;
240        if (dt < 8*3600.0 && QString(eph->prn().toInternalString().c_str()) == prn && eph->IOD() == iod) {
241          it = _ephs.erase(it);
242          return eph;
243        }
244        ++it;
245      }
246    }
247  }
248
249  // Get Ephemeris according to time
250  // -------------------------------
251  else {
252    vector<t_eph*>::iterator it = _ephs.begin();
253    while (it != _ephs.end()) {
254      t_eph* eph = *it;
255      double dt = eph->TOC() - tt;
256      if (dt < 2*3600.0) {
257        it = _ephs.erase(it);
258        return eph;
259      }
260      ++it;
261    }
262  }
263
264  return 0;
265}
266
267//
268////////////////////////////////////////////////////////////////////////////
269void t_rnxNavFile::writeHeader(const QMap<QString, QString>* txtMap) {
270
271  QString     runBy = BNC_CORE->userName();
272  QStringList comments;
273
274  if (txtMap) {
275    QMapIterator<QString, QString> it(*txtMap);
276    while (it.hasNext()) {
277      it.next();
278      if      (it.key() == "RUN BY") {
279        runBy = it.value();
280      }
281      else if (it.key() == "COMMENT") {
282        comments = it.value().split("\\n", QString::SkipEmptyParts);
283      }
284    }
285  }
286
287  if (version() < 3.0) {
288    const QString fmt = glonass() ? "%1           GLONASS navigation data"
289                                  : "%1           Navigation data";
290    *_stream << QString(fmt)
291      .arg(_header._version, 9, 'f', 2)
292      .leftJustified(60)
293             << "RINEX VERSION / TYPE\n";
294  }
295  else {
296        QString fmt;
297    t_eph::e_type sys = satSystem();
298    switch(sys) {
299      case t_eph::e_type::GPS:
300        fmt.append("%1           N: GNSS NAV DATA    G: GPS");
301        break;
302      case t_eph::e_type::GLONASS:
303        fmt.append("%1           N: GNSS NAV DATA    R: GLONASS");
304        break;
305      case t_eph::e_type::Galileo:
306        fmt.append("%1           N: GNSS NAV DATA    E: Galileo");
307        break;
308      case t_eph::e_type::QZSS:
309        fmt.append("%1           N: GNSS NAV DATA    J: QZSS");
310        break;
311      case t_eph::e_type::BDS:
312        fmt.append("%1           N: GNSS NAV DATA    C: BDS");
313        break;
314      case t_eph::e_type::IRNSS:
315        fmt.append("%1           N: GNSS NAV DATA    I: IRNSS");
316        break;
317      case t_eph::e_type::SBAS:
318        fmt.append("%1           N: GNSS NAV DATA    S: SBAS");
319        break;
320      case t_eph::e_type::unknown:
321        fmt.append("%1           N: GNSS NAV DATA    M: MIXED");
322        break;
323    }
324    *_stream << fmt
325      .arg(_header._version, 9, 'f', 2)
326      .leftJustified(60)
327             << "RINEX VERSION / TYPE\n";
328  }
329
330  const QString fmtDate = (version() < 3.0) ? "dd-MMM-yy hh:mm"
331                                            : "yyyyMMdd hhmmss UTC";
332  *_stream << QString("%1%2%3")
333    .arg(BNC_CORE->pgmName(), -20)
334    .arg(runBy.trimmed().left(20), -20)
335    .arg(QDateTime::currentDateTime().toUTC().toString(fmtDate), -20)
336    .leftJustified(60)
337           << "PGM / RUN BY / DATE\n";
338
339  QStringListIterator itCmnt(comments);
340  while (itCmnt.hasNext()) {
341    *_stream << itCmnt.next().trimmed().left(60).leftJustified(60) << "COMMENT\n";
342  }
343
344  *_stream << QString()
345    .leftJustified(60)
346           << "END OF HEADER\n";
347}
348
349//
350////////////////////////////////////////////////////////////////////////////
351void t_rnxNavFile::writeEph(const t_eph* eph) {
352  *_stream << eph->toString(version());
353}
Note: See TracBrowser for help on using the repository browser.