WxObsMap.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: WxObsMap.cpp 1161 2008-03-27 17:16:22Z ckiesch $"
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "WxObsMap.hpp"
00045 
00046 using namespace std;
00047 using namespace gpstk;
00048 
00049 namespace gpstk
00050 {
00051 
00052    WxObservation WxObsData::getMostRecent( const DayTime& t ) const
00053       throw()
00054    {
00055       if(obs.size() == 0)
00056          return WxObservation();
00057      
00058       WxObsMap::const_iterator i = obs.upper_bound(t);
00059       if (i== obs.end())
00060          i--;
00061       if (i != obs.begin())
00062          i--;
00063       return  i->second;
00064    };
00065 
00066    void WxObsData::insertObservation( const WxObservation& wx )
00067       throw()
00068    {
00069       obs[wx.t] = wx;
00070       if (wx.t > lastTime)  lastTime=wx.t;
00071       if (wx.t < firstTime) firstTime=wx.t;
00072    }
00073 
00074    bool WxObservation::isAllValid() const
00075       throw()
00076    {
00077       return temperatureSource != noWx
00078          && pressureSource != noWx
00079          && humiditySource != noWx;
00080    };
00081 
00082    void WxObsData::flush(const DayTime& t) throw()
00083    {
00084       // remove data from the WxObsMap
00085       // map is sorted by time, stop removing data at
00086       // first point after t
00087       WxObsMap::iterator i = obs.begin();
00088       while (i != obs.end())
00089       {
00090          if (i->first < t)
00091          {
00092             obs.erase(i);
00093             i = obs.begin();
00094             firstTime = i->second.t;
00095          }
00096          else
00097             break;
00098       }
00099    }
00100 
00101    WxObservation WxObsData::getWxObservation(const DayTime& t,
00102                                              unsigned iv,
00103                                              bool interpolate) const
00104       throw(ObjectNotFound)
00105    {
00106       if (obs.empty())
00107       {
00108          ObjectNotFound e("No WxObservation available near time " +
00109                           t.printf("%02H:%02M:%02S on day %03j of %4Y"));
00110          GPSTK_THROW(e);
00111       }
00112 
00113       // get the first object after time t;
00114       WxObsMap::const_iterator after = obs.upper_bound(t);
00115       
00116       if (after == obs.begin())
00117       {
00118          const WxObservation& wxa = after->second;
00119          if ((wxa.t >= (t - iv)) && (wxa.t <= (t + iv)))
00120          {
00121             // only after point fits
00122             return wxa;
00123          }
00124          else
00125          {
00126             ObjectNotFound e("No WxObservation available near time " +
00127                              t.printf("%02H:%02M:%02S on day %03j of %4Y"));
00128             GPSTK_THROW(e);
00129          }
00130       }
00131       
00132 
00133       // get the first object at or before time t;
00134       WxObsMap::const_iterator before = after;
00135       before--;
00136 
00137       if (after == obs.end())
00138       {
00139          const WxObservation& wxb = before->second;
00140          if((wxb.t >= (t - iv)) && (wxb.t <= (t + iv)))
00141          {
00142             // only before point fits
00143             return wxb;
00144          }
00145          else
00146          {
00147             ObjectNotFound e("No WeatherData available near time " +
00148                              t.printf("%02H:%02M:%02S on day %03j of %4Y"));
00149             GPSTK_THROW(e);
00150          }
00151       }
00152       else
00153       {
00154          const WxObservation& wxa = after->second;
00155          const WxObservation& wxb = before->second;
00156 
00157          if (interpolate)
00158          {
00159             if((wxb.t >= (t - iv)) && (wxb.t <= (t + iv)))
00160             {
00161                if ((wxa.t >= (t - iv)) && (wxa.t <= (t + iv)))
00162                {
00163                   // both points fit, linearly interpolate and create
00164                   // a WeatherData object with those values
00165                   double dtw = wxa.t - wxb.t;
00166                   double dt = t - wxb.t;
00167 
00168                   double slope = (wxa.pressure - wxb.pressure) / dtw;
00169                   double pressure = slope * dt + wxb.pressure;
00170 
00171                   slope = (wxa.humidity - wxb.humidity) / dtw;
00172                   double humidity = slope * dt + wxb.humidity;
00173 
00174                   slope = (wxa.temperature - wxb.temperature) / dtw;
00175                   double temp = slope * dt + wxb.temperature;
00176 
00177                   WxObservation wx(t, temp, pressure, humidity);
00178                   return wx;
00179                }
00180                else
00181                {
00182                   // only before point fits
00183                   return wxb;
00184                }
00185             }
00186             else if ((wxa.t >= (t - iv)) && (wxa.t <= (t + iv)))
00187             {
00188                // only after point fits
00189                return wxa;
00190             }
00191             else
00192             {
00193                ObjectNotFound e("No WeatherData available near time " +
00194                                 t.printf("%02H:%02M:%02S on day %03j of %4Y"));
00195                GPSTK_THROW(e);
00196             }
00197          }
00198          else
00199          {
00200             if((wxb.t >= (t - iv)) && (wxb.t <= (t + iv)))
00201             {
00202                if ((wxa.t >= (t - iv)) && (wxa.t <= (t + iv)))
00203                {
00204                   // both points fit, return closer point, or
00205                   // before point if at same distance
00206                   double diffa = wxa.t - t;
00207                   double diffb = t - wxb.t;
00208                   return(diffa < diffb ? wxa : wxb);
00209                }
00210                else
00211                {
00212                   // only before point fits
00213                   return wxb;
00214                }
00215             }
00216             else if ((wxa.t >= (t - iv)) && (wxa.t <= (t + iv)))
00217             {
00218                // only after point fits
00219                return wxa;
00220             }
00221             else
00222             {
00223                ObjectNotFound e("No WeatherData available near time " +
00224                                 t.printf("%02H:%02M:%02S on day %03j of %4Y"));
00225                GPSTK_THROW(e);
00226             }
00227          }
00228       }
00229    }
00230 
00231    // These are just to facilitate debugging.
00232    std::ostream& operator<<(std::ostream& s, const gpstk::WxObservation& obs)
00233       throw()
00234    {
00235       // Note that this does not flag where the wx data came from
00236       s << obs.t << ", t=" << obs.temperature
00237         << ", p=" << obs.pressure
00238         << ", rh=" << obs.humidity;
00239       return s;
00240    }
00241 
00242 
00243 }  // namespace

Generated on Tue May 22 03:31:02 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1