GNSS-SDR  0.0.17
An Open Source GNSS Software Defined Receiver
rinex_printer.h
Go to the documentation of this file.
1 /*!
2  * \file rinex_printer.h
3  * \brief Interface of a RINEX 2.11 / 3.01 printer
4  * See ftp://igs.org/pub/data/format/rinex301.pdf
5  *
6  * Receiver Independent EXchange Format (RINEX):
7  * The first proposal for the Receiver Independent Exchange Format RINEX
8  * was developed by the Astronomical Institute of the University of Berne
9  * for the easy exchange of the GPS data to be collected during the large
10  * European GPS campaign EUREF 89, which involved more than 60 GPS receivers
11  * of 4 different manufacturers.
12  * The governing aspect during the development was the fact that most geodetic
13  * processing software for GPS data use a well-defined set of observables:
14  * 1) The carrier-phase measurement at one or both carriers (actually being a
15  * measurement on the beat frequency between the received carrier of the
16  * satellite signal and a receiver-generated reference frequency).
17  * 2) The pseudorange (code) measurement , equivalent to the difference
18  * of the time of reception (expressed in the time frame of the receiver)
19  * and the time of transmission (expressed in the time frame of the satellite)
20  * of a distinct satellite signal.
21  * 3) The observation time being the reading of the receiver clock at the
22  * instant of validity of the carrier-phase and/or the code measurements.
23  * Note: A collection of the formats currently used by the IGS can be found
24  * here: https://kb.igs.org/hc/en-us/articles/201096516-IGS-Formats
25  * \author Carles Fernandez Prades, 2011. cfernandez(at)cttc.es
26  *
27  * -----------------------------------------------------------------------------
28  *
29  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
30  * This file is part of GNSS-SDR.
31  *
32  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
33  * SPDX-License-Identifier: GPL-3.0-or-later
34  *
35  * -----------------------------------------------------------------------------
36  */
37 
38 #ifndef GNSS_SDR_RINEX_PRINTER_H
39 #define GNSS_SDR_RINEX_PRINTER_H
40 
41 #include <boost/date_time/posix_time/posix_time.hpp>
42 #include <cstdint> // for int32_t
43 #include <cstdlib> // for strtol, strtod
44 #include <fstream> // for fstream
45 #include <iomanip> // for setprecision
46 #include <map> // for map
47 #include <sstream> // for stringstream
48 #include <string> // for string
49 #include <vector>
50 
51 
52 /** \addtogroup PVT
53  * \{ */
54 /** \addtogroup PVT_libs
55  * \{ */
56 
57 
59 class Beidou_Dnav_Iono;
61 class Galileo_Ephemeris;
62 class Galileo_Iono;
63 class Galileo_Utc_Model;
67 class Gnss_Synchro;
68 class Gps_CNAV_Ephemeris;
69 class Gps_CNAV_Iono;
70 class Gps_CNAV_Utc_Model;
71 class Gps_Ephemeris;
72 class Gps_Iono;
74 class Gps_Utc_Model;
75 class Rtklib_Solver;
76 
77 
78 /*!
79  * \brief Class that handles the generation of Receiver
80  * INdependent EXchange format (RINEX) files
81  */
83 {
84 public:
85  /*!
86  * \brief Constructor. Creates GNSS Navigation and Observables RINEX files.
87  */
88  explicit Rinex_Printer(int version = 0,
89  const std::string& base_path = ".",
90  const std::string& base_name = "-");
91 
92  /*!
93  * \brief Destructor. Removes created files if empty.
94  */
96 
97  /*!
98  * \brief Print RINEX annotation. If it is the first annotation, it also
99  * prints the RINEX headers for navigation and observation files. If it is
100  * not the first annotation, it only annotates the observation, and updates
101  * the navigation header if UTC data was not available when writing it for
102  * the first time. The meaning of type_of_rx is as follows:
103  *
104  * type_of_rx | Signals
105  * ------------- | -------------
106  * 0 | Unknown
107  * 1 | GPS L1 C/A
108  * 2 | GPS L2C
109  * 3 | GPS L5
110  * 4 | Galileo E1B
111  * 5 | Galileo E5a
112  * 6 | Galileo E5b
113  * 7 | GPS L1 C/A + GPS L2C
114  * 8 | GPS L1 C/A + GPS L5
115  * 9 | GPS L1 C/A + Galileo E1B
116  * 10 | GPS L1 C/A + Galileo E5a
117  * 11 | GPS L1 C/A + Galileo E5b
118  * 12 | Galileo E1B + GPS L2C
119  * 13 | Galileo E5a + GPS L5
120  * 14 | Galileo E1B + Galileo E5a
121  * 15 | Galileo E1B + Galileo E5b
122  * 16 | GPS L2C + GPS L5
123  * 17 | GPS L2C + Galileo E5a
124  * 20 | GPS L5 + Galileo E5b
125  * 21 | GPS L1 C/A + Galileo E1B + GPS L2C
126  * 22 | GPS L1 C/A + Galileo E1B + GPS L5
127  * 23 | GLONASS L1 C/A
128  * 24 | GLONASS L2 C/A
129  * 25 | GLONASS L1 C/A + GLONASS L2 C/A
130  * 26 | GPS L1 C/A + GLONASS L1 C/A
131  * 27 | Galileo E1B + GLONASS L1 C/A
132  * 28 | GPS L2C + GLONASS L1 C/A
133  * 29 | GPS L1 C/A + GLONASS L2 C/A
134  * 30 | Galileo E1B + GLONASS L2 C/A
135  * 31 | GPS L2C + GLONASS L2 C/A
136  * 32 | GPS L1 C/A + Galileo E1B + GPS L5 + Galileo E5a
137  * 33 | GPS L1 C/A + Galileo E1B + Galileo E5a
138  * 100 | Galileo E6B
139  * 101 | Galileo E1B + Galileo E6B
140  * 102 | Galileo E5a + Galileo E6B
141  * 103 | Galileo E5b + Galileo E6B
142  * 104 | Galileo E1B + Galileo E5a + Galileo E6B
143  * 105 | Galileo E1B + Galileo E5b + Galileo E6B
144  * 106 | GPS L1 C/A + Galileo E1B + Galileo E6B
145  * 500 | BeiDou B1I
146  * 501 | BeiDou B1I + GPS L1 C/A
147  * 502 | BeiDou B1I + Galileo E1B
148  * 503 | BeiDou B1I + GLONASS L1 C/A
149  * 504 | BeiDou B1I + GPS L1 C/A + Galileo E1B
150  * 505 | BeiDou B1I + GPS L1 C/A + GLONASS L1 C/A + Galileo E1B
151  * 506 | BeiDou B1I + Beidou B3I
152  * 600 | BeiDou B3I
153  * 601 | BeiDou B3I + GPS L2C
154  * 602 | BeiDou B3I + GLONASS L2 C/A
155  * 603 | BeiDou B3I + GPS L2C + GLONASS L2 C/A
156  * 604 | BeiDou B3I + GPS L1 C/A
157  * 605 | BeiDou B3I + Galileo E1B
158  * 606 | BeiDou B3I + GLONASS L1 C/A
159  * 607 | BeiDou B3I + GPS L1 C/A + Galileo E1B
160  * 608 | BeiDou B3I + GPS L1 C/A + Galileo E1B + BeiDou B1I
161  * 609 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A
162  * 610 | BeiDou B3I + GPS L1 C/A + Galileo E1B + GLONASS L1 C/A + BeiDou B1I
163  * 1000 | GPS L1 C/A + GPS L2C + GPS L5
164  * 1001 | GPS L1 C/A + Galileo E1B + GPS L2C + GPS L5 + Galileo E5a
165  *
166  */
167  void print_rinex_annotation(const Rtklib_Solver* pvt_solver,
168  const std::map<int, Gnss_Synchro>& gnss_observables_map,
169  double rx_time,
170  int type_of_rx,
171  bool flag_write_RINEX_obs_output);
172 
173  /*!
174  * \brief Print RINEX annotation for GPS NAV message
175  */
176  void log_rinex_nav_gps_nav(int type_of_rx,
177  const std::map<int32_t, Gps_Ephemeris>& new_eph);
178 
179  /*!
180  * \brief Print RINEX annotation for GPS CNAV message
181  */
182  void log_rinex_nav_gps_cnav(int type_of_rx,
183  const std::map<int32_t, Gps_CNAV_Ephemeris>& new_cnav_eph);
184 
185  /*!
186  * \brief Print RINEX annotation for Galileo NAV message
187  */
188  void log_rinex_nav_gal_nav(int type_of_rx,
189  const std::map<int32_t, Galileo_Ephemeris>& new_gal_eph);
190 
191  /*!
192  * \brief Print RINEX annotation for Glonass GNAV message
193  */
194  void log_rinex_nav_glo_gnav(int type_of_rx,
195  const std::map<int32_t, Glonass_Gnav_Ephemeris>& new_glo_eph);
196 
197  /*!
198  * \brief Print RINEX annotation for BeiDou DNAV message
199  */
200  void log_rinex_nav_bds_dnav(int type_of_rx,
201  const std::map<int32_t, Beidou_Dnav_Ephemeris>& new_bds_eph);
202 
203  /*!
204  * \brief Set processing for signals older than 2009
205  */
206  void set_pre_2009_file(bool pre_2009_file);
207 
208  /*!
209  * \brief Returns true is the RINEX file headers are already written
210  */
211  inline bool is_rinex_header_written() const
212  {
213  return d_rinex_header_written;
214  }
215 
216  /*!
217  * \brief Returns name of RINEX navigation file(s)
218  */
219  inline std::vector<std::string> get_navfilename() const
220  {
221  return output_navfilename;
222  }
223 
224  /*!
225  * \brief Returns name of RINEX observation file
226  */
227  inline std::string get_obsfilename() const
228  {
229  return obsfilename;
230  }
231 
232 
233 private:
234  /*
235  * Generates the GPS Observation data header
236  */
237  void rinex_obs_header(std::fstream& out,
238  const Gps_Ephemeris& eph,
239  double d_TOW_first_observation);
240 
241  /*
242  * Generates the GPS L2 Observation data header
243  */
244  void rinex_obs_header(std::fstream& out,
245  const Gps_CNAV_Ephemeris& eph,
246  double d_TOW_first_observation,
247  const std::string& gps_bands = "2S");
248 
249  /*
250  * Generates the dual frequency GPS L1 & L2/L5 Observation data header
251  */
252  void rinex_obs_header(std::fstream& out,
253  const Gps_Ephemeris& eph,
254  const Gps_CNAV_Ephemeris& eph_cnav,
255  double d_TOW_first_observation,
256  const std::string& gps_bands = "1C 2S");
257 
258  /*
259  * Generates the Galileo Observation data header.
260  * Example: bands("1B"), bands("1B 5X"), bands("5X"), ... Default: "1B".
261  */
262  void rinex_obs_header(std::fstream& out,
263  const Galileo_Ephemeris& eph,
264  double d_TOW_first_observation,
265  const std::string& bands = "1B");
266 
267  /*
268  * Generates the Mixed (GPS/Galileo) Observation data header.
269  * Example: galileo_bands("1B"), galileo_bands("1B 5X"),
270  * galileo_bands("5X"), ... Default: "1B".
271  */
272  void rinex_obs_header(std::fstream& out,
273  const Gps_Ephemeris& gps_eph,
274  const Galileo_Ephemeris& galileo_eph,
275  double d_TOW_first_observation,
276  const std::string& galileo_bands = "1B");
277 
278  /*
279  * Generates the Mixed (GPS/Galileo) Observation data header.
280  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
281  */
282  void rinex_obs_header(std::fstream& out,
283  const Gps_Ephemeris& gps_eph,
284  const Gps_CNAV_Ephemeris& eph_cnav,
285  const Galileo_Ephemeris& galileo_eph,
286  double d_TOW_first_observation,
287  const std::string& gps_bands = "1C 2S",
288  const std::string& galileo_bands = "1B");
289 
290  /*
291  * Generates the Mixed (GPS/Galileo) Observation data header.
292  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
293  */
294  void rinex_obs_header(std::fstream& out,
295  const Gps_CNAV_Ephemeris& eph_cnav,
296  const Galileo_Ephemeris& galileo_eph,
297  double d_TOW_first_observation,
298  const std::string& gps_bands = "2S",
299  const std::string& galileo_bands = "1B");
300 
301  /*
302  * Generates the GLONASS GNAV Observation data header.
303  * Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C".
304  */
305  void rinex_obs_header(std::fstream& out,
306  const Glonass_Gnav_Ephemeris& eph,
307  double d_TOW_first_observation,
308  const std::string& bands = "1G");
309 
310  /*
311  * Generates the Mixed (GPS L1 C/A /GLONASS) Observation data header.
312  * Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
313  */
314  void rinex_obs_header(std::fstream& out,
315  const Gps_Ephemeris& gps_eph,
316  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
317  double d_TOW_first_observation,
318  const std::string& glonass_bands = "1C");
319 
320  /*
321  * Generates the Mixed (Galileo/GLONASS) Observation data header.
322  * Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
323  */
324  void rinex_obs_header(std::fstream& out,
325  const Galileo_Ephemeris& galileo_eph,
326  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
327  double d_TOW_first_observation,
328  const std::string& galileo_bands = "1B",
329  const std::string& glonass_bands = "1C");
330 
331  /*
332  * Generates the Mixed (GPS L2C/GLONASS) Observation data header.
333  * Example: galileo_bands("1G")... Default: "1G".
334  */
335  void rinex_obs_header(std::fstream& out,
336  const Gps_CNAV_Ephemeris& gps_cnav_eph,
337  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
338  double d_TOW_first_observation,
339  const std::string& glonass_bands = "1G");
340 
341  /*
342  * Generates the a Beidou B1I Observation data header. Example: beidou_bands("B1")
343  */
344  void rinex_obs_header(std::fstream& out,
345  const Beidou_Dnav_Ephemeris& eph,
346  double d_TOW_first_observation,
347  const std::string& bands);
348 
349  /*
350  * Generates the SBAS raw data header
351  */
352  void rinex_sbs_header(std::fstream& out) const;
353 
354  /*
355  * Writes GPS L1 observables into the RINEX file
356  */
357  void log_rinex_obs(std::fstream& out,
358  const Gps_Ephemeris& eph,
359  double obs_time,
360  const std::map<int32_t, Gnss_Synchro>& observables) const;
361 
362  /*
363  * Writes GPS L2 observables into the RINEX file
364  */
365  void log_rinex_obs(std::fstream& out,
366  const Gps_CNAV_Ephemeris& eph,
367  double obs_time,
368  const std::map<int32_t, Gnss_Synchro>& observables) const;
369 
370  /*
371  * Writes dual frequency GPS L1 and L2 observables into the RINEX file
372  */
373  void log_rinex_obs(std::fstream& out,
374  const Gps_Ephemeris& eph,
375  const Gps_CNAV_Ephemeris& eph_cnav,
376  double obs_time,
377  const std::map<int32_t, Gnss_Synchro>& observables,
378  bool triple_band = false) const;
379 
380  /*
381  * Writes Galileo observables into the RINEX file.
382  * Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
383  */
384  void log_rinex_obs(std::fstream& out,
385  const Galileo_Ephemeris& eph,
386  double obs_time,
387  const std::map<int32_t, Gnss_Synchro>& observables,
388  const std::string& galileo_bands = "1B") const;
389 
390  /*
391  * Writes Mixed GPS / Galileo observables into the RINEX file
392  */
393  void log_rinex_obs(std::fstream& out,
394  const Gps_Ephemeris& gps_eph,
395  const Galileo_Ephemeris& galileo_eph,
396  double gps_obs_time,
397  const std::map<int32_t, Gnss_Synchro>& observables) const;
398 
399  /*
400  * Writes Mixed GPS / Galileo observables into the RINEX file
401  */
402  void log_rinex_obs(std::fstream& out,
403  const Gps_CNAV_Ephemeris& eph,
404  const Galileo_Ephemeris& galileo_eph,
405  double gps_obs_time,
406  const std::map<int32_t, Gnss_Synchro>& observables) const;
407 
408  /*
409  * Writes Mixed GPS / Galileo observables into the RINEX file
410  */
411  void log_rinex_obs(std::fstream& out,
412  const Gps_Ephemeris& gps_eph,
413  const Gps_CNAV_Ephemeris& gps_cnav_eph,
414  const Galileo_Ephemeris& galileo_eph,
415  double gps_obs_time,
416  const std::map<int32_t, Gnss_Synchro>& observables,
417  bool triple_band = false) const;
418 
419  /*
420  * Writes GLONASS GNAV observables into the RINEX file.
421  * Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B".
422  */
423  void log_rinex_obs(std::fstream& out,
424  const Glonass_Gnav_Ephemeris& eph,
425  double obs_time,
426  const std::map<int32_t, Gnss_Synchro>& observables,
427  const std::string& glonass_bands = "1C") const;
428 
429  /*
430  * Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file
431  */
432  void log_rinex_obs(std::fstream& out,
433  const Gps_Ephemeris& gps_eph,
434  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
435  double gps_obs_time,
436  const std::map<int32_t, Gnss_Synchro>& observables) const;
437 
438  /*
439  * Writes Mixed GPS L2C - GLONASS observables into the RINEX file
440  */
441  void log_rinex_obs(std::fstream& out,
442  const Gps_CNAV_Ephemeris& gps_eph,
443  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
444  double gps_obs_time,
445  const std::map<int32_t, Gnss_Synchro>& observables) const;
446 
447  /*
448  * Writes Mixed Galileo/GLONASS observables into the RINEX file
449  */
450  void log_rinex_obs(std::fstream& out,
451  const Galileo_Ephemeris& galileo_eph,
452  const Glonass_Gnav_Ephemeris& glonass_gnav_eph,
453  double galileo_obs_time,
454  const std::map<int32_t, Gnss_Synchro>& observables) const;
455 
456  /*
457  * Writes BDS B1I observables into the RINEX file
458  */
459  void log_rinex_obs(std::fstream& out,
460  const Beidou_Dnav_Ephemeris& eph,
461  double obs_time,
462  const std::map<int32_t, Gnss_Synchro>& observables,
463  const std::string& bds_bands) const;
464 
465  /*
466  * Generates the GPS L1 C/A Navigation Data header
467  */
468  void rinex_nav_header(std::fstream& out,
469  const Gps_Iono& iono,
470  const Gps_Utc_Model& utc_model,
471  const Gps_Ephemeris& eph) const;
472 
473  /*
474  * Generates the GPS L2C(M) Navigation Data header
475  */
476  void rinex_nav_header(std::fstream& out,
477  const Gps_CNAV_Iono& iono,
478  const Gps_CNAV_Utc_Model& utc_model) const;
479 
480  /*
481  * Generates the Galileo Navigation Data header
482  */
483  void rinex_nav_header(std::fstream& out,
484  const Galileo_Iono& iono,
485  const Galileo_Utc_Model& utc_model) const;
486 
487  /*
488  * Generates the Mixed (GPS/Galileo) Navigation Data header
489  */
490  void rinex_nav_header(std::fstream& out,
491  const Gps_Iono& gps_iono,
492  const Gps_Utc_Model& gps_utc_model,
493  const Gps_Ephemeris& eph,
494  const Galileo_Iono& galileo_iono,
495  const Galileo_Utc_Model& galileo_utc_model) const;
496 
497  /*
498  * Generates the Mixed (GPS CNAV/Galileo) Navigation Data header
499  */
500  void rinex_nav_header(std::fstream& out,
501  const Gps_CNAV_Iono& iono,
502  const Gps_CNAV_Utc_Model& utc_model,
503  const Galileo_Iono& galileo_iono,
504  const Galileo_Utc_Model& galileo_utc_model) const;
505 
506  /*
507  * Generates the GLONASS L1, L2 C/A Navigation Data header
508  */
509  void rinex_nav_header(std::fstream& out,
510  const Glonass_Gnav_Utc_Model& utc_model,
511  const Glonass_Gnav_Ephemeris& glonass_gnav_eph);
512 
513  /*
514  * Generates the Mixed (Galileo/GLONASS) Navigation Data header
515  */
516  void rinex_nav_header(std::fstream& out,
517  const Galileo_Iono& galileo_iono,
518  const Galileo_Utc_Model& galileo_utc_model,
519  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
520  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
521 
522  /*
523  * Generates the Mixed (GPS L1 C/A/GLONASS L1, L2) Navigation Data header
524  */
525  void rinex_nav_header(std::fstream& out,
526  const Gps_Iono& gps_iono,
527  const Gps_Utc_Model& gps_utc_model,
528  const Gps_Ephemeris& eph,
529  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
530  const Glonass_Gnav_Almanac& glonass_gnav_almanac);
531 
532  /*
533  * Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header
534  */
535  void rinex_nav_header(std::fstream& out,
536  const Gps_CNAV_Iono& gps_iono,
537  const Gps_CNAV_Utc_Model& gps_utc_model,
538  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
539  const Glonass_Gnav_Almanac& glonass_gnav_almanac);
540 
541  /*
542  * Generates the BDS B1I or B3I Navigation Data header
543  */
544  void rinex_nav_header(std::fstream& out,
545  const Beidou_Dnav_Iono& iono,
546  const Beidou_Dnav_Utc_Model& utc_model) const;
547 
548  /*
549  * Generates the Mixed GPS L1,L5 + BDS B1I, B3I Navigation Data header
550  */
551  void rinex_nav_header(std::fstream& out,
552  const Gps_Iono& gps_iono,
553  const Gps_Utc_Model& gps_utc_model,
554  const Gps_Ephemeris& eph,
555  const Beidou_Dnav_Iono& bds_dnav_iono,
556  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
557 
558  /*
559  * Generates the Mixed GPS L2C + BDS B1I, B3I Navigation Data header
560  */
561  void rinex_nav_header(std::fstream& out,
562  const Gps_CNAV_Iono& gps_cnav_iono,
563  const Gps_CNAV_Utc_Model& gps_cnav_utc_model,
564  const Beidou_Dnav_Iono& bds_dnav_iono,
565  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model);
566 
567  /*
568  * Generates the Mixed GLONASS L1,L2 + BDS B1I, B3I Navigation Data header
569  */
570  void rinex_nav_header(std::fstream& out,
571  const Glonass_Gnav_Utc_Model& glo_gnav_utc_model,
572  const Beidou_Dnav_Iono& bds_dnav_iono,
573  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
574 
575  /*
576  * Generates the Mixed (Galileo/BDS B1I, B3I) Navigation Data header
577  */
578  void rinex_nav_header(std::fstream& out,
579  const Galileo_Iono& galileo_iono,
580  const Galileo_Utc_Model& galileo_utc_model,
581  const Beidou_Dnav_Iono& bds_dnav_iono,
582  const Beidou_Dnav_Utc_Model& bds_dnav_utc_model) const;
583 
584  /*
585  * Writes data from the GPS L1 C/A navigation message into the RINEX file
586  */
587  void log_rinex_nav(std::fstream& out,
588  const std::map<int32_t, Gps_Ephemeris>& eph_map) const;
589 
590  /*
591  * Writes data from the GPS L2 navigation message into the RINEX file
592  */
593  void log_rinex_nav(std::fstream& out,
594  const std::map<int32_t, Gps_CNAV_Ephemeris>& eph_map);
595 
596  /*
597  * Writes data from the Galileo navigation message into the RINEX file
598  */
599  void log_rinex_nav(std::fstream& out,
600  const std::map<int32_t, Galileo_Ephemeris>& eph_map) const;
601 
602  /*
603  * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
604  */
605  void log_rinex_nav(std::fstream& out,
606  const std::map<int32_t, Gps_Ephemeris>& gps_eph_map,
607  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map);
608 
609  /*
610  * Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file
611  */
612  void log_rinex_nav(std::fstream& out,
613  const std::map<int32_t, Gps_CNAV_Ephemeris>& gps_cnav_eph_map,
614  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map);
615 
616  /*
617  * Writes data from the GLONASS GNAV navigation message into the RINEX file
618  */
619  void log_rinex_nav(std::fstream& out,
620  const std::map<int32_t, Glonass_Gnav_Ephemeris>& eph_map) const;
621 
622  /*
623  * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
624  */
625  void log_rinex_nav(std::fstream& out,
626  const std::map<int32_t, Gps_Ephemeris>& gps_eph_map,
627  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map) const;
628 
629  /*
630  * Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file
631  */
632  void log_rinex_nav(std::fstream& out,
633  const std::map<int32_t, Gps_CNAV_Ephemeris>& gps_cnav_eph_map,
634  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
635 
636  /*
637  * Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file
638  */
639  void log_rinex_nav(std::fstream& out,
640  const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map,
641  const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
642 
643  /*
644  * Writes data from the Beidou B1I navigation message into the RINEX file
645  */
646  void log_rinex_nav(std::fstream& out,
647  const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map) const;
648 
649  /*
650  * Computes the BDS Time and returns a boost::posix_time::ptime object
651  * \details Function used to convert the observation time into BDT time which is used
652  * as the default time for RINEX files
653  * \param eph BeiDou DNAV Ephemeris object
654  * \param obs_time Observation time in BDT seconds of week
655  */
656  boost::posix_time::ptime compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, double obs_time) const;
657 
658  /*
659  * Computes the UTC time and returns a boost::posix_time::ptime object
660  */
661  boost::posix_time::ptime compute_UTC_time(const Gps_Navigation_Message& nav_msg) const;
662 
663  /*
664  * Computes the GPS time and returns a boost::posix_time::ptime object
665  */
666  boost::posix_time::ptime compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const;
667 
668  /*
669  * Computes the GPS time and returns a boost::posix_time::ptime object
670  */
671  boost::posix_time::ptime compute_GPS_time(const Gps_CNAV_Ephemeris& eph, double obs_time) const;
672 
673  /*
674  * Computes the Galileo time and returns a boost::posix_time::ptime object
675  */
676  boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const;
677 
678  /*
679  * Computes the UTC Time and returns a boost::posix_time::ptime object
680  * \details Function used as a method to convert the observation time into UTC time which is used
681  * as the default time for RINEX files
682  * \param eph GLONASS GNAV Ephemeris object
683  * \param obs_time Observation time in GPS seconds of week
684  */
685  boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, double obs_time) const;
686 
687  /*
688  * Computes number of leap seconds of GPS relative to UTC
689  * \param eph GLONASS GNAV Ephemeris object
690  * \param gps_obs_time Observation time in GPS seconds of week
691  */
692  double get_leap_second(const Glonass_Gnav_Ephemeris& eph, double gps_obs_time) const;
693 
694  /*
695  * Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
696  */
697  void to_date_time(int gps_week,
698  int gps_tow,
699  int& year,
700  int& month,
701  int& day,
702  int& hour,
703  int& minute,
704  int& second) const;
705 
706  /*
707  * Writes raw SBAS messages into the RINEX file
708  */
709  // void log_rinex_sbs(std::fstream & out, const Sbas_Raw_Msg & sbs_message);
710 
711  void update_nav_header(std::fstream& out,
712  const Gps_Utc_Model& utc_model,
713  const Gps_Iono& gps_iono, const Gps_Ephemeris& eph) const;
714 
715  void update_nav_header(std::fstream& out,
716  const Gps_CNAV_Utc_Model& utc_model,
717  const Gps_CNAV_Iono& iono) const;
718 
719  void update_nav_header(std::fstream& out,
720  const Gps_Iono& gps_iono,
721  const Gps_Utc_Model& gps_utc_model,
722  const Gps_Ephemeris& eph,
723  const Galileo_Iono& galileo_iono,
724  const Galileo_Utc_Model& galileo_utc_model) const;
725 
726  void update_nav_header(std::fstream& out,
727  const Gps_CNAV_Utc_Model& utc_model,
728  const Gps_CNAV_Iono& iono,
729  const Galileo_Iono& galileo_iono,
730  const Galileo_Utc_Model& galileo_utc_model) const;
731 
732  void update_nav_header(std::fstream& out,
733  const Galileo_Iono& galileo_iono,
734  const Galileo_Utc_Model& utc_model) const;
735 
736  void update_nav_header(std::fstream& out,
737  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
738  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
739 
740  void update_nav_header(std::fstream& out,
741  const Gps_Iono& gps_iono,
742  const Gps_Utc_Model& gps_utc,
743  const Gps_Ephemeris& eph,
744  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
745  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
746 
747  void update_nav_header(std::fstream& out,
748  const Gps_CNAV_Iono& gps_iono,
749  const Gps_CNAV_Utc_Model& gps_utc_model,
750  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
751  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
752 
753  void update_nav_header(std::fstream& out,
754  const Galileo_Iono& galileo_iono,
755  const Galileo_Utc_Model& galileo_utc_model,
756  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model,
757  const Glonass_Gnav_Almanac& glonass_gnav_almanac) const;
758 
759  void update_nav_header(std::fstream& out,
760  const Beidou_Dnav_Utc_Model& utc_model,
761  const Beidou_Dnav_Iono& beidou_dnav_iono) const;
762 
763  void update_obs_header(std::fstream& out,
764  const Gps_Utc_Model& utc_model) const;
765 
766  void update_obs_header(std::fstream& out,
767  const Gps_CNAV_Utc_Model& utc_model) const;
768 
769  void update_obs_header(std::fstream& out,
770  const Galileo_Utc_Model& galileo_utc_model) const;
771 
772  void update_obs_header(std::fstream& out,
773  const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) const;
774 
775  void update_obs_header(std::fstream& out,
776  const Beidou_Dnav_Utc_Model& utc_model) const;
777 
778  /*
779  * Generation of RINEX signal strength indicators
780  */
781  int signalStrength(double snr) const;
782 
783  /* Creates RINEX file names according to the naming convention
784  *
785  * See ftp://igs.org/pub/data/format/rinex301.pdf
786  * Section 4, page 6
787  *
788  * \param[in] type of RINEX file. Can be:
789  * "RINEX_FILE_TYPE_OBS" - Observation file.
790  * "RINEX_FILE_TYPE_GPS_NAV" - GPS navigation message file.
791  * "RINEX_FILE_TYPE_MET" - Meteorological data file.
792  * "RINEX_FILE_TYPE_GLO_NAV" - GLONASS navigation file.
793  * "RINEX_FILE_TYPE_GAL_NAV" - Galileo navigation message file.
794  * "RINEX_FILE_TYPE_MIXED_NAV" - Mixed GNSS navigation message file.
795  * "RINEX_FILE_TYPE_GEO_NAV" - SBAS Payload navigation message file.
796  * "RINEX_FILE_TYPE_SBAS" - SBAS broadcast data file.
797  * "RINEX_FILE_TYPE_CLK" - Clock file.
798  */
799  std::string createFilename(const std::string& type, const std::string& base_name) const;
800 
801  /*
802  * Generates the data for the PGM / RUN BY / DATE line
803  */
804  std::string getLocalTime() const;
805 
806  /*
807  * Checks that the line is 80 characters length
808  */
809  void lengthCheck(const std::string& line) const;
810 
811  /*
812  * If the string is bigger than length, truncate it from the right.
813  * otherwise, add pad characters to its right.
814  *
815  * Left-justifies the input in a string of the specified
816  * length. If the new length (\a length) is larger than the
817  * current length, the string is extended by the pad
818  * character (\a pad). The default pad character is a
819  * blank.
820  * \param[in] s string to be modified.
821  * \param[in] length new desired length of string.
822  * \param[in] pad character to pad string with (blank by default).
823  * \return a reference to \a s. */
824  inline std::string& leftJustify(std::string& s,
825  std::string::size_type length,
826  char pad = ' ') const;
827 
828  /*
829  * If the string is bigger than length, truncate it from the right.
830  * otherwise, add pad characters to its right.
831  *
832  * Left-justifies the receiver in a string of the specified
833  * length (const version). If the new length (\a length) is larger
834  * than the current length, the string is extended by the pad
835  * character (\a pad). The default pad character is a
836  * blank.
837  * \param[in] s string to be modified.
838  * \param[in] length new desired length of string.
839  * \param[in] pad character to pad string with (blank by default).
840  * \return a reference to \a s. */
841  inline std::string leftJustify(const std::string& s,
842  std::string::size_type length,
843  char pad = ' ') const
844  {
845  std::string t(s);
846  return leftJustify(t, length, pad);
847  }
848 
849 
850  /*
851  * Right-justifies the receiver in a string of the specified
852  * length. If the receiver's data is shorter than the
853  * requested length (\a length), it is padded on the left with
854  * the pad character (\a pad). The default pad
855  * character is a blank. */
856  inline std::string& rightJustify(std::string& s,
857  std::string::size_type length,
858  char pad = ' ') const;
859 
860  /*
861  * Right-justifies the receiver in a string of the specified
862  * length (const version). If the receiver's data is shorter than the
863  * requested length (\a length), it is padded on the left with
864  * the pad character (\a pad). The default pad
865  * character is a blank.*/
866  inline std::string rightJustify(const std::string& s,
867  std::string::size_type length,
868  char pad = ' ') const
869  {
870  std::string t(s);
871  return rightJustify(t, length, pad);
872  }
873 
874 
875  /*
876  * Convert a double to a scientific notation number.
877  * @param d the double to convert
878  * @param length length (in characters) of output, including exponent
879  * @param expLen length (in characters) of the exponent, with sign
880  * @param showSign if true, reserves 1 character for +/- sign
881  * @param checkSwitch if true, keeps the exponential sanity check for
882  * exponentials above three characters in length. If false, it removes
883  * that check.
884  */
885  inline std::string doub2sci(double d,
886  std::string::size_type length,
887  std::string::size_type expLen,
888  bool showSign = true,
889  bool checkSwitch = true) const;
890 
891 
892  /*
893  * Convert scientific notation to FORTRAN notation.
894  * As an example, the string "1.5636E5" becomes " .15636D6".
895  * Note that the first character of the string will be '-' if
896  * the number is negative or ' ' if the first character is positive.
897  * @param aStr string with number to convert
898  * @param startPos start position of number in string
899  * @param length length (in characters) of number, including exponent.
900  * @param expLen length (in characters of exponent, not including sign.
901  * @param checkSwitch will keep the method running as originally programmed
902  * when set to true. If false, the method will always resize exponentials,
903  * produce an exponential with an E instead of a D, and always have a leading
904  * zero. For example -> 0.87654E-0004 or -0.1234E00005.
905  */
906  inline std::string& sci2for(std::string& aStr,
907  std::string::size_type startPos = 0,
908  std::string::size_type length = std::string::npos,
909  std::string::size_type expLen = 3,
910  bool checkSwitch = true) const;
911 
912 
913  /*
914  * Convert double precision floating point to a string
915  * containing the number in FORTRAN notation.
916  * As an example, the number 156360 becomes ".15636D6".
917  * @param d number to convert.
918  * @param length length (in characters) of number, including exponent.
919  * @param expLen length (in characters of exponent, including sign.
920  * @param checkSwitch if true, keeps the exponential sanity check for
921  * exponentials above three characters in length. If false, it removes
922  * that check.
923  * @return a string containing \a d in FORTRAN notation.
924  */
925  inline std::string doub2for(double d,
926  std::string::size_type length,
927  std::string::size_type expLen,
928  bool checkSwitch = true) const;
929 
930 
931  /*
932  * Convert a string to a double precision floating point number.
933  * @param s string containing a number.
934  * @return double representation of string.
935  */
936  inline double asDouble(const std::string& s) const
937  {
938  return strtod(s.c_str(), nullptr);
939  }
940 
941 
942  inline int toInt(const std::string& bitString, int sLength) const;
943 
944  /*
945  * Convert a string to an integer.
946  * @param s string containing a number.
947  * @return int64_t integer representation of string.
948  */
949  inline int64_t asInt(const std::string& s) const
950  {
951  return strtol(s.c_str(), nullptr, 10);
952  }
953 
954 
955  /*
956  * Convert a double to a string in fixed notation.
957  * @param x double.
958  * @param precision the number of decimal places you want displayed.
959  * @return string representation of \a x.
960  */
961  inline std::string asString(double x,
962  std::string::size_type precision = 17) const;
963 
964 
965  /*
966  * Convert a long double to a string in fixed notation.
967  * @param x long double.
968  * @param precision the number of decimal places you want displayed.
969  * @return string representation of \a x.
970  */
971  inline std::string asString(long double x,
972  std::string::size_type precision = 21) const;
973 
974 
975  /*
976  * Convert any old object to a string.
977  * The class must have stream operators defined.
978  * @param x object to turn into a string.
979  * @return string representation of \a x.
980  */
981  template <class X>
982  inline std::string asString(const X x) const;
983 
984  inline std::string asFixWidthString(int x, int width, char fill_digit) const;
985 
986  std::map<std::string, std::string> satelliteSystem; // GPS, GLONASS, SBAS payload, Galileo or Beidou
987  std::map<std::string, std::string> observationType; // PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
988  std::map<std::string, std::string> observationCode; // GNSS observation descriptors
989 
990  std::fstream obsFile; // Output file stream for RINEX observation file
991  std::fstream navFile; // Output file stream for RINEX navigation data file
992  std::fstream sbsFile; // Output file stream for RINEX SBAS raw data file
993  std::fstream navGalFile; // Output file stream for RINEX Galileo navigation data file
994  std::fstream navGloFile; // Output file stream for RINEX GLONASS navigation data file
995  std::fstream navBdsFile; // Output file stream for RINEX Galileo navigation data file
996  std::fstream navMixFile; // Output file stream for RINEX Mixed navigation data file
997 
998  std::string navfilename; // Name of RINEX navigation file for GPS L1
999  std::string obsfilename; // Name of RINEX observation file
1000  std::string sbsfilename; // Name of RINEX SBAS file
1001  std::string navGalfilename; // Name of RINEX navigation file for Galileo
1002  std::string navGlofilename; // Name of RINEX navigation file for Glonass
1003  std::string navBdsfilename; // Name of RINEX navigation file for BeiDou
1004  std::string navMixfilename; // Name of RINEX navigation file for fixed signals
1005  std::vector<std::string> output_navfilename; // Name of output RINEX navigation file(s)
1006 
1007  std::string d_stringVersion; // RINEX version (2.10/2.11 or 3.01/3.02)
1008 
1009  double d_fake_cnav_iode;
1010  int d_version; // RINEX version (2 for 2.10/2.11 and 3 for 3.01)
1011  int d_numberTypesObservations; // Number of available types of observable in the system. Should be public?
1012  bool d_rinex_header_updated;
1013  bool d_rinex_header_written;
1014  bool d_pre_2009_file;
1015 };
1016 
1017 
1018 // Implementation of inline functions (modified versions from GPSTk https://github.com/SGL-UT/GPSTk)
1019 
1020 inline std::string& Rinex_Printer::leftJustify(std::string& s,
1021  std::string::size_type length,
1022  char pad) const
1023 {
1024  if (length < s.length())
1025  {
1026  s = s.substr(0, length);
1027  }
1028  else
1029  {
1030  s.append(length - s.length(), pad);
1031  }
1032  return s;
1033 }
1034 
1035 
1036 // if the string is bigger than length, truncate it from the left.
1037 // otherwise, add pad characters to its left.
1038 inline std::string& Rinex_Printer::rightJustify(std::string& s,
1039  std::string::size_type length,
1040  char pad) const
1041 {
1042  if (length < s.length())
1043  {
1044  s = s.substr(s.length() - length, std::string::npos);
1045  }
1046  else
1047  {
1048  s.insert(static_cast<std::string::size_type>(0), length - s.length(), pad);
1049  }
1050  return s;
1051 }
1052 
1053 
1054 inline std::string Rinex_Printer::doub2for(double d,
1055  std::string::size_type length,
1056  std::string::size_type expLen,
1057  bool checkSwitch) const
1058 {
1059  int16_t exponentLength = expLen;
1060 
1061  /* Validate the assumptions regarding the input arguments */
1062  if (exponentLength < 0)
1063  {
1064  exponentLength = 1;
1065  }
1066 
1067  if (exponentLength > 3 && checkSwitch)
1068  {
1069  exponentLength = 3;
1070  }
1071 
1072  std::string toReturn = doub2sci(d, length, exponentLength, true, checkSwitch);
1073  sci2for(toReturn, 0, length, exponentLength, checkSwitch);
1074 
1075  return toReturn;
1076 }
1077 
1078 
1079 inline std::string Rinex_Printer::doub2sci(double d,
1080  std::string::size_type length,
1081  std::string::size_type expLen,
1082  bool showSign,
1083  bool checkSwitch) const
1084 {
1085  std::string toReturn;
1086  int16_t exponentLength = expLen;
1087 
1088  /* Validate the assumptions regarding the input arguments */
1089  if (exponentLength < 0)
1090  {
1091  exponentLength = 1;
1092  }
1093 
1094  if (exponentLength > 3 && checkSwitch)
1095  {
1096  exponentLength = 3;
1097  }
1098 
1099  std::stringstream c;
1100  c.setf(std::ios::scientific, std::ios::floatfield);
1101 
1102  // length - 3 for special characters ('.', 'e', '+' or '-')
1103  // - exponentlength (e04)
1104  // - 1 for the digit before the decimal (2.)
1105  // and if showSign == true,
1106  // an extra -1 for '-' or ' ' if it's positive or negative
1107  int expSize = 0;
1108  if (showSign)
1109  {
1110  expSize = 1;
1111  }
1112 
1113  c.precision(length - 3 - exponentLength - 1 - expSize);
1114  c << d;
1115  c >> toReturn;
1116  return toReturn;
1117 }
1118 
1119 
1120 inline std::string& Rinex_Printer::sci2for(std::string& aStr,
1121  std::string::size_type startPos,
1122  std::string::size_type length,
1123  std::string::size_type expLen,
1124  bool checkSwitch) const
1125 {
1126  std::string::size_type idx = aStr.find('.', startPos);
1127  int expAdd = 0;
1128  std::string exp;
1129  int64_t iexp;
1130  // If checkSwitch is false, always redo the exponential. Otherwise,
1131  // set it to false.
1132  bool redoexp = !checkSwitch;
1133 
1134  // Check for decimal place within specified boundaries
1135  if ((idx <= 0) || (idx >= (startPos + length - expLen - 1)))
1136  {
1137  // Error: no decimal point in string
1138  return aStr;
1139  }
1140 
1141  // Here, account for the possibility that there are
1142  // no numbers to the left of the decimal, but do not
1143  // account for the possibility of non-scientific
1144  // notation (more than one digit to the left of the
1145  // decimal)
1146  if (idx > startPos)
1147  {
1148  redoexp = true;
1149  // Swap digit and decimal.
1150  aStr[idx] = aStr[idx - 1];
1151  aStr[idx - 1] = '.';
1152  // Only add one to the exponent if the number is non-zero
1153  if (asDouble(aStr.substr(startPos, length)) != 0.0)
1154  {
1155  expAdd = 1;
1156  }
1157  }
1158 
1159  idx = aStr.find('e', startPos);
1160  if (idx == std::string::npos)
1161  {
1162  idx = aStr.find('E', startPos);
1163  if (idx == std::string::npos)
1164  {
1165  // Error: no 'e' or 'E' in string";
1166  }
1167  }
1168 
1169  // Change the exponent character to D normally, or E of checkSwitch is false.
1170  if (checkSwitch)
1171  {
1172  aStr[idx] = 'D';
1173  }
1174  else
1175  {
1176  aStr[idx] = 'E';
1177  }
1178 
1179  // Change the exponent itself
1180  if (redoexp)
1181  {
1182  exp = aStr.substr(idx + 1, std::string::npos);
1183  iexp = asInt(exp);
1184  iexp += expAdd;
1185 
1186  aStr.erase(idx + 1);
1187  if (iexp < 0)
1188  {
1189  aStr += "-";
1190  iexp -= iexp * 2;
1191  }
1192  else
1193  {
1194  aStr += "+";
1195  }
1196 
1197  aStr += Rinex_Printer::rightJustify(asString(iexp), expLen, '0');
1198  }
1199 
1200  // if the number is positive, append a space
1201  // (if it's negative, there's a leading '-'
1202  if (aStr[0] == '.')
1203  {
1204  aStr.insert(static_cast<std::string::size_type>(0), 1, ' ');
1205  }
1206 
1207  // If checkSwitch is false, add on one leading zero to the string
1208  if (!checkSwitch)
1209  {
1210  aStr.insert(static_cast<std::string::size_type>(1), 1, '0');
1211  }
1212 
1213  return aStr;
1214 } // end sci2for
1215 
1216 
1217 inline std::string asString(long double x, std::string::size_type precision)
1218 {
1219  std::ostringstream ss;
1220  ss << std::fixed << std::setprecision(precision) << x;
1221  return ss.str();
1222 }
1223 
1224 
1225 inline std::string Rinex_Printer::asString(double x, std::string::size_type precision) const
1226 {
1227  std::ostringstream ss;
1228  ss << std::fixed << std::setprecision(precision) << x;
1229  return ss.str();
1230 }
1231 
1232 
1233 inline std::string Rinex_Printer::asFixWidthString(int x, int width, char fill_digit) const
1234 {
1235  std::ostringstream ss;
1236  ss << std::setfill(fill_digit) << std::setw(width) << x;
1237  return ss.str().substr(ss.str().size() - width);
1238 }
1239 
1240 
1241 inline int64_t asInt(const std::string& s)
1242 {
1243  return strtol(s.c_str(), nullptr, 10);
1244 }
1245 
1246 
1247 inline int Rinex_Printer::toInt(const std::string& bitString, int sLength) const
1248 {
1249  int tempInt;
1250  int num = 0;
1251  for (int i = 0; i < sLength; i++)
1252  {
1253  tempInt = bitString[i] - '0';
1254  num |= (1 << (sLength - 1 - i)) * tempInt;
1255  }
1256  return num;
1257 }
1258 
1259 
1260 template <class X>
1261 inline std::string Rinex_Printer::asString(const X x) const
1262 {
1263  std::ostringstream ss;
1264  ss << x;
1265  return ss.str();
1266 }
1267 
1268 
1269 /** \} */
1270 /** \} */
1271 #endif // GNSS_SDR_RINEX_PRINTER_H
This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M. ...
Definition: gps_iono.h:35
std::string get_obsfilename() const
Returns name of RINEX observation file.
This is a storage class for the GPS CNAV ephemeris data as described in IS-GPS-200M.
This class is a storage for the BeiDou DNAV UTC Model.
This class is a storage and orbital model functions for the GPS SV ephemeris data as described in IS-...
Definition: gps_ephemeris.h:40
bool is_rinex_header_written() const
Returns true is the RINEX file headers are already written.
Rinex_Printer(int version=0, const std::string &base_path=".", const std::string &base_name="-")
Constructor. Creates GNSS Navigation and Observables RINEX files.
This class is a storage for the BEIDOU IONOSPHERIC data as described in ICD v2.1. ...
Class that handles the generation of Receiver INdependent EXchange format (RINEX) files...
Definition: rinex_printer.h:82
void print_rinex_annotation(const Rtklib_Solver *pvt_solver, const std::map< int, Gnss_Synchro > &gnss_observables_map, double rx_time, int type_of_rx, bool flag_write_RINEX_obs_output)
Print RINEX annotation. If it is the first annotation, it also prints the RINEX headers for navigatio...
This class is a storage and orbital model functions for the GLONASS SV ephemeris data as described in...
This class implements a PVT solution based on RTKLIB.
Definition: rtklib_solver.h:75
~Rinex_Printer()
Destructor. Removes created files if empty.
This is a storage class for the Beidou SV ephemeris data as described in BeiDou Navigation Satellite ...
This is the class that contains the information that is shared by the processing blocks.
Definition: gnss_synchro.h:38
void log_rinex_nav_gal_nav(int type_of_rx, const std::map< int32_t, Galileo_Ephemeris > &new_gal_eph)
Print RINEX annotation for Galileo NAV message.
void log_rinex_nav_gps_cnav(int type_of_rx, const std::map< int32_t, Gps_CNAV_Ephemeris > &new_cnav_eph)
Print RINEX annotation for GPS CNAV message.
void log_rinex_nav_gps_nav(int type_of_rx, const std::map< int32_t, Gps_Ephemeris > &new_eph)
Print RINEX annotation for GPS NAV message.
This class is a storage for the GPS UTC MODEL data as described in in IS-GPS-200M.
This class decodes a GPS NAV Data message as described in IS-GPS-200M.
This class is a storage for the GALILEO IONOSPHERIC data as described in Galileo ICD paragraph 5...
Definition: galileo_iono.h:37
void set_pre_2009_file(bool pre_2009_file)
Set processing for signals older than 2009.
This class is a storage and orbital model functions for the Galileo SV ephemeris data as described in...
This class is a storage for the GLONASS GNAV UTC MODEL data as described in GLONASS ICD (Edition 5...
This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200M.
Definition: gps_utc_model.h:35
This class is a storage for the GLONASS SV ALMANAC data as described GLONASS ICD (Edition 5...
void log_rinex_nav_glo_gnav(int type_of_rx, const std::map< int32_t, Glonass_Gnav_Ephemeris > &new_glo_eph)
Print RINEX annotation for Glonass GNAV message.
This class is a storage for the GALILEO UTC MODEL data as described in Galileo ICD https://www...
std::vector< std::string > get_navfilename() const
Returns name of RINEX navigation file(s)
This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M. ...
Definition: gps_cnav_iono.h:34
void log_rinex_nav_bds_dnav(int type_of_rx, const std::map< int32_t, Beidou_Dnav_Ephemeris > &new_bds_eph)
Print RINEX annotation for BeiDou DNAV message.