IonexHeader.cpp

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

Generated on Thu May 23 03:31:08 2013 for GPS ToolKit Software Library by  doxygen 1.3.9.1