source: ntrip/trunk/BNC/src/rinex/reqcedit.cpp@ 4451

Last change on this file since 4451 was 4364, checked in by mervart, 13 years ago
File size: 12.2 KB
RevLine 
[3901]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_reqcEdit
30 *
31 * Purpose: Edit/Concatenate RINEX Files
32 *
33 * Author: L. Mervart
34 *
35 * Created: 11-Apr-2012
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include "reqcedit.h"
[3972]43#include "bncapp.h"
[3901]44#include "bncsettings.h"
45
46using namespace std;
47
[4229]48const double rnxV2 = 2.11;
49const double rnxV3 = 3.01;
50
[3901]51// Constructor
52////////////////////////////////////////////////////////////////////////////
53t_reqcEdit::t_reqcEdit(QObject* parent) : QThread(parent) {
54
55 bncSettings settings;
56
57 _obsFileNames = settings.value("reqcObsFile").toString().split(",", QString::SkipEmptyParts);
58 _outObsFileName = settings.value("reqcOutObsFile").toString();
[3999]59 _navFileNames = settings.value("reqcNavFile").toString().split(",", QString::SkipEmptyParts);
60 _outNavFileName = settings.value("reqcOutNavFile").toString();
[4010]61 int version = settings.value("reqcRnxVersion").toInt();
62 if (version < 3) {
[4229]63 _rnxVersion = rnxV2;
[4010]64 }
65 else {
[4229]66 _rnxVersion = rnxV3;
[4010]67 }
[3981]68 _samplingRate = settings.value("reqcSampling").toInt();
[3989]69 _begTime = bncTime(settings.value("reqcStartDateTime").toString().toAscii().data());
70 _endTime = bncTime(settings.value("reqcEndDateTime").toString().toAscii().data());
[3901]71}
72
73// Destructor
74////////////////////////////////////////////////////////////////////////////
75t_reqcEdit::~t_reqcEdit() {
76 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
77 delete _rnxObsFiles[ii];
78 }
[4001]79 for (int ii = 0; ii < _ephs.size(); ii++) {
80 delete _ephs[ii];
81 }
[3901]82}
83
84//
85////////////////////////////////////////////////////////////////////////////
86void t_reqcEdit::run() {
[3998]87
88 editObservations();
[3901]89
[3998]90 editEphemerides();
91
92 bncApp* app = (bncApp*) qApp;
93 if ( app->mode() != bncApp::interactive) {
94 app->exit(0);
95 }
96 else {
97 emit finished();
98 deleteLater();
99 }
100}
101
[4254]102// Initialize input observation files, sort them according to start time
[3998]103////////////////////////////////////////////////////////////////////////////
[4254]104void t_reqcEdit::initRnxObsFiles(const QStringList& obsFileNames,
105 QVector<t_rnxObsFile*>& rnxObsFiles) {
[3998]106
[4254]107 QStringListIterator it(obsFileNames);
[3901]108 while (it.hasNext()) {
109 QString fileName = it.next();
[4080]110 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
111 QFileInfo fileInfo(fileName);
112 QDir dir = fileInfo.dir();
113 QStringList filters; filters << fileInfo.fileName();
114 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
115 while (it.hasNext()) {
116 QString filePath = it.next().filePath();
[4364]117 t_rnxObsFile* rnxObsFile = 0;
[4363]118 try {
[4364]119 rnxObsFile = new t_rnxObsFile(filePath, t_rnxObsFile::input);
[4363]120 rnxObsFiles.append(rnxObsFile);
121 }
122 catch (...) {
[4364]123 delete rnxObsFile;
124 cerr << "Error in rnxObsFile " << filePath.toAscii().data() << endl;
[4363]125 }
[4080]126 }
127 }
128 else {
[4364]129 t_rnxObsFile* rnxObsFile = 0;
[4363]130 try {
[4364]131 rnxObsFile = new t_rnxObsFile(fileName, t_rnxObsFile::input);
[4363]132 rnxObsFiles.append(rnxObsFile);
133 }
134 catch (...) {
[4364]135 cerr << "Error in rnxObsFile " << fileName.toAscii().data() << endl;
[4363]136 }
[4080]137 }
[3901]138 }
[4254]139 qStableSort(rnxObsFiles.begin(), rnxObsFiles.end(),
[3901]140 t_rnxObsFile::earlierStartTime);
[4254]141}
[3901]142
[4254]143//
144////////////////////////////////////////////////////////////////////////////
145void t_reqcEdit::editObservations() {
146
147 // Easy Exit
148 // ---------
149 if (_obsFileNames.isEmpty() || _outObsFileName.isEmpty()) {
150 return;
151 }
152
153 t_reqcEdit::initRnxObsFiles(_obsFileNames, _rnxObsFiles);
154
[3901]155 // Initialize output observation file
156 // ----------------------------------
157 t_rnxObsFile outObsFile(_outObsFileName, t_rnxObsFile::output);
158
159 // Loop over all input observation files
160 // -------------------------------------
161 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
162 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
163 if (ii == 0) {
[3956]164 outObsFile.setHeader(obsFile->header(), _rnxVersion);
[3992]165 if (_begTime.valid() && _begTime > outObsFile.startTime()) {
166 outObsFile.setStartTime(_begTime);
167 }
[4112]168 if (_samplingRate > outObsFile.interval()) {
169 outObsFile.setInterval(_samplingRate);
170 }
[3982]171 editRnxObsHeader(outObsFile);
[4117]172 bncSettings settings;
[4114]173 QMap<QString, QString> txtMap;
[4117]174 QString runBy = settings.value("reqcRunBy").toString();
175 if (!runBy.isEmpty()) {
176 txtMap["RUN BY"] = runBy;
177 }
178 QString comment = settings.value("reqcComment").toString();
179 if (!comment.isEmpty()) {
180 txtMap["COMMENT"] = comment;
181 }
[4137]182 outObsFile.writeHeader(&txtMap);
[3901]183 }
[4054]184 else {
185 outObsFile.checkNewHeader(obsFile->header());
186 }
[3994]187 t_rnxObsFile::t_rnxEpo* epo = 0;
[3901]188 while ( (epo = obsFile->nextEpoch()) != 0) {
[3993]189 if (_begTime.valid() && epo->tt < _begTime) {
190 continue;
191 }
192 if (_endTime.valid() && epo->tt > _endTime) {
193 break;
194 }
195
196 if (_samplingRate == 0 ||
197 fmod(round(epo->tt.gpssec()), _samplingRate) == 0) {
[3995]198 applyLLI(obsFile, epo);
[3990]199 outObsFile.writeEpoch(epo);
200 }
[3994]201 else {
[3995]202 rememberLLI(obsFile, epo);
[3994]203 }
[3901]204 }
205 }
206}
[3982]207
208// Change RINEX Header Content
209////////////////////////////////////////////////////////////////////////////
[3985]210void t_reqcEdit::editRnxObsHeader(t_rnxObsFile& obsFile) {
[3982]211
[3983]212 bncSettings settings;
213
214 QString oldMarkerName = settings.value("reqcOldMarkerName").toString();
215 QString newMarkerName = settings.value("reqcNewMarkerName").toString();
[4090]216 if (!newMarkerName.isEmpty()) {
217 if (oldMarkerName.isEmpty() ||
218 QRegExp(oldMarkerName).exactMatch(obsFile.markerName())) {
219 obsFile.setMarkerName(newMarkerName);
220 }
[3985]221 }
222
[3983]223 QString oldAntennaName = settings.value("reqcOldAntennaName").toString();
224 QString newAntennaName = settings.value("reqcNewAntennaName").toString();
[4090]225 if (!newAntennaName.isEmpty()) {
226 if (oldAntennaName.isEmpty() ||
227 QRegExp(oldAntennaName).exactMatch(obsFile.antennaName())) {
228 obsFile.setAntennaName(newAntennaName);
229 }
[3985]230 }
[3983]231
[3985]232 QString oldReceiverType = settings.value("reqcOldReceiverName").toString();
233 QString newReceiverType = settings.value("reqcNewReceiverName").toString();
[4090]234 if (!newReceiverType.isEmpty()) {
235 if (oldReceiverType.isEmpty() ||
236 QRegExp(oldReceiverType).exactMatch(obsFile.receiverType())) {
237 obsFile.setReceiverType(newReceiverType);
238 }
[3985]239 }
[3982]240}
[3994]241
242//
243////////////////////////////////////////////////////////////////////////////
[3995]244void t_reqcEdit::rememberLLI(const t_rnxObsFile* obsFile,
245 const t_rnxObsFile::t_rnxEpo* epo) {
[3994]246
[3995]247 if (_samplingRate == 0) {
248 return;
249 }
250
251 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
252 const t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
253 char sys = rnxSat.satSys;
[3997]254 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
255
[3995]256 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[3997]257 if (!_lli[prn].contains(iType)) {
258 _lli[prn][iType] = 0;
[3996]259 }
260 if (rnxSat.lli[iType] & 1) {
[3997]261 _lli[prn][iType] |= 1;
[3996]262 }
[3995]263 }
264 }
[3994]265}
266
267//
268////////////////////////////////////////////////////////////////////////////
[3995]269void t_reqcEdit::applyLLI(const t_rnxObsFile* obsFile,
270 t_rnxObsFile::t_rnxEpo* epo) {
[3996]271
272 if (_samplingRate == 0) {
[3995]273 return;
274 }
[3996]275
276 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
277 t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
278 char sys = rnxSat.satSys;
[3997]279 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
280
[3996]281 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[3997]282 if (_lli[prn].contains(iType) && _lli[prn][iType] & 1) {
[3996]283 rnxSat.lli[iType] |= 1;
284 }
285 }
286 }
287
288 _lli.clear();
[3994]289}
[3998]290
[4256]291/// Read All Ephemerides
[3998]292////////////////////////////////////////////////////////////////////////////
[4256]293void t_reqcEdit::readEphemerides(const QStringList& navFileNames,
294 QVector<t_eph*>& ephs) {
[3998]295
[4256]296 QStringListIterator it(navFileNames);
[3999]297 while (it.hasNext()) {
298 QString fileName = it.next();
[4081]299 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
300 QFileInfo fileInfo(fileName);
301 QDir dir = fileInfo.dir();
302 QStringList filters; filters << fileInfo.fileName();
303 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
304 while (it.hasNext()) {
305 QString filePath = it.next().filePath();
[4256]306 appendEphemerides(filePath, ephs);
[4000]307 }
308 }
[4081]309 else {
[4256]310 appendEphemerides(fileName, ephs);
[4081]311 }
[3999]312 }
[4256]313 qStableSort(ephs.begin(), ephs.end(), t_eph::earlierTime);
314}
[3999]315
[4256]316//
317////////////////////////////////////////////////////////////////////////////
318void t_reqcEdit::editEphemerides() {
319
320 // Easy Exit
321 // ---------
322 if (_navFileNames.isEmpty() || _outNavFileName.isEmpty()) {
323 return;
324 }
325
[4257]326 // Read Ephemerides
327 // ----------------
[4256]328 t_reqcEdit::readEphemerides(_navFileNames, _ephs);
329
[4229]330 // Check Satellite Systems
331 // -----------------------
332 bool haveGPS = false;
333 bool haveGlonass = false;
334 for (int ii = 0; ii < _ephs.size(); ii++) {
335 const t_eph* eph = _ephs[ii];
336 if (eph->type() == t_eph::GPS) {
337 haveGPS = true;
338 }
339 else if (eph->type() == t_eph::GLONASS) {
340 haveGlonass = true;
341 }
342 }
343
[4007]344 // Initialize output navigation file
345 // ---------------------------------
[4004]346 t_rnxNavFile outNavFile(_outNavFileName, t_rnxNavFile::output);
[4229]347
348 outNavFile.setGlonass(haveGlonass);
349
350 if (haveGPS && haveGlonass) {
351 outNavFile.setVersion(rnxV3);
352 }
353 else {
354 outNavFile.setVersion(_rnxVersion);
355 }
356
[4221]357 bncSettings settings;
358 QMap<QString, QString> txtMap;
359 QString runBy = settings.value("reqcRunBy").toString();
360 if (!runBy.isEmpty()) {
361 txtMap["RUN BY"] = runBy;
362 }
363 QString comment = settings.value("reqcComment").toString();
364 if (!comment.isEmpty()) {
365 txtMap["COMMENT"] = comment;
366 }
[4229]367
[4221]368 outNavFile.writeHeader(&txtMap);
[4009]369
[4004]370 // Loop over all ephemerides
371 // -------------------------
372 for (int ii = 0; ii < _ephs.size(); ii++) {
373 const t_eph* eph = _ephs[ii];
[4229]374 outNavFile.writeEph(eph);
[4004]375 }
[3998]376}
[4081]377
378//
379////////////////////////////////////////////////////////////////////////////
[4256]380void t_reqcEdit::appendEphemerides(const QString& fileName,
381 QVector<t_eph*>& ephs) {
[4081]382
383 t_rnxNavFile rnxNavFile(fileName, t_rnxNavFile::input);
384 for (unsigned ii = 0; ii < rnxNavFile.ephs().size(); ii++) {
385 t_eph* eph = rnxNavFile.ephs()[ii];
386 bool isNew = true;
[4256]387 for (int iOld = 0; iOld < ephs.size(); iOld++) {
388 const t_eph* ephOld = ephs[iOld];
[4236]389 if (ephOld->prn() == eph->prn() && ephOld->TOC() == eph->TOC()) {
[4081]390 isNew = false;
391 break;
392 }
393 }
394 if (isNew) {
395 if (eph->type() == t_eph::GPS) {
[4256]396 ephs.append(new t_ephGPS(*dynamic_cast<t_ephGPS*>(eph)));
[4081]397 }
398 else if (eph->type() == t_eph::GLONASS) {
[4256]399 ephs.append(new t_ephGlo(*dynamic_cast<t_ephGlo*>(eph)));
[4081]400 }
401 else if (eph->type() == t_eph::Galileo) {
[4256]402 ephs.append(new t_ephGal(*dynamic_cast<t_ephGal*>(eph)));
[4081]403 }
404 }
405 }
406}
Note: See TracBrowser for help on using the repository browser.