IonexHeader.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk 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 GNSSTk 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 GNSSTk; 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-2022, 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 
44 #include <cctype>
45 
46 #include "StringUtils.hpp"
47 #include "MathBase.hpp"
48 #include "IonexHeader.hpp"
49 #include "IonexStream.hpp"
50 #include "CivilTime.hpp"
51 
52 using namespace std;
53 using namespace gnsstk::StringUtils;
54 
55 namespace gnsstk
56 {
57  const string IonexHeader::versionString = "IONEX VERSION / TYPE";
58  const string IonexHeader::runByString = "PGM / RUN BY / DATE";
59  const string IonexHeader::descriptionString = "DESCRIPTION";
60  const string IonexHeader::commentString = "COMMENT";
61  const string IonexHeader::firstTimeString = "EPOCH OF FIRST MAP";
62  const string IonexHeader::lastTimeString = "EPOCH OF LAST MAP";
63  const string IonexHeader::intervalString = "INTERVAL";
64  const string IonexHeader::numMapsString = "# OF MAPS IN FILE";
65  const string IonexHeader::mappingFunctionString = "MAPPING FUNCTION";
66  const string IonexHeader::elevationString = "ELEVATION CUTOFF";
67  const string IonexHeader::observablesUsedString = "OBSERVABLES USED";
68  const string IonexHeader::numStationsString = "# OF STATIONS";
69  const string IonexHeader::numSatsString = "# OF SATELLITES";
70  const string IonexHeader::baseRadiusString = "BASE RADIUS";
71  const string IonexHeader::mapDimensionString = "MAP DIMENSION";
72  const string IonexHeader::hgtGridString = "HGT1 / HGT2 / DHGT";
73  const string IonexHeader::latGridString = "LAT1 / LAT2 / DLAT";
74  const string IonexHeader::lonGridString = "LON1 / LON2 / DLON";
75  const string IonexHeader::exponentString = "EXPONENT";
76  const string IonexHeader::startAuxDataString = "START OF AUX DATA";
77  const string IonexHeader::endAuxDataString = "END OF AUX DATA";
78  const string IonexHeader::endOfHeader = "END OF HEADER";
79 
80  const string IonexHeader::DCB::svsAuxDataString = "PRN / BIAS / RMS";
81  const string IonexHeader::DCB::stationsAuxDataString =
82  "STATION / BIAS / RMS";
83 
84 
85  IonexHeader ::
86  IonexHeader()
87  : version(1.0), exponent(-1), valid(false)
88  {
89  }
90 
91 
94  {
95  }
96 
97 
98  // Clear (empty out) header
99  void IonexHeader ::
101  {
102  version = 1.0;
103  descriptionList.clear();
104  commentList.clear();
105  interval = 0;
106  numMaps = numStations = numSVs = mapDims = 0;
107  elevation = baseRadius = 0;
108 
109  hgt[0] = hgt[1] = hgt[2] = 0.0;
110  lat[0] = lat[1] = lat[2] = 0.0;
111  lon[0] = lon[1] = lon[2] = 0.0;
112 
113  exponent = -1; // that's the default value
114  svsmap.clear();
115  stamap.clear();
116  valid = auxDataFlag = false;
117  } // End of method 'IonexHeader::clear()'
118 
119 
120 
121  /* Simple debug output function.
122  *
123  * It simply outputs the version, name and number of maps contained
124  * in this Ionex header.
125  */
126  void IonexHeader ::
127  dump(std::ostream& os) const
128  {
129  os << "-------------------------------- IONEX HEADER"
130  << "--------------------------------" << endl;
131 
132  os << "First epoch : " << firstEpoch << endl;
133  os << "Last epoch : " << lastEpoch << endl;
134  os << "Interval : " << interval << endl;
135  os << "Number of ionex maps : " << numMaps << endl;
136  os << "Mapping function : " << mappingFunction << endl;
137  os << "Elevation cut off : " << elevation << endl;
138  os << "Number of stations : " << numStations << endl;
139  os << "Number of satellites : " << numSVs << endl;
140  os << "Map dimensions : " << mapDims << endl;
141 
142  os << "HGT1 / HGT2 / DHGT : " << hgt[0] << " / "
143  << hgt[1] << " / "
144  << hgt[2] << endl;
145  os << "LAT1 / LAT2 / DLAT : " << lat[0] << " / "
146  << lat[1] << " / "
147  << lat[2] << endl;
148  os << "LON1 / LON2 / DLON : " << lon[0] << " / "
149  << lon[1] << " / "
150  << lon[2] << endl;
151  os << "Valid object? : " << valid << endl;
152 
153  os << "-------------------------------- END OF HEADER"
154  << "-------------------------------" << endl;
155 
156  os << endl;
157  } //End of method 'IonexHeader::dump()'
158 
159 
160 
161  /*
162  * Parse a single auxiliary header record that contains "Differential
163  * code biases".
164  */
165  void IonexHeader ::
166  parseDcbRecord(const std::string &line)
167  {
168  string label(line, 60, 20);
169 
170  if (label == DCB::svsAuxDataString)
171  {
172  // prepare the DCB structure
173  // This makes round-trip conversion impossible.
174  //char c = isspace(line[3]) ? 'G' : line[3];
175  char c = line[3];
176  int prn = asInt(line.substr(4,2));
177  double bias = asDouble(line.substr(6,16));
178  double rms = asDouble(line.substr(16,26));
179 
180  // prepare SatID object that is the key of the map
181  SatelliteSystem satsys;
182  switch(line[3])
183  {
184  case ' ':
185  case 'G':
186  case 'g':
187  satsys = SatelliteSystem::GPS;
188  break;
189 
190  case 'R':
191  case 'r':
192  satsys = SatelliteSystem::Glonass;
193  break;
194 
195  default: // non-IONEX system character
196  FFStreamError e(std::string("Invalid system character \"")
197  + c + std::string("\""));
198  GNSSTK_THROW(e);
199  } // End of 'switch(line[3])'
200 
201  SatID svid = SatID(prn,satsys);
202 
203  // add to map
204  svsmap[svid] = DCB(c,prn,bias,rms);
205  } // End of 'if (label == DCB::svsAuxDataString)'...
206  else if (label == DCB::stationsAuxDataString)
207  {
208  string name = line.substr(6,4);
213  string num = line.substr(11,15);
214  double bias = asDouble(line.substr(26,10));
215  double rms = asDouble(line.substr(36,10));
216  stamap[name] = DCB(name, num, bias, rms);
217  }
218  else if (label == commentString)
219  {
220  // CODE's product has a comment line before aux data end
221  string s = strip(line.substr(0,60));
222  commentList.push_back(s);
223  }
224  else if (label == endAuxDataString)
225  {
226  auxDataFlag = false; // End of aux data
227  }
228  else
229  {
230  FFStreamError e(std::string( "Unidentified IONEX::DCB label: "
231  + label) );
232  GNSSTK_THROW(e);
233  } // End of 'if (label == endAuxDataString)'...
234  } // End of method 'IonexHeader::parseDcbRecord()'
235 
236 
237 
238  /* Parse a single header record, and modify 'valid' accordingly.
239  *
240  * Used by reallyGetRecord for both IonexHeader and IonexData.
241  */
242  void IonexHeader ::
243  parseHeaderRecord(const std::string& line)
244  {
245  string label(line, 60, 20);
246 
247  if (label == versionString)
248  {
249  version = asDouble(line.substr(0,20));
250  fileType = strip(line.substr(20,20));
251  system = strip(line.substr(40,20));
252  }
253  else if (label == runByString)
254  {
255  fileProgram = strip(line.substr( 0,20));
256  fileAgency = strip(line.substr(20,20));
257  date = strip(line.substr(40,20));
258  }
259  else if (label == descriptionString)
260  {
261  string s = line.substr(0,60);
262  descriptionList.push_back(s);
263  }
264  else if (label == commentString)
265  {
266  string s = line.substr(0,60);
267  commentList.push_back(s);
268  }
269  else if (label == firstTimeString)
270  {
271  firstEpoch = parseTime(line);
272  }
273  else if (label == lastTimeString)
274  {
275  lastEpoch = parseTime(line);
276  }
277  else if (label == intervalString)
278  {
279  interval = asInt(line.substr(0,6));
280  }
281  else if (label == numMapsString)
282  {
283  numMaps = asInt(line.substr(0,6));
284  }
285  else if (label == mappingFunctionString)
286  {
287  mappingFunction = strip(line.substr(0, 6));
288  }
289  else if (label == elevationString)
290  {
291  elevation = asDouble(line.substr(0, 8));
292  }
293  else if (label == observablesUsedString)
294  {
295  observablesUsed = strip(line.substr(0,60));
296  }
297  else if (label == numStationsString)
298  {
299  numStations = asInt(line.substr(0,6));
300  }
301  else if (label == numSatsString)
302  {
303  numSVs = asInt(line.substr(0,6));
304  }
305  else if (label == baseRadiusString)
306  {
307  baseRadius = asDouble(line.substr(0, 8));
308  }
309  else if (label == mapDimensionString)
310  {
311  mapDims = asInt(line.substr(0,6));
312  }
313  else if (label == hgtGridString)
314  {
315  hgt[0] = asDouble(line.substr( 2, 6));
316  hgt[1] = asDouble(line.substr( 8, 6));
317  hgt[2] = asDouble(line.substr(14, 6));
318  }
319  else if (label == latGridString)
320  {
321  lat[0] = asDouble(line.substr( 2, 6));
322  lat[1] = asDouble(line.substr( 8, 6));
323  lat[2] = asDouble(line.substr(14, 6));
324  }
325  else if (label == lonGridString)
326  {
327  lon[0] = asDouble(line.substr( 2, 6));
328  lon[1] = asDouble(line.substr( 8, 6));
329  lon[2] = asDouble(line.substr(14, 6));
330  }
331  else if (label == exponentString)
332  {
333  exponent = asInt(line.substr(0,6));
334  }
335  else if (label == startAuxDataString)
336  {
337  auxData = strip(line.substr(0,60));
338  auxDataFlag = true;
339  }
340  else if (label == endOfHeader)
341  {
342  auxDataFlag = true;
343  valid = true;
344  }
345  else
346  {
347  FFStreamError e("Unidentified IONEX header record: " + label);
348  GNSSTK_THROW(e);
349  }
350  } // End of method 'IonexHeader::parseHeaderRecord()'
351 
352 
353 
354  // This function parses the entire header from the given stream
355  void IonexHeader ::
357  {
358  IonexStream& strm = dynamic_cast<IonexStream&> (ffs);
359 
360  // if already read, just return
361  if (strm.headerRead == true)
362  {
363  return;
364  }
365 
366  // since we read a new header, we need to reinitialize
367  // all our list structures. All the other objects should be ok.
368  // This also applies if we threw an exception the first time we read
369  // the header and are now re-reading it. Some of these data
370  // structures could be full and we need to empty them.
371  clear();
372 
373  string line;
374 
375  while (!valid)
376  {
377  strm.formattedGetLine(line);
379 
380  // skip empty lines
381  if (line.length() == 0)
382  {
383  continue;
384  }
385  else
386  {
387  if (line.length() < 60 || line.length() > 80)
388  {
389  FFStreamError e("Invalid line length");
390  GNSSTK_THROW(e);
391  }
392  } // End of 'if (line.length() == 0)...'
393 
394  if (auxDataFlag) // when it is set true, then parse auxiliar data
395  {
396  try
397  {
398  parseDcbRecord(line);
399  }
400  catch (FFStreamError& e)
401  {
402  GNSSTK_RETHROW(e);
403  }
404  }
405  else
406  {
407  try
408  {
409  parseHeaderRecord(line);
410  }
411  catch (FFStreamError& e)
412  {
413  GNSSTK_RETHROW(e);
414  }
415  } // End of 'if (auxDataFlag)...'
416  } // End of 'while (!valid)...' (not for the header)
417 
418  // Here come some validity checkings
419  // Checking ionex version
420  if (version != 1.0)
421  {
422  FFStreamError e( "Invalid IONEX version number " +
423  asString(version));
424  GNSSTK_THROW(e);
425  }
426 
427  // time arguments consistency
428  double interval0( (lastEpoch - firstEpoch) / (numMaps -1.0) );
429  if (interval != static_cast<int>(interval0))
430  {
431  FFStreamError e("Inconsistent time arguments.");
432  GNSSTK_THROW(e);
433  }
434 
435  // map dimension consistency
436  if (mapDims == 2)
437  {
438  if ( (hgt[0] != hgt[1]) || (hgt[2] != 0.0) )
439  {
440  FFStreamError e("Error concerning map dimension.");
441  GNSSTK_THROW(e);
442  }
443  }
444  else
445  {
446  if ( (hgt[0] == hgt[1]) || (hgt[2] == 0.0) )
447  {
448  FFStreamError e("Error concerning map dimension.");
449  GNSSTK_THROW(e);
450  }
451  } // End of 'if (mapDims == 2)...'
452 
453  // grid checkings
454  double grdfac[4];
455  try
456  {
457  grdfac[0] = lat[0]/lat[2];
458  grdfac[1] = lat[1]/lat[2];
459  grdfac[2] = lon[0]/lon[2];
460  grdfac[3] = lon[1]/lon[2];
461  }
462  catch(std::exception& e)
463  {
464  throw;
465  }
466 
467  for (int i = 0; i < 4; i++)
468  {
469  //const double xdif1( grdfac[i] - static_cast<int>(grdfac[i]) );
470  const double xdif( ABS(grdfac[i] - static_cast<int>(grdfac[i])) );
471 
472  if (xdif > 1e-4)
473  {
474  FFStreamError e("Irregular Ionex data grid.");
475  GNSSTK_THROW(e);
476  }
477  } // End of 'for (int i = 0; i < 4; i++)...'
478 
479  // reach end of header line
480  strm.header = *this;
481  strm.headerRead = true;
482  } // End of method 'IonexHeader::reallyGetRecord()'
483 
484 
485 
486  void IonexHeader ::
488  {
489  IonexStream& strm = dynamic_cast<IonexStream&>(ffs);
490 
491  if (version != 1.0)
492  {
493  FFStreamError err( "Unknown IONEX version: " + asString(version,2) );
494  err.addText("Make sure to set the version correctly.");
495  GNSSTK_THROW(err);
496  }
497 
498  try
499  {
500  writeHeaderRecords(strm);
501  }
502  catch(FFStreamError& e)
503  {
504  GNSSTK_RETHROW(e);
505  }
506  catch(StringException& e)
507  {
508  GNSSTK_RETHROW(e);
509  }
510  } // End of method 'IonexHeader::reallyPutRecord()'
511 
512 
513  // this function writes all valid header records
514  void IonexHeader ::
516  {
517  IonexStream& strm = dynamic_cast<IonexStream&>(ffs);
518  string line;
519 
520  if (valid)
521  {
522  // write first IONEX record
523  line.clear();
524  line = rightJustify(asString(version,1), 8);
525  line += string(12, ' ');
526  if ((fileType[0] != 'I') && (fileType[0] != 'i'))
527  {
528  FFStreamError err("This isn't a Ionex file: " +
529  fileType.substr(0,1));
530  GNSSTK_THROW(err);
531  }
532 
533  line += leftJustify(fileType, 20);
534  line += leftJustify(system, 20);
535  line += versionString;
536  strm << line << endl;
537  strm.lineNumber++;
538 
539  // write second IONEX record
540  line.clear();
541  line += leftJustify(fileProgram,20);
542  line += leftJustify(fileAgency,20);
543  line += leftJustify(date,20);
544  line += runByString;
545  strm << line << endl;
546  strm.lineNumber++;
547 
548  // write multi-line description (optional)
549  if (descriptionList.size() > 0)
550  {
551  vector<std::string>::size_type i = 0;
552 
553  for( ; i < descriptionList.size(); i++)
554  {
555  line.clear();
556  line += leftJustify(descriptionList[i],60);
557  line += descriptionString;
558  strm << line << endl;
559  strm.lineNumber++;
560  }
561  } // End of 'if (descriptionList.size() > 0) ...'
562 
563  // write epoch of first epoch
564  line.clear();
565  line += writeTime(firstEpoch);
566  line += string(24, ' ');
567  line += firstTimeString;
568  strm << line << endl;
569  strm.lineNumber++;
570 
571  // write epoch of last epoch
572  line.clear();
573  line += writeTime(lastEpoch);
574  line += string(24, ' ');
575  line += lastTimeString;
576  strm << line << endl;
577  strm.lineNumber++;
578 
579  // write interval
580  line.clear();
581  line += rightJustify( asString(interval), 6 );
582  line += string(54, ' ');
583  line += intervalString;
584  strm << line << endl;
585  strm.lineNumber++;
586 
587  // write # of maps
588  line.clear();
589  line += rightJustify( asString<short>(numMaps), 6 );
590  line += string(54, ' ');
591  line += numMapsString;
592  strm << line << endl;
593  strm.lineNumber++;
594 
595  // write mapping function
596  line.clear();
597  line += string(2, ' ');
598  line += rightJustify(mappingFunction, 4);
599  line += string(54, ' ');
600  line += mappingFunctionString;
601  strm << line << endl;
602  strm.lineNumber++;
603 
604  // write elevation cutoff
605  line.clear();
606  line += rightJustify( asString(elevation,1), 8 );
607  line += string(52, ' ');
608  line += elevationString;
609  strm << line << endl;
610  strm.lineNumber++;
611 
612  // write observables used
613  line.clear();
614  line += leftJustify(observablesUsed,60);
615  line += observablesUsedString;
616  strm << line << endl;
617  strm.lineNumber++;
618 
619  // write # of stations (optional)
620  if (numStations > 0)
621  {
622  line.clear();
623  line += rightJustify( asString<short>(numStations), 6 );
624  line += string(54, ' ');
625  line += numStationsString;
626  strm << line << endl;
627  strm.lineNumber++;
628  }
629 
630  // write # of satellites (optional)
631  if (numSVs > 0)
632  {
633  line.clear();
634  line += rightJustify( asString<short>(numSVs), 6 );
635  line += string(54, ' ');
636  line += numSatsString;
637  strm << line << endl;
638  strm.lineNumber++;
639  }
640 
641  // write base radius
642  line.clear();
643  line += rightJustify( asString(baseRadius,1), 8 );
644  line += string(52, ' ');
645  line += baseRadiusString;
646  strm << line << endl;
647  strm.lineNumber++;
648 
649  // write map dimension
650  line.clear();
651  line += rightJustify( asString(mapDims), 6 );
652  line += string(54, ' ');
653  line += mapDimensionString;
654  strm << line << endl;
655  strm.lineNumber++;
656 
657  // write grid specifications
658  line.clear();
659  line += string(2, ' ');
660  line += rightJustify( asString(hgt[0],1), 6 );
661  line += rightJustify( asString(hgt[1],1), 6 );
662  line += rightJustify( asString(hgt[2],1), 6 );
663  line += string(40, ' ');
664  line += hgtGridString;
665  strm << line << endl;
666  strm.lineNumber++;
667 
668  line.clear();
669  line += string(2, ' ');
670  line += rightJustify( asString(lat[0],1), 6 );
671  line += rightJustify( asString(lat[1],1), 6 );
672  line += rightJustify( asString(lat[2],1), 6 );
673  line += string(40, ' ');
674  line += latGridString;
675  strm << line << endl;
676  strm.lineNumber++;
677 
678  line.clear();
679  line += string(2, ' ');
680  line += rightJustify( asString(lon[0],1), 6 );
681  line += rightJustify( asString(lon[1],1), 6 );
682  line += rightJustify( asString(lon[2],1), 6 );
683  line += string(40, ' ');
684  line += lonGridString;
685  strm << line << endl;
686  strm.lineNumber++;
687 
688  // write default exponent (optional)
689  line.clear();
690  line += rightJustify( asString(exponent), 6 );
691  line += string(54, ' ');
692  line += exponentString;
693  strm << line << endl;
694  strm.lineNumber++;
695 
696  // write multi-line comment
697  for( vector<std::string>::size_type i = 0;
698  i < commentList.size(); i++)
699  {
700  line.clear();
701  line += leftJustify(commentList[i],60);
702  line += commentString;
703  strm << line << endl;
704  strm.lineNumber++;
705  }
706 
707  // write auxiliary data (optional)
708  if (auxDataFlag)
709  {
710  // start of aux data
711  line.clear();
712  line += leftJustify(auxData,60);
713  line += startAuxDataString;
714  strm << line << endl;
715  strm.lineNumber++;
716 
717  for(const auto& isv : svsmap)
718  {
719  line.clear();
720  line += isv.second.toString();
721  line += string(34, ' ');
722  line += DCB::svsAuxDataString;
723  strm << line << endl;
724  strm.lineNumber++;
725  }
726 
727  for (const auto& ista : stamap)
728  {
729  line.clear();
730  line += leftJustify(ista.second.toString(), 60);
732  strm << line << endl;
733  strm.lineNumber++;
734  }
735 
736  // end of aux data
737  line.clear();
738  line += leftJustify(auxData,60);
739  line += endAuxDataString;
740  strm << line << endl;
741  strm.lineNumber++;
742 
743  } // End of 'if (auxDataFlag)...'
744 
745  // write record closing Ionex header
746  line.clear();
747  line += string(60, ' ');
748  line += endOfHeader;
749  strm << line << endl;
750  strm.lineNumber++;
751  } // End of 'if (valid)...'
752  }
753 
754 
755  /* This function sets the time for this header.
756  *
757  * It looks at \a line to obtain the needed information.
758  */
760  parseTime(const std::string& line) const
761  {
762  int year, month, day, hour, min, sec;
763 
764  year = asInt(line.substr( 0,6));
765  month = asInt(line.substr( 6,6));
766  day = asInt(line.substr(12,6));
767  hour = asInt(line.substr(18,6));
768  min = asInt(line.substr(24,6));
769  sec = asInt(line.substr(30,6));
770 
771  return CivilTime(year, month, day, hour, min, (double)sec);
772  } // End of method 'IonexHeader::parseTime()'
773 
774 
778  string IonexHeader ::
779  writeTime(const CommonTime& dt) const
780  {
781  string line;
782 
783  line = rightJustify(asString<short>(static_cast<CivilTime>(dt).year), 6);
784  line += rightJustify(asString<short>(static_cast<CivilTime>(dt).month),
785  6);
786  line += rightJustify(asString<short>(static_cast<CivilTime>(dt).day), 6);
787  line += rightJustify(asString<short>(static_cast<CivilTime>(dt).hour), 6);
788  line += rightJustify(asString<short>(static_cast<CivilTime>(dt).minute),
789  6);
790  line += rightJustify(
791  asString (static_cast<int>(static_cast<CivilTime>(dt).second)), 6);
792 
793  return line;
794  } // End of method 'IonexHeader::writeTime()'
795 
796 
799  : system('U'), prn(-1), bias(0), rms(0.0), isPRN(true)
800  {
801  }
802 
803 
805  DCB(char s, int p, double b, double r)
806  : system(s), prn(p), bias(b), rms(r), isPRN(true)
807  {
808  }
809 
810 
812  DCB(const std::string& s, const std::string& n, double b, double r)
813  : system('U'), prn(-1), bias(b), rms(r), isPRN(false), name(s),
814  number(n)
815  {
816  }
817 
818 
819  std::string IonexHeader::DCB ::
820  toString() const
821  {
822  std::string line;
823  if (isPRN)
824  {
825  line = string(3, ' ');
826  line += std::string(3, '0');
827 
828  // update with the system char
829  line[3] = system;
830 
831  // convert the prn into 2-digit string
832  std::string s = StringUtils::asString(prn);
833  if (prn < 10)
834  {
835  line[5] = s[0];
836  }
837  else
838  {
839  line[4] = s[0];
840  line[5] = s[1];
841  }
842  }
843  else
844  {
845  line = string(6, ' ');
846  line += StringUtils::leftJustify(name, 4);
847  line += ' ';
848  line += StringUtils::leftJustify(number, 15);
849  }
850  // append bias and rms
851  line += StringUtils::rightJustify( StringUtils::asString(bias,3), 10 );
852  line += StringUtils::rightJustify( StringUtils::asString(rms, 3), 10 );
853 
854  return line;
855  } // End of method 'DCB::toString()'
856 } // End of namespace gnsstk
gnsstk::IonexHeader::latGridString
static const GNSSTK_EXPORT std::string latGridString
"LAT1 / LAT2 / DLAT"
Definition: IonexHeader.hpp:120
gnsstk::IonexHeader::stamap
StaDCBMap stamap
Map of stations' DCBs (in nanoseconds)
Definition: IonexHeader.hpp:234
gnsstk::IonexHeader::lon
double lon[3]
Definition: IonexHeader.hpp:222
gnsstk::IonexHeader::interval
int interval
Time interval between maps (seconds)
Definition: IonexHeader.hpp:205
example3.svid
svid
Definition: example3.py:19
gnsstk::IonexHeader::intervalString
static const GNSSTK_EXPORT std::string intervalString
"INTERVAL"
Definition: IonexHeader.hpp:100
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
gnsstk::IonexStream::header
IonexHeader header
The header for this file.
Definition: IonexStream.hpp:94
gnsstk::IonexHeader::observablesUsed
std::string observablesUsed
One-line specification of used obs.
Definition: IonexHeader.hpp:209
example6.day
day
Definition: example6.py:66
gnsstk::IonexHeader::observablesUsedString
static const GNSSTK_EXPORT std::string observablesUsedString
"OBSERVABLES USED"
Definition: IonexHeader.hpp:108
gnsstk::IonexHeader::lastEpoch
CommonTime lastEpoch
Epoch of last map.
Definition: IonexHeader.hpp:203
gnsstk::IonexHeader::reallyGetRecord
void reallyGetRecord(FFStream &s) override
Definition: IonexHeader.cpp:356
gnsstk::IonexHeader::system
std::string system
Satellite system or theoretical model.
Definition: IonexHeader.hpp:194
gnsstk::IonexHeader::exponentString
static const GNSSTK_EXPORT std::string exponentString
"EXPONENT"
Definition: IonexHeader.hpp:124
gnsstk::IonexHeader::mappingFunctionString
static const GNSSTK_EXPORT std::string mappingFunctionString
"MAPPING FUNCTION"
Definition: IonexHeader.hpp:104
gnsstk::FFStream
Definition: FFStream.hpp:119
gnsstk::IonexHeader::descriptionString
static const GNSSTK_EXPORT std::string descriptionString
"DESCRIPTION"
Definition: IonexHeader.hpp:92
StringUtils.hpp
gnsstk::IonexHeader::commentString
static const GNSSTK_EXPORT std::string commentString
"COMMENT"
Definition: IonexHeader.hpp:94
gnsstk::IonexHeader::elevation
double elevation
Minimum elevation angle, in degrees.
Definition: IonexHeader.hpp:208
example6.year
year
Definition: example6.py:64
IonexHeader.hpp
gnsstk::IonexHeader::DCB::svsAuxDataString
static const GNSSTK_EXPORT std::string svsAuxDataString
"PRN / BIAS / RMS"
Definition: IonexHeader.hpp:177
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::SatelliteSystem
SatelliteSystem
Supported satellite systems.
Definition: SatelliteSystem.hpp:55
gnsstk::IonexHeader::writeTime
std::string writeTime(const CommonTime &dt) const
Definition: IonexHeader.cpp:779
gnsstk::IonexHeader::DCB::DCB
DCB()
Default constructor. Defines and invalid structure.
Definition: IonexHeader.cpp:798
gnsstk::FFTextStream::lineNumber
unsigned int lineNumber
Definition: FFTextStream.hpp:98
example6.hour
hour
Definition: example6.py:67
gnsstk::SatID
Definition: SatID.hpp:89
gnsstk::IonexHeader::date
std::string date
Date and time of file creation.
Definition: IonexHeader.hpp:197
gnsstk::IonexHeader::svsmap
SatDCBMap svsmap
Map of satellites' DCBs (in nanoseconds)
Definition: IonexHeader.hpp:233
gnsstk::IonexHeader::version
double version
IONEX version.
Definition: IonexHeader.hpp:191
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::IonexHeader::baseRadiusString
static const GNSSTK_EXPORT std::string baseRadiusString
"BASE RADIUS"
Definition: IonexHeader.hpp:114
gnsstk::IonexHeader::dump
virtual void dump(std::ostream &s=std::cout) const
Definition: IonexHeader.cpp:127
gnsstk::IonexHeader::auxData
std::string auxData
Type of auxiliar data (optional)
Definition: IonexHeader.hpp:226
IonexStream.hpp
example6.minute
minute
Definition: example6.py:68
gnsstk::IonexHeader::startAuxDataString
static const GNSSTK_EXPORT std::string startAuxDataString
"START OF AUX DATA"
Definition: IonexHeader.hpp:126
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::SatelliteSystem::GPS
@ GPS
gnsstk::IonexHeader::~IonexHeader
virtual ~IonexHeader()
Destructor.
Definition: IonexHeader.cpp:93
gnsstk::StringUtils::stripTrailing
std::string & stripTrailing(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1453
gnsstk::IonexHeader::fileAgency
std::string fileAgency
Name of agency creating this file.
Definition: IonexHeader.hpp:196
example6.second
second
Definition: example6.py:69
gnsstk::IonexStream
Definition: IonexStream.hpp:61
gnsstk::IonexHeader::mapDimensionString
static const GNSSTK_EXPORT std::string mapDimensionString
"MAP DIMENSION"
Definition: IonexHeader.hpp:116
gnsstk::IonexHeader::firstTimeString
static const GNSSTK_EXPORT std::string firstTimeString
"EPOCH OF FIRST MAP"
Definition: IonexHeader.hpp:96
gnsstk::IonexHeader::parseDcbRecord
void parseDcbRecord(const std::string &line)
Definition: IonexHeader.cpp:166
gnsstk::IonexHeader::auxDataFlag
bool auxDataFlag
Flag to monitor the sequence of auxiliar data.
Definition: IonexHeader.hpp:235
gnsstk::IonexHeader::numMaps
size_t numMaps
Total number of TEC/RMS/HGT maps.
Definition: IonexHeader.hpp:206
example4.err
err
Definition: example4.py:126
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::IonexHeader::firstEpoch
CommonTime firstEpoch
Epoch of first map.
Definition: IonexHeader.hpp:202
gnsstk::min
T min(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:858
gnsstk::IonexHeader::lonGridString
static const GNSSTK_EXPORT std::string lonGridString
"LON1 / LON2 / DLON"
Definition: IonexHeader.hpp:122
version
string version(string("2.4 9/23/15 rev"))
example6.valid
valid
Definition: example6.py:20
CivilTime.hpp
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
gnsstk::IonexHeader::hgt
double hgt[3]
Definition: IonexHeader.hpp:217
gnsstk::IonexHeader::numSVs
size_t numSVs
Number of contributing satellites (opt)
Definition: IonexHeader.hpp:212
gnsstk::IonexHeader::baseRadius
double baseRadius
Mean earth radius, or bottom of height grid (km)
Definition: IonexHeader.hpp:214
gnsstk::IonexHeader::lat
double lat[3]
Definition: IonexHeader.hpp:220
gnsstk::IonexHeader::writeHeaderRecords
void writeHeaderRecords(FFStream &s) const
Definition: IonexHeader.cpp:515
gnsstk::IonexHeader::numMapsString
static const GNSSTK_EXPORT std::string numMapsString
"# OF MAPS IN FILE"
Definition: IonexHeader.hpp:102
ABS
#define ABS(x)
Definition: MathBase.hpp:73
gnsstk::IonexHeader::versionString
static const GNSSTK_EXPORT std::string versionString
"IONEXVERSION / TYPE"
Definition: IonexHeader.hpp:88
gnsstk::IonexHeader::elevationString
static const GNSSTK_EXPORT std::string elevationString
"ELEVATION CUTOFF"
Definition: IonexHeader.hpp:106
gnsstk::IonexHeader::commentList
std::vector< std::string > commentList
Comments in header(optional)
Definition: IonexHeader.hpp:200
gnsstk::CivilTime
Definition: CivilTime.hpp:55
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
gnsstk::IonexHeader::fileType
std::string fileType
IONEX filetype ('I' for Ionoshere Maps)
Definition: IonexHeader.hpp:193
gnsstk::IonexHeader::runByString
static const GNSSTK_EXPORT std::string runByString
"PGM / RUN BY / DATE"
Definition: IonexHeader.hpp:90
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
gnsstk::IonexHeader::valid
bool valid
return code, Am I valid?
Definition: IonexHeader.hpp:238
gnsstk::IonexHeader::numStations
size_t numStations
Number of contributing stations (optional)
Definition: IonexHeader.hpp:211
gnsstk::IonexHeader::numStationsString
static const GNSSTK_EXPORT std::string numStationsString
"# OF STATIONS"
Definition: IonexHeader.hpp:110
std
Definition: Angle.hpp:142
gnsstk::IonexHeader::DCB
Definition: IonexHeader.hpp:134
gnsstk::IonexHeader::parseTime
CommonTime parseTime(const std::string &line) const
Definition: IonexHeader.cpp:760
gnsstk::StringUtils::strip
std::string & strip(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1482
gnsstk::IonexStream::headerRead
bool headerRead
Whether or not the IonexHeader has been read.
Definition: IonexStream.hpp:91
gnsstk::StringUtils::leftJustify
std::string & leftJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1582
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::IonexHeader::DCB::stationsAuxDataString
static const GNSSTK_EXPORT std::string stationsAuxDataString
"STATION/BIAS/RMS"
Definition: IonexHeader.hpp:179
gnsstk::SatelliteSystem::Glonass
@ Glonass
gnsstk::IonexHeader::parseHeaderRecord
void parseHeaderRecord(const std::string &line)
Definition: IonexHeader.cpp:243
example6.month
month
Definition: example6.py:65
MathBase.hpp
gnsstk::IonexHeader::exponent
int exponent
Exponent defining the unit of the values (optional)
Definition: IonexHeader.hpp:225
gnsstk::IonexHeader::lastTimeString
static const GNSSTK_EXPORT std::string lastTimeString
"EPOCH OF LAST MAP"
Definition: IonexHeader.hpp:98
gnsstk::IonexHeader::reallyPutRecord
void reallyPutRecord(FFStream &s) const override
Definition: IonexHeader.cpp:487
gnsstk::IonexHeader::clear
void clear()
Clear (empty out) header.
Definition: IonexHeader.cpp:100
gnsstk::IonexHeader::descriptionList
std::vector< std::string > descriptionList
Descriptions in header (opt)
Definition: IonexHeader.hpp:199
gnsstk::IonexHeader::mapDims
size_t mapDims
Dimension of maps (2 or 3)
Definition: IonexHeader.hpp:215
gnsstk::IonexHeader::endAuxDataString
static const GNSSTK_EXPORT std::string endAuxDataString
"END OF AUX DATA"
Definition: IonexHeader.hpp:128
gnsstk::IonexHeader::endOfHeader
static const GNSSTK_EXPORT std::string endOfHeader
"END OF HEADER"
Definition: IonexHeader.hpp:130
gnsstk::IonexHeader::DCB::toString
std::string toString() const
convert DCB structure to a string
Definition: IonexHeader.cpp:820
gnsstk::IonexHeader::numSatsString
static const GNSSTK_EXPORT std::string numSatsString
"# OF SATELLITES"
Definition: IonexHeader.hpp:112
gnsstk::IonexHeader::mappingFunction
std::string mappingFunction
Mapping function adopted.
Definition: IonexHeader.hpp:207
gnsstk::IonexHeader::fileProgram
std::string fileProgram
Name of program creating this file.
Definition: IonexHeader.hpp:195
gnsstk::IonexHeader::hgtGridString
static const GNSSTK_EXPORT std::string hgtGridString
"HGT1 / HGT2 / DHGT"
Definition: IonexHeader.hpp:118


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:39