source: ntrip/trunk/BNC/rinex/reqcedit.cpp@ 4229

Last change on this file since 4229 was 4229, checked in by mervart, 13 years ago
File size: 11.3 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
102//
103////////////////////////////////////////////////////////////////////////////
104void t_reqcEdit::editObservations() {
105
[4013]106 // Easy Exit
107 // ---------
108 if (_obsFileNames.isEmpty() || _outObsFileName.isEmpty()) {
109 return;
110 }
111
[3901]112 // Initialize input observation files, sort them according to start time
113 // ---------------------------------------------------------------------
114 QStringListIterator it(_obsFileNames);
115 while (it.hasNext()) {
116 QString fileName = it.next();
[4080]117 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
118 QFileInfo fileInfo(fileName);
119 QDir dir = fileInfo.dir();
120 QStringList filters; filters << fileInfo.fileName();
121 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
122 while (it.hasNext()) {
123 QString filePath = it.next().filePath();
124 t_rnxObsFile* rnxObsFile = new t_rnxObsFile(filePath, t_rnxObsFile::input);
125 _rnxObsFiles.append(rnxObsFile);
126 }
127 }
128 else {
129 t_rnxObsFile* rnxObsFile = new t_rnxObsFile(fileName, t_rnxObsFile::input);
130 _rnxObsFiles.append(rnxObsFile);
131 }
[3901]132 }
133 qStableSort(_rnxObsFiles.begin(), _rnxObsFiles.end(),
134 t_rnxObsFile::earlierStartTime);
135
136 // Initialize output observation file
137 // ----------------------------------
138 t_rnxObsFile outObsFile(_outObsFileName, t_rnxObsFile::output);
139
140 // Loop over all input observation files
141 // -------------------------------------
142 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
143 t_rnxObsFile* obsFile = _rnxObsFiles[ii];
144 if (ii == 0) {
[3956]145 outObsFile.setHeader(obsFile->header(), _rnxVersion);
[3992]146 if (_begTime.valid() && _begTime > outObsFile.startTime()) {
147 outObsFile.setStartTime(_begTime);
148 }
[4112]149 if (_samplingRate > outObsFile.interval()) {
150 outObsFile.setInterval(_samplingRate);
151 }
[3982]152 editRnxObsHeader(outObsFile);
[4117]153 bncSettings settings;
[4114]154 QMap<QString, QString> txtMap;
[4117]155 QString runBy = settings.value("reqcRunBy").toString();
156 if (!runBy.isEmpty()) {
157 txtMap["RUN BY"] = runBy;
158 }
159 QString comment = settings.value("reqcComment").toString();
160 if (!comment.isEmpty()) {
161 txtMap["COMMENT"] = comment;
162 }
[4137]163 outObsFile.writeHeader(&txtMap);
[3901]164 }
[4054]165 else {
166 outObsFile.checkNewHeader(obsFile->header());
167 }
[3994]168 t_rnxObsFile::t_rnxEpo* epo = 0;
[3901]169 while ( (epo = obsFile->nextEpoch()) != 0) {
[3993]170 if (_begTime.valid() && epo->tt < _begTime) {
171 continue;
172 }
173 if (_endTime.valid() && epo->tt > _endTime) {
174 break;
175 }
176
177 if (_samplingRate == 0 ||
178 fmod(round(epo->tt.gpssec()), _samplingRate) == 0) {
[3995]179 applyLLI(obsFile, epo);
[3990]180 outObsFile.writeEpoch(epo);
181 }
[3994]182 else {
[3995]183 rememberLLI(obsFile, epo);
[3994]184 }
[3901]185 }
186 }
187}
[3982]188
189// Change RINEX Header Content
190////////////////////////////////////////////////////////////////////////////
[3985]191void t_reqcEdit::editRnxObsHeader(t_rnxObsFile& obsFile) {
[3982]192
[3983]193 bncSettings settings;
194
195 QString oldMarkerName = settings.value("reqcOldMarkerName").toString();
196 QString newMarkerName = settings.value("reqcNewMarkerName").toString();
[4090]197 if (!newMarkerName.isEmpty()) {
198 if (oldMarkerName.isEmpty() ||
199 QRegExp(oldMarkerName).exactMatch(obsFile.markerName())) {
200 obsFile.setMarkerName(newMarkerName);
201 }
[3985]202 }
203
[3983]204 QString oldAntennaName = settings.value("reqcOldAntennaName").toString();
205 QString newAntennaName = settings.value("reqcNewAntennaName").toString();
[4090]206 if (!newAntennaName.isEmpty()) {
207 if (oldAntennaName.isEmpty() ||
208 QRegExp(oldAntennaName).exactMatch(obsFile.antennaName())) {
209 obsFile.setAntennaName(newAntennaName);
210 }
[3985]211 }
[3983]212
[3985]213 QString oldReceiverType = settings.value("reqcOldReceiverName").toString();
214 QString newReceiverType = settings.value("reqcNewReceiverName").toString();
[4090]215 if (!newReceiverType.isEmpty()) {
216 if (oldReceiverType.isEmpty() ||
217 QRegExp(oldReceiverType).exactMatch(obsFile.receiverType())) {
218 obsFile.setReceiverType(newReceiverType);
219 }
[3985]220 }
[3982]221}
[3994]222
223//
224////////////////////////////////////////////////////////////////////////////
[3995]225void t_reqcEdit::rememberLLI(const t_rnxObsFile* obsFile,
226 const t_rnxObsFile::t_rnxEpo* epo) {
[3994]227
[3995]228 if (_samplingRate == 0) {
229 return;
230 }
231
232 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
233 const t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
234 char sys = rnxSat.satSys;
[3997]235 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
236
[3995]237 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[3997]238 if (!_lli[prn].contains(iType)) {
239 _lli[prn][iType] = 0;
[3996]240 }
241 if (rnxSat.lli[iType] & 1) {
[3997]242 _lli[prn][iType] |= 1;
[3996]243 }
[3995]244 }
245 }
[3994]246}
247
248//
249////////////////////////////////////////////////////////////////////////////
[3995]250void t_reqcEdit::applyLLI(const t_rnxObsFile* obsFile,
251 t_rnxObsFile::t_rnxEpo* epo) {
[3996]252
253 if (_samplingRate == 0) {
[3995]254 return;
255 }
[3996]256
257 for (unsigned iSat = 0; iSat < epo->rnxSat.size(); iSat++) {
258 t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
259 char sys = rnxSat.satSys;
[3997]260 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
261
[3996]262 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
[3997]263 if (_lli[prn].contains(iType) && _lli[prn][iType] & 1) {
[3996]264 rnxSat.lli[iType] |= 1;
265 }
266 }
267 }
268
269 _lli.clear();
[3994]270}
[3998]271
272//
273////////////////////////////////////////////////////////////////////////////
274void t_reqcEdit::editEphemerides() {
275
[4013]276 // Easy Exit
277 // ---------
278 if (_navFileNames.isEmpty() || _outNavFileName.isEmpty()) {
279 return;
280 }
281
[4000]282 // Read All Ephemerides
283 // --------------------
[3999]284 QStringListIterator it(_navFileNames);
285 while (it.hasNext()) {
286 QString fileName = it.next();
[4081]287 if (fileName.indexOf('*') != -1 || fileName.indexOf('?') != -1) {
288 QFileInfo fileInfo(fileName);
289 QDir dir = fileInfo.dir();
290 QStringList filters; filters << fileInfo.fileName();
291 QListIterator<QFileInfo> it(dir.entryInfoList(filters));
292 while (it.hasNext()) {
293 QString filePath = it.next().filePath();
294 appendEphemerides(filePath);
[4000]295 }
296 }
[4081]297 else {
298 appendEphemerides(fileName);
299 }
[3999]300 }
[4003]301 qStableSort(_ephs.begin(), _ephs.end(), t_eph::earlierTime);
[3999]302
[4229]303 // Check Satellite Systems
304 // -----------------------
305 bool haveGPS = false;
306 bool haveGlonass = false;
307 for (int ii = 0; ii < _ephs.size(); ii++) {
308 const t_eph* eph = _ephs[ii];
309 if (eph->type() == t_eph::GPS) {
310 haveGPS = true;
311 }
312 else if (eph->type() == t_eph::GLONASS) {
313 haveGlonass = true;
314 }
315 }
316
[4007]317 // Initialize output navigation file
318 // ---------------------------------
[4004]319 t_rnxNavFile outNavFile(_outNavFileName, t_rnxNavFile::output);
[4229]320
321 outNavFile.setGlonass(haveGlonass);
322
323 if (haveGPS && haveGlonass) {
324 outNavFile.setVersion(rnxV3);
325 }
326 else {
327 outNavFile.setVersion(_rnxVersion);
328 }
329
[4221]330 bncSettings settings;
331 QMap<QString, QString> txtMap;
332 QString runBy = settings.value("reqcRunBy").toString();
333 if (!runBy.isEmpty()) {
334 txtMap["RUN BY"] = runBy;
335 }
336 QString comment = settings.value("reqcComment").toString();
337 if (!comment.isEmpty()) {
338 txtMap["COMMENT"] = comment;
339 }
[4229]340
[4221]341 outNavFile.writeHeader(&txtMap);
[4009]342
[4004]343 // Loop over all ephemerides
344 // -------------------------
345 for (int ii = 0; ii < _ephs.size(); ii++) {
346 const t_eph* eph = _ephs[ii];
[4229]347 outNavFile.writeEph(eph);
[4004]348 }
[3998]349}
[4081]350
351//
352////////////////////////////////////////////////////////////////////////////
353void t_reqcEdit::appendEphemerides(const QString& fileName) {
354
355 t_rnxNavFile rnxNavFile(fileName, t_rnxNavFile::input);
356 for (unsigned ii = 0; ii < rnxNavFile.ephs().size(); ii++) {
357 t_eph* eph = rnxNavFile.ephs()[ii];
358 bool isNew = true;
359 for (int iOld = 0; iOld < _ephs.size(); iOld++) {
360 const t_eph* ephOld = _ephs[iOld];
361 if (ephOld->prn() == eph->prn() && ephOld->IOD() == eph->IOD()) {
362 isNew = false;
363 break;
364 }
365 }
366 if (isNew) {
367 if (eph->type() == t_eph::GPS) {
368 _ephs.append(new t_ephGPS(*dynamic_cast<t_ephGPS*>(eph)));
369 }
370 else if (eph->type() == t_eph::GLONASS) {
371 _ephs.append(new t_ephGlo(*dynamic_cast<t_ephGlo*>(eph)));
372 }
373 else if (eph->type() == t_eph::Galileo) {
374 _ephs.append(new t_ephGal(*dynamic_cast<t_ephGal*>(eph)));
375 }
376 }
377 }
378}
Note: See TracBrowser for help on using the repository browser.