RinexNavHeader.cpp

Go to the documentation of this file.
00001 
00002 #pragma ident "$Id: RinexNavHeader.cpp 766 2007-09-20 18:32:38Z snelsen $"
00003 
00004 
00005 
00006 //============================================================================
00007 //
00008 //  This file is part of GPSTk, the GPS Toolkit.
00009 //
00010 //  The GPSTk is free software; you can redistribute it and/or modify
00011 //  it under the terms of the GNU Lesser General Public License as published
00012 //  by the Free Software Foundation; either version 2.1 of the License, or
00013 //  any later version.
00014 //
00015 //  The GPSTk is distributed in the hope that it will be useful,
00016 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 //  GNU Lesser General Public License for more details.
00019 //
00020 //  You should have received a copy of the GNU Lesser General Public
00021 //  License along with GPSTk; if not, write to the Free Software Foundation,
00022 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //  
00024 //  Copyright 2004, The University of Texas at Austin
00025 //
00026 //============================================================================
00027 
00028 //============================================================================
00029 //
00030 //This software developed by Applied Research Laboratories at the University of
00031 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00032 //Department of Defense. The U.S. Government retains all rights to use,
00033 //duplicate, distribute, disclose, or release this software. 
00034 //
00035 //Pursuant to DoD Directive 523024 
00036 //
00037 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00038 //                           release, distribution is unlimited.
00039 //
00040 //=============================================================================
00041 
00042 
00043 
00044 
00045 
00046 
00052 #include "StringUtils.hpp"
00053 #include "DayTime.hpp"
00054 #include "RinexNavHeader.hpp"
00055 #include "RinexNavStream.hpp"
00056 
00057 #include <iostream>
00058 
00059 using namespace gpstk::StringUtils;
00060 using namespace std;
00061 
00062 namespace gpstk
00063 {
00064    const string RinexNavHeader::endOfHeader = "END OF HEADER";
00065    const string RinexNavHeader::leapSecondsString = "LEAP SECONDS";
00066    const string RinexNavHeader::deltaUTCString = "DELTA-UTC: A0,A1,T,W";
00067    const string RinexNavHeader::ionBetaString = "ION BETA";
00068    const string RinexNavHeader::ionAlphaString = "ION ALPHA";
00069    const string RinexNavHeader::commentString = "COMMENT";
00070    const string RinexNavHeader::runByString = "PGM / RUN BY / DATE";
00071    const string RinexNavHeader::versionString = "RINEX VERSION / TYPE";
00072 
00073    void RinexNavHeader::reallyPutRecord(FFStream& ffs) const 
00074       throw(std::exception, FFStreamError, StringException)
00075    {
00076       RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
00077       
00078       strm.header = (*this);
00079       
00080       unsigned long allValid;
00081       if (version == 2.0)        allValid = allValid20;
00082       else if (version == 2.1)   allValid = allValid21;
00083       else if (version == 2.11)  allValid = allValid211;
00084       else
00085       {
00086          FFStreamError err("Unknown RINEX version: " + asString(version,3));
00087          err.addText("Make sure to set the version correctly.");
00088          GPSTK_THROW(err);
00089       }
00090       
00091       if ((valid & allValid) != allValid)
00092       {
00093          FFStreamError err("Incomplete or invalid header.");
00094          err.addText("Make sure you set all header valid bits for all of the available data.");
00095          GPSTK_THROW(err);
00096       }
00097       
00098       string line;
00099       
00100       if (valid & versionValid)
00101       {
00102          line  = rightJustify(asString(version,3), 10);
00103          line += string(10, ' ');
00104          line += string("NAVIGATION"); //leftJustify(fileType, 20);
00105          line += string(30, ' ');
00106          line += versionString;
00107          strm << line << endl;
00108          strm.lineNumber++;
00109       }
00110       if (valid & runByValid) 
00111       {
00112          line  = leftJustify(fileProgram,20);
00113          line += leftJustify(fileAgency,20);
00114          DayTime dt;
00115          dt.setLocalTime();
00116          string dat = dt.printf("%02m/%02d/%04Y %02H:%02M:%02S");
00117          line += leftJustify(dat, 20);
00118          line += runByString;
00119          strm << line << endl;
00120          strm.lineNumber++;
00121       }
00122       if (valid & commentValid)
00123       {
00124          vector<string>::const_iterator itr = commentList.begin();
00125          while (itr != commentList.end())
00126          {
00127             line  = leftJustify((*itr), 60);
00128             line += commentString;
00129             strm << line << endl;
00130             strm.lineNumber++;
00131             itr++;
00132          }
00133       }
00134       if (valid & ionAlphaValid)
00135       {
00136          line  = string(2, ' ');
00137          for (int i = 0; i < 4; i++)
00138          {
00139             line += rightJustify(doub2for(ionAlpha[i], 12, 2),12);  // should be 12.4
00140          }
00141          line += string(10, ' ');
00142          line += ionAlphaString;
00143          strm << line << endl;
00144          strm.lineNumber++;
00145       }
00146       if (valid & ionBetaValid)
00147       {
00148          line  = string(2, ' ');
00149          for (int i = 0; i < 4; i++)
00150          {
00151             line += rightJustify(doub2for(ionBeta[i], 12, 2),12);
00152          }
00153          line += string(10, ' ');
00154          line += ionBetaString;
00155          strm << line << endl;
00156          strm.lineNumber++;
00157       }
00158       if (valid & deltaUTCValid)
00159       {
00160          line  = string(3, ' ');
00161          //line += string(2, ' ');
00162          line += doub2for(A0, 19, 2);
00163          line += doub2for(A1, 19, 2);
00164          line += rightJustify(asString(UTCRefTime),9);
00165          line += rightJustify(asString(UTCRefWeek),9);               
00166          line += string(1, ' ');
00167          line += deltaUTCString;
00168          strm << line << endl;
00169          strm.lineNumber++;
00170       }
00171       if (valid & leapSecondsValid)
00172       {
00173          line  = rightJustify(asString(leapSeconds), 6);
00174          line += string(54, ' ');
00175          line += leapSecondsString;
00176          strm << line << endl;
00177          strm.lineNumber++;
00178       }
00179       if (valid & endValid)
00180       {
00181          line  = string(60,' ');
00182          line += endOfHeader;
00183          strm << line << endl;
00184          strm.lineNumber++;
00185       }
00186       
00187    }
00188 
00189    void RinexNavHeader::reallyGetRecord(FFStream& ffs) 
00190       throw(std::exception, FFStreamError, StringException)
00191    {
00192       RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
00193       
00194          // if already read, just return
00195       if (strm.headerRead == true)
00196          return;
00197       
00198       valid = 0;
00199       
00200          // clear out anything that was unsuccessfully read the first
00201       commentList.clear();
00202       
00203       while (! (valid & endValid))
00204       {
00205          string line;
00206          strm.formattedGetLine(line);
00207          StringUtils::stripTrailing(line);
00208 
00209          if (line.length()==0) continue;
00210          else if (line.length()<60 || line.length()>80)
00211          {
00212             FFStreamError e("Invalid line length");
00213             GPSTK_THROW(e);
00214          }
00215          
00216          string thisLabel(line, 60, 20);
00217          
00218          if (thisLabel == versionString)
00219          {
00220             version = asDouble(line.substr(0,20));
00221             fileType = strip(line.substr(20,20));
00222             if ( (fileType[0] != 'N') &&
00223                  (fileType[0] != 'n'))
00224             {
00225                FFStreamError e("This isn't a Rinex Nav file");
00226                GPSTK_THROW(e);
00227             }
00228             valid |= versionValid;
00229          }
00230          else if (thisLabel == runByString)
00231          {
00232             fileProgram = strip(line.substr(0,20));
00233             fileAgency = strip(line.substr(20,20));
00234             date = strip(line.substr(40,20));
00235             valid |= runByValid;
00236          }
00237          else if (thisLabel == commentString)
00238          {
00239             commentList.push_back(strip(line.substr(0,60)));
00240             valid |= commentValid;
00241          }
00242          else if (thisLabel == ionAlphaString)
00243          {
00244             for(int i = 0; i < 4; i++)
00245                ionAlpha[i] = gpstk::StringUtils::for2doub(line.substr(2 + 12 * i,12));
00246             valid |= ionAlphaValid;
00247          }
00248          else if (thisLabel == ionBetaString)
00249          {
00250             for(int i = 0; i < 4; i++)
00251                ionBeta[i] = gpstk::StringUtils::for2doub(line.substr(2 + 12 * i,12));
00252             valid |= ionBetaValid;
00253          }
00254          else if (thisLabel == deltaUTCString)
00255          {
00256             A0 = gpstk::StringUtils::for2doub(line.substr(3,19));
00257             A1 = gpstk::StringUtils::for2doub(line.substr(22,19));
00258             UTCRefTime = asInt(line.substr(41,9));
00259             UTCRefWeek = asInt(line.substr(50,9));
00260             valid |= deltaUTCValid;
00261          }
00262          else if (thisLabel == leapSecondsString)
00263          {
00264             leapSeconds = asInt(line.substr(0,6));
00265             valid |= leapSecondsValid;
00266          }
00267          else if (thisLabel == endOfHeader)
00268          {
00269             valid |= endValid;
00270          }
00271          else
00272          {
00273             throw(FFStreamError("Unknown header label at line " + 
00274                                 asString<size_t>(strm.lineNumber)));
00275          }
00276       }
00277       
00278       unsigned long allValid;
00279       if      (version == 2.0)      allValid = allValid20;
00280       else if (version == 2.1)      allValid = allValid21;
00281       else if (version == 2.11)     allValid = allValid211;
00282       else
00283       {
00284          FFStreamError e("Unknown or unsupported RINEX version " + 
00285                          asString(version));
00286          GPSTK_THROW(e);
00287       }
00288       
00289       if ( (allValid & valid) != allValid)
00290       {
00291          FFStreamError e("Incomplete or invalid header");
00292          GPSTK_THROW(e);               
00293       }            
00294       
00295          // we got here, so something must be right...
00296       strm.header = *this;
00297       strm.headerRead = true;      
00298    }
00299 
00300    void RinexNavHeader::dump(ostream& s) const
00301    {
00302       int i;
00303        s << "---------------------------------- REQUIRED ----------------------------------\n";
00304       s << "Rinex Version " << fixed << setw(5) << setprecision(2) << version
00305          << ",  File type " << fileType << ".\n";
00306       s << "Prgm: " << fileProgram << ",  Run: " << date << ",  By: " << fileAgency << endl;
00307 
00308       s << "(This header is ";
00309       if((valid & allValid211) == allValid211) s << "VALID 2.11";
00310       else if((valid & allValid21) == allValid21) s << "VALID 2.1";
00311       else if((valid & allValid20) == allValid20) s << "VALID 2.0";
00312       else s << "NOT VALID";
00313       s << " Rinex.)\n";
00314 
00315       if(!(valid & versionValid)) s << " Version is NOT valid\n";
00316       if(!(valid & runByValid)) s << " Run by is NOT valid\n";
00317       if(!(valid & endValid)) s << " End is NOT valid\n";
00318 
00319       s << "---------------------------------- OPTIONAL ----------------------------------\n";
00320       if(valid & ionAlphaValid) { s << "Ion alpha:";
00321          for(i=0; i<4; i++) s << " " << scientific << setprecision(4) << ionAlpha[i];
00322       s << endl; }
00323       else s << " Ion alpha is NOT valid\n";
00324       if(valid & ionBetaValid) { s << "Ion beta:";
00325          for(i=0; i<4; i++) s << " " << scientific << setprecision(4) << ionBeta[i];
00326       s << endl; }
00327       else s << " Ion beta is NOT valid\n";
00328       if(valid & deltaUTCValid) s << "Delta UTC: A0="
00329          << scientific << setprecision(12) << A0 << ", A1="
00330          << scientific << setprecision(12) << A1 << ", UTC ref = ("
00331          << UTCRefWeek << "," << UTCRefTime << ")\n";
00332       else s << " Delta UTC is NOT valid\n";
00333       if(valid & leapSecondsValid) s << "Leap seconds: " << leapSeconds << endl;
00334       else s << " Leap seconds is NOT valid\n";
00335       if(commentList.size() > 0) {
00336          s << "Comments (" << commentList.size() << ") :\n";
00337          for(int i=0; i<commentList.size(); i++)
00338             s << commentList[i] << endl;
00339       }
00340       s << "-------------------------------- END OF HEADER -------------------------------\n";
00341    }
00342 
00343 } // namespace

Generated on Wed Feb 8 03:31:02 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1