RinexMetData.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 "StringUtils.hpp"
45 #include "CivilTime.hpp"
46 #include "RinexMetHeader.hpp"
47 #include "RinexMetData.hpp"
48 #include "RinexMetStream.hpp"
49 
50 using namespace gnsstk::StringUtils;
51 using namespace std;
52 
53 namespace gnsstk
54 {
55  const int RinexMetData::maxObsPerLine = 8;
57 
59  {
60  RinexMetStream& strm = dynamic_cast<RinexMetStream&>(ffs);
61  string line;
62 
63  // first the epoch line to 'line'
64  line = writeTime(time, strm.header.version);
65 
66  for (int i = 0;
67  (i < int(strm.header.obsTypeList.size())) && (i < maxObsPerLine);
68  i++)
69  {
71  RinexMetMap::const_iterator itr = data.find(thistype);
72  if (itr == data.end())
73  {
74  FFStreamError err("Couldn't find data for " +
77  }
78  line += rightJustify(asString((*itr).second,1),7);
79  }
80 
81  // Do we need continuation lines?
82  if ((int)strm.header.obsTypeList.size() > maxObsPerLine)
83  {
84  for (size_t i = maxObsPerLine;
85  i < strm.header.obsTypeList.size();
86  i++)
87  {
88  if (((i - maxObsPerLine) % maxObsPerContinuationLine) == 0)
89  {
90  ffs << line << endl;
91  strm.lineNumber++;
92  line.clear();
93  line += string(4,' ');
94  }
96  RinexMetMap::const_iterator itr = data.find(thistype);
97  if (itr == data.end())
98  {
99  FFStreamError err("Couldn't find data for " +
101  GNSSTK_THROW(err);
102  }
103  line += rightJustify(asString((*itr).second,1),7);
104  }
105  }
106 
107  ffs << line << endl;
108  strm.lineNumber++;
109  }
110 
112  {
113  RinexMetStream& strm = dynamic_cast<RinexMetStream&>(ffs);
114 
115  if(!strm.headerRead)
116  strm >> strm.header;
117 
118  RinexMetHeader& hdr = strm.header;
119 
120  string line;
121  data.clear();
122 
123  // this is to see whether or not we expect an EOF
124  // when we read this next line
125  if ((int)hdr.obsTypeList.size() > maxObsPerLine)
126  strm.formattedGetLine(line);
127  else
128  strm.formattedGetLine(line, true);
129 
130  processFirstLine(line, hdr, hdr.version);
131 
132  time = parseTime(line, hdr.version);
133 
134  while (data.size() < hdr.obsTypeList.size())
135  {
136  if ((int)(hdr.obsTypeList.size() - data.size()) < maxObsPerContinuationLine)
137  strm.formattedGetLine(line, true);
138  else
139  strm.formattedGetLine(line);
140  processContinuationLine(line, hdr);
141  }
142 
143  if (data.size() != hdr.obsTypeList.size())
144  {
145  FFStreamError e("Incorrect number of records");
146  GNSSTK_THROW(e);
147  }
148  }
149 
150  void RinexMetData::processFirstLine(const string& line,
151  const RinexMetHeader& hdr,
152  double version)
153  {
154  int yrLen = 18;
155  if(version >= 3.02)
156  {
157  yrLen = 20;
158  }
159  try
160  {
161  for (int i = 0;
162  (i < maxObsPerLine) && (i < int(hdr.obsTypeList.size()));
163  i++)
164  {
165  int currPos = 7*i + yrLen;
166  data[hdr.obsTypeList[i]] = asDouble(line.substr(currPos,7));
167  }
168  }
169  catch (std::exception &e)
170  {
171  FFStreamError err("std::exception: " + string(e.what()));
172  GNSSTK_THROW(err);
173  }
174  }
175 
176  void RinexMetData::processContinuationLine(const string& line,
177  const RinexMetHeader& hdr)
178  {
179  try
180  {
181  int currentElements = data.size();
182  for (int i = currentElements;
183  (i < (maxObsPerContinuationLine + currentElements)) &&
184  (i < int(hdr.obsTypeList.size()));
185  i++)
186  {
187  int currPos = 7*((i - maxObsPerLine) % maxObsPerContinuationLine) + 4;
188  data[hdr.obsTypeList[i]] = asDouble(line.substr(currPos,7));
189  }
190  }
191  catch (std::exception &e)
192  {
193  FFStreamError err("std::exception: " + string(e.what()));
194  GNSSTK_THROW(err);
195  }
196  }
197 
198  CommonTime RinexMetData::parseTime(const string& line, double version) const
199  {
200  int addYrLen = 0;
201  if(version >=3.02)
202  {
203  addYrLen = 2;
204  }
205  try
206  {
207  // According to the RINEX spec, any 2 digit year 80 or greater
208  // is a year in the 1900s (1980-1999), under 80 is 2000s.
209  // Rinex 3.02 uses 4 digit years
210  const int YearRollover = 80;
211 
212  // check if the spaces are in the right place - an easy way to check
213  // if there's corruption in the file
214  if ( line.size() < 18+addYrLen ||
215  (line[0] != ' ') ||
216  (line[3+addYrLen] != ' ') ||
217  (line[6+addYrLen] != ' ') ||
218  (line[9+addYrLen] != ' ') ||
219  (line[12+addYrLen] != ' ') ||
220  (line[15+addYrLen] != ' '))
221  {
222  FFStreamError e("Invalid time format");
223  GNSSTK_THROW(e);
224  }
225 
226  int year, month, day, hour, min;
227  double sec;
228 
229  year = asInt(line.substr(1, 2+addYrLen));
230  month = asInt(line.substr(3+addYrLen, 3));
231  day = asInt(line.substr(6+addYrLen, 3));
232  hour = asInt(line.substr(9+addYrLen, 3));
233  min = asInt(line.substr(12+addYrLen,3));
234  sec = asInt(line.substr(15+addYrLen,3));
235 
236  if(!addYrLen)
237  {
238  if (year < YearRollover)
239  {
240  year += 100;
241  }
242  year += 1900;
243  }
244 
246  return CommonTime(rv);
247  }
248  catch (std::exception &e)
249  {
250  FFStreamError err("std::exception: " + string(e.what()));
251  GNSSTK_THROW(err);
252  }
253  }
254 
255  string RinexMetData::writeTime(const CommonTime& dt, double version) const
256  {
257  int yrLen = 2;
258  if(version >= 3.02)
259  {
260  yrLen = 4;
261  }
262 
264  {
265  return string(26, ' ');
266  }
267 
268  string line(" ");
269  CivilTime civtime(dt);
270  line += rightJustify(asString<short>(civtime.year ),yrLen,'0');
271  line += " ";
272  line += rightJustify(asString<short>(civtime.month ),2);
273  line += " ";
274  line += rightJustify(asString<short>(civtime.day ),2);
275  line += " ";
276  line += rightJustify(asString<short>(civtime.hour ),2);
277  line += " ";
278  line += rightJustify(asString<short>(civtime.minute),2);
279  line += " ";
280  line += rightJustify(asString<short>(civtime.second),2);
281 
282  return line;
283  }
284 
285  void RinexMetData::dump(ostream& s) const
286  {
287  s << " " << writeTime(time) << endl;
288 
289  RinexMetMap::const_iterator itr;
290  for(itr = data.begin(); itr != data.end(); itr++)
291  {
292  s << " " << RinexMetHeader::convertObsType((*itr).first)
293  << " " << (*itr).second << endl;
294  }
295  }
296 
298  {
299  ostringstream s;
300  s << " " << writeTime(time) << endl;
301 
302  RinexMetMap::const_iterator itr;
303  for(itr = data.begin(); itr != data.end(); itr++)
304  {
305  s << " " << RinexMetHeader::convertObsType((*itr).first)
306  << " " << fixed << setprecision(1) << (*itr).second << endl;
307  }
308  return s.str();
309  }
310 
311 } // end of namespace
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
gnsstk::RinexMetStream
Definition: RinexMetStream.hpp:70
gnsstk::RinexMetData::stableText
virtual std::string stableText() const
Definition: RinexMetData.cpp:297
example6.day
day
Definition: example6.py:66
gnsstk::CivilTime::year
int year
Definition: CivilTime.hpp:198
gnsstk::FFStream
Definition: FFStream.hpp:119
StringUtils.hpp
example6.year
year
Definition: example6.py:64
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::FFTextStream::lineNumber
unsigned int lineNumber
Definition: FFTextStream.hpp:98
example6.hour
hour
Definition: example6.py:67
gnsstk::RinexMetData::parseTime
CommonTime parseTime(const std::string &line, double version) const
Definition: RinexMetData.cpp:198
gnsstk::TimeSystem::Any
@ Any
wildcard; allows comparison with any other type
gnsstk::RinexMetStream::header
RinexMetHeader header
RINEX met header for this file.
Definition: RinexMetStream.hpp:89
gnsstk::RinexMetData::maxObsPerLine
static const GNSSTK_EXPORT int maxObsPerLine
The maximum number of obs per line before you need a new line.
Definition: RinexMetData.hpp:107
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::CivilTime::day
int day
Definition: CivilTime.hpp:200
gnsstk::RinexMetData::reallyGetRecord
virtual void reallyGetRecord(FFStream &s)
Definition: RinexMetData.cpp:111
gnsstk::CommonTime::BEGINNING_OF_TIME
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
Definition: CommonTime.hpp:102
gnsstk::RinexMetHeader::RinexMetType
RinexMetType
Enum for the different types of data in this file.
Definition: RinexMetHeader.hpp:81
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::RinexMetData::maxObsPerContinuationLine
static const GNSSTK_EXPORT int maxObsPerContinuationLine
Definition: RinexMetData.hpp:110
example4.time
time
Definition: example4.py:103
gnsstk::RinexMetHeader::convertObsType
static RinexMetType convertObsType(const std::string &oneObs)
Definition: RinexMetHeader.cpp:464
example4.err
err
Definition: example4.py:126
gnsstk::RinexMetStream::headerRead
bool headerRead
Flag showing whether or not the header has been read.
Definition: RinexMetStream.hpp:92
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::min
T min(const SparseMatrix< T > &SM)
Maximum element - return 0 if empty.
Definition: SparseMatrix.hpp:858
version
string version(string("2.4 9/23/15 rev"))
CivilTime.hpp
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
RinexMetHeader.hpp
gnsstk::CivilTime::minute
int minute
Definition: CivilTime.hpp:202
example3.data
data
Definition: example3.py:22
gnsstk::CivilTime
Definition: CivilTime.hpp:55
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
gnsstk::RinexMetData::processFirstLine
void processFirstLine(const std::string &line, const RinexMetHeader &hdr, double version)
Definition: RinexMetData.cpp:150
RinexMetStream.hpp
RinexMetData.hpp
std
Definition: Angle.hpp:142
gnsstk::CivilTime::month
int month
Definition: CivilTime.hpp:199
gnsstk::RinexMetHeader::obsTypeList
std::vector< RinexMetType > obsTypeList
Definition: RinexMetHeader.hpp:213
gnsstk::CivilTime::second
double second
Definition: CivilTime.hpp:203
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
example6.month
month
Definition: example6.py:65
gnsstk::RinexMetHeader::version
double version
RINEX Version.
Definition: RinexMetHeader.hpp:197
gnsstk::RinexMetData::processContinuationLine
void processContinuationLine(const std::string &line, const RinexMetHeader &hdr)
Definition: RinexMetData.cpp:176
gnsstk::RinexMetData::dump
virtual void dump(std::ostream &s) const
Definition: RinexMetData.cpp:285
gnsstk::CivilTime::hour
int hour
Definition: CivilTime.hpp:201
gnsstk::RinexMetHeader
Definition: RinexMetHeader.hpp:70
gnsstk::RinexMetData::writeTime
std::string writeTime(const CommonTime &dtd, double version=2.11) const
Definition: RinexMetData.cpp:255
gnsstk::RinexMetData::reallyPutRecord
void reallyPutRecord(FFStream &s) const
Definition: RinexMetData.cpp:58


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