RinexNavHeader.cpp

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

Generated on Sat May 25 03:31:12 2013 for GPS ToolKit Software Library by  doxygen 1.3.9.1