IonexHeader.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: IonexHeader.cpp 1398 2008-09-11 14:30:26Z coandrei $"
00002 
00008 //============================================================================
00009 //
00010 //  This file is part of GPSTk, the GPS Toolkit.
00011 //
00012 //  The GPSTk is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU Lesser General Public License as published
00014 //  by the Free Software Foundation; either version 2.1 of the License, or
00015 //  any later version.
00016 //
00017 //  The GPSTk is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU Lesser General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU Lesser General Public
00023 //  License along with GPSTk; if not, write to the Free Software Foundation,
00024 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 //
00026 //  Octavian Andrei - FGI ( http://www.fgi.fi ). 2008
00027 //
00028 //============================================================================
00029 
00030 
00031 #include <cctype>
00032 
00033 #include "StringUtils.hpp"
00034 #include "MathBase.hpp"
00035 #include "IonexHeader.hpp"
00036 #include "IonexStream.hpp"
00037 
00038 using namespace std;
00039 using namespace gpstk::StringUtils;
00040 
00041 namespace gpstk
00042 {
00043    const string IonexHeader::versionString         =  "IONEX VERSION / TYPE";
00044    const string IonexHeader::runByString           =  "PGM / RUN BY / DATE";
00045    const string IonexHeader::descriptionString     =  "DESCRIPTION";
00046    const string IonexHeader::commentString         =  "COMMENT";
00047    const string IonexHeader::firstTimeString       =  "EPOCH OF FIRST MAP";
00048    const string IonexHeader::lastTimeString        =  "EPOCH OF LAST MAP";
00049    const string IonexHeader::intervalString        =  "INTERVAL";
00050    const string IonexHeader::numMapsString         =  "# OF MAPS IN FILE";
00051    const string IonexHeader::mappingFunctionString =  "MAPPING FUNCTION";
00052    const string IonexHeader::elevationString       =  "ELEVATION CUTOFF";
00053    const string IonexHeader::observablesUsedString =  "OBSERVABLES USED";
00054    const string IonexHeader::numStationsString     =  "# OF STATIONS";
00055    const string IonexHeader::numSatsString         =  "# OF SATELLITES";
00056    const string IonexHeader::baseRadiusString      =  "BASE RADIUS";
00057    const string IonexHeader::mapDimensionString    =  "MAP DIMENSION";
00058    const string IonexHeader::hgtGridString         =  "HGT1 / HGT2 / DHGT";
00059    const string IonexHeader::latGridString         =  "LAT1 / LAT2 / DLAT";
00060    const string IonexHeader::lonGridString         =  "LON1 / LON2 / DLON";
00061    const string IonexHeader::exponentString        =  "EXPONENT";
00062    const string IonexHeader::startAuxDataString    =  "START OF AUX DATA";
00063    const string IonexHeader::endAuxDataString      =  "END OF AUX DATA";
00064    const string IonexHeader::endOfHeader           =  "END OF HEADER";
00065 
00066    const string IonexHeader::DCB::svsAuxDataString       =  "PRN / BIAS / RMS";
00067    const string IonexHeader::DCB::stationsAuxDataString  =
00068                                                          "STATION / BIAS / RMS";
00069 
00070 
00071       // Clear (empty out) header
00072    void IonexHeader::clear(void)
00073    {
00074 
00075       version = 1.0;
00076       descriptionList.clear();
00077       commentList.clear();
00078       interval = 0;
00079       numMaps = numStations = numSVs = mapDims = 0;
00080       elevation = baseRadius = 0;
00081 
00082       hgt[0] = hgt[1] = hgt[2] = 0.0;
00083       lat[0] = lat[1] = lat[2] = 0.0;
00084       lon[0] = lon[1] = lon[2] = 0.0;
00085 
00086       exponent = -1;    // that's the default value
00087       svsmap.clear();
00088       valid = auxDataFlag = false;
00089 
00090       return;
00091 
00092    }  // End of method 'IonexHeader::clear()'
00093 
00094 
00095 
00096       /* Simple debug output function.
00097        *
00098        * It simply outputs the version, name and number of maps contained
00099        * in this Ionex header.
00100        */
00101    void IonexHeader::dump(std::ostream& os) const
00102    {
00103 
00104       os << "-------------------------------- IONEX HEADER"
00105          << "--------------------------------" << endl;
00106 
00107       os << "First epoch            : " << firstEpoch << endl;
00108       os << "Last epoch             : " << lastEpoch << endl; 
00109       os << "Interval               : " << interval << endl;
00110       os << "Number of ionex maps   : " << numMaps << endl;
00111       os << "Mapping function       : " << mappingFunction << endl;
00112       os << "Elevation cut off      : " << elevation << endl;
00113       os << "Number of stations     : " << numStations << endl;
00114       os << "Number of satellites   : " << numSVs << endl;
00115       os << "Map dimensions         : " << mapDims << endl;
00116 
00117       os << "HGT1 / HGT2 / DHGT     : " << hgt[0] << " / "
00118                                         << hgt[1] << " / "
00119                                         << hgt[2] << endl;
00120       os << "LAT1 / LAT2 / DLAT     : " << lat[0] << " / "
00121                                         << lat[1] << " / "
00122                                         << lat[2] << endl;
00123       os << "LON1 / LON2 / DLON     : " << lon[0] << " / "
00124                                         << lon[1] << " / "
00125                                         << lon[2] << endl;
00126       os << "Valid object?          : " << valid  << endl;
00127 
00128       os << "-------------------------------- END OF HEADER"
00129          << "-------------------------------" << endl;
00130 
00131       os << endl;
00132 
00133    }  //End of method 'IonexHeader::dump()'
00134 
00135 
00136 
00137       /*
00138        * Parse a single auxiliary header record that contains "Differential
00139        * code biases".
00140        */
00141    void IonexHeader::ParseDcbRecord(std::string &line)
00142       throw (FFStreamError)
00143    {
00144 
00145       string label(line, 60, 20);
00146 
00147       if (label == DCB::svsAuxDataString)
00148       {
00149             // prepare the DCB structure
00150          char c = isspace(line[3]) ? 'G' : line[3];
00151          int prn     = asInt(line.substr(4,2));
00152          double bias = asDouble(line.substr(6,16));// * 1e-9; // change to seconds
00153          double rms  = asDouble(line.substr(16,26));
00154 
00155             // prepare SatID object that is the key of the map
00156          SatID::SatelliteSystem system;
00157          switch(line[3])
00158          {
00159 
00160             case ' ': case 'G': case 'g':
00161                system = SatID::systemGPS;
00162                break;
00163 
00164             case 'R': case 'r':
00165                system = SatID::systemGlonass;
00166                break;
00167 
00168             default:                   // non-IONEX system character
00169                FFStreamError e(std::string("Invalid system character \"")
00170                                + c + std::string("\""));
00171                GPSTK_THROW(e);
00172 
00173          }  // End of 'switch(line[3])'
00174 
00175          SatID svid = SatID(prn,system);
00176 
00177             // add to map
00178          svsmap[svid] = DCB(c,prn,bias,rms);
00179 
00180       }  // End of 'if (label == DCB::svsAuxDataString)'...
00181       else if (label == DCB::stationsAuxDataString)
00182       {
00183 
00184          // WARNING: at this stage the DCB values for the contributing
00185          // stations are not mapped.
00186 
00187       }
00188       else if (label == commentString)
00189       {
00190 
00191             // CODE's product has a comment line before aux data end
00192          string s = strip(line.substr(0,60));
00193          commentList.push_back(s);
00194 
00195       }
00196       else if (label == endAuxDataString)
00197       {
00198 
00199          auxDataFlag = false;          // End of aux data
00200 
00201       }
00202       else
00203       {
00204 
00205          FFStreamError e(std::string( "Unidentified IONEX::DCB label: "
00206                                       + label) );
00207 
00208          GPSTK_THROW(e);
00209 
00210       }  // End of 'if (label == endAuxDataString)'...
00211 
00212       return;
00213 
00214    }  // End of method 'IonexHeader::ParseDcbRecord()'
00215 
00216 
00217 
00218       /* Parse a single header record, and modify 'valid' accordingly.
00219        *
00220        * Used by reallyGetRecord for both IonexHeader and IonexData.
00221        */
00222    void IonexHeader::ParseHeaderRecord(std::string &line)
00223       throw (FFStreamError)
00224    {
00225 
00226       string label(line, 60, 20);
00227 
00228       if (label == versionString)
00229       {
00230 
00231          version  = asDouble(line.substr(0,20));
00232          fileType = strip(line.substr(20,20));
00233          system   = strip(line.substr(40,20));
00234 
00235       }
00236       else if (label == runByString)
00237       {
00238 
00239          fileProgram = strip(line.substr( 0,20));
00240          fileAgency  = strip(line.substr(20,20));
00241          date        = strip(line.substr(40,20));
00242 
00243       }
00244       else if (label == descriptionString)
00245       {
00246 
00247          string s = line.substr(0,60);
00248          descriptionList.push_back(s);
00249 
00250       }
00251       else if (label == commentString)
00252       {
00253 
00254          string s = line.substr(0,60);
00255          commentList.push_back(s);
00256 
00257       }
00258       else if (label == firstTimeString)
00259       {
00260 
00261          firstEpoch = parseTime(line);
00262 
00263       }
00264       else if (label == lastTimeString)
00265       {
00266 
00267          lastEpoch = parseTime(line);
00268 
00269       }
00270       else if (label == intervalString)
00271       {
00272 
00273          interval = asInt(line.substr(0,6));
00274 
00275       }
00276       else if (label == numMapsString)
00277       {
00278 
00279          numMaps = asInt(line.substr(0,6));
00280 
00281       }
00282       else if (label == mappingFunctionString)
00283       {
00284 
00285          mappingFunction = strip(line.substr(0, 6));
00286 
00287       }
00288       else if (label == elevationString)
00289       {
00290 
00291          elevation = asDouble(line.substr(0, 8));
00292 
00293       }
00294       else if (label == observablesUsedString)
00295       {
00296 
00297          observablesUsed = strip(line.substr(0,60));
00298 
00299       }
00300       else if (label == numStationsString)
00301       {
00302 
00303          numStations = asInt(line.substr(0,6));
00304 
00305       }
00306       else if (label == numSatsString)
00307       {
00308 
00309          numSVs = asInt(line.substr(0,6));
00310 
00311       }
00312       else if (label == baseRadiusString)
00313       {
00314 
00315          baseRadius = asDouble(line.substr(0, 8));
00316 
00317       }
00318       else if (label == mapDimensionString)
00319       {
00320 
00321          mapDims = asInt(line.substr(0,6));
00322 
00323       }
00324       else if (label == hgtGridString)
00325       {
00326 
00327          hgt[0] = asDouble(line.substr( 2, 6));
00328          hgt[1] = asDouble(line.substr( 8, 6));
00329          hgt[2] = asDouble(line.substr(14, 6));
00330 
00331       }
00332       else if (label == latGridString)
00333       {
00334 
00335          lat[0] = asDouble(line.substr( 2, 6));
00336          lat[1] = asDouble(line.substr( 8, 6));
00337          lat[2] = asDouble(line.substr(14, 6));
00338 
00339       }
00340       else if (label == lonGridString)
00341       {
00342 
00343          lon[0] = asDouble(line.substr( 2, 6));
00344          lon[1] = asDouble(line.substr( 8, 6));
00345          lon[2] = asDouble(line.substr(14, 6));
00346 
00347       }
00348       else if (label == exponentString)
00349       {
00350 
00351          exponent = asInt(line.substr(0,6));
00352 
00353       }
00354       else if (label == startAuxDataString)
00355       {
00356 
00357          auxData = strip(line.substr(0,60));
00358          auxDataFlag = true;
00359 
00360       }
00361       else if (label == endOfHeader)
00362       {
00363 
00364          auxDataFlag = true;
00365          valid = true;
00366 
00367       }
00368       else
00369       {
00370 
00371          FFStreamError e("Unidentified IONEX header record: " + label);
00372 
00373          GPSTK_THROW(e);
00374 
00375       }
00376 
00377       return;
00378 
00379    }  // End of method 'IonexHeader::ParseHeaderRecord()'
00380 
00381 
00382 
00383       // This function parses the entire header from the given stream
00384    void IonexHeader::reallyGetRecord(FFStream& ffs)
00385       throw(exception, FFStreamError, StringException)
00386    {
00387 
00388       IonexStream& strm = dynamic_cast<IonexStream&> (ffs);
00389 
00390          // if already read, just return
00391       if (strm.headerRead == true)
00392       {
00393          return;
00394       }
00395 
00396          // since we read a new header, we need to reinitialize
00397          // all our list structures. All the other objects should be ok.
00398          // This also applies if we threw an exception the first time we read
00399          // the header and are now re-reading it. Some of these data
00400          // structures could be full and we need to empty them.
00401       clear();
00402 
00403       string line;
00404 
00405       while (!valid)
00406       {
00407 
00408          strm.formattedGetLine(line);
00409          StringUtils::stripTrailing(line);
00410 
00411             // skip empty lines
00412          if (line.length() == 0)
00413          {
00414             continue;
00415          }
00416          else
00417          {
00418 
00419             if (line.length() < 60 || line.length() > 80)
00420             {
00421 
00422                FFStreamError e("Invalid line length");
00423                GPSTK_THROW(e);
00424 
00425             }
00426 
00427          }  // End of 'if (line.length() == 0)...'
00428 
00429 
00430          if (auxDataFlag)     // when it is set true, then parse auxiliar data
00431          {
00432 
00433             try
00434             {
00435                ParseDcbRecord(line);
00436             }
00437             catch (FFStreamError& e)
00438             {
00439                GPSTK_RETHROW(e);
00440             }
00441 
00442          }
00443          else
00444          {
00445 
00446             try
00447             {
00448                ParseHeaderRecord(line);
00449             }
00450             catch (FFStreamError& e)
00451             {
00452                GPSTK_RETHROW(e);
00453             }
00454 
00455          }  // End of 'if (auxDataFlag)...'
00456 
00457       }  // End of 'while (!valid)...' (not for the header)
00458 
00459 
00460          // Here come some validity checkings
00461          // Checking ionex version
00462       if (version != 1.0)
00463       {
00464          FFStreamError e( "Invalid IONEX version number " +
00465                           asString(version));
00466          GPSTK_THROW(e);
00467       }
00468 
00469          // time arguments consistency
00470       double interval0( (lastEpoch - firstEpoch) / (numMaps -1.0) );
00471       if (interval != static_cast<int>(interval0))
00472       {
00473          FFStreamError e("Inconsistent time arguments.");
00474          GPSTK_THROW(e);
00475       }
00476 
00477          // map dimension consistency
00478       if (mapDims == 2)
00479       {
00480 
00481          if ( (hgt[0] != hgt[1]) || (hgt[2] != 0.0) )
00482          {
00483             FFStreamError e("Error concerning map dimension.");
00484             GPSTK_THROW(e);
00485          }
00486 
00487       }
00488       else
00489       {
00490 
00491          if ( (hgt[0] == hgt[1]) || (hgt[2] == 0.0) )
00492          {
00493             FFStreamError e("Error concerning map dimension.");
00494             GPSTK_THROW(e);
00495          }
00496 
00497       }  // End of 'if (mapDims == 2)...'
00498 
00499          // grid checkings
00500       double grdfac[4];
00501       try
00502       {
00503          grdfac[0] = lat[0]/lat[2];
00504          grdfac[1] = lat[1]/lat[2];
00505          grdfac[2] = lon[0]/lon[2];
00506          grdfac[3] = lon[1]/lon[2];
00507       }
00508       catch(exception& e)
00509       {
00510          cerr << "Problems computing grdfac: " << e.what() << endl;
00511          throw;
00512       }
00513 
00514       for (int i = 0; i < 4; i++)
00515       {
00516          double xdif1( grdfac[i] - static_cast<int>(grdfac[i]) );
00517          double xdif( ABS(grdfac[i] - static_cast<int>(grdfac[i])) );
00518 
00519          if (xdif > 1e-4)
00520          {
00521             FFStreamError e("Irregular Ionex data grid.");
00522             GPSTK_THROW(e);
00523          }
00524 
00525       }  // End of 'for (int i = 0; i < 4; i++)...'
00526 
00527          // reach end of header line
00528       strm.header = *this;
00529       strm.headerRead = true;
00530 
00531       return;
00532 
00533    }  // End of method 'IonexHeader::reallyGetRecord()'
00534 
00535 
00536 
00537    void IonexHeader::reallyPutRecord(FFStream& ffs) const
00538       throw(exception, FFStreamError, StringException)
00539    {
00540 
00541       IonexStream& strm = dynamic_cast<IonexStream&>(ffs);
00542 
00543       if (version != 1.0)
00544       {
00545          FFStreamError err( "Unknown IONEX version: " + asString(version,2) );
00546          err.addText("Make sure to set the version correctly.");
00547          GPSTK_THROW(err);
00548       }
00549 
00550       try
00551       {
00552          WriteHeaderRecords(strm);
00553       }
00554       catch(FFStreamError& e)
00555       {
00556          GPSTK_RETHROW(e);
00557       }
00558       catch(StringException& e)
00559       {
00560          GPSTK_RETHROW(e);
00561       }
00562 
00563    }  // End of method 'IonexHeader::reallyPutRecord()'
00564 
00565 
00566       // this function writes all valid header records
00567    void IonexHeader::WriteHeaderRecords(FFStream& ffs) const
00568       throw(FFStreamError, StringException)
00569    {
00570       IonexStream& strm = dynamic_cast<IonexStream&>(ffs);
00571       string line;
00572 
00573       if (valid)
00574       {
00575 
00576             // write first IONEX record
00577          line.clear();
00578          line  = rightJustify(asString(version,1), 8);
00579          line += string(12, ' ');
00580          if ((fileType[0] != 'I') && (fileType[0] != 'i'))
00581          {
00582             FFStreamError err("This isn't a Ionex file: " + 
00583                               fileType.substr(0,1));
00584             GPSTK_THROW(err);
00585          }
00586 
00587          line += leftJustify(fileType, 20);
00588          line += leftJustify(system, 20);
00589          line += leftJustify(versionString,20);
00590          strm << line << endl;
00591          strm.lineNumber++;
00592 
00593 
00594             // write second IONEX record
00595          line.clear();
00596          line += leftJustify(fileProgram,20);
00597          line += leftJustify(fileAgency,20);
00598          line += leftJustify(date,20);
00599          line += leftJustify(runByString,20);
00600          strm << line << endl;
00601          strm.lineNumber++;
00602 
00603 
00604             // write title (optional)
00605          if( commentList.size() > 0 )
00606          {
00607             line.clear();
00608             line += leftJustify(commentList[0],60);
00609             line += leftJustify(commentString,20);
00610             strm << line << endl;
00611             strm.lineNumber++;
00612          }
00613 
00614 
00615             // write multi-line description (optional)
00616          if (descriptionList.size() > 0)
00617          {
00618 
00619             vector<std::string>::size_type i = 0;
00620 
00621             for( ; i < descriptionList.size(); i++)
00622             {
00623 
00624                line.clear();
00625                line += leftJustify(descriptionList[i],60);
00626                line += leftJustify(descriptionString,20);
00627                strm << line << endl;
00628                strm.lineNumber++;
00629 
00630             }
00631 
00632          }  // End of 'if (descriptionList.size() > 0) ...'
00633 
00634 
00635             // write epoch of first epoch
00636          line.clear();
00637          line += writeTime(firstEpoch);
00638          line += string(24, ' ');
00639          line += leftJustify(firstTimeString,20);
00640          strm << line << endl;
00641          strm.lineNumber++;
00642 
00643 
00644             // write epoch of last epoch
00645          line.clear();
00646          line += writeTime(lastEpoch);
00647          line += string(24, ' ');
00648          line += leftJustify(lastTimeString,20);
00649          strm << line << endl;
00650          strm.lineNumber++;
00651 
00652 
00653             // write interval
00654          line.clear();
00655          line += rightJustify( asString(interval), 6 );
00656          line += string(54, ' ');
00657          line += leftJustify(intervalString,20);
00658          strm << line << endl;
00659          strm.lineNumber++;
00660 
00661 
00662             // write # of maps
00663          line.clear();
00664          line += rightJustify( asString<short>(numMaps), 6 );
00665          line += string(54, ' ');
00666          line += leftJustify(numMapsString,20);
00667          strm << line << endl;
00668          strm.lineNumber++;
00669 
00670 
00671             // write mapping function
00672          line.clear();
00673          line += string(2, ' ');
00674          line += rightJustify(mappingFunction, 4);
00675          line += string(54, ' ');
00676          line += leftJustify(mappingFunctionString,20);
00677          strm << line << endl;
00678          strm.lineNumber++;
00679 
00680 
00681             // write elevation cutoff
00682          line.clear();
00683          line += rightJustify( asString(elevation,1), 8 );
00684          line += string(52, ' ');
00685          line += leftJustify(elevationString,20);
00686          strm << line << endl;
00687          strm.lineNumber++;
00688 
00689 
00690             // write observables used
00691          line.clear();
00692          line += leftJustify(observablesUsed,60);
00693          line += leftJustify(observablesUsedString,20);
00694          strm << line << endl;
00695          strm.lineNumber++;
00696 
00697 
00698             // write # of stations (optional)
00699          if (numStations > 0)
00700          {
00701             line.clear();
00702             line += rightJustify( asString<short>(numStations), 6 );
00703             line += string(54, ' ');
00704             line += leftJustify(numStationsString,20);
00705             strm << line << endl;
00706             strm.lineNumber++;
00707          }
00708 
00709 
00710             // write # of satellites (optional)
00711          if (numSVs > 0)
00712          {
00713             line.clear();
00714             line += rightJustify( asString<short>(numSVs), 6 );
00715             line += string(54, ' ');
00716             line += leftJustify(numSatsString,20);
00717             strm << line << endl;
00718             strm.lineNumber++;
00719          }
00720 
00721 
00722             // write base radius
00723          line.clear();
00724          line += rightJustify( asString(baseRadius,1), 8 );
00725          line += string(52, ' ');
00726          line += leftJustify(baseRadiusString,20);
00727          strm << line << endl;
00728          strm.lineNumber++;
00729 
00730 
00731             // write map dimension
00732          line.clear();
00733          line += rightJustify( asString(mapDims), 6 );
00734          line += string(54, ' ');
00735          line += leftJustify(mapDimensionString,20);
00736          strm << line << endl;
00737          strm.lineNumber++;
00738 
00739 
00740             // write grid specifications
00741          line.clear();
00742          line += string(2, ' ');
00743          line += rightJustify( asString(hgt[0],1), 6 );
00744          line += rightJustify( asString(hgt[1],1), 6 );
00745          line += rightJustify( asString(hgt[2],1), 6 );
00746          line += string(40, ' ');
00747          line += leftJustify(hgtGridString,20);
00748          strm << line << endl;
00749          strm.lineNumber++;
00750 
00751          line.clear();
00752          line += string(2, ' ');
00753          line += rightJustify( asString(lat[0],1), 6 );
00754          line += rightJustify( asString(lat[1],1), 6 );
00755          line += rightJustify( asString(lat[2],1), 6 );
00756          line += string(40, ' ');
00757          line += leftJustify(latGridString,20);
00758          strm << line << endl;
00759          strm.lineNumber++;
00760 
00761          line.clear();
00762          line += string(2, ' ');
00763          line += rightJustify( asString(lon[0],1), 6 );
00764          line += rightJustify( asString(lon[1],1), 6 );
00765          line += rightJustify( asString(lon[2],1), 6 );
00766          line += string(40, ' ');
00767          line += leftJustify(lonGridString,20);
00768          strm << line << endl;
00769          strm.lineNumber++;
00770 
00771 
00772             // write default exponent (optional)
00773          line.clear();
00774          line += rightJustify( asString(exponent), 6 );
00775          line += string(54, ' ');
00776          line += leftJustify(exponentString,20);
00777          strm << line << endl;
00778          strm.lineNumber++;
00779 
00780 
00781             // write multi-line comment
00782          for( vector<std::string>::size_type i = 1; 
00783               i < commentList.size(); i++)
00784          {
00785             line.clear();
00786             line += leftJustify(commentList[i],60);
00787             line += leftJustify(commentString,20);
00788             strm << line << endl;
00789             strm.lineNumber++;
00790          }
00791 
00792 
00793             // write auxiliary data (optional)
00794          if (auxDataFlag)
00795          {
00796 
00797                // start of aux data
00798             line.clear();
00799             line += leftJustify(auxData,60);
00800             line += leftJustify(startAuxDataString,20);
00801             strm << line << endl;
00802             strm.lineNumber++;
00803 
00804             IonexHeader::SatDCBMap::const_iterator isv = svsmap.begin();
00805 
00806             for(; isv != svsmap.end(); isv++)
00807             {
00808                line.clear();
00809                line += isv->second.toString();
00810                line += string(34, ' ');
00811                line += leftJustify(DCB::svsAuxDataString,20);
00812                strm << line << endl;
00813                strm.lineNumber++;
00814             }
00815 
00816                // end of aux data
00817             line.clear();
00818             line += leftJustify(auxData,60);
00819             line += leftJustify(endAuxDataString,20);
00820             strm << line << endl;
00821             strm.lineNumber++;
00822 
00823          }  // End of 'if (auxDataFlag)...'
00824 
00825 
00826             // write record closing Ionex header
00827          line.clear();
00828          line += string(60, ' ');
00829          line += leftJustify(endOfHeader,20);
00830          strm << line << endl;
00831          strm.lineNumber++;
00832 
00833       }  // End of 'if (valid)...'
00834    }
00835 
00836 
00837       /* This function sets the time for this header.
00838        *
00839        * It looks at \a line to obtain the needed information.
00840        */
00841    DayTime IonexHeader::parseTime(const string& line) const
00842    {
00843 
00844       int year, month, day, hour, min, sec;
00845 
00846       year  = asInt(line.substr( 0,6));
00847       month = asInt(line.substr( 6,6));
00848       day   = asInt(line.substr(12,6));
00849       hour  = asInt(line.substr(18,6));
00850       min   = asInt(line.substr(24,6));
00851       sec   = asInt(line.substr(30,6));
00852 
00853       return DayTime(year, month, day, hour, min, (double)sec);
00854 
00855    }  // End of method 'IonexHeader::parseTime()'
00856 
00857 
00861    string IonexHeader::writeTime(const DayTime& dt) const
00862    {
00863 
00864       string line;
00865 
00866       line  = rightJustify(asString<short>(dt.year()), 6);
00867       line += rightJustify(asString<short>(dt.month()), 6);
00868       line += rightJustify(asString<short>(dt.day()), 6);
00869       line += rightJustify(asString<short>(dt.hour()), 6);
00870       line += rightJustify(asString<short>(dt.minute()), 6);
00871       line += rightJustify(asString (static_cast<int>(dt.second())), 6);
00872 
00873       return line;
00874 
00875    }  // End of method 'IonexHeader::writeTime()'
00876 
00877 
00878 
00879 }  // End of namespace gpstk

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