14#include <boost/date_time/posix_time/posix_time.hpp>
15#include <fmt/chrono.h>
16#include <fmt/format.h>
17using namespace fmt::literals;
42 if (std::ranges::find_if(obsDescriptions, [&code, &type](
const auto& obsDesc) {
43 return obsDesc.code == code && obsDesc.type == type;
45 == obsDescriptions.end())
95 std::string longSatSysString;
99 longSatSysString =
"GPS";
102 longSatSysString =
"GALILEO";
105 longSatSysString =
"GLONASS";
108 longSatSysString =
"BEIDOU";
111 longSatSysString =
"QZSS";
114 longSatSysString =
"IRNSS";
117 longSatSysString =
"MIXED";
121 return fmt::format(
"{version: 9.2f}{X:11}{fileType:<20}{satSys:1}: {satSysTxt:<17}{label:<20}\n",
"X"_a =
"",
"label"_a =
"RINEX VERSION / TYPE",
123 "fileType"_a =
"OBSERVATION DATA",
124 "satSys"_a =
satSys.toChar(),
125 "satSysTxt"_a = longSatSysString);
129 std::stringstream ss;
130 ss.imbue(std::locale{ ss.getloc(),
new boost::posix_time::time_facet{
"%Y%m%d %H%M%S" } });
131 ss << boost::posix_time::second_clock::universal_time();
132 return fmt::format(
"{pgm:20}{runBy:20}{date} UTC {label:20}\n",
"label"_a =
"PGM / RUN BY / DATE",
134 "runBy"_a =
runBy.substr(0, 20),
135 "date"_a = ss.str());
140 for (
const auto& comment :
comments)
142 str += fmt::format(
"{comment:60}{label:<20}\n",
"label"_a =
"COMMENT",
143 "comment"_a = comment.substr(0, 60));
149 return fmt::format(
"{markerName:60}{label:<20}\n",
"label"_a =
"MARKER NAME",
156 return fmt::format(
"{markerNumber:60}{label:<20}\n",
"label"_a =
"MARKER NUMBER",
163 return fmt::format(
"{markerType:20}{X:40}{label:<20}\n",
"X"_a =
"",
"label"_a =
"MARKER TYPE",
170 return fmt::format(
"{observer:20}{agency:40}{label:<20}\n",
"label"_a =
"OBSERVER / AGENCY",
171 "observer"_a =
observer.substr(0, 20),
172 "agency"_a =
agency.substr(0, 40));
176 return fmt::format(
"{rec:20}{type:20}{vers:20}{label:<20}\n",
"label"_a =
"REC # / TYPE / VERS",
183 return fmt::format(
"{ant:20}{type:20}{X:20}{label:<20}\n",
"X"_a =
"",
"label"_a =
"ANT # / TYPE",
191 return fmt::format(
"{x:14.4f}{y:14.4f}{z:14.4f}{X:18}{label:<20}\n",
"X"_a =
"",
"label"_a =
"APPROX POSITION XYZ",
200 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",
210 bool firstLine =
true;
211 for (
size_t i = 0; i < types.size(); ++i)
213 const auto& obsDesc = types.at(i);
218 str += fmt::format(
"{sys:1}{X:2}{num:3}",
"X"_a =
"",
219 "sys"_a =
satSys.toChar(),
220 "num"_a = types.size());
223 else {
str += fmt::format(
"{X:6}",
"X"_a =
""); }
226 str += fmt::format(
"{X:1}{desc:3}",
"X"_a =
"",
228 + fmt::format(
"{}", obsDesc.code).substr(1, 2));
230 if ((i + 1) % 13 == 0 || i == types.size() - 1)
232 str += fmt::format(
"{X:{w}}{label:<20}\n",
"X"_a =
"",
"label"_a =
"SYS / # / OBS TYPES",
233 "w"_a = 54 - 4 * ((i % 13) + 1));
241 return fmt::format(
"{sigUnit:20}{X:40}{label:<20}\n",
"X"_a =
"",
"label"_a =
"SIGNAL STRENGTH UNIT",
242 "sigUnit"_a =
"DBHZ");
246 if (
interval == 1e9) {
return fmt::format(
"{X:60}{label:<20}\n",
"X"_a =
"",
"label"_a =
"INTERVAL"); }
247 return fmt::format(
"{interval:10.3f}{X:50}{label:<20}\n",
"X"_a =
"",
"label"_a =
"INTERVAL",
253 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 "y"_a = firstObsYMDHMS.year,
255 "m"_a = firstObsYMDHMS.month,
256 "d"_a = firstObsYMDHMS.day,
257 "h"_a = firstObsYMDHMS.hour,
258 "min"_a = firstObsYMDHMS.min,
259 "sec"_a =
static_cast<double>(firstObsYMDHMS.sec),
265 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 "y"_a = lastObsYMDHMS.year,
267 "m"_a = lastObsYMDHMS.month,
268 "d"_a = lastObsYMDHMS.day,
269 "h"_a = lastObsYMDHMS.hour,
270 "min"_a = lastObsYMDHMS.min,
271 "sec"_a =
static_cast<double>(lastObsYMDHMS.sec),
276 return fmt::format(
"{X:60}{label:<20}\n",
"X"_a =
"",
"label"_a =
"SYS / PHASE SHIFT");
280 return fmt::format(
"{X:60}{label:<20}\n",
"X"_a =
"",
"label"_a =
"GLONASS COD/PHS/BIS");
284 return fmt::format(
"{leap:6d}{X:54}{label:<20}\n",
"X"_a =
"",
"label"_a =
"LEAP SECONDS",
289 return fmt::format(
"{nSat:6d}{X:54}{label:<20}\n",
"X"_a =
"",
"label"_a =
"# OF SATELLITES",
294 return fmt::format(
"{X:60}{label:<20}\n",
"X"_a =
"",
"label"_a =
"END OF HEADER");
300 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 "y"_a = timeYMDHMS.year,
302 "m"_a = timeYMDHMS.month,
303 "d"_a = timeYMDHMS.day,
304 "h"_a = timeYMDHMS.hour,
305 "min"_a = timeYMDHMS.min,
306 "sec"_a =
static_cast<double>(timeYMDHMS.sec),
307 "numSat"_a = nSatellites);
314 {
"runBy", obj.
runBy },
335 if (j.contains(
"version")) { j.at(
"version").get_to(obj.
version); }
336 if (j.contains(
"runBy")) { j.at(
"runBy").get_to(obj.
runBy); }
337 if (j.contains(
"comments")) { j.at(
"comments").get_to(obj.
comments); }
338 if (j.contains(
"markerName")) { j.at(
"markerName").get_to(obj.
markerName); }
339 if (j.contains(
"markerNumber")) { j.at(
"markerNumber").get_to(obj.
markerNumber); }
340 if (j.contains(
"markerType")) { j.at(
"markerType").get_to(obj.
markerType); }
341 if (j.contains(
"markerTypeUser")) { j.at(
"markerTypeUser").get_to(obj.
markerTypeUser); }
342 if (j.contains(
"observer")) { j.at(
"observer").get_to(obj.
observer); }
343 if (j.contains(
"agency")) { j.at(
"agency").get_to(obj.
agency); }
344 if (j.contains(
"receiverNumber")) { j.at(
"receiverNumber").get_to(obj.
receiverNumber); }
345 if (j.contains(
"receiverType")) { j.at(
"receiverType").get_to(obj.
receiverType); }
346 if (j.contains(
"receiverVersion")) { j.at(
"receiverVersion").get_to(obj.
receiverVersion); }
347 if (j.contains(
"antennaNumber")) { j.at(
"antennaNumber").get_to(obj.
antennaNumber); }
348 if (j.contains(
"antennaType")) { j.at(
"antennaType").get_to(obj.
antennaType); }
349 if (j.contains(
"approxPositionEnabled")) { j.at(
"approxPositionEnabled").get_to(obj.
approxPositionEnabled); }
350 if (j.contains(
"approxPositionXYZ")) { j.at(
"approxPositionXYZ").get_to(obj.
approxPositionXYZ); }
599 LOG_ERROR(
"Cannot find frequency for satellite system '{}' and band '{}'", satSys, band);
610 case MarkerTypes::GEODETIC:
612 case MarkerTypes::NON_GEODETIC:
613 return "NON_GEODETIC";
614 case MarkerTypes::NON_PHYSICAL:
615 return "NON_PHYSICAL";
616 case MarkerTypes::SPACEBORNE:
618 case MarkerTypes::GROUND_CRAFT:
619 return "GROUND_CRAFT";
620 case MarkerTypes::WATER_CRAFT:
621 return "WATER_CRAFT";
622 case MarkerTypes::AIRBORNE:
624 case MarkerTypes::FIXED_BUOY:
626 case MarkerTypes::FLOATING_BUOY:
627 return "FLOATING_BUOY";
628 case MarkerTypes::FLOATING_ICE:
629 return "FLOATING_ICE";
630 case MarkerTypes::GLACIER:
632 case MarkerTypes::BALLISTIC:
634 case MarkerTypes::ANIMAL:
636 case MarkerTypes::HUMAN:
638 case MarkerTypes::USER_DEFINED:
639 return "USER_DEFINED";
640 case MarkerTypes::COUNT:
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:
nlohmann::json json
json namespace
Utility class for logging to console and file.
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
Functions to work with RINEX.
Provides the version of the project.
#define PROJECT_VERSION_STRING
Project Version String in the form "major.minor.patch".
Enumerate for GNSS Codes.
Frequency getFrequency() const
Returns the frequency for the code.
Frequency definition for different satellite systems.
SatelliteSystem getSatSys() const
Get the satellite system for which this frequency is defined.
The class is responsible for all time-related tasks.
constexpr InsTime_YMDHMS toYMDHMS(TimeSystem timesys=UTC, int digits=-1) const
Converts this time object into a different format.
void from_json(const json &j, ObsHeader &obj)
Converts the provided json object into a struct.
ObsType
Observation types of the 'SYS / # / OBS TYPES' header.
@ X
Receiver channel numbers.
@ S
Raw signal strength(carrier to noise ratio)
@ I
Ionosphere phase delay.
std::string timeSystemString(TimeSystem timeSys)
Converts the satellite system(s) to 3 characters representation of the time system.
char obsTypeToChar(ObsType type)
Converts an ObsType to char.
void to_json(json &j, const ObsHeader &obj)
Converts the provided struct into a json object.
TimeSystem timeSystem(SatelliteSystem satSys)
Converts the satellite system(s) to the time system.
Frequency getFrequencyFromBand(SatelliteSystem satSys, int band)
Get the Frequency from the provided satellite system and band in the 'SYS / # / OBS TYPES' header.
ObsType obsTypeFromChar(char c)
Converts a character to an ObsType.
TimeSystem_
List of all time systems.
@ IRNSST
Indian Regional Navigation Satellite System Time.
@ GST
Galileo System Time.
@ GLNT
GLONASS Time (GLONASST)
@ TimeSys_None
No Time system.
@ QZSST
Quasi-Zenith Satellite System Time.
@ UTC
Coordinated Universal Time.
@ E07
Galileo E5b (1207.14 MHz).
@ R03
GLONASS, "G3" (1202.025 MHz).
@ J01
QZSS L1 (1575.42 MHz).
@ B02
Beidou B1-2 (B1I) (1561.098 MHz).
@ S01
SBAS L1 (1575.42 MHz).
@ E06
Galileo E6 (1278.75 MHz).
@ I09
IRNSS S (2492.028 MHz).
@ B05
Beidou B2a (1176.45 MHz).
@ I05
IRNSS L5 (1176.45 MHz).
@ R02
GLONASS, "G2" (1246 MHz).
@ B08
Beidou B2 (B2a + B2b) (1191.795MHz).
@ R06
GLONASS, "G2a" (1248.06 MHz).
@ E01
Galileo, "E1" (1575.42 MHz).
@ B06
Beidou B3 (1268.52 MHz).
@ E05
Galileo E5a (1176.45 MHz).
@ S05
SBAS L5 (1176.45 MHz).
@ G02
GPS L2 (1227.6 MHz).
@ R01
GLONASS, "G1" (1602 MHZ).
@ G01
GPS L1 (1575.42 MHz).
@ B01
Beidou B1 (1575.42 MHz).
@ J05
QZSS L5 (1176.45 MHz).
@ J02
QZSS L2 (1227.6 MHz).
@ B07
Beidou B2b (B2I) (1207.14 MHz).
@ R04
GLONASS, "G1a" (1600.995 MHZ).
@ E08
Galileo E5 (E5a + E5b) (1191.795MHz).
@ J06
QZSS L6 / LEX (1278.75 MHz).
@ G05
GPS L5 (1176.45 MHz).
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
const char * tooltip(vendor::RINEX::ObsHeader::MarkerTypes markerType)
Converts the enum to a string tooltip.
SatelliteSystem_
Satellite System enumeration.
@ GPS
Global Positioning System.
@ QZSS
Quasi-Zenith Satellite System.
@ GLO
Globalnaja nawigazionnaja sputnikowaja sistema (GLONASS)
@ SBAS
Satellite Based Augmentation System.
@ SatSys_None
No Satellite system.
@ IRNSS
Indian Regional Navigation Satellite System.
Description of the observations from the 'SYS / # / OBS TYPES' header.