28 #include <wx/wxprec.h>
35 #include <wx/gdicmn.h>
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"
56 extern bool g_bShowShipToActive;
57 extern bool g_bAdvanceRouteWaypointOnArrivalOnly;
63 extern std::vector<Track*> g_TrackList;
69 static 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 =
83 []{
if (console) console->ShowWithFreshFonts(); };
84 ctx.clear_console_background = [] () {
85 console->pCDI->ClearBackground();
86 console->Show(
false); };
87 ctx.route_mgr_dlg_update_list_ctrl = []() {
88 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
89 pRouteManagerDialog->UpdateRouteListCtrl();
95 bool RoutemanGui::UpdateProgress() {
96 bool bret_val =
false;
98 if (m_routeman.pActiveRoute) {
104 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
105 gLat, gLon, &east, &north);
106 double a = atan(north / east);
107 if (fabs(m_routeman.pActivePoint->m_lon - gLon) < 180.) {
108 if (m_routeman.pActivePoint->m_lon > gLon)
109 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
111 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
113 if (m_routeman.pActivePoint->m_lon > gLon)
114 m_routeman.CurrentBrgToActivePoint = 270. - (a * 180 / PI);
116 m_routeman.CurrentBrgToActivePoint = 90. - (a * 180 / PI);
122 DistGreatCircle(gLat, gLon, m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon);
123 m_routeman.CurrentRngToActivePoint = d5;
128 double brg1, dist1, brg2, dist2;
129 DistanceBearingMercator(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
130 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
131 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &brg1,
133 vb.x = dist1 * sin(brg1 * PI / 180.);
134 vb.y = dist1 * cos(brg1 * PI / 180.);
136 DistanceBearingMercator(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon, gLat,
137 gLon, &brg2, &dist2);
138 va.x = dist2 * sin(brg2 * PI / 180.);
139 va.y = dist2 * cos(brg2 * PI / 180.);
141 double sdelta = vGetLengthOfNormal(&va, &vb, &vn);
142 m_routeman.CurrentXTEToActivePoint = sdelta;
147 vector2D vToArriveNormal;
148 vSubtractVectors(&va, &vn, &vToArriveNormal);
150 m_routeman.CurrentRangeToActiveNormalCrossing =
151 vVectorMagnitude(&vToArriveNormal);
155 double x1, y1, x2, y2;
156 toSM(m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
157 m_routeman.pActiveRouteSegmentBeginPoint->m_lon,
158 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
159 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x1, &y1);
161 toSM(m_routeman.pActivePoint->m_lat, m_routeman.pActivePoint->m_lon,
162 m_routeman.pActiveRouteSegmentBeginPoint->m_lat,
163 m_routeman.pActiveRouteSegmentBeginPoint->m_lon, &x2, &y2);
165 double e1 = atan2((x2 - x1), (y2 - y1));
166 m_routeman.CurrentSegmentCourse = e1 * 180 / PI;
167 if (m_routeman.CurrentSegmentCourse < 0)
168 m_routeman.CurrentSegmentCourse += 360;
171 double h = atan(vn.y / vn.x);
173 m_routeman.CourseToRouteSegment = 90. - (h * 180 / PI);
175 m_routeman.CourseToRouteSegment = 270. - (h * 180 / PI);
177 h = m_routeman.CurrentBrgToActivePoint - m_routeman.CourseToRouteSegment;
178 if (h < 0) h = h + 360;
181 m_routeman.XTEDir = 1;
183 m_routeman.XTEDir = -1;
187 if (g_bShowShipToActive) {
188 if (m_routeman.pActiveRoute->GetIndexOf(m_routeman.pActivePoint) == 1)
189 g_bAllowShipToActive =
true;
194 ll_gc_ll(gLat, gLon, m_routeman.CourseToRouteSegment,
195 (m_routeman.CurrentXTEToActivePoint / 1.852), &tlat, &tlon);
196 gFrame->GetFocusCanvas()->GetCanvasPointPix(gLat, gLon, &r1);
197 gFrame->GetFocusCanvas()->GetCanvasPointPix(tlat, tlon, &r);
199 sqrt(pow((
double)(r1.x - r.x), 2) + pow((
double)(r1.y - r.y), 2));
201 double xtemm = xtepix / gFrame->GetFocusCanvas()->GetPixPerMM();
203 g_bAllowShipToActive = (xtemm > 3.0) ?
true :
false;
209 bool bDidArrival =
false;
213 if (m_routeman.pActivePoint->GetWaypointArrivalRadius() > 0) {
214 if (m_routeman.CurrentRangeToActiveNormalCrossing <=
215 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
216 m_routeman.m_bArrival =
true;
217 m_routeman.UpdateAutopilot();
226 if ((m_routeman.CurrentRangeToActiveNormalCrossing - m_routeman.m_arrival_min) >
227 m_routeman.pActivePoint->GetWaypointArrivalRadius()) {
228 if (++m_routeman.m_arrival_test > 2 &&
229 !g_bAdvanceRouteWaypointOnArrivalOnly)
231 m_routeman.m_bArrival =
true;
232 m_routeman.UpdateAutopilot();
238 m_routeman.m_arrival_test = 0;
242 m_routeman.m_arrival_min = wxMin(m_routeman.m_arrival_min,
243 m_routeman.CurrentRangeToActiveNormalCrossing);
245 if (!bDidArrival) m_routeman.UpdateAutopilot();
248 m_routeman.m_bDataValid =
true;
252 void RoutemanGui::DeleteTrack(
Track *pTrack) {
254 if (pTrack->m_bIsInLayer)
return;
256 ::wxBeginBusyCursor();
258 wxGenericProgressDialog *pprog =
nullptr;
260 int count = pTrack->GetnPoints();
262 pprog =
new wxGenericProgressDialog(
263 _(
"OpenCPN Track Delete"), _T(
"0/0"), count, NULL,
264 wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME |
265 wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
266 pprog->SetSize(400, wxDefaultCoord);
269 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
270 (pTrackPropDialog->IsShown()) &&
271 (pTrack == pTrackPropDialog->GetTrack())) {
272 pTrackPropDialog->Hide();
275 if ((pTrack == g_pActiveTrack) && pTrack->IsRunning()){
276 pTrack = gFrame->TrackOff();
279 pSelect->DeleteAllSelectableTrackSegments(pTrack);
280 auto it = std::find(g_TrackList.begin(), g_TrackList.end(), pTrack);
281 if (it != g_TrackList.end()) {
282 g_TrackList.erase(it);
292 void RoutemanGui::DeleteAllTracks() {
295 ::wxBeginBusyCursor();
300 std::vector<Track*> to_del = g_TrackList;
301 for (
Track *ptrack : to_del) {
302 if (ptrack->m_bIsInLayer)
continue;
304 g_pAIS->DeletePersistentTrack(ptrack);
305 NavObjectChanges::getInstance()->m_bSkipChangeSetUpdate =
true;
306 NavObjectChanges::getInstance()->DeleteConfigTrack(ptrack);
308 NavObjectChanges::getInstance()->m_bSkipChangeSetUpdate =
false;
311 if (pConfig && pConfig->IsChangesFileDirty()) {
312 pConfig->UpdateNavObj(
true);
318 void RoutemanGui::DoAdvance(
void) {
321 Route *pthis_route = m_routeman.pActiveRoute;
322 m_routeman.DeactivateRoute(
true);
324 if (pthis_route->m_bDeleteOnArrival && !pthis_route->m_bIsBeingEdited) {
325 NavObjectChanges::getInstance()->DeleteConfigRoute(pthis_route);
326 m_routeman.
DeleteRoute(pthis_route, NavObjectChanges::getInstance());
329 if (pRouteManagerDialog) pRouteManagerDialog->UpdateRouteListCtrl();
bool ActivateNextPoint(Route *pr, bool skipped)
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)