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();
845 std::vector<Route *> delete_list;
850 if (!m_route_dlg_ctx.confirm_delete_ais_mob()) {
855 if (proute->m_bIsInLayer)
continue;
857 delete_list.push_back(proute);
862 while (delete_list.size()) {
864 delete_list.pop_back();
870void Routeman::SetColorScheme(ColorScheme cs,
double displayDPmm) {
873 int scaled_line_width = g_route_line_width;
874 int track_scaled_line_width = g_track_line_width;
877 double nominal_line_width_pix = wxMax(2.0, floor(displayDPmm * 0.4));
879 double sline_width = wxMax(nominal_line_width_pix, g_route_line_width);
881 scaled_line_width = wxMax(sline_width, 2);
883 double tsline_width = wxMax(nominal_line_width_pix, g_track_line_width);
885 track_scaled_line_width = wxMax(tsline_width, 2);
888 m_pActiveRoutePointPen = wxThePenList->FindOrCreatePen(
889 wxColour(0, 0, 255), scaled_line_width, wxPENSTYLE_SOLID);
890 m_pRoutePointPen = wxThePenList->FindOrCreatePen(
891 wxColour(0, 0, 255), scaled_line_width, wxPENSTYLE_SOLID);
896 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UINFB"),
897 scaled_line_width, wxPENSTYLE_SOLID);
898 m_pSelectedRoutePen =
899 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UINFO"),
900 scaled_line_width, wxPENSTYLE_SOLID);
902 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"UARTE"),
903 scaled_line_width, wxPENSTYLE_SOLID);
905 wxThePenList->FindOrCreatePen(m_route_dlg_ctx.get_global_colour(
"CHMGD"),
906 track_scaled_line_width, wxPENSTYLE_SOLID);
907 m_pRouteBrush = wxTheBrushList->FindOrCreateBrush(
908 m_route_dlg_ctx.get_global_colour(
"UINFB"), wxBRUSHSTYLE_SOLID);
909 m_pSelectedRouteBrush = wxTheBrushList->FindOrCreateBrush(
910 m_route_dlg_ctx.get_global_colour(
"UINFO"), wxBRUSHSTYLE_SOLID);
911 m_pActiveRouteBrush = wxTheBrushList->FindOrCreateBrush(
912 m_route_dlg_ctx.get_global_colour(
"PLRTE"), wxBRUSHSTYLE_SOLID);
915wxString Routeman::GetRouteReverseMessage() {
917 _(
"Waypoints can be renamed to reflect the new order, the names will be "
918 "'001', '002' etc.\n\nDo you want to rename the waypoints?"));
921wxString Routeman::GetRouteResequenceMessage() {
923 _(
"Waypoints will be renamed to reflect the natural order, the names "
924 "will be '001', '002' etc.\n\nDo you want to rename the waypoints?"));
927Route *Routeman::FindRouteByGUID(
const wxString &guid) {
929 if (pRoute->
m_GUID == guid)
return pRoute;
934Track *Routeman::FindTrackByGUID(
const wxString &guid) {
936 if (pTrack->m_GUID == guid)
return pTrack;
941void Routeman::ZeroCurrentXTEToActivePoint() {
943 if (pRouteActivatePoint)
delete pRouteActivatePoint;
948 pActiveRouteSegmentBeginPoint = pRouteActivatePoint;
956WayPointman::WayPointman(GlobalColourFunc color_func)
957 : m_get_global_colour(color_func) {
958 m_pWayPointList =
new RoutePointList;
960 pmarkicon_image_list = NULL;
963 m_pIconArray =
new ArrayOfMarkIcon;
964 m_pLegacyIconArray = NULL;
965 m_pExtendedIconArray = NULL;
967 m_cs = (ColorScheme)-1;
970 m_iconListScale = -999.0;
971 m_iconListHeight = -1;
974WayPointman::~WayPointman() {
980 RoutePointList temp_list;
983 temp_list.push_back(pr);
989 m_pWayPointList->clear();
990 delete m_pWayPointList;
992 for (
unsigned int i = 0; i < m_pIconArray->GetCount(); i++) {
994 delete pmi->piconBitmap;
998 m_pIconArray->Clear();
1001 if (pmarkicon_image_list) pmarkicon_image_list->RemoveAll();
1002 delete pmarkicon_image_list;
1003 if (m_pLegacyIconArray) {
1004 m_pLegacyIconArray->Clear();
1005 delete m_pLegacyIconArray;
1007 if (m_pExtendedIconArray) {
1008 m_pExtendedIconArray->Clear();
1009 delete m_pExtendedIconArray;
1014 if (!prp)
return false;
1016 m_pWayPointList->push_back(prp);
1017 prp->SetManagerListNode(prp);
1023 if (!prp)
return false;
1025 auto *prpnode = (
RoutePoint *)(prp->GetManagerListNode());
1029 std::find(m_pWayPointList->begin(), m_pWayPointList->end(), prpnode);
1030 if (pos != m_pWayPointList->end()) m_pWayPointList->erase(pos);
1032 auto pos = std::find(m_pWayPointList->begin(), m_pWayPointList->end(), prp);
1033 if (pos != m_pWayPointList->end()) m_pWayPointList->erase(pos);
1036 prp->SetManagerListNode(NULL);
1041wxImageList *WayPointman::Getpmarkicon_image_list(
int nominal_height) {
1043 if (pmarkicon_image_list && (nominal_height == m_iconListHeight)) {
1044 return pmarkicon_image_list;
1048 if (NULL != pmarkicon_image_list) {
1049 pmarkicon_image_list->RemoveAll();
1050 delete pmarkicon_image_list;
1052 pmarkicon_image_list =
new wxImageList(nominal_height, nominal_height);
1054 m_iconListHeight = nominal_height;
1055 m_bitmapSizeForList = nominal_height;
1057 return pmarkicon_image_list;
1060wxBitmap *WayPointman::CreateDimBitmap(wxBitmap *pBitmap,
double factor) {
1061 wxImage img = pBitmap->ConvertToImage();
1062 int sx = img.GetWidth();
1063 int sy = img.GetHeight();
1065 wxImage new_img(img);
1067 for (
int i = 0; i < sx; i++) {
1068 for (
int j = 0; j < sy; j++) {
1069 if (!img.IsTransparent(i, j)) {
1070 new_img.SetRGB(i, j, (
unsigned char)(img.GetRed(i, j) * factor),
1071 (
unsigned char)(img.GetGreen(i, j) * factor),
1072 (
unsigned char)(img.GetBlue(i, j) * factor));
1077 wxBitmap *pret =
new wxBitmap(new_img);
1082wxImage WayPointman::CreateDimImage(wxImage &image,
double factor) {
1083 int sx = image.GetWidth();
1084 int sy = image.GetHeight();
1086 wxImage new_img(image);
1088 for (
int i = 0; i < sx; i++) {
1089 for (
int j = 0; j < sy; j++) {
1090 if (!image.IsTransparent(i, j)) {
1091 new_img.SetRGB(i, j, (
unsigned char)(image.GetRed(i, j) * factor),
1092 (
unsigned char)(image.GetGreen(i, j) * factor),
1093 (
unsigned char)(image.GetBlue(i, j) * factor));
1098 return wxImage(new_img);
1101bool WayPointman::DoesIconExist(
const wxString &icon_key)
const {
1105 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1106 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1107 if (pmi->icon_name.IsSameAs(icon_key))
return true;
1113wxBitmap *WayPointman::GetIconBitmap(
const wxString &icon_key)
const {
1114 wxBitmap *pret = NULL;
1118 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1119 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1120 if (pmi->icon_name.IsSameAs(icon_key))
break;
1123 if (i == m_pIconArray->GetCount())
1126 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1127 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1133 if (i == m_pIconArray->GetCount())
1134 pmi = (
MarkIcon *)m_pIconArray->Item(0);
1137 if (pmi->piconBitmap)
1138 pret = pmi->piconBitmap;
1140 if (pmi->iconImage.IsOk()) {
1141 pmi->piconBitmap =
new wxBitmap(pmi->iconImage);
1142 pret = pmi->piconBitmap;
1149bool WayPointman::GetIconPrescaled(
const wxString &icon_key)
const {
1153 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1154 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1155 if (pmi->icon_name.IsSameAs(icon_key))
break;
1158 if (i == m_pIconArray->GetCount())
1161 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1162 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1168 if (i == m_pIconArray->GetCount())
1169 pmi = (
MarkIcon *)m_pIconArray->Item(0);
1172 return pmi->preScaled;
1177wxBitmap WayPointman::GetIconBitmapForList(
int index,
int height)
const {
1182 pmi = (
MarkIcon *)m_pIconArray->Item(index);
1184 if (pmi->iconImage.GetHeight() != height) {
1187 int w0 = pmi->iconImage.GetWidth();
1188 int h0 = pmi->iconImage.GetHeight();
1190 wxImage icon_resized = pmi->iconImage;
1191 if (h0 <= h && w0 <= w) {
1192 icon_resized = pmi->iconImage.Resize(
1193 wxSize(w, h), wxPoint(w / 2 - w0 / 2, h / 2 - h0 / 2));
1200 w1 = wxRound((
double)w0 * ((
double)h / (
double)h0));
1203 h1 = wxRound((
double)h0 * ((
double)w / (
double)w0));
1205 icon_resized = pmi->iconImage.Rescale(w1, h1);
1206 icon_resized = pmi->iconImage.Resize(
1207 wxSize(w, h), wxPoint(w / 2 - w1 / 2, h / 2 - h1 / 2));
1210 pret = wxBitmap(icon_resized);
1213 pret = wxBitmap(pmi->iconImage);
1219wxString *WayPointman::GetIconDescription(
int index)
const {
1220 wxString *pret = NULL;
1224 pret = &pmi->icon_description;
1229wxString WayPointman::GetIconDescription(wxString icon_key)
const {
1233 for (i = 0; i < m_pIconArray->GetCount(); i++) {
1234 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1235 if (pmi->icon_name.IsSameAs(icon_key))
1236 return wxString(pmi->icon_description);
1242wxString *WayPointman::GetIconKey(
int index)
const {
1243 wxString *pret = NULL;
1245 if ((index >= 0) && ((
unsigned int)index < m_pIconArray->GetCount())) {
1247 pret = &pmi->icon_name;
1252int WayPointman::GetIconIndex(
const wxBitmap *pbm)
const {
1253 unsigned int ret = 0;
1256 wxASSERT(m_pIconArray->GetCount() >= 1);
1257 for (
unsigned int i = 0; i < m_pIconArray->GetCount(); i++) {
1258 pmi = (
MarkIcon *)m_pIconArray->Item(i);
1259 if (pmi->piconBitmap == pbm) {
1268int WayPointman::GetIconImageListIndex(
const wxBitmap *pbm)
const {
1272 if (pmarkicon_image_list && !pmi->m_blistImageOK) {
1273 int h0 = pmi->iconImage.GetHeight();
1274 int w0 = pmi->iconImage.GetWidth();
1275 int h = m_bitmapSizeForList;
1276 int w = m_bitmapSizeForList;
1278 wxImage icon_larger = pmi->iconImage;
1279 if (h0 <= h && w0 <= w) {
1280 icon_larger = pmi->iconImage.Resize(
1281 wxSize(w, h), wxPoint(w / 2 - w0 / 2, h / 2 - h0 / 2));
1290 w1 = wxRound((
double)w0 * ((
double)h / (
double)h0));
1293 h1 = wxRound((
double)h0 * ((
double)w / (
double)w0));
1295 icon_larger = pmi->iconImage.Rescale(w1, h1).Resize(
1296 wxSize(w, h), wxPoint(w / 2 - w1 / 2, h / 2 - h1 / 2));
1299 int index = pmarkicon_image_list->Add(wxBitmap(icon_larger));
1304 icon_larger.ConvertAlphaToMask(128);
1306 unsigned char r, g, b;
1307 icon_larger.GetOrFindMaskColour(&r, &g, &b);
1308 wxColour unused_color(r, g, b);
1311 wxBitmap xIcon(icon_larger);
1313 wxBitmap xbmp(w, h, -1);
1314 wxMemoryDC mdc(xbmp);
1315 mdc.SetBackground(wxBrush(unused_color));
1317 mdc.DrawBitmap(xIcon, 0, 0);
1318 int xm = xbmp.GetWidth() / 2;
1319 int ym = xbmp.GetHeight() / 2;
1321 int width = wxMax(xm / 10, 2);
1322 wxPen red(m_get_global_colour(
"URED"), width);
1324 mdc.DrawLine(xm - dp, ym - dp, xm + dp, ym + dp);
1325 mdc.DrawLine(xm - dp, ym + dp, xm + dp, ym - dp);
1326 mdc.SelectObject(wxNullBitmap);
1328 wxMask *pmask =
new wxMask(xbmp, unused_color);
1329 xbmp.SetMask(pmask);
1331 pmarkicon_image_list->Add(xbmp);
1334 wxBitmap fIcon(icon_larger);
1336 wxBitmap fbmp(w, h, -1);
1337 wxMemoryDC fmdc(fbmp);
1338 fmdc.SetBackground(wxBrush(unused_color));
1340 fmdc.DrawBitmap(xIcon, 0, 0);
1341 xm = fbmp.GetWidth() / 2;
1342 ym = fbmp.GetHeight() / 2;
1344 width = wxMax(xm / 10, 2);
1345 wxPen fred(m_get_global_colour(
"UGREN"), width);
1347 fmdc.DrawLine(xm - dp, ym + dp, xm + dp, ym + dp);
1348 fmdc.SelectObject(wxNullBitmap);
1350 wxMask *pfmask =
new wxMask(fbmp, unused_color);
1351 fbmp.SetMask(pfmask);
1353 pmarkicon_image_list->Add(fbmp);
1355 pmi->m_blistImageOK =
true;
1356 pmi->listIndex = index;
1359 return pmi->listIndex;
1363 return GetIconImageListIndex(pbm) + 1;
1367 return GetIconImageListIndex(pbm) + 2;
1371wxString WayPointman::CreateGUID(
RoutePoint *pRP) {
1375RoutePoint *WayPointman::FindRoutePointByGUID(
const wxString &guid) {
1377 if (prp->m_GUID == guid)
return (prp);
1382RoutePoint *WayPointman::GetNearbyWaypoint(
double lat,
double lon,
1383 double radius_meters) {
1387 double a = lat - pr->m_lat;
1388 double b = lon - pr->m_lon;
1389 double l = sqrt((a * a) + (b * b));
1391 if ((l * 60. * 1852.) < radius_meters)
return pr;
1396RoutePoint *WayPointman::GetOtherNearbyWaypoint(
double lat,
double lon,
1397 double radius_meters,
1398 const wxString &guid) {
1402 double a = lat - pr->m_lat;
1403 double b = lon - pr->m_lon;
1404 double l = sqrt((a * a) + (b * b));
1406 if ((l * 60. * 1852.) < radius_meters)
1407 if (pr->m_GUID != guid)
return pr;
1412bool WayPointman::IsReallyVisible(
RoutePoint *pWP) {
1415 if (proute && proute->pRoutePointList) {
1416 auto &list = proute->pRoutePointList;
1417 auto pos = std::find(list->begin(), list->end(), pWP);
1418 if (pos != list->end()) {
1419 if (proute->IsVisible())
return true;
1423 if (pWP->IsShared())
1425 return pWP->IsVisible();
1430void WayPointman::ClearRoutePointFonts() {
1434 pr->m_pMarkFont = NULL;
1438bool WayPointman::SharedWptsExist() {
1447void WayPointman::DeleteAllWaypoints(
bool b_delete_used) {
1449 auto it = m_pWayPointList->begin();
1450 while (it != m_pWayPointList->end()) {
1453 if (!prp->
m_bIsInLayer && (prp->GetIconName() !=
"mob") &&
1454 ((b_delete_used && prp->IsShared()) ||
1457 DestroyWaypoint(prp);
1459 it = m_pWayPointList->begin();
1466RoutePoint *WayPointman::FindWaypointByGuid(
const std::string &guid) {
1468 if (guid == rp->m_GUID)
return rp;
1472void WayPointman::DestroyWaypoint(
RoutePoint *pRp,
bool b_update_changeset) {
1478 for (
unsigned int ir = 0; ir < proute_array->GetCount(); ir++) {
1485 pr->RemovePoint(pRp);
1489 for (
unsigned int ir = 0; ir < proute_array->GetCount(); ir++) {
1491 if (pr->GetnPoints() < 2) {
1496 delete proute_array;
1500 NavObj_dB::GetInstance().DeleteRoutePoint(pRp);
1502 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.