27 #include <wx/wxprec.h>
36 #include "model/comm_appmsg.h"
37 #include "model/ocpn_utils.h"
41 std::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);
54 std::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;
63 double PosPartsToDegrees(
float degrees,
float minutes,
64 float percent_of_minute) {
65 return degrees + minutes / 60 + percent_of_minute / 6000;
72 : lat(TypeToLat(t, _lat)), lon(TypeToLong(t, _lon)), type(t) {}
75 : lat(_lat), lon(_lon), type(LatLongToType(_lat, _lon)) {};
80 std::stringstream buf;
81 const std::string NE(TypeToStr(type));
82 auto lat_s = DegreesToString(abs(lat));
83 auto lon_s = DegreesToString(abs(lon));
84 buf << lat_s << NE[0] <<
" " << lon_s << NE[1];
88 std::string Position::TypeToStr(
const Type t)
const {
109 Position::Type Position::LatLongToType(
double lat,
double lon) {
111 return lon >= 0 ? Type::NE : Type::NW;
113 return lon >= 0 ? Type::SE : Type::SW;
116 double Position::TypeToLat(Type t,
double lat) {
117 return t == Type::SW || t == Type::SE ? -lat : lat;
120 double Position::TypeToLong(Type t,
double lon) {
121 return t == Type::NE || t == Type::SE ? lon : -lon;
125 static double GgaPartToDouble(
const std::string& s) {
126 size_t dotpos = s.find(
'.');
127 if (dotpos < 2)
return nan(
"");
128 auto degrees = s.substr(0, dotpos - 2);
129 auto minutes = s.substr(dotpos - 2);
130 return std::stod(degrees) + std::stod(minutes)/60;
135 auto parts = ocpn::split(gga.c_str(),
",");
136 if (parts.size() != 4) {
139 double lat = GgaPartToDouble(parts[0]);
142 else if (parts[1] !=
"N")
144 double lon = GgaPartToDouble(parts[2]);
147 else if (parts[3] !=
"E")
156 std::string AppMsg::TypeToString(
const AppMsg::Type t)
const {
158 case AppMsg::Type::AisData:
161 case AppMsg::Type::BasicNavData:
162 return "basic-nav-data";
164 case AppMsg::Type::CustomMsg:
167 case AppMsg::Type::DataPrioNeeded:
168 return "data-prio-needed";
170 case AppMsg::Type::GnssFix:
173 case AppMsg::Type::GPSWatchdog:
174 return "gps-watchdog";
176 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.