1 //============================================================================== 2 // 3 // This file is part of GPSTk, the GPS Toolkit. 4 // 5 // The GPSTk is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published 7 // by the Free Software Foundation; either version 3.0 of the License, or 8 // any later version. 9 // 10 // The GPSTk is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with GPSTk; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 18 // 19 // This software was developed by Applied Research Laboratories at the 20 // University of Texas at Austin. 21 // Copyright 2004-2020, The Board of Regents of The University of Texas System 22 // 23 //============================================================================== 24 25 //============================================================================== 26 // 27 // This software was developed by Applied Research Laboratories at the 28 // University of Texas at Austin, under contract to an agency or agencies 29 // within the U.S. Department of Defense. The U.S. Government retains all 30 // rights to use, duplicate, distribute, disclose, or release this software. 31 // 32 // Pursuant to DoD Directive 523024 33 // 34 // DISTRIBUTION STATEMENT A: This software has been approved for public 35 // release, distribution is unlimited. 36 // 37 //============================================================================== 38 39 /** 40 * @file IonexData.hpp 41 * Encapsulate IONEX file data, including I/O 42 */ 43 44 #ifndef GPSTK_IONEXDATA_HPP 45 #define GPSTK_IONEXDATA_HPP 46 47 #include <map> 48 49 #include "FFStream.hpp" 50 #include "Position.hpp" 51 #include "Vector.hpp" 52 #include "WGS84Ellipsoid.hpp" 53 54 #include "IonexStream.hpp" 55 56 57 58 namespace gpstk 59 { 60 61 /// @ingroup IonosphereMaps 62 //@{ 63 64 /** This class models a IONEX Data Record. 65 * 66 * @sa gpstk::IonexStream and gpstk::IonexHeader 67 * @sa main ionex test.cpp for example 68 */ 69 class IonexData : public IonexBase 70 { 71 public: 72 73 74 /** 75 * @name IonexDataFormatStrings 76 * IONEX Data Formatting Strings 77 */ 78 //@{ 79 static const std::string startTecMapString; ///<"START OF TEC MAP" 80 static const std::string startRmsMapString; ///<"START OF RMS MAP" 81 static const std::string startHgtMapString; ///<"START OF HEIGHT MAP" 82 static const std::string currentEpochString; ///<"EPOCH OF CURRENT MAP" 83 static const std::string dataBlockString; ///<"LAT/LON1/LON2/DLON/H" 84 static const std::string endTecMapString; ///<"END OF TEC MAP" 85 static const std::string endRmsMapString; ///<"END OF RMS MAP" 86 static const std::string endHgtMapString; ///<"END OF HEIGHT MAP" 87 static const std::string endOfFile; ///<"END OF FILE" 88 //@} 89 90 91 /// A structure used to store IONEX Value Types 92 struct IonexValType 93 { 94 95 std::string type; ///< type e.g. TEC, RMS 96 std::string description; ///< Description (optional) 97 std::string units; ///< units (optional). E.g. "meters" 98 IonexValTypegpstk::IonexData::IonexValType99 IonexValType() 100 : type( std::string("UN") ), 101 description( std::string("Unknown or Invalid") ), 102 units( std::string("") ) 103 {}; 104 IonexValTypegpstk::IonexData::IonexValType105 IonexValType(std::string t, std::string d, std::string u) 106 : type(t), description(d), units(u) {}; 107 108 }; // End of struct 'IonexValType' 109 110 111 /** 112 * @name Standard IONEX value types 113 */ 114 //@{ 115 static const IonexValType UN; 116 static const IonexValType TEC; 117 static const IonexValType RMS; 118 //@} 119 120 121 /** 122 * @name IonexDataValues 123 */ 124 //@{ 125 int mapID; ///< denote the internal number of the current map 126 int dim[3]; ///< How many values are along latitude, longitude, height 127 CommonTime time; ///< the time corresponding to the current data records 128 129 IonexValType type; ///< Type of data either TEC or RMS 130 Vector<double> data; ///< TEC or RMS data 131 132 // The following fields are similar to the ones in 'IonexHeader' 133 int exponent; ///< Exponent defining the unit of the values 134 135 double lat[3]; ///< Definition of a grid in latitude 136 double lon[3]; ///< Definition of a grid in longitude 137 double hgt[3]; ///< Definition of a grid in height 138 139 bool valid; ///< Validity flag 140 //@} 141 142 143 /// Default constructor. IonexData()144 IonexData() 145 : time(CommonTime::BEGINNING_OF_TIME), valid(false) {}; 146 147 148 /// Destructor ~IonexData()149 virtual ~IonexData() {}; 150 151 152 153 // The next four lines define our common interface 154 155 /// IonexData is a "data", so this function always returns true isData() const156 virtual bool isData() const 157 { return true; } 158 159 160 /// Am I an valid object? isValid() const161 virtual bool isValid() const 162 { return valid; }; 163 164 165 /// A debug output function. 166 virtual void dump (std::ostream& s = std::cout) const; 167 168 169 /** Get the position of a grid point based on input position 170 * 171 * @param in input lat, lon and height (Triple object) 172 * @param type grid point to be returned 173 * (1) neareast grid point 174 * (2) lower left hand grid point 175 * @param out output lat, lon and height (Triple object) 176 * @return the index within the data 177 * @throw InvalidRequest 178 * @warning Keep in mind the assumptions of IONEX grid (i.e., latitude 179 * between [87.5, -87.5], longitude between [-180, 180]) 180 * when you construct a Triple object. 181 */ 182 int getIndex( const Triple& in, const int& type, Triple& out ) const; 183 184 185 /** Get IONEX TEC or RMS value as a function of the position 186 * and nominal height. 187 * 188 * A simple 4-point formula is applied to interpolate between 189 * grid points. 190 * 191 * For more information see page 3 of IONEX manual: 192 * 193 * http://igscb.jpl.nasa.gov/igscb/data/format/ionex1.pdf 194 * 195 * @param pos input position (Position object). 196 * 197 * @return Computed TEC or RMS value. 198 * @throw InvalidRequest 199 * @throw FFStreamError 200 */ 201 double getValue(const Position& pos) const; 202 203 204 protected: 205 206 /** Writes a correctly formatted record from this data to stream \a s. 207 * 208 * @throw std::exception 209 * @throw FFStreamError 210 * @throw StringException when a StringUtils function fails 211 */ 212 virtual void reallyPutRecord(FFStream& s) const; 213 214 215 /** This function obtains a IONEX Data record from 216 * the given FFStream. 217 * 218 * If there is an error reading the stream, it is reset 219 * to its original position and its fail-bit is set. 220 * 221 * @throw std::exception 222 * @throw StringException when a StringUtils function fails 223 * @throw FFStreamError when exceptions(failbit) is set and 224 * a read or formatting error occurs. This also resets the 225 * stream to its pre-read position. 226 */ 227 virtual void reallyGetRecord(FFStream& s); 228 229 230 private: 231 232 233 /** Writes the CommonTime object into IONEX format. If it's a bad time, 234 * it will return blanks. 235 * 236 * @param dt time to be written into a IONEX data record. 237 * @throw StringUtils::StringException 238 */ 239 std::string writeTime(const CommonTime& dt) const; 240 241 242 /** This function constructs a CommonTime object from the given 243 * parameters. 244 * 245 * @param line Encoded time string found in the IONEX record. 246 */ 247 CommonTime parseTime(const std::string& line) const; 248 249 250 }; // End of class 'IonexData' 251 252 253 /// operator == for IonexData::IonexValType operator ==(const IonexData::IonexValType & x,const IonexData::IonexValType & y)254 inline bool operator==( const IonexData::IonexValType& x, 255 const IonexData::IonexValType& y ) 256 {return (x.type == y.type); }; 257 258 259 /// operator != for IonexData::IonexValType operator !=(const IonexData::IonexValType & x,const IonexData::IonexValType & y)260 inline bool operator!=( const IonexData::IonexValType& x, 261 const IonexData::IonexValType& y ) 262 {return (x.type != y.type); }; 263 264 265 /// operator < for IonexData::IonexValType operator <(const IonexData::IonexValType & x,const IonexData::IonexValType & y)266 inline bool operator<( const IonexData::IonexValType& x, 267 const IonexData::IonexValType& y ) 268 {return (x.type < y.type); }; 269 270 271 /// operator << for IonexData::IonexValType operator <<(std::ostream & s,const IonexData::IonexValType ivt)272 inline std::ostream& operator<<( std::ostream& s, 273 const IonexData::IonexValType ivt ) 274 { 275 return s << "Type= " << ivt.type 276 << ", Description= " << ivt.description 277 << ", Units= " << ivt.units; 278 }; 279 280 281 //@} 282 283 284 } // End of namespace gpstk 285 #endif // GPSTK_IONEXDATA_HPP 286