OpenCPN Partial API docs
Loading...
Searching...
No Matches
ais_target_data.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 *
5 ***************************************************************************
6 * Copyright (C) 2010 by David S. Register *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 ***************************************************************************
23 */
24#include <unordered_map>
25
26#include <wx/datetime.h>
27#include <wx/string.h>
28
29#include "ais_target_data.h"
30#include "config_vars.h"
31#include "ocpn_frame.h"
32#include "navutil_base.h"
33
34extern bool bGPSValid;
35extern bool g_bAISRolloverShowClass;
36extern bool g_bAISRolloverShowCOG;
37extern bool g_bAISRolloverShowCPA;
38extern bool g_bShowMag;
39extern bool g_bShowTrue;
40//extern MyFrame *gFrame;
41extern bool g_bAISShowTracks;
42extern double gVar;
43
44static std::unordered_map<int, wxString> s_ERI_hash;
45
46void make_hash_ERI(int key, const wxString &description) {
47 s_ERI_hash[key] = description;
48}
49
50void clear_hash_ERI() { s_ERI_hash.clear(); }
51
52static wxString FormatTimeAdaptive(int seconds) {
53 int m = seconds / 60;
54 if (seconds < 100)
55 return wxString::Format(_T("%3ds"), seconds);
56 else if (seconds < 3600) {
57 int m = seconds / 60;
58 int s = seconds % 60;
59 return wxString::Format(_T("%2dmin %02ds"), m, s);
60 }
61 int h = seconds / 3600;
62 m -= h * 60;
63 return wxString::Format(_T("%2dh %02dmin"), h, m);
64}
65
66static wxString html_escape(const wxString &src) {
67 // Escape &, <, > as well as single and double quotes for HTML.
68 wxString ret = src;
69
70 ret.Replace(_T("<"), _T("&lt;"));
71 ret.Replace(_T(">"), _T("&gt;"));
72
73 // only < and > in 6 bits AIS ascii
74 // ret.Replace(_T("\""), _T("&quot;"));
75 // ret.Replace(_T("&"), _T("&amp;"));
76 // ret.Replace(_T("'"), _T("&#39;"));
77
78 // Do we care about multiple spaces?
79 // ret.Replace(_T(" "), _T("&nbsp;"));
80 return ret;
81}
82
83wxString trimAISField(char *data) {
84 // Clip any unused characters (@) from data
85
86 wxString field = wxString::From8BitData(data);
87 while (field.Right(1) == '@' || field.Right(1) == ' ') field.RemoveLast();
88
89 // And remove any leading spaces to properly sort and display
90 field.Trim(false);
91
92 return field;
93}
94
95
96wxString ais_get_status(int index) {
97 static const wxString ais_status[] = {
98 _("Underway using Engine"),
99 _("At Anchor"),
100 _("Not Under Command"),
101 _("Restricted Manoeuvrability"),
102 _("Constrained by draught"),
103 _("Moored"),
104 _("Aground"),
105 _("Engaged in Fishing"),
106 _("Underway Sailing"),
107 _("High Speed Craft"),
108 _("Wing In Ground Effect"),
109 _("Power-driven vessel towing astern (regional use)"),
110 _("Power-driven vessel pushing ahead or towing alongside (regional use)"),
111 _("Reserved 13"),
112 _("Reserved 14"),
113 _("Undefined"),
114 _("AtoN Virtual"),
115 _("AtoN Virtual (On Position)"),
116 _("AtoN Virtual (Off Position)"),
117 _("AtoN Real"),
118 _("AtoN Real (On Position)"),
119 _("AtoN Real(Off Position)")};
120
121 return ais_status[index];
122}
123
124AisTargetData::AisTargetData(AisTargetCallbacks cb ) : m_callbacks(cb) {
125 strncpy(ShipName, "Unknown ", SHIP_NAME_LEN);
126 strncpy(CallSign, " ", 8);
127 strncpy(Destination, " ", DESTINATION_LEN);
128 ShipNameExtension[0] = 0;
129 b_show_AIS_CPA = false;
130
131 SOG = 555.;
132 COG = 666.;
133 HDG = 511.;
134 ROTAIS = -128;
135 Lat = 0.;
136 Lon = 0.;
137
138 wxDateTime now = wxDateTime::Now();
139 now.MakeGMT();
140 PositionReportTicks = now.GetTicks(); // Default is my idea of NOW
141 StaticReportTicks = now.GetTicks();
142 b_lost = false;
143 b_removed = false;
144
145 IMO = 0;
146 MID = 555;
147 MMSI = 666;
148 NavStatus = UNDEFINED;
149 SyncState = 888;
150 SlotTO = 999;
151 ShipType = 19; // "Unknown"
152 b_isDSCtarget = false;
153 m_dscNature = 99;
154 m_dscTXmmsi = 666;
155
156 CPA = 100; // Large values avoid false alarms
157 TCPA = 100;
158
159 Range_NM = -1.;
160 Brg = -1.;
161
162 DimA = DimB = DimC = DimD = 0;
163 ;
164
165 ETA_Mo = 0;
166 ETA_Day = 0;
167 ETA_Hr = 24;
168 ETA_Min = 60;
169
170 Draft = 0.;
171
172 RecentPeriod = 0;
173
174 m_utc_hour = 0;
175 m_utc_min = 0;
176 m_utc_sec = 0;
177
178 Class = AIS_CLASS_A; // default
179 n_alert_state = AIS_NO_ALERT;
180 b_suppress_audio = false;
181 b_positionDoubtful = false;
182 b_positionOnceValid = false;
183 b_nameValid = false;
184
185 Euro_Length = 0; // Extensions for European Inland AIS
186 Euro_Beam = 0;
187 Euro_Draft = 0;
188 strncpy(Euro_VIN, " ", 8);
189 UN_shiptype = 0;
190
191 b_isEuroInland = false;
192 b_blue_paddle = false;
193
194 b_NoTrack = false;
195 b_OwnShip = false;
196 b_PersistTrack = false;
197 b_mPropPersistTrack = false;
198 b_in_ack_timeout = false;
199
200 b_active = false;
201 blue_paddle = 0;
202 bCPA_Valid = false;
203 b_isFollower = false;
204 ROTIND = 0;
205 b_show_track = g_bAISShowTracks;
206 b_SarAircraftPosnReport = false;
207 altitude = 0;
208 b_nameFromCache = false;
209 importance = 0.0;
210 for (unsigned int i = 0; i < AIS_TARGETDATA_MAX_CANVAS; i++)
211 last_scale[i] = 50;
212}
213
214void AisTargetData::CloneFrom(AisTargetData *q) {
215 strncpy(ShipName, q->ShipName, SHIP_NAME_LEN);
216 strncpy(CallSign, q->CallSign, 8);
217 strncpy(Destination, q->Destination, DESTINATION_LEN);
218 ShipNameExtension[0] = 0;
219 b_show_AIS_CPA = q->b_show_AIS_CPA;
220 ;
221
222 SOG = q->SOG;
223 COG = q->COG;
224 HDG = q->HDG;
225 ROTAIS = q->ROTAIS;
226 Lat = q->Lat;
227 Lon = q->Lon;
228
229 PositionReportTicks = q->PositionReportTicks;
230 StaticReportTicks = q->StaticReportTicks;
231 b_lost = q->b_lost;
232 b_removed = q->b_removed;
233
234 IMO = q->IMO;
235 MID = q->MID;
236 MMSI = q->MMSI;
237 NavStatus = q->NavStatus;
238 SyncState = q->SyncState;
239 SlotTO = q->SlotTO;
240 ShipType = q->ShipType;
241 b_isDSCtarget = q->b_isDSCtarget;
242 m_dscNature = q->m_dscNature;
243 m_dscTXmmsi = q->m_dscTXmmsi;
244
245 CPA = q->CPA;
246 TCPA = q->TCPA;
247
248 Range_NM = q->Range_NM;
249 Brg = q->Brg;
250
251 DimA = q->DimA;
252 DimB = q->DimB;
253 DimC = q->DimC;
254 DimD = q->DimD;
255
256 ETA_Mo = q->ETA_Mo;
257 ETA_Day = q->ETA_Day;
258 ETA_Hr = q->ETA_Hr;
259 ETA_Min = q->ETA_Min;
260
261 Draft = q->Draft;
262
263 RecentPeriod = q->RecentPeriod;
264
265 m_utc_hour = q->m_utc_hour;
266 m_utc_min = q->m_utc_min;
267 m_utc_sec = q->m_utc_sec;
268
269 Class = q->Class;
270 n_alert_state = q->n_alert_state;
271 b_suppress_audio = q->b_suppress_audio;
272 b_positionDoubtful = q->b_positionDoubtful;
273 b_positionOnceValid = q->b_positionOnceValid;
274 b_nameValid = q->b_nameValid;
275
276 Euro_Length = q->Euro_Length; // Extensions for European Inland AIS
277 Euro_Beam = q->Euro_Beam;
278 Euro_Draft = q->Euro_Draft;
279 memcpy(Euro_VIN, q->Euro_VIN, EURO_VIN_LEN);
280 UN_shiptype = q->UN_shiptype;
281
282 b_isEuroInland = q->b_isEuroInland;
283 b_blue_paddle = q->b_blue_paddle;
284
285 b_OwnShip = q->b_OwnShip;
286 b_in_ack_timeout = q->b_in_ack_timeout;
287
288 m_ptrack = q->m_ptrack;
289
290 b_active = q->b_active;
291 blue_paddle = q->blue_paddle;
292 bCPA_Valid = q->bCPA_Valid;
293 ROTIND = q->ROTIND;
294 b_show_track = q->b_show_track;
295 b_SarAircraftPosnReport = q->b_SarAircraftPosnReport;
296 altitude = q->altitude;
297}
298
299AisTargetData::~AisTargetData() { m_ptrack.clear(); }
300
301wxString AisTargetData::GetFullName(void) {
302 wxString retName;
303 if (b_nameValid) {
304 wxString shipName = trimAISField(ShipName);
305 if (shipName == _T("Unknown"))
306 retName = wxGetTranslation(shipName);
307 else
308 retName = shipName;
309
310 if (strlen(ShipNameExtension)) {
311 wxString shipNameExt = trimAISField(ShipNameExtension);
312 retName += shipNameExt;
313 }
314 }
315
316 return retName;
317}
318
319wxString AisTargetData::BuildQueryResult(void) {
320 wxString html;
321 wxDateTime now = wxDateTime::Now();
322
323 wxString tableStart = _T("\n<table border=0 cellpadding=1 cellspacing=0>\n");
324 wxString tableEnd = _T("</table>\n\n");
325 wxString rowStart = _T("<tr><td><font size=-2>");
326 wxString rowStartH = _T("<tr><td nowrap>");
327 wxString rowSeparator = _T("</font></td><td></td><td><b>");
328 wxString rowSeparatorH = _T("</td><td></td><td>");
329 wxString colSeparator = _T("<td></td>");
330 wxString rowEnd = _T("</b></td></tr>\n");
331 wxString vertSpacer =
332 _T("<tr><td></td></tr><tr><td></td></tr><tr><td></td></tr>\n\n");
333
334 wxString IMOstr, MMSIstr, ClassStr;
335
336 html << tableStart << _T("<tr><td nowrap colspan=2>");
337 if (b_nameValid) {
338 html << _T("<font size=+2><i><b>") << GetFullName();
339 html << _T("</b></i></font>&nbsp;&nbsp;<b>");
340 }
341
342 if ((Class != AIS_ATON) && (Class != AIS_BASE) && (Class != AIS_GPSG_BUDDY) &&
343 (Class != AIS_SART)) {
344 html << trimAISField(CallSign) << _T("</b>") << rowEnd;
345
346 if (Class != AIS_CLASS_B) {
347 if (IMO > 0) IMOstr = wxString::Format(_T("%08d"), abs(IMO));
348 }
349 } else
350 html << _T("</b>") << rowEnd;
351
352 html << vertSpacer;
353
354 if (Class != AIS_GPSG_BUDDY) {
355 MMSIstr = wxString::Format(_T("%09d"), abs(MMSI));
356 }
357 ClassStr = wxGetTranslation(Get_class_string(false));
358
359 if (Class == AIS_ATON) {
360 wxString cls(_T("AtoN: "));
361 cls += Get_vessel_type_string(false);
362 ClassStr = wxGetTranslation(cls);
363 }
364
365 if (b_SarAircraftPosnReport) {
366 int airtype = (MMSI % 1000) / 100;
367 ClassStr = airtype == 5 ? _("SAR Helicopter") : _("SAR Aircraft");
368 }
369
370 if (IMOstr.Length())
371 html << _T("<tr><td colspan=2><table width=100% border=0 cellpadding=0 ")
372 _T("cellspacing=0>")
373 << rowStart << _("MMSI")
374 << _T("</font></td><td>&nbsp;</td><td><font size=-2>") << _("Class")
375 << _T("</font></td><td>&nbsp;</td><td align=right><font size=-2>")
376 << _("IMO") << _T("</font></td></tr>") << rowStartH << _T("<b>")
377 << MMSIstr << _T("</b></td><td>&nbsp;</td><td><b>") << ClassStr
378 << _T("</b></td><td>&nbsp;</td><td align=right><b>") << IMOstr
379 << rowEnd << _T("</table></td></tr>");
380
381 else
382 html << _T("<tr><td colspan=2><table width=100% border=0 cellpadding=0 ")
383 _T("cellspacing=0>")
384 << rowStart << _("MMSI")
385 << _T("</font></td><td>&nbsp;</td><td align=right><font size=-2>")
386 << _("Class") << _T("</font></td></tr>") << rowStartH << _T("<b>")
387 << MMSIstr << _T("</b></td><td>&nbsp;</td><td align=right><b>")
388 << ClassStr << rowEnd << _T("</table></td></tr>");
389
390 if ((Class != AIS_SART) ) //&& (Class != AIS_DSC))
391 html << _T("<tr><td colspan=2><table width=100% border=0 cellpadding=0 ")
392 _T("cellspacing=0>")
393 << rowStart
394 << ((Class == AIS_BASE || Class == AIS_ATON) ? _("Nation") : _("Flag"))
395 << rowEnd << _T("</font></td></tr>") << rowStartH << _T("<b>")
396 << GetCountryCode(true) << rowEnd << _T("</table></td></tr>");
397
398 html << vertSpacer;
399
400 wxString navStatStr;
401 if ((Class != AIS_BASE) && (Class != AIS_CLASS_B) && (Class != AIS_SART)) {
402 if ((NavStatus <= 21) && (NavStatus >= 0))
403 navStatStr = wxGetTranslation(ais_get_status(NavStatus));
404 } else if (Class == AIS_SART) {
405 if (NavStatus == RESERVED_14)
406 navStatStr = _("Active");
407 else if (NavStatus == UNDEFINED)
408 navStatStr = _("Testing");
409 }
410
411 wxString sart_sub_type;
412 if (Class == AIS_SART) {
413 int mmsi_start = MMSI / 1000000;
414 switch (mmsi_start) {
415 case 970:
416 // sart_sub_type = _T("SART");
417 break;
418 case 972:
419 sart_sub_type = _T("MOB");
420 break;
421 case 974:
422 sart_sub_type = _T("EPIRB");
423 break;
424 default:
425 sart_sub_type = _("Unknown");
426 break;
427 }
428 }
429
430 wxString AISTypeStr, UNTypeStr, sizeString;
431 if ((Class != AIS_BASE) && (Class != AIS_SART) && (Class != AIS_DSC)) {
432 // Ship type
433 AISTypeStr = wxGetTranslation(Get_vessel_type_string());
434
435 if (b_isEuroInland && UN_shiptype) {
436 auto it = s_ERI_hash.find(UN_shiptype);
437 wxString type;
438 if (it == s_ERI_hash.end())
439 type = _("Undefined");
440 else
441 type = it->second;
442
443 UNTypeStr = wxGetTranslation(type);
444 }
445
446 if (b_SarAircraftPosnReport) {
447 AISTypeStr.Clear();
448 UNTypeStr.Clear();
449 navStatStr.Clear();
450 }
451
452 if (Class == AIS_SART) {
453 if (MSG_14_text.Len()) {
454 html << rowStart << _("Safety Broadcast Message") << rowEnd << rowStartH
455 << _T("<b>") << MSG_14_text << rowEnd;
456 }
457 }
458
459 // Dimensions
460
461 if (NavStatus != ATON_VIRTUAL && Class != AIS_ARPA && Class != AIS_APRS) {
462 if ((Class == AIS_CLASS_B) || (Class == AIS_ATON)) {
463 sizeString =
464 wxString::Format(_T("%dm x %dm"), (DimA + DimB), (DimC + DimD));
465 } else if (!b_SarAircraftPosnReport) {
466 if ((DimA + DimB + DimC + DimD) == 0) {
467 if (b_isEuroInland) {
468 if (Euro_Length == 0.0) {
469 if (Euro_Draft > 0.01) {
470 sizeString << wxString::Format(_T("---m x ---m x %4.1fm"),
471 Euro_Draft);
472 } else {
473 sizeString << _T("---m x ---m x ---m");
474 }
475 } else {
476 if (Euro_Draft > 0.01) {
477 sizeString << wxString::Format(_T("%5.1fm x %4.1fm x %4.1fm"),
478 Euro_Length, Euro_Beam,
479 Euro_Draft);
480 } else {
481 sizeString << wxString::Format(_T("%5.1fm x %4.1fm x ---m\n\n"),
482 Euro_Length, Euro_Beam);
483 }
484 }
485 } else {
486 if (Draft > 0.01) {
487 sizeString << wxString::Format(_T("---m x ---m x %4.1fm"), Draft);
488 } else {
489 sizeString << _T("---m x ---m x ---m");
490 }
491 }
492 } else if (Draft < 0.01) {
493 sizeString << wxString::Format(_T("%dm x %dm x ---m"), (DimA + DimB),
494 (DimC + DimD));
495 } else {
496 sizeString << wxString::Format(_T("%dm x %dm x %4.1fm"),
497 (DimA + DimB), (DimC + DimD), Draft);
498 }
499 }
500 }
501 }
502
503 if (Class == AIS_SART) {
504 html << _T("<tr><td colspan=2>")
505 << _T("<b>") << AISTypeStr;
506 if (sart_sub_type.Length()) html << _T(" (") << sart_sub_type << _T("), ");
507 html << navStatStr;
508 html << rowEnd << _T("<tr><td colspan=2>")
509 << _T("<b>") << sizeString << rowEnd;
510 }
511
512 else if (Class == AIS_ATON) {
513 html << _T("<tr><td colspan=2>")
514 << _T("<b>") << navStatStr;
515 html << rowEnd << _T("<tr><td colspan=2>")
516 << _T("<b>") << sizeString << rowEnd;
517 }
518 else if (Class == AIS_DSC && (ShipType == 12 || ShipType == 16) ) {
519 if (ShipType == 16) { //Distress relay
520 html << _T("<tr><td colspan=2>") << _T("<b>") << _("Distress relay");
521 if (m_dscTXmmsi > 2000000) {
522 wxString mmsirelay = wxString::Format(_T(" %09d"), abs(m_dscTXmmsi));
523 html << _T(" ") << _("by:") << mmsirelay;
524 }
525 html << _T("<b>") << sizeString << rowEnd;
526 }
527 html << _T("<tr><td colspan=2>") << _("Nature of distress: ")
528 << rowEnd << _T("<tr><td colspan=2>");
529 if (m_dscNature < 13) {
530 html << _T("<tr><td colspan=2>") << _T("<b>") << GetNatureofDistress(m_dscNature)
531 << _T("<b>") << sizeString << rowEnd << _T("<tr><td colspan=2>");
532 }
533 }
534 else if ((Class != AIS_BASE) && (Class != AIS_DSC)) {
535 html << _T("<tr><td colspan=2>")
536 << _T("<b>") << AISTypeStr;
537 if (navStatStr.Length()) html << _T(", ") << navStatStr;
538 if (UNTypeStr.Length()) html << _T(" (UN Type ") << UNTypeStr << _T(")");
539 html << rowEnd << _T("<tr><td colspan=2>")
540 << _T("<b>") << sizeString << rowEnd;
541 }
542
543 if (b_positionOnceValid) {
544 wxString posTypeStr;
545 if (b_positionDoubtful) posTypeStr << _(" (Last Known)");
546
547 now.MakeGMT();
548 int target_age = now.GetTicks() - PositionReportTicks;
549 // wxLogMessage(wxString::Format(_T("** PositionReportTicks %ld %ld %d"),
550 // now.GetTicks(), PositionReportTicks,
551 // target_age));
552
553 html << vertSpacer << rowStart << _("Position") << posTypeStr
554 << _T("</font></td><td align=right><font size=-2>") << _("Report Age")
555 << _T("</font></td></tr>")
556
557 << rowStartH << _T("<b>") << toSDMM(1, Lat)
558 << _T("</b></td><td align=right><b>") << FormatTimeAdaptive(target_age)
559 << rowEnd << rowStartH << _T("<b>") << toSDMM(2, Lon) << rowEnd;
560 }
561
562 wxString courseStr, sogStr, hdgStr, rotStr, rngStr, brgStr, destStr, etaStr;
563
564 if (Class == AIS_GPSG_BUDDY) {
565 long month, year, day;
566 m_date_string.Mid(0, 2).ToLong(&day);
567 m_date_string.Mid(2, 2).ToLong(&month);
568 m_date_string.Mid(4, 2).ToLong(&year);
569 wxDateTime date;
570 date.SetDay(day);
571 date.SetMonth((wxDateTime::Month)(month - 1));
572 date.SetYear(year + 2000);
573
574 wxString f_date = date.FormatISODate();
575
576 html << vertSpacer << rowStart << _("Report as of") << rowEnd << rowStartH
577 << _T("<b>") << f_date + _T("</b> at <b>")
578 << wxString::Format(_T("%d:%d UTC "), m_utc_hour, m_utc_min) << rowEnd;
579 } else {
580 if (Class == AIS_CLASS_A && !b_SarAircraftPosnReport) {
581 html << vertSpacer << rowStart << _("Destination")
582 << _T("</font></td><td align=right><font size=-2>") << _("ETA (UTC)")
583 << _T("</font></td></tr>\n") << rowStartH << _T("<b>");
584 wxString dest = trimAISField(Destination);
585 if (dest.Length())
586 html << html_escape(dest);
587 else
588 html << _T("---");
589 html << _T("</b></td><td nowrap align=right><b>");
590
591 if ((ETA_Mo) && (ETA_Hr < 24)) {
592 int yearOffset = 0;
593 if (now.GetMonth() > (ETA_Mo - 1)) yearOffset = 1;
594 wxDateTime eta(ETA_Day, wxDateTime::Month(ETA_Mo - 1),
595 now.GetYear() + yearOffset, ETA_Hr, ETA_Min);
596 html << eta.Format(_T("%b %d %H:%M"));
597 } else
598 html << _T("---");
599 html << rowEnd;
600 }
601
602 if (Class == AIS_CLASS_A || Class == AIS_CLASS_B || Class == AIS_ARPA ||
603 Class == AIS_APRS || Class == AIS_SART) {
604 int crs = wxRound(COG);
605 if (crs < 360) {
606 wxString magString, trueString;
607 if (g_bShowMag)
608 magString << wxString::Format(wxString("%03d%c(M)"),
609 static_cast<int>(m_callbacks.get_mag(COG)),
610 0x00B0);
611 if (g_bShowTrue)
612 trueString << wxString::Format( wxString("%03d%c "), (int)crs, 0x00B0 );
613
614 courseStr << trueString << magString;
615 } else if (COG == 360.0)
616 courseStr = _T("---");
617 else if (crs == 360)
618 courseStr = _T("0&deg;");
619
620 double speed_show = toUsrSpeed(SOG);
621
622 if ((SOG <= 102.2) || b_SarAircraftPosnReport) {
623 if (speed_show < 10.0)
624 sogStr =
625 wxString::Format(_T("%.2f "), speed_show) + getUsrSpeedUnit();
626 else if (speed_show < 100.0)
627 sogStr =
628 wxString::Format(_T("%.1f "), speed_show) + getUsrSpeedUnit();
629 else
630 sogStr =
631 wxString::Format(_T("%.0f "), speed_show) + getUsrSpeedUnit();
632 }
633 // sogStr = wxString::Format( _T("%5.2f ") +
634 // getUsrSpeedUnit(), toUsrSpeed( SOG ) );
635 else
636 sogStr = _T("---");
637
638 if ((int)HDG != 511)
639 hdgStr = wxString::Format(_T("%03d&deg;"), (int)HDG);
640 else
641 hdgStr = _T("---");
642
643 if (ROTAIS != -128) {
644 if (ROTAIS == 127)
645 rotStr << _T("> 5&deg;/30s ") << _("Right");
646 else if (ROTAIS == -127)
647 rotStr << _T("> 5&deg;/30s ") << _("Left");
648 else {
649 if (ROTIND > 0)
650 rotStr << wxString::Format(_T("%3d&deg;/Min "), ROTIND)
651 << _("Right");
652 else if (ROTIND < 0)
653 rotStr << wxString::Format(_T("%3d&deg;/Min "), -ROTIND)
654 << _("Left");
655 else
656 rotStr = _T("0");
657 }
658 } else if (!b_SarAircraftPosnReport)
659 rotStr = _T("---");
660 }
661 }
662
663 if (b_positionOnceValid && bGPSValid && (Range_NM >= 0.))
664 rngStr = FormatDistanceAdaptive(Range_NM);
665 else
666 rngStr = _T("---");
667
668 int brg = (int)wxRound(Brg);
669 if (Brg > 359.5) brg = 0;
670 if (b_positionOnceValid && bGPSValid && (Brg >= 0.) && (Range_NM > 0.) &&
671 (fabs(Lat) < 85.)) {
672 wxString magString, trueString;
673 if (g_bShowMag)
674 magString << wxString::Format(wxString("%03d%c(M)"),
675 static_cast<int>(m_callbacks.get_mag(COG)),
676 0x00B0);
677 if (g_bShowTrue)
678 trueString << wxString::Format( wxString("%03d%c "), (int)Brg, 0x00B0 );
679
680 brgStr << trueString << magString;
681 } else
682 brgStr = _T("---");
683
684 wxString turnRateHdr; // Blank if ATON or BASE or Special Position Report (9)
685 if ((Class != AIS_ATON) && (Class != AIS_BASE) && (Class != AIS_DSC)) {
686 html << vertSpacer
687 << _T("<tr><td colspan=2><table width=100% border=0 cellpadding=0 ")
688 _T("cellspacing=0>")
689 << rowStart << _("Speed")
690 << _T("</font></td><td>&nbsp;</td><td><font size=-2>") << _("Course")
691 << _T("</font></td><td>&nbsp;</td><td align=right><font size=-2>");
692 if (!b_SarAircraftPosnReport) html << _("Heading");
693
694 html << _T("</font></td></tr>") << rowStartH << _T("<b>") << sogStr
695 << _T("</b></td><td>&nbsp;</td><td><b>") << courseStr
696 << _T("</b></td><td>&nbsp;</td><td align=right><b>");
697 if (!b_SarAircraftPosnReport) html << hdgStr;
698 html << rowEnd << _T("</table></td></tr>") << vertSpacer;
699
700 if (!b_SarAircraftPosnReport) turnRateHdr = _("Turn Rate");
701 }
702 html << _T("<tr><td colspan=2><table width=100% border=0 cellpadding=0 ")
703 _T("cellspacing=0>")
704 << rowStart << _("Range")
705 << _T("</font></td><td>&nbsp;</td><td><font size=-2>") << _("Bearing")
706 << _T("</font></td><td>&nbsp;</td><td align=right><font size=-2>")
707 << turnRateHdr << _T("</font></td></tr>") << rowStartH << _T("<b>")
708 << rngStr << _T("</b></td><td>&nbsp;</td><td><b>") << brgStr
709 << _T("</b></td><td>&nbsp;</td><td align=right><b>");
710
711 if (!b_SarAircraftPosnReport) html << rotStr;
712 html << rowEnd << _T("</table></td></tr>") << vertSpacer;
713
714 if (bCPA_Valid) {
715 wxString tcpaStr;
716 tcpaStr << _T("</b> ") << _("in ") << _T("</td><td align=right><b>")
717 << FormatTimeAdaptive((int)(TCPA * 60.));
718
719 html << /*vertSpacer << */ rowStart << _T("<font size=-2>") << _("CPA")
720 << _T("</font>") << rowEnd << rowStartH << _T("<b>")
721 << FormatDistanceAdaptive(CPA) << tcpaStr << rowEnd;
722 }
723
724 if (Class != AIS_BASE) {
725 if (blue_paddle == 1) {
726 html << rowStart << _("Inland Blue Flag") << rowEnd << rowStartH
727 << _T("<b>") << _("Clear") << rowEnd;
728 } else if (blue_paddle == 2) {
729 html << rowStart << _("Inland Blue Flag") << rowEnd << rowStartH
730 << _T("<b>") << _("Set") << rowEnd;
731 }
732 }
733
734 if (b_SarAircraftPosnReport) {
735 wxString altStr;
736 if (altitude != 4095)
737 altStr.Printf(_T("%4d m"), altitude);
738 else
739 altStr = _("Unknown");
740
741 html << rowStart << _("Altitude")
742 << _T("</font></td><td>&nbsp;</td><td><font size=-0>") << rowStartH
743 << _T("<b>") << altStr << _T("</b></td><td>&nbsp;</td><td><b>")
744 << rowEnd << _T("</table></td></tr>") << vertSpacer;
745 }
746
747 html << _T("</table>");
748 return html;
749}
750
751wxString AisTargetData::GetRolloverString(void) {
752 wxString result;
753 wxString t;
754 if (b_nameValid) {
755 result.Append(_T("\""));
756 result.Append(GetFullName());
757 result.Append(_T("\" "));
758 }
759 if (Class != AIS_GPSG_BUDDY) {
760 t.Printf(_T("%09d"), abs(MMSI));
761 result.Append(t);
762 result.Append(_T(" "));
763 result.Append(GetCountryCode(false));
764 }
765 t = trimAISField(CallSign);
766 if (t.Len()) {
767 result.Append(_T(" ("));
768 result.Append(t);
769 result.Append(_T(")"));
770 }
771 if (g_bAISRolloverShowClass || (Class == AIS_SART)) {
772 if (result.Len()) result.Append(_T("\n"));
773 result.Append(_T("["));
774 if (Class == AIS_ATON) {
775 result.Append(wxGetTranslation(Get_class_string(true)));
776 result.Append(_T(": "));
777 result.Append(wxGetTranslation(Get_vessel_type_string(false)));
778 } else if (b_SarAircraftPosnReport) {
779 int airtype = (MMSI % 1000) / 100;
780 result.Append(airtype == 5 ? _("SAR Helicopter") : _("SAR Aircraft"));
781 } else
782 result.Append(wxGetTranslation(Get_class_string(false)));
783
784 result.Append(_T("] "));
785 if ((Class != AIS_ATON) && (Class != AIS_BASE)) {
786 if (Class == AIS_SART) {
787 int mmsi_start = MMSI / 1000000;
788 switch (mmsi_start) {
789 case 970:
790 break;
791 case 972:
792 result += _T("MOB");
793 break;
794 case 974:
795 result += _T("EPIRB");
796 break;
797 default:
798 result += _("Unknown");
799 break;
800 }
801 }
802
803 if (Class != AIS_SART) {
804 if (!b_SarAircraftPosnReport)
805 result.Append(wxGetTranslation(Get_vessel_type_string(false)));
806 }
807
808 if ((Class != AIS_CLASS_B) && (Class != AIS_SART) &&
809 Class != AIS_DSC && !b_SarAircraftPosnReport) {
810 if ((NavStatus <= 15) && (NavStatus >= 0)) {
811 result.Append(_T(" ("));
812 result.Append(wxGetTranslation(ais_get_status(NavStatus)));
813 result.Append(_T(")"));
814 }
815 } else if (Class == AIS_SART) {
816 result.Append(_T(" ("));
817 if (NavStatus == RESERVED_14)
818 result.Append(_("Active"));
819 else if (NavStatus == UNDEFINED)
820 result.Append(_("Testing"));
821 result.Append(_T(")"));
822 } else if (Class == AIS_DSC) {
823 result.Append(_T(" ("));
824 result.Append(GetNatureofDistress(m_dscNature));
825 result.Append(_T(")"));
826 }
827 }
828 }
829
830 if (g_bAISRolloverShowCOG && ((SOG <= 102.2) || b_SarAircraftPosnReport) &&
831 ((Class != AIS_ATON) && (Class != AIS_BASE))) {
832 if (result.Len()) result << _T("\n");
833
834 double speed_show = toUsrSpeed(SOG);
835 if (speed_show < 10.0)
836 result << wxString::Format(_T("SOG %.2f "), speed_show)
837 << getUsrSpeedUnit() << _T(" ");
838 else if (speed_show < 100.0)
839 result << wxString::Format(_T("SOG %.1f "), speed_show)
840 << getUsrSpeedUnit() << _T(" ");
841 else
842 result << wxString::Format(_T("SOG %.0f "), speed_show)
843 << getUsrSpeedUnit() << _T(" ");
844
845 int crs = wxRound(COG);
846 if (b_positionOnceValid) {
847 if (crs < 360) {
848 wxString magString, trueString;
849 if (g_bShowMag)
850 magString << wxString::Format(wxString("%03d%c(M) "),
851 static_cast<int>(m_callbacks.get_mag(COG)),
852 0x00B0);
853 if (g_bShowTrue)
854 trueString << wxString::Format( wxString("%03d%c "), (int)crs, 0x00B0 );
855
856 result << trueString << magString;
857 }
858
859 else if (COG == 360.0)
860 result << _(" COG Unavailable");
861 else if (crs == 360)
862 result << wxString(" COG 000\u00B0");
863 } else
864 result << _(" COG Unavailable");
865 }
866
867 if (g_bAISRolloverShowCPA && bCPA_Valid) {
868 if (result.Len()) result << _T("\n");
869 result << _("CPA") << _T(" ") << FormatDistanceAdaptive(CPA) << _T(" ")
870 << _("in") << _T(" ") << wxString::Format(_T("%.0f"), TCPA)
871 << _T(" ") << _("min");
872 }
873 return result;
874}
875
876wxString AisTargetData::Get_vessel_type_string(bool b_short) {
877 int i = 19;
878 if (Class == AIS_ATON) {
879 i = ShipType + 20;
880 } else
881 switch (ShipType) {
882 case 30:
883 i = 0;
884 break;
885 case 31:
886 i = 1;
887 break;
888 case 32:
889 i = 2;
890 break;
891 case 33:
892 i = 3;
893 break;
894 case 34:
895 i = 4;
896 break;
897 case 35:
898 i = 5;
899 break;
900 case 36:
901 i = 6;
902 break;
903 case 37:
904 i = 7;
905 break;
906 case 50:
907 i = 9;
908 break;
909 case 51:
910 i = 10;
911 break;
912 case 52:
913 i = 11;
914 break;
915 case 53:
916 i = 12;
917 break;
918 case 54:
919 i = 13;
920 break;
921 case 55:
922 i = 14;
923 break;
924 case 58:
925 i = 15;
926 break;
927 default:
928 i = 19;
929 break;
930 }
931
932 if ((Class == AIS_CLASS_B) || (Class == AIS_CLASS_A)) {
933 if ((ShipType >= 40) && (ShipType < 50)) i = 8;
934
935 if ((ShipType >= 60) && (ShipType < 70)) i = 16;
936
937 if ((ShipType >= 70) && (ShipType < 80)) i = 17;
938
939 if ((ShipType >= 80) && (ShipType < 90)) i = 18;
940 } else if (Class == AIS_GPSG_BUDDY)
941 i = 52;
942 else if (Class == AIS_ARPA)
943 i = 55;
944 else if (Class == AIS_APRS)
945 i = 56;
946 else if (Class == AIS_DSC)
947 i = (ShipType == 12 || ShipType == 16) ? 54 : 53; // 12 & 16 is distress
948
949 if (!b_short)
950 return ais_get_type(i);
951 else
952 return ais_get_short_type(i);
953}
954
955wxString AisTargetData::Get_class_string(bool b_short) {
956 switch (Class) {
957 case AIS_CLASS_A:
958 return _("A");
959 case AIS_CLASS_B:
960 return _("B");
961 case AIS_ATON:
962 return b_short ? _("AtoN") : _("Aid to Navigation");
963 case AIS_BASE:
964 return b_short ? _("Base") : _("Base Station");
965 case AIS_GPSG_BUDDY:
966 return b_short ? _("Buddy") : _("GPSGate Buddy");
967 case AIS_DSC:
968 if (ShipType == 12 || ( ShipType == 16 && m_dscNature < 13))
969 return b_short ? _("DSC") : _("DSC Distress");
970 else
971 return b_short ? _("DSC") : _("DSC Position Report");
972 case AIS_SART:
973 return b_short ? _("SART") : _("SART");
974 case AIS_ARPA:
975 return b_short ? _("ARPA") : _("ARPA");
976 case AIS_APRS:
977 return b_short ? _("APRS") : _("APRS Position Report");
978
979 default:
980 return b_short ? _("Unk") : _("Unknown");
981 }
982}
983
984wxString AisTargetData::GetNatureofDistress(int dscnature) {
985 // Natures of distress from: Rec. ITU-R M.493-10.
986 wxString dscDistressType[] = { _("Fire, explosion"), _("Floding"),
987 _("Collision"), _("Grounding"),
988 _("Listing, in danger of capsazing"), _("Sinking"),
989 _("Disabled and adrift"), _("Undesignated distress"),
990 _("Abandoning ship"), _("Pirazy/armed robbery attack"),
991 _("Man overboard"), _T("-"), _("EPIRB emission") };
992 if (dscnature >= 0 && dscnature < 13)
993 return dscDistressType[dscnature];
994
995 return wxEmptyString;
996}
997
998void AisTargetData::Toggle_AIS_CPA(void) {
999 b_show_AIS_CPA = !b_show_AIS_CPA ? true : false;
1000}
1001
1002void AisTargetData::ToggleShowTrack(void) {
1003 b_show_track = !b_show_track ? true : false;
1004}
1005
1006// Get country name and code according to ITU 2019-02
1007// (http://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/mid.aspx)
1008wxString AisTargetData::GetCountryCode(
1009 bool
1010 b_CntryLongStr) // false = Short country code, true = Full country name
1011{
1012 int nMID = MMSI / 1000000;
1013 // SAR Aircraft start with 111 and has a MID at pos 4,5,6
1014 if (111 == nMID) nMID = (MMSI - 111000000) / 1000;
1015 // Base station start with 00 and has a MID at pos 4,5,6
1016 if (Class == AIS_BASE) nMID = MMSI / 10000;
1017 // AtoN start with 99 and has a MID at pos 3,4,5
1018 if (99 == MMSI / 10000000) nMID = (MMSI - 990000000) / 10000;
1019 // Check if a proper MID
1020 if (nMID < 201 || nMID > 775) return wxEmptyString;
1021
1022#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1023
1024 switch (nMID) {
1025 case 201:
1026 return b_CntryLongStr ? _("Albania") : _T("AL");
1027 case 202:
1028 return b_CntryLongStr ? _("Andorra") : _T("AD");
1029 case 203:
1030 return b_CntryLongStr ? _("Austria") : _T("AT");
1031 case 204:
1032 return b_CntryLongStr ? _("Azores") : _T("AZ");
1033 case 205:
1034 return b_CntryLongStr ? _("Belgium") : _T("BE");
1035 case 206:
1036 return b_CntryLongStr ? _("Belarus") : _T("BY");
1037 case 207:
1038 return b_CntryLongStr ? _("Bulgaria") : _T("BG");
1039 case 208:
1040 return b_CntryLongStr ? _("Vatican City State") : _T("VA");
1041 case 209:
1042 case 210:
1043 return b_CntryLongStr ? _("Cyprus") : _T("CY");
1044 case 211:
1045 return b_CntryLongStr ? _("Germany") : _T("DE");
1046 case 212:
1047 return b_CntryLongStr ? _("Cyprus") : _T("CY");
1048 case 213:
1049 return b_CntryLongStr ? _("Georgia") : _T("GE");
1050 case 214:
1051 return b_CntryLongStr ? _("Moldova") : _T("MD");
1052 case 215:
1053 return b_CntryLongStr ? _("Malta") : _T("MT");
1054 case 216:
1055 return b_CntryLongStr ? _("Armenia") : _T("AM");
1056 case 218:
1057 return b_CntryLongStr ? _("Germany") : _T("DE");
1058 case 219:
1059 case 220:
1060 return b_CntryLongStr ? _("Denmark") : _T("DK");
1061 case 224:
1062 return b_CntryLongStr ? _("Spain") : _T("ES");
1063 case 225:
1064 return b_CntryLongStr ? _("Spain") : _T("ES");
1065 case 226:
1066 case 227:
1067 case 228:
1068 return b_CntryLongStr ? _("France") : _T("FR");
1069 case 229:
1070 return b_CntryLongStr ? _("Malta") : _T("MT");
1071 case 230:
1072 return b_CntryLongStr ? _("Finland") : _T("FI");
1073 case 231:
1074 return b_CntryLongStr ? _("Faroe Islands") : _T("FO");
1075 case 232:
1076 case 233:
1077 case 234:
1078 case 235:
1079 return b_CntryLongStr ? _("Great Britain") : _T("GB");
1080 case 236:
1081 return b_CntryLongStr ? _("Gibraltar") : _T("GI");
1082 case 237:
1083 return b_CntryLongStr ? _("Greece") : _T("GR");
1084 case 238:
1085 return b_CntryLongStr ? _("Croatia") : _T("HR");
1086 case 239:
1087 case 240:
1088 case 241:
1089 return b_CntryLongStr ? _("Greece") : _T("GR");
1090 case 242:
1091 return b_CntryLongStr ? _("Morocco") : _T("MA");
1092 case 243:
1093 return b_CntryLongStr ? _("Hungary") : _T("HU");
1094 case 244:
1095 case 245:
1096 case 246:
1097 return b_CntryLongStr ? _("Netherlands") : _T("NL");
1098 case 247:
1099 return b_CntryLongStr ? _("Italy") : _T("IT");
1100 case 248:
1101 case 249:
1102 return b_CntryLongStr ? _("Malta") : _T("MT");
1103 case 250:
1104 return b_CntryLongStr ? _("Ireland") : _T("IE");
1105 case 251:
1106 return b_CntryLongStr ? _("Iceland") : _T("IS");
1107 case 252:
1108 return b_CntryLongStr ? _("Liechtenstein") : _T("LI");
1109 case 253:
1110 return b_CntryLongStr ? _("Luxembourg") : _T("LU");
1111 case 254:
1112 return b_CntryLongStr ? _("Monaco") : _T("MC");
1113 case 255:
1114 return b_CntryLongStr ? _("Madeira") : _T("PT");
1115 case 256:
1116 return b_CntryLongStr ? _("Malta") : _T("MT");
1117 case 257:
1118 case 258:
1119 case 259:
1120 return b_CntryLongStr ? _("Norway") : _T("NO");
1121 case 261:
1122 return b_CntryLongStr ? _("Poland") : _T("PL");
1123 case 262:
1124 return b_CntryLongStr ? _("Montenegro") : _T("ME");
1125 case 263:
1126 return b_CntryLongStr ? _("Portugal") : _T("PT");
1127 case 264:
1128 return b_CntryLongStr ? _("Romania") : _T("RO");
1129 case 265:
1130 case 266:
1131 return b_CntryLongStr ? _("Sweden") : _T("SE");
1132 case 267:
1133 return b_CntryLongStr ? _("Slovak Republic") : _T("SK");
1134 case 268:
1135 return b_CntryLongStr ? _("San Marino") : _T("SM");
1136 case 269:
1137 return b_CntryLongStr ? _("Switzerland") : _T("CH");
1138 case 270:
1139 return b_CntryLongStr ? _("Czech Republic") : _T("CZ");
1140 case 271:
1141 return b_CntryLongStr ? _("Turkey") : _T("TR");
1142 case 272:
1143 return b_CntryLongStr ? _("Ukraine") : _T("UA");
1144 case 273:
1145 return b_CntryLongStr ? _("Russian") : _T("RU");
1146 case 274:
1147 return b_CntryLongStr ? _("Macedonia") : _T("MK");
1148 case 275:
1149 return b_CntryLongStr ? _("Latvia") : _T("LV");
1150 case 276:
1151 return b_CntryLongStr ? _("Estonia") : _T("EE");
1152 case 277:
1153 return b_CntryLongStr ? _("Lithuania") : _T("LT");
1154 case 278:
1155 return b_CntryLongStr ? _("Slovenia") : _T("SI");
1156 case 279:
1157 return b_CntryLongStr ? _("Serbia") : _T("RS");
1158 case 301:
1159 return b_CntryLongStr ? _("Anguilla") : _T("AI");
1160 case 303:
1161 return b_CntryLongStr ? _("Alaska") : _T("AK");
1162 case 304:
1163 case 305:
1164 return b_CntryLongStr ? _("Antigua and Barbuda") : _T("AG");
1165 case 306:
1166 return b_CntryLongStr ? _("Antilles") : _T("AN");
1167 case 307:
1168 return b_CntryLongStr ? _("Aruba") : _T("AW");
1169 case 308:
1170 case 309:
1171 return b_CntryLongStr ? _("Bahamas") : _T("BS");
1172 case 310:
1173 return b_CntryLongStr ? _("Bermuda") : _T("BM");
1174 case 311:
1175 return b_CntryLongStr ? _("Bahamas") : _T("BS");
1176 case 312:
1177 return b_CntryLongStr ? _("Belize") : _T("BZ");
1178 case 314:
1179 return b_CntryLongStr ? _("Barbados") : _T("BB");
1180 case 316:
1181 return b_CntryLongStr ? _("Canada") : _T("CA");
1182 case 319:
1183 return b_CntryLongStr ? _("Cayman Islands") : _T("KY");
1184 case 321:
1185 return b_CntryLongStr ? _("Costa Rica") : _T("CR");
1186 case 323:
1187 return b_CntryLongStr ? _("Cuba") : _T("CU");
1188 case 325:
1189 return b_CntryLongStr ? _("Dominica") : _T("DM");
1190 case 327:
1191 return b_CntryLongStr ? _("Dominican Republic") : _T("DM");
1192 case 329:
1193 return b_CntryLongStr ? _("Guadeloupe") : _T("GP");
1194 case 330:
1195 return b_CntryLongStr ? _("Grenada") : _T("GD");
1196 case 331:
1197 return b_CntryLongStr ? _("Greenland") : _T("GL");
1198 case 332:
1199 return b_CntryLongStr ? _("Guatemala") : _T("GT");
1200 case 334:
1201 return b_CntryLongStr ? _("Honduras") : _T("HN");
1202 case 336:
1203 return b_CntryLongStr ? _("Haiti") : _T("HT");
1204 case 338:
1205 return b_CntryLongStr ? _("United States of America") : _T("US");
1206 case 339:
1207 return b_CntryLongStr ? _("Jamaica") : _T("JM");
1208 case 341:
1209 return b_CntryLongStr ? _("Saint Kitts and Nevis") : _T("KN");
1210 case 343:
1211 return b_CntryLongStr ? _("Saint Lucia") : _T("LC");
1212 case 345:
1213 return b_CntryLongStr ? _("Mexico") : _T("MX");
1214 case 347:
1215 return b_CntryLongStr ? _("Martinique") : _T("MQ");
1216 case 348:
1217 return b_CntryLongStr ? _("Montserrat") : _T("MS");
1218 case 350:
1219 return b_CntryLongStr ? _("Nicaragua") : _T("NI");
1220 case 351:
1221 case 352:
1222 case 353:
1223 case 354:
1224 case 355:
1225 case 356:
1226 case 357:
1227 return b_CntryLongStr ? _("Panama") : _T("PA");
1228 case 358:
1229 return b_CntryLongStr ? _("Puerto Rico") : _T("PR");
1230 case 359:
1231 return b_CntryLongStr ? _("El Salvador") : _T("SV");
1232 case 361:
1233 return b_CntryLongStr ? _("Saint Pierre and Miquelon") : _T("PM");
1234 case 362:
1235 return b_CntryLongStr ? _("Trinidad and Tobago") : _T("TT");
1236 case 364:
1237 return b_CntryLongStr ? _("Turks and Caicos Islands") : _T("TC");
1238 case 366:
1239 case 367:
1240 case 368:
1241 case 369:
1242 return b_CntryLongStr ? _("United States of America") : _T("US");
1243 case 370:
1244 case 371:
1245 case 372:
1246 case 373:
1247 case 374:
1248 return b_CntryLongStr ? _("Panama") : _T("PA");
1249 case 375:
1250 case 376:
1251 case 377:
1252 return b_CntryLongStr ? _("Saint Vincent and the Grenadines") : _T("VC");
1253 case 378:
1254 return b_CntryLongStr ? _("British Virgin Islands") : _T("VG");
1255 case 379:
1256 return b_CntryLongStr ? _("United States Virgin Islands") : _T("AE");
1257 case 401:
1258 return b_CntryLongStr ? _("Afghanistan") : _T("AF");
1259 case 403:
1260 return b_CntryLongStr ? _("Saudi Arabia") : _T("SA");
1261 case 405:
1262 return b_CntryLongStr ? _("Bangladesh") : _T("BD");
1263 case 408:
1264 return b_CntryLongStr ? _("Bahrain") : _T("BH");
1265 case 410:
1266 return b_CntryLongStr ? _("Bhutan") : _T("BT");
1267 case 412:
1268 case 413:
1269 case 414:
1270 return b_CntryLongStr ? _("China") : _T("CN");
1271 case 416:
1272 return b_CntryLongStr ? _("Taiwan") : _T("TW");
1273 case 417:
1274 return b_CntryLongStr ? _("Sri Lanka") : _T("LK");
1275 case 419:
1276 return b_CntryLongStr ? _("India") : _T("IN");
1277 case 422:
1278 return b_CntryLongStr ? _("Iran") : _T("IR");
1279 case 423:
1280 return b_CntryLongStr ? _("Azerbaijani Republic") : _T("AZ");
1281 case 425:
1282 return b_CntryLongStr ? _("Iraq") : _T("IQ");
1283 case 428:
1284 return b_CntryLongStr ? _("Israel") : _T("IL");
1285 case 431:
1286 return b_CntryLongStr ? _("Japan") : _T("JP");
1287 case 432:
1288 return b_CntryLongStr ? _("Japan") : _T("JP");
1289 case 434:
1290 return b_CntryLongStr ? _("Turkmenistan") : _T("TM");
1291 case 436:
1292 return b_CntryLongStr ? _("Kazakhstan") : _T("KZ");
1293 case 437:
1294 return b_CntryLongStr ? _("Uzbekistan") : _T("UZ");
1295 case 438:
1296 return b_CntryLongStr ? _("Jordan") : _T("JO");
1297 case 440:
1298 case 441:
1299 return b_CntryLongStr ? _("Korea") : _T("KR");
1300 case 443:
1301 return b_CntryLongStr ? _("Palestine") : _T("PS");
1302 case 445:
1303 return b_CntryLongStr ? _("People's Rep. of Korea") : _T("KP");
1304 case 447:
1305 return b_CntryLongStr ? _("Kuwait") : _T("KW");
1306 case 450:
1307 return b_CntryLongStr ? _("Lebanon") : _T("LB");
1308 case 451:
1309 return b_CntryLongStr ? _("Kyrgyz Republic") : _T("KG");
1310 case 453:
1311 return b_CntryLongStr ? _("Macao") : _T("MO");
1312 case 455:
1313 return b_CntryLongStr ? _("Maldives") : _T("MV");
1314 case 457:
1315 return b_CntryLongStr ? _("Mongolia") : _T("MN");
1316 case 459:
1317 return b_CntryLongStr ? _("Nepal") : _T("NP");
1318 case 461:
1319 return b_CntryLongStr ? _("Oman") : _T("OM");
1320 case 463:
1321 return b_CntryLongStr ? _("Pakistan") : _T("PK");
1322 case 466:
1323 return b_CntryLongStr ? _("Qatar") : _T("QA");
1324 case 468:
1325 return b_CntryLongStr ? _("Syrian Arab Republic") : _T("SY");
1326 case 470:
1327 case 471:
1328 return b_CntryLongStr ? _("United Arab Emirates") : _T("AE");
1329 case 472:
1330 return b_CntryLongStr ? _("Tajikistan") : _T("TJ");
1331 case 473:
1332 case 475:
1333 return b_CntryLongStr ? _("Yemen") : _T("YE");
1334 case 477:
1335 return b_CntryLongStr ? _("Hong Kong") : _T("HK");
1336 case 478:
1337 return b_CntryLongStr ? _("Bosnia and Herzegovina") : _T("BA");
1338 case 501:
1339 return b_CntryLongStr ? _("Adelie Land") : _T("TF");
1340 case 503:
1341 return b_CntryLongStr ? _("Australia") : _T("AU");
1342 case 506:
1343 return b_CntryLongStr ? _("Myanmar") : _T("MM");
1344 case 508:
1345 return b_CntryLongStr ? _("Brunei Darussalam") : _T("BN");
1346 case 510:
1347 return b_CntryLongStr ? _("Micronesia") : _T("FM");
1348 case 511:
1349 return b_CntryLongStr ? _("Palau") : _T("PW");
1350 case 512:
1351 return b_CntryLongStr ? _("New Zealand") : _T("NZ");
1352 case 514:
1353 case 515:
1354 return b_CntryLongStr ? _("Cambodia") : _T("KH");
1355 case 516:
1356 return b_CntryLongStr ? _("Christmas Island") : _T("CX");
1357 case 518:
1358 return b_CntryLongStr ? _("Cook Islands") : _T("CK");
1359 case 520:
1360 return b_CntryLongStr ? _("Fiji") : _T("FJ");
1361 case 523:
1362 return b_CntryLongStr ? _("Cocos (Keeling) Islands") : _T("CC");
1363 case 525:
1364 return b_CntryLongStr ? _("Indonesia") : _T("ID");
1365 case 529:
1366 return b_CntryLongStr ? _("Kiribati") : _T("KI");
1367 case 531:
1368 return b_CntryLongStr ? _("Lao People's Dem. Rep.") : _T("LA");
1369 case 533:
1370 return b_CntryLongStr ? _("Malaysia") : _T("MY");
1371 case 536:
1372 return b_CntryLongStr ? _("Northern Mariana Islands") : _T("MP");
1373 case 538:
1374 return b_CntryLongStr ? _("Marshall Islands") : _T("MH");
1375 case 540:
1376 return b_CntryLongStr ? _("New Caledonia") : _T("NC");
1377 case 542:
1378 return b_CntryLongStr ? _("Niue") : _T("NU");
1379 case 544:
1380 return b_CntryLongStr ? _("Nauru") : _T("NR");
1381 case 546:
1382 return b_CntryLongStr ? _("French Polynesia") : _T("PF");
1383 case 548:
1384 return b_CntryLongStr ? _("Philippines") : _T("PH");
1385 case 550:
1386 return b_CntryLongStr ? _("East Timor") : _T("TL");
1387 case 553:
1388 return b_CntryLongStr ? _("Papua New Guinea") : _T("PG");
1389 case 555:
1390 return b_CntryLongStr ? _("Pitcairn Island") : _T("PN");
1391 case 557:
1392 return b_CntryLongStr ? _("Solomon Islands") : _T("SB");
1393 case 559:
1394 return b_CntryLongStr ? _("American Samoa") : _T("AS");
1395 case 561:
1396 return b_CntryLongStr ? _("Samoa") : _T("WS");
1397 case 563:
1398 case 564:
1399 case 565:
1400 case 566:
1401 return b_CntryLongStr ? _("Singapore") : _T("SG");
1402 case 567:
1403 return b_CntryLongStr ? _("Thailand") : _T("TH");
1404 case 570:
1405 return b_CntryLongStr ? _("Tonga") : _T("TO");
1406 case 572:
1407 return b_CntryLongStr ? _("Tuvalu") : _T("TV");
1408 case 574:
1409 return b_CntryLongStr ? _("Viet Nam") : _T("VN");
1410 case 576:
1411 case 577:
1412 return b_CntryLongStr ? _("Vanuatu") : _T("VU");
1413 case 578:
1414 return b_CntryLongStr ? _("Wallis and Futuna Islands") : _T("WF");
1415 case 601:
1416 return b_CntryLongStr ? _("South Africa") : _T("ZA");
1417 case 603:
1418 return b_CntryLongStr ? _("Angola") : _T("AO");
1419 case 605:
1420 return b_CntryLongStr ? _("Algeria") : _T("DZ");
1421 case 607:
1422 return b_CntryLongStr ? _("Saint Paul") : _T("TF");
1423 case 608:
1424 return b_CntryLongStr ? _("Ascension Island") : _T("SH");
1425 case 609:
1426 return b_CntryLongStr ? _("Burundi") : _T("BI");
1427 case 610:
1428 return b_CntryLongStr ? _("Benin") : _T("BJ");
1429 case 611:
1430 return b_CntryLongStr ? _("Botswana") : _T("BW");
1431 case 612:
1432 return b_CntryLongStr ? _("Central African Republic") : _T("CF");
1433 case 613:
1434 return b_CntryLongStr ? _("Cameroon") : _T("CM");
1435 case 615:
1436 return b_CntryLongStr ? _("Congo") : _T("CD");
1437 case 616:
1438 return b_CntryLongStr ? _("Comoros") : _T("KM");
1439 case 617:
1440 return b_CntryLongStr ? _("Capo Verde") : _T("CV");
1441 case 618:
1442 return b_CntryLongStr ? _("Crozet Archipelago") : _T("TF");
1443 case 619:
1444 return b_CntryLongStr ? _("Ivory Coast") : _T("CI");
1445 case 620:
1446 return b_CntryLongStr ? _("Comoros (Union of the)") : _T("KM");
1447 case 621:
1448 return b_CntryLongStr ? _("Djibouti") : _T("DJ");
1449 case 622:
1450 return b_CntryLongStr ? _("Egypt") : _T("EG");
1451 case 624:
1452 return b_CntryLongStr ? _("Ethiopia") : _T("ET");
1453 case 625:
1454 return b_CntryLongStr ? _("Eritrea") : _T("ER");
1455 case 626:
1456 return b_CntryLongStr ? _("Gabonese Republic") : _T("GA");
1457 case 627:
1458 return b_CntryLongStr ? _("Ghana") : _T("GH");
1459 case 629:
1460 return b_CntryLongStr ? _("Gambia") : _T("GM");
1461 case 630:
1462 return b_CntryLongStr ? _("Guinea-Bissau") : _T("GW");
1463 case 631:
1464 return b_CntryLongStr ? _("Equatorial Guinea") : _T("GQ");
1465 case 632:
1466 return b_CntryLongStr ? _("Guinea") : _T("GN");
1467 case 633:
1468 return b_CntryLongStr ? _("Burkina Faso") : _T("BF");
1469 case 634:
1470 return b_CntryLongStr ? _("Kenya") : _T("KE");
1471 case 635:
1472 return b_CntryLongStr ? _("Kerguelen Islands") : _T("TF");
1473 case 636:
1474 case 637:
1475 return b_CntryLongStr ? _("Liberia") : _T("LR");
1476 case 638:
1477 return b_CntryLongStr ? _("South Sudan (Republic of)") : _T("SS");
1478 case 642:
1479 return b_CntryLongStr ? _("Libya") : _T("LY");
1480 case 644:
1481 return b_CntryLongStr ? _("Lesotho") : _T("LS");
1482 case 645:
1483 return b_CntryLongStr ? _("Mauritius") : _T("MU");
1484 case 647:
1485 return b_CntryLongStr ? _("Madagascar") : _T("MG");
1486 case 649:
1487 return b_CntryLongStr ? _("Mali") : _T("ML");
1488 case 650:
1489 return b_CntryLongStr ? _("Mozambique") : _T("MZ");
1490 case 654:
1491 return b_CntryLongStr ? _("Mauritania") : _T("MR");
1492 case 655:
1493 return b_CntryLongStr ? _("Malawi") : _T("MW");
1494 case 656:
1495 return b_CntryLongStr ? _("Niger") : _T("NE");
1496 case 657:
1497 return b_CntryLongStr ? _("Nigeria") : _T("NG");
1498 case 659:
1499 return b_CntryLongStr ? _("Namibia") : _T("NA");
1500 case 660:
1501 return b_CntryLongStr ? _("Reunion") : _T("RE");
1502 case 661:
1503 return b_CntryLongStr ? _("Rwanda") : _T("RW");
1504 case 662:
1505 return b_CntryLongStr ? _("Sudan") : _T("SD");
1506 case 663:
1507 return b_CntryLongStr ? _("Senegal") : _T("SN");
1508 case 664:
1509 return b_CntryLongStr ? _("Seychelles") : _T("SC");
1510 case 665:
1511 return b_CntryLongStr ? _("Saint Helena") : _T("SH");
1512 case 666:
1513 return b_CntryLongStr ? _("Somalia") : _T("SO");
1514 case 667:
1515 return b_CntryLongStr ? _("Sierra Leone") : _T("SL");
1516 case 668:
1517 return b_CntryLongStr ? _("Sao Tome and Principe") : _T("ST");
1518 case 669:
1519 return b_CntryLongStr ? _("Eswatini") : _T("SZ");
1520 case 670:
1521 return b_CntryLongStr ? _("Chad") : _T("TD");
1522 case 671:
1523 return b_CntryLongStr ? _("Togolese Republic") : _T("TG");
1524 case 672:
1525 return b_CntryLongStr ? _("Tunisia") : _T("TN");
1526 case 674:
1527 return b_CntryLongStr ? _("Tanzania") : _T("TZ");
1528 case 675:
1529 return b_CntryLongStr ? _("Uganda") : _T("UG");
1530 case 676:
1531 return b_CntryLongStr ? _("Dem Rep.of the Congo") : _T("CD");
1532 case 677:
1533 return b_CntryLongStr ? _("Tanzania") : _T("TZ");
1534 case 678:
1535 return b_CntryLongStr ? _("Zambia") : _T("ZM");
1536 case 679:
1537 return b_CntryLongStr ? _("Zimbabwe") : _T("ZW");
1538 case 701:
1539 return b_CntryLongStr ? _("Argentine Republic") : _T("AR");
1540 case 710:
1541 return b_CntryLongStr ? _("Brazil") : _T("BR");
1542 case 720:
1543 return b_CntryLongStr ? _("Bolivia") : _T("BO");
1544 case 725:
1545 return b_CntryLongStr ? _("Chile") : _T("CL");
1546 case 730:
1547 return b_CntryLongStr ? _("Colombia") : _T("CO");
1548 case 735:
1549 return b_CntryLongStr ? _("Ecuador") : _T("EC");
1550 case 740:
1551 return b_CntryLongStr ? _("Falkland Islands") : _T("FK");
1552 case 745:
1553 return b_CntryLongStr ? _("France - Guiana") : _T("GY");
1554 case 750:
1555 return b_CntryLongStr ? _("Guyana") : _T("GY");
1556 case 755:
1557 return b_CntryLongStr ? _("Paraguay") : _T("PY");
1558 case 760:
1559 return b_CntryLongStr ? _("Peru") : _T("PE");
1560 case 765:
1561 return b_CntryLongStr ? _("Suriname") : _T("SR");
1562 case 770:
1563 return b_CntryLongStr ? _("Uruguay") : _T("UY");
1564 case 775:
1565 return b_CntryLongStr ? _("Venezuela") : _T("VE");
1566
1567 default:
1568 return wxEmptyString;
1569 }
1570#else
1571 return wxEmptyString;
1572#endif
1573}
1574
1575
1576wxString ais_get_type(int index) {
1577 static const wxString ais_type[] = {
1578 _("Fishing Vessel"), // 30 0
1579 _("Towing Vessel"), // 31 1
1580 _("Towing Vessel, Long"), // 32 2
1581 _("Dredger"), // 33 3
1582 _("Diving Ops Vessel"), // 34 4
1583 _("Military Vessel"), // 35 5
1584 _("Sailing Vessel"), // 36 6
1585 _("Pleasure craft"), // 37 7
1586 _("High Speed Craft"), // 4x 8
1587 _("Pilot Vessel"), // 50 9
1588 _("Search and Rescue Vessel"), // 51 10
1589 _("Tug"), // 52 11
1590 _("Port Tender"), // 53 12
1591 _("Pollution Control Vessel"), // 54 13
1592 _("Law Enforcement Vessel"), // 55 14
1593 _("Medical Transport"), // 58 15
1594 _("Passenger Ship"), // 6x 16
1595 _("Cargo Ship"), // 7x 17
1596 _("Tanker"), // 8x 18
1597 _("Unknown"), // 19
1598 _("Unspecified"), // 00 20
1599 _("Reference Point"), // 01 21
1600 _("RACON"), // 02 22
1601 _("Fixed Structure"), // 03 23
1602 _("Spare"), // 04 24
1603 _("Light"), // 05 25
1604 _("Light w/Sectors"), // 06 26
1605 _("Leading Light Front"), // 07 27
1606 _("Leading Light Rear"), // 08 28
1607 _("Cardinal N Beacon"), // 09 29
1608 _("Cardinal E Beacon"), // 10 30
1609 _("Cardinal S Beacon"), // 11 31
1610 _("Cardinal W Beacon"), // 12 32
1611 _("Beacon, Port Hand"), // 13 33
1612 _("Beacon, Starboard Hand"), // 14 34
1613 _("Beacon, Preferred Channel Port Hand"), // 15 35
1614 _("Beacon, Preferred Channel Starboard Hand"), // 16 36
1615 _("Beacon, Isolated Danger"), // 17 37
1616 _("Beacon, Safe Water"), // 18 38
1617 _("Beacon, Special Mark"), // 19 39
1618 _("Cardinal Mark N"), // 20 40
1619 _("Cardinal Mark E"), // 21 41
1620 _("Cardinal Mark S"), // 22 42
1621 _("Cardinal Mark W"), // 23 43
1622 _("Port Hand Mark"), // 24 44
1623 _("Starboard Hand Mark"), // 25 45
1624 _("Preferred Channel Port Hand"), // 26 46
1625 _("Preferred Channel Starboard Hand"), // 27 47
1626 _("Isolated Danger"), // 28 48
1627 _("Safe Water"), // 29 49
1628 _("Special Mark"), // 30 50
1629 _("Light Vessel/Rig"), // 31 51
1630 _("GpsGate Buddy"), // xx 52
1631 _("Position Report"), // xx 53
1632 _("Distress"), // xx 54
1633 _("ARPA radar target"), // xx 55
1634 _("APRS Position Report") // xx 56
1635 };
1636
1637 return ais_type[index];
1638}
1639
1640wxString ais_get_short_type(int index) {
1641 static const wxString short_ais_type[] = {
1642 _("F/V"), // 30 0
1643 _("Tow"), // 31 1
1644 _("Long Tow"), // 32 2
1645 _("Dredge"), // 33 3
1646 _("D/V"), // 34 4
1647 _("Mil/V"), // 35 5
1648 _("S/V"), // 36 6
1649 _("Yat"), // 37 7
1650 _("HSC"), // 4x 8
1651 _("P/V"), // 50 9
1652 _("SAR/V"), // 51 10
1653 _("Tug"), // 52 11
1654 _("Tender"), // 53 12
1655 _("PC/V"), // 54 13
1656 _("LE/V"), // 55 14
1657 _("Med/V"), // 58 15
1658 _("Pass/V"), // 6x 16
1659 _("M/V"), // 7x 17
1660 _("M/T"), // 8x 18
1661 _("?"), // 19
1662
1663 _("AtoN"), // 00 20
1664 _("Ref. Pt"), // 01 21
1665 _("RACON"), // 02 22
1666 _("Fix.Struct."), // 03 23
1667 _("?"), // 04 24
1668 _("Lt"), // 05 25
1669 _("Lt sect."), // 06 26
1670 _("Ldg Lt Front"), // 07 27
1671 _("Ldg Lt Rear"), // 08 28
1672 _("Card. N"), // 09 29
1673 _("Card. E"), // 10 30
1674 _("Card. S"), // 11 31
1675 _("Card. W"), // 12 32
1676 _("Port"), // 13 33
1677 _("Stbd"), // 14 34
1678 _("Pref. Chnl"), // 15 35
1679 _("Pref. Chnl"), // 16 36
1680 _("Isol. Dngr"), // 17 37
1681 _("Safe Water"), // 18 38
1682 _("Special"), // 19 39
1683 _("Card. N"), // 20 40
1684 _("Card. E"), // 21 41
1685 _("Card. S"), // 22 42
1686 _("Card. W"), // 23 43
1687 _("Port Hand"), // 24 44
1688 _("Stbd Hand"), // 25 45
1689 _("Pref. Chnl"), // 26 46
1690 _("Pref. Chnl"), // 27 47
1691 _("Isol. Dngr"), // 28 48
1692 _("Safe Water"), // 29 49
1693 _("Special"), // 30 50
1694 _("LtV/Rig"), // 31 51
1695 _("Buddy"), // xx 52
1696 _("DSC"), // xx 53
1697 _("Distress"), // xx 54
1698 _("ARPA"), // xx 55
1699 _("APRS") // xx 56
1700 };
1701 return short_ais_type[index];
1702}