INSTINCT Code Coverage Report


Directory: src/
File: util/Vendor/RINEX/RINEXUtilities.cpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 292 452 64.6%
Functions: 32 35 91.4%
Branches: 324 660 49.1%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 #include "RINEXUtilities.hpp"
10
11 #include <sstream>
12 #include <locale>
13
14 #include <boost/date_time/posix_time/posix_time.hpp> // TODO: Remove 'boost.dateTime' from conan as soon as 'std::chrono::utc_clock' becomes available
15 #include <fmt/chrono.h>
16 #include <fmt/format.h>
17 using namespace fmt::literals; // NOLINT(google-build-using-namespace)
18
19 #include "internal/Version.hpp"
20 #include "Navigation/Math/Math.hpp"
21 #include "util/Logger.hpp"
22
23 namespace NAV
24 {
25 namespace vendor::RINEX
26 {
27
28 36 void ObsHeader::reset()
29 {
30 36 satSys = SatSys_None;
31 36 systemObsTypes.clear();
32 36 interval = 1e9;
33 36 timeFirstObs.reset();
34 36 timeLastObs.reset();
35 36 satellites.clear();
36 36 timeSys = TimeSys_None;
37 36 }
38
39 480715 bool ObsHeader::addObsType(const Code& code, ObsType type)
40 {
41
3/6
✓ Branch 1 taken 480715 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 480715 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 480715 times.
✗ Branch 8 not taken.
480715 auto& obsDescriptions = systemObsTypes[code.getFrequency().getSatSys()];
42
1/2
✓ Branch 1 taken 480715 times.
✗ Branch 2 not taken.
480715 if (std::ranges::find_if(obsDescriptions, [&code, &type](const auto& obsDesc) {
43
4/4
✓ Branch 1 taken 1147161 times.
✓ Branch 2 taken 1242543 times.
✓ Branch 3 taken 480196 times.
✓ Branch 4 taken 666965 times.
2389704 return obsDesc.code == code && obsDesc.type == type;
44 })
45
2/2
✓ Branch 2 taken 519 times.
✓ Branch 3 taken 480196 times.
961430 == obsDescriptions.end())
46 {
47
1/2
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
519 obsDescriptions.push_back(ObservationDescription{ .type = type, .code = code });
48 519 return true;
49 }
50 480196 return false;
51 }
52
53 49 std::string ObsHeader::generateHeader() const
54 {
55 49 std::string str;
56
57
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineRinexVersionType();
58
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLinePgmRunByDate();
59
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineComments();
60
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineMarkerName();
61
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineMarkerNumber();
62
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineMarkerType();
63
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineObserverAgency();
64
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineRecNumTypeVers();
65
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineAntNumType();
66
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineApproxPositionXYZ();
67
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineAntennaDeltaHEN();
68 // ANTENNA: DELTA X/Y/Z (optional)
69 // ANTENNA:PHASECENTER (optional)
70 // ANTENNA: B.SIGHT XYZ (optional)
71 // ANTENNA: ZERODIR AZI (optional)
72 // ANTENNA: ZERODIR XYZ (optional)
73 // CENTER OF MASS: XYZ (optional)
74
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineSysNumObsType();
75
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineSignalStrengthUnit();
76
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineInterval();
77
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineTimeOfFirstObs();
78
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineTimeOfLastObs();
79 // RCV CLOCK OFFS APPL (optional)
80 // SYS / DCBS APPLIED (optional)
81 // SYS / PCVS APPLIED (optional)
82 // SYS / SCALE FACTOR (optional)
83
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineSysPhaseShift();
84 // GLONASS SLOT / FRQ # (is mandatory, but a lot of receivers also do not write it. So we leave it out. Would require NAV information)
85
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineGlonassCodPhsBis();
86
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineLeapSeconds();
87
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineNumSatellites();
88 // PRN / # OF OBS (optional)
89
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 str += headerLineEndOfHeader();
90
91 49 return str;
92 }
93 61 std::string ObsHeader::headerLineRinexVersionType() const
94 {
95 61 std::string longSatSysString;
96
2/7
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 58 times.
61 switch (static_cast<SatelliteSystem_>(satSys))
97 {
98 case GPS:
99 longSatSysString = "GPS";
100 break;
101 case GAL:
102 longSatSysString = "GALILEO";
103 break;
104 3 case GLO:
105
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 longSatSysString = "GLONASS";
106 3 break;
107 case BDS:
108 longSatSysString = "BEIDOU";
109 break;
110 case QZSS:
111 longSatSysString = "QZSS";
112 break;
113 case IRNSS:
114 longSatSysString = "IRNSS";
115 break;
116 58 default:
117
1/2
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
58 longSatSysString = "MIXED";
118 58 break;
119 }
120
121
2/4
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
61 return fmt::format("{version: 9.2f}{X:11}{fileType:<20}{satSys:1}: {satSysTxt:<17}{label:<20}\n", "X"_a = "", "label"_a = "RINEX VERSION / TYPE",
122
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "version"_a = version,
123
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "fileType"_a = "OBSERVATION DATA",
124
2/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 61 times.
✗ Branch 6 not taken.
61 "satSys"_a = satSys.toChar(),
125
2/4
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 61 times.
✗ Branch 6 not taken.
183 "satSysTxt"_a = longSatSysString);
126 61 }
127 49 std::string ObsHeader::headerLinePgmRunByDate() const
128 {
129
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 std::stringstream ss;
130
7/16
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 49 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 49 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 49 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 49 times.
✗ Branch 21 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
49 ss.imbue(std::locale{ ss.getloc(), new boost::posix_time::time_facet{ "%Y%m%d %H%M%S" } });
131
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
49 ss << boost::posix_time::second_clock::universal_time();
132
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 return fmt::format("{pgm:20}{runBy:20}{date} UTC {label:20}\n", "label"_a = "PGM / RUN BY / DATE",
133
8/16
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 49 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 49 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 49 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 49 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 49 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 49 times.
✗ Branch 27 not taken.
294 "pgm"_a = "INSTINCT " + PROJECT_VERSION_STRING,
134
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
98 "runBy"_a = runBy.substr(0, 20),
135
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
245 "date"_a = ss.str()); // std::chrono::floor<std::chrono::seconds>(std::chrono::utc_clock::now())
136 49 }
137 49 std::string ObsHeader::headerLineComments() const
138 {
139 49 std::string str;
140
2/2
✓ Branch 4 taken 147 times.
✓ Branch 5 taken 49 times.
196 for (const auto& comment : comments)
141 {
142
1/2
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
294 str += fmt::format("{comment:60}{label:<20}\n", "label"_a = "COMMENT",
143
3/6
✓ Branch 1 taken 147 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 147 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 147 times.
✗ Branch 9 not taken.
441 "comment"_a = comment.substr(0, 60));
144 }
145 49 return str;
146 }
147 49 std::string ObsHeader::headerLineMarkerName() const
148 {
149
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 return fmt::format("{markerName:60}{label:<20}\n", "label"_a = "MARKER NAME",
150
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
147 "markerName"_a = markerName.substr(0, 60));
151 }
152 49 std::string ObsHeader::headerLineMarkerNumber() const
153 {
154
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 if (!markerNumber.empty())
155 {
156
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 return fmt::format("{markerNumber:60}{label:<20}\n", "label"_a = "MARKER NUMBER",
157
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
147 "markerNumber"_a = markerNumber.substr(0, 60));
158 }
159 return "";
160 }
161 49 std::string ObsHeader::headerLineMarkerType() const
162 {
163
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{markerType:20}{X:40}{label:<20}\n", "X"_a = "", "label"_a = "MARKER TYPE",
164 49 "markerType"_a = (markerType == MarkerTypes::USER_DEFINED
165
3/10
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 49 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
98 ? markerTypeUser.substr(0, 20)
166
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
196 : NAV::to_string(markerType)));
167 }
168 49 std::string ObsHeader::headerLineObserverAgency() const
169 {
170
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 return fmt::format("{observer:20}{agency:40}{label:<20}\n", "label"_a = "OBSERVER / AGENCY",
171
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 "observer"_a = observer.substr(0, 20),
172
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
147 "agency"_a = agency.substr(0, 40));
173 }
174 49 std::string ObsHeader::headerLineRecNumTypeVers() const
175 {
176
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 return fmt::format("{rec:20}{type:20}{vers:20}{label:<20}\n", "label"_a = "REC # / TYPE / VERS",
177
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 "rec"_a = receiverNumber.substr(0, 20),
178
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
98 "type"_a = receiverType.substr(0, 20),
179
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
196 "vers"_a = receiverVersion.substr(0, 20));
180 }
181 49 std::string ObsHeader::headerLineAntNumType() const
182 {
183
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{ant:20}{type:20}{X:20}{label:<20}\n", "X"_a = "", "label"_a = "ANT # / TYPE",
184
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 "ant"_a = antennaNumber.substr(0, 20),
185
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
147 "type"_a = antennaType.substr(0, 20));
186 }
187 49 std::string ObsHeader::headerLineApproxPositionXYZ() const
188 {
189
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 if (approxPositionEnabled)
190 {
191
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{x:14.4f}{y:14.4f}{z:14.4f}{X:18}{label:<20}\n", "X"_a = "", "label"_a = "APPROX POSITION XYZ",
192
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 "x"_a = approxPositionXYZ.x(),
193
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 "y"_a = approxPositionXYZ.y(),
194
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
147 "z"_a = approxPositionXYZ.z());
195 }
196 return "";
197 }
198 49 std::string ObsHeader::headerLineAntennaDeltaHEN() const
199 {
200
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{antH:14.4f}{antE:14.4f}{antN:14.4f}{X:18}{label:<20}\n", "X"_a = "", "label"_a = "ANTENNA: DELTA H/E/N",
201
1/2
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
49 "antH"_a = antennaDeltaHeightEastNorth[0],
202
1/2
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
49 "antE"_a = antennaDeltaHeightEastNorth[1],
203
2/4
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
147 "antN"_a = antennaDeltaHeightEastNorth[2]);
204 }
205 49 std::string ObsHeader::headerLineSysNumObsType() const
206 {
207 49 std::string str;
208
2/2
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 49 times.
102 for (const auto& [satSys, types] : systemObsTypes) // SYS / # / OBS TYPES
209 {
210 53 bool firstLine = true;
211
2/2
✓ Branch 1 taken 527 times.
✓ Branch 2 taken 53 times.
580 for (size_t i = 0; i < types.size(); ++i)
212 {
213
1/2
✓ Branch 1 taken 527 times.
✗ Branch 2 not taken.
527 const auto& obsDesc = types.at(i);
214
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 460 times.
527 if (i % 13 == 0)
215 {
216
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 14 times.
67 if (firstLine)
217 {
218
2/4
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 53 times.
✗ Branch 6 not taken.
106 str += fmt::format("{sys:1}{X:2}{num:3}", "X"_a = "",
219
2/4
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 53 times.
✗ Branch 6 not taken.
53 "sys"_a = satSys.toChar(),
220
2/4
✓ Branch 3 taken 53 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 53 times.
✗ Branch 7 not taken.
106 "num"_a = types.size());
221 53 firstLine = false;
222 }
223
2/4
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
28 else { str += fmt::format("{X:6}", "X"_a = ""); }
224 }
225
226
1/2
✓ Branch 2 taken 527 times.
✗ Branch 3 not taken.
1054 str += fmt::format("{X:1}{desc:3}", "X"_a = "",
227 1054 "desc"_a = vendor::RINEX::obsTypeToChar(obsDesc.type)
228
4/8
✓ Branch 2 taken 527 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 527 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 527 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 527 times.
✗ Branch 12 not taken.
3162 + fmt::format("{}", obsDesc.code).substr(1, 2));
229
230
6/6
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 14 times.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 460 times.
✓ Branch 5 taken 67 times.
✓ Branch 6 taken 460 times.
527 if ((i + 1) % 13 == 0 || i == types.size() - 1)
231 {
232
3/6
✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 67 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 67 times.
✗ Branch 10 not taken.
134 str += fmt::format("{X:{w}}{label:<20}\n", "X"_a = "", "label"_a = "SYS / # / OBS TYPES",
233
2/4
✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 67 times.
✗ Branch 6 not taken.
201 "w"_a = 54 - 4 * ((i % 13) + 1));
234 }
235 }
236 }
237 49 return str;
238 }
239 49 std::string ObsHeader::headerLineSignalStrengthUnit()
240 {
241
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{sigUnit:20}{X:40}{label:<20}\n", "X"_a = "", "label"_a = "SIGNAL STRENGTH UNIT",
242
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
147 "sigUnit"_a = "DBHZ");
243 }
244 61 std::string ObsHeader::headerLineInterval() const
245 {
246
4/6
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 10 times.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 51 times.
✗ Branch 9 not taken.
112 if (interval == 1e9) { return fmt::format("{X:60}{label:<20}\n", "X"_a = "", "label"_a = "INTERVAL"); }
247
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
10 return fmt::format("{interval:10.3f}{X:50}{label:<20}\n", "X"_a = "", "label"_a = "INTERVAL",
248
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
30 "interval"_a = interval);
249 }
250 49 std::string ObsHeader::headerLineTimeOfFirstObs() const
251 {
252
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 auto firstObsYMDHMS = timeFirstObs.toYMDHMS(timeSys, 7);
253
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{y:6d}{m:6d}{d:6d}{h:6d}{min:6d}{sec:13.7f}{X:5}{sys:3}{X:9}{label:<20}\n", "X"_a = "", "label"_a = "TIME OF FIRST OBS",
254
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "y"_a = firstObsYMDHMS.year,
255
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "m"_a = firstObsYMDHMS.month,
256
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "d"_a = firstObsYMDHMS.day,
257
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "h"_a = firstObsYMDHMS.hour,
258
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "min"_a = firstObsYMDHMS.min,
259
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 "sec"_a = static_cast<double>(firstObsYMDHMS.sec),
260
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
147 "sys"_a = vendor::RINEX::timeSystemString(timeSys));
261 }
262 61 std::string ObsHeader::headerLineTimeOfLastObs() const
263 {
264
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 auto lastObsYMDHMS = timeLastObs.toYMDHMS(timeSys, 7);
265
2/4
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
61 return fmt::format("{y:6d}{m:6d}{d:6d}{h:6d}{min:6d}{sec:13.7f}{X:5}{sys:3}{X:9}{label:<20}\n", "X"_a = "", "label"_a = "TIME OF LAST OBS",
266
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "y"_a = lastObsYMDHMS.year,
267
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "m"_a = lastObsYMDHMS.month,
268
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "d"_a = lastObsYMDHMS.day,
269
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "h"_a = lastObsYMDHMS.hour,
270
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "min"_a = lastObsYMDHMS.min,
271
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 "sec"_a = static_cast<double>(lastObsYMDHMS.sec),
272
3/6
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 61 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 61 times.
✗ Branch 9 not taken.
183 "sys"_a = vendor::RINEX::timeSystemString(timeSys));
273 }
274 49 std::string ObsHeader::headerLineSysPhaseShift()
275 {
276
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
98 return fmt::format("{X:60}{label:<20}\n", "X"_a = "", "label"_a = "SYS / PHASE SHIFT");
277 }
278 49 std::string ObsHeader::headerLineGlonassCodPhsBis()
279 {
280
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
98 return fmt::format("{X:60}{label:<20}\n", "X"_a = "", "label"_a = "GLONASS COD/PHS/BIS");
281 }
282 49 std::string ObsHeader::headerLineLeapSeconds() const
283 {
284
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
49 return fmt::format("{leap:6d}{X:54}{label:<20}\n", "X"_a = "", "label"_a = "LEAP SECONDS",
285
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 49 times.
✗ Branch 9 not taken.
147 "leap"_a = timeFirstObs.leapGps2UTC());
286 }
287 61 std::string ObsHeader::headerLineNumSatellites() const
288 {
289
2/4
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
61 return fmt::format("{nSat:6d}{X:54}{label:<20}\n", "X"_a = "", "label"_a = "# OF SATELLITES",
290
2/4
✓ Branch 3 taken 61 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
183 "nSat"_a = satellites.size());
291 }
292 49 std::string ObsHeader::headerLineEndOfHeader()
293 {
294
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
98 return fmt::format("{X:60}{label:<20}\n", "X"_a = "", "label"_a = "END OF HEADER");
295 }
296
297 2037 std::string ObsHeader::epochRecordLine(const InsTime& epochTime, size_t nSatellites) const
298 {
299
1/2
✓ Branch 1 taken 2037 times.
✗ Branch 2 not taken.
2037 auto timeYMDHMS = epochTime.toYMDHMS(timeSys, 7);
300
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 return fmt::format("> {y:4d} {m:2d} {d:2d} {h:2d} {min:2d}{sec:11.7f} 0{numSat:3d}{X:6}{X:15}\n", "X"_a = "",
301
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "y"_a = timeYMDHMS.year,
302
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "m"_a = timeYMDHMS.month,
303
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "d"_a = timeYMDHMS.day,
304
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "h"_a = timeYMDHMS.hour,
305
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "min"_a = timeYMDHMS.min,
306
1/2
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
2037 "sec"_a = static_cast<double>(timeYMDHMS.sec),
307
2/4
✓ Branch 2 taken 2037 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2037 times.
✗ Branch 6 not taken.
6111 "numSat"_a = nSatellites);
308 }
309
310 void to_json(json& j, const ObsHeader& obj)
311 {
312 j = json{
313 { "version", obj.version },
314 { "runBy", obj.runBy },
315 { "comments", obj.comments },
316 { "markerName", obj.markerName },
317 { "markerNumber", obj.markerNumber },
318 { "markerType", obj.markerType },
319 { "markerTypeUser", obj.markerTypeUser },
320 { "observer", obj.observer },
321 { "agency", obj.agency },
322 { "receiverNumber", obj.receiverNumber },
323 { "receiverType", obj.receiverType },
324 { "receiverVersion", obj.receiverVersion },
325 { "antennaNumber", obj.antennaNumber },
326 { "antennaType", obj.antennaType },
327 { "approxPositionEnabled", obj.approxPositionEnabled },
328 { "approxPositionXYZ", obj.approxPositionXYZ },
329 { "antennaDeltaHeightEastNorth", obj.antennaDeltaHeightEastNorth },
330 };
331 }
332
333 12 void from_json(const json& j, ObsHeader& obj)
334 {
335
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("version")) { j.at("version").get_to(obj.version); }
336
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("runBy")) { j.at("runBy").get_to(obj.runBy); }
337
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("comments")) { j.at("comments").get_to(obj.comments); }
338
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("markerName")) { j.at("markerName").get_to(obj.markerName); }
339
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("markerNumber")) { j.at("markerNumber").get_to(obj.markerNumber); }
340
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("markerType")) { j.at("markerType").get_to(obj.markerType); }
341
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("markerTypeUser")) { j.at("markerTypeUser").get_to(obj.markerTypeUser); }
342
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("observer")) { j.at("observer").get_to(obj.observer); }
343
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("agency")) { j.at("agency").get_to(obj.agency); }
344
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("receiverNumber")) { j.at("receiverNumber").get_to(obj.receiverNumber); }
345
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("receiverType")) { j.at("receiverType").get_to(obj.receiverType); }
346
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("receiverVersion")) { j.at("receiverVersion").get_to(obj.receiverVersion); }
347
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("antennaNumber")) { j.at("antennaNumber").get_to(obj.antennaNumber); }
348
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("antennaType")) { j.at("antennaType").get_to(obj.antennaType); }
349
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("approxPositionEnabled")) { j.at("approxPositionEnabled").get_to(obj.approxPositionEnabled); }
350
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("approxPositionXYZ")) { j.at("approxPositionXYZ").get_to(obj.approxPositionXYZ); }
351
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (j.contains("antennaDeltaHeightEastNorth")) { j.at("antennaDeltaHeightEastNorth").get_to(obj.antennaDeltaHeightEastNorth); }
352 12 }
353 2785 ObsType obsTypeFromChar(char c)
354 {
355
4/7
✓ Branch 0 taken 769 times.
✓ Branch 1 taken 760 times.
✓ Branch 2 taken 592 times.
✓ Branch 3 taken 676 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
2785 switch (c)
356 {
357 769 case 'C':
358 769 return ObsType::C;
359 760 case 'L':
360 760 return ObsType::L;
361 592 case 'D':
362 592 return ObsType::D;
363 676 case 'S':
364 676 return ObsType::S;
365 case 'I':
366 return ObsType::I;
367 case 'X':
368 return ObsType::X;
369 default:
370 return ObsType::Error;
371 }
372 }
373
374 3283 char obsTypeToChar(ObsType type)
375 {
376
4/7
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 902 times.
✓ Branch 2 taken 687 times.
✓ Branch 3 taken 790 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
3283 switch (type)
377 {
378 916 case ObsType::C:
379 916 return 'C';
380 902 case ObsType::L:
381 902 return 'L';
382 687 case ObsType::D:
383 687 return 'D';
384 790 case ObsType::S:
385 790 return 'S';
386 case ObsType::I:
387 return 'I';
388 case ObsType::X:
389 return 'X';
390 default:
391 return '\0';
392 }
393 }
394
395 110 std::string timeSystemString(TimeSystem timeSys)
396 {
397
3/7
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 72 times.
110 switch (static_cast<TimeSystem_>(timeSys))
398 {
399 33 case GPST:
400
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
66 return "GPS";
401 case GST:
402 return "GAL";
403 5 case GLNT:
404
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 return "GLO";
405 case BDT:
406 return "BDT";
407 case QZSST:
408 return "QZS";
409 case IRNSST:
410 return "IRN";
411 72 case UTC:
412 case TimeSys_None:
413 default:
414 72 break;
415 }
416
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
144 return "GPS";
417 }
418
419 13 TimeSystem timeSystem(SatelliteSystem satSys)
420 {
421
2/7
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 11 times.
13 switch (static_cast<SatelliteSystem_>(satSys))
422 {
423 case GPS:
424 return GPST;
425 case GAL:
426 return GST;
427 2 case GLO:
428 2 return GLNT;
429 case BDS:
430 return BDT;
431 case QZSS:
432 return QZSST;
433 case IRNSS:
434 return IRNSST;
435 11 default:
436 11 break;
437 }
438 11 return GPST;
439 }
440
441 2776 Frequency getFrequencyFromBand(SatelliteSystem satSys, int band)
442 {
443
8/11
✓ Branch 0 taken 1032 times.
✓ Branch 1 taken 631 times.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 422 times.
✓ Branch 5 taken 164 times.
✓ Branch 6 taken 323 times.
✓ Branch 7 taken 75 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
2776 switch (band)
444 {
445 1032 case 1:
446 // 1 = L1 (GPS, QZSS, SBAS, BDS)
447 // G1 (GLO)
448 // E1 (GAL)
449 // B1 (BDS)
450
2/2
✓ Branch 1 taken 320 times.
✓ Branch 2 taken 715 times.
1032 if (satSys == GPS)
451 {
452 320 return Frequency_::G01;
453 }
454
2/2
✓ Branch 1 taken 211 times.
✓ Branch 2 taken 501 times.
715 if (satSys == QZSS)
455 {
456 211 return Frequency_::J01;
457 }
458
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 441 times.
501 if (satSys == SBAS)
459 {
460 60 return Frequency_::S01;
461 }
462
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 396 times.
441 if (satSys == BDS)
463 {
464 48 return Frequency_::B01;
465 }
466
2/2
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 207 times.
396 if (satSys == GLO)
467 {
468 190 return Frequency_::R01;
469 }
470
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
207 if (satSys == GAL)
471 {
472 209 return Frequency_::E01;
473 }
474 break;
475 631 case 2:
476 // 2 = L2 (GPS, QZSS)
477 // G2 (GLO)
478 // B1-2 (BDS)
479
2/2
✓ Branch 1 taken 291 times.
✓ Branch 2 taken 336 times.
631 if (satSys == GPS)
480 {
481 291 return Frequency_::G02;
482 }
483
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 305 times.
336 if (satSys == QZSS)
484 {
485 32 return Frequency_::J02;
486 }
487
2/2
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 137 times.
305 if (satSys == GLO)
488 {
489 166 return Frequency_::R02;
490 }
491
1/2
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
137 if (satSys == BDS)
492 {
493 139 return Frequency_::B02;
494 }
495 break;
496 80 case 3:
497 // 3 = G3 (GLO)
498
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 if (satSys == GLO)
499 {
500 80 return Frequency_::R03;
501 }
502 break;
503 60 case 4:
504 // 4 = G1a (GLO)
505
1/2
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
60 if (satSys == GLO)
506 {
507 60 return Frequency_::R04;
508 }
509 break;
510 422 case 5:
511 // 5 = L5 (GPS, QZSS, SBAS, IRNSS)
512 // E5a (GAL)
513 // B2/B2a (BDS)
514
2/2
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 334 times.
422 if (satSys == GPS)
515 {
516 87 return Frequency_::G05;
517 }
518
2/2
✓ Branch 1 taken 119 times.
✓ Branch 2 taken 215 times.
334 if (satSys == QZSS)
519 {
520 119 return Frequency_::J05;
521 }
522
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 184 times.
215 if (satSys == SBAS)
523 {
524 32 return Frequency_::S05;
525 }
526
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 152 times.
184 if (satSys == IRNSS)
527 {
528 32 return Frequency_::I05;
529 }
530
2/2
✓ Branch 1 taken 104 times.
✓ Branch 2 taken 48 times.
152 if (satSys == GAL)
531 {
532 104 return Frequency_::E05;
533 }
534
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 if (satSys == BDS)
535 {
536 48 return Frequency_::B05;
537 }
538 break;
539 164 case 6:
540 // 6 = E6 (GAL)
541 // L6 (QZSS)
542 // B3 (BDS)
543 // G2a (GLO)
544
2/2
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 84 times.
164 if (satSys == GAL)
545 {
546 80 return Frequency_::E06;
547 }
548
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 64 times.
84 if (satSys == QZSS)
549 {
550 20 return Frequency_::J06;
551 }
552
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 20 times.
64 if (satSys == BDS)
553 {
554 44 return Frequency_::B06;
555 }
556
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 if (satSys == GLO)
557 {
558 20 return Frequency_::R06;
559 }
560 break;
561 323 case 7:
562 // 7 = E5b (GAL)
563 // B2/B2b (BDS)
564
2/2
✓ Branch 1 taken 170 times.
✓ Branch 2 taken 152 times.
323 if (satSys == GAL)
565 {
566 170 return Frequency_::E07;
567 }
568
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 if (satSys == BDS)
569 {
570 152 return Frequency_::B07;
571 }
572 break;
573 75 case 8:
574 // 8 = E5a+b (GAL)
575 // B2a+b (BDS)
576
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 1 times.
75 if (satSys == GAL)
577 {
578 75 return Frequency_::E08;
579 }
580
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 if (satSys == BDS)
581 {
582 return Frequency_::B08;
583 }
584 break;
585 case 9:
586 // 9 = S (IRNSS)
587 if (satSys == IRNSS)
588 {
589 return Frequency_::I09;
590 }
591 break;
592 case 0:
593 // 0 for type X (all)
594 break;
595 default:
596 break;
597 }
598
599 LOG_ERROR("Cannot find frequency for satellite system '{}' and band '{}'", satSys, band);
600 return Freq_None;
601 }
602
603 } // namespace vendor::RINEX
604
605 const char* to_string(vendor::RINEX::ObsHeader::MarkerTypes markerType)
606 {
607 using MarkerTypes = NAV::vendor::RINEX::ObsHeader::MarkerTypes;
608 switch (markerType)
609 {
610 case MarkerTypes::GEODETIC:
611 return "GEODETIC";
612 case MarkerTypes::NON_GEODETIC:
613 return "NON_GEODETIC";
614 case MarkerTypes::NON_PHYSICAL:
615 return "NON_PHYSICAL";
616 case MarkerTypes::SPACEBORNE:
617 return "SPACEBORNE";
618 case MarkerTypes::GROUND_CRAFT:
619 return "GROUND_CRAFT";
620 case MarkerTypes::WATER_CRAFT:
621 return "WATER_CRAFT";
622 case MarkerTypes::AIRBORNE:
623 return "AIRBORNE";
624 case MarkerTypes::FIXED_BUOY:
625 return "FIXED_BUOY";
626 case MarkerTypes::FLOATING_BUOY:
627 return "FLOATING_BUOY";
628 case MarkerTypes::FLOATING_ICE:
629 return "FLOATING_ICE";
630 case MarkerTypes::GLACIER:
631 return "GLACIER";
632 case MarkerTypes::BALLISTIC:
633 return "BALLISTIC";
634 case MarkerTypes::ANIMAL:
635 return "ANIMAL";
636 case MarkerTypes::HUMAN:
637 return "HUMAN";
638 case MarkerTypes::USER_DEFINED:
639 return "USER_DEFINED";
640 case MarkerTypes::COUNT:
641 return "";
642 }
643 return "";
644 }
645
646 const char* tooltip(vendor::RINEX::ObsHeader::MarkerTypes markerType)
647 {
648 using MarkerTypes = NAV::vendor::RINEX::ObsHeader::MarkerTypes;
649 switch (markerType)
650 {
651 case MarkerTypes::GEODETIC:
652 return "Earth-fixed, high-precision monument";
653 case MarkerTypes::NON_GEODETIC:
654 return "Earth-fixed, low-precision monument";
655 case MarkerTypes::NON_PHYSICAL:
656 return "Generated from network processing";
657 case MarkerTypes::SPACEBORNE:
658 return "Orbiting space vehicle";
659 case MarkerTypes::GROUND_CRAFT:
660 return "Mobile terrestrial vehicle";
661 case MarkerTypes::WATER_CRAFT:
662 return "Mobile water craft";
663 case MarkerTypes::AIRBORNE:
664 return "Aircraft, balloon, etc.";
665 case MarkerTypes::FIXED_BUOY:
666 return "'Fixed' on water surface";
667 case MarkerTypes::FLOATING_BUOY:
668 return "Floating on water surface";
669 case MarkerTypes::FLOATING_ICE:
670 return "Floating ice sheet, etc.";
671 case MarkerTypes::GLACIER:
672 return "'Fixed' on a glacier";
673 case MarkerTypes::BALLISTIC:
674 return "Rockets, shells, etc";
675 case MarkerTypes::ANIMAL:
676 return "Animal carrying a receiver";
677 case MarkerTypes::HUMAN:
678 return "Human being";
679 case MarkerTypes::USER_DEFINED:
680 return "Users may define other project-dependent keywords";
681 case MarkerTypes::COUNT:
682 return "";
683 }
684 return "";
685 }
686
687 } // namespace NAV
688