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"
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;
69extern bool g_bhide_route_console;
71static bool ConfirmDeleteAisMob() {
72 int r = OCPNMessageBox(NULL,
73 _(
"You are trying to delete an active AIS MOB "
74 "route, are you REALLY sure?"),
75 _(
"OpenCPN Warning"), wxYES_NO);
82 ctx.confirm_delete_ais_mob = []() {
return ConfirmDeleteAisMob(); };
83 ctx.get_global_colour = [](wxString c) {
return GetGlobalColor(c); };
84 ctx.show_with_fresh_fonts = [] {
85 if (console && !g_bhide_route_console) console->ShowWithFreshFonts();
87 ctx.clear_console_background = []() {
88 console->GetCDI()->ClearBackground();
91 ctx.route_mgr_dlg_update_list_ctrl = []() {
92 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
93 pRouteManagerDialog->UpdateRouteListCtrl();
98bool RoutemanGui::UpdateProgress() {
99 bool bret_val =
false;
101 if (m_routeman.pActiveRoute) {
107 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon, gLat,
108 gLon, &east, &north);
109 double a = atan(north / east);
110 if (fabs(m_routeman.pActivePoint->m_lon - gLon) < 180.) {
111 if (m_routeman.pActivePoint->m_lon > gLon)
112 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
114 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
116 if (m_routeman.pActivePoint->m_lon > gLon)
117 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
119 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
124 double d5 = DistGreatCircle(gLat, gLon, m_routeman.pActivePoint->m_lat,
125 m_routeman.pActivePoint->m_lon);
126 m_routeman.CurrentRngToActivePoint = d5;
131 double brg1, dist1, brg2, dist2;
132 DistanceBearingMercator(
133 m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
134 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
135 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &brg1, &dist1);
136 vb.x = dist1 * sin(brg1 * PI / 180.);
137 vb.y = dist1 * cos(brg1 * PI / 180.);
139 DistanceBearingMercator(m_routeman.pActivePoint->m_lat,
140 m_routeman.pActivePoint->m_lon, gLat, gLon, &brg2,
142 va.x = dist2 * sin(brg2 * PI / 180.);
143 va.y = dist2 * cos(brg2 * PI / 180.);
145 double sdelta = vGetLengthOfNormal(&va, &vb, &vn);
146 m_routeman.CurrentXTEToActivePoint = sdelta;
151 vector2D vToArriveNormal;
152 vSubtractVectors(&va, &vn, &vToArriveNormal);
154 m_routeman.CurrentRangeToActiveNormalCrossing =
155 vVectorMagnitude(&vToArriveNormal);
159 double x1, y1, x2, y2;
160 toSM(m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
161 m_routeman.pActiveRouteSegmentBeginPoint->m_lon,
162 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
163 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x1, &y1);
165 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
166 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
167 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x2, &y2);
169 double e1 = atan2((x2 - x1), (y2 - y1));
170 m_routeman.CurrentSegmentCourse = e1 * 180 / PI;
171 if (m_routeman.CurrentSegmentCourse < 0)
172 m_routeman.CurrentSegmentCourse += 360;
175 double h = atan(vn.y / vn.x);
177 m_routeman.CourseToRouteSegment = 90. - (h * 180 / PI);
179 m_routeman.CourseToRouteSegment = 270. - (h * 180 / PI);
181 h = m_routeman.CurrentBrgToActivePoint - m_routeman.CourseToRouteSegment;
182 if (h < 0) h = h + 360;
185 m_routeman.XTEDir = 1;
187 m_routeman.XTEDir = -1;
191 if (g_bShowShipToActive) {
192 if (m_routeman.pActiveRoute->GetIndexOf(m_routeman.pActivePoint) == 1)
193 g_bAllowShipToActive =
true;
198 ll_gc_ll(gLat, gLon, m_routeman.CourseToRouteSegment,
199 (m_routeman.CurrentXTEToActivePoint / 1.852), &tlat, &tlon);
200 gFrame->GetFocusCanvas()->GetCanvasPointPix(gLat, gLon, &r1);
201 gFrame->GetFocusCanvas()->GetCanvasPointPix(tlat, tlon, &r);
203 sqrt(pow((
double)(r1.x - r.x), 2) + pow((
double)(r1.y - r.y), 2));
205 double xtemm = xtepix / gFrame->GetFocusCanvas()->GetPixPerMM();
207 g_bAllowShipToActive = (xtemm > 3.0) ?
true : false;
213 bool bDidArrival =
false;
216 if (isnan(m_routeman.CurrentRangeToActiveNormalCrossing)) {
217 m_routeman.CurrentRangeToActiveNormalCrossing =
218 m_routeman.CurrentRngToActivePoint;
223 if (m_routeman.pActivePoint->GetWaypointArrivalRadius() > 0) {
224 if (m_routeman.CurrentRangeToActiveNormalCrossing <=
225 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
226 m_routeman.m_bArrival =
true;
227 m_routeman.UpdateAutopilot();
236 if ((m_routeman.CurrentRangeToActiveNormalCrossing -
237 m_routeman.m_arrival_min) >
238 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
239 if (++m_routeman.m_arrival_test > 2 &&
240 !g_bAdvanceRouteWaypointOnArrivalOnly) {
241 m_routeman.m_bArrival =
true;
242 m_routeman.UpdateAutopilot();
248 m_routeman.m_arrival_test = 0;
252 m_routeman.m_arrival_min =
253 wxMin(m_routeman.m_arrival_min,
254 m_routeman.CurrentRangeToActiveNormalCrossing);
256 if (!bDidArrival) m_routeman.UpdateAutopilot();
259 m_routeman.m_bDataValid =
true;
263void RoutemanGui::DeleteTrack(
Track *pTrack) {
265 if (pTrack->m_bIsInLayer)
return;
267 ::wxBeginBusyCursor();
269 wxGenericProgressDialog *pprog =
nullptr;
271 int count = pTrack->GetnPoints();
273 pprog =
new wxGenericProgressDialog(
274 _(
"OpenCPN Track Delete"), _T(
"0/0"), count, NULL,
275 wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME |
276 wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
277 pprog->SetSize(400, wxDefaultCoord);
280 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
281 (pTrackPropDialog->IsShown()) &&
282 (pTrack == pTrackPropDialog->GetTrack())) {
283 pTrackPropDialog->Hide();
286 if ((pTrack == g_pActiveTrack) && pTrack->IsRunning()) {
287 pTrack = gFrame->TrackOff();
290 pSelect->DeleteAllSelectableTrackSegments(pTrack);
291 auto it = std::find(g_TrackList.begin(), g_TrackList.end(), pTrack);
292 if (it != g_TrackList.end()) {
293 g_TrackList.erase(it);
303void RoutemanGui::DeleteAllTracks() {
306 ::wxBeginBusyCursor();
311 std::vector<Track *> to_del = g_TrackList;
312 for (
Track *ptrack : to_del) {
313 if (ptrack->m_bIsInLayer)
continue;
315 g_pAIS->DeletePersistentTrack(ptrack);
316 NavObj_dB::GetInstance().DeleteTrack(ptrack);
322void RoutemanGui::DoAdvance(
void) {
326 Route *pthis_route = m_routeman.pActiveRoute;
327 m_routeman.DeactivateRoute(
true);
333 if (pRouteManagerDialog) pRouteManagerDialog->UpdateRouteListCtrl();
Class AisDecoder and helpers.
Represents an active track that is currently being recorded.
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.