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

Last change on this file since 4229 was 4229, checked in by mervart, 12 years ago
File size: 11.3 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_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"
43#include "bncapp.h"
44#include "bncsettings.h"
45
46using namespace std;
47
48const double rnxV2 = 2.11;
49const double rnxV3 = 3.01;
50
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();
59 _navFileNames = settings.value("reqcNavFile").toString().split(",", QString::SkipEmptyParts);
60 _outNavFileName = settings.value("reqcOutNavFile").toString();
61 int version = settings.value("reqcRnxVersion").toInt();
62 if (version < 3) {
63 _rnxVersion = rnxV2;
64 }
65 else {
66 _rnxVersion = rnxV3;
67 }
68 _samplingRate = settings.value("reqcSampling").toInt();
69 _begTime = bncTime(settings.value("reqcStartDateTime").toString().toAscii().data());
70 _endTime = bncTime(settings.value("reqcEndDateTime").toString().toAscii().data());
71}
72
73// Destructor
74////////////////////////////////////////////////////////////////////////////
75t_reqcEdit::~t_reqcEdit() {
76 for (int ii = 0; ii < _rnxObsFiles.size(); ii++) {
77 delete _rnxObsFiles[ii];
78 }
79 for (int ii = 0; ii < _ephs.size(); ii++) {
80 delete _ephs[ii];
81 }
82}
83
84//
85////////////////////////////////////////////////////////////////////////////
86void t_reqcEdit::run() {
87
88 editObservations();
89
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
106 // Easy Exit
107 // ---------
108 if (_obsFileNames.isEmpty() || _outObsFileName.isEmpty()) {
109 return;
110 }
111
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();
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 }
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) {
145 outObsFile.setHeader(obsFile->header(), _rnxVersion);
146 if (_begTime.valid() && _begTime > outObsFile.startTime()) {
147 outObsFile.setStartTime(_begTime);
148 }
149 if (_samplingRate > outObsFile.interval()) {
150 outObsFile.setInterval(_samplingRate);
151 }
152 editRnxObsHeader(outObsFile);
153 bncSettings settings;
154 QMap<QString, QString> txtMap;
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 }
163 outObsFile.writeHeader(&txtMap);
164 }
165 else {
166 outObsFile.checkNewHeader(obsFile->header());
167 }
168 t_rnxObsFile::t_rnxEpo* epo = 0;
169 while ( (epo = obsFile->nextEpoch()) != 0) {
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) {
179 applyLLI(obsFile, epo);
180 outObsFile.writeEpoch(epo);
181 }
182 else {
183 rememberLLI(obsFile, epo);
184 }
185 }
186 }
187}
188
189// Change RINEX Header Content
190////////////////////////////////////////////////////////////////////////////
191void t_reqcEdit::editRnxObsHeader(t_rnxObsFile& obsFile) {
192
193 bncSettings settings;
194
195 QString oldMarkerName = settings.value("reqcOldMarkerName").toString();
196 QString newMarkerName = settings.value("reqcNewMarkerName").toString();
197 if (!newMarkerName.isEmpty()) {
198 if (oldMarkerName.isEmpty() ||
199 QRegExp(oldMarkerName).exactMatch(obsFile.markerName())) {
200 obsFile.setMarkerName(newMarkerName);
201 }
202 }
203
204 QString oldAntennaName = settings.value("reqcOldAntennaName").toString();
205 QString newAntennaName = settings.value("reqcNewAntennaName").toString();
206 if (!newAntennaName.isEmpty()) {
207 if (oldAntennaName.isEmpty() ||
208 QRegExp(oldAntennaName).exactMatch(obsFile.antennaName())) {
209 obsFile.setAntennaName(newAntennaName);
210 }
211 }
212
213 QString oldReceiverType = settings.value("reqcOldReceiverName").toString();
214 QString newReceiverType = settings.value("reqcNewReceiverName").toString();
215 if (!newReceiverType.isEmpty()) {
216 if (oldReceiverType.isEmpty() ||
217 QRegExp(oldReceiverType).exactMatch(obsFile.receiverType())) {
218 obsFile.setReceiverType(newReceiverType);
219 }
220 }
221}
222
223//
224////////////////////////////////////////////////////////////////////////////
225void t_reqcEdit::rememberLLI(const t_rnxObsFile* obsFile,
226 const t_rnxObsFile::t_rnxEpo* epo) {
227
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;
235 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
236
237 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
238 if (!_lli[prn].contains(iType)) {
239 _lli[prn][iType] = 0;
240 }
241 if (rnxSat.lli[iType] & 1) {
242 _lli[prn][iType] |= 1;
243 }
244 }
245 }
246}
247
248//
249////////////////////////////////////////////////////////////////////////////
250void t_reqcEdit::applyLLI(const t_rnxObsFile* obsFile,
251 t_rnxObsFile::t_rnxEpo* epo) {
252
253 if (_samplingRate == 0) {
254 return;
255 }
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;
260 QString prn = QString("%1%2").arg(sys).arg(rnxSat.satNum,2,10,QChar('0'));
261
262 for (int iType = 0; iType < obsFile->nTypes(sys); iType++) {
263 if (_lli[prn].contains(iType) && _lli[prn][iType] & 1) {
264 rnxSat.lli[iType] |= 1;
265 }
266 }
267 }
268
269 _lli.clear();
270}
271
272//
273////////////////////////////////////////////////////////////////////////////
274void t_reqcEdit::editEphemerides() {
275
276 // Easy Exit
277 // ---------
278 if (_navFileNames.isEmpty() || _outNavFileName.isEmpty()) {
279 return;
280 }
281
282 // Read All Ephemerides
283 // --------------------
284 QStringListIterator it(_navFileNames);
285 while (it.hasNext()) {
286 QString fileName = it.next();
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);
295 }
296 }
297 else {
298 appendEphemerides(fileName);
299 }
300 }
301 qStableSort(_ephs.begin(), _ephs.end(), t_eph::earlierTime);
302
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
317 // Initialize output navigation file
318 // ---------------------------------
319 t_rnxNavFile outNavFile(_outNavFileName, t_rnxNavFile::output);
320
321 outNavFile.setGlonass(haveGlonass);
322
323 if (haveGPS && haveGlonass) {
324 outNavFile.setVersion(rnxV3);
325 }
326 else {
327 outNavFile.setVersion(_rnxVersion);
328 }
329
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 }
340
341 outNavFile.writeHeader(&txtMap);
342
343 // Loop over all ephemerides
344 // -------------------------
345 for (int ii = 0; ii < _ephs.size(); ii++) {
346 const t_eph* eph = _ephs[ii];
347 outNavFile.writeEph(eph);
348 }
349}
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.