37#include "model/georef.h"
38#include "model/nav_object_database.h"
39#include "model/own_ship.h"
40#include "model/route.h"
41#include "model/route_point.h"
42#include "model/select.h"
43#include "model/track.h"
47#include "model/ais_decoder.h"
50#include "ocpn_frame.h"
51#include "routemanagerdialog.h"
52#include "routeman_gui.h"
53#include "TrackPropDlg.h"
56extern bool g_bShowShipToActive;
57extern bool g_bAdvanceRouteWaypointOnArrivalOnly;
63extern std::vector<Track *> g_TrackList;
69static bool ConfirmDeleteAisMob() {
70 int r = OCPNMessageBox(NULL,
71 _(
"You are trying to delete an active AIS MOB "
72 "route, are you REALLY sure?"),
73 _(
"OpenCPN Warning"), wxYES_NO);
80 ctx.confirm_delete_ais_mob = []() {
return ConfirmDeleteAisMob(); };
81 ctx.get_global_colour = [](wxString c) {
return GetGlobalColor(c); };
82 ctx.show_with_fresh_fonts = [] {
85 ctx.clear_console_background = []() {
86 console->pCDI->ClearBackground();
89 ctx.route_mgr_dlg_update_list_ctrl = []() {
90 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
91 pRouteManagerDialog->UpdateRouteListCtrl();
96bool RoutemanGui::UpdateProgress() {
97 bool bret_val =
false;
99 if (m_routeman.pActiveRoute) {
105 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon, gLat,
106 gLon, &east, &north);
107 double a = atan(north / east);
108 if (fabs(m_routeman.pActivePoint->m_lon - gLon) < 180.) {
109 if (m_routeman.pActivePoint->m_lon > gLon)
110 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
112 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
114 if (m_routeman.pActivePoint->m_lon > gLon)
115 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
117 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
122 double d5 = DistGreatCircle(gLat, gLon, m_routeman.pActivePoint->m_lat,
123 m_routeman.pActivePoint->m_lon);
124 m_routeman.CurrentRngToActivePoint = d5;
129 double brg1, dist1, brg2, dist2;
130 DistanceBearingMercator(
131 m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
132 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
133 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &brg1, &dist1);
134 vb.x = dist1 * sin(brg1 * PI / 180.);
135 vb.y = dist1 * cos(brg1 * PI / 180.);
137 DistanceBearingMercator(m_routeman.pActivePoint->m_lat,
138 m_routeman.pActivePoint->m_lon, gLat, gLon, &brg2,
140 va.x = dist2 * sin(brg2 * PI / 180.);
141 va.y = dist2 * cos(brg2 * PI / 180.);
143 double sdelta = vGetLengthOfNormal(&va, &vb, &vn);
144 m_routeman.CurrentXTEToActivePoint = sdelta;
149 vector2D vToArriveNormal;
150 vSubtractVectors(&va, &vn, &vToArriveNormal);
152 m_routeman.CurrentRangeToActiveNormalCrossing =
153 vVectorMagnitude(&vToArriveNormal);
157 double x1, y1, x2, y2;
158 toSM(m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
159 m_routeman.pActiveRouteSegmentBeginPoint->m_lon,
160 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
161 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x1, &y1);
163 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
164 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
165 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x2, &y2);
167 double e1 = atan2((x2 - x1), (y2 - y1));
168 m_routeman.CurrentSegmentCourse = e1 * 180 / PI;
169 if (m_routeman.CurrentSegmentCourse < 0)
170 m_routeman.CurrentSegmentCourse += 360;
173 double h = atan(vn.y / vn.x);
175 m_routeman.CourseToRouteSegment = 90. - (h * 180 / PI);
177 m_routeman.CourseToRouteSegment = 270. - (h * 180 / PI);
179 h = m_routeman.CurrentBrgToActivePoint - m_routeman.CourseToRouteSegment;
180 if (h < 0) h = h + 360;
183 m_routeman.XTEDir = 1;
185 m_routeman.XTEDir = -1;
189 if (g_bShowShipToActive) {
190 if (m_routeman.pActiveRoute->GetIndexOf(m_routeman.pActivePoint) == 1)
191 g_bAllowShipToActive =
true;
196 ll_gc_ll(gLat, gLon, m_routeman.CourseToRouteSegment,
197 (m_routeman.CurrentXTEToActivePoint / 1.852), &tlat, &tlon);
198 gFrame->GetFocusCanvas()->GetCanvasPointPix(gLat, gLon, &r1);
199 gFrame->GetFocusCanvas()->GetCanvasPointPix(tlat, tlon, &r);
201 sqrt(pow((
double)(r1.x - r.x), 2) + pow((
double)(r1.y - r.y), 2));
203 double xtemm = xtepix / gFrame->GetFocusCanvas()->GetPixPerMM();
205 g_bAllowShipToActive = (xtemm > 3.0) ?
true : false;
211 bool bDidArrival =
false;
215 if (m_routeman.pActivePoint->GetWaypointArrivalRadius() > 0) {
216 if (m_routeman.CurrentRangeToActiveNormalCrossing <=
217 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
218 m_routeman.m_bArrival =
true;
219 m_routeman.UpdateAutopilot();
228 if ((m_routeman.CurrentRangeToActiveNormalCrossing -
229 m_routeman.m_arrival_min) >
230 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
231 if (++m_routeman.m_arrival_test > 2 &&
232 !g_bAdvanceRouteWaypointOnArrivalOnly) {
233 m_routeman.m_bArrival =
true;
234 m_routeman.UpdateAutopilot();
240 m_routeman.m_arrival_test = 0;
244 m_routeman.m_arrival_min =
245 wxMin(m_routeman.m_arrival_min,
246 m_routeman.CurrentRangeToActiveNormalCrossing);
248 if (!bDidArrival) m_routeman.UpdateAutopilot();
251 m_routeman.m_bDataValid =
true;
255void RoutemanGui::DeleteTrack(
Track *pTrack) {
257 if (pTrack->m_bIsInLayer)
return;
259 ::wxBeginBusyCursor();
261 wxGenericProgressDialog *pprog =
nullptr;
263 int count = pTrack->GetnPoints();
265 pprog =
new wxGenericProgressDialog(
266 _(
"OpenCPN Track Delete"), _T(
"0/0"), count, NULL,
267 wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME |
268 wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
269 pprog->SetSize(400, wxDefaultCoord);
272 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
273 (pTrackPropDialog->IsShown()) &&
274 (pTrack == pTrackPropDialog->GetTrack())) {
275 pTrackPropDialog->Hide();
278 if ((pTrack == g_pActiveTrack) && pTrack->IsRunning()) {
279 pTrack = gFrame->TrackOff();
282 pSelect->DeleteAllSelectableTrackSegments(pTrack);
283 auto it = std::find(g_TrackList.begin(), g_TrackList.end(), pTrack);
284 if (it != g_TrackList.end()) {
285 g_TrackList.erase(it);
295void RoutemanGui::DeleteAllTracks() {
298 ::wxBeginBusyCursor();
303 std::vector<Track *> to_del = g_TrackList;
304 for (
Track *ptrack : to_del) {
305 if (ptrack->m_bIsInLayer)
continue;
307 g_pAIS->DeletePersistentTrack(ptrack);
308 NavObjectChanges::getInstance()->m_bSkipChangeSetUpdate =
true;
309 NavObjectChanges::getInstance()->DeleteConfigTrack(ptrack);
311 NavObjectChanges::getInstance()->m_bSkipChangeSetUpdate =
false;
314 if (pConfig && pConfig->IsChangesFileDirty()) {
315 pConfig->UpdateNavObj(
true);
321void RoutemanGui::DoAdvance(
void) {
325 Route *pthis_route = m_routeman.pActiveRoute;
326 m_routeman.DeactivateRoute(
true);
328 if (pthis_route->m_bDeleteOnArrival && !pthis_route->m_bIsBeingEdited) {
329 NavObjectChanges::getInstance()->DeleteConfigRoute(pthis_route);
330 m_routeman.
DeleteRoute(pthis_route, NavObjectChanges::getInstance());
333 if (pRouteManagerDialog) pRouteManagerDialog->UpdateRouteListCtrl();
Represents an active track that is currently being recorded.
Primary navigation console display for route and vessel tracking.
void ShowWithFreshFonts(void)
Recomputes and applies new fonts to console elements.
bool ActivateNextPoint(Route *pr, bool skipped)
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)
Represents a track, which is a series of connected track points.