24#include <unordered_map>
26#include <wx/datetime.h>
36static std::unordered_map<int, wxString> s_ERI_hash;
38void make_hash_ERI(
int key,
const wxString &description) {
39 s_ERI_hash[key] = description;
42void clear_hash_ERI() { s_ERI_hash.clear(); }
44static wxString FormatTimeAdaptive(
int seconds) {
47 return wxString::Format(
"%3ds", seconds);
48 else if (seconds < 3600) {
51 return wxString::Format(
"%2dmin %02ds", m, s);
53 int h = seconds / 3600;
55 return wxString::Format(
"%2dh %02dmin", h, m);
58static wxString html_escape(
const wxString &src) {
62 ret.Replace(
"<",
"<");
63 ret.Replace(
">",
">");
75wxString trimAISField(
char *data) {
78 wxString field = wxString::From8BitData(data);
79 while (field.Right(1) ==
'@' || field.Right(1) ==
' ') field.RemoveLast();
87wxString ais_get_status(
int index) {
88 static const wxString ais_status[] = {
89 _(
"Underway using Engine"),
91 _(
"Not Under Command"),
92 _(
"Restricted Manoeuvrability"),
93 _(
"Constrained by draught"),
96 _(
"Engaged in Fishing"),
97 _(
"Underway Sailing"),
98 _(
"High Speed Craft"),
99 _(
"Wing In Ground Effect"),
100 _(
"Power-driven vessel towing astern (regional use)"),
101 _(
"Power-driven vessel pushing ahead or towing alongside (regional use)"),
106 _(
"AtoN Virtual (On Position)"),
107 _(
"AtoN Virtual (Off Position)"),
109 _(
"AtoN Real (On Position)"),
110 _(
"AtoN Real(Off Position)")};
112 return ais_status[index];
115wxString ais_meteo_get_trend(
int tend) {
121 trend = _(
"decreasing");
123 trend = _(
"increasing");
128wxString aisMeteoPrecipType(
int precip) {
138 prec =
"Thunderstorm";
141 prec =
"Freezing rain";
144 prec =
"Mixed / ice";
150 prec =
"not available";
156wxString aisMeteoWaterLevelRef(
int refID) {
206 strncpy(ShipName,
"Unknown ", SHIP_NAME_LEN);
207 strncpy(CallSign,
" ", 8);
208 strncpy(Destination,
" ", DESTINATION_LEN);
209 ShipNameExtension[0] = 0;
210 b_show_AIS_CPA =
false;
219 wxDateTime now = wxDateTime::Now();
221 PositionReportTicks = now.GetTicks();
222 StaticReportTicks = now.GetTicks();
229 NavStatus = UNDEFINED;
233 b_isDSCtarget =
false;
243 DimA = DimB = DimC = DimD = 0;
260 n_alert_state = AIS_NO_ALERT;
261 b_suppress_audio =
false;
262 b_positionDoubtful =
false;
263 b_positionOnceValid =
false;
269 strncpy(Euro_VIN,
" ", 8);
272 b_isEuroInland =
false;
273 b_blue_paddle =
false;
277 b_PersistTrack =
false;
278 b_mPropPersistTrack =
false;
279 b_in_ack_timeout =
false;
284 b_isFollower =
false;
286 b_show_track = g_bAISShowTracks;
287 b_SarAircraftPosnReport =
false;
289 b_nameFromCache =
false;
291 for (
unsigned int i = 0; i < AIS_TARGETDATA_MAX_CANVAS; i++)
293 met_data.original_mmsi = 0;
294 met_data.stationID = 0;
298 met_data.minute = 60;
299 met_data.pos_acc = 1;
300 met_data.wind_kn = 122;
301 met_data.wind_gust_kn = 127;
302 met_data.wind_dir = 360;
303 met_data.wind_gust_dir = 360;
304 met_data.air_temp = -102.4;
305 met_data.rel_humid = 101;
306 met_data.dew_point = 50.1;
307 met_data.airpress = 1310;
308 met_data.airpress_tend = 3;
309 met_data.hor_vis = 12.7;
310 met_data.hor_vis_GT =
false;
311 met_data.water_lev_dev = 4001 / 100 - 10;
312 met_data.water_level = -32;
313 met_data.water_lev_trend = 3;
314 met_data.current = 25.5;
315 met_data.curr_dir = 360;
316 met_data.wave_height = 25.5;
317 met_data.wave_period = 63;
318 met_data.wave_dir = 360;
319 met_data.swell_height = 25.5;
320 met_data.swell_per = 63;
321 met_data.swell_dir = 360;
322 met_data.seastate = 13;
323 met_data.water_temp = 501;
324 met_data.precipitation = 7;
325 met_data.salinity = 51.;
327 met_data.vertical_ref = 14;
331 strncpy(ShipName, q->ShipName, SHIP_NAME_LEN);
332 strncpy(CallSign, q->CallSign, 8);
333 strncpy(Destination, q->Destination, DESTINATION_LEN);
334 ShipNameExtension[0] = 0;
335 b_show_AIS_CPA = q->b_show_AIS_CPA;
345 PositionReportTicks = q->PositionReportTicks;
346 StaticReportTicks = q->StaticReportTicks;
348 b_removed = q->b_removed;
353 NavStatus = q->NavStatus;
354 SyncState = q->SyncState;
356 ShipType = q->ShipType;
357 b_isDSCtarget = q->b_isDSCtarget;
358 m_dscNature = q->m_dscNature;
359 m_dscTXmmsi = q->m_dscTXmmsi;
364 Range_NM = q->Range_NM;
373 ETA_Day = q->ETA_Day;
375 ETA_Min = q->ETA_Min;
379 RecentPeriod = q->RecentPeriod;
381 m_utc_hour = q->m_utc_hour;
382 m_utc_min = q->m_utc_min;
383 m_utc_sec = q->m_utc_sec;
386 n_alert_state = q->n_alert_state;
387 b_suppress_audio = q->b_suppress_audio;
388 b_positionDoubtful = q->b_positionDoubtful;
389 b_positionOnceValid = q->b_positionOnceValid;
390 b_nameValid = q->b_nameValid;
392 Euro_Length = q->Euro_Length;
393 Euro_Beam = q->Euro_Beam;
394 Euro_Draft = q->Euro_Draft;
395 memcpy(Euro_VIN, q->Euro_VIN, EURO_VIN_LEN);
396 UN_shiptype = q->UN_shiptype;
398 b_isEuroInland = q->b_isEuroInland;
399 b_blue_paddle = q->b_blue_paddle;
401 b_OwnShip = q->b_OwnShip;
402 b_in_ack_timeout = q->b_in_ack_timeout;
404 m_ptrack = q->m_ptrack;
406 b_active = q->b_active;
407 blue_paddle = q->blue_paddle;
408 bCPA_Valid = q->bCPA_Valid;
410 b_show_track = q->b_show_track;
411 b_SarAircraftPosnReport = q->b_SarAircraftPosnReport;
412 altitude = q->altitude;
415AisTargetData::~AisTargetData() { m_ptrack.clear(); }
418wxString AisTargetData::GetFullName() {
421 wxString shipName = trimAISField(ShipName);
422 if (shipName ==
"Unknown")
423 retName = wxGetTranslation(shipName);
427 if (strlen(ShipNameExtension)) {
428 wxString shipNameExt = trimAISField(ShipNameExtension);
429 retName += shipNameExt;
436wxString AisTargetData::BuildQueryResult() {
438 wxDateTime now = wxDateTime::Now();
440 wxString tableStart =
"\n<table border=0 cellpadding=1 cellspacing=0>\n";
441 wxString tableEnd =
"</table>\n\n";
442 wxString rowStart =
"<tr><td><font size=-2>";
443 wxString rowStartH =
"<tr><td nowrap>";
444 wxString rowSeparator =
"</font></td><td></td><td><b>";
445 wxString rowSeparatorH =
"</td><td></td><td>";
446 wxString colSeparator =
"<td></td>";
447 wxString rowEnd =
"</b></td></tr>\n";
448 wxString vertSpacer =
449 "<tr><td></td></tr><tr><td></td></tr><tr><td></td></tr>\n\n";
451 wxString IMOstr, MMSIstr, ClassStr;
453 html << tableStart <<
"<tr><td nowrap colspan=2>";
455 html <<
"<font size=+2><i><b>" << GetFullName();
456 html <<
"</b></i></font> <b>";
459 if ((Class != AIS_ATON) && (Class != AIS_BASE) && (Class != AIS_GPSG_BUDDY) &&
460 (Class != AIS_SART) && (Class != AIS_METEO)) {
461 html << trimAISField(CallSign) <<
"</b>" << rowEnd;
463 if (Class != AIS_CLASS_B) {
464 if (IMO > 0) IMOstr = wxString::Format(
"%08d", abs(IMO));
467 html <<
"</b>" << rowEnd;
471 if (Class != AIS_GPSG_BUDDY) {
472 MMSIstr = wxString::Format(
"%09d", abs(MMSI));
474 ClassStr = wxGetTranslation(Get_class_string(
false));
476 if (Class == AIS_ATON) {
477 wxString cls(
"AtoN: ");
478 cls += Get_vessel_type_string(
false);
479 ClassStr = wxGetTranslation(cls);
482 if (b_SarAircraftPosnReport) {
483 int airtype = (MMSI % 1000) / 100;
484 ClassStr = airtype == 5 ? _(
"SAR Helicopter") : _(
"SAR Aircraft");
488 html <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
490 << rowStart << _(
"MMSI")
491 <<
"</font></td><td> </td><td><font size=-2>" << _(
"Class")
492 <<
"</font></td><td> </td><td align=right><font size=-2>"
493 << _(
"IMO") <<
"</font></td></tr>" << rowStartH <<
"<b>" << MMSIstr
494 <<
"</b></td><td> </td><td><b>" << ClassStr
495 <<
"</b></td><td> </td><td align=right><b>" << IMOstr << rowEnd
496 <<
"</table></td></tr>";
498 else if (Class == AIS_METEO) {
499 MMSIstr = wxString::Format(
"%09d", abs(met_data.original_mmsi));
500 html <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
502 << rowStart << _(
"MMSI")
503 <<
"</font></td><td> </td><td align=right><font size=-2>"
504 << _(
"Class") <<
"</font></td></tr>" << rowStartH <<
"<b>" << MMSIstr
505 <<
"</b></td><td> </td><td align=right><b>"
506 <<
"<font size=-1>" << ClassStr << rowEnd << rowStart
507 <<
"<b>ID: " << MMSI;
508 if (met_data.stationID) {
509 wxString SK_ID = wxString::Format(
"%06d", (met_data.stationID - 1000000));
510 html <<
"<td> </td><td align=right>"
511 <<
"SK-ID: " << SK_ID;
513 html << rowEnd <<
"</b></table></td></tr>";
515 html <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
517 << rowStart << _(
"MMSI")
518 <<
"</font></td><td> </td><td align=right><font size=-2>"
519 << _(
"Class") <<
"</font></td></tr>" << rowStartH <<
"<b>" << MMSIstr
520 <<
"</b></td><td> </td><td align=right><b>" << ClassStr << rowEnd
521 <<
"</table></td></tr>";
523 if ((Class != AIS_SART))
524 html <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
527 << ((Class == AIS_BASE || Class == AIS_ATON || Class == AIS_METEO)
530 << rowEnd <<
"</font></td></tr>" << rowStartH <<
"<font size=-1><b>"
531 << GetCountryCode(true);
532 if (Class == AIS_CLASS_B && MMSIstr.StartsWith(
"8")) {
533 html <<
"<td align=right>" << _(
"Handheld");
535 html << rowEnd <<
"</font></table></td></tr>";
538 if ((Class != AIS_BASE) && (Class != AIS_CLASS_B) && (Class != AIS_SART) &&
539 (Class != AIS_METEO)) {
541 if ((NavStatus <= 21) && (NavStatus >= 0))
542 navStatStr = wxGetTranslation(ais_get_status(NavStatus));
543 }
else if (Class == AIS_SART) {
544 if (NavStatus == RESERVED_14)
545 navStatStr = _(
"Active");
546 else if (NavStatus == UNDEFINED)
547 navStatStr = _(
"Testing");
550 wxString sart_sub_type;
551 if (Class == AIS_SART) {
552 int mmsi_start = MMSI / 1000000;
553 switch (mmsi_start) {
558 sart_sub_type =
"MOB";
561 sart_sub_type =
"EPIRB";
564 sart_sub_type = _(
"Unknown");
569 wxString AISTypeStr, UNTypeStr, sizeString;
570 if ((Class != AIS_BASE) && (Class != AIS_SART) && (Class != AIS_DSC) &&
571 (Class != AIS_METEO)) {
573 AISTypeStr = wxGetTranslation(Get_vessel_type_string());
575 if (b_isEuroInland && UN_shiptype) {
576 auto it = s_ERI_hash.find(UN_shiptype);
578 if (it == s_ERI_hash.end())
579 type = _(
"Undefined");
583 UNTypeStr = wxGetTranslation(type);
586 if (b_SarAircraftPosnReport) {
592 if (Class == AIS_SART) {
593 if (MSG_14_text.Len()) {
594 html << rowStart << _(
"Safety Broadcast Message") << rowEnd << rowStartH
595 <<
"<b>" << MSG_14_text << rowEnd;
601 if (NavStatus != ATON_VIRTUAL && Class != AIS_ARPA && Class != AIS_APRS &&
603 if ((Class == AIS_CLASS_B) || (Class == AIS_ATON)) {
605 wxString::Format(
"%dm x %dm", (DimA + DimB), (DimC + DimD));
606 }
else if (!b_SarAircraftPosnReport) {
607 if ((DimA + DimB + DimC + DimD) == 0) {
608 if (b_isEuroInland) {
609 if (Euro_Length == 0.0) {
610 if (Euro_Draft > 0.01) {
611 sizeString << wxString::Format(
"---m x ---m x %4.1fm",
614 sizeString <<
"---m x ---m x ---m";
617 if (Euro_Draft > 0.01) {
618 sizeString << wxString::Format(
"%5.1fm x %4.1fm x %4.1fm",
619 Euro_Length, Euro_Beam,
622 sizeString << wxString::Format(
"%5.1fm x %4.1fm x ---m\n\n",
623 Euro_Length, Euro_Beam);
628 sizeString << wxString::Format(
"---m x ---m x %4.1fm", Draft);
630 sizeString <<
"---m x ---m x ---m";
633 }
else if (Draft < 0.01) {
634 sizeString << wxString::Format(
"%dm x %dm x ---m", (DimA + DimB),
637 sizeString << wxString::Format(
"%dm x %dm x %4.1fm", (DimA + DimB),
638 (DimC + DimD), Draft);
644 if (Class == AIS_SART) {
645 html <<
"<tr><td colspan=2>"
646 <<
"<b>" << AISTypeStr;
647 if (sart_sub_type.Length()) html <<
" (" << sart_sub_type <<
"), ";
649 html << rowEnd <<
"<tr><td colspan=2>"
650 <<
"<b>" << sizeString << rowEnd;
653 else if (Class == AIS_ATON) {
654 html <<
"<tr><td colspan=2>"
655 <<
"<b>" << navStatStr;
656 html << rowEnd <<
"<tr><td colspan=2>"
657 <<
"<b>" << sizeString << rowEnd;
658 }
else if (Class == AIS_DSC && (ShipType == 12 || ShipType == 16)) {
659 if (ShipType == 16) {
660 html <<
"<tr><td colspan=2>"
661 <<
"<b>" << _(
"Distress relay");
662 if (m_dscTXmmsi > 2000000) {
663 wxString mmsirelay = wxString::Format(
" %09d", abs(m_dscTXmmsi));
664 html <<
" " << _(
"by:") << mmsirelay;
666 html <<
"<b>" << sizeString << rowEnd;
668 html <<
"<tr><td colspan=2>" << _(
"Nature of distress: ") << rowEnd
669 <<
"<tr><td colspan=2>";
670 if (m_dscNature < 13) {
671 html <<
"<tr><td colspan=2>"
672 <<
"<b>" << GetNatureofDistress(m_dscNature) <<
"<b>" << sizeString
673 << rowEnd <<
"<tr><td colspan=2>";
675 }
else if ((Class != AIS_BASE) && (Class != AIS_DSC)) {
676 html <<
"<tr><td colspan=2>"
677 <<
"<b>" << AISTypeStr;
678 if (navStatStr.Length()) html <<
", " << navStatStr;
679 if (UNTypeStr.Length()) html <<
" (UN Type " << UNTypeStr <<
")";
680 html << rowEnd <<
"<tr><td colspan=2>"
681 <<
"<b>" << sizeString << rowEnd;
684 if (b_positionOnceValid) {
686 if (b_positionDoubtful) posTypeStr << _(
" (Last Known)");
689 int target_age = now.GetTicks() - PositionReportTicks;
694 html << vertSpacer << rowStart << _(
"Position") << posTypeStr
695 <<
"</font></td><td align=right><font size=-2>" << _(
"Report Age")
696 <<
"</font></td></tr>"
698 << rowStartH <<
"<b>" << toSDMM(1, Lat)
699 <<
"</b></td><td align=right><b>" << FormatTimeAdaptive(target_age)
700 << rowEnd << rowStartH <<
"<b>" << toSDMM(2, Lon);
701 if (Class != AIS_METEO)
705 wxString::Format(
" %02d:%02d", met_data.hour, met_data.minute);
706 html <<
" </td><td align=right></b></font><font size=-3>"
707 << _(
"Issued (UTC)") <<
"</font><font size=-1><b>" << meteoTime
708 <<
"</font>" << rowEnd;
712 wxString courseStr, sogStr, hdgStr, rotStr, rngStr, brgStr, destStr, etaStr;
714 if (Class == AIS_GPSG_BUDDY) {
715 long month, year, day;
716 m_date_string.Mid(0, 2).ToLong(&day);
717 m_date_string.Mid(2, 2).ToLong(&month);
718 m_date_string.Mid(4, 2).ToLong(&year);
721 date.SetMonth((wxDateTime::Month)(month - 1));
722 date.SetYear(year + 2000);
724 wxString f_date = date.FormatISODate();
726 html << vertSpacer << rowStart << _(
"Report as of") << rowEnd << rowStartH
727 <<
"<b>" << f_date +
"</b> at <b>"
728 << wxString::Format(
"%d:%d UTC ", m_utc_hour, m_utc_min) << rowEnd;
730 if (Class == AIS_CLASS_A && !b_SarAircraftPosnReport) {
731 html << vertSpacer << rowStart << _(
"Destination")
732 <<
"</font></td><td align=right><font size=-2>" << _(
"ETA (UTC)")
733 <<
"</font></td></tr>\n"
734 << rowStartH <<
"<b>";
735 wxString dest = trimAISField(Destination);
737 html << html_escape(dest);
740 html <<
"</b></td><td nowrap align=right><b>";
742 if ((ETA_Mo) && (ETA_Hr < 24)) {
744 if (now.GetMonth() > (ETA_Mo - 1)) yearOffset = 1;
745 wxDateTime eta(ETA_Day, wxDateTime::Month(ETA_Mo - 1),
746 now.GetYear() + yearOffset, ETA_Hr, ETA_Min);
747 html << eta.Format(
"%b %d %H:%M");
753 if (Class == AIS_CLASS_A || Class == AIS_CLASS_B || Class == AIS_ARPA ||
754 Class == AIS_APRS || Class == AIS_SART || Class == AIS_BUOY) {
755 int crs = wxRound(COG);
757 wxString magString, trueString;
759 magString << wxString::Format(
760 wxString(
"%03d%c(M)"),
static_cast<int>(m_callbacks.get_mag(COG)),
763 trueString << wxString::Format(wxString(
"%03d%c "), (
int)crs, 0x00B0);
765 courseStr << trueString << magString;
766 }
else if (COG == 360.0)
769 courseStr =
"0°";
771 double speed_show = toUsrSpeed(SOG);
773 if ((SOG <= 102.2) || b_SarAircraftPosnReport) {
774 if (speed_show < 10.0)
775 sogStr = wxString::Format(
"%.2f ", speed_show) + getUsrSpeedUnit();
776 else if (speed_show < 100.0)
777 sogStr = wxString::Format(
"%.1f ", speed_show) + getUsrSpeedUnit();
779 sogStr = wxString::Format(
"%.0f ", speed_show) + getUsrSpeedUnit();
787 hdgStr = wxString::Format(
"%03d°", (
int)HDG);
791 if (ROTAIS != -128) {
793 rotStr <<
"> 5°/30s " << _(
"Right");
794 else if (ROTAIS == -127)
795 rotStr <<
"> 5°/30s " << _(
"Left");
798 rotStr << wxString::Format(
"%3d°/Min ", ROTIND) << _(
"Right");
800 rotStr << wxString::Format(
"%3d°/Min ", -ROTIND) << _(
"Left");
804 }
else if (!b_SarAircraftPosnReport)
809 if (b_positionOnceValid &&
bGPSValid && (Range_NM >= 0.))
814 int brg = (int)wxRound(Brg);
815 if (Brg > 359.5) brg = 0;
816 if (b_positionOnceValid &&
bGPSValid && (Brg >= 0.) && (Range_NM > 0.) &&
818 wxString magString, trueString;
820 magString << wxString::Format(wxString(
"%03d%c(M)"),
821 static_cast<int>(m_callbacks.get_mag(Brg)),
824 trueString << wxString::Format(wxString(
"%03d%c "), (
int)Brg, 0x00B0);
826 brgStr << trueString << magString;
830 wxString turnRateHdr;
831 if ((Class != AIS_ATON) && (Class != AIS_BASE) && (Class != AIS_DSC) &&
832 (Class != AIS_METEO)) {
834 <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
836 << rowStart << _(
"Speed")
837 <<
"</font></td><td> </td><td><font size=-2>" << _(
"Course")
838 <<
"</font></td><td> </td><td align=right><font size=-2>";
839 if (!b_SarAircraftPosnReport) html << _(
"Heading");
841 html <<
"</font></td></tr>" << rowStartH <<
"<b>" << sogStr
842 <<
"</b></td><td> </td><td><b>" << courseStr
843 <<
"</b></td><td> </td><td align=right><b>";
844 if (!b_SarAircraftPosnReport) html << hdgStr;
845 html << rowEnd <<
"</table></td></tr>" << vertSpacer;
847 if (!b_SarAircraftPosnReport) turnRateHdr = _(
"Turn Rate");
849 if (Class != AIS_METEO) {
850 html <<
"<tr><td colspan=2><table width=100% border=0 cellpadding=0 "
852 << rowStart << _(
"Range")
853 <<
"</font></td><td> </td><td><font size=-2>" << _(
"Bearing")
854 <<
"</font></td><td> </td><td align=right><font size=-2>"
855 << turnRateHdr <<
"</font></td></tr>" << rowStartH <<
"<b>" << rngStr
856 <<
"</b></td><td> </td><td><b>" << brgStr
857 <<
"</b></td><td> </td><td align=right><b>";
858 if (!b_SarAircraftPosnReport) html << rotStr;
859 html << rowEnd <<
"</table></td></tr>" << vertSpacer;
862 if (bCPA_Valid && Class != AIS_METEO) {
864 tcpaStr <<
"</b> " << _(
"in ") <<
"</td><td align=right><b>"
865 << FormatTimeAdaptive((
int)(TCPA * 60.));
867 html << rowStart <<
"<font size=-2>" << _(
"CPA")
868 <<
"</font>" << rowEnd << rowStartH <<
"<b>"
872 if (Class != AIS_BASE && Class != AIS_METEO) {
873 if (blue_paddle == 1) {
874 html << rowStart << _(
"Inland Blue Flag") << rowEnd << rowStartH <<
"<b>"
875 << _(
"Clear") << rowEnd;
876 }
else if (blue_paddle == 2) {
877 html << rowStart << _(
"Inland Blue Flag") << rowEnd << rowStartH <<
"<b>"
878 << _(
"Set") << rowEnd;
882 if (b_SarAircraftPosnReport) {
884 if (altitude != 4095)
885 altStr.Printf(
"%4d m", altitude);
887 altStr = _(
"Unknown");
889 html << rowStart << _(
"Altitude")
890 <<
"</font></td><td> </td><td><font size=-0>" << rowStartH
891 <<
"<b>" << altStr <<
"</b></td><td> </td><td><b>" << rowEnd
892 <<
"</table></td></tr>" << vertSpacer;
895 if (Class == AIS_METEO) {
896 if (met_data.wind_kn < 122) {
897 double userwindspeed = toUsrWindSpeed(met_data.wind_kn);
899 wxString::Format(
"%0.1f %s %d%c", userwindspeed,
900 getUsrWindSpeedUnit(), met_data.wind_dir, 0x00B0);
902 double userwindgustspeed = toUsrWindSpeed(met_data.wind_gust_kn);
903 wxString wspeedGust = wxString::Format(
"%.0f %s %d%c", userwindgustspeed,
904 getUsrWindSpeedUnit(),
905 met_data.wind_gust_dir, 0x00B0);
906 if (met_data.wind_gust_kn >= 126) wspeedGust =
"";
908 html << vertSpacer << rowStart << _(
"Wind speed")
909 <<
"</font></td><td align=right><font size=-2>" << _(
"Wind gust")
910 <<
"</font></td></tr>" << rowStartH <<
"<b>" << wspeed
911 <<
"</b></td><td align=right><b>" << wspeedGust << rowEnd;
914 if (met_data.water_lev_dev < 30. || met_data.water_level > -32. ||
915 met_data.current < 25.5) {
916 wxString wlevel_txt = _(
"Water level deviation");
918 if (met_data.water_lev_dev < 30.) {
919 double userlevel =
toUsrDepth(met_data.water_lev_dev);
921 wxString::Format(
"%.1f %s %s", userlevel, getUsrDepthUnit(),
922 ais_meteo_get_trend(met_data.water_lev_trend));
923 if (met_data.vertical_ref < 14) {
924 wlevel_txt = _(
"Water level dev. Ref: ");
925 wlevel_txt << aisMeteoWaterLevelRef(met_data.vertical_ref);
928 if (met_data.water_lev_dev >= 30.) wlevel =
"";
930 }
else if (met_data.water_level > -32.) {
931 double userlevel =
toUsrDepth(met_data.water_level);
933 wxString::Format(
"%.1f %s %s", userlevel, getUsrDepthUnit(),
934 ais_meteo_get_trend(met_data.water_lev_trend));
935 wlevel_txt = _(
"Water level");
936 if (met_data.water_level <= -32.) wlevel =
"";
939 wxString current = wxString::Format(
"%.1f kts %d%c", met_data.current,
940 met_data.curr_dir, 0x00B0);
941 if (met_data.current >= 25.5) current =
"";
943 html << vertSpacer << rowStart << wlevel_txt
944 <<
"</font></td><td align=right><font size=-2>"
945 << _(
"Surface current ") <<
"</font></td></tr>" << rowStartH <<
"<b>"
946 << wlevel <<
"</b></td><td align=right><b>" << current << rowEnd;
949 if (met_data.wave_height < 24.6 || met_data.swell_height < 24.6) {
950 double userwave =
toUsrDepth(met_data.wave_height);
951 wxString wave = wxString::Format(
"%.1f %s %d%c %d %s ", userwave,
952 getUsrDepthUnit(), met_data.wave_dir,
953 0x00B0, met_data.wave_period, _(
"s"));
954 if (met_data.wave_height >= 24.6) wave =
"";
956 double userswell =
toUsrDepth(met_data.swell_height);
957 wxString swell = wxString::Format(
"%.1f %s %d%c %d %s", userswell,
958 getUsrDepthUnit(), met_data.swell_dir,
959 0x00B0, met_data.swell_per, _(
"s"));
960 if (met_data.swell_height >= 25.) swell =
"";
962 html << vertSpacer << rowStart << _(
"Waves height & period")
963 <<
"</font></td><td align=right><font size=-2>"
964 << _(
"Swell height & period ") <<
"</font></td></tr>" << rowStartH
965 <<
"<b>" << wave <<
"</b></td><td align=right><b>" << swell
969 if (met_data.air_temp != -102.4 || met_data.airpress < 1310) {
970 double usertemp =
toUsrTemp(met_data.air_temp);
972 wxString::Format(
"%.1f%c%s", usertemp, 0x00B0, getUsrTempUnit());
973 if (met_data.air_temp == -102.4) airtemp =
"";
976 wxString::Format(
"%d hPa %s", met_data.airpress,
977 ais_meteo_get_trend(met_data.airpress_tend));
978 const int ap = met_data.airpress;
979 if (ap < 800 || ap >= 1310) airpress =
"";
981 html << vertSpacer << rowStart << _(
"Air Temperatur")
982 <<
"</font></td><td align=right><font size=-2>" << _(
"Air pressure")
983 <<
"</font></td></tr>" << rowStartH <<
"<b>" << airtemp
984 <<
"</b></td><td align=right><b>" << airpress << rowEnd;
987 if (met_data.rel_humid < 101 || met_data.dew_point < 50.) {
988 wxString humid = wxString::Format(
"%d%c", met_data.rel_humid,
'%');
989 if (met_data.rel_humid >= 101) humid =
"";
991 double usertempDew =
toUsrTemp(met_data.dew_point);
993 wxString::Format(
"%.1f%c%s", usertempDew, 0x00B0, getUsrTempUnit());
994 if (met_data.dew_point >= 50.) dewpoint =
"";
996 html << vertSpacer << rowStart << _(
"Relative Humidity")
997 <<
"</font></td><td align=right><font size=-2>" << _(
"Dew Point ")
998 <<
"</font></td></tr>" << rowStartH <<
"<b>" << humid
999 <<
"</b></td><td align=right><b>" << dewpoint << rowEnd;
1002 if (met_data.water_temp < 50.1 || met_data.seastate < 13) {
1003 double usertemp =
toUsrTemp(met_data.water_temp);
1004 wxString watertemp =
1005 wxString::Format(
"%.1f%c%s", usertemp, 0x00B0, getUsrTempUnit());
1006 if (met_data.water_temp >= 50.1) watertemp =
"";
1008 wxString seastate = wxString::Format(
"%d Bf ", met_data.seastate);
1009 if (met_data.seastate == 13) seastate =
"";
1011 html << vertSpacer << rowStart << _(
"Water Temperatur")
1012 <<
"</font></td><td align=right><font size=-2>" << _(
"Sea state")
1013 <<
"</font></td></tr>" << rowStartH <<
"<b>" << watertemp
1014 <<
"</b></td><td align=right><b>" << seastate << rowEnd;
1017 if (met_data.precipitation < 7 || met_data.hor_vis < 12.7) {
1019 wxString::Format(
"%s", aisMeteoPrecipType(met_data.precipitation));
1020 if (met_data.precipitation >= 6) precip =
"";
1024 wxString::Format(
"%s%.1f %s", (met_data.hor_vis_GT ?
">" :
""),
1025 userVisDist, getUsrDistanceUnit());
1026 if (met_data.hor_vis >= 12.7) horVis =
"";
1027 html << vertSpacer << rowStart << _(
"Precipitation")
1028 <<
"</font></td><td align=right><font size=-2>"
1029 << _(
"Horizontal Visibility") <<
"</font></td></tr>" << rowStartH
1030 <<
"<b>" << precip <<
"</b></td><td align=right><b>" << horVis
1034 if (met_data.salinity < 50. || met_data.ice < 2) {
1035 wxString sal = wxString::Format(
"%.1f%c", met_data.salinity, 0x2030);
1036 if (met_data.salinity >= 50.) sal =
"";
1038 wxString icestatus = _(
"No");
1039 if (met_data.ice == 1) icestatus = _(
"Yes");
1040 if (met_data.ice >= 2) icestatus =
"";
1042 html << vertSpacer << rowStart << _(
"Sea salinity")
1043 <<
"</font></td><td align=right><font size=-2>" << _(
"Ice status")
1044 <<
"</font></td></tr>" << rowStartH <<
"<b>" << sal
1045 <<
"</b></td><td align=right><b>" << icestatus << rowEnd;
1052wxString AisTargetData::GetRolloverString() {
1056 result.Append(
"\"");
1057 result.Append(GetFullName());
1058 result.Append(
"\" ");
1060 if (Class != AIS_GPSG_BUDDY) {
1061 t.Printf(
"%09d", abs(MMSI));
1064 result.Append(GetCountryCode(
false));
1066 t = trimAISField(CallSign);
1068 result.Append(
" (");
1072 if (g_bAISRolloverShowClass || (Class == AIS_SART)) {
1073 if (result.Len()) result.Append(
"\n");
1075 if (Class == AIS_ATON) {
1076 result.Append(wxGetTranslation(Get_class_string(
true)));
1077 result.Append(
": ");
1078 result.Append(wxGetTranslation(Get_vessel_type_string(
false)));
1079 }
else if (b_SarAircraftPosnReport) {
1080 int airtype = (MMSI % 1000) / 100;
1081 result.Append(airtype == 5 ? _(
"SAR Helicopter") : _(
"SAR Aircraft"));
1083 result.Append(wxGetTranslation(Get_class_string(
false)));
1085 result.Append(
"] ");
1086 if ((Class != AIS_ATON) && (Class != AIS_BASE)) {
1087 if (Class == AIS_SART) {
1088 int mmsi_start = MMSI / 1000000;
1089 switch (mmsi_start) {
1099 result += _(
"Unknown");
1104 if (Class != AIS_SART && Class != AIS_METEO) {
1105 if (!b_SarAircraftPosnReport)
1106 result.Append(wxGetTranslation(Get_vessel_type_string(
false)));
1109 if ((Class != AIS_CLASS_B) && (Class != AIS_SART) && Class != AIS_DSC &&
1110 Class != AIS_METEO && !b_SarAircraftPosnReport) {
1111 if ((NavStatus <= 15) && (NavStatus >= 0)) {
1112 result.Append(
" (");
1113 result.Append(wxGetTranslation(ais_get_status(NavStatus)));
1116 }
else if (Class == AIS_SART) {
1117 result.Append(
" (");
1118 if (NavStatus == RESERVED_14)
1119 result.Append(_(
"Active"));
1120 else if (NavStatus == UNDEFINED)
1121 result.Append(_(
"Testing"));
1123 }
else if (Class == AIS_DSC) {
1124 result.Append(
" (");
1125 result.Append(GetNatureofDistress(m_dscNature));
1131 if (g_bAISRolloverShowCOG && ((SOG <= 102.2) || b_SarAircraftPosnReport) &&
1132 !((Class == AIS_ATON) || (Class == AIS_BASE) || (Class == AIS_METEO))) {
1133 if (result.Len()) result <<
"\n";
1135 double speed_show = toUsrSpeed(SOG);
1136 if (speed_show < 10.0)
1137 result << wxString::Format(
"SOG %.2f ", speed_show) << getUsrSpeedUnit()
1139 else if (speed_show < 100.0)
1140 result << wxString::Format(
"SOG %.1f ", speed_show) << getUsrSpeedUnit()
1143 result << wxString::Format(
"SOG %.0f ", speed_show) << getUsrSpeedUnit()
1146 int crs = wxRound(COG);
1147 if (b_positionOnceValid) {
1149 wxString magString, trueString;
1151 magString << wxString::Format(
1152 wxString(
"%03d%c(M) "),
1153 static_cast<int>(m_callbacks.get_mag(COG)), 0x00B0);
1155 trueString << wxString::Format(wxString(
"%03d%c "), (
int)crs, 0x00B0);
1157 result << trueString << magString;
1160 else if (COG == 360.0)
1161 result << _(
" COG Unavailable");
1162 else if (crs == 360)
1163 result << wxString(
" COG 000\u00B0");
1165 result << _(
" COG Unavailable");
1168 if (g_bAISRolloverShowCPA && bCPA_Valid && Class != AIS_METEO) {
1169 if (result.Len()) result <<
"\n";
1171 <<
" " << wxString::Format(
"%.0f", TCPA) <<
" " << _(
"min");
1173 if (Class == AIS_METEO) {
1174 if (met_data.wind_kn < 122) {
1175 if (result.Len()) result <<
"\n";
1176 double userwindspeed = toUsrWindSpeed(met_data.wind_kn);
1177 result << _(
"Wind speed");
1178 result << wxString::Format(
": %0.1f %s", userwindspeed,
1179 getUsrWindSpeedUnit())
1180 << wxString::Format(
" %d%c ", met_data.wind_dir, 0x00B0);
1183 if (met_data.water_lev_dev < 30.) {
1184 if (result.Len()) result <<
"\n";
1185 result << _(
"Water level deviation");
1187 userdepth =
toUsrDepth(met_data.water_lev_dev);
1188 result << wxString::Format(
": %.1f %s", userdepth, getUsrDepthUnit());
1190 }
else if (met_data.water_level > -32.) {
1191 if (result.Len()) result <<
"\n";
1192 result << _(
"Water level");
1194 userdepth =
toUsrDepth(met_data.water_level);
1195 result << wxString::Format(
": %.1f %s", userdepth, getUsrDepthUnit());
1198 if (met_data.current < 25.) {
1199 if (result.Len()) result <<
"\n";
1200 result << _(
"Current");
1201 result << wxString::Format(
": %.1f ", met_data.current) << _(
"kts")
1202 << wxString::Format(
" %d%c ", met_data.curr_dir, 0x00B0);
1205 if (met_data.wave_height < 24.6) {
1206 if (result.Len()) result <<
"\n";
1207 double userwh =
toUsrDepth(met_data.wave_height);
1208 result << _(
"Wave height")
1209 << wxString::Format(
": %.1f %s", userwh, getUsrDepthUnit())
1210 <<
" / " << met_data.wave_period <<
" " << _(
"s");
1213 if (met_data.water_temp < 50.) {
1214 if (result.Len()) result <<
"\n";
1215 double usertemp =
toUsrTemp(met_data.water_temp);
1216 result << _(
"Water temp");
1217 result << wxString::Format(
": %.1f%c", usertemp, 0x00B0)
1218 << getUsrTempUnit();
1221 if (met_data.air_temp != -102.4) {
1222 if (result.Len()) result <<
"\n";
1223 double usertemp =
toUsrTemp(met_data.air_temp);
1224 result << _(
"Air temp");
1225 result << wxString::Format(
": %.1f%c", usertemp, 0x00B0)
1226 << getUsrTempUnit() <<
" ";
1229 if (met_data.airpress > 799 && met_data.airpress < 1310) {
1230 if (met_data.air_temp == -102.4 && result.Len()) result <<
"\n";
1231 result << _(
"Air press");
1232 result << wxString::Format(
": %d hPa", met_data.airpress);
1235 if (met_data.hor_vis < 12.) {
1236 if (result.Len()) result <<
"\n";
1239 wxString::Format(
": %s%.1f %s", (met_data.hor_vis_GT ?
">" :
""),
1240 userVisDist, getUsrDistanceUnit());
1241 result << _(
"Visibility") << horVis;
1247wxString AisTargetData::Get_vessel_type_string(
bool b_short) {
1249 if (Class == AIS_ATON) {
1303 if ((Class == AIS_CLASS_B) || (Class == AIS_CLASS_A)) {
1304 if ((ShipType >= 40) && (ShipType < 50)) i = 8;
1306 if ((ShipType >= 60) && (ShipType < 70)) i = 16;
1308 if ((ShipType >= 70) && (ShipType < 80)) i = 17;
1310 if ((ShipType >= 80) && (ShipType < 90)) i = 18;
1311 }
else if (Class == AIS_GPSG_BUDDY)
1313 else if (Class == AIS_ARPA)
1315 else if (Class == AIS_APRS)
1317 else if (Class == AIS_BUOY)
1319 else if (Class == AIS_DSC)
1320 i = (ShipType == 12 || ShipType == 16) ? 54 : 53;
1323 return ais_get_type(i);
1325 return ais_get_short_type(i);
1328wxString AisTargetData::Get_class_string(
bool b_short) {
1335 return b_short ? _(
"AtoN") : _(
"Aid to Navigation");
1337 return b_short ? _(
"Base") : _(
"Base Station");
1338 case AIS_GPSG_BUDDY:
1339 return b_short ? _(
"Buddy") : _(
"GPSGate Buddy");
1341 if (ShipType == 12 || (ShipType == 16 && m_dscNature < 13))
1342 return b_short ? _(
"DSC") : _(
"DSC Distress");
1344 return b_short ? _(
"DSC") : _(
"DSC Position Report");
1346 return b_short ? _(
"SART") : _(
"SART");
1348 return b_short ? _(
"ARPA") : _(
"ARPA");
1350 return b_short ? _(
"Buoy") : _(
"BUOY");
1352 return b_short ? _(
"APRS") : _(
"APRS Position Report");
1354 return b_short ? _(
"Meteo") : _(
"Meteorologic");
1357 return b_short ? _(
"Unk") : _(
"Unknown");
1361wxString AisTargetData::GetNatureofDistress(
int dscnature) {
1363 wxString dscDistressType[] = {_(
"Fire, explosion"),
1367 _(
"Listing, in danger of capsizing"),
1369 _(
"Disabled and adrift"),
1370 _(
"Undesignated distress"),
1371 _(
"Abandoning ship"),
1372 _(
"Piracy/armed robbery attack"),
1375 _(
"EPIRB emission")};
1376 if (dscnature >= 0 && dscnature < 13)
return dscDistressType[dscnature];
1381void AisTargetData::Toggle_AIS_CPA() {
1382 b_show_AIS_CPA = !b_show_AIS_CPA ? true :
false;
1385void AisTargetData::ToggleShowTrack() {
1386 b_show_track = !b_show_track ? true :
false;
1389bool AisTargetData::IsValidMID(
int mid) {
1390 if (mid >= 201 && mid <= 775)
return true;
1396wxString AisTargetData::GetCountryCode(
bool b_CntryLongStr) {
1397 if (Class == AIS_BUOY)
return "";
1400 int tmpMmsi = met_data.original_mmsi ? met_data.original_mmsi : MMSI;
1402 int nMID = tmpMmsi / 1000000;
1403 if (!IsValidMID(nMID) || Class == AIS_ATON) {
1406 if (tmpMmsi < 1000 || 97 == tmpMmsi / 10000000)
return "";
1411 bool foundMID =
false;
1413 i = nMID > 900 ? 2 : 0;
1414 for (i; i < s_mmsi.length() - 3; i++) {
1415 nMID = wxAtoi(s_mmsi.Mid(i, 3));
1416 if (IsValidMID(nMID)) {
1421 if (!foundMID)
return "";
1424#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1428 return b_CntryLongStr ? _(
"Albania") :
"AL";
1430 return b_CntryLongStr ? _(
"Andorra") :
"AD";
1432 return b_CntryLongStr ? _(
"Austria") :
"AT";
1434 return b_CntryLongStr ? _(
"Azores") :
"AZ";
1436 return b_CntryLongStr ? _(
"Belgium") :
"BE";
1438 return b_CntryLongStr ? _(
"Belarus") :
"BY";
1440 return b_CntryLongStr ? _(
"Bulgaria") :
"BG";
1442 return b_CntryLongStr ? _(
"Vatican City State") :
"VA";
1445 return b_CntryLongStr ? _(
"Cyprus") :
"CY";
1447 return b_CntryLongStr ? _(
"Germany") :
"DE";
1449 return b_CntryLongStr ? _(
"Cyprus") :
"CY";
1451 return b_CntryLongStr ? _(
"Georgia") :
"GE";
1453 return b_CntryLongStr ? _(
"Moldova") :
"MD";
1455 return b_CntryLongStr ? _(
"Malta") :
"MT";
1457 return b_CntryLongStr ? _(
"Armenia") :
"AM";
1459 return b_CntryLongStr ? _(
"Germany") :
"DE";
1462 return b_CntryLongStr ? _(
"Denmark") :
"DK";
1464 return b_CntryLongStr ? _(
"Spain") :
"ES";
1466 return b_CntryLongStr ? _(
"Spain") :
"ES";
1470 return b_CntryLongStr ? _(
"France") :
"FR";
1472 return b_CntryLongStr ? _(
"Malta") :
"MT";
1474 return b_CntryLongStr ? _(
"Finland") :
"FI";
1476 return b_CntryLongStr ? _(
"Faroe Islands") :
"FO";
1481 return b_CntryLongStr ? _(
"Great Britain") :
"GB";
1483 return b_CntryLongStr ? _(
"Gibraltar") :
"GI";
1485 return b_CntryLongStr ? _(
"Greece") :
"GR";
1487 return b_CntryLongStr ? _(
"Croatia") :
"HR";
1491 return b_CntryLongStr ? _(
"Greece") :
"GR";
1493 return b_CntryLongStr ? _(
"Morocco") :
"MA";
1495 return b_CntryLongStr ? _(
"Hungary") :
"HU";
1499 return b_CntryLongStr ? _(
"Netherlands") :
"NL";
1501 return b_CntryLongStr ? _(
"Italy") :
"IT";
1504 return b_CntryLongStr ? _(
"Malta") :
"MT";
1506 return b_CntryLongStr ? _(
"Ireland") :
"IE";
1508 return b_CntryLongStr ? _(
"Iceland") :
"IS";
1510 return b_CntryLongStr ? _(
"Liechtenstein") :
"LI";
1512 return b_CntryLongStr ? _(
"Luxembourg") :
"LU";
1514 return b_CntryLongStr ? _(
"Monaco") :
"MC";
1516 return b_CntryLongStr ? _(
"Madeira") :
"PT";
1518 return b_CntryLongStr ? _(
"Malta") :
"MT";
1522 return b_CntryLongStr ? _(
"Norway") :
"NO";
1524 return b_CntryLongStr ? _(
"Poland") :
"PL";
1526 return b_CntryLongStr ? _(
"Montenegro") :
"ME";
1528 return b_CntryLongStr ? _(
"Portugal") :
"PT";
1530 return b_CntryLongStr ? _(
"Romania") :
"RO";
1533 return b_CntryLongStr ? _(
"Sweden") :
"SE";
1535 return b_CntryLongStr ? _(
"Slovak Republic") :
"SK";
1537 return b_CntryLongStr ? _(
"San Marino") :
"SM";
1539 return b_CntryLongStr ? _(
"Switzerland") :
"CH";
1541 return b_CntryLongStr ? _(
"Czech Republic") :
"CZ";
1543 return b_CntryLongStr ? _(
"Turkey") :
"TR";
1545 return b_CntryLongStr ? _(
"Ukraine") :
"UA";
1547 return b_CntryLongStr ? _(
"Russian") :
"RU";
1549 return b_CntryLongStr ? _(
"Macedonia") :
"MK";
1551 return b_CntryLongStr ? _(
"Latvia") :
"LV";
1553 return b_CntryLongStr ? _(
"Estonia") :
"EE";
1555 return b_CntryLongStr ? _(
"Lithuania") :
"LT";
1557 return b_CntryLongStr ? _(
"Slovenia") :
"SI";
1559 return b_CntryLongStr ? _(
"Serbia") :
"RS";
1561 return b_CntryLongStr ? _(
"Anguilla") :
"AI";
1563 return b_CntryLongStr ? _(
"Alaska") :
"AK";
1566 return b_CntryLongStr ? _(
"Antigua and Barbuda") :
"AG";
1568 return b_CntryLongStr ? _(
"Antilles") :
"AN";
1570 return b_CntryLongStr ? _(
"Aruba") :
"AW";
1573 return b_CntryLongStr ? _(
"Bahamas") :
"BS";
1575 return b_CntryLongStr ? _(
"Bermuda") :
"BM";
1577 return b_CntryLongStr ? _(
"Bahamas") :
"BS";
1579 return b_CntryLongStr ? _(
"Belize") :
"BZ";
1581 return b_CntryLongStr ? _(
"Barbados") :
"BB";
1583 return b_CntryLongStr ? _(
"Canada") :
"CA";
1585 return b_CntryLongStr ? _(
"Cayman Islands") :
"KY";
1587 return b_CntryLongStr ? _(
"Costa Rica") :
"CR";
1589 return b_CntryLongStr ? _(
"Cuba") :
"CU";
1591 return b_CntryLongStr ? _(
"Dominica") :
"DM";
1593 return b_CntryLongStr ? _(
"Dominican Republic") :
"DM";
1595 return b_CntryLongStr ? _(
"Guadeloupe") :
"GP";
1597 return b_CntryLongStr ? _(
"Grenada") :
"GD";
1599 return b_CntryLongStr ? _(
"Greenland") :
"GL";
1601 return b_CntryLongStr ? _(
"Guatemala") :
"GT";
1603 return b_CntryLongStr ? _(
"Honduras") :
"HN";
1605 return b_CntryLongStr ? _(
"Haiti") :
"HT";
1607 return b_CntryLongStr ? _(
"United States of America") :
"US";
1609 return b_CntryLongStr ? _(
"Jamaica") :
"JM";
1611 return b_CntryLongStr ? _(
"Saint Kitts and Nevis") :
"KN";
1613 return b_CntryLongStr ? _(
"Saint Lucia") :
"LC";
1615 return b_CntryLongStr ? _(
"Mexico") :
"MX";
1617 return b_CntryLongStr ? _(
"Martinique") :
"MQ";
1619 return b_CntryLongStr ? _(
"Montserrat") :
"MS";
1621 return b_CntryLongStr ? _(
"Nicaragua") :
"NI";
1629 return b_CntryLongStr ? _(
"Panama") :
"PA";
1631 return b_CntryLongStr ? _(
"Puerto Rico") :
"PR";
1633 return b_CntryLongStr ? _(
"El Salvador") :
"SV";
1635 return b_CntryLongStr ? _(
"Saint Pierre and Miquelon") :
"PM";
1637 return b_CntryLongStr ? _(
"Trinidad and Tobago") :
"TT";
1639 return b_CntryLongStr ? _(
"Turks and Caicos Islands") :
"TC";
1644 return b_CntryLongStr ? _(
"United States of America") :
"US";
1650 return b_CntryLongStr ? _(
"Panama") :
"PA";
1654 return b_CntryLongStr ? _(
"Saint Vincent and the Grenadines") :
"VC";
1656 return b_CntryLongStr ? _(
"British Virgin Islands") :
"VG";
1658 return b_CntryLongStr ? _(
"United States Virgin Islands") :
"AE";
1660 return b_CntryLongStr ? _(
"Afghanistan") :
"AF";
1662 return b_CntryLongStr ? _(
"Saudi Arabia") :
"SA";
1664 return b_CntryLongStr ? _(
"Bangladesh") :
"BD";
1666 return b_CntryLongStr ? _(
"Bahrain") :
"BH";
1668 return b_CntryLongStr ? _(
"Bhutan") :
"BT";
1672 return b_CntryLongStr ? _(
"China") :
"CN";
1674 return b_CntryLongStr ? _(
"Taiwan") :
"TW";
1676 return b_CntryLongStr ? _(
"Sri Lanka") :
"LK";
1678 return b_CntryLongStr ? _(
"India") :
"IN";
1680 return b_CntryLongStr ? _(
"Iran") :
"IR";
1682 return b_CntryLongStr ? _(
"Azerbaijani Republic") :
"AZ";
1684 return b_CntryLongStr ? _(
"Iraq") :
"IQ";
1686 return b_CntryLongStr ? _(
"Israel") :
"IL";
1688 return b_CntryLongStr ? _(
"Japan") :
"JP";
1690 return b_CntryLongStr ? _(
"Japan") :
"JP";
1692 return b_CntryLongStr ? _(
"Turkmenistan") :
"TM";
1694 return b_CntryLongStr ? _(
"Kazakhstan") :
"KZ";
1696 return b_CntryLongStr ? _(
"Uzbekistan") :
"UZ";
1698 return b_CntryLongStr ? _(
"Jordan") :
"JO";
1701 return b_CntryLongStr ? _(
"Korea") :
"KR";
1703 return b_CntryLongStr ? _(
"Palestine") :
"PS";
1705 return b_CntryLongStr ? _(
"People's Rep. of Korea") :
"KP";
1707 return b_CntryLongStr ? _(
"Kuwait") :
"KW";
1709 return b_CntryLongStr ? _(
"Lebanon") :
"LB";
1711 return b_CntryLongStr ? _(
"Kyrgyz Republic") :
"KG";
1713 return b_CntryLongStr ? _(
"Macao") :
"MO";
1715 return b_CntryLongStr ? _(
"Maldives") :
"MV";
1717 return b_CntryLongStr ? _(
"Mongolia") :
"MN";
1719 return b_CntryLongStr ? _(
"Nepal") :
"NP";
1721 return b_CntryLongStr ? _(
"Oman") :
"OM";
1723 return b_CntryLongStr ? _(
"Pakistan") :
"PK";
1725 return b_CntryLongStr ? _(
"Qatar") :
"QA";
1727 return b_CntryLongStr ? _(
"Syrian Arab Republic") :
"SY";
1730 return b_CntryLongStr ? _(
"United Arab Emirates") :
"AE";
1732 return b_CntryLongStr ? _(
"Tajikistan") :
"TJ";
1735 return b_CntryLongStr ? _(
"Yemen") :
"YE";
1737 return b_CntryLongStr ? _(
"Hong Kong") :
"HK";
1739 return b_CntryLongStr ? _(
"Bosnia and Herzegovina") :
"BA";
1741 return b_CntryLongStr ? _(
"Adelie Land") :
"TF";
1743 return b_CntryLongStr ? _(
"Australia") :
"AU";
1745 return b_CntryLongStr ? _(
"Myanmar") :
"MM";
1747 return b_CntryLongStr ? _(
"Brunei Darussalam") :
"BN";
1749 return b_CntryLongStr ? _(
"Micronesia") :
"FM";
1751 return b_CntryLongStr ? _(
"Palau") :
"PW";
1753 return b_CntryLongStr ? _(
"New Zealand") :
"NZ";
1756 return b_CntryLongStr ? _(
"Cambodia") :
"KH";
1758 return b_CntryLongStr ? _(
"Christmas Island") :
"CX";
1760 return b_CntryLongStr ? _(
"Cook Islands") :
"CK";
1762 return b_CntryLongStr ? _(
"Fiji") :
"FJ";
1764 return b_CntryLongStr ? _(
"Cocos (Keeling) Islands") :
"CC";
1766 return b_CntryLongStr ? _(
"Indonesia") :
"ID";
1768 return b_CntryLongStr ? _(
"Kiribati") :
"KI";
1770 return b_CntryLongStr ? _(
"Lao People's Dem. Rep.") :
"LA";
1772 return b_CntryLongStr ? _(
"Malaysia") :
"MY";
1774 return b_CntryLongStr ? _(
"Northern Mariana Islands") :
"MP";
1776 return b_CntryLongStr ? _(
"Marshall Islands") :
"MH";
1778 return b_CntryLongStr ? _(
"New Caledonia") :
"NC";
1780 return b_CntryLongStr ? _(
"Niue") :
"NU";
1782 return b_CntryLongStr ? _(
"Nauru") :
"NR";
1784 return b_CntryLongStr ? _(
"French Polynesia") :
"PF";
1786 return b_CntryLongStr ? _(
"Philippines") :
"PH";
1788 return b_CntryLongStr ? _(
"East Timor") :
"TL";
1790 return b_CntryLongStr ? _(
"Papua New Guinea") :
"PG";
1792 return b_CntryLongStr ? _(
"Pitcairn Island") :
"PN";
1794 return b_CntryLongStr ? _(
"Solomon Islands") :
"SB";
1796 return b_CntryLongStr ? _(
"American Samoa") :
"AS";
1798 return b_CntryLongStr ? _(
"Samoa") :
"WS";
1803 return b_CntryLongStr ? _(
"Singapore") :
"SG";
1805 return b_CntryLongStr ? _(
"Thailand") :
"TH";
1807 return b_CntryLongStr ? _(
"Tonga") :
"TO";
1809 return b_CntryLongStr ? _(
"Tuvalu") :
"TV";
1811 return b_CntryLongStr ? _(
"Viet Nam") :
"VN";
1814 return b_CntryLongStr ? _(
"Vanuatu") :
"VU";
1816 return b_CntryLongStr ? _(
"Wallis and Futuna Islands") :
"WF";
1818 return b_CntryLongStr ? _(
"South Africa") :
"ZA";
1820 return b_CntryLongStr ? _(
"Angola") :
"AO";
1822 return b_CntryLongStr ? _(
"Algeria") :
"DZ";
1824 return b_CntryLongStr ? _(
"Saint Paul") :
"TF";
1826 return b_CntryLongStr ? _(
"Ascension Island") :
"SH";
1828 return b_CntryLongStr ? _(
"Burundi") :
"BI";
1830 return b_CntryLongStr ? _(
"Benin") :
"BJ";
1832 return b_CntryLongStr ? _(
"Botswana") :
"BW";
1834 return b_CntryLongStr ? _(
"Central African Republic") :
"CF";
1836 return b_CntryLongStr ? _(
"Cameroon") :
"CM";
1838 return b_CntryLongStr ? _(
"Congo") :
"CD";
1840 return b_CntryLongStr ? _(
"Comoros") :
"KM";
1842 return b_CntryLongStr ? _(
"Capo Verde") :
"CV";
1844 return b_CntryLongStr ? _(
"Crozet Archipelago") :
"TF";
1846 return b_CntryLongStr ? _(
"Ivory Coast") :
"CI";
1848 return b_CntryLongStr ? _(
"Comoros (Union of the)") :
"KM";
1850 return b_CntryLongStr ? _(
"Djibouti") :
"DJ";
1852 return b_CntryLongStr ? _(
"Egypt") :
"EG";
1854 return b_CntryLongStr ? _(
"Ethiopia") :
"ET";
1856 return b_CntryLongStr ? _(
"Eritrea") :
"ER";
1858 return b_CntryLongStr ? _(
"Gabonese Republic") :
"GA";
1860 return b_CntryLongStr ? _(
"Ghana") :
"GH";
1862 return b_CntryLongStr ? _(
"Gambia") :
"GM";
1864 return b_CntryLongStr ? _(
"Guinea-Bissau") :
"GW";
1866 return b_CntryLongStr ? _(
"Equatorial Guinea") :
"GQ";
1868 return b_CntryLongStr ? _(
"Guinea") :
"GN";
1870 return b_CntryLongStr ? _(
"Burkina Faso") :
"BF";
1872 return b_CntryLongStr ? _(
"Kenya") :
"KE";
1874 return b_CntryLongStr ? _(
"Kerguelen Islands") :
"TF";
1877 return b_CntryLongStr ? _(
"Liberia") :
"LR";
1879 return b_CntryLongStr ? _(
"South Sudan (Republic of)") :
"SS";
1881 return b_CntryLongStr ? _(
"Libya") :
"LY";
1883 return b_CntryLongStr ? _(
"Lesotho") :
"LS";
1885 return b_CntryLongStr ? _(
"Mauritius") :
"MU";
1887 return b_CntryLongStr ? _(
"Madagascar") :
"MG";
1889 return b_CntryLongStr ? _(
"Mali") :
"ML";
1891 return b_CntryLongStr ? _(
"Mozambique") :
"MZ";
1893 return b_CntryLongStr ? _(
"Mauritania") :
"MR";
1895 return b_CntryLongStr ? _(
"Malawi") :
"MW";
1897 return b_CntryLongStr ? _(
"Niger") :
"NE";
1899 return b_CntryLongStr ? _(
"Nigeria") :
"NG";
1901 return b_CntryLongStr ? _(
"Namibia") :
"NA";
1903 return b_CntryLongStr ? _(
"Reunion") :
"RE";
1905 return b_CntryLongStr ? _(
"Rwanda") :
"RW";
1907 return b_CntryLongStr ? _(
"Sudan") :
"SD";
1909 return b_CntryLongStr ? _(
"Senegal") :
"SN";
1911 return b_CntryLongStr ? _(
"Seychelles") :
"SC";
1913 return b_CntryLongStr ? _(
"Saint Helena") :
"SH";
1915 return b_CntryLongStr ? _(
"Somalia") :
"SO";
1917 return b_CntryLongStr ? _(
"Sierra Leone") :
"SL";
1919 return b_CntryLongStr ? _(
"Sao Tome and Principe") :
"ST";
1921 return b_CntryLongStr ? _(
"Eswatini") :
"SZ";
1923 return b_CntryLongStr ? _(
"Chad") :
"TD";
1925 return b_CntryLongStr ? _(
"Togolese Republic") :
"TG";
1927 return b_CntryLongStr ? _(
"Tunisia") :
"TN";
1929 return b_CntryLongStr ? _(
"Tanzania") :
"TZ";
1931 return b_CntryLongStr ? _(
"Uganda") :
"UG";
1933 return b_CntryLongStr ? _(
"Dem Rep.of the Congo") :
"CD";
1935 return b_CntryLongStr ? _(
"Tanzania") :
"TZ";
1937 return b_CntryLongStr ? _(
"Zambia") :
"ZM";
1939 return b_CntryLongStr ? _(
"Zimbabwe") :
"ZW";
1941 return b_CntryLongStr ? _(
"Argentine Republic") :
"AR";
1943 return b_CntryLongStr ? _(
"Brazil") :
"BR";
1945 return b_CntryLongStr ? _(
"Bolivia") :
"BO";
1947 return b_CntryLongStr ? _(
"Chile") :
"CL";
1949 return b_CntryLongStr ? _(
"Colombia") :
"CO";
1951 return b_CntryLongStr ? _(
"Ecuador") :
"EC";
1953 return b_CntryLongStr ? _(
"Falkland Islands") :
"FK";
1955 return b_CntryLongStr ? _(
"France - Guiana") :
"GY";
1957 return b_CntryLongStr ? _(
"Guyana") :
"GY";
1959 return b_CntryLongStr ? _(
"Paraguay") :
"PY";
1961 return b_CntryLongStr ? _(
"Peru") :
"PE";
1963 return b_CntryLongStr ? _(
"Suriname") :
"SR";
1965 return b_CntryLongStr ? _(
"Uruguay") :
"UY";
1967 return b_CntryLongStr ? _(
"Venezuela") :
"VE";
1977wxString ais_get_type(
int index) {
1978 static const wxString ais_type[] = {
1979 _(
"Fishing Vessel"),
1981 _(
"Towing Vessel, Long"),
1983 _(
"Diving Ops Vessel"),
1984 _(
"Military Vessel"),
1985 _(
"Sailing Vessel"),
1986 _(
"Pleasure craft"),
1987 _(
"High Speed Craft"),
1989 _(
"Search and Rescue Vessel"),
1992 _(
"Pollution Control Vessel"),
1993 _(
"Law Enforcement Vessel"),
1994 _(
"Medical Transport"),
1995 _(
"Passenger Ship"),
2000 _(
"Reference Point"),
2002 _(
"Fixed Structure"),
2005 _(
"Light w/Sectors"),
2006 _(
"Leading Light Front"),
2007 _(
"Leading Light Rear"),
2008 _(
"Cardinal N Beacon"),
2009 _(
"Cardinal E Beacon"),
2010 _(
"Cardinal S Beacon"),
2011 _(
"Cardinal W Beacon"),
2012 _(
"Beacon, Port Hand"),
2013 _(
"Beacon, Starboard Hand"),
2014 _(
"Beacon, Preferred Channel Port Hand"),
2015 _(
"Beacon, Preferred Channel Starboard Hand"),
2016 _(
"Beacon, Isolated Danger"),
2017 _(
"Beacon, Safe Water"),
2018 _(
"Beacon, Special Mark"),
2019 _(
"Cardinal Mark N"),
2020 _(
"Cardinal Mark E"),
2021 _(
"Cardinal Mark S"),
2022 _(
"Cardinal Mark W"),
2023 _(
"Port Hand Mark"),
2024 _(
"Starboard Hand Mark"),
2025 _(
"Preferred Channel Port Hand"),
2026 _(
"Preferred Channel Starboard Hand"),
2027 _(
"Isolated Danger"),
2030 _(
"Light Vessel/Rig"),
2032 _(
"Position Report"),
2034 _(
"ARPA radar target"),
2035 _(
"APRS Position Report"),
2036 _(
"Buoy or similar")
2039 return ais_type[index];
2042wxString ais_get_short_type(
int index) {
2043 static const wxString short_ais_type[] = {
2102 _(
"Buoy or similar")
2104 return short_ais_type[index];
Global state for AIS decoder.
Global variables stored in configuration file.
double toUsrDepth(double m_depth, int unit)
Convert a depth from meters to user display units.
double toUsrTemp(double cel_temp, int unit)
Convert a temperature from Celsius to user display units.
double toUsrDistance(double nm_distance, int unit)
Convert a distance from nautical miles (NMi) to user display units.
wxString FormatDistanceAdaptive(double distance)
Format a distance (given in nautical miles) using the current distance preference,...
Navigation Utility Functions without GUI dependencies.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
Position, course, speed, etc.