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"
57extern bool g_bShowShipToActive;
58extern bool g_bAdvanceRouteWaypointOnArrivalOnly;
64extern std::vector<Track *> g_TrackList;
70static bool ConfirmDeleteAisMob() {
71 int r = OCPNMessageBox(NULL,
72 _(
"You are trying to delete an active AIS MOB "
73 "route, are you REALLY sure?"),
74 _(
"OpenCPN Warning"), wxYES_NO);
81 ctx.confirm_delete_ais_mob = []() {
return ConfirmDeleteAisMob(); };
82 ctx.get_global_colour = [](wxString c) {
return GetGlobalColor(c); };
83 ctx.show_with_fresh_fonts = [] {
86 ctx.clear_console_background = []() {
87 console->pCDI->ClearBackground();
90 ctx.route_mgr_dlg_update_list_ctrl = []() {
91 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
92 pRouteManagerDialog->UpdateRouteListCtrl();
97bool RoutemanGui::UpdateProgress() {
98 bool bret_val =
false;
100 if (m_routeman.pActiveRoute) {
106 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon, gLat,
107 gLon, &east, &north);
108 double a = atan(north / east);
109 if (fabs(m_routeman.pActivePoint->m_lon - gLon) < 180.) {
110 if (m_routeman.pActivePoint->m_lon > gLon)
111 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
113 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
115 if (m_routeman.pActivePoint->m_lon > gLon)
116 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
118 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
123 double d5 = DistGreatCircle(gLat, gLon, m_routeman.pActivePoint->m_lat,
124 m_routeman.pActivePoint->m_lon);
125 m_routeman.CurrentRngToActivePoint = d5;
130 double brg1, dist1, brg2, dist2;
131 DistanceBearingMercator(
132 m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
133 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
134 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &brg1, &dist1);
135 vb.x = dist1 * sin(brg1 * PI / 180.);
136 vb.y = dist1 * cos(brg1 * PI / 180.);
138 DistanceBearingMercator(m_routeman.pActivePoint->m_lat,
139 m_routeman.pActivePoint->m_lon, gLat, gLon, &brg2,
141 va.x = dist2 * sin(brg2 * PI / 180.);
142 va.y = dist2 * cos(brg2 * PI / 180.);
144 double sdelta = vGetLengthOfNormal(&va, &vb, &vn);
145 m_routeman.CurrentXTEToActivePoint = sdelta;
150 vector2D vToArriveNormal;
151 vSubtractVectors(&va, &vn, &vToArriveNormal);
153 m_routeman.CurrentRangeToActiveNormalCrossing =
154 vVectorMagnitude(&vToArriveNormal);
158 double x1, y1, x2, y2;
159 toSM(m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
160 m_routeman.pActiveRouteSegmentBeginPoint->m_lon,
161 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
162 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x1, &y1);
164 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
165 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
166 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x2, &y2);
168 double e1 = atan2((x2 - x1), (y2 - y1));
169 m_routeman.CurrentSegmentCourse = e1 * 180 / PI;
170 if (m_routeman.CurrentSegmentCourse < 0)
171 m_routeman.CurrentSegmentCourse += 360;
174 double h = atan(vn.y / vn.x);
176 m_routeman.CourseToRouteSegment = 90. - (h * 180 / PI);
178 m_routeman.CourseToRouteSegment = 270. - (h * 180 / PI);
180 h = m_routeman.CurrentBrgToActivePoint - m_routeman.CourseToRouteSegment;
181 if (h < 0) h = h + 360;
184 m_routeman.XTEDir = 1;
186 m_routeman.XTEDir = -1;
190 if (g_bShowShipToActive) {
191 if (m_routeman.pActiveRoute->GetIndexOf(m_routeman.pActivePoint) == 1)
192 g_bAllowShipToActive =
true;
197 ll_gc_ll(gLat, gLon, m_routeman.CourseToRouteSegment,
198 (m_routeman.CurrentXTEToActivePoint / 1.852), &tlat, &tlon);
199 gFrame->GetFocusCanvas()->GetCanvasPointPix(gLat, gLon, &r1);
200 gFrame->GetFocusCanvas()->GetCanvasPointPix(tlat, tlon, &r);
202 sqrt(pow((
double)(r1.x - r.x), 2) + pow((
double)(r1.y - r.y), 2));
204 double xtemm = xtepix / gFrame->GetFocusCanvas()->GetPixPerMM();
206 g_bAllowShipToActive = (xtemm > 3.0) ?
true : false;
212 bool bDidArrival =
false;
216 if (m_routeman.pActivePoint->GetWaypointArrivalRadius() > 0) {
217 if (m_routeman.CurrentRangeToActiveNormalCrossing <=
218 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
219 m_routeman.m_bArrival =
true;
220 m_routeman.UpdateAutopilot();
229 if ((m_routeman.CurrentRangeToActiveNormalCrossing -
230 m_routeman.m_arrival_min) >
231 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
232 if (++m_routeman.m_arrival_test > 2 &&
233 !g_bAdvanceRouteWaypointOnArrivalOnly) {
234 m_routeman.m_bArrival =
true;
235 m_routeman.UpdateAutopilot();
241 m_routeman.m_arrival_test = 0;
245 m_routeman.m_arrival_min =
246 wxMin(m_routeman.m_arrival_min,
247 m_routeman.CurrentRangeToActiveNormalCrossing);
249 if (!bDidArrival) m_routeman.UpdateAutopilot();
252 m_routeman.m_bDataValid =
true;
256void RoutemanGui::DeleteTrack(
Track *pTrack) {
258 if (pTrack->m_bIsInLayer)
return;
260 ::wxBeginBusyCursor();
262 wxGenericProgressDialog *pprog =
nullptr;
264 int count = pTrack->GetnPoints();
266 pprog =
new wxGenericProgressDialog(
267 _(
"OpenCPN Track Delete"), _T(
"0/0"), count, NULL,
268 wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME |
269 wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
270 pprog->SetSize(400, wxDefaultCoord);
273 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
274 (pTrackPropDialog->IsShown()) &&
275 (pTrack == pTrackPropDialog->GetTrack())) {
276 pTrackPropDialog->Hide();
279 if ((pTrack == g_pActiveTrack) && pTrack->IsRunning()) {
280 pTrack = gFrame->TrackOff();
283 pSelect->DeleteAllSelectableTrackSegments(pTrack);
284 auto it = std::find(g_TrackList.begin(), g_TrackList.end(), pTrack);
285 if (it != g_TrackList.end()) {
286 g_TrackList.erase(it);
296void RoutemanGui::DeleteAllTracks() {
299 ::wxBeginBusyCursor();
304 std::vector<Track *> to_del = g_TrackList;
305 for (
Track *ptrack : to_del) {
306 if (ptrack->m_bIsInLayer)
continue;
308 g_pAIS->DeletePersistentTrack(ptrack);
309 NavObj_dB::GetInstance().DeleteTrack(ptrack);
315void RoutemanGui::DoAdvance(
void) {
319 Route *pthis_route = m_routeman.pActiveRoute;
320 m_routeman.DeactivateRoute(
true);
326 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.
Represents a navigational route in the navigation system.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
bool m_bIsBeingEdited
Flag indicating that the route is currently being edited by the user.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute)
Represents a track, which is a series of connected track points.