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

Last change on this file since 7767 was 7767, checked in by stuerze, 8 years ago

some bugs in SINEX TRO header line fixed

  • Property svn:keywords set to Author Date Id Rev URL;svn:eol-style=native
  • Property svn:mime-type set to text/plain
File size: 11.6 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 = 1 : _sampl = sampl;
35
36 if (!_opt->_antexFileName.empty()) {
37 _antex = new bncAntex(_opt->_antexFileName.c_str());
38 }
39 else {
40 _antex = 0;
41 }
42}
43
44// Destructor
45////////////////////////////////////////////////////////////////////////////
46bncSinexTro::~bncSinexTro() {
47 closeFile();
48 if (_antex)
49 delete _antex;
50}
51
52// Write Header
53////////////////////////////////////////////////////////////////////////////
54void bncSinexTro::writeHeader(const QDateTime& datTim) {
55 int GPSWeek;
56 double GPSWeeks;
57 bncSettings settings;
58 GPSweekFromDateAndTime(datTim, GPSWeek, GPSWeeks);
59 int daysec = int(fmod(GPSWeeks, 86400.0));
60 int dayOfYear = datTim.date().dayOfYear();
61 QString yy = datTim.toString("yy");
62 QString creationTime = QString("%1:%2:%3").arg(yy)
63 .arg(dayOfYear, 3, 10, QLatin1Char('0'))
64 .arg(daysec , 5, 10, QLatin1Char('0'));
65 QString startTime = creationTime;
66 QString intStr = settings.value("PPP/snxtroIntr").toString();
67 int intr, indHlp = 0;
68 if ((indHlp = intStr.indexOf("min")) != -1) {
69 intr = intStr.left(indHlp-1).toInt();
70 intr *= 60;
71 }
72 else if ((indHlp = intStr.indexOf("hour")) != -1) {
73 intr = intStr.left(indHlp-1).toInt();
74 intr *= 3600;
75 }
76 else if ((indHlp = intStr.indexOf("day")) != -1) {
77 intr = intStr.left(indHlp-1).toInt();
78 intr *= 86400;
79 }
80 int nominalStartSec = daysec - (int(fmod(double(daysec), double(intr))));
81 int nominalEndSec = nominalStartSec + intr - _sampl;
82 QString endTime = QString("%1:%2:%3").arg(yy)
83 .arg(dayOfYear , 3, 10, QLatin1Char('0'))
84 .arg(nominalEndSec , 5, 10, QLatin1Char('0'));
85 int numEpochs = ((nominalEndSec - daysec) / _sampl) +1;
86 QString epo = QString("%1").arg(numEpochs, 5, 10, QLatin1Char('0'));
87 QString ac = QString("%1").arg(settings.value("PPP/snxtroAc").toString(),3,QLatin1Char('0'));
88 QString sol = QString("%1").arg(settings.value("PPP/snxtroSol").toString(),4,QLatin1Char('0'));
89 QString corr = settings.value("PPP/corrMount").toString();
90
91 _out << "%=TRO 2.00 " << ac.toStdString() << " "
92 << creationTime.toStdString() << " " << ac.toStdString() << " "
93 << startTime.toStdString() << " " << endTime.toStdString() << " P "
94 << epo.toStdString() << " 0 " << " T " << endl;
95
96 _out << "+FILE/REFERENCE" << endl;
97 _out << " DESCRIPTION " << "BNC generated SINEX TRO file" << endl;
98 _out << " OUTPUT " << "Total Troposphere Zenith Path Delay Product" << endl;
99 _out << " SOFTWARE " << BNCPGMNAME << endl;
100 _out << " INPUT " << "Ntrip streams, additional Orbit and Clock information from "
101 << corr.toStdString() <<endl;
102 _out << "-FILE/REFERENCE" << endl << endl;
103
104 double recEll[3];
105 int lonD, lonM, latD, latM;
106 double lonS, latS;
107 xyz2ell(_opt->_xyzAprRover.data(), recEll);
108 recEll[0] = recEll[0] * 180.0 / M_PI;
109 recEll[1] = recEll[1] * 180.0 / M_PI;
110 deg2DMS(recEll[1], lonD, lonM, lonS);
111 deg2DMS(recEll[0], latD, latM, latS);
112 QString country;
113 QListIterator<QString> it(settings.value("mountPoints").toStringList());
114 while (it.hasNext()) {
115 QStringList hlp = it.next().split(" ");
116 if (hlp.size() < 7)
117 continue;
118 if (hlp.join(" ").indexOf(QString::fromStdString(_opt->_roverName), 0) != -1) {
119 country = hlp[2];
120 }
121 }
122 _out << "+SITE/ID" << endl;
123 _out << "*CODE PT DOMES____ T _STATION DESCRIPTION___ APPROX_LON_ APPROX_LAT_ _APP_H_" << endl;
124 _out << " " << _opt->_roverName.substr(0,4) << " A P "
125 << country.toStdString() << " "
126 << QString(" %1").arg(lonD, 3, 10, QLatin1Char(' ')).toStdString()
127 << QString(" %1").arg(lonM, 2, 10, QLatin1Char(' ')).toStdString()
128 << QString(" %1").arg(lonS, 4, 'f', 1, QLatin1Char(' ')).toStdString()
129 << QString(" %1").arg(latD, 3, 10, QLatin1Char(' ')).toStdString()
130 << QString(" %1").arg(latM, 2, 10, QLatin1Char(' ')).toStdString()
131 << QString(" %1").arg(latS, 4, 'f', 1, QLatin1Char(' ')).toStdString()
132 << QString(" %1").arg(recEll[2], 7, 'f', 1, QLatin1Char(' ')).toStdString()
133 << endl;
134 _out << "-SITE/ID" << endl << endl;
135
136 if (!_opt->_recNameRover.empty()) {
137 _out << "+SITE/RECEIVER" << endl;
138 _out << "*SITE PT SOLN T DATA_START__ DATA_END____ DESCRIPTION_________ S/N__ FIRMWARE___" << endl;
139 _out << " " << _opt->_roverName.substr(0,4) << " A " << sol.toStdString() << " P "
140 << startTime.toStdString() << " " << endTime.toStdString() << " " << _opt->_recNameRover << endl;
141 _out << "-SITE/RECEIVER" << endl << endl;
142 }
143
144 _out << "+SITE/ANTENNA" << endl;
145 _out << "*SITE PT SOLN T DATA_START__ DATA_END____ DESCRIPTION_________ S/N__" << endl;
146 _out << " " << _opt->_roverName.substr(0,4) << " A " << sol.toStdString() << " P "
147 << startTime.toStdString() << " " << endTime.toStdString() << " " << _opt->_antNameRover << endl;
148 _out << "-SITE/ANTENNA" << endl << endl;
149
150 if (_antex) {
151 if (_opt->_LCsGPS.size()) {
152 _out << "+SITE/GPS_PHASE_CENTER" << endl;
153 _out << "* UP____ NORTH_ EAST__ UP____ NORTH_ EAST__" << endl;
154 _out << "*DESCRIPTION_________ S/N__ L1->ARP(m)__________ L2->ARP(m)__________ AZ_EL____" << endl;
155 _out << QString(" %1").arg(_opt->_antNameRover.c_str(), 20,QLatin1Char(' ')).toStdString()
156 << " "
157 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::G1).toStdString()
158 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::G2).toStdString()
159 << endl;
160 _out << "-SITE/GPS_PHASE_CENTER" << endl << endl;
161 }
162 if (_opt->_LCsGLONASS.size()) {
163 _out << "+SITE/GLONASS_PHASE_CENTER" << endl;
164 _out << "* UP____ NORTH_ EAST__ UP____ NORTH_ EAST__" << endl;
165 _out << "*DESCRIPTION_________ S/N__ L1->ARP(m)__________ L2->ARP(m)__________ AZ_EL____" << endl;
166 _out << QString(" %1").arg(_opt->_antNameRover.c_str(), 20,QLatin1Char(' ')).toStdString()
167 << " "
168 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::R1).toStdString()
169 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::R2).toStdString()
170 << endl;
171 _out << "-SITE/GLONASS_PHASE_CENTER" << endl << endl;
172 }
173 if (_opt->_LCsGalileo.size()) {
174 _out << "+SITE/GALILEO_PHASE_CENTER" << endl;
175 _out << "* UP____ NORTH_ EAST__ UP____ NORTH_ EAST__" << endl;
176 _out << "*DESCRIPTION_________ S/N__ L1->ARP(m)__________ L2->ARP(m)__________ AZ_EL____" << endl;
177 _out << QString(" %1").arg(_opt->_antNameRover.c_str(), 20,QLatin1Char(' ')).toStdString()
178 << " "
179 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::E1).toStdString()
180 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::E5).toStdString()
181 << endl;
182 _out << "-SITE/GALILEO_PHASE_CENTER" << endl << endl;
183 }
184 if (_opt->_LCsBDS.size()) {
185 _out << "+SITE/BEIDOU_PHASE_CENTER" << endl;
186 _out << "* UP____ NORTH_ EAST__ UP____ NORTH_ EAST__" << endl;
187 _out << "*DESCRIPTION_________ S/N__ L1->ARP(m)__________ L2->ARP(m)__________ AZ_EL____" << endl;
188 _out << QString(" %1").arg(_opt->_antNameRover.c_str(), 20,QLatin1Char(' ')).toStdString()
189 << " "
190 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::C2).toStdString()
191 << _antex->pcoSinexString(_opt->_antNameRover, t_frequency::C7).toStdString()
192 << endl;
193 _out << "-SITE/BEIDOU_PHASE_CENTER" << endl << endl;
194 }
195 }
196
197 _out << "+SITE/ECCENTRICITY" << endl;
198 _out << "* UP______ NORTH___ EAST____" << endl;
199 _out << "*SITE PT SOLN T DATA_START__ DATA_END____ AXE ARP->BENCHMARK(M)_________" << endl;
200 _out << " " << _opt->_roverName.substr(0,4) << " A " << sol.toStdString() << " P "
201 << startTime.toStdString() << " " << endTime.toStdString() << " UNE"
202 << QString("%1").arg(_opt->_neuEccRover(3), 9, 'f', 4, QLatin1Char(' ')).toStdString()
203 << QString("%1").arg(_opt->_neuEccRover(1), 9, 'f', 4, QLatin1Char(' ')).toStdString()
204 << QString("%1").arg(_opt->_neuEccRover(2), 9, 'f', 4, QLatin1Char(' ')).toStdString() << endl;
205 _out << "-SITE/ANTENNA" << endl << endl;
206
207 _out << "+TROP/COORDINATES" << endl;
208 _out << "*SITE PT SOLN T STA_X_______ STA_Y_______ STA_Z_______ SYSTEM REMARK" << endl;
209 _out << " " << _opt->_roverName.substr(0,4) << " A " << sol.toStdString() << " P"
210 << QString(" %1").arg(_opt->_xyzAprRover(1), 12, 'f', 3, QLatin1Char(' ')).toStdString()
211 << QString(" %1").arg(_opt->_xyzAprRover(2), 12, 'f', 3, QLatin1Char(' ')).toStdString()
212 << QString(" %1").arg(_opt->_xyzAprRover(3), 12, 'f', 3, QLatin1Char(' ')).toStdString()
213 << " ITRF08"<< endl;
214 _out << "-TROP/COORDINATES"<< endl << endl;
215
216 _out << "+TROP/DESCRIPTION" << endl;
217 _out << "*KEYWORD______________________ VALUE(S)______________" << endl;
218 _out << " SAMPLING INTERVAL "
219 << setw(4) << _sampl << endl;
220 _out << " SAMPLING TROP "
221 << setw(4) << _sampl << endl;
222 _out << " ELEVATION CUTOFF ANGLE "
223 << setw(4) << int(_opt->_minEle * 180.0/M_PI) << endl;
224 _out << " TROP MAPPING FUNCTION " << "Saastamoinen" << endl;
225 _out << " SOLUTION_FIELDS_1 " << "TROTOT STDEV" << endl;
226 _out << "-TROP/DESCRIPTION"<< endl << endl;
227
228 _out << "+TROP/SOLUTION" << endl;
229 _out << "*SITE EPOCH_______ TROTOT STDEV" << endl;
230}
231
232// Write One Epoch
233////////////////////////////////////////////////////////////////////////////
234t_irc bncSinexTro::write(QByteArray staID, int GPSWeek, double GPSWeeks,
235 double trotot, double stdev) {
236
237 QDateTime datTim = dateAndTimeFromGPSweek(GPSWeek, GPSWeeks);
238 int daysec = int(fmod(GPSWeeks, 86400.0));
239 int dayOfYear = datTim.date().dayOfYear();
240 QString yy = datTim.toString("yy");
241 QString time = QString("%1:%2:%3").arg(yy)
242 .arg(dayOfYear, 3, 10, QLatin1Char('0'))
243 .arg(daysec , 5, 10, QLatin1Char('0'));
244
245 if ((reopen(GPSWeek, GPSWeeks) == success) &&
246 (fmod(daysec, double(_sampl)) == 0.0)) {
247 _out << ' ' << staID.left(4).data() << ' ' << time.toStdString() << ' '
248 << noshowpos << setw(6) << setprecision(1) << trotot * 1000.0
249 << noshowpos << setw(6) << setprecision(1) << stdev * 1000.0 << endl;
250 _out.flush();
251 return success;
252 } else {
253 return failure;
254 }
255}
256
257// Close File (write last lines)
258////////////////////////////////////////////////////////////////////////////
259void bncSinexTro::closeFile() {
260 _out << "-TROP/SOLUTION" << endl;
261 _out << "%=ENDTROP" << endl;
262 bncoutf::closeFile();
263}
264
265
266
267
Note: See TracBrowser for help on using the repository browser.