00001 #pragma ident "$Id: RinexObsData.cpp 2558 2011-04-18 21:06:12Z architest $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00044 #include "StringUtils.hpp"
00045 #include "RinexObsData.hpp"
00046 #include "RinexObsStream.hpp"
00047
00048 using namespace gpstk::StringUtils;
00049 using namespace std;
00050
00051 namespace gpstk
00052 {
00053
00054
00055 DayTime gpstk::RinexObsData::previousTime;
00056
00057 void RinexObsData::reallyPutRecord(FFStream& ffs) const
00058 throw(std::exception, FFStreamError, StringException)
00059 {
00060
00061 if( (epochFlag==0 || epochFlag==1 || epochFlag==6)
00062 && (numSvs==0 || obs.empty()) ) return;
00063 if((epochFlag>=2 && epochFlag<=5) &&
00064 auxHeader.NumberHeaderRecordsToBeWritten()==0) return;
00065
00066 RinexObsStream& strm = dynamic_cast<RinexObsStream&>(ffs);
00067 string line;
00068
00069
00070 line = writeTime(time);
00071 line += string(2, ' ');
00072 line += rightJustify(asString<short>(epochFlag), 1);
00073 line += rightJustify(asString<short>(numSvs), 3);
00074
00075
00076 const int maxPrnsPerLine = 12;
00077 int satsWritten = 0;
00078 RinexSatMap::const_iterator obsItr = obs.begin();
00079 if(epochFlag==0 || epochFlag==1 || epochFlag==6) {
00080 while ((obsItr != obs.end()) && (satsWritten < maxPrnsPerLine))
00081 {
00082 RinexSatID prn((*obsItr).first);
00083 line += prn.toString();
00084 satsWritten++;
00085 obsItr++;
00086 }
00087
00088
00089 if(clockOffset != 0.0) {
00090 line += string(68 - line.size(), ' ');
00091 line += rightJustify(asString(clockOffset, 9), 12);
00092 }
00093
00094
00095 while (satsWritten != obs.size())
00096 {
00097 if ((satsWritten % maxPrnsPerLine) == 0)
00098 {
00099 strm << line << endl;
00100 strm.lineNumber++;
00101 line = string(32, ' ');
00102 }
00103 RinexSatID prn(obsItr->first);
00104 line += prn.toString();
00105 satsWritten++;
00106 obsItr++;
00107 }
00108 }
00109
00110
00111 strm << line << endl;
00112 strm.lineNumber++;
00113
00114
00115 if(epochFlag >= 2 && epochFlag <= 5)
00116 {
00117 try {
00118 auxHeader.WriteHeaderRecords(strm);
00119 }
00120 catch(FFStreamError& e)
00121 {
00122 GPSTK_RETHROW(e);
00123 }
00124 catch(StringException& e)
00125 {
00126 GPSTK_RETHROW(e);
00127 }
00128 }
00129
00130
00131 else if (!obs.empty())
00132 {
00133
00134 obsItr = obs.begin();
00135
00136 const int maxObsPerLine = 5;
00137
00138 while(obsItr != obs.end())
00139 {
00140 vector<RinexObsHeader::RinexObsType>::iterator obsTypeItr =
00141 strm.header.obsTypeList.begin();
00142
00143 line.erase();
00144 int obsWritten = 0;
00145
00146 while (obsTypeItr != strm.header.obsTypeList.end())
00147 {
00148 if ( ((obsWritten % maxObsPerLine) == 0) &&
00149 (obsWritten != 0))
00150 {
00151 strm << line << endl;
00152 strm.lineNumber++;
00153 line.erase();
00154 }
00155
00156 RinexObsTypeMap::const_iterator rotmi(obsItr->second.find(*obsTypeItr));
00157 RinexDatum thisData;
00158 if (rotmi != obsItr->second.end())
00159 thisData = rotmi->second;
00160 line += rightJustify(asString(thisData.data,3),14);
00161 if (thisData.lli == 0)
00162 line += string(1, ' ');
00163 else
00164 line += rightJustify(asString<short>(thisData.lli),1);
00165 if (thisData.ssi == 0)
00166 line += string(1, ' ');
00167 else
00168 line += rightJustify(asString<short>(thisData.ssi),1);
00169 obsWritten++;
00170 obsTypeItr++;
00171 }
00172 strm << line << endl;
00173 strm.lineNumber++;
00174 obsItr++;
00175 }
00176 }
00177 }
00178
00179
00180 void RinexObsData::reallyGetRecord(FFStream& ffs)
00181 throw(exception, FFStreamError, gpstk::StringUtils::StringException)
00182 {
00183 RinexObsStream& strm = dynamic_cast<RinexObsStream&>(ffs);
00184
00185
00186 if(!strm.headerRead) strm >> strm.header;
00187
00188
00189 RinexObsHeader& hdr = strm.header;
00190
00191 RinexObsData rod;
00192 *this=rod;
00193
00194 string line;
00195
00196
00197
00198
00199
00200 bool isValidEpochLine(false);
00201 while( !isValidEpochLine )
00202 {
00203
00204 strm.formattedGetLine(line, true);
00205
00206 isValidEpochLine = true;
00207
00208 try
00209 {
00210
00211 if( line.size()>80 ) isValidEpochLine = false;
00212
00213
00214 DayTime tempEpoch = parseTime(line, hdr);
00215
00216
00217 if( tempEpoch == DayTime::BEGINNING_OF_TIME )
00218 {
00219 isValidEpochLine = false;
00220 }
00221
00222
00223 short tempNumSat = asInt(line.substr(29,3));
00224
00225 }
00226 catch(...)
00227 {
00228
00229 isValidEpochLine = false;
00230 }
00231
00232 }
00233
00234
00235 epochFlag = asInt(line.substr(28,1));
00236 if ((epochFlag < 0) || (epochFlag > 6))
00237 {
00238 FFStreamError e("Invalid epoch flag: " + asString(epochFlag));
00239 GPSTK_THROW(e);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 bool noEpochTime = (line.substr(0,26) == string(26, ' '));
00252 if (noEpochTime &&
00253 (epochFlag==0 || epochFlag==1 || epochFlag==5 || epochFlag==6 ))
00254 {
00255 FFStreamError e("Required epoch time missing: " + line);
00256 GPSTK_THROW(e);
00257 }
00258 else if (noEpochTime)
00259 {
00260 time = previousTime;
00261 }
00262 else
00263 {
00264 time = parseTime(line, hdr);
00265 previousTime = time;
00266 }
00267
00268 numSvs = asInt(line.substr(29,3));
00269
00270 if( line.size() > 68 )
00271 clockOffset = asDouble(line.substr(68, 12));
00272 else
00273 clockOffset = 0.0;
00274
00275
00276 if(epochFlag==0 || epochFlag==1 || epochFlag==6) {
00277 int isv, ndx, line_ndx;
00278 vector<SatID> satIndex(numSvs);
00279 int col=30;
00280 for (isv=1, ndx=0; ndx<numSvs; isv++, ndx++) {
00281 if(! (isv % 13)) {
00282 strm.formattedGetLine(line);
00283 isv = 1;
00284 if(line.size() > 80) {
00285 FFStreamError err("Invalid line size:" + asString(line.size()));
00286 GPSTK_THROW(err);
00287 }
00288 }
00289 try {
00290 satIndex[ndx] = RinexSatID(line.substr(col+isv*3-1, 3));
00291 }
00292 catch (Exception& e)
00293 {
00294 FFStreamError ffse(e);
00295 GPSTK_THROW(ffse);
00296 }
00297 }
00298
00299 for (isv=0; isv < numSvs; isv++)
00300 {
00301 short numObs = hdr.obsTypeList.size();
00302 for (ndx=0, line_ndx=0; ndx < numObs; ndx++, line_ndx++)
00303 {
00304 SatID sat = satIndex[isv];
00305 RinexObsHeader::RinexObsType obs_type = hdr.obsTypeList[ndx];
00306 if (! (line_ndx % 5))
00307 {
00308 strm.formattedGetLine(line);
00309 line_ndx = 0;
00310 if (line.size() > 80)
00311 {
00312 FFStreamError err("Invalid line size:" + asString(line.size()));
00313 GPSTK_THROW(err);
00314 }
00315 }
00316
00317 line.resize(80, ' ');
00318
00319 obs[sat][obs_type].data = asDouble(line.substr(line_ndx*16, 14));
00320 obs[sat][obs_type].lli = asInt( line.substr(line_ndx*16+14, 1));
00321 obs[sat][obs_type].ssi = asInt( line.substr(line_ndx*16+15, 1));
00322 }
00323 }
00324 }
00325
00326 else if(numSvs > 0) {
00327 auxHeader.clear();
00328 for(int i=0; i<numSvs; i++) {
00329 strm.formattedGetLine(line);
00330 StringUtils::stripTrailing(line);
00331 try {
00332 auxHeader.ParseHeaderRecord(line);
00333 }
00334 catch(FFStreamError& e)
00335 {
00336 GPSTK_RETHROW(e);
00337 }
00338 catch(StringException& e)
00339 {
00340 GPSTK_RETHROW(e);
00341 }
00342 }
00343 }
00344
00345 return;
00346
00347 }
00348
00349
00350 DayTime RinexObsData::parseTime(const string& line,
00351 const RinexObsHeader& hdr) const
00352 throw(FFStreamError)
00353 {
00354 try
00355 {
00356
00357
00358 if ( (line[0] != ' ') ||
00359 (line[3] != ' ') ||
00360 (line[6] != ' ') ||
00361 (line[9] != ' ') ||
00362 (line[12] != ' ') ||
00363 (line[15] != ' '))
00364 {
00365 FFStreamError e("Invalid time format");
00366 GPSTK_THROW(e);
00367 }
00368
00369
00370 if (line.substr(0,26) == string(26, ' '))
00371 {
00372 return DayTime(DayTime::BEGINNING_OF_TIME);
00373 }
00374
00375 int year, month, day, hour, min;
00376 double sec;
00377 int yy = hdr.firstObs.year()/100;
00378 yy *= 100;
00379
00380 year = asInt( line.substr(1, 2 ));
00381 month = asInt( line.substr(4, 2 ));
00382 day = asInt( line.substr(7, 2 ));
00383 hour = asInt( line.substr(10, 2 ));
00384 min = asInt( line.substr(13, 2 ));
00385 sec = asDouble(line.substr(15, 11));
00386
00387
00388 double ds=0;
00389 if(sec >= 60.) { ds=sec; sec=0.0; }
00390 DayTime rv(yy+year, month, day, hour, min, sec);
00391 if(ds != 0) rv += ds;
00392
00393 return rv;
00394 }
00395
00396 catch (std::exception &e)
00397 {
00398 FFStreamError err("std::exception: " + string(e.what()));
00399 GPSTK_THROW(err);
00400 }
00401 catch (gpstk::Exception& e)
00402 {
00403 std::string text;
00404 for(int i=0; i<e.getTextCount(); i++) text += e.getText(i);
00405 FFStreamError err("gpstk::Exception in parseTime(): " + text);
00406 GPSTK_THROW(err);
00407 }
00408
00409 }
00410
00411 string RinexObsData::writeTime(const DayTime& dt) const
00412 throw(StringException)
00413 {
00414 if (dt == DayTime::BEGINNING_OF_TIME)
00415 {
00416 return string(26, ' ');
00417 }
00418
00419 string line;
00420 line = string(1, ' ');
00421 line += rightJustify(asString<short>(dt.year()),2);
00422 line += string(1, ' ');
00423 line += rightJustify(asString<short>(dt.month()),2);
00424 line += string(1, ' ');
00425 line += rightJustify(asString<short>(dt.day()),2);
00426 line += string(1, ' ');
00427 line += rightJustify(asString<short>(dt.hour()),2);
00428 line += string(1, ' ');
00429 line += rightJustify(asString<short>(dt.minute()),2);
00430 line += rightJustify(asString(dt.second(), 7),11);
00431
00432 return line;
00433 }
00434
00435
00436 void RinexObsData::dump(ostream& s) const
00437 {
00438 if (obs.empty())
00439 return;
00440
00441 s << "Dump of RinexObsData - time: ";
00442 s << writeTime(time) << " epochFlag: "
00443 << " " << epochFlag << " numSvs: " << numSvs
00444 << fixed << setprecision(6)
00445 << " clk offset: " << clockOffset << endl;
00446 if(epochFlag == 0 || epochFlag == 1)
00447 {
00448 RinexSatMap::const_iterator it;
00449 for(it=obs.begin(); it!=obs.end(); it++) {
00450 s << "Sat " << setw(2) << RinexSatID(it->first);
00451 RinexObsTypeMap::const_iterator jt;
00452 for(jt=it->second.begin(); jt!=it->second.end(); jt++)
00453 {
00454 s << " " << jt->first.type << ":" << fixed << setprecision(3)
00455 << " " << setw(12) << jt->second.data
00456 << "/" << jt->second.lli << "/" << jt->second.ssi;
00457 }
00458 s << endl;
00459 }
00460 }
00461 else {
00462 s << "aux. header info:\n";
00463 auxHeader.dump(s);
00464 }
00465 }
00466
00467 }