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

Last change on this file since 9765 was 9765, checked in by stuerze, 22 months ago

some more changes to consider RINEX Version 4 nav file (EPH key only)

File size: 23.8 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 *
[7474]37 * Changes:
[3901]38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include "reqcedit.h"
[5070]43#include "bnccore.h"
[3901]44#include "bncsettings.h"
[4516]45#include "bncutils.h"
[5378]46#include "rnxobsfile.h"
47#include "rnxnavfile.h"
[3901]48
49using namespace std;
50
51// Constructor
52////////////////////////////////////////////////////////////////////////////
53t_reqcEdit::t_reqcEdit(QObject* parent) : QThread(parent) {
54
55 bncSettings settings;
56
[4516]57 _logFileName = settings.value("reqcOutLogFile").toString(); expandEnvVar(_logFileName);
58 _logFile = 0;
59 _log = 0;
[3901]60 _obsFileNames = settings.value("reqcObsFile").toString().split(",", QString::SkipEmptyParts);
61 _outObsFileName = settings.value("reqcOutObsFile").toString();
[3999]62 _navFileNames = settings.value("reqcNavFile").toString().split(",", QString::SkipEmptyParts);
63 _outNavFileName = settings.value("reqcOutNavFile").toString();
[4010]64 int version = settings.value("reqcRnxVersion").toInt();
[9765]65 if (version == 2) {
[8127]66 _rnxVersion = defaultRnxObsVersion2;
[4010]67 }
[9765]68 if (version == 3) {
[8127]69 _rnxVersion = defaultRnxObsVersion3;
[4010]70 }
[9765]71 if (version == 4) {
72 _rnxVersion = defaultRnxObsVersion4;
73 }
[8397]74 _samplingRate = settings.value("reqcSampling").toString().split("sec").first().toDouble();
[8204]75 _begTime = bncTime(settings.value("reqcStartDateTime").toString().toLatin1().data());
76 _endTime = bncTime(settings.value("reqcEndDateTime").toString().toLatin1().data());
[6898]77
[3901]78}
79
80// Destructor
81////////////////////////////////////////////////////////////////////////////
82t_reqcEdit::~t_reqcEdit() {
83 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
84 delete _rnxObsFiles[ii];
85 }
[4001]86 for (int ii = 0; ii < _ephs.size(); ii++) {
87 delete _ephs[ii];
88 }
[4516]89 delete _log; _log = 0;
90 delete _logFile; _logFile = 0;
[3901]91}
92
[7474]93//
[3901]94////////////////////////////////////////////////////////////////////////////
95void t_reqcEdit::run() {
[7474]96
[4516]97 // Open Log File
98 // -------------
[7280]99 if (!_logFileName.isEmpty()) {
100 _logFile = new QFile(_logFileName);
101 if (_logFile->open(QIODevice::WriteOnly | QIODevice::Text)) {
102 _log = new QTextStream();
103 _log->setDevice(_logFile);
104 }
[4518]105 }
[4516]106
[4518]107 // Log File Header
108 // ---------------
109 if (_log) {
[4519]110 *_log << QByteArray(78, '-') << endl;
[7992]111 *_log << "RINEX File Editing\n";
[4519]112 *_log << QByteArray(78, '-') << endl;
[4520]113
[4523]114 *_log << QByteArray("Program").leftJustified(15) << ": "
[5068]115 << BNC_CORE->pgmName() << endl;
[4523]116 *_log << QByteArray("Run by").leftJustified(15) << ": "
[5068]117 << BNC_CORE->userName() << endl;
[4523]118 *_log << QByteArray("Date").leftJustified(15) << ": "
[4521]119 << QDateTime::currentDateTime().toUTC().toString("yyyy-MM-dd hh:mm:ss") << endl;
[4523]120 *_log << QByteArray("RINEX Version").leftJustified(15) << ": "
[4522]121 << _rnxVersion << endl;
[4523]122 *_log << QByteArray("Sampling").leftJustified(15) << ": "
[8397]123 << _samplingRate << " sec" << endl;
[4523]124 *_log << QByteArray("Start time").leftJustified(15) << ": "
[7474]125 << _begTime.datestr().c_str() << ' '
[4522]126 << _begTime.timestr(0).c_str() << endl;
[4523]127 *_log << QByteArray("End time").leftJustified(15) << ": "
[7474]128 << _endTime.datestr().c_str() << ' '
[4522]129 << _endTime.timestr(0).c_str() << endl;
[4523]130 *_log << QByteArray("Input Obs Files").leftJustified(15) << ": "
131 << _obsFileNames.join(",") << endl;
132 *_log << QByteArray("Input Nav Files").leftJustified(15) << ": "
133 << _navFileNames.join(",") << endl;
134 *_log << QByteArray("Output Obs File").leftJustified(15) << ": "
135 << _outObsFileName << endl;
136 *_log << QByteArray("Output Nav File").leftJustified(15) << ": "
137 << _outNavFileName << endl;
[4520]138
139 *_log << QByteArray(78, '-') << endl;
[4518]140 _log->flush();
141 }
142
[4516]143 // Handle Observation Files
144 // ------------------------
[3998]145 editObservations();
[3901]146
[4516]147 // Handle Navigations Files
148 // ------------------------
[3998]149 editEphemerides();
150
[4516]151 // Exit (thread)
152 // -------------
[5072]153 if (BNC_CORE->mode() != t_bncCore::interactive) {
[5066]154 qApp->exit(0);
[7942]155 msleep(100); //sleep 0.1 sec
[3998]156 }
157 else {
158 emit finished();
159 deleteLater();
160 }
[7980]161
[3998]162}
163
[4254]164// Initialize input observation files, sort them according to start time
[3998]165////////////////////////////////////////////////////////////////////////////
[7474]166void t_reqcEdit::initRnxObsFiles(const QStringList& obsFileNames,
[4525]167 QVector<t_rnxObsFile*>& rnxObsFiles,
168 QTextStream* log) {
[3998]169
[4254]170 QStringListIterator it(obsFileNames);
[3901]171 while (it.hasNext()) {
172 QString fileName = it.next();
[4080]173 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
174 QFileInfo fileInfo(fileName);
175 QDir dir = fileInfo.dir();
176 QStringList filters; filters << fileInfo.fileName();
177 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
178 while (it.hasNext()) {
[7474]179 QString filePath = it.next().filePath();
[4364]180 t_rnxObsFile* rnxObsFile = 0;
[4363]181 try {
[4364]182 rnxObsFile = new t_rnxObsFile(filePath, t_rnxObsFile::input);
[4363]183 rnxObsFiles.append(rnxObsFile);
184 }
185 catch (...) {
[4364]186 delete rnxObsFile;
[4525]187 if (log) {
[8204]188 *log << "Error in rnxObsFile " << filePath.toLatin1().data() << endl;
[4525]189 }
[4363]190 }
[4080]191 }
192 }
193 else {
[4364]194 t_rnxObsFile* rnxObsFile = 0;
[4363]195 try {
[4364]196 rnxObsFile = new t_rnxObsFile(fileName, t_rnxObsFile::input);
[4363]197 rnxObsFiles.append(rnxObsFile);
198 }
199 catch (...) {
[4525]200 if (log) {
[8204]201 *log << "Error in rnxObsFile " << fileName.toLatin1().data() << endl;
[4525]202 }
[4363]203 }
[4080]204 }
[3901]205 }
[7474]206 qStableSort(rnxObsFiles.begin(), rnxObsFiles.end(),
[3901]207 t_rnxObsFile::earlierStartTime);
[4254]208}
[3901]209
[7474]210//
[4254]211////////////////////////////////////////////////////////////////////////////
212void t_reqcEdit::editObservations() {
213
214 // Easy Exit
215 // ---------
216 if (_obsFileNames.isEmpty() || _outObsFileName.isEmpty()) {
217 return;
218 }
219
[4525]220 t_reqcEdit::initRnxObsFiles(_obsFileNames, _rnxObsFiles, _log);
[4254]221
[3901]222 // Initialize output observation file
223 // ----------------------------------
224 t_rnxObsFile outObsFile(_outObsFileName, t_rnxObsFile::output);
[7474]225
[6118]226 // Select observation types
227 // ------------------------
228 bncSettings settings;
229 QStringList useObsTypes = settings.value("reqcUseObsTypes").toString().split(" ", QString::SkipEmptyParts);
230
[6130]231 // Put together all observation types
232 // ----------------------------------
233 if (_rnxObsFiles.size() > 1 && useObsTypes.size() == 0) {
234 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
235 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
236 for (int iSys = 0; iSys < obsFile->numSys(); iSys++) {
237 char sys = obsFile->system(iSys);
238 if (sys != ' ') {
[6131]239 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
240 QString type = obsFile->obsType(sys, iType);
[6132]241 if (_rnxVersion < 3.0) {
242 useObsTypes << type;
243 }
244 else {
245 useObsTypes << QString(sys) + ":" + type;
246 }
[6131]247 }
[6130]248 }
249 }
250 }
[6132]251 useObsTypes.removeDuplicates();
[6130]252 }
253
[6841]254 // Put together all phase shifts
255 // -----------------------------
256 QStringList phaseShifts;
257 if (_rnxVersion >= 3.0 && _rnxObsFiles.size() > 1) {
258 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
259 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
260 phaseShifts << obsFile->phaseShifts();
261 }
[9639]262 phaseShifts.removeDuplicates();
[6841]263 }
264
265 // Put together all GLONASS biases
266 // -------------------------------
267 QStringList gloBiases;
268 if (_rnxVersion >= 3.0 && _rnxObsFiles.size() > 1) {
269 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
270 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
271 if (ii == 0 && obsFile->numGloBiases() == 4) {
272 break;
273 }
274 else {
275 gloBiases << obsFile->gloBiases();
276 }
277 }
278 gloBiases.removeDuplicates();
279 }
280
281 // Put together all GLONASS slots
282 // -----------------------------
283 QStringList gloSlots;
284 if (_rnxVersion >= 3.0 && _rnxObsFiles.size() > 1) {
285 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
286 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
287 if (ii == 0 &&
288 obsFile->numGloSlots() == signed(t_prn::MAXPRN_GLONASS)) {
289 break;
290 }
291 else {
292 gloSlots << obsFile->gloSlots();
293 }
294 }
295 gloSlots.removeDuplicates();
296 }
297
[3901]298 // Loop over all input observation files
299 // -------------------------------------
300 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
301 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
[4524]302 if (_log) {
[7474]303 *_log << "Processing File: " << obsFile->fileName() << " start: "
304 << obsFile->startTime().datestr().c_str() << ' '
[4524]305 << obsFile->startTime().timestr(0).c_str() << endl;
306 }
[3901]307 if (ii == 0) {
[6841]308 outObsFile.setHeader(obsFile->header(), int(_rnxVersion), &useObsTypes,
309 &phaseShifts, &gloBiases, &gloSlots);
[3992]310 if (_begTime.valid() && _begTime > outObsFile.startTime()) {
311 outObsFile.setStartTime(_begTime);
312 }
[4112]313 if (_samplingRate > outObsFile.interval()) {
314 outObsFile.setInterval(_samplingRate);
315 }
[3982]316 editRnxObsHeader(outObsFile);
[4117]317 bncSettings settings;
[4114]318 QMap<QString, QString> txtMap;
[4117]319 QString runBy = settings.value("reqcRunBy").toString();
320 if (!runBy.isEmpty()) {
321 txtMap["RUN BY"] = runBy;
322 }
323 QString comment = settings.value("reqcComment").toString();
324 if (!comment.isEmpty()) {
325 txtMap["COMMENT"] = comment;
326 }
[7474]327 if (int(_rnxVersion) < int(obsFile->header().version())) {
328 addRnxConversionDetails(obsFile, txtMap);
329 }
[4514]330 outObsFile.header().write(outObsFile.stream(), &txtMap);
[3901]331 }
[3994]332 t_rnxObsFile::t_rnxEpo* epo = 0;
[4541]333 try {
334 while ( (epo = obsFile->nextEpoch()) != 0) {
335 if (_begTime.valid() && epo->tt < _begTime) {
336 continue;
337 }
338 if (_endTime.valid() && epo->tt > _endTime) {
339 break;
340 }
[7474]341
[8372]342 int sec = int(nint(epo->tt.gpssec()*10));
[8397]343 if (sec % (int(_samplingRate)*10) == 0) {
[4541]344 applyLLI(obsFile, epo);
345 outObsFile.writeEpoch(epo);
346 }
347 else {
348 rememberLLI(obsFile, epo);
349 }
[3993]350 }
[4541]351 }
352 catch (QString str) {
353 if (_log) {
354 *_log << "Exception " << str << endl;
[3993]355 }
[3994]356 else {
[7474]357 qDebug() << str;
[3994]358 }
[4541]359 return;
[3901]360 }
[6130]361 catch (...) {
362 if (_log) {
363 *_log << "Exception unknown" << endl;
364 }
365 else {
366 qDebug() << "Exception unknown";
367 }
368 return;
369 }
[3901]370 }
371}
[3982]372
[7474]373// Change RINEX Header Content
[3982]374////////////////////////////////////////////////////////////////////////////
[3985]375void t_reqcEdit::editRnxObsHeader(t_rnxObsFile& obsFile) {
[3982]376
[3983]377 bncSettings settings;
378
379 QString oldMarkerName = settings.value("reqcOldMarkerName").toString();
380 QString newMarkerName = settings.value("reqcNewMarkerName").toString();
[4090]381 if (!newMarkerName.isEmpty()) {
[7474]382 if (oldMarkerName.isEmpty() ||
[4090]383 QRegExp(oldMarkerName).exactMatch(obsFile.markerName())) {
384 obsFile.setMarkerName(newMarkerName);
385 }
[3985]386 }
387
[3983]388 QString oldAntennaName = settings.value("reqcOldAntennaName").toString();
389 QString newAntennaName = settings.value("reqcNewAntennaName").toString();
[4090]390 if (!newAntennaName.isEmpty()) {
[7474]391 if (oldAntennaName.isEmpty() ||
[4090]392 QRegExp(oldAntennaName).exactMatch(obsFile.antennaName())) {
393 obsFile.setAntennaName(newAntennaName);
394 }
[3985]395 }
[3983]396
[6795]397 QString oldAntennaNumber = settings.value("reqcOldAntennaNumber").toString();
398 QString newAntennaNumber = settings.value("reqcNewAntennaNumber").toString();
399 if (!newAntennaNumber.isEmpty()) {
400 if (oldAntennaNumber.isEmpty() ||
401 QRegExp(oldAntennaNumber).exactMatch(obsFile.antennaNumber())) {
402 obsFile.setAntennaNumber(newAntennaNumber);
403 }
404 }
405
406
407 const ColumnVector& obsFileAntNEU = obsFile.antNEU();
408 QString oldAntennadN = settings.value("reqcOldAntennadN").toString();
409 QString newAntennadN = settings.value("reqcNewAntennadN").toString();
410 if(!newAntennadN.isEmpty()) {
411 if (oldAntennadN.isEmpty() ||
412 oldAntennadN.toDouble() == obsFileAntNEU(1)) {
413 obsFile.setAntennaN(newAntennadN.toDouble());
414 }
415 }
416 QString oldAntennadE = settings.value("reqcOldAntennadE").toString();
417 QString newAntennadE = settings.value("reqcNewAntennadE").toString();
418 if(!newAntennadE.isEmpty()) {
419 if (oldAntennadE.isEmpty() ||
420 oldAntennadE.toDouble() == obsFileAntNEU(2)) {
421 obsFile.setAntennaE(newAntennadE.toDouble());
422 }
423 }
424 QString oldAntennadU = settings.value("reqcOldAntennadU").toString();
425 QString newAntennadU = settings.value("reqcNewAntennadU").toString();
426 if(!newAntennadU.isEmpty()) {
427 if (oldAntennadU.isEmpty() ||
428 oldAntennadU.toDouble() == obsFileAntNEU(3)) {
429 obsFile.setAntennaU(newAntennadU.toDouble());
430 }
431 }
432
[3985]433 QString oldReceiverType = settings.value("reqcOldReceiverName").toString();
434 QString newReceiverType = settings.value("reqcNewReceiverName").toString();
[4090]435 if (!newReceiverType.isEmpty()) {
[7474]436 if (oldReceiverType.isEmpty() ||
[4090]437 QRegExp(oldReceiverType).exactMatch(obsFile.receiverType())) {
438 obsFile.setReceiverType(newReceiverType);
439 }
[3985]440 }
[6795]441
442 QString oldReceiverNumber = settings.value("reqcOldReceiverNumber").toString();
443 QString newReceiverNumber = settings.value("reqcNewReceiverNumber").toString();
444 if (!newReceiverNumber.isEmpty()) {
445 if (oldReceiverNumber.isEmpty() ||
446 QRegExp(oldReceiverNumber).exactMatch(obsFile.receiverNumber())) {
447 obsFile.setReceiverNumber(newReceiverNumber);
448 }
449 }
[3982]450}
[3994]451
[7474]452//
[3994]453////////////////////////////////////////////////////////////////////////////
[7474]454void t_reqcEdit::rememberLLI(const t_rnxObsFile* obsFile,
[3995]455 const t_rnxObsFile::t_rnxEpo* epo) {
[3994]456
[3995]457 if (_samplingRate == 0) {
458 return;
459 }
460
461 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
462 const t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
[6121]463 char sys = rnxSat.prn.system();
464 QString prn(rnxSat.prn.toString().c_str());
[3997]465
[3995]466 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[6121]467 QString type = obsFile->obsType(sys, iType);
[3997]468 if (!_lli[prn].contains(iType)) {
469 _lli[prn][iType] = 0;
[3996]470 }
[6121]471 if (rnxSat.obs.contains(type) && rnxSat.obs[type].lli & 1) {
[3997]472 _lli[prn][iType] |= 1;
[3996]473 }
[3995]474 }
475 }
[3994]476}
[7474]477
478//
[3994]479////////////////////////////////////////////////////////////////////////////
[7474]480void t_reqcEdit::applyLLI(const t_rnxObsFile* obsFile,
[3995]481 t_rnxObsFile::t_rnxEpo* epo) {
[7474]482
[3996]483 if (_samplingRate == 0) {
[3995]484 return;
485 }
[3996]486
487 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
488 t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
[6121]489 char sys = rnxSat.prn.system();
490 QString prn(rnxSat.prn.toString().c_str());
[3997]491
[3996]492 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[6121]493 QString type = obsFile->obsType(sys, iType);
[3997]494 if (_lli[prn].contains(iType) && _lli[prn][iType] & 1) {
[6121]495 if (rnxSat.obs.contains(type)) {
496 rnxSat.obs[type].lli |= 1;
497 }
[3996]498 }
499 }
500 }
501
502 _lli.clear();
[3994]503}
[3998]504
[4256]505/// Read All Ephemerides
[3998]506////////////////////////////////////////////////////////////////////////////
[4256]507void t_reqcEdit::readEphemerides(const QStringList& navFileNames,
508 QVector<t_eph*>& ephs) {
[3998]509
[4256]510 QStringListIterator it(navFileNames);
[3999]511 while (it.hasNext()) {
512 QString fileName = it.next();
[4081]513 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
514 QFileInfo fileInfo(fileName);
515 QDir dir = fileInfo.dir();
516 QStringList filters; filters << fileInfo.fileName();
517 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
518 while (it.hasNext()) {
[7474]519 QString filePath = it.next().filePath();
[4256]520 appendEphemerides(filePath, ephs);
[4000]521 }
522 }
[4081]523 else {
[4256]524 appendEphemerides(fileName, ephs);
[4081]525 }
[3999]526 }
[9366]527 // TODO: enable user decision
[4256]528 qStableSort(ephs.begin(), ephs.end(), t_eph::earlierTime);
[9366]529 //qStableSort(ephs.begin(), ephs.end(), t_eph::prnSort);
[4256]530}
[3999]531
[7474]532//
[4256]533////////////////////////////////////////////////////////////////////////////
534void t_reqcEdit::editEphemerides() {
535
536 // Easy Exit
537 // ---------
538 if (_navFileNames.isEmpty() || _outNavFileName.isEmpty()) {
539 return;
540 }
[7999]541 // Concatenate all comments
542 // ------------------------
543 QStringList comments;
544 bncSettings settings;
545 QString comment = settings.value("reqcComment").toString();
546 if (!comment.isEmpty()) {
547 comments.append(comment);
548 }
549 QStringListIterator it(_navFileNames);
550 while (it.hasNext()) {
551 QString fileName = it.next();
552 t_rnxNavFile rnxNavFile(fileName, t_rnxNavFile::input);
553 QStringListIterator itCmnt(rnxNavFile.comments());
554 while (itCmnt.hasNext()) {
555 comments.append(itCmnt.next());
556 }
557 }
558 comments.removeDuplicates();
[4256]559
[4257]560 // Read Ephemerides
561 // ----------------
[4256]562 t_reqcEdit::readEphemerides(_navFileNames, _ephs);
563
[4229]564 // Check Satellite Systems
565 // -----------------------
566 bool haveGPS = false;
567 bool haveGlonass = false;
[8354]568 QMap<t_eph::e_type, bool> haveGnss;
[4229]569 for (int ii = 0; ii < _ephs.size(); ii++) {
570 const t_eph* eph = _ephs[ii];
[8354]571 switch (eph->type()) {
572 case t_eph::GPS:
573 haveGPS = true;
[8655]574 haveGnss[t_eph::GPS] = true;
[8354]575 break;
576 case t_eph::GLONASS:
577 haveGlonass = true;
[8655]578 haveGnss[t_eph::GLONASS] = true;
[8354]579 break;
580 case t_eph::Galileo:
581 haveGnss[t_eph::Galileo] = true;
582 break;
583 case t_eph::BDS:
584 haveGnss[t_eph::BDS] = true;
585 break;
586 case t_eph::QZSS:
587 haveGnss[t_eph::QZSS] = true;
588 break;
589 case t_eph::IRNSS:
590 haveGnss[t_eph::IRNSS] = true;
591 break;
592 case t_eph::SBAS:
593 haveGnss[t_eph::SBAS] = true;
594 break;
595 default:
596 haveGnss[t_eph::unknown] = true;
[4229]597 }
598 }
599
[4007]600 // Initialize output navigation file
601 // ---------------------------------
[4004]602 t_rnxNavFile outNavFile(_outNavFileName, t_rnxNavFile::output);
[4229]603
604 outNavFile.setGlonass(haveGlonass);
605
[9765]606 if (_rnxVersion < 3.0) {
607 if (haveGPS && haveGlonass) {
608 outNavFile.setVersion(defaultRnxNavVersion3);
609 }
610 if (haveGPS && !haveGlonass) {
611 outNavFile.setVersion(defaultRnxNavVersion2);
612 }
613 }
614
615 if (_rnxVersion >= 3.0 && _rnxVersion < 4.0) {
[8127]616 outNavFile.setVersion(defaultRnxNavVersion3);
[4229]617 }
[9765]618
619 if (_rnxVersion >= 4.0) {
620 outNavFile.setVersion(defaultRnxNavVersion4);
[4229]621 }
622
[8354]623 if (outNavFile.version() > 3.0) {
624 if (haveGnss.size() > 1) {
625 outNavFile.setGnssTypeV3(t_eph::unknown);
626 }
627 else if (haveGnss.size() == 1){
[8355]628 outNavFile.setGnssTypeV3(haveGnss.keys().first());
[8354]629 }
630 }
631
[4221]632 QMap<QString, QString> txtMap;
633 QString runBy = settings.value("reqcRunBy").toString();
634 if (!runBy.isEmpty()) {
635 txtMap["RUN BY"] = runBy;
636 }
[7999]637 if (!comments.isEmpty()) {
638 txtMap["COMMENT"] = comments.join("\\n");
[4221]639 }
[4229]640
[9765]641 int mergedNavFiles = _navFileNames.size();
642 unsigned year, month, day;
643 int gps_utc = 0;
644 if (_ephs.size()) {
645 _ephs.at(0)->TOC().civil_date(year, month, day);
646 gps_utc = gnumleap(year, month, day);
647 }
648 outNavFile.writeHeader(&txtMap, mergedNavFiles, gps_utc);
[4009]649
[4004]650 // Loop over all ephemerides
651 // -------------------------
652 for (int ii = 0; ii < _ephs.size(); ii++) {
653 const t_eph* eph = _ephs[ii];
[6954]654 bncTime begTime = _begTime;
655 bncTime endTime = _endTime;
656 if (eph->type() == t_eph::BDS) {
657 begTime += 14;
658 endTime += 14;
659 }
660 if (begTime.valid() && eph->TOC() < begTime) {
[6898]661 continue;
662 }
[6954]663 if (endTime.valid() && eph->TOC() > endTime) {
[6898]664 break;
665 }
[8437]666 if (eph->checkState() == t_eph::bad) {
[8368]667 continue;
668 }
[9765]669 if (outNavFile.version() >= 4.0 &&
670 eph->navType() == t_eph::undefined) { // input files < version 4.0
671 continue;
672 }
[4229]673 outNavFile.writeEph(eph);
[4004]674 }
[3998]675}
[4081]676
[7474]677//
[4081]678////////////////////////////////////////////////////////////////////////////
[4256]679void t_reqcEdit::appendEphemerides(const QString& fileName,
680 QVector<t_eph*>& ephs) {
[4081]681 t_rnxNavFile rnxNavFile(fileName, t_rnxNavFile::input);
682 for (unsigned ii = 0; ii < rnxNavFile.ephs().size(); ii++) {
683 t_eph* eph = rnxNavFile.ephs()[ii];
684 bool isNew = true;
[4256]685 for (int iOld = 0; iOld < ephs.size(); iOld++) {
686 const t_eph* ephOld = ephs[iOld];
[6804]687 if (ephOld->prn() == eph->prn() &&
[6809]688 ephOld->TOC() == eph->TOC()) {
[4081]689 isNew = false;
690 break;
691 }
692 }
693 if (isNew) {
694 if (eph->type() == t_eph::GPS) {
[4256]695 ephs.append(new t_ephGPS(*dynamic_cast<t_ephGPS*>(eph)));
[4081]696 }
697 else if (eph->type() == t_eph::GLONASS) {
[4256]698 ephs.append(new t_ephGlo(*dynamic_cast<t_ephGlo*>(eph)));
[4081]699 }
700 else if (eph->type() == t_eph::Galileo) {
[4256]701 ephs.append(new t_ephGal(*dynamic_cast<t_ephGal*>(eph)));
[4081]702 }
[6377]703 else if (eph->type() == t_eph::QZSS) {
704 ephs.append(new t_ephGPS(*dynamic_cast<t_ephGPS*>(eph)));
705 }
[6391]706 else if (eph->type() == t_eph::SBAS) {
707 ephs.append(new t_ephSBAS(*dynamic_cast<t_ephSBAS*>(eph)));
708 }
[6602]709 else if (eph->type() == t_eph::BDS) {
[6600]710 ephs.append(new t_ephBDS(*dynamic_cast<t_ephBDS*>(eph)));
[6402]711 }
[8168]712 else if (eph->type() == t_eph::IRNSS) {
713 ephs.append(new t_ephGPS(*dynamic_cast<t_ephGPS*>(eph)));
714 }
[4081]715 }
716 }
717}
[7474]718
719void t_reqcEdit::addRnxConversionDetails(const t_rnxObsFile* obsFile,
720 QMap<QString, QString>& txtMap) {
721
722 int key = 0;
723 QString systems = obsFile->header().usedSystems();
[7980]724 QString comment = QString("Signal priorities for RINEX 3 => 2 conversion:");
[7474]725 QString commentKey = QString("COMMENT %1").arg(key, 3, 10, QChar('0'));
726 txtMap.insert(commentKey, comment);
727
728 for(int ii = 0; ii < obsFile->numSys(); ii++) {
[8204]729 char sys = systems[ii].toLatin1();
[7474]730 txtMap.insert(commentKey, comment);
[7980]731 QMap <char, QString> signalPriorityMap;
732 QStringList preferredAttribListSys = obsFile->signalPriorities(sys);
[7474]733 QStringList types = obsFile->header().obsTypes(sys);
734 for (int jj = 0; jj < types.size(); jj++) {
735 QString inType = types[jj];
[8204]736 char band = inType[1].toLatin1();
[7980]737 for (int ii = 0; ii < preferredAttribListSys.size(); ii++) {
738 QString preferredAttrib;
739 if (preferredAttribListSys[ii].indexOf("&") != -1) {
740 QStringList hlp = preferredAttribListSys[ii].split("&", QString::SkipEmptyParts);
741 if (hlp.size() == 2 && hlp[0].contains(band)) {
742 preferredAttrib = hlp[1];
743 }
[7474]744 }
[7980]745 else {
746 preferredAttrib = preferredAttribListSys[ii];
747 }
748 if (!signalPriorityMap.contains(band) && !preferredAttrib.isEmpty()){
749 signalPriorityMap[band] = preferredAttrib;
750 }
[7474]751 }
752 }
[7980]753 QMapIterator<char, QString> it(signalPriorityMap);
754 while (it.hasNext()) {
755 it.next();
756 key++;
757 comment = QString("%1 band %2: %3").arg(sys).arg(it.key()).arg(it.value());
758 commentKey = QString("COMMENT %1").arg(key, 3, 10, QChar('0'));
759 txtMap.insert(commentKey, comment);
760 }
[7474]761 }
762}
Note: See TracBrowser for help on using the repository browser.