Go to the documentation of this file.
57 const string IonexData::startTecMapString =
"START OF TEC MAP";
58 const string IonexData::startRmsMapString =
"START OF RMS MAP";
59 const string IonexData::startHgtMapString =
"START OF HEIGHT MAP";
60 const string IonexData::currentEpochString =
"EPOCH OF CURRENT MAP";
61 const string IonexData::dataBlockString =
"LAT/LON1/LON2/DLON/H";
62 const string IonexData::endTecMapString =
"END OF TEC MAP";
63 const string IonexData::endRmsMapString =
"END OF RMS MAP";
64 const string IonexData::endHgtMapString =
"END OF HEIGHT MAP";
65 const string IonexData::endOfFile =
"END OF FILE";
67 const IonexData::IonexValType IonexData::UN(
"UN",
71 const IonexData::IonexValType IonexData::TEC(
"TEC",
72 "Total Electron Content map",
76 "Root Mean Square error",
80 IonexData::IonexValType ::
82 : type(
std::string(
"UN") ),
83 description(
std::string(
"Unknown or Invalid") ),
84 units(
std::string(
"") )
92 :
type(t), description(d), units(u)
124 line += string(54,
' ');
136 FFStreamError
err(
"This isn't a valid standard IONEX value type: " +
140 strm << line << endl;
146 line += string(24,
' ');
148 strm << line << endl;
152 int nlat(
dim[0]), nlon(
dim[1]);
154 for (
int ilat = 0; ilat < nlat; ilat++)
158 double currLat =
lat[0] + ilat*
lat[2];
161 line += string(2,
' ');
167 line += string(28,
' ');
169 strm << line << endl;
174 for (
int ilon = 0; ilon < nlon; ilon++)
176 int index = ilat*
dim[1]+ilon;
178 double val = (
data[index] != 999.9) ?
182 int valint = (val > 0.0) ?
183 static_cast<int>(val+0.5) :
static_cast<int>(val-0.5);
186 if (line.size() == 80)
188 strm << line << endl;
192 else if (ilon == nlon-1)
194 strm << line << endl;
206 line += string(54,
' ');
218 FFStreamError
err(
"This isn't a valid standard IONEX value type: " +
222 strm << line << endl;
246 for (
int i = 0; i < 3; i++)
268 if (line.size() > 80)
270 FFStreamError e(
"Bad epoch line");
275 if (line.length() == 0)
280 string label(line, 60, 20);
310 dim[0] =
static_cast<int>( ( hdr.
lat[1] - hdr.
lat[0] )
313 dim[1] =
static_cast<int>( ( hdr.
lon[1] - hdr.
lon[0] )
316 dim[2] = (hdr.
hgt[2] == 0) ?
317 1 :
static_cast<int>( (hdr.
hgt[1]-hdr.
hgt[0])
326 FFStreamError e(
string(
"Map type undefined: " + line) );
330 #ifdef GNSSTK_IONEX_UNUSED
331 const double lat0 =
asDouble(line.substr( 2,6)),
336 #endif // GNSSTK_IONEX_UNUSED
339 for (
int ival = 0,line_ndx = 0; ival <
dim[1]; ival++, line_ndx++)
342 if (!(line_ndx % 16))
350 if (line.size() > 80)
353 "Error reading IONEX data. Bad epoch line");
358 if (line.size() == 0)
366 line.resize(80,
' ');
369 int val =
asInt(line.substr(line_ndx*5,5));
372 data[ilat*
dim[1]+ival] = (val != 9999) ?
373 std::pow(10.0,
exponent)*val : 999.9;
400 FFStreamError e(
string(
"Unidentified Ionex Data record " + line) );
412 os <<
"IonexData dump() function" << std::endl;
413 os <<
"Epoch : " <<
time << std::endl;
414 os <<
"Map index : " <<
mapID << std::endl;
416 <<
" (" <<
type.
units <<
")" << std::endl;
417 os <<
"Grid size (lat x lon x hgt) : " <<
dim[0]
419 <<
" x " <<
dim[2] << std::endl;
420 os <<
"Number of values : " <<
data.
size()
421 <<
" values." << std::endl;
422 os <<
"Valid object? : " <<
isValid() << endl;
437 int ilat, ilon, ihgt, ncyc;
438 double xlat, xlon, xhgt;
441 xlat = (in[0] -
lat[0]) /
lat[2] + 1.0;
444 static_cast<int>(xlat+0.5) :
static_cast<int>(xlat);
446 if (ilat >= 1 && ilat <= nlat)
448 ABC[0] =
lat[0] + (ilat-1)*
lat[2];
452 InvalidRequest e(
"Irregular latitude. Latitude "
458 xlon = (in[1] -
lon[0]) /
lon[2] + 1.0;
461 static_cast<int>(xlon + 0.5) :
static_cast<int>(xlon);
464 ncyc =
static_cast<int>( ( 360.0 / std::abs(
lon[2]) ) + 0.5 );
470 else if (ilon > nlon)
476 if ( (ilon >= 1) && (ilon <= nlon) )
478 ABC[1] =
lon[0] + (ilon-1) *
lon[2];
482 InvalidRequest e(
"Irregular longitude. Longitude: "
495 xhgt = (in[2]/1000.0 -
hgt[0]) /
hgt[2] + 1.0;
498 static_cast<int>(xhgt + 0.5) :
static_cast<int>(xhgt);
500 if ( (ihgt >= 1) && (ihgt <= nhgt) )
502 ABC[2] = (
hgt[0] + (ihgt-1) *
hgt[2] ) * 1000.0;
506 InvalidRequest e(
"Irregular height. Height: "
507 +
asString( in[2]/1000.0 ) +
" km.");
514 return ( (ilon-1) + (ilat-1)*nlon + (ihgt-1)*nlon*nlat );
525 InvalidRequest e(
"Position object is not in GEOCENTRIC coordinates");
548 lambda = lambda - 360.0;
553 e[0] =
getIndex( inarg, 2, ABC[0] );
557 double xp( (inarg[1] - ABC[0][1]) /
lon[2] );
558 double xq( (inarg[0] - ABC[0][0]) /
lat[2] );
561 if ( (xp < 0) || (xp > 1) || (xq < 0) || (xq > 1) )
564 Exception exc(
"IonexData::getValue(): Wrong xp and xq factors!");
570 inarg =
Triple( ABC[0][0], ABC[0][1]+
lon[2], ABC[0][2] );
571 e[1] =
getIndex( inarg, 1, ABC[1] );
574 inarg =
Triple( ABC[0][0]+
lat[2], ABC[0][1], ABC[0][2] );
575 e[2] =
getIndex( inarg, 1, ABC[2] );
578 inarg =
Triple( ABC[0][0]+
lat[2], ABC[0][1]+
lon[2], ABC[0][2] );
579 e[3] =
getIndex( inarg, 1, ABC[3] );
583 for (
int i = 0; i < 4; i++)
585 double xval(
data[e[i]] );
593 FFStreamError e(
"Undefined TEC/RMS value(s).");
599 xsum = (1.0-xp) * (1.0-xq) * pntval[0] +
600 xp * (1.0-xq) * pntval[1] +
601 (1.0-xp) * xq * pntval[2] +
617 sec =
asInt(line.substr(30,6));
627 return string(36,
' ');
CommonTime time
the time corresponding to the current data records
long asInt(const std::string &s)
IonexHeader header
The header for this file.
void reallyGetRecord(FFStream &s) override
std::string units
units (optional). E.g. "meters"
double lat[3]
Definition of a grid in latitude.
static const GNSSTK_EXPORT std::string endRmsMapString
"END OF RMS MAP"
const Epoch BEGINNING_OF_TIME(CommonTime::BEGINNING_OF_TIME)
Earliest representable Epoch.
static const GNSSTK_EXPORT std::string dataBlockString
"LAT/LON1/LON2/DLON/H"
static const GNSSTK_EXPORT std::string currentEpochString
"EPOCH OF CURRENT MAP"
void formattedGetLine(std::string &line, const bool expectEOF=false)
Vector< double > data
TEC or RMS data.
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
std::string writeTime(const CommonTime &dt) const
std::valarray< double > theArray
CommonTime parseTime(const std::string &line) const
Vector & resize(const size_t index)
std::string & stripTrailing(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
std::string type
type e.g. TEC, RMS
double hgt[3]
Definition of a grid in height.
int mapID
denote the internal number of the current map
static const GNSSTK_EXPORT IonexValType RMS
@ Geocentric
geocentric (regular spherical coordinates)
static const GNSSTK_EXPORT std::string startRmsMapString
"START OF RMS MAP"
IonexData()
Default constructor.
IonexValType type
Type of data either TEC or RMS.
@ WGS84
The reference frame used by GPS.
T min(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
double lon[3]
Definition of a grid in longitude.
int getIndex(const Triple &in, int igp, Triple &out) const
double beta(double x, double y)
double asDouble(const std::string &s)
static const GNSSTK_EXPORT std::string endOfFile
"END OF FILE"
int dim[3]
How many values are along latitude, longitude, height.
static const GNSSTK_EXPORT std::string endTecMapString
"END OF TEC MAP"
bool empty() const
STL empty.
virtual ~IonexData()
Destructor.
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
static const GNSSTK_EXPORT IonexValType TEC
size_t size() const
STL size.
static const GNSSTK_EXPORT std::string startTecMapString
"START OF TEC MAP"
void reallyPutRecord(FFStream &s) const override
bool headerRead
Whether or not the IonexHeader has been read.
int exponent
Exponent defining the unit of the values.
#define GNSSTK_THROW(exc)
double getValue(const Position &pos) const
static const GNSSTK_EXPORT std::string startHgtMapString
"START OF HEIGHT MAP"
virtual bool isValid() const
Am I an valid object?
T RMS(const ConstVectorBase< T, BaseClass > &l)
std::string description
Description (optional)
virtual void dump(std::ostream &s=std::cout) const
A debug output function.
gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:39