36#include "model/comm_appmsg.h"
37#include "model/ocpn_utils.h"
41std::string TimeToString(
const time_t t) {
44 errno_t e = ctime_s(buff,
sizeof(buff), &t);
45 assert(e == 0 &&
"Huh? ctime_s returned an error");
46 return std::string(buff);
48 const char* r = ctime_r(&t, buff);
49 assert(r != NULL &&
"ctime_r failed...");
50 return std::string(buff);
54std::string DegreesToString(
double degrees) {
56 std::stringstream buf;
57 buf << setw(2) << static_cast<int>(trunc(degrees)) <<
"\u00B0"
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;
133 auto parts = ocpn::split(gga.c_str(),
",");
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:
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.