source: ntrip/trunk/BNC/src/bncsinextro.cpp@ 10792

Last change on this file since 10792 was 10791, checked in by mervart, 3 days ago

BNC Multifrequency and PPPAR Client (initial version)

  • Property svn:keywords set to Author Date Id Rev URL;svn:eol-style=native
  • Property svn:mime-type set to text/plain
File size: 12.0 KB
Line 
1
2/* -------------------------------------------------------------------------
3 * BKG NTRIP Server
4 * -------------------------------------------------------------------------
5 *
6 * Class: bncSinexTro
7 *
8 * Purpose: writes SINEX TRO files
9 *
10 * Author: A. Stürze
11 *
12 * Created: 19-Feb-2015
13 *
14 * Changes:
15 *
16 * -----------------------------------------------------------------------*/
17
18#include <math.h>
19#include <iomanip>
20
21#include "bncsinextro.h"
22
23using namespace BNC_PPP;
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncSinexTro::bncSinexTro(const t_pppOptions* opt,
29 const QString& sklFileName, const QString& intr,
30 int sampl)
31 : bncoutf(sklFileName, intr, sampl) {
32
33 _opt = opt;
34 _sampl = sampl;
35
36 _antex = 0;
37}
38
39// Destructor
40////////////////////////////////////////////////////////////////////////////
41bncSinexTro::~bncSinexTro() {
42 closeFile();
43 if (_antex)
44 delete _antex;
45}
46
47// Write Header
48////////////////////////////////////////////////////////////////////////////
49void bncSinexTro::writeHeader(const QDateTime& datTim) {
50 int GPSWeek;
51 double GPSWeeks;
52 bncSettings settings;
53 GPSweekFromDateAndTime(datTim, GPSWeek, GPSWeeks);
54 int daysec = int(fmod(GPSWeeks, 86400.0));
55 int dayOfYear = datTim.date().dayOfYear();
56 QString yyyy = datTim.toString("yyyy");
57 QString creationTime = QString("%1:%2:%3").arg(yyyy)
58 .arg(dayOfYear, 3, 10, QLatin1Char('0'))
59 .arg(daysec , 5, 10, QLatin1Char('0'));
60 QString startTime = creationTime;
61 QString intStr = settings.value("PPP/snxtroIntr").toString();
62 int intr, indHlp = 0;
63 if ((indHlp = intStr.indexOf("min")) != -1) {
64 intr = intStr.left(indHlp-1).toInt();
65 intr *= 60;
66 }
67 else if ((indHlp = intStr.indexOf("hour")) != -1) {
68 intr = intStr.left(indHlp-1).toInt();
69 intr *= 3600;
70 }
71 else if ((indHlp = intStr.indexOf("day")) != -1) {
72 intr = intStr.left(indHlp-1).toInt();
73 intr *= 86400;
74 }
75 int nominalStartSec = daysec - (int(fmod(double(daysec), double(intr))));
76 int nominalEndSec = nominalStartSec + intr - _sampl;
77 QString endTime = QString("%1:%2:%3").arg(yyyy)
78 .arg(dayOfYear , 3, 10, QLatin1Char('0'))
79 .arg(nominalEndSec , 5, 10, QLatin1Char('0'));
80 int numEpochs = ((nominalEndSec - daysec) / _sampl) +1;
81 QString epo = QString("%1").arg(numEpochs, 5, 10, QLatin1Char('0'));
82 QString ac = QString("%1").arg(settings.value("PPP/snxtroAc").toString(),3,QLatin1Char(' '));
83 QString solId = settings.value("PPP/snxtroSolId").toString();
84 QString corr = "";
85 if (settings.value("PPP/dataSource").toString() == "Real-Time Streams") {
86 corr = settings.value("PPP/corrMount").toString();
87 }
88 else if (settings.value("PPP/dataSource").toString() == "RINEX Files") {
89 corr = settings.value("PPP/corrFile").toString();
90 }
91
92 _out << "%=TRO 2.00 " << ac.toStdString() << " "
93 << creationTime.toStdString() << " " << ac.toStdString() << " "
94 << startTime.toStdString() << " " << endTime.toStdString() << " P "
95 << _opt->_roverName.substr(0,9) << endl;
96 _out << "*-------------------------------------------------------------------------------" << endl;
97 _out << "+FILE/REFERENCE" << endl;
98 _out << "*INFO_TYPE_________ INFO________________________________________________________" << endl;
99 _out << " DESCRIPTION " << "BNC generated SINEX TRO file" << endl;
100 _out << " OUTPUT " << "Total Troposphere Zenith Path Delay Product" << endl;
101 _out << " SOFTWARE " << BNCPGMNAME << endl;
102 _out << " INPUT " << "OBS: " << _opt->_roverName.substr(0,9) << ", SSR: " << corr.toStdString() << endl;
103 _out << " VERSION NUMBER " << QString("%1").arg(solId, 3, QLatin1Char('0')).toStdString() << endl;
104 _out << "-FILE/REFERENCE" << endl;
105 _out << "*-------------------------------------------------------------------------------" << endl;
106
107 QString systems;
108 if (settings.value("PPP/lcGPS" ).toString() != "no") {systems += "G, ";}
109 if (settings.value("PPP/lcGLONASS").toString() != "no") {systems += "R, ";}
110 if (settings.value("PPP/lcGalileo").toString() != "no") {systems += "E, ";}
111 if (settings.value("PPP/lcBDS" ).toString() != "no") {systems += "C";}
112 QString blqFileName = QString::fromStdString(_opt->_blqFileName);
113 QString blqFileBaseName;
114 QString blqFileExtension;
115 if (! blqFileName.isEmpty()) {
116 QFileInfo fileInfo(blqFileName);
117 blqFileBaseName = fileInfo.baseName();
118 blqFileExtension = fileInfo.completeSuffix();
119 if (!blqFileExtension.isEmpty()) {
120 blqFileExtension = "." + blqFileExtension;
121 }
122 }
123 bool eleWeighting = false;
124 if (settings.value("PPP/eleWgtCode").toInt() > 0 ||
125 settings.value("PPP/eleWgtCode").toInt() > 0 ) {
126 eleWeighting = true;
127 }
128
129 _out << "+TROP/DESCRIPTION" << endl;
130 _out << "*KEYWORD______________________ VALUE(S)______________" << endl;
131 _out << " TROPO SAMPLING INTERVAL " << left << setw(22) << _sampl << endl;
132 _out << " DATA SAMPLING INTERVAL " << left << setw(22) << 1 << endl;
133 _out << " ELEVATION CUTOFF ANGLE " << left << setw(22) << int(_opt->_minEle * 180.0/M_PI) << endl;
134 _out << " OBSERVATION WEIGHTING " << ((eleWeighting) ? "SINEL" : "") << endl;
135 _out << " GNSS SYSTEMS " << systems.toStdString() << endl;
136 _out << " TIME SYSTEM " << "G" << endl;
137 _out << " TROPO MODELING METHOD " << "KALMAN FILTER" << endl;
138 if (! blqFileName.isEmpty()) {
139 _out << " OCEAN TIDE LOADING MODEL " << blqFileBaseName.toStdString() + blqFileExtension.toStdString() << endl;
140 }
141 _out << " TROP MAPPING FUNCTION " << "Saastamoinen" << endl;
142 _out << " TROPO PARAMETER NAMES " << "TROTOT STDEV" << endl;
143 _out << " TROPO PARAMETER UNITS " << "1e+03 1e+03" << endl;
144 _out << "-TROP/DESCRIPTION"<< endl;
145 _out << "*-------------------------------------------------------------------------------" << endl;
146
147 double recEll[3];
148 int lonD, lonM, latD, latM;
149 double lonS, latS;
150 xyz2ell(_opt->_xyzAprRover.data(), recEll);
151 deg2DMS(recEll[0] * 180.0 / M_PI, latD, latM, latS);
152 deg2DMS(recEll[1] * 180.0 / M_PI, lonD, lonM, lonS);
153 QString country;
154 QListIterator<QString> it(settings.value("mountPoints").toStringList());
155 while (it.hasNext()) {
156 QStringList hlp = it.next().split(" ");
157 if (hlp.size() < 7)
158 continue;
159 if (hlp.join(" ").indexOf(QString::fromStdString(_opt->_roverName), 0) != -1) {
160 country = hlp[2];
161 }
162 }
163 _out << "+SITE/ID" << endl;
164 _out << "*STATION__ PT __DOMES__ T _STATION_DESCRIPTION__ _LONGITUDE _LATITUDE_ _HGT_ELI_" << endl;
165 _out << " " << _opt->_roverName.substr(0,9) << " A P "
166 << country.toStdString() << " "
167 << QString(" %1").arg(recEll[0]* 180.0 / M_PI,10, 'f', 6, QLatin1Char(' ')).toStdString()
168 << QString(" %1").arg(recEll[1]* 180.0 / M_PI,10, 'f', 6, QLatin1Char(' ')).toStdString()
169 << QString(" %1").arg(recEll[2], 9, 'f', 3, QLatin1Char(' ')).toStdString()
170 << endl;
171 _out << "-SITE/ID" << endl;
172 _out << "*-------------------------------------------------------------------------------" << endl;
173
174 _out << "+TROP/COORDINATES" << endl;
175 _out << "*STATION__ PT SOLN T __DATA_START__ __DATA_END____ __STA_X_____ __STA_Y_____ __STA_Z_____ SYSTEM REMRK" << endl;
176 _out << " " << _opt->_roverName.substr(0,9) << " A "
177 << QString("%1").arg(solId, 4, QLatin1Char(' ')).toStdString() << " P "
178 << startTime.toStdString() << " " << endTime.toStdString()
179 << QString(" %1").arg(_opt->_xyzAprRover(1), 12, 'f', 3, QLatin1Char(' ')).toStdString()
180 << QString(" %1").arg(_opt->_xyzAprRover(2), 12, 'f', 3, QLatin1Char(' ')).toStdString()
181 << QString(" %1").arg(_opt->_xyzAprRover(3), 12, 'f', 3, QLatin1Char(' ')).toStdString()
182 << QString(" %1").arg("IGS20", 6, QLatin1Char(' ')).toStdString()
183 << QString(" %1").arg(ac, 5, QLatin1Char(' ')).toStdString() << endl;
184 _out << "-TROP/COORDINATES"<< endl;
185 _out << "*-------------------------------------------------------------------------------" << endl;
186
187
188 _out << "+SITE/ECCENTRICITY" << endl;
189 _out << "* UP______ NORTH___ EAST____" << endl;
190 _out << "*STATION__ PT SOLN T __DATA_START__ __DATA_END____ AXE MARKER->ARP(m)__________" << endl;
191 _out << " " << _opt->_roverName.substr(0,9) << " A "
192 << QString("%1").arg(solId, 4, QLatin1Char(' ')).toStdString() << " P "
193 << startTime.toStdString() << " " << endTime.toStdString()
194 << QString(" %1").arg("UNE", 3, QLatin1Char(' ')).toStdString()
195 << QString("%1").arg(_opt->_neuEccRover(3), 8, 'f', 4, QLatin1Char(' ')).toStdString()
196 << QString("%1").arg(_opt->_neuEccRover(1), 8, 'f', 4, QLatin1Char(' ')).toStdString()
197 << QString("%1").arg(_opt->_neuEccRover(2), 8, 'f', 4, QLatin1Char(' ')).toStdString() << endl;
198 _out << "-SITE/ECCENTRICITY" << endl;
199 _out << "*-------------------------------------------------------------------------------" << endl;
200
201 if (!_opt->_recNameRover.empty()) {
202 _out << "+SITE/RECEIVER" << endl;
203 _out << "*STATION__ PT SOLN T __DATA_START__ __DATA_END____ DESCRIPTION_________ S/N_________________ FIRMW______" << endl;
204 _out << " " << _opt->_roverName.substr(0,9) << " A "
205 << QString("%1").arg(solId, 4, QLatin1Char(' ')).toStdString() << " P "
206 << startTime.toStdString() << " " << endTime.toStdString() << " "
207 << left << std::setw(20) << _opt->_recNameRover
208 << " --------------------" << " -----------" << endl;
209 _out << "-SITE/RECEIVER" << endl;
210 _out << "*-------------------------------------------------------------------------------" << endl;
211 }
212 if (!_opt->_antexFileName.empty()) {
213 _antex = new bncAntex(_opt->_antexFileName.c_str());
214 _out << "+SITE/ANTENNA" << endl;
215 _out << "*STATION__ PT SOLN T __DATA_START__ __DATA_END____ DESCRIPTION_________ S/N_________________ PCV_MODEL_" << endl;
216 _out << " " << _opt->_roverName.substr(0,9) << " A "
217 << QString("%1").arg(solId, 4, QLatin1Char(' ')).toStdString() << " P "
218 << startTime.toStdString() << " " << endTime.toStdString()
219 << QString(" %1").arg(_opt->_antNameRover.c_str(), 20,QLatin1Char(' ')).toStdString()
220 << " --------------------" << _antex->snxCodeSinexString(_opt->_antNameRover).toStdString() << endl;
221 _out << "-SITE/ANTENNA" << endl;
222 _out << "*-------------------------------------------------------------------------------" << endl;
223 delete _antex;
224 _antex = 0;
225}
226 _out << "+TROP/SOLUTION" << endl;
227 _out << "*STATION__ ____EPOCH_____ TROTOT STDDEV " << endl;
228}
229
230// Write One Epoch
231////////////////////////////////////////////////////////////////////////////
232t_irc bncSinexTro::write(QByteArray staID, int GPSWeek, double GPSWeeks,
233 double trotot, double stdev) {
234
235 QDateTime datTim = dateAndTimeFromGPSweek(GPSWeek, GPSWeeks);
236 int daysec = int(fmod(GPSWeeks, 86400.0));
237 int dayOfYear = datTim.date().dayOfYear();
238 QString yyyy = datTim.toString("yyyy");
239 QString time = QString("%1:%2:%3").arg(yyyy)
240 .arg(dayOfYear, 3, 10, QLatin1Char('0'))
241 .arg(daysec , 5, 10, QLatin1Char('0'));
242
243 if ((reopen(GPSWeek, GPSWeeks) == success) &&
244 (fmod(daysec, double(_sampl)) == 0.0)) {
245 _out << ' ' << staID.left(9).data() << ' ' << time.toStdString()
246 << QString(" %1").arg(trotot * 1000.0, 6, 'f', 1, QLatin1Char(' ')).toStdString()
247 << QString(" %1").arg(stdev * 1000.0, 6, 'f', 1, QLatin1Char(' ')).toStdString() << endl;
248 _out.flush();
249 return success;
250 } else {
251 return failure;
252 }
253}
254
255// Close File (write last lines)
256////////////////////////////////////////////////////////////////////////////
257void bncSinexTro::closeFile() {
258 _out << "-TROP/SOLUTION" << endl;
259 _out << "%=ENDTROP" << endl;
260 bncoutf::closeFile();
261}
262
263
264
265
Note: See TracBrowser for help on using the repository browser.