OpenCPN Partial API docs
Loading...
Searching...
No Matches
route.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 *
5 ***************************************************************************
6 * Copyright (C) 2013 by David S. Register *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 **************************************************************************/
23
24// For compilers that support precompilation, includes "wx.h".
25#include <wx/wxprec.h>
26
27#ifndef WX_PRECOMP
28#include <wx/wx.h>
29#endif // precompiled headers
30
31#ifndef WX_PRECOMP
32#include "wx/wx.h"
33#endif // precompiled headers
34
35#include <wx/arrstr.h>
36#include <wx/datetime.h>
37#include <wx/gdicmn.h>
38#include <wx/log.h>
39#include <wx/pen.h>
40#include <wx/string.h>
41
42#include "model/config_vars.h"
43#include "model/cutil.h"
44#include "model/georef.h"
45#include "model/georef.h"
46#include "model/config_vars.h"
47#include "model/nav_object_database.h"
48#include "model/route.h"
49#include "model/routeman.h"
50#include "model/select.h"
51#include "model/navobj_db.h"
52
53WayPointman *pWayPointMan;
54double g_defaultBoatSpeed;
55
56#include <wx/listimpl.cpp>
57
58WX_DEFINE_LIST(RouteList);
59
60Route::Route() {
61 m_bRtIsSelected = false;
62 m_bRtIsActive = false;
64 m_bIsBeingEdited = false;
65 m_bIsBeingCreated = false;
66 m_nm_sequence = 1;
67 m_route_length = 0.0;
68 m_route_time = 0.0;
69 m_bVisible = true;
70 m_bListed = true;
71 m_bDeleteOnArrival = false;
72 m_width = WIDTH_UNDEFINED;
73 m_style = wxPENSTYLE_INVALID;
74 m_hiliteWidth = 0;
75
76 pRoutePointList = new RoutePointList;
77 m_GUID = pWayPointMan->CreateGUID(NULL);
78 m_btemp = false;
79
80 m_ArrivalRadius = g_n_arrival_circle_radius; // Nautical Miles
81
82 m_LayerID = 0;
83 m_bIsInLayer = false;
84
85 m_Colour = wxEmptyString;
86
89
90 m_PlannedSpeed = ROUTE_DEFAULT_SPEED;
91 if (g_defaultBoatSpeed != ROUTE_DEFAULT_SPEED)
92 m_PlannedSpeed = g_defaultBoatSpeed;
93
94 m_PlannedDeparture = RTE_UNDEF_DEPARTURE;
95 m_TimeDisplayFormat = RTE_TIME_DISP_PC;
96 m_HyperlinkList = new HyperlinkList;
97
98 m_bsharedWPViz = false;
99}
100
101Route::~Route() {
102 pRoutePointList->DeleteContents(false); // do not delete Marks
103 delete pRoutePointList;
104 delete m_HyperlinkList;
105}
106
107// The following is used only for route splitting, assumes just created, empty
108// route
109//
110void Route::CloneRoute(Route *psourceroute, int start_nPoint, int end_nPoint,
111 const wxString &suffix,
112 const bool duplicate_first_point) {
113 m_RouteNameString = psourceroute->m_RouteNameString + suffix;
115 m_RouteEndString = psourceroute->m_RouteEndString;
116
117 int i;
118 for (i = start_nPoint; i <= end_nPoint; i++) {
119 if (!psourceroute->m_bIsInLayer &&
120 !(i == start_nPoint && duplicate_first_point)) {
121 AddPoint(psourceroute->GetPoint(i), false);
122 } else {
123 RoutePoint *psourcepoint = psourceroute->GetPoint(i);
124 RoutePoint *ptargetpoint = new RoutePoint(
125 psourcepoint->m_lat, psourcepoint->m_lon, psourcepoint->GetIconName(),
126 psourcepoint->GetName(), wxEmptyString, true);
127 ptargetpoint->m_bShowName =
128 psourcepoint->m_bShowName; // do not change new wpt's name visibility
129 AddPoint(ptargetpoint, false);
130 }
131 }
132
133 FinalizeForRendering();
134}
135
136wxString Route::IsPointNameValid(RoutePoint *pPoint,
137 const wxString &name) const {
138 RoutePoint *point;
139 wxRoutePointListNode *node = pRoutePointList->GetFirst();
140 wxString substr = name.SubString(0, 6);
141
142 while (node) {
143 point = node->GetData();
144 wxString exist = point->GetName().SubString(0, 6);
145
146 if (pPoint->m_GUID == point->m_GUID) {
147 node = node->GetNext();
148 } else if (substr == exist) {
149 return wxString("Name is not unique in route");
150 } else {
151 node = node->GetNext();
152 }
153 }
154
155 return wxEmptyString;
156}
157
158void Route::AddPoint(RoutePoint *pNewPoint, bool b_rename_in_sequence,
159 bool b_deferBoxCalc) {
160 if (pNewPoint->m_bIsolatedMark) {
161 pNewPoint->SetShared(true);
162 }
163 pNewPoint->m_bIsolatedMark = false; // definitely no longer isolated
164 pNewPoint->m_bIsInRoute = true;
165
166 RoutePoint *prev = GetLastPoint();
167 pRoutePointList->Append(pNewPoint);
168
169 if (!b_deferBoxCalc) FinalizeForRendering();
170
171 if (prev) UpdateSegmentDistance(prev, pNewPoint);
172
173 if (b_rename_in_sequence && pNewPoint->GetName().IsEmpty() &&
174 !pNewPoint->IsShared()) {
175 wxString name;
176 name.Printf(_T("%03d"), GetnPoints());
177 pNewPoint->SetName(name);
178 }
179 return;
180}
181
182void Route::AddPointAndSegment(RoutePoint *pNewPoint, bool b_rename_in_sequence,
183 bool b_deferBoxCalc) {
184 int npoints = GetnPoints();
185 RoutePoint *newpoint = pNewPoint;
186 if (newpoint->m_bIsInLayer) {
187 newpoint = new RoutePoint(pNewPoint->m_lat, pNewPoint->m_lon,
188 pNewPoint->GetIconName(), pNewPoint->GetName(),
189 wxEmptyString, false);
190 newpoint->m_bShowName =
191 pNewPoint->m_bShowName; // do not change new wpt's name visibility
192 }
193 AddPoint(newpoint, false);
194 if (npoints != 0) {
195 double rlat = GetPoint(npoints)->m_lat;
196 double rlon = GetPoint(npoints)->m_lon;
197 npoints = GetnPoints();
198 pSelect->AddSelectableRouteSegment(
199 rlat, rlon, GetPoint(npoints)->m_lat, GetPoint(npoints)->m_lon,
200 GetPoint(npoints - 1), GetPoint(npoints), this);
201 }
202 m_lastMousePointIndex = GetnPoints();
203}
204
205void Route::InsertPointAndSegment(RoutePoint *pNewPoint, int insert_after,
206 bool bRenamePoints, bool b_deferBoxCalc) {
207 {
208 bool add = false;
209
210 if (pNewPoint->m_bIsolatedMark) {
211 pNewPoint->SetShared(true);
212 }
213 pNewPoint->m_bIsolatedMark = false; // definitely no longer isolated
214 pNewPoint->m_bIsInRoute = true;
215
216 if (insert_after >= GetnPoints() - 1) {
217 wxLogMessage(wxT("Error insert after last point"));
218 return;
219 }
220
221 int insert = insert_after++;
222 pNewPoint->m_bIsInRoute = true;
223 pNewPoint->SetNameShown(false);
224 pRoutePointList->Insert(insert, pNewPoint);
225 if (bRenamePoints) RenameRoutePoints();
226 m_lastMousePointIndex = GetnPoints();
227 FinalizeForRendering();
228 UpdateSegmentDistances();
229 return;
230 }
231}
232
233RoutePoint *Route::GetPoint(int nWhichPoint) {
234 RoutePoint *prp;
235 wxRoutePointListNode *node = pRoutePointList->GetFirst();
236
237 int i = 1;
238 while (node) {
239 prp = node->GetData();
240 if (i == nWhichPoint) {
241 return prp;
242 }
243 i++;
244 node = node->GetNext();
245 }
246
247 return (NULL);
248}
249
250RoutePoint *Route::GetPoint(const wxString &guid) {
251 RoutePoint *prp;
252 wxRoutePointListNode *node = pRoutePointList->GetFirst();
253
254 while (node) {
255 prp = node->GetData();
256 if (guid == prp->m_GUID) return prp;
257
258 node = node->GetNext();
259 }
260
261 return (NULL);
262}
263
264static void TestLongitude(double lon, double min, double max, bool &lonl,
265 bool &lonr) {
266 double clon = (min + max) / 2;
267 if (min - lon > 180) lon += 360;
268
269 lonl = lonr = false;
270 if (lon < min) {
271 if (lon < clon - 180)
272 lonr = true;
273 else
274 lonl = true;
275 } else if (lon > max) {
276 if (lon > clon + 180)
277 lonl = true;
278 else
279 lonr = true;
280 }
281}
282
283bool Route::ContainsSharedWP() {
284 for (wxRoutePointListNode *node = pRoutePointList->GetFirst(); node;
285 node = node->GetNext()) {
286 RoutePoint *prp = node->GetData();
287 if (prp->IsShared()) return true;
288 }
289 return false;
290}
291
292// FIXME (leamas): can this be moved to GUI?
293int s_arrow_icon[] = {0, 0, 5, 2, 18, 6, 12, 0, 18, -6, 5, -2, 0, 0};
294void Route::ClearHighlights(void) {
295 RoutePoint *prp = NULL;
296 wxRoutePointListNode *node = pRoutePointList->GetFirst();
297
298 while (node) {
299 prp = node->GetData();
300 if (prp) prp->m_bPtIsSelected = false;
301 node = node->GetNext();
302 }
303}
304
305RoutePoint *Route::InsertPointBefore(RoutePoint *pRP, double rlat, double rlon,
306 bool bRenamePoints) {
307 RoutePoint *newpoint = new RoutePoint(rlat, rlon, g_default_routepoint_icon,
308 GetNewMarkSequenced(), wxEmptyString);
309 newpoint->m_bIsInRoute = true;
310 newpoint->SetNameShown(false);
311
312 int nRP = pRoutePointList->IndexOf(pRP);
313 pRoutePointList->Insert(nRP, newpoint);
314
315 if (bRenamePoints) RenameRoutePoints();
316
317 FinalizeForRendering();
318 UpdateSegmentDistances();
319
320 return (newpoint);
321}
322
323RoutePoint *Route::InsertPointAfter(RoutePoint *pRP, double rlat, double rlon,
324 bool bRenamePoints) {
325 int nRP = pRoutePointList->IndexOf(pRP);
326 if (nRP >= GetnPoints() - 1) return NULL;
327 nRP++;
328
329 RoutePoint *newpoint = new RoutePoint(rlat, rlon, g_default_routepoint_icon,
330 GetNewMarkSequenced(), wxEmptyString);
331 newpoint->m_bIsInRoute = true;
332 newpoint->SetNameShown(false);
333
334 pRoutePointList->Insert(nRP, newpoint);
335
336 if (bRenamePoints) RenameRoutePoints();
337
338 FinalizeForRendering();
339 UpdateSegmentDistances();
340
341 return (newpoint);
342}
343
344wxString Route::GetNewMarkSequenced(void) {
345 wxString ret;
346 ret.Printf(_T ( "NM%03d" ), m_nm_sequence);
347 m_nm_sequence++;
348
349 return ret;
350}
351
352RoutePoint *Route::GetLastPoint() {
353 if (pRoutePointList->IsEmpty()) return NULL;
354
355 return pRoutePointList->GetLast()->GetData();
356}
357
358int Route::GetIndexOf(RoutePoint *prp) {
359 int ret = pRoutePointList->IndexOf(prp) + 1;
360 if (ret == wxNOT_FOUND)
361 return 0;
362 else
363 return ret;
364}
365
366void Route::DeletePoint(RoutePoint *rp, bool bRenamePoints) {
367 // n.b. must delete Selectables and update config before deleting the
368 // point
369 if (rp->m_bIsInLayer) return;
370
371 pSelect->DeleteAllSelectableRoutePoints(this);
372 pSelect->DeleteAllSelectableRouteSegments(this);
373
374 pRoutePointList->DeleteObject(rp);
375
376 delete rp;
377
378 if (bRenamePoints) RenameRoutePoints();
379
380 if (GetnPoints() > 1) {
381 pSelect->AddAllSelectableRouteSegments(this);
382 pSelect->AddAllSelectableRoutePoints(this);
383
384 FinalizeForRendering();
385 UpdateSegmentDistances();
386 }
387}
388
389void Route::RemovePoint(RoutePoint *rp, bool bRenamePoints) {
390 if (rp->m_bIsActive && this->IsActive()) // FS#348
391 g_pRouteMan->DeactivateRoute();
392
393 pSelect->DeleteAllSelectableRoutePoints(this);
394 pSelect->DeleteAllSelectableRouteSegments(this);
395
396 // Arrange to remove all references to the same routepoint
397 // within the route. This can happen with circular or "round-trip" routes.
398 pRoutePointList->DeleteContents(false);
399 bool deleted = pRoutePointList->DeleteObject(rp);
400 while (deleted) {
401 deleted = pRoutePointList->DeleteObject(rp);
402 }
403
404 // check all other routes to see if this point appears in any other route
405 Route *pcontainer_route = FindRouteContainingWaypoint(rp);
406
407 if (pcontainer_route == NULL) {
408 rp->m_bIsInRoute = false; // Take this point out of this (and only) route
409 rp->m_bIsolatedMark = true; // This has become an isolated mark
410 NavObj_dB::GetInstance().UpdateRoutePoint(rp);
411 }
412
413 if (bRenamePoints) RenameRoutePoints();
414
415 // if ( m_nPoints > 1 )
416 {
417 pSelect->AddAllSelectableRouteSegments(this);
418 pSelect->AddAllSelectableRoutePoints(this);
419
420 // NavObjectChanges::getInstance()->UpdateRoute(this);
421 NavObj_dB::GetInstance().UpdateRoute(this);
422 FinalizeForRendering();
423 UpdateSegmentDistances();
424 }
425}
426
427void Route::DeSelectRoute() {
428 wxRoutePointListNode *node = pRoutePointList->GetFirst();
429
430 RoutePoint *rp;
431 while (node) {
432 rp = node->GetData();
433 rp->m_bPtIsSelected = false;
434
435 node = node->GetNext();
436 }
437}
438
439void Route::ReloadRoutePointIcons() {
440 wxRoutePointListNode *node = pRoutePointList->GetFirst();
441
442 RoutePoint *rp;
443 while (node) {
444 rp = node->GetData();
445 rp->ReLoadIcon();
446
447 node = node->GetNext();
448 }
449}
450
451void Route::FinalizeForRendering() { RBBox.Invalidate(); }
452
453LLBBox &Route::GetBBox(void) {
454 if (RBBox.GetValid()) return RBBox;
455
456 double bbox_lonmin, bbox_lonmax, bbox_latmin, bbox_latmax;
457
458 wxRoutePointListNode *node = pRoutePointList->GetFirst();
459 RoutePoint *data = node->GetData();
460
461 if (data->m_wpBBox.GetValid()) {
462 bbox_lonmax = data->m_wpBBox.GetMaxLon();
463 bbox_lonmin = data->m_wpBBox.GetMinLon();
464 bbox_latmax = data->m_wpBBox.GetMaxLat();
465 bbox_latmin = data->m_wpBBox.GetMinLat();
466 } else {
467 bbox_lonmax = bbox_lonmin = data->m_lon;
468 bbox_latmax = bbox_latmin = data->m_lat;
469 }
470
471 double lastlon = data->m_lon, wrap = 0;
472
473 node = node->GetNext();
474 while (node) {
475 data = node->GetData();
476
477 if (lastlon - data->m_lon > 180)
478 wrap += 360;
479 else if (data->m_lon - lastlon > 180)
480 wrap -= 360;
481
482 double lon = data->m_lon + wrap;
483
484 if (lon > bbox_lonmax) bbox_lonmax = lon;
485 if (lon < bbox_lonmin) bbox_lonmin = lon;
486
487 if (data->m_lat > bbox_latmax) bbox_latmax = data->m_lat;
488 if (data->m_lat < bbox_latmin) bbox_latmin = data->m_lat;
489
490 lastlon = data->m_lon;
491 node = node->GetNext();
492 }
493
494 if (bbox_lonmin < -360)
495 bbox_lonmin += 360, bbox_lonmax += 360;
496 else if (bbox_lonmax > 360)
497 bbox_lonmin -= 360, bbox_lonmax -= 360;
498
499 if (bbox_lonmax - bbox_lonmin > 360) bbox_lonmin = -180, bbox_lonmax = 180;
500
501 RBBox.Set(bbox_latmin, bbox_lonmin, bbox_latmax, bbox_lonmax);
502
503 return RBBox;
504}
505
506/*
507 Update a single route segment lengths
508 Also, compute total route length by summing segment distances.
509 */
511 double planspeed) {
512 double slat1 = prp0->m_lat, slon1 = prp0->m_lon;
513 double slat2 = prp->m_lat, slon2 = prp->m_lon;
514
515 // Calculate the absolute distance from 1->2
516
517 double dd;
518 double br;
519 // why are we using mercator rather than great circle here?? [sean 8-11-2015]
520 DistanceBearingMercator(slat2, slon2, slat1, slon1, &br, &dd);
521
522 prp->SetCourse(br);
523 prp->SetDistance(dd);
524
525 // And store in Point 2
526 prp->m_seg_len = dd;
527
528 m_route_length += dd;
529
530 // If Point1 Description contains VMG, store it for Properties Dialog in
531 // Point2 If Point1 Description contains ETD, store it in Point1
532
533 if (planspeed > 0.) {
534 wxDateTime etd;
535
536 double legspeed = planspeed;
537 if (prp->GetPlannedSpeed() > 0.1 && prp->GetPlannedSpeed() < 1000.)
538 legspeed = prp->GetPlannedSpeed();
539 if (legspeed > 0.1 && legspeed < 1000.) {
540 m_route_time += 3600. * dd / legspeed;
541 prp->m_seg_vmg = legspeed;
542 }
543 wxLongLong duration = wxLongLong(3600.0 * prp->m_seg_len / prp->m_seg_vmg);
544 prp->SetETE(duration);
545 wxTimeSpan ts(0, 0, duration);
546 if (!prp0->GetManualETD().IsValid()) {
547 prp0->m_manual_etd = false;
548 if (prp0->GetETA().IsValid()) {
549 prp0->m_seg_etd = prp0->GetETA();
550 } else {
551 prp0->m_seg_etd =
552 m_PlannedDeparture + wxTimeSpan(0, 0, m_route_time - duration);
553 }
554 }
555
556 prp->m_seg_eta = prp0->GetETD() + ts;
557 if (!prp->m_manual_etd || !prp->GetETD().IsValid()) {
558 prp->m_seg_etd = prp->m_seg_eta;
559 prp->m_manual_etd = false;
560 }
561 }
562}
563
564/*
565 Update the route segment lengths, storing each segment length in <destination>
566 point. Also, compute total route length by summing segment distances.
567 */
568void Route::UpdateSegmentDistances(double planspeed) {
569 wxPoint rpt, rptn;
570
571 m_route_length = 0.0;
572 m_route_time = 0.0;
573
574 wxRoutePointListNode *node = pRoutePointList->GetFirst();
575
576 if (node) {
577 // Route start point
578 RoutePoint *prp0 = node->GetData();
579 if (!prp0->m_manual_etd) {
582 }
583 node = node->GetNext();
584
585 while (node) {
586 RoutePoint *prp = node->GetData();
587 UpdateSegmentDistance(prp0, prp, planspeed);
588
589 prp0 = prp;
590
591 node = node->GetNext();
592 }
593 }
594}
595
596void Route::Reverse(bool bRenamePoints) {
597 // Reverse the GUID list
598 wxArrayString RoutePointGUIDList;
599
600 int ncount = pRoutePointList->GetCount();
601 for (int i = 0; i < ncount; i++)
602 RoutePointGUIDList.Add(GetPoint(ncount - i)->m_GUID);
603
604 pRoutePointList->DeleteContents(false);
605 pRoutePointList->Clear();
606 m_route_length = 0.0;
607
608 // iterate over the RoutePointGUIDs
609 for (unsigned int ip = 0; ip < RoutePointGUIDList.GetCount(); ip++) {
610 wxString GUID = RoutePointGUIDList[ip];
611
612 // And on the RoutePoints themselves
613 wxRoutePointListNode *prpnode = pWayPointMan->GetWaypointList()->GetFirst();
614 while (prpnode) {
615 RoutePoint *prp = prpnode->GetData();
616
617 if (prp->m_GUID == GUID) {
618 AddPoint(prp);
619 break;
620 }
621 prpnode = prpnode->GetNext(); // RoutePoint
622 }
623 }
624
625 if (bRenamePoints) RenameRoutePoints();
626
627 // Switch start/end strings. anders, 2010-01-29
628 wxString tmp = m_RouteStartString;
630 m_RouteEndString = tmp;
631}
632
633void Route::SetVisible(bool visible, bool includeWpts) {
634 m_bVisible = visible;
635
636 if (!includeWpts) return;
637
638 wxRoutePointListNode *node = pRoutePointList->GetFirst();
639 RoutePoint *rp;
640 while (node) {
641 rp = node->GetData();
642
643 // if this is a "shared" point, then do not turn off visibility.
644 // This step keeps the point available for selection to other routes,
645 // or may be manaully hidden in route-manager dialog.
646 if (rp->IsShared()) {
647 if (visible) rp->SetVisible(visible);
648 }
649 node = node->GetNext();
650 }
651}
652
653void Route::SetListed(bool visible) { m_bListed = visible; }
654
655void Route::AssembleRoute(void) {}
656
657void Route::ShowWaypointNames(bool bshow) {
658 wxRoutePointListNode *node = pRoutePointList->GetFirst();
659
660 while (node) {
661 RoutePoint *prp = node->GetData();
662 prp->SetNameShown(bshow);
663
664 node = node->GetNext();
665 }
666}
667
668bool Route::AreWaypointNamesVisible() {
669 bool bvis = false;
670 wxRoutePointListNode *node = pRoutePointList->GetFirst();
671
672 while (node) {
673 RoutePoint *prp = node->GetData();
674 if (prp->GetNameShown()) bvis = true;
675
676 node = node->GetNext();
677 }
678
679 return bvis;
680}
681
682void Route::RenameRoutePoints(void) {
683 // iterate on the route points.
684 // If dynamically named, rename according to current list position
685
686 wxRoutePointListNode *node = pRoutePointList->GetFirst();
687
688 int i = 1;
689 while (node) {
690 RoutePoint *prp = node->GetData();
691 if (prp->IsNameDynamic()) {
692 wxString name = prp->GetName();
693 if (name.Len() == 3) {
694 name.Printf(_T ( "%03d" ), i);
695 } else if (name.Left(2) == "NM") {
696 name.Printf(_T ( "%03d" ), i);
697 if (prp->GetName().Len() >= 5) {
698 name.Append(prp->GetName().Mid(5));
699 }
700 } else {
701 name.Printf(_T ( "%03d" ), i);
702 name.Append(prp->GetName().Mid(3));
703 }
704 prp->SetName(name);
705 }
706
707 node = node->GetNext();
708 i++;
709 }
710}
711
712// Is this route equal to another, meaning,
713// Do all routepoint positions and names match?
714bool Route::IsEqualTo(Route *ptargetroute) {
715 wxRoutePointListNode *pthisnode = (this->pRoutePointList)->GetFirst();
716 wxRoutePointListNode *pthatnode = (ptargetroute->pRoutePointList)->GetFirst();
717
718 if (NULL == pthisnode) return false;
719
720 if (this->m_bIsInLayer || ptargetroute->m_bIsInLayer) return false;
721
722 if (this->GetnPoints() != ptargetroute->GetnPoints()) return false;
723
724 while (pthisnode) {
725 if (NULL == pthatnode) return false;
726
727 RoutePoint *pthisrp = pthisnode->GetData();
728 RoutePoint *pthatrp = pthatnode->GetData();
729
730 if ((fabs(pthisrp->m_lat - pthatrp->m_lat) > 1.0e-6) ||
731 (fabs(pthisrp->m_lon - pthatrp->m_lon) > 1.0e-6))
732 return false;
733
734 if (!pthisrp->GetName().IsSameAs(pthatrp->GetName())) return false;
735
736 pthisnode = pthisnode->GetNext();
737 pthatnode = pthatnode->GetNext();
738 }
739
740 return true; // success, they are the same
741}
Represents a waypoint or mark within the navigation system.
Definition route_point.h:70
LLBBox m_wpBBox
Bounding box for the waypoint.
wxString m_GUID
Globally Unique Identifier for the waypoint.
wxDateTime GetETD()
Retrieves the Estimated Time of Departure for this waypoint, in UTC.
bool IsNameDynamic()
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bIsActive
Flag indicating if this waypoint is active for navigation.
wxDateTime GetManualETD()
Retrieves the manually set Estimated Time of Departure for this waypoint, in UTC.
wxDateTime m_seg_etd
Estimated Time of Departure from this waypoint, in UTC.
bool m_bIsInRoute
Flag indicating if this waypoint is part of a route.
double m_seg_len
Length of the leg from previous waypoint to this waypoint in nautical miles.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
double GetPlannedSpeed()
Return the planned speed associated with this waypoint.
bool m_bPtIsSelected
Flag indicating if this waypoint is currently selected.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
bool m_manual_etd
Flag indicating whether the ETD has been manually set by the user.
double m_seg_vmg
Planned speed for traveling FROM this waypoint TO the next waypoint.
wxDateTime m_seg_eta
Estimated Time of Arrival at this waypoint, in UTC.
wxDateTime GetETA()
Retrieves the Estimated Time of Arrival for this waypoint, in UTC.
Represents a navigational route in the navigation system.
Definition route.h:98
int m_hiliteWidth
Width in pixels for highlighting the route when selected.
Definition route.h:355
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
Definition route.h:202
double m_PlannedSpeed
Default planned speed for the route in knots.
Definition route.h:320
wxString m_RouteStartString
Name or description of the route's starting point.
Definition route.h:251
bool m_bIsBeingCreated
Flag indicating that the route is currently being created by the user.
Definition route.h:218
void UpdateSegmentDistance(RoutePoint *prp0, RoutePoint *prp, double planspeed=-1.0)
Updates the navigation data for a single route segment between two waypoints.
Definition route.cpp:510
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
Definition route.h:335
double m_route_length
Total length of the route in nautical miles, calculated using rhumb line (Mercator) distances.
Definition route.h:236
bool m_bRtIsActive
Flag indicating whether this route is currently active for navigation.
Definition route.h:207
wxString m_Colour
Color name for rendering the route on the chart.
Definition route.h:345
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
Definition route.h:267
wxString m_RouteEndString
Name or description of the route's ending point.
Definition route.h:256
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
Definition route.h:213
bool m_btemp
Flag indicating if this is a temporary route.
Definition route.h:350
wxPenStyle m_style
Style of the route line when rendered on the chart.
Definition route.h:292
wxString m_TimeDisplayFormat
Format for displaying times in the UI.
Definition route.h:330
int m_width
Width of the route line in pixels when rendered on the chart.
Definition route.h:287
wxString m_RouteNameString
User-assigned name for the route.
Definition route.h:246
wxString m_GUID
Globally unique identifier for this route.
Definition route.h:272
wxDateTime m_PlannedDeparture
Planned departure time for the route, in UTC.
Definition route.h:325
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
Definition route.h:277
double m_route_time
Total estimated time to complete the route in seconds.
Definition route.h:241
int m_lastMousePointIndex
Index of the most recently interacted with route point.
Definition route.h:297
HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this route.
Definition route.h:360
bool m_bIsBeingEdited
Flag indicating that the route is currently being edited by the user.
Definition route.h:223
bool m_NextLegGreatCircle
Flag indicating whether the next leg should be calculated using great circle navigation or rhumb line...
Definition route.h:314
int m_LayerID
Identifier of the layer containing this route.
Definition route.h:282
Class NavObj_dB.