38static const auto kUtfDegrees = wxString::FromUTF8(u8
"\u00B0");
42std::string TimeToString(
const time_t t) {
45 errno_t e = ctime_s(buff,
sizeof(buff), &t);
46 assert(e == 0 &&
"Huh? ctime_s returned an error");
48 const char* r = ctime_r(&t, buff);
49 assert(r != NULL &&
"ctime_r failed...");
51 return std::string(buff, strlen(buff) - 1);
54std::string DegreesToString(
double degrees) {
56 std::stringstream buf;
57 buf << setw(2) << static_cast<int>(trunc(degrees)) << kUtfDegrees
58 <<
static_cast<int>(trunc(degrees * 100)) % 100 <<
"," << setw(2)
59 << (
static_cast<int>(trunc(degrees * 10000)) % 10000) % 100;
63double PosPartsToDegrees(
float degrees,
float minutes,
64 float percent_of_minute) {
65 return degrees + minutes / 60 + percent_of_minute / 6000;
71 : lat(TypeToLat(t, _lat)), lon(TypeToLong(t, _lon)), type(t) {}
74 : lat(_lat), lon(_lon), type(LatLongToType(_lat, _lon)) {};
79 std::stringstream buf;
80 const std::string NE(TypeToStr(type));
81 auto lat_s = DegreesToString(abs(lat));
82 auto lon_s = DegreesToString(abs(lon));
83 buf << lat_s << NE[0] <<
" " << lon_s << NE[1];
87std::string Position::TypeToStr(
const Type t)
const {
108Position::Type Position::LatLongToType(
double lat,
double lon) {
110 return lon >= 0 ? Type::NE : Type::NW;
112 return lon >= 0 ? Type::SE : Type::SW;
115double Position::TypeToLat(Type t,
double lat) {
116 return t == Type::SW || t == Type::SE ? -lat : lat;
119double Position::TypeToLong(Type t,
double lon) {
120 return t == Type::NE || t == Type::SE ? lon : -lon;
124static double GgaPartToDouble(
const std::string& s) {
125 size_t dotpos = s.find(
'.');
126 if (dotpos < 2)
return nan(
"");
127 auto degrees = s.substr(0, dotpos - 2);
128 auto minutes = s.substr(dotpos - 2);
129 return std::stod(degrees) + std::stod(minutes) / 60;
134 if (parts.size() != 4) {
137 double lat = GgaPartToDouble(parts[0]);
140 else if (parts[1] !=
"N")
142 double lon = GgaPartToDouble(parts[2]);
145 else if (parts[3] !=
"E")
153std::string AppMsg::TypeToString(
const AppMsg::Type t)
const {
155 case AppMsg::Type::AisData:
158 case AppMsg::Type::BasicNavData:
159 return "basic-nav-data";
161 case AppMsg::Type::CustomMsg:
164 case AppMsg::Type::DataPrioNeeded:
165 return "data-prio-needed";
167 case AppMsg::Type::GnssFix:
170 case AppMsg::Type::GPSWatchdog:
171 return "gps-watchdog";
173 case AppMsg::Type::Undef:
180std::string BasicNavDataMsg::to_string()
const {
181 std::stringstream ss;
182 ss << AppMsg::to_string() <<
" pos: " << pos.
to_string() <<
" sog: " << sog
183 <<
" cog: " << cog <<
" var: " << var <<
" hdt: " << hdt
184 <<
" vflag: " << vflag <<
" set_time: " << TimeToString(set_time.tv_sec);
187std::string AisData::to_string()
const {
188 std::stringstream ss;
189 ss << TimeToString(time) <<
" " << pos.
to_string() <<
" sog: " << sog
190 <<
" cog: " << cog <<
" heading: " << heading
191 <<
" rate of turn: " << rate_of_turn <<
"type: 0x" << std::hex << type
192 <<
" name " << name <<
" callsign " << callsign <<
" dest: " << dest
193 <<
" length " << std::dec << length <<
" beam: " << beam
194 <<
" draft: " << draft <<
" status: 0x" << std::hex << status;
Position()
Construct a (0,0) position, type == Undef.
static Position ParseGGA(const std::string gga)
Parse a GGA string like "5800.588,N,01145.776,E" as present in GGA and other n0183 messages.
std::string to_string() const
Return utf string like 65°25,11N 21°12,01E.
Decoded messages definitions.
std::vector< std::string > split(const char *token_string, const std::string &delimiter)
Return vector of items in s separated by delimiter.
Miscellaneous utilities, many of which string related.