57 using namespace StringUtils;
59 const string Rinex3ClockHeader::versionString =
"RINEX VERSION / TYPE";
60 const string Rinex3ClockHeader::runByString =
"PGM / RUN BY / DATE";
61 const string Rinex3ClockHeader::commentString =
"COMMENT";
62 const string Rinex3ClockHeader::sysString =
"SYS / # / OBS TYPES";
63 const string Rinex3ClockHeader::timeSystemString =
"TIME SYSTEM ID";
64 const string Rinex3ClockHeader::leapSecondsString =
"LEAP SECONDS";
65 const string Rinex3ClockHeader::sysDCBString =
"SYS / DCBS APPLIED";
66 const string Rinex3ClockHeader::sysPCVString =
"SYS / PCVS APPLIED";
67 const string Rinex3ClockHeader::numDataString =
"# / TYPES OF DATA";
68 const string Rinex3ClockHeader::stationNameString =
"STATION NAME / NUM";
69 const string Rinex3ClockHeader::stationClockRefString =
"STATION CLK REF";
70 const string Rinex3ClockHeader::analysisCenterString =
"ANALYSIS CENTER";
71 const string Rinex3ClockHeader::numClockRefString =
"# OF CLK REF";
72 const string Rinex3ClockHeader::analysisClkRefrString =
"ANALYSIS CLK REF";
73 const string Rinex3ClockHeader::numReceiversString =
"# OF SOLN STA / TRF";
74 const string Rinex3ClockHeader::solnStateString =
"SOLN STA NAME / NUM";
75 const string Rinex3ClockHeader::numSolnSatsString =
"# OF SOLN SATS";
76 const string Rinex3ClockHeader::prnListString =
"PRN LIST";
77 const string Rinex3ClockHeader::endOfHeaderString =
"END OF HEADER";
80 void Rinex3ClockHeader::reallyGetRecord(
FFStream& ffs)
91 while(!(
valid & endOfHeaderValid)) {
96 if(
debug) cout <<
"Rinex3Clock Header Line " << line << endl;
98 if(line.length() == 0)
continue;
99 else if(line.length() < 60 || line.length() > 80) {
100 FFStreamError e(
"Invalid line length");
106 string label(line, 60, 20);
107 if(label == versionString) {
109 if(line[20] !=
'C') {
110 FFStreamError e(
"Invalid file type: " + line.substr(20,1));
113 fileSys =
strip(line.substr(35,20));
114 valid |= versionValid;
116 else if(label == runByString) {
117 program =
strip(line.substr(0,20));
118 runby =
strip(line.substr(20,20));
122 else if(label == commentString) {
123 commentList.push_back(
strip(line.substr(0,60)));
124 valid |= commentValid;
126 else if(label == sysString) {
127 string satSys =
strip(line.substr(0,1));
130 numObs =
asInt(line.substr(3,3));
138 const int maxObsPerLine = 13;
139 for (
int i=0; i < maxObsPerLine && sysObsTypes[satSys].size() < numObs; i++)
140 sysObsTypes[satSys].push_back(
143 catch(InvalidParameter& ip)
145 FFStreamError fse(
"InvalidParameter: "+ip.what());
150 else if(label == timeSystemString) {
153 valid |= timeSystemValid;
155 else if(label == leapSecondsString) {
156 leapSeconds =
asInt(line.substr(0,6));
157 valid |= leapSecondsValid;
159 else if(label == sysDCBString)
161 string satstr(line.substr(0,1));
167 strip(line.substr(20,40)));
171 FFStreamError e(exc);
172 e.addText(
"Invalid dcbs system : " + line.substr(0,1));
175 valid |= sysDCBValid;
177 else if(label == sysPCVString)
179 string satstr(line.substr(0,1));
185 strip(line.substr(20,40)));
189 FFStreamError e(exc);
190 e.addText(
"Invalid pcvs system : " + line.substr(0,1));
193 valid |= sysPCVValid;
195 else if(label == numDataString) {
196 int n(
asInt(line.substr(0,6)));
197 for(
int i=0; i<n; ++i)
198 dataTypes.push_back(line.substr(10+i*6,2));
199 valid |= numDataValid;
201 else if(label == stationNameString) {
204 valid |= stationNameValid;
206 else if(label == stationClockRefString) {
207 valid |= stationClockRefValid;
209 else if(label == analysisCenterString) {
210 analCenterDesignator =
strip(line.substr(0,3));
211 analysisCenter =
strip(line.substr(5,55));
212 valid |= analysisCenterValid;
214 else if(label == numClockRefString) {
215 valid |= numClockRefValid;
217 else if(label == analysisClkRefrString) {
218 valid |= analysisClkRefrValid;
220 else if(label == numReceiversString) {
221 numSolnStations =
asInt(line.substr(0,6));
222 terrRefFrame =
strip(line.substr(10,50));
223 valid |= numReceiversValid;
225 else if(label == solnStateString) {
226 string label(
strip(line.substr(0,4)));
227 stationID[label] =
strip(line.substr(5,20));
228 stationX[label] =
strip(line.substr(25,11));
229 stationY[label] =
strip(line.substr(37,11));
230 stationZ[label] =
strip(line.substr(49,11));
231 valid |= solnStateValid;
233 else if(label == numSolnSatsString) {
234 numSolnSatellites =
asInt(line.substr(0,6));
235 valid |= numSolnSatsValid;
237 else if(label == prnListString) {
240 for(i=0; i<15; ++i) {
241 label = line.substr(4*i,3);
242 if(label ==
string(
" "))
247 satList.push_back(sat);
251 FFStreamError e(exc);
252 e.addText(
"Invalid sat (PRN LIST): /" + label +
"/");
257 valid |= prnListValid;
259 else if(label == endOfHeaderString) {
260 valid |= endOfHeaderValid;
263 FFStreamError e(
"Invalid line label: " + label);
267 if(
debug) cout <<
"Valid is " << hex <<
valid << fixed << endl;
274 if(
debug) cout <<
"Header read; Valid is " << hex <<
valid << fixed << endl;
277 if( (
valid & allRequiredValid) != allRequiredValid) {
278 cout <<
"Header is invalid on input (valid is x" << hex <<
valid
281 FFStreamError e(
"Invalid header");
290 void Rinex3ClockHeader::reallyPutRecord(
FFStream& ffs)
const
296 if( (
valid & allRequiredValid) != allRequiredValid) {
297 FFStreamError e(
"Invalid header");
305 line += string(11,
' ');
306 line += string(
"CLOCK") + string(15,
' ');
310 line += string(20,
' ');
311 line += versionString;
312 strm << line << endl;
320 dat =
printTime(dt,
"%04Y/%02m/%02d %02H:%02M:%02S %4P");
322 dat =
printTime(dt,
"%02m/%02d/%04Y %02H:%02M:%02S");
325 strm << line << endl;
329 RinexObsMap::const_iterator it = sysObsTypes.begin();
330 for (;it != sysObsTypes.end(); it++)
332 static const int maxObsPerLine = 13;
334 map<string,vector<RinexObsID> >::const_iterator mapIter;
335 for(mapIter = sysObsTypes.begin(); mapIter != sysObsTypes.end();
341 vector<RinexObsID> ObsTypeList = mapIter->second;
343 for(
size_t i = 0; i < ObsTypeList.size(); i++)
349 line += string(2,
' ');
353 else if((obsWritten % maxObsPerLine) == 0)
355 line += string(2,
' ');
357 strm << line << endl;
359 line = string(6,
' ');
361 line += string(1,
' ');
365 line += string(60 - line.size(),
' ');
367 strm << line << endl;
374 line = string(3,
' ');
376 line += timeSystemString;
377 strm << line << endl;
381 for(i=0; i<commentList.size(); ++i) {
383 line += commentString;
384 strm << line << endl;
388 if(
valid & leapSecondsValid) {
390 line += string(54,
' ');
391 line += leapSecondsString;
392 strm << line << endl;
397 std::map<std::string,stringPair>::const_iterator cbsCor;
398 for (cbsCor = dcbsMap.begin(); cbsCor != dcbsMap.end(); cbsCor++)
403 line += sysDCBString;
404 strm << line << endl;
410 std::map<std::string,stringPair>::const_iterator pcCor;
411 for (pcCor = pcvsMap.begin(); pcCor != pcvsMap.end(); pcCor++)
416 line += sysPCVString;
417 strm << line << endl;
423 for(i=0; i<dataTypes.size(); ++i)
424 line +=
string(4,
' ') + dataTypes[i];
425 line += string(60-line.size(),
' ');
426 line += numDataString;
427 strm << line << endl;
438 line = analCenterDesignator;
439 line += string(2,
' ');
441 line += analysisCenterString;
442 strm << line << endl;
454 line += string(4,
' ');
456 line += numReceiversString;
457 strm << line << endl;
460 map<string,string>::const_iterator it, jt;
461 for(it=stationID.begin(); it != stationID.end(); ++it) {
462 string label(it->first),field;
464 line += string(1,
' ');
466 jt = stationX.find(label);
469 line += string(1,
' ');
470 jt = stationY.find(label);
473 line += string(1,
' ');
474 jt = stationZ.find(label);
477 line += solnStateString;
478 strm << line << endl;
483 line += string(54,
' ');
484 line += numSolnSatsString;
485 strm << line << endl;
489 for(i=0; i<satList.size(); ++i) {
491 satstr[0] = satList[i].systemChar();
493 if(satstr[1] ==
' ') satstr[1] =
'0';
494 line += satstr + string(1,
' ');
495 if(((i+1) % 15) == 0 || i==satList.size()-1) {
496 line += string(60-line.size(),
' ');
497 line += prnListString;
498 strm << line << endl;
504 line = string(60,
' ');
505 line += endOfHeaderString;
506 strm << line << endl;
521 os <<
"Dump Rinex3Clock Header:\n";
522 os <<
" Version = " << fixed << setprecision(2) <<
version
523 <<
" Prgm /" << program <<
"/ Run By /" << runby <<
"/" << endl;
524 os <<
" There are " << dataTypes.size() <<
" data types, as follows:";
525 for(i=0; i<dataTypes.size(); ++i)
526 os <<
" " << dataTypes[i];
528 os <<
" Leap seconds is " << leapSeconds << endl;
529 os <<
" Analysis center: /" << analCenterDesignator
530 <<
"/ /" << analysisCenter <<
"/" << endl;
531 os <<
" Terrestrial Reference Frame " << terrRefFrame << endl;
532 std::map<std::string,stringPair>::const_iterator dcbs;
533 for (dcbs = dcbsMap.begin(); dcbs != dcbsMap.end(); dcbs++)
535 os <<
" DCBs: " << dcbs->first <<
" /" << dcbs->second.first <<
"/ /"
536 << dcbs->second.second <<
"/" << endl;
538 std::map<std::string,stringPair>::const_iterator pcvs;
539 for (pcvs = pcvsMap.begin(); pcvs != pcvsMap.end(); pcvs++)
541 os <<
" PCVs: " << pcvs->first <<
" /" << pcvs->second.first <<
"/ /"
542 << pcvs->second.second <<
"/" << endl;
544 os <<
" Comments:\n";
545 for(i=0; i<commentList.size(); ++i)
546 os <<
" " << commentList[i] << endl;
547 os <<
" There are " << stationID.size() <<
" stations." << endl;
548 os <<
" There are " << satList.size() <<
" satellites." << endl;
550 os <<
" Stations: identifier X(mm) Y(mm) Z(mm)\n";
551 map<string,string>::const_iterator it, jt;
552 for(it=stationID.begin(); it!=stationID.end(); ++it) {
553 string label(it->first),field;
554 os <<
" " << label <<
" " << it->second;
555 jt = stationX.find(label);
558 jt = stationY.find(label);
561 jt = stationZ.find(label);
565 os <<
" Sat list:\n";
566 for(i=0; i<satList.size(); ++i) {
567 os <<
" " << satList[i];
568 if(((i+1)%15) == 0 || i == satList.size()-1) os << endl;
571 if(detail >= 2) dumpValid(os);
574 os <<
"End of Rinex3Clock header dump." << endl;
578 void Rinex3ClockHeader::dumpValid(ostream& os)
const noexcept
580 if( (
valid & allValid) == allValid)
return;
581 string tag(
" Invalid or missing header line: ");
582 os <<
"Dump invalid or missing header records:\n";
583 if(!(
valid & versionValid)) os << tag << versionString << endl;
584 if(!(
valid & runByValid)) os << tag << runByString << endl;
585 if(!(
valid & commentValid)) os << tag << commentString << endl;
586 if(!(
valid & sysValid)) os << tag << sysString << endl;
587 if(!(
valid & timeSystemValid)) os << tag << timeSystemString << endl;
588 if(!(
valid & leapSecondsValid)) os << tag << leapSecondsString << endl;
589 if(!(
valid & sysDCBValid)) os << tag << sysDCBString << endl;
590 if(!(
valid & sysPCVValid)) os << tag << sysPCVString << endl;
591 if(!(
valid & numDataValid)) os << tag << numDataString << endl;
592 if(!(
valid & stationNameValid)) os << tag << stationNameString << endl;
593 if(!(
valid & stationClockRefValid)) os << tag << stationClockRefString << endl;
594 if(!(
valid & analysisCenterValid)) os << tag << analysisCenterString << endl;
595 if(!(
valid & numClockRefValid)) os << tag << numClockRefString << endl;
596 if(!(
valid & analysisClkRefrValid)) os << tag << analysisClkRefrString << endl;
597 if(!(
valid & numReceiversValid)) os << tag << numReceiversString << endl;
598 if(!(
valid & solnStateValid)) os << tag << solnStateString << endl;
599 if(!(
valid & numSolnSatsValid)) os << tag << numSolnSatsString << endl;
600 if(!(
valid & prnListValid)) os << tag << prnListString << endl;
601 if(!(
valid & endOfHeaderValid)) os << tag << endOfHeaderString << endl;
602 os <<
"End of invalid or missing dump" << endl;