30#include <wx/datetime.h>
41#include "model/nav_object_database.h"
49#include <wx/listimpl.cpp>
68 m_GUID = pWayPointMan->CreateGUID(NULL);
71 m_ArrivalRadius = g_n_arrival_circle_radius;
82 if (g_defaultBoatSpeed != ROUTE_DEFAULT_SPEED)
89 m_bsharedWPViz =
false;
100void Route::CloneRoute(
Route *psourceroute,
int start_nPoint,
int end_nPoint,
101 const wxString &suffix,
102 const bool duplicate_first_point) {
108 for (i = start_nPoint; i <= end_nPoint; i++) {
110 !(i == start_nPoint && duplicate_first_point)) {
111 AddPoint(psourceroute->GetPoint(i),
false);
113 RoutePoint *psourcepoint = psourceroute->GetPoint(i);
115 psourcepoint->m_lat, psourcepoint->m_lon, psourcepoint->GetIconName(),
116 psourcepoint->GetName(),
"",
true);
119 AddPoint(ptargetpoint,
false);
123 FinalizeForRendering();
126wxString Route::IsPointNameValid(
RoutePoint *pPoint,
127 const wxString &name)
const {
128 wxString substr = name;
132 wxString exist = point->GetName();
136 }
else if (substr == exist) {
137 return _(
"Name is not unique in route");
145void Route::AddPoint(
RoutePoint *pNewPoint,
bool b_rename_in_sequence,
146 bool b_deferBoxCalc) {
148 pNewPoint->SetShared(
true);
156 if (!b_deferBoxCalc) FinalizeForRendering();
160 if (b_rename_in_sequence && pNewPoint->GetName().IsEmpty() &&
161 !pNewPoint->IsShared()) {
163 name.Printf(
"%03d", GetnPoints());
164 pNewPoint->SetName(name);
169void Route::AddPointAndSegment(
RoutePoint *pNewPoint,
bool b_rename_in_sequence,
170 bool b_deferBoxCalc) {
171 int npoints = GetnPoints();
174 newpoint =
new RoutePoint(pNewPoint->m_lat, pNewPoint->m_lon,
175 pNewPoint->GetIconName(), pNewPoint->GetName(),
180 AddPoint(newpoint,
false);
182 double rlat = GetPoint(npoints)->m_lat;
183 double rlon = GetPoint(npoints)->m_lon;
184 npoints = GetnPoints();
185 pSelect->AddSelectableRouteSegment(
186 rlat, rlon, GetPoint(npoints)->m_lat, GetPoint(npoints)->m_lon,
187 GetPoint(npoints - 1), GetPoint(npoints),
this);
192void Route::InsertPointAndSegment(
RoutePoint *pNewPoint,
int insert_after,
193 bool bRenamePoints,
bool b_deferBoxCalc) {
198 pNewPoint->SetShared(
true);
203 if (insert_after >= GetnPoints() - 1) {
204 wxLogMessage(
"Error insert after last point");
210 pNewPoint->SetNameShown(
false);
212 if (bRenamePoints) RenameRoutePoints();
214 FinalizeForRendering();
215 UpdateSegmentDistances();
222 if (nWhichPoint < 1)
return nullptr;
223 if (nWhichPoint >
static_cast<int>(
pRoutePointList->size()))
return nullptr;
228RoutePoint *Route::GetPoint(
const wxString &guid) {
230 if (guid == prp->m_GUID)
return prp;
235static void TestLongitude(
double lon,
double min,
double max,
bool &lonl,
237 double clon = (min + max) / 2;
238 if (min - lon > 180) lon += 360;
242 if (lon < clon - 180)
246 }
else if (lon > max) {
247 if (lon > clon + 180)
254bool Route::ContainsSharedWP() {
256 if (prp->IsShared())
return true;
262int s_arrow_icon[] = {0, 0, 5, 2, 18, 6, 12, 0, 18, -6, 5, -2, 0, 0};
264void Route::ClearHighlights() {
266 if (prp) prp->m_bPtIsSelected =
false;
271 bool bRenamePoints) {
273 GetNewMarkSequenced(),
"");
275 newpoint->SetNameShown(
false);
281 if (bRenamePoints) RenameRoutePoints();
283 FinalizeForRendering();
284 UpdateSegmentDistances();
290 bool bRenamePoints) {
296 GetNewMarkSequenced(),
"");
298 newpoint->SetNameShown(
false);
302 if (bRenamePoints) RenameRoutePoints();
304 FinalizeForRendering();
305 UpdateSegmentDistances();
310wxString Route::GetNewMarkSequenced() {
312 ret.Printf(
"NM%03d", m_nm_sequence);
330void Route::DeletePoint(
RoutePoint *rp,
bool bRenamePoints) {
335 pSelect->DeleteAllSelectableRoutePoints(
this);
336 pSelect->DeleteAllSelectableRouteSegments(
this);
341 if (bRenamePoints) RenameRoutePoints();
343 if (GetnPoints() > 1) {
344 pSelect->AddAllSelectableRouteSegments(
this);
345 pSelect->AddAllSelectableRoutePoints(
this);
347 FinalizeForRendering();
348 UpdateSegmentDistances();
352void Route::RemovePoint(
RoutePoint *rp,
bool bRenamePoints) {
356 pSelect->DeleteAllSelectableRoutePoints(
this);
357 pSelect->DeleteAllSelectableRouteSegments(
this);
368 Route *pcontainer_route = FindRouteContainingWaypoint(rp);
370 if (pcontainer_route == NULL) {
373 NavObj_dB::GetInstance().UpdateRoutePoint(rp);
376 if (bRenamePoints) RenameRoutePoints();
380 pSelect->AddAllSelectableRouteSegments(
this);
381 pSelect->AddAllSelectableRoutePoints(
this);
384 NavObj_dB::GetInstance().UpdateRoute(
this);
385 FinalizeForRendering();
386 UpdateSegmentDistances();
390void Route::DeSelectRoute() {
396void Route::ReloadRoutePointIcons() {
402void Route::FinalizeForRendering() { RBBox.Invalidate(); }
404LLBBox &Route::GetBBox() {
405 if (RBBox.GetValid())
return RBBox;
407 double bbox_lonmin, bbox_lonmax, bbox_latmin, bbox_latmax;
413 if (data->m_wpBBox.GetValid()) {
414 bbox_lonmax = data->
m_wpBBox.GetMaxLon();
415 bbox_lonmin = data->m_wpBBox.GetMinLon();
416 bbox_latmax = data->m_wpBBox.GetMaxLat();
417 bbox_latmin = data->m_wpBBox.GetMinLat();
419 bbox_lonmax = bbox_lonmin = data->m_lon;
420 bbox_latmax = bbox_latmin = data->m_lat;
423 double lastlon = data->m_lon, wrap = 0;
427 if (lastlon - data->m_lon > 180)
429 else if (data->m_lon - lastlon > 180)
432 double lon = data->m_lon + wrap;
434 if (lon > bbox_lonmax) bbox_lonmax = lon;
435 if (lon < bbox_lonmin) bbox_lonmin = lon;
437 if (data->m_lat > bbox_latmax) bbox_latmax = data->m_lat;
438 if (data->m_lat < bbox_latmin) bbox_latmin = data->m_lat;
440 lastlon = data->m_lon;
443 if (bbox_lonmin < -360)
444 bbox_lonmin += 360, bbox_lonmax += 360;
445 else if (bbox_lonmax > 360)
446 bbox_lonmin -= 360, bbox_lonmax -= 360;
448 if (bbox_lonmax - bbox_lonmin > 360) bbox_lonmin = -180, bbox_lonmax = 180;
450 RBBox.Set(bbox_latmin, bbox_lonmin, bbox_latmax, bbox_lonmax);
461 double slat1 = prp0->m_lat, slon1 = prp0->m_lon;
462 double slat2 = prp->m_lat, slon2 = prp->m_lon;
469 DistanceBearingMercator(slat2, slon2, slat1, slon1, &br, &dd);
472 prp->SetDistance(dd);
482 if (planspeed > 0.) {
485 double legspeed = planspeed;
488 if (legspeed > 0.1 && legspeed < 1000.) {
493 prp->SetETE(duration);
494 wxTimeSpan ts(0, 0, duration);
497 if (prp0->
GetETA().IsValid()) {
517void Route::UpdateSegmentDistances(
double planspeed) {
542void Route::Reverse(
bool bRenamePoints) {
544 wxArrayString RoutePointGUIDList;
547 for (
int i = 0; i < ncount; i++)
548 RoutePointGUIDList.Add(GetPoint(ncount - i)->
m_GUID);
554 for (
unsigned int ip = 0; ip < RoutePointGUIDList.GetCount(); ip++) {
555 wxString GUID = RoutePointGUIDList[ip];
556 for (
RoutePoint *prp : *pWayPointMan->GetWaypointList()) {
557 if (prp->
m_GUID == GUID) {
564 if (bRenamePoints) RenameRoutePoints();
572void Route::SetVisible(
bool visible,
bool includeWpts) {
573 m_bVisible = visible;
575 if (!includeWpts)
return;
577 for (
RoutePoint *rp : *pWayPointMan->GetWaypointList()) {
581 if (rp->IsShared()) {
582 if (visible) rp->SetVisible(visible);
587void Route::SetListed(
bool visible) { m_bListed = visible; }
589void Route::AssembleRoute() {}
591void Route::ShowWaypointNames(
bool bshow) {
593 prp->SetNameShown(bshow);
597bool Route::AreWaypointNamesVisible() {
600 if (prp->GetNameShown()) bvis =
true;
605void Route::RenameRoutePoints() {
612 wxString name = prp->GetName();
613 if (name.Len() == 3) {
614 name.Printf(
"%03d", i);
615 }
else if (name.Left(2) ==
"NM") {
616 name.Printf(
"%03d", i);
617 if (prp->GetName().Len() >= 5) {
618 name.Append(prp->GetName().Mid(5));
621 name.Printf(
"%03d", i);
622 name.Append(prp->GetName().Mid(3));
632bool Route::IsEqualTo(
Route *ptargetroute) {
640 if (this->GetnPoints() != ptargetroute->GetnPoints())
return false;
648 if ((fabs(pthisrp->m_lat - pthatrp->m_lat) > 1.0e-6) ||
649 (fabs(pthisrp->m_lon - pthatrp->m_lon) > 1.0e-6))
652 if (!pthisrp->GetName().IsSameAs(pthatrp->GetName()))
return false;
Represents a waypoint or mark within the navigation system.
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 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.
int m_hiliteWidth
Width in pixels for highlighting the route when selected.
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
double m_PlannedSpeed
Default planned speed for the route in knots.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bIsBeingCreated
Flag indicating that the route is currently being created by the user.
void UpdateSegmentDistance(RoutePoint *prp0, RoutePoint *prp, double planspeed=-1.0)
Updates the navigation data for a single route segment between two waypoints.
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
double m_route_length
Total length of the route in nautical miles, calculated using rhumb line (Mercator) distances.
bool m_bRtIsActive
Flag indicating whether this route is currently active for navigation.
wxString m_Colour
Color name for rendering the route on the chart.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
bool m_btemp
Flag indicating if this is a temporary route.
wxPenStyle m_style
Style of the route line when rendered on the chart.
wxString m_TimeDisplayFormat
Format for displaying times in the UI.
int m_width
Width of the route line in pixels when rendered on the chart.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
wxDateTime m_PlannedDeparture
Planned departure time for the route, in UTC.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
double m_route_time
Total estimated time to complete the route in seconds.
int m_lastMousePointIndex
Index of the most recently interacted with route point.
HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this route.
bool m_bIsBeingEdited
Flag indicating that the route is currently being edited by the user.
bool m_NextLegGreatCircle
Flag indicating whether the next leg should be calculated using great circle navigation or rhumb line...
int m_LayerID
Identifier of the layer containing this route.
Global variables stored in configuration file.
Extern C linked utilities.
MySQL based storage for routes, tracks, etc.
Routeman * g_pRouteMan
Global instance.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.