GPSZcount.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: GPSZcount.cpp 500 2007-04-27 12:02:53Z ocibu $"
00002 
00003 
00004 
00010 //============================================================================
00011 //
00012 //  This file is part of GPSTk, the GPS Toolkit.
00013 //
00014 //  The GPSTk is free software; you can redistribute it and/or modify
00015 //  it under the terms of the GNU Lesser General Public License as published
00016 //  by the Free Software Foundation; either version 2.1 of the License, or
00017 //  any later version.
00018 //
00019 //  The GPSTk is distributed in the hope that it will be useful,
00020 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 //  GNU Lesser General Public License for more details.
00023 //
00024 //  You should have received a copy of the GNU Lesser General Public
00025 //  License along with GPSTk; if not, write to the Free Software Foundation,
00026 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027 //  
00028 //  Copyright 2004, The University of Texas at Austin
00029 //
00030 //============================================================================
00031 
00032 #include <limits>
00033 
00034 #include "GPSZcount.hpp"
00035 #include "StringUtils.hpp"
00036 
00037 using namespace std;
00038 using gpstk::StringUtils::asString;
00039 
00040 namespace gpstk
00041 {
00042    const long GPSZcount::ZCOUNT_MINUTE = 40;
00043    const long GPSZcount::ZCOUNT_HOUR = 2400;
00044    const long GPSZcount::ZCOUNT_DAY = 57600;
00045    const long GPSZcount::ZCOUNT_WEEK = 403200;
00046    
00047    GPSZcount::GPSZcount(short inWeek, 
00048                         long inZcount) 
00049       throw(gpstk::InvalidParameter) 
00050    {
00051       try
00052       {
00053          setWeek(inWeek);
00054          setZcount(inZcount);
00055       }
00056       catch(gpstk::InvalidParameter& ip)
00057       {
00058          GPSTK_RETHROW(ip);
00059       }
00060    }
00061 
00062    GPSZcount::GPSZcount(long inFullZcount)
00063       throw(gpstk::InvalidParameter)
00064    {
00065       try
00066       {
00067          setFullZcount(inFullZcount);
00068       }
00069       catch(gpstk::InvalidParameter& ip)
00070       {
00071          GPSTK_RETHROW(ip);
00072       }
00073    }
00074 
00075    GPSZcount::GPSZcount(const GPSZcount& right)
00076       throw() 
00077    {
00078       operator=(right) ;
00079    }
00080    
00081    GPSZcount& GPSZcount::setWeek(short inWeek)
00082       throw(gpstk::InvalidParameter)
00083    {
00084       if( inWeek < 0 )
00085       {
00086          gpstk::InvalidParameter ip("GPS Week invalid: " +
00087                                     asString<short>(inWeek)) ;
00088          GPSTK_THROW(ip) ;
00089       }
00090       week = inWeek;
00091       return *this;
00092    }
00093    
00094    GPSZcount& GPSZcount::setZcount(long inZcount)
00095       throw(gpstk::InvalidParameter)
00096    {
00097       if(validZcount(inZcount) != 0)
00098       {
00099          gpstk::InvalidParameter ip("GPS Z-count invalid: " +
00100                                     asString<long>(inZcount)) ;
00101          GPSTK_THROW(ip) ;
00102       }
00103       zcount = inZcount ;
00104       return *this ;
00105    }
00106    
00107    GPSZcount& GPSZcount::setFullZcount(long inZcount)
00108          throw(gpstk::InvalidParameter) 
00109    {
00110       try
00111       {
00112          setZcount(inZcount & 0x7FFFFL) ;        // 19-bit mask
00113 
00114          // A 10-bit value will always be within constraints for a GPS week, so
00115          // there's no need to test it.
00116          setWeek((inZcount >> 19) & 0x3FFL) ;   // 10-bit mask
00117 
00118       }
00119       catch(gpstk::InvalidParameter& ip)
00120       {
00121          ip.addText("GPS Full Z-count invalid: " + asString<long>(inZcount)) ;
00122          GPSTK_RETHROW(ip) ;
00123       }
00124       return *this ;
00125    }
00126 
00127    GPSZcount& GPSZcount::addWeeks(short inWeeks)
00128       throw(gpstk::InvalidRequest) 
00129    {
00130       if (inWeeks == 0)
00131       {
00132          return *this ;
00133       }
00134 
00135       try
00136       {
00137          return setWeek(week + inWeeks) ;
00138       }
00139       catch(gpstk::InvalidParameter& ip)
00140       {
00141          gpstk::InvalidRequest ir(ip) ;
00142          ir.addText("Addition of " + asString(inWeeks) + 
00143                     " weeks renders this object invalid.") ;
00144          GPSTK_THROW(ir) ;
00145       }
00146    }
00147 
00148    GPSZcount& GPSZcount::addZcounts(long inZcounts)
00149       throw(gpstk::InvalidRequest) 
00150    {
00151       if (inZcounts == 0)
00152       {
00153          return *this ;
00154       }
00155 
00156       short originalWeek(week) ;
00157       long originalZcount(zcount) ;
00158 
00159       try
00160       {
00161             // First, do week modifications.
00162          addWeeks(inZcounts / ZCOUNT_WEEK) ; 
00163 
00164             // Now, take care of Z-counts.
00165          long tmp = zcount + (inZcounts % ZCOUNT_WEEK) ;
00166 
00167          if (tmp < 0)
00168          {
00169             addWeeks(-1);
00170             tmp += ZCOUNT_WEEK ;
00171          }
00172          else if (tmp >= ZCOUNT_WEEK)
00173          {
00174             addWeeks(1);
00175             tmp -= ZCOUNT_WEEK ;
00176          }
00177          
00178          setZcount(tmp) ;
00179          return *this ;
00180 
00181       }
00182       catch(gpstk::InvalidRequest& ir)
00183       {
00184          setWeek(originalWeek) ;
00185          setZcount(originalZcount) ; 
00186          ir.addText("Did not add " + asString(inZcounts) + " Z-counts.") ;
00187          GPSTK_RETHROW(ir) ;
00188          
00189       }
00190       catch(gpstk::InvalidParameter& ip)
00191       {
00192          setWeek(originalWeek) ;
00193          setZcount(originalZcount) ; 
00194          gpstk::InvalidRequest ir(ip) ;
00195          ir.addText("Did not add " + asString(inZcounts) + " Z-counts.") ;
00196          GPSTK_THROW(ir) ;         
00197       }
00198    }
00199    
00200    GPSZcount GPSZcount::operator++(int) 
00201       throw(gpstk::InvalidRequest)
00202    {
00203       GPSZcount temp = *this ;
00204       ++(*this) ;
00205       return temp ;
00206    }
00207 
00208    GPSZcount& GPSZcount::operator++() 
00209       throw(gpstk::InvalidRequest)
00210    {
00211       return addZcounts(1);
00212    }
00213 
00214    GPSZcount GPSZcount::operator--(int)
00215       throw(gpstk::InvalidRequest)
00216    {
00217       GPSZcount temp = *this ;
00218       --(*this) ;
00219       return temp ;
00220    }
00221 
00222    GPSZcount& GPSZcount::operator--()
00223       throw(gpstk::InvalidRequest)
00224    {
00225       return addZcounts(-1);
00226    }
00227    
00228    GPSZcount GPSZcount::operator+(long inZcounts) const
00229       throw(gpstk::InvalidRequest)
00230    {
00231       return GPSZcount(*this).addZcounts(inZcounts);
00232    }
00233    
00234    GPSZcount GPSZcount::operator-(long inZcounts) const
00235       throw(gpstk::InvalidRequest)
00236    {
00237       return operator+(-inZcounts);
00238    }
00239 
00240    double GPSZcount::operator-(const GPSZcount& right) const
00241       throw() 
00242    {
00243       return (double(week) - right.week) * ZCOUNT_WEEK 
00244          + (zcount - right.zcount) ;
00245    }
00246 
00247    long GPSZcount::operator%(const long right) const
00248       throw() 
00249    {
00250       return zcount % right;
00251    }
00252 
00253    GPSZcount& GPSZcount::operator+=(long inZcounts)
00254       throw(gpstk::InvalidRequest)
00255    {
00256       return addZcounts(inZcounts);
00257    }
00258 
00259    GPSZcount& GPSZcount::operator-=(long inZcounts)
00260       throw(gpstk::InvalidRequest)
00261    {
00262       return addZcounts(-inZcounts);
00263    }
00264 
00265    GPSZcount& GPSZcount::operator=(const GPSZcount& right)
00266       throw()
00267    {
00268       week = right.week;
00269       zcount = right.zcount;
00270       return *this;
00271    }
00272 
00273    bool GPSZcount::operator<(const GPSZcount& right) const
00274       throw()
00275    {
00276       if (week < right.week)
00277       {
00278          return true;
00279       }
00280       if (week == right.week && 
00281           zcount < right.zcount)
00282       {
00283          return true;
00284       }
00285       return false;
00286    }
00287    
00288    bool GPSZcount::operator>(const GPSZcount& right) const
00289       throw()
00290    {
00291       if (week > right.week)
00292       {
00293          return true;
00294       }
00295       if (week == right.week &&
00296           zcount > right.zcount)
00297       {
00298          return true;
00299       }
00300       return false;
00301    }
00302    
00303    bool GPSZcount::operator==(const GPSZcount& right) const
00304       throw()
00305    {
00306       if (week == right.week &&
00307           zcount == right.zcount)
00308       {
00309          return true;
00310       }
00311       return false;
00312    }
00313    
00314    bool GPSZcount::operator!=(const GPSZcount& right) const
00315       throw()
00316    {
00317       return (! operator==(right));
00318    }
00319 
00320    bool GPSZcount::operator<=(const GPSZcount& right) const
00321       throw()
00322    {
00323       return (! operator>(right));
00324    }
00325    
00326    bool GPSZcount::operator>=(const GPSZcount& right) const
00327       throw()
00328    {
00329       return (! operator<(right));
00330    }
00331 
00332    GPSZcount::operator std::string() const
00333       throw() 
00334    {
00335       return asString<short>(week) + "w" + asString<long>(zcount) + "z";
00336    }
00337 
00338    bool GPSZcount::inSameTimeBlock(const GPSZcount& other,
00339                                    unsigned long inZcountBlock,
00340                                    unsigned long inZcountOffset)
00341       throw()
00342    {
00343       if (inZcountBlock < ZCOUNT_WEEK)
00344       {
00345             // Make sure that we're in the same week, and then check to see if 
00346             // we're in the same time block
00347          if ( (getWeek() == other.getWeek()) &&
00348               (((getZcount() - inZcountOffset) / inZcountBlock) ==
00349                ((other.getZcount() - inZcountOffset) / inZcountBlock)) ) 
00350          {
00351             return true ;
00352          }
00353       }
00354       else // inZcountBlock >= ZCOUNT_WEEK
00355       {
00356             // Compare using the total number of Z-counts.
00357          if (long((getTotalZcounts() - inZcountOffset) / inZcountBlock) ==
00358              long((other.getTotalZcounts() - inZcountOffset) / inZcountBlock))
00359          {
00360             return true ;
00361          }
00362       }
00363       
00364       return false ;
00365    }
00366    
00367    void GPSZcount::dump(std::ostream& out,
00368                         short level) const
00369       throw()
00370    {
00371       switch(level)
00372       {
00373          case 0:
00374             out << week << "w" << zcount << "z" << flush;
00375             break;
00376          case 1:
00377          default:
00378             out << "GPS Full Week: " << setw(6) << week << endl
00379                 << "GPS Z-count:   " << setw(6) << zcount << endl;
00380             break;
00381       }               
00382    }
00383 
00384    long GPSZcount::validZcount(long z) 
00385       throw()
00386    {
00387       if (z < 0)
00388       {
00389          return z;
00390       }
00391       if (z >= GPSZcount::ZCOUNT_WEEK)
00392       {
00393          return (z - (GPSZcount::ZCOUNT_WEEK - 1));
00394       }
00395       return 0; // z is OK
00396    }
00397    
00398    std::ostream& operator<<(std::ostream& s, 
00399                             const gpstk::GPSZcount& z)
00400    {
00401       z.dump(s, 0) ;
00402       return s;
00403    }
00404 
00405 } // namespace gpstk

Generated on Thu Sep 9 03:30:53 2010 for GPS ToolKit Software Library by  doxygen 1.3.9.1