00001 #pragma ident "$Id: RinexMetHeader.cpp 438 2007-03-21 17:22:21Z btolman $"
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
00039
00040
00041
00042
00043
00044
00045
00051 #include <algorithm>
00052
00053 #include "StringUtils.hpp"
00054 #include "DayTime.hpp"
00055 #include "RinexMetHeader.hpp"
00056 #include "RinexMetStream.hpp"
00057
00058 using namespace gpstk::StringUtils;
00059 using namespace std;
00060
00061 namespace gpstk
00062 {
00063 const int RinexMetHeader::maxObsPerLine = 9;
00064
00065 const string RinexMetHeader::versionString = "RINEX VERSION / TYPE";
00066 const string RinexMetHeader::runByString = "PGM / RUN BY / DATE";
00067 const string RinexMetHeader::commentString = "COMMENT";
00068 const string RinexMetHeader::markerNameString = "MARKER NAME";
00069 const string RinexMetHeader::markerNumberString = "MARKER NUMBER";
00070 const string RinexMetHeader::obsTypeString = "# / TYPES OF OBSERV";
00071 const string RinexMetHeader::sensorTypeString = "SENSOR MOD/TYPE/ACC";
00072 const string RinexMetHeader::sensorPosString = "SENSOR POS XYZ/H";
00073 const string RinexMetHeader::endOfHeader = "END OF HEADER";
00074
00075
00076
00077 std::string RinexMetHeader::bitString(unsigned long vb, char quote,
00078 std::string sep)
00079 {
00080 unsigned long b = 1;
00081 std::string rv;
00082 while (b)
00083 {
00084 if (vb & b)
00085 {
00086 if (rv.length())
00087 rv += sep;
00088 if (quote)
00089 rv += quote + bitsAsString((validBits)b) + quote;
00090 else
00091 rv += bitsAsString((validBits)b);
00092 }
00093 b <<= 1;
00094 }
00095 return rv;
00096 }
00097
00098 void RinexMetHeader::reallyPutRecord(FFStream& ffs) const
00099 throw(std::exception, FFStreamError,
00100 gpstk::StringUtils::StringException)
00101 {
00102 RinexMetStream& strm = dynamic_cast<RinexMetStream&>(ffs);
00103
00104
00105
00106 strm.header = (*this);
00107
00108
00109
00110
00111
00112 unsigned long allValid;
00113 if (version == 2.0) allValid = allValid20;
00114 else if (version == 2.1) allValid = allValid21;
00115 else
00116 {
00117 FFStreamError err("Unknown RINEX version: " + asString(version,2));
00118 err.addText("Make sure to set the version correctly.");
00119 GPSTK_THROW(err);
00120 }
00121
00122 if ((valid & allValid) != allValid)
00123 {
00124 string errstr("Incomplete or invalid header: missing: ");
00125 errstr += bitString(allValid & ~valid);
00126 FFStreamError err(errstr);
00127 err.addText("Make sure you set all header valid bits for all of the available data.");
00128 GPSTK_THROW(err);
00129 }
00130
00131 string line;
00132
00133 if (valid & versionValid)
00134 {
00135 line = rightJustify(asString(version,2), 9);
00136 line += string(11, ' ');
00137 line += leftJustify(fileType, 40);
00138 line += versionString;
00139 strm << line << endl;
00140 strm.lineNumber++;
00141 }
00142 if (valid & runByValid)
00143 {
00144 line = leftJustify(fileProgram,20);
00145 line += leftJustify(fileAgency,20);
00146 DayTime dt;
00147 dt.setLocalTime();
00148 string dat = dt.printf("%02m/%02d/%04Y %02H:%02M:%02S");
00149 line += leftJustify(dat, 20);
00150 line += runByString;
00151 strm << line << endl;
00152 strm.lineNumber++;
00153 }
00154 if (valid & commentValid)
00155 {
00156 vector<string>::const_iterator itr = commentList.begin();
00157 while (itr != commentList.end())
00158 {
00159 line = leftJustify((*itr), 60);
00160 line += commentString;
00161 strm << line << endl;
00162 strm.lineNumber++;
00163 itr++;
00164 }
00165 }
00166 if (valid & markerNameValid)
00167 {
00168 line = leftJustify(markerName, 60);
00169 line += markerNameString;
00170 strm << line << endl;
00171 strm.lineNumber++;
00172 }
00173 if (valid & markerNumberValid)
00174 {
00175 line = leftJustify(markerNumber, 60);
00176 line += markerNumberString;
00177 strm << line << endl;
00178 strm.lineNumber++;
00179 }
00180 if (valid & obsTypeValid)
00181 {
00182 line = rightJustify(asString(obsTypeList.size()),6);
00183 vector<RinexMetType>::const_iterator itr = obsTypeList.begin();
00184 size_t numWritten = 0;
00185 while (itr != obsTypeList.end())
00186 {
00187 numWritten++;
00188
00189 if ((numWritten % (maxObsPerLine+1)) == 0)
00190 {
00191 line += obsTypeString;
00192 strm << line << endl;
00193 strm.lineNumber++;
00194 line = string(6,' ');
00195 }
00196 line += rightJustify(convertObsType(*itr), 6);
00197 itr++;
00198 }
00199
00200 line += string(60 - line.size(), ' ');
00201 line += obsTypeString;
00202 strm << line << endl;
00203 strm.lineNumber++;
00204 }
00205 if (valid & sensorTypeValid)
00206 {
00207
00208
00209 vector<sensorType>::const_iterator itr = sensorTypeList.begin();
00210 while (itr != sensorTypeList.end())
00211 {
00212 if (std::find(obsTypeList.begin(), obsTypeList.end(),
00213 (*itr).obsType) != obsTypeList.end())
00214 {
00215 line = leftJustify((*itr).model, 20);
00216 line += leftJustify((*itr).type, 20);
00217 line += string(6, ' ');
00218 line += rightJustify(asString((*itr).accuracy,1),7);
00219 line += string(4, ' ');
00220 line += convertObsType((*itr).obsType);
00221 line += string(1, ' ');
00222 line += sensorTypeString;
00223 strm << line << endl;
00224 strm.lineNumber++;
00225 }
00226 itr++;
00227 }
00228 }
00229 if (valid & sensorPosValid)
00230 {
00231
00232
00233 vector<sensorPosType>::const_iterator itr = sensorPosList.begin();
00234 while (itr != sensorPosList.end())
00235 {
00236 if (std::find(obsTypeList.begin(), obsTypeList.end(),
00237 (*itr).obsType) != obsTypeList.end())
00238 {
00239 line = rightJustify(asString((*itr).position[0],4),14);
00240 line += rightJustify(asString((*itr).position[1],4),14);
00241 line += rightJustify(asString((*itr).position[2],4),14);
00242 line += rightJustify(asString((*itr).height,4),14);
00243 line += string(1, ' ');
00244 line += convertObsType((*itr).obsType);
00245 line += string(1, ' ');
00246 line += sensorPosString;
00247 strm << line << endl;
00248 strm.lineNumber++;
00249 }
00250 itr++;
00251 }
00252 }
00253 if (valid & endValid)
00254 {
00255 line = string(60, ' ');
00256 line += endOfHeader;
00257 strm << line << endl;
00258 strm.lineNumber++;
00259 }
00260 }
00261
00262
00263 void RinexMetHeader::reallyGetRecord(FFStream& ffs)
00264 throw(std::exception, FFStreamError,
00265 gpstk::StringUtils::StringException)
00266 {
00267
00268 RinexMetStream& strm = dynamic_cast<RinexMetStream&>(ffs);
00269
00270 if (strm.headerRead == true)
00271 return;
00272
00273 valid = 0;
00274
00275
00276
00277 commentList.clear();
00278 obsTypeList.clear();
00279 sensorTypeList.clear();
00280 sensorPosList.clear();
00281
00282 int numObs;
00283
00284 while (! (valid & endValid))
00285 {
00286 string line;
00287 strm.formattedGetLine(line);
00288
00289 if (line.length()<60 || line.length()>81)
00290 {
00291 FFStreamError e("Bad line length");
00292 GPSTK_THROW(e);
00293 }
00294
00295 string thisLabel(line, 60, 20);
00296
00297 if (thisLabel == versionString)
00298 {
00299 version = asDouble(line.substr(0,20));
00300 fileType = strip(line.substr(20,20));
00301 if ( (fileType[0] != 'M') &&
00302 (fileType[0] != 'm'))
00303 {
00304 FFStreamError e("This isn't a Rinex Met file");
00305 GPSTK_THROW(e);
00306 }
00307 valid |= versionValid;
00308 }
00309 else if (thisLabel == runByString)
00310 {
00311 fileProgram = strip(line.substr(0,20));
00312 fileAgency = strip(line.substr(20,20));
00313 date = strip(line.substr(40,20));
00314 valid |= runByValid;
00315 }
00316 else if (thisLabel == commentString)
00317 {
00318 commentList.push_back(strip(line.substr(0,60)));
00319 valid |= commentValid;
00320 }
00321 else if (thisLabel == markerNameString)
00322 {
00323 markerName = strip(line.substr(0,60));
00324 valid |= markerNameValid;
00325 }
00326 else if (thisLabel == markerNumberString)
00327 {
00328 markerNumber = strip(line.substr(0,20));
00329 valid |= markerNumberValid;
00330 }
00331 else if (thisLabel == obsTypeString)
00332 {
00333
00334 if (! (valid & obsTypeValid))
00335 {
00336 numObs = gpstk::StringUtils::asInt(line.substr(0,6));
00337 for (int i = 0; (i < numObs) && (i < maxObsPerLine); i++)
00338 {
00339 int currPos = i * 6 + 6;
00340 if (line.substr(currPos, 4) != string(4, ' '))
00341 {
00342 FFStreamError e("Format error for line type " +
00343 obsTypeString);
00344 GPSTK_THROW(e);
00345 }
00346
00347 obsTypeList.push_back(convertObsType(line.substr(currPos + 4, 2)));
00348 }
00349 valid |= obsTypeValid;
00350 }
00351
00352 else
00353 {
00354 int currentObsTypes = obsTypeList.size();
00355 for (int i = currentObsTypes;
00356 (i < numObs) && (i < (maxObsPerLine + currentObsTypes));
00357 i++)
00358 {
00359 int currPos = (i % maxObsPerLine) * 6 + 6;
00360 if (line.substr(currPos, 4) != string(4,' '))
00361 {
00362 FFStreamError e("Format error for line type " +
00363 obsTypeString);
00364 GPSTK_THROW(e);
00365 }
00366 obsTypeList.push_back(convertObsType(line.substr(currPos + 4, 2)));
00367 }
00368 }
00369 }
00370 else if (thisLabel == sensorTypeString)
00371 {
00372 if (line.substr(40,6) != string(6, ' '))
00373 {
00374 FFStreamError e("Format error for line type " +
00375 sensorTypeString);
00376 GPSTK_THROW(e);
00377 }
00378 sensorType st;
00379 st.model = strip(line.substr(0,20));
00380 st.type = strip(line.substr(20,20));
00381 st.accuracy = asDouble(line.substr(46,9));
00382 st.obsType = convertObsType(line.substr(57,2));
00383
00384 sensorTypeList.push_back(st);
00385
00386
00387
00388 if (sensorTypeList.size() == obsTypeList.size())
00389 {
00390 valid |= sensorTypeValid;
00391 }
00392 else
00393 {
00394 valid &= ~(long)sensorTypeValid;
00395 }
00396 }
00397 else if (thisLabel == sensorPosString)
00398 {
00399
00400 sensorPosType sp;
00401 sp.position[0] = asDouble(line.substr(0,14));
00402 sp.position[1] = asDouble(line.substr(14,14));
00403 sp.position[2] = asDouble(line.substr(28,14));
00404 sp.height = asDouble(line.substr(42,14));
00405
00406 sp.obsType = convertObsType(line.substr(57,2));
00407
00408 sensorPosList.push_back(sp);
00409
00410
00411
00412 if (sp.obsType == PR)
00413 {
00414 valid |= sensorPosValid;
00415 }
00416 }
00417 else if (thisLabel == endOfHeader)
00418 {
00419 valid |= endValid;
00420 }
00421 else
00422 {
00423 FFStreamError e("Unknown header label " + thisLabel);
00424 GPSTK_THROW(e);
00425 }
00426 }
00427
00428 unsigned long allValid;
00429 if (version == 2.0) allValid = allValid20;
00430 else if (version == 2.1) allValid = allValid21;
00431 else
00432 {
00433 FFStreamError e("Unknown or unsupported RINEX version " +
00434 asString(version));
00435 GPSTK_THROW(e);
00436 }
00437
00438 if ( (allValid & valid) != allValid)
00439 {
00440 string errstr("Incomplete or invalid header: missing: ");
00441 errstr += bitString(allValid & ~valid);
00442 FFStreamError err(errstr);
00443 GPSTK_THROW(err);
00444 }
00445
00446
00447 strm.header = *this;
00448 strm.headerRead = true;
00449 }
00450
00451 void RinexMetHeader::dump(ostream& s) const
00452 {
00453 s << "Marker " << markerName << endl;
00454
00455 if (!obsTypeList.empty())
00456 {
00457 cout << "Obs types:" << endl;
00458 vector<RinexMetType>::const_iterator itr = obsTypeList.begin();
00459 while (itr != obsTypeList.end())
00460 {
00461 cout << convertObsType(*itr) << " ";
00462 itr++;
00463 }
00464 cout << endl;
00465 }
00466 }
00467
00468
00469 RinexMetHeader::RinexMetType
00470 RinexMetHeader::convertObsType(const string& oneObs)
00471 throw(FFStreamError)
00472 {
00473 if (oneObs == "PR") return PR;
00474 else if (oneObs == "TD") return TD;
00475 else if (oneObs == "HR") return HR;
00476 else if (oneObs == "ZW") return ZW;
00477 else if (oneObs == "ZD") return ZD;
00478 else if (oneObs == "ZT") return ZT;
00479 else if (oneObs == "WD") return WD;
00480 else if (oneObs == "WS") return WS;
00481 else if (oneObs == "RI") return RI;
00482 else if (oneObs == "HI") return HI;
00483 else
00484 {
00485 FFStreamError e("Bad obs type:" + oneObs);
00486 GPSTK_THROW(e);
00487 }
00488 }
00489
00490 string RinexMetHeader::convertObsType(const RinexMetHeader::RinexMetType& oneObs)
00491 throw(FFStreamError)
00492 {
00493 if (oneObs == PR) return "PR";
00494 else if (oneObs == TD) return "TD";
00495 else if (oneObs == HR) return "HR";
00496 else if (oneObs == ZW) return "ZW";
00497 else if (oneObs == ZD) return "ZD";
00498 else if (oneObs == ZT) return "ZT";
00499 else if (oneObs == WD) return "WD";
00500 else if (oneObs == WS) return "WS";
00501 else if (oneObs == RI) return "RI";
00502 else if (oneObs == HI) return "HI";
00503 else
00504 {
00505 FFStreamError e("Bad obs type:" + asString(oneObs));
00506 GPSTK_THROW(e);
00507 }
00508 }
00509
00510
00511 }