source: ntrip/trunk/BNC/src/rinex/rnxnavfile.cpp@ 7141

Last change on this file since 7141 was 7055, checked in by stuerze, 10 years ago

IOD data type changed, to support IODs computed from CRC over broadcasted ephemris and clock parameters

File size: 8.7 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 }
83
84 return success;
85}
86
87// Constructor
88////////////////////////////////////////////////////////////////////////////
89t_rnxNavFile::t_rnxNavFile(const QString& fileName, e_inpOut inpOut) {
90 _inpOut = inpOut;
91 _stream = 0;
92 _file = 0;
93 if (_inpOut == input) {
94 openRead(fileName);
95 }
96 else {
97 openWrite(fileName);
98 }
99}
100
101// Open for input
102////////////////////////////////////////////////////////////////////////////
103void t_rnxNavFile::openRead(const QString& fileName) {
104
105 _fileName = fileName; expandEnvVar(_fileName);
106 _file = new QFile(_fileName);
107 _file->open(QIODevice::ReadOnly | QIODevice::Text);
108 _stream = new QTextStream();
109 _stream->setDevice(_file);
110
111 _header.read(_stream);
112 this->read(_stream);
113}
114
115// Open for output
116////////////////////////////////////////////////////////////////////////////
117void t_rnxNavFile::openWrite(const QString& fileName) {
118
119 _fileName = fileName; expandEnvVar(_fileName);
120 _file = new QFile(_fileName);
121 _file->open(QIODevice::WriteOnly | QIODevice::Text);
122 _stream = new QTextStream();
123 _stream->setDevice(_file);
124}
125
126// Destructor
127////////////////////////////////////////////////////////////////////////////
128t_rnxNavFile::~t_rnxNavFile() {
129 close();
130 for (unsigned ii = 0; ii < _ephs.size(); ii++) {
131 delete _ephs[ii];
132 }
133}
134
135// Close
136////////////////////////////////////////////////////////////////////////////
137void t_rnxNavFile::close() {
138 delete _stream; _stream = 0;
139 delete _file; _file = 0;
140}
141
142// Read File Content
143////////////////////////////////////////////////////////////////////////////
144void t_rnxNavFile::read(QTextStream* stream) {
145
146 while (stream->status() == QTextStream::Ok && !stream->atEnd()) {
147 QString line = stream->readLine();
148 if (line.isEmpty()) {
149 continue;
150 }
151 QStringList hlp = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
152 QString prn;
153 if (version() >= 3.0) {
154 prn = hlp.at(0);
155 }
156 else {
157 if (glonass()) {
158 prn = QString("R%1").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
159 }
160 else {
161 prn = QString("G%1").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
162 }
163 }
164 t_eph* eph = 0;
165 QStringList lines; lines << line;
166 if (prn[0] == 'G') {
167 for (int ii = 1; ii < 8; ii++) {
168 lines << stream->readLine();
169 }
170 eph = new t_ephGPS(version(), lines);
171 }
172 else if (prn[0] == 'R') {
173 for (int ii = 1; ii < 4; ii++) {
174 lines << stream->readLine();
175 }
176 eph = new t_ephGlo(version(), lines);
177 }
178 else if (prn[0] == 'E') {
179 for (int ii = 1; ii < 8; ii++) {
180 lines << stream->readLine();
181 }
182 eph = new t_ephGal(version(), lines);
183 }
184 else if (prn[0] == 'J') {
185 for (int ii = 1; ii < 8; ii++) {
186 lines << stream->readLine();
187 }
188 eph = new t_ephGPS(version(), lines);
189 }
190 else if (prn[0] == 'S') {
191 for (int ii = 1; ii < 4; ii++) {
192 lines << stream->readLine();
193 }
194 eph = new t_ephSBAS(version(), lines);
195 }
196 else if (prn[0] == 'C') {
197 for (int ii = 1; ii < 8; ii++) {
198 lines << stream->readLine();
199 }
200 eph = new t_ephBDS(version(), lines);
201 }
202 if (eph && eph->checkState() != t_eph::bad) {
203 _ephs.push_back(eph);
204 }
205 else {
206 delete eph;
207 }
208 }
209}
210
211// Read Next Ephemeris
212////////////////////////////////////////////////////////////////////////////
213t_eph* t_rnxNavFile::getNextEph(const bncTime& tt,
214 const QMap<QString, unsigned long>* corrIODs) {
215
216 // Get Ephemeris according to IOD
217 // ------------------------------
218 if (corrIODs) {
219 QMapIterator<QString, unsigned long> itIOD(*corrIODs);
220 while (itIOD.hasNext()) {
221 itIOD.next();
222 QString prn = itIOD.key();
223 unsigned long iod = itIOD.value();
224 vector<t_eph*>::iterator it = _ephs.begin();
225 while (it != _ephs.end()) {
226 t_eph* eph = *it;
227 double dt = eph->TOC() - tt;
228 if (dt < 8*3600.0 && QString(eph->prn().toInternalString().c_str()) == prn && eph->IOD() == iod) {
229 it = _ephs.erase(it);
230 return eph;
231 }
232 ++it;
233 }
234 }
235 }
236
237 // Get Ephemeris according to time
238 // -------------------------------
239 else {
240 vector<t_eph*>::iterator it = _ephs.begin();
241 while (it != _ephs.end()) {
242 t_eph* eph = *it;
243
244 double dt = eph->TOC() - tt;
245
246 if (dt < 2*3600.0) {
247 it = _ephs.erase(it);
248 return eph;
249 }
250 ++it;
251 }
252 }
253
254 return 0;
255}
256
257//
258////////////////////////////////////////////////////////////////////////////
259void t_rnxNavFile::writeHeader(const QMap<QString, QString>* txtMap) {
260
261 QString runBy = BNC_CORE->userName();
262 QStringList comments;
263
264 if (txtMap) {
265 QMapIterator<QString, QString> it(*txtMap);
266 while (it.hasNext()) {
267 it.next();
268 if (it.key() == "RUN BY") {
269 runBy = it.value();
270 }
271 else if (it.key() == "COMMENT") {
272 comments = it.value().split("\\n", QString::SkipEmptyParts);
273 }
274 }
275 }
276
277 if (version() < 3.0) {
278 const QString fmt = glonass() ? "%1 GLONASS navigation data"
279 : "%1 Navigation data";
280 *_stream << QString(fmt)
281 .arg(_header._version, 9, 'f', 2)
282 .leftJustified(60)
283 << "RINEX VERSION / TYPE\n";
284 }
285 else {
286 *_stream << QString("%1 N: GNSS NAV DATA M: MIXED")
287 .arg(_header._version, 9, 'f', 2)
288 .leftJustified(60)
289 << "RINEX VERSION / TYPE\n";
290 }
291
292 const QString fmtDate = (version() < 3.0) ? "dd-MMM-yy hh:mm"
293 : "yyyyMMdd hhmmss UTC";
294 *_stream << QString("%1%2%3")
295 .arg(BNC_CORE->pgmName(), -20)
296 .arg(runBy.trimmed().left(20), -20)
297 .arg(QDateTime::currentDateTime().toUTC().toString(fmtDate), -20)
298 .leftJustified(60)
299 << "PGM / RUN BY / DATE\n";
300
301 QStringListIterator itCmnt(comments);
302 while (itCmnt.hasNext()) {
303 *_stream << itCmnt.next().trimmed().left(60).leftJustified(60) << "COMMENT\n";
304 }
305
306 *_stream << QString()
307 .leftJustified(60)
308 << "END OF HEADER\n";
309}
310
311//
312////////////////////////////////////////////////////////////////////////////
313void t_rnxNavFile::writeEph(const t_eph* eph) {
314 *_stream << eph->toString(version());
315}
Note: See TracBrowser for help on using the repository browser.