34#include <wx/jsonval.h>
43#include "model/nav_object_database.h"
55#include "androidUTIL.h"
71void appendOSDirSlash(wxString *pString);
73static void ActivatePersistedRoute(
Routeman *routeman) {
74 if (g_active_route ==
"") {
75 wxLogWarning(
"\"Persist route\" but no persisted route configured");
78 Route *route = routeman->FindRouteByGUID(g_active_route);
80 wxLogWarning(
"Persisted route GUID not available");
94 pRouteActivatePoint(0),
95 m_NMEA0183(NmeaCtxFactory()),
97 m_route_dlg_ctx(route_dlg_ctx) {
99 auto route_action = [&](wxCommandEvent) {
100 if (g_persist_active_route) ActivatePersistedRoute(
this);
102 active_route_listener.Init(active_route, route_action);
105Routeman::~Routeman() {
106 if (pRouteActivatePoint)
delete pRouteActivatePoint;
109bool Routeman::IsRouteValid(
Route *pRoute) {
111 if (pRoute == route)
return true;
119 for (
RoutePoint *prp : *proute->pRoutePointList) {
120 if (prp == pWP)
return proute;
127Route *Routeman::FindRouteContainingWaypoint(
const std::string &guid) {
129 for (
RoutePoint *prp : *proute->pRoutePointList) {
130 if (prp->m_GUID == guid)
return proute;
140 if (proute->IsVisible()) {
141 for (
RoutePoint *prp : *proute->pRoutePointList) {
142 if (prp == pWP)
return proute;
151 wxArrayPtrVoid *pArray =
new wxArrayPtrVoid;
154 for (
RoutePoint *prp : *proute->pRoutePointList) {
156 pArray->Add((
void *)proute);
163 if (pArray->GetCount())
175 pSelect->DeleteAllSelectableRoutePoints(route);
176 pSelect->DeleteAllSelectableRouteSegments(route);
178 route->RemovePoint(point);
182 if (route->GetnPoints() <= 1 && route_state == 0) {
187 pSelect->AddSelectableRoutePoint(point->m_lat, point->m_lon, point);
192 m_prop_dlg_ctx.set_route_and_update(route);
195RoutePoint *Routeman::FindBestActivatePoint(
Route *pR,
double lat,
double lon,
196 double cog,
double sog) {
197 if (!pR)
return NULL;
201 double min_time_found = 1e6;
205 DistanceBearingMercator(pn->m_lat, pn->m_lon, lat, lon, &brg, &dist);
207 double angle = brg - cog;
208 double soa = cos(angle * PI / 180.);
210 double time_to_wp = dist / soa;
212 if (time_to_wp > 0) {
213 if (time_to_wp < min_time_found) {
214 min_time_found = time_to_wp;
223 g_bAllowShipToActive =
false;
226 v[
"GUID"] = pRouteToActivate->
m_GUID;
227 json_msg.
Notify(std::make_shared<wxJSONValue>(v),
"OCPN_RTE_ACTIVATED");
232 m_have_n0183_out =
false;
233 m_have_n2000_out =
false;
235 m_output_drivers.clear();
238 if (attributes.find(
"protocol") == attributes.end())
continue;
239 if (attributes.at(
"protocol") ==
"nmea0183") {
240 if (attributes.find(
"ioDirection") != attributes.end()) {
241 if ((attributes.at(
"ioDirection") ==
"IN/OUT") ||
242 (attributes.at(
"ioDirection") ==
"OUT")) {
243 m_output_drivers.push_back(handle);
244 m_have_n0183_out =
true;
250 if (attributes.find(
"protocol") == attributes.end())
continue;
251 if (attributes.at(
"protocol") ==
"nmea2000") {
252 if (attributes.find(
"ioDirection") != attributes.end()) {
253 if ((attributes.at(
"ioDirection") ==
"IN/OUT") ||
254 (attributes.at(
"ioDirection") ==
"OUT")) {
255 m_output_drivers.push_back(handle);
256 m_have_n2000_out =
true;
263 pActiveRoute = pRouteToActivate;
264 g_active_route = pActiveRoute->GetGUID();
267 pActivePoint = pStartPoint;
280 m_bDataValid =
false;
282 m_route_dlg_ctx.show_with_fresh_fonts();
287 g_bAllowShipToActive =
false;
289 v[
"GUID"] = pRP_target->
m_GUID;
290 v[
"WP_activated"] = pRP_target->GetName();
292 json_msg.
Notify(std::make_shared<wxJSONValue>(v),
"OCPN_WPT_ACTIVATED");
298 pActivePoint = pRP_target;
303 pn->m_bIsActive =
false;
311 if (pRP_target == prp_first) {
312 if (pRouteActivatePoint)
delete pRouteActivatePoint;
314 pRouteActivatePoint =
319 pActiveRouteSegmentBeginPoint = pRouteActivatePoint;
328 if (pnext == pRP_target) {
329 pActiveRouteSegmentBeginPoint = np_prev;
353 m_prop_dlg_ctx.set_enroute_point(pA, pActivePoint);
358 g_bAllowShipToActive =
false;
365 v[
"isSkipped"] = skipped;
366 v[
"GUID"] = pActivePoint->
m_GUID;
367 v[
"GUID_WP_arrived"] = pActivePoint->
m_GUID;
368 v[
"WP_arrived"] = pActivePoint->GetName();
370 int n_index_active = pActiveRoute->GetIndexOf(pActivePoint);
371 if (n_index_active < 0)
return false;
373 while (n_index_active == pActiveRoute->GetIndexOf(pActivePoint)) {
374 int candidate = n_index_active + step;
375 if (candidate < pActiveRoute->GetnPoints()) {
376 int candidate_point = candidate + 1;
377 pActiveRouteSegmentBeginPoint = pActivePoint;
379 pActiveRoute->GetPoint(candidate_point);
380 pActivePoint = pActiveRoute->GetPoint(candidate_point);
389 v[
"Next_WP"] = pActivePoint->GetName();
390 v[
"GUID_Next_WP"] = pActivePoint->
m_GUID;
405 m_prop_dlg_ctx.set_enroute_point(pr, pActivePoint);
407 json_msg.
Notify(std::make_shared<wxJSONValue>(v),
"OCPN_WPT_ARRIVED");
412bool Routeman::DeactivateRoute(
bool b_arrival) {
421 g_active_route.Clear();
426 v[
"GUID"] = pActiveRoute->
m_GUID;
427 json_msg.
Notify(std::make_shared<wxJSONValue>(v),
"OCPN_RTE_DEACTIVATED");
429 v[
"GUID"] = pActiveRoute->
m_GUID;
431 json_msg.
Notify(std::make_shared<wxJSONValue>(v),
"OCPN_RTE_ENDED");
437 if (pRouteActivatePoint)
delete pRouteActivatePoint;
438 pRouteActivatePoint = NULL;
442 m_route_dlg_ctx.clear_console_background();
443 m_bDataValid =
false;
448bool Routeman::UpdateAutopilot() {
449 if (!pActiveRoute)
return false;
456 if ((g_maxWPNameLength >= 3) && (g_maxWPNameLength <= 32))
457 maxName = g_maxWPNameLength;
459 if (m_have_n0183_out) rv |= UpdateAutopilotN0183(*
this);
460 if (m_have_n2000_out) rv |= UpdateAutopilotN2K(*
this);
464 if (!pActiveRoute)
return false;
468 leg_info.Btw = CurrentBrgToActivePoint;
469 leg_info.Dtw = CurrentRngToActivePoint;
470 leg_info.Xte = CurrentXTEToActivePoint;
472 leg_info.Xte = -leg_info.Xte;
474 leg_info.wp_name = pActivePoint->GetName().Truncate(maxName);
475 leg_info.arrival = m_bArrival;
486 if ((g_maxWPNameLength >= 3) && (g_maxWPNameLength <= 32))
487 maxName = g_maxWPNameLength;
491 double r_Sog(0.0), r_Cog(0.0);
492 if (!std::isnan(
gSog)) r_Sog =
gSog;
493 if (!std::isnan(
gCog)) r_Cog =
gCog;
498 leg_info.Btw = CurrentBrgToActivePoint;
499 leg_info.Dtw = CurrentRngToActivePoint;
500 leg_info.Xte = CurrentXTEToActivePoint;
502 leg_info.Xte = -leg_info.Xte;
504 leg_info.wp_name = pActivePoint->GetName().Truncate(maxName);
505 leg_info.arrival = m_bArrival;
511 m_NMEA0183.TalkerID =
"EC";
513 m_NMEA0183.Rmb.IsDataValid =
bGPSValid ? NTrue : NFalse;
514 m_NMEA0183.Rmb.CrossTrackError = CurrentXTEToActivePoint;
515 m_NMEA0183.Rmb.DirectionToSteer = XTEDir < 0 ? Left : Right;
516 m_NMEA0183.Rmb.RangeToDestinationNauticalMiles = CurrentRngToActivePoint;
517 m_NMEA0183.Rmb.BearingToDestinationDegreesTrue = CurrentBrgToActivePoint;
519 if (pActivePoint->m_lat < 0.)
520 m_NMEA0183.Rmb.DestinationPosition.Latitude.Set(-pActivePoint->m_lat,
523 m_NMEA0183.Rmb.DestinationPosition.Latitude.Set(pActivePoint->m_lat,
"N");
525 if (pActivePoint->m_lon < 0.)
526 m_NMEA0183.Rmb.DestinationPosition.Longitude.Set(-pActivePoint->m_lon,
529 m_NMEA0183.Rmb.DestinationPosition.Longitude.Set(pActivePoint->m_lon,
532 m_NMEA0183.Rmb.DestinationClosingVelocityKnots =
533 r_Sog * cos((r_Cog - CurrentBrgToActivePoint) * PI / 180.0);
534 m_NMEA0183.Rmb.IsArrivalCircleEntered = m_bArrival ? NTrue : NFalse;
535 m_NMEA0183.Rmb.FAAModeIndicator =
bGPSValid ?
"A" :
"N";
538 int wp_len = maxName;
540 m_NMEA0183.Rmb.To = pActivePoint->GetName().Truncate(wp_len);
541 m_NMEA0183.Rmb.From =
542 pActiveRouteSegmentBeginPoint->GetName().Truncate(wp_len);
543 m_NMEA0183.Rmb.Write(snt);
545 }
while (snt.Sentence.size() > 82 && wp_len > 0);
552 m_NMEA0183.TalkerID =
"EC";
555 m_NMEA0183.Rmc.IsDataValid = NTrue;
556 if (!
bGPSValid) m_NMEA0183.Rmc.IsDataValid = NFalse;
559 m_NMEA0183.Rmc.Position.Latitude.Set(-
gLat,
"S");
561 m_NMEA0183.Rmc.Position.Latitude.Set(
gLat,
"N");
564 m_NMEA0183.Rmc.Position.Longitude.Set(-
gLon,
"W");
566 m_NMEA0183.Rmc.Position.Longitude.Set(
gLon,
"E");
568 m_NMEA0183.Rmc.SpeedOverGroundKnots = r_Sog;
569 m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue = r_Cog;
571 if (!std::isnan(
gVar)) {
573 m_NMEA0183.Rmc.MagneticVariation = -
gVar;
574 m_NMEA0183.Rmc.MagneticVariationDirection = West;
576 m_NMEA0183.Rmc.MagneticVariation =
gVar;
577 m_NMEA0183.Rmc.MagneticVariationDirection = East;
580 m_NMEA0183.Rmc.MagneticVariation =
584 if (!gRmcTime.IsEmpty() && !gRmcDate.IsEmpty()) {
585 m_NMEA0183.Rmc.UTCTime = gRmcTime;
586 m_NMEA0183.Rmc.Date = gRmcDate;
588 wxDateTime now = wxDateTime::Now();
589 wxDateTime utc = now.ToUTC();
590 wxString time = utc.Format(
"%H%M%S");
591 m_NMEA0183.Rmc.UTCTime = time;
592 wxString date = utc.Format(
"%d%m%y");
593 m_NMEA0183.Rmc.Date = date;
596 m_NMEA0183.Rmc.FAAModeIndicator =
"A";
597 if (!
bGPSValid) m_NMEA0183.Rmc.FAAModeIndicator =
"N";
599 m_NMEA0183.Rmc.Write(snt);
606 m_NMEA0183.TalkerID =
"EC";
610 m_NMEA0183.Apb.IsLoranBlinkOK =
612 if (!
bGPSValid) m_NMEA0183.Apb.IsLoranBlinkOK = NFalse;
614 m_NMEA0183.Apb.IsLoranCCycleLockOK = NTrue;
615 if (!
bGPSValid) m_NMEA0183.Apb.IsLoranCCycleLockOK = NFalse;
617 m_NMEA0183.Apb.CrossTrackErrorMagnitude = CurrentXTEToActivePoint;
620 m_NMEA0183.Apb.DirectionToSteer = Left;
622 m_NMEA0183.Apb.DirectionToSteer = Right;
624 m_NMEA0183.Apb.CrossTrackUnits =
"N";
627 m_NMEA0183.Apb.IsArrivalCircleEntered = NTrue;
629 m_NMEA0183.Apb.IsArrivalCircleEntered = NFalse;
633 m_NMEA0183.Apb.IsPerpendicular = NFalse;
635 m_NMEA0183.Apb.To = pActivePoint->GetName().Truncate(maxName);
638 DistanceBearingMercator(pActivePoint->m_lat, pActivePoint->m_lon,
639 pActiveRouteSegmentBeginPoint->m_lat,
640 pActiveRouteSegmentBeginPoint->m_lon, &brg1,
643 if (g_bMagneticAPB && !std::isnan(
gVar)) {
645 ((brg1 -
gVar) >= 0.) ? (brg1 -
gVar) : (brg1 -
gVar + 360.);
646 double bapm = ((CurrentBrgToActivePoint -
gVar) >= 0.)
647 ? (CurrentBrgToActivePoint -
gVar)
648 : (CurrentBrgToActivePoint -
gVar + 360.);
650 m_NMEA0183.Apb.BearingOriginToDestination = brg1m;
651 m_NMEA0183.Apb.BearingOriginToDestinationUnits =
"M";
653 m_NMEA0183.Apb.BearingPresentPositionToDestination = bapm;
654 m_NMEA0183.Apb.BearingPresentPositionToDestinationUnits =
"M";
656 m_NMEA0183.Apb.HeadingToSteer = bapm;
657 m_NMEA0183.Apb.HeadingToSteerUnits =
"M";
659 m_NMEA0183.Apb.BearingOriginToDestination = brg1;
660 m_NMEA0183.Apb.BearingOriginToDestinationUnits =
"T";
662 m_NMEA0183.Apb.BearingPresentPositionToDestination =
663 CurrentBrgToActivePoint;
664 m_NMEA0183.Apb.BearingPresentPositionToDestinationUnits =
"T";
666 m_NMEA0183.Apb.HeadingToSteer = CurrentBrgToActivePoint;
667 m_NMEA0183.Apb.HeadingToSteerUnits =
"T";
670 m_NMEA0183.Apb.Write(snt);
676 m_NMEA0183.TalkerID =
"EC";
680 m_NMEA0183.Xte.IsLoranBlinkOK =
682 if (!
bGPSValid) m_NMEA0183.Xte.IsLoranBlinkOK = NFalse;
684 m_NMEA0183.Xte.IsLoranCCycleLockOK = NTrue;
685 if (!
bGPSValid) m_NMEA0183.Xte.IsLoranCCycleLockOK = NFalse;
687 m_NMEA0183.Xte.CrossTrackErrorDistance = CurrentXTEToActivePoint;
690 m_NMEA0183.Xte.DirectionToSteer = Left;
692 m_NMEA0183.Xte.DirectionToSteer = Right;
694 m_NMEA0183.Xte.CrossTrackUnits =
"N";
696 m_NMEA0183.Xte.Write(snt);
704bool Routeman::DoesRouteContainSharedPoints(
Route *pRoute) {
708 for (
RoutePoint *prp : *pRoute->pRoutePointList) {
712 for (
unsigned int ir = 0; ir < pRA->GetCount(); ir++) {
724 for (
RoutePoint *prp : *pRoute->pRoutePointList) {
725 if (prp->IsShared())
return true;
732bool Routeman::DeleteTrack(
Track *pTrack) {
733 if (pTrack && !pTrack->m_bIsInLayer) {
734 ::wxBeginBusyCursor();
750 pSelect->DeleteAllSelectableTrackSegments(pTrack);
768 if (!m_route_dlg_ctx.confirm_delete_ais_mob()) {
773 ::wxBeginBusyCursor();
775 if (GetpActiveRoute() == pRoute) DeactivateRoute();
785 m_prop_dlg_ctx.hide(pRoute);
790 pSelect->DeleteAllSelectableRouteSegments(pRoute);
794 m_route_dlg_ctx.route_mgr_dlg_update_list_ctrl();
799 auto pnode = list->begin();
800 while (pnode != list->end()) {
804 Route *pcontainer_route = FindRouteContainingWaypoint(prp);
809 if (!prp->IsShared()) {
810 pSelect->DeleteSelectablePoint(prp, SELTYPE_ROUTEPOINT);
814 while (pdnode != list->end()) {
816 pdnode = std::find(list->begin(), list->end(), prp);
820 NavObj_dB::GetInstance().DeleteRoutePoint(prp);
824 prp->SetShared(
false);
825 NavObj_dB::GetInstance().UpdateRoutePoint(prp);
828 if (pnode != list->end())
831 pnode = list->begin();
834 NavObj_dB::GetInstance().DeleteRoute(pRoute);
842void Routeman::DeleteAllRoutes() {
843 ::wxBeginBusyCursor();
848 if (!m_route_dlg_ctx.confirm_delete_ais_mob()) {
852 ::wxBeginBusyCursor();
854 if (proute->m_bIsInLayer)
continue;
862void Routeman::SetColorScheme(ColorScheme cs,
double displayDPmm) {
865 int scaled_line_width = g_route_line_width;
866 int track_scaled_line_width = g_track_line_width;
869 double nominal_line_width_pix = wxMax(2.0, floor(displayDPmm * 0.4));
871 double sline_width = wxMax(nominal_line_width_pix, g_route_line_width);
873 scaled_line_width = wxMax(sline_width, 2);
875 double tsline_width = wxMax(nominal_line_width_pix, g_track_line_width);
877 track_scaled_line_width = wxMax(tsline_width, 2);
880 m_pActiveRoutePointPen = wxThePenList->FindOrCreatePen(
881 wxColour(0, 0, 255), scaled_line_width, wxPENSTYLE_SOLID);
882 m_pRoutePointPen = wxThePenList->FindOrCreatePen(
883 wxColour(0, 0, 255), scaled_line_width, wxPENSTYLE_SOLID);
888 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UINFB"),
889 scaled_line_width, wxPENSTYLE_SOLID);
890 m_pSelectedRoutePen =
891 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UINFO"),
892 scaled_line_width, wxPENSTYLE_SOLID);
894 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UARTE"),
895 scaled_line_width, wxPENSTYLE_SOLID);
897 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"CHMGD"),
898 track_scaled_line_width, wxPENSTYLE_SOLID);
899 m_pRouteBrush = wxTheBrushList->FindOrCreateBrush(
900 m_route_dlg_ctx.get_global_colour(
"UINFB"), wxBRUSHSTYLE_SOLID);
901 m_pSelectedRouteBrush = wxTheBrushList->FindOrCreateBrush(
902 m_route_dlg_ctx.get_global_colour(
"UINFO"), wxBRUSHSTYLE_SOLID);
903 m_pActiveRouteBrush = wxTheBrushList->FindOrCreateBrush(
904 m_route_dlg_ctx.get_global_colour(
"PLRTE"), wxBRUSHSTYLE_SOLID);
907wxString Routeman::GetRouteReverseMessage() {
909 _(
"Waypoints can be renamed to reflect the new order, the names will be "
910 "'001', '002' etc.\n\nDo you want to rename the waypoints?"));
913wxString Routeman::GetRouteResequenceMessage() {
915 _(
"Waypoints will be renamed to reflect the natural order, the names "
916 "will be '001', '002' etc.\n\nDo you want to rename the waypoints?"));
919Route *Routeman::FindRouteByGUID(
const wxString &guid) {
921 if (pRoute->
m_GUID == guid)
return pRoute;
926Track *Routeman::FindTrackByGUID(
const wxString &guid) {
928 if (pTrack->m_GUID == guid)
return pTrack;
933void Routeman::ZeroCurrentXTEToActivePoint() {
935 if (pRouteActivatePoint)
delete pRouteActivatePoint;
940 pActiveRouteSegmentBeginPoint = pRouteActivatePoint;
948WayPointman::WayPointman(GlobalColourFunc color_func)
949 : m_get_global_colour(color_func) {
950 m_pWayPointList =
new RoutePointList;
952 pmarkicon_image_list = NULL;
955 m_pIconArray =
new ArrayOfMarkIcon;
956 m_pLegacyIconArray = NULL;
957 m_pExtendedIconArray = NULL;
959 m_cs = (ColorScheme)-1;
962 m_iconListScale = -999.0;
963 m_iconListHeight = -1;
966WayPointman::~WayPointman() {
972 RoutePointList temp_list;
975 temp_list.push_back(pr);
981 m_pWayPointList->clear();
982 delete m_pWayPointList;
984 for (
unsigned int i = 0; i < m_pIconArray->GetCount(); i++) {
986 delete pmi->piconBitmap;
990 m_pIconArray->Clear();
993 if (pmarkicon_image_list) pmarkicon_image_list->RemoveAll();
994 delete pmarkicon_image_list;
995 if (m_pLegacyIconArray) {
996 m_pLegacyIconArray->Clear();
997 delete m_pLegacyIconArray;
999 if (m_pExtendedIconArray) {
1000 m_pExtendedIconArray->Clear();
1001 delete m_pExtendedIconArray;
1006 if (!prp)
return false;
1008 m_pWayPointList->push_back(prp);
1009 prp->SetManagerListNode(prp);
1015 if (!prp)
return false;
1017 auto *prpnode = (
RoutePoint *)(prp->GetManagerListNode());
1021 std::find(m_pWayPointList->begin(), m_pWayPointList->end(), prpnode);
1022 if (pos != m_pWayPointList->end()) m_pWayPointList->erase(pos);
1024 auto pos = std::find(m_pWayPointList->begin(), m_pWayPointList->end(), prp);
1025 if (pos != m_pWayPointList->end()) m_pWayPointList->erase(pos);
1028 prp->SetManagerListNode(NULL);
1033wxImageList *WayPointman::Getpmarkicon_image_list(
int nominal_height) {
1035 if (pmarkicon_image_list && (nominal_height == m_iconListHeight)) {
1036 return pmarkicon_image_list;
1040 if (NULL != pmarkicon_image_list) {
1041 pmarkicon_image_list->RemoveAll();
1042 delete pmarkicon_image_list;
1044 pmarkicon_image_list =
new wxImageList(nominal_height, nominal_height);
1046 m_iconListHeight = nominal_height;
1047 m_bitmapSizeForList = nominal_height;
1049 return pmarkicon_image_list;
1052wxBitmap *WayPointman::CreateDimBitmap(wxBitmap *pBitmap,
double factor) {
1053 wxImage img = pBitmap->ConvertToImage();
1054 int sx = img.GetWidth();
1055 int sy = img.GetHeight();
1057 wxImage new_img(img);
1059 for (
int i = 0; i < sx; i++) {
1060 for (
int j = 0; j < sy; j++) {
1061 if (!img.IsTransparent(i, j)) {
1062 new_img.SetRGB(i, j, (
unsigned char)(img.GetRed(i, j) * factor),
1063 (
unsigned char)(img.GetGreen(i, j) * factor),
1064 (
unsigned char)(img.GetBlue(i, j) * factor));
1069 wxBitmap *pret =
new wxBitmap(new_img);
1074wxImage WayPointman::CreateDimImage(wxImage &image,
double factor) {
1075 int sx = image.GetWidth();
1076 int sy = image.GetHeight();
1078 wxImage new_img(image);
1080 for (
int i = 0; i < sx; i++) {
1081 for (
int j = 0; j < sy; j++) {
1082 if (!image.IsTransparent(i, j)) {
1083 new_img.SetRGB(i, j, (
unsigned char)(image.GetRed(i, j) * factor),
1084 (
unsigned char)(image.GetGreen(i, j) * factor),
1085 (
unsigned char)(image.GetBlue(i, j) * factor));
1090 return wxImage(new_img);
1093bool WayPointman::DoesIconExist(
const wxString &icon_key)
const {
1097 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1098 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1099 if (pmi->icon_name.IsSameAs(icon_key))
return true;
1105wxBitmap *WayPointman::GetIconBitmap(
const wxString &icon_key)
const {
1106 wxBitmap *pret = NULL;
1110 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1111 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1112 if (pmi->icon_name.IsSameAs(icon_key))
break;
1115 if (i == m_pIconArray->GetCount())
1118 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1119 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1125 if (i == m_pIconArray->GetCount())
1126 pmi = (
MarkIcon *)m_pIconArray->Item(0);
1129 if (pmi->piconBitmap)
1130 pret = pmi->piconBitmap;
1132 if (pmi->iconImage.IsOk()) {
1133 pmi->piconBitmap =
new wxBitmap(pmi->iconImage);
1134 pret = pmi->piconBitmap;
1141bool WayPointman::GetIconPrescaled(
const wxString &icon_key)
const {
1145 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1146 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1147 if (pmi->icon_name.IsSameAs(icon_key))
break;
1150 if (i == m_pIconArray->GetCount())
1153 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1154 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1160 if (i == m_pIconArray->GetCount())
1161 pmi = (
MarkIcon *)m_pIconArray->Item(0);
1164 return pmi->preScaled;
1169wxBitmap WayPointman::GetIconBitmapForList(
int index,
int height)
const {
1174 pmi = (
MarkIcon *)m_pIconArray->Item(index);
1176 if (pmi->iconImage.GetHeight() != height) {
1179 int w0 = pmi->iconImage.GetWidth();
1180 int h0 = pmi->iconImage.GetHeight();
1182 wxImage icon_resized = pmi->iconImage;
1183 if (h0 <= h && w0 <= w) {
1184 icon_resized = pmi->iconImage.Resize(
1185 wxSize(w, h), wxPoint(w / 2 - w0 / 2, h / 2 - h0 / 2));
1192 w1 = wxRound((
double)w0 * ((
double)h / (
double)h0));
1195 h1 = wxRound((
double)h0 * ((
double)w / (
double)w0));
1197 icon_resized = pmi->iconImage.Rescale(w1, h1);
1198 icon_resized = pmi->iconImage.Resize(
1199 wxSize(w, h), wxPoint(w / 2 - w1 / 2, h / 2 - h1 / 2));
1202 pret = wxBitmap(icon_resized);
1205 pret = wxBitmap(pmi->iconImage);
1211wxString *WayPointman::GetIconDescription(
int index)
const {
1212 wxString *pret = NULL;
1216 pret = &pmi->icon_description;
1221wxString WayPointman::GetIconDescription(wxString icon_key)
const {
1225 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1226 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1227 if (pmi->icon_name.IsSameAs(icon_key))
1228 return wxString(pmi->icon_description);
1234wxString *WayPointman::GetIconKey(
int index)
const {
1235 wxString *pret = NULL;
1237 if ((index >= 0) && ((
unsigned int)index < m_pIconArray->GetCount())) {
1239 pret = &pmi->icon_name;
1244int WayPointman::GetIconIndex(
const wxBitmap *pbm)
const {
1245 unsigned int ret = 0;
1248 wxASSERT(m_pIconArray->GetCount() >= 1);
1249 for (
unsigned int i = 0; i < m_pIconArray->GetCount(); i++) {
1250 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1251 if (pmi->piconBitmap == pbm) {
1260int WayPointman::GetIconImageListIndex(
const wxBitmap *pbm)
const {
1264 if (pmarkicon_image_list && !pmi->m_blistImageOK) {
1265 int h0 = pmi->iconImage.GetHeight();
1266 int w0 = pmi->iconImage.GetWidth();
1267 int h = m_bitmapSizeForList;
1268 int w = m_bitmapSizeForList;
1270 wxImage icon_larger = pmi->iconImage;
1271 if (h0 <= h && w0 <= w) {
1272 icon_larger = pmi->iconImage.Resize(
1273 wxSize(w, h), wxPoint(w / 2 - w0 / 2, h / 2 - h0 / 2));
1282 w1 = wxRound((
double)w0 * ((
double)h / (
double)h0));
1285 h1 = wxRound((
double)h0 * ((
double)w / (
double)w0));
1287 icon_larger = pmi->iconImage.Rescale(w1, h1).Resize(
1288 wxSize(w, h), wxPoint(w / 2 - w1 / 2, h / 2 - h1 / 2));
1291 int index = pmarkicon_image_list->Add(wxBitmap(icon_larger));
1296 icon_larger.ConvertAlphaToMask(128);
1298 unsigned char r, g, b;
1299 icon_larger.GetOrFindMaskColour(&r, &g, &b);
1300 wxColour unused_color(r, g, b);
1303 wxBitmap xIcon(icon_larger);
1305 wxBitmap xbmp(w, h, -1);
1306 wxMemoryDC mdc(xbmp);
1307 mdc.SetBackground(wxBrush(unused_color));
1309 mdc.DrawBitmap(xIcon, 0, 0);
1310 int xm = xbmp.GetWidth() / 2;
1311 int ym = xbmp.GetHeight() / 2;
1313 int width = wxMax(xm / 10, 2);
1314 wxPen red(m_get_global_colour(
"URED"), width);
1316 mdc.DrawLine(xm - dp, ym - dp, xm + dp, ym + dp);
1317 mdc.DrawLine(xm - dp, ym + dp, xm + dp, ym - dp);
1318 mdc.SelectObject(wxNullBitmap);
1320 wxMask *pmask =
new wxMask(xbmp, unused_color);
1321 xbmp.SetMask(pmask);
1323 pmarkicon_image_list->Add(xbmp);
1326 wxBitmap fIcon(icon_larger);
1328 wxBitmap fbmp(w, h, -1);
1329 wxMemoryDC fmdc(fbmp);
1330 fmdc.SetBackground(wxBrush(unused_color));
1332 fmdc.DrawBitmap(xIcon, 0, 0);
1333 xm = fbmp.GetWidth() / 2;
1334 ym = fbmp.GetHeight() / 2;
1336 width = wxMax(xm / 10, 2);
1337 wxPen fred(m_get_global_colour(
"UGREN"), width);
1339 fmdc.DrawLine(xm - dp, ym + dp, xm + dp, ym + dp);
1340 fmdc.SelectObject(wxNullBitmap);
1342 wxMask *pfmask =
new wxMask(fbmp, unused_color);
1343 fbmp.SetMask(pfmask);
1345 pmarkicon_image_list->Add(fbmp);
1347 pmi->m_blistImageOK =
true;
1348 pmi->listIndex = index;
1351 return pmi->listIndex;
1355 return GetIconImageListIndex(pbm) + 1;
1359 return GetIconImageListIndex(pbm) + 2;
1363wxString WayPointman::CreateGUID(
RoutePoint *pRP) {
1367RoutePoint *WayPointman::FindRoutePointByGUID(
const wxString &guid) {
1369 if (prp->m_GUID == guid)
return (prp);
1374RoutePoint *WayPointman::GetNearbyWaypoint(
double lat,
double lon,
1375 double radius_meters) {
1379 double a = lat - pr->m_lat;
1380 double b = lon - pr->m_lon;
1381 double l = sqrt((a * a) + (b * b));
1383 if ((l * 60. * 1852.) < radius_meters)
return pr;
1388RoutePoint *WayPointman::GetOtherNearbyWaypoint(
double lat,
double lon,
1389 double radius_meters,
1390 const wxString &guid) {
1394 double a = lat - pr->m_lat;
1395 double b = lon - pr->m_lon;
1396 double l = sqrt((a * a) + (b * b));
1398 if ((l * 60. * 1852.) < radius_meters)
1399 if (pr->m_GUID != guid)
return pr;
1404bool WayPointman::IsReallyVisible(
RoutePoint *pWP) {
1407 if (proute && proute->pRoutePointList) {
1408 auto &list = proute->pRoutePointList;
1409 auto pos = std::find(list->begin(), list->end(), pWP);
1410 if (pos != list->end()) {
1411 if (proute->IsVisible())
return true;
1415 if (pWP->IsShared())
1417 return pWP->IsVisible();
1422void WayPointman::ClearRoutePointFonts() {
1426 pr->m_pMarkFont = NULL;
1430bool WayPointman::SharedWptsExist() {
1439void WayPointman::DeleteAllWaypoints(
bool b_delete_used) {
1441 auto it = m_pWayPointList->begin();
1442 while (it != m_pWayPointList->end()) {
1445 if (!prp->
m_bIsInLayer && (prp->GetIconName() !=
"mob") &&
1446 ((b_delete_used && prp->IsShared()) ||
1449 DestroyWaypoint(prp);
1451 it = m_pWayPointList->begin();
1458RoutePoint *WayPointman::FindWaypointByGuid(
const std::string &guid) {
1460 if (guid == rp->m_GUID)
return rp;
1464void WayPointman::DestroyWaypoint(
RoutePoint *pRp,
bool b_update_changeset) {
1470 for (
unsigned int ir = 0; ir < proute_array->GetCount(); ir++) {
1477 pr->RemovePoint(pRp);
1481 for (
unsigned int ir = 0; ir < proute_array->GetCount(); ir++) {
1483 if (pr->GetnPoints() < 2) {
1488 delete proute_array;
1492 NavObj_dB::GetInstance().DeleteRoutePoint(pRp);
1494 pSelect->DeleteSelectableRoutePoint(pRp);
Class AisDecoder and helpers.
Autopilot output support.
void Notify() override
Notify all listeners, no data supplied.
Wrapper for global variable, supports notification events when value changes.
static wxString GetUUID(void)
Return a unique RFC4122 version 4 compliant GUID string.
Represents a waypoint or mark within the navigation system.
wxRect CurrentRect_in_DC
Current rectangle occupied by the waypoint in the display.
wxString m_GUID
Globally Unique Identifier for the waypoint.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bIsActive
Flag indicating if this waypoint is active for navigation.
bool m_bIsInRoute
Flag indicating if this waypoint is part of a route.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
bool m_bBlink
Flag indicating if the waypoint should blink when displayed.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
bool m_bRtIsActive
Flag indicating whether this route is currently active for navigation.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Activates a specific waypoint within a route for navigation.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
EventVar json_msg
Notified with message targeting all plugins.
EventVar json_leg_info
Notified with a shared_ptr<ActiveLegDat>, leg info to all plugins.
EventVar on_message_sent
Notified when a message available as GetString() is sent to garmin.
Represents a track, which is a series of connected track points.
int GetXIconImageListIndex(const wxBitmap *pbm) const
index of "X-ed out" icon in the image list
int GetFIconImageListIndex(const wxBitmap *pbm) const
index of "fixed viz" icon in the image list
bool AddRoutePoint(RoutePoint *prp)
Add a point to list which owns it.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.
The JSON value class implementation.
NMEA Data Multiplexer Object.
Global variables stored in configuration file.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
Wrapper for creating an NmeaContext based on global vars.
Global variables Listen()/Notify() wrapper.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gVar
Magnetic variation in degrees.
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
std::vector< DriverHandle > GetActiveDrivers()
Comm port plugin TX support methods
const std::unordered_map< std::string, std::string > GetAttributes(DriverHandle handle)
Query a specific driver for attributes.
wxRect g_blink_rect
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
bool g_bPluginHandleAutopilotRoute
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
float g_ChartScaleFactorExp
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
bool g_bPluginHandleAutopilotRoute
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
float g_ChartScaleFactorExp
Global instance.
Select * pSelect
Global instance.
Callbacks for RoutePropDlg.
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.