26#include <wx/datetime.h>
27#include <wx/dynarray.h>
29#include <wx/tokenzr.h>
31#include "model/base_platform.h"
32#include "model/cutil.h"
33#include "model/georef.h"
34#include "model/navutil_base.h"
35#include "model/route.h"
36#include "model/routeman.h"
37#include "model/route_point.h"
38#include "model/select.h"
40#include <wx/listimpl.cpp>
42WX_DEFINE_LIST(RoutePointList);
44wxColour g_colourWaypointRangeRingsColour;
51 [](unsigned,
const unsigned *) { assert(
true); };
53RoutePoint::RoutePoint() {
60 m_seg_etd = wxInvalidDateTime;
63 m_seg_eta = wxInvalidDateTime;
64 m_bPtIsSelected =
false;
65 m_bRPIsBeingEdited =
false;
69 m_CreateTimeX = wxDateTime::Now();
70 m_bIsolatedMark =
false;
75 CurrentRect_in_DC = wxRect(0, 0, 0, 0);
76 m_NameLocationOffsetX = -10;
77 m_NameLocationOffsetY = 8;
85 m_HyperlinkList =
new HyperlinkList;
87 m_GUID = pWayPointMan->CreateGUID(
this);
89 m_IconName = wxEmptyString;
91 m_MarkName = wxEmptyString;
96 m_WaypointArrivalRadius = g_n_arrival_circle_radius;
98 m_bShowWaypointRangeRings = (bool)g_iWaypointRangeRingsNumber;
100 m_iWaypointRangeRingsNumber = g_iWaypointRangeRingsNumber;
101 m_fWaypointRangeRingsStep = g_fWaypointRangeRingsStep;
102 m_iWaypointRangeRingsStepUnits = g_iWaypointRangeRingsStepUnits;
103 m_wxcWaypointRangeRingsColour = g_colourWaypointRangeRingsColour;
104 m_ScaMin = g_iWpt_ScaMin;
105 m_bShowName = g_bShowWptName;
107 b_UseScamin = g_bUseWptScaMin;
109 m_pos_on_screen =
false;
110 m_bDrawDragHandle =
false;
111 m_dragIconTexture = 0;
112 m_draggingOffsetx = m_draggingOffsety = 0;
115 m_IconIsDirty =
true;
120 m_MarkName = orig->GetName();
123 m_seg_len = orig->m_seg_len;
124 m_seg_vmg = orig->m_seg_vmg;
126 m_seg_etd = orig->m_seg_etd;
127 m_manual_etd =
false;
129 m_bPtIsSelected = orig->m_bPtIsSelected;
130 m_bRPIsBeingEdited = orig->m_bRPIsBeingEdited;
131 m_bIsActive = orig->m_bIsActive;
132 m_bBlink = orig->m_bBlink;
133 m_bIsInRoute = orig->m_bIsInRoute;
134 m_CreateTimeX = orig->m_CreateTimeX;
135 m_bIsolatedMark = orig->m_bIsolatedMark;
136 m_bShowName = orig->m_bShowName;
137 SetShared(orig->IsShared());
138 m_bIsVisible = orig->m_bIsVisible;
139 m_bIsListed = orig->m_bIsListed;
140 CurrentRect_in_DC = orig->CurrentRect_in_DC;
141 m_NameLocationOffsetX = orig->m_NameLocationOffsetX;
142 m_NameLocationOffsetY = orig->m_NameLocationOffsetY;
143 m_pMarkFont = orig->m_pMarkFont;
144 m_MarkDescription = orig->m_MarkDescription;
145 m_btemp = orig->m_btemp;
146 m_ScaMin = orig->m_ScaMin;
147 m_ScaMax = orig->m_ScaMax;
148 m_HyperlinkList =
new HyperlinkList;
149 m_IconName = orig->m_IconName;
150 m_TideStation = orig->m_TideStation;
151 SetPlannedSpeed(orig->GetPlannedSpeed());
153 m_bIsInLayer = orig->m_bIsInLayer;
154 m_GUID = pWayPointMan->CreateGUID(
this);
157 m_ManagerNode = NULL;
159 m_WaypointArrivalRadius = orig->GetWaypointArrivalRadius();
160 m_bShowWaypointRangeRings = orig->m_bShowWaypointRangeRings;
161 m_iWaypointRangeRingsNumber = orig->m_iWaypointRangeRingsNumber;
162 m_fWaypointRangeRingsStep = orig->m_fWaypointRangeRingsStep;
163 m_iWaypointRangeRingsStepUnits = orig->m_iWaypointRangeRingsStepUnits;
164 m_wxcWaypointRangeRingsColour = orig->m_wxcWaypointRangeRingsColour;
165 m_ScaMin = orig->m_ScaMin;
166 m_ScaMax = orig->m_ScaMax;
167 b_UseScamin = orig->b_UseScamin;
168 m_IconIsDirty = orig->m_IconIsDirty;
170 m_bDrawDragHandle =
false;
171 m_dragIconTexture = 0;
172 m_draggingOffsetx = m_draggingOffsety = 0;
175RoutePoint::RoutePoint(
double lat,
double lon,
const wxString &icon_ident,
176 const wxString &name,
const wxString &pGUID,
185 else if (m_lon > 180.)
192 m_seg_etd = wxInvalidDateTime;
193 m_manual_etd =
false;
195 m_bPtIsSelected =
false;
196 m_bRPIsBeingEdited =
false;
199 m_bIsInRoute =
false;
200 m_CreateTimeX = wxDateTime::Now();
201 m_bIsolatedMark =
false;
206 CurrentRect_in_DC = wxRect(0, 0, 0, 0);
207 m_NameLocationOffsetX = -10;
208 m_NameLocationOffsetY = 8;
211 m_bPreScaled =
false;
214 m_ManagerNode = NULL;
215 m_IconScaleFactor = 1.0;
216 m_ScaMin = MAX_INT_VAL;
218 m_HyperlinkList =
new HyperlinkList;
219 m_IconIsDirty =
true;
223 if (!pGUID.IsEmpty())
226 m_GUID = pWayPointMan->CreateGUID(
this);
229 m_IconName = icon_ident;
236 if (bAddToList && NULL != pWayPointMan) pWayPointMan->
AddRoutePoint(
this);
238 m_bIsInLayer =
false;
241 SetWaypointArrivalRadius(g_n_arrival_circle_radius);
243 m_bShowWaypointRangeRings = (bool)g_iWaypointRangeRingsNumber;
245 m_iWaypointRangeRingsNumber = g_iWaypointRangeRingsNumber;
246 m_fWaypointRangeRingsStep = g_fWaypointRangeRingsStep;
247 m_iWaypointRangeRingsStepUnits = g_iWaypointRangeRingsStepUnits;
248 m_wxcWaypointRangeRingsColour = g_colourWaypointRangeRingsColour;
249 m_ScaMin = g_iWpt_ScaMin;
251 b_UseScamin = g_bUseWptScaMin;
252 m_bShowName = g_bShowWptName;
254 m_bDrawDragHandle =
false;
255 m_dragIconTexture = 0;
256 m_draggingOffsetx = m_draggingOffsety = 0;
261RoutePoint::~RoutePoint() {
265 if (m_HyperlinkList) {
266 m_HyperlinkList->DeleteContents(
true);
267 delete m_HyperlinkList;
272wxDateTime RoutePoint::GetCreateTime() {
273 if (!m_CreateTimeX.IsValid()) {
274 if (m_timestring.Len()) ParseGPXDateTime(m_CreateTimeX, m_timestring);
276 return m_CreateTimeX;
279void RoutePoint::SetCreateTime(wxDateTime dt) { m_CreateTimeX = dt; }
281void RoutePoint::SetName(
const wxString &name) {
282 if (m_iTextTexture) {
287 CalculateNameExtents();
290void RoutePoint::CalculateNameExtents(
void) {
296 dc.GetTextExtent(m_MarkName, &w, &h, NULL, NULL, m_pMarkFont);
297 m_NameExtents = wxSize(w, h);
299 dc.SetFont(*m_pMarkFont);
300 m_NameExtents = dc.GetMultiLineTextExtent(m_MarkName);
303 m_NameExtents = wxSize(0, 0);
306bool RoutePoint::IsVisibleSelectable(
double scale_val,
bool boverrideViz) {
316 if (g_bOverruleScaMin)
318 else if (scale_val >= (
double)(m_ScaMin + 1))
324bool RoutePoint::IsSharedInVisibleRoute() {
327 wxArrayPtrVoid *proute_array = g_pRouteMan->GetRouteArrayContaining(
this);
330 bool brp_viz =
false;
332 for (
unsigned int ir = 0; ir < proute_array->GetCount(); ir++) {
334 if (pr->IsVisible()) {
346void RoutePoint::SetPosition(
double lat,
double lon) {
351bool RoutePoint::IsSame(
RoutePoint *pOtherRP) {
354 if (this->m_MarkName == pOtherRP->m_MarkName) {
355 if (fabs(this->m_lat - pOtherRP->m_lat) < 1.e-6 &&
356 fabs(this->m_lon - pOtherRP->m_lon) < 1.e-6)
368 bool b_numeric =
false;
370 if (GetName().Len() >= 2) {
371 wxString substring = GetName().Left(2);
372 if (substring ==
"NM") {
373 substring = GetName().substr(2, 3);
375 substring = GetName().Left(3);
378 for (
unsigned int i = 0; i < substring.Len(); i++) {
379 if (b_numeric ==
true) {
380 b_numeric = wxIsdigit(substring[i]);
388double RoutePoint::GetWaypointArrivalRadius() {
389 if ((m_WaypointArrivalRadius >= 0) && (m_WaypointArrivalRadius < 0.001)) {
390 SetWaypointArrivalRadius(g_n_arrival_circle_radius);
391 return m_WaypointArrivalRadius;
393 return m_WaypointArrivalRadius;
396int RoutePoint::GetWaypointRangeRingsNumber() {
397 if (m_iWaypointRangeRingsNumber == -1)
398 return g_iWaypointRangeRingsNumber;
400 return m_iWaypointRangeRingsNumber;
403float RoutePoint::GetWaypointRangeRingsStep() {
404 if (m_fWaypointRangeRingsStep == -1)
405 return g_fWaypointRangeRingsStep;
407 return m_fWaypointRangeRingsStep;
410int RoutePoint::GetWaypointRangeRingsStepUnits() {
411 if (m_iWaypointRangeRingsStepUnits == -1)
412 return g_iWaypointRangeRingsStepUnits;
414 return m_iWaypointRangeRingsStepUnits;
417void RoutePoint::SetScaMin(
long val) {
418 if (val < SCAMIN_MIN)
421 if (val < (
long)m_ScaMax * 5) val = (long)m_ScaMax * 5;
424void RoutePoint::SetScaMin(wxString str) {
426 if (!str.ToLong(&val)) val = MAX_INT_VAL;
430void RoutePoint::SetScaMax(
long val) {
431 if (val > (
int)m_ScaMin / 5)
432 m_ScaMax = (int)m_ScaMin /
435void RoutePoint::SetScaMax(wxString str) {
437 if (!str.ToLong(&val)) val = 0;
441void RoutePoint::SetPlannedSpeed(
double spd) {
442 if (spd >= 0.0 && spd <= 1000.0) m_PlannedSpeed = spd;
445double RoutePoint::GetPlannedSpeed() {
446 if (m_PlannedSpeed < 0.0001 &&
447 m_MarkDescription.Find(_T(
"VMG=")) != wxNOT_FOUND) {
451 (m_MarkDescription.Mid(m_MarkDescription.Find(_T(
"VMG=")) + 4))
454 if (!s_vmg.ToDouble(&vmg)) {
455 m_MarkDescription.Replace(_T(
"VMG=") + s_vmg +
";", wxEmptyString);
456 SetPlannedSpeed(vmg);
459 return m_PlannedSpeed;
462wxDateTime RoutePoint::GetETD() {
463 if (m_seg_etd.IsValid()) {
464 if (!GetETA().IsValid() || m_seg_etd > GetETA()) {
470 if (m_MarkDescription.Find(_T(
"ETD=")) != wxNOT_FOUND) {
471 wxDateTime etd = wxInvalidDateTime;
473 (m_MarkDescription.Mid(m_MarkDescription.Find(_T(
"ETD=")) + 4))
475 const wxChar *parse_return = etd.ParseDateTime(s_etd);
477 wxString tz(parse_return);
479 if (tz.Find(_T(
"UT")) != wxNOT_FOUND) {
482 if (tz.Find(_T(
"LMT")) != wxNOT_FOUND) {
484 long lmt_offset = (long)((m_lon * 3600.) / 15.);
485 wxTimeSpan lmt(0, 0, (
int)lmt_offset, 0);
488 m_seg_etd = etd.ToUTC();
491 if (etd.IsValid() && (!GetETA().IsValid() || etd > GetETA())) {
492 m_MarkDescription.Replace(s_etd, wxEmptyString);
501 return wxInvalidDateTime;
504wxDateTime RoutePoint::GetManualETD() {
505 if (m_manual_etd && m_seg_etd.IsValid()) {
508 return wxInvalidDateTime;
511wxDateTime RoutePoint::GetETA() {
512 if (m_seg_eta.IsValid()) {
515 return wxInvalidDateTime;
518wxString RoutePoint::GetETE() {
519 if (m_seg_ete != 0) {
520 return formatTimeDelta(m_seg_ete);
522 return wxEmptyString;
525void RoutePoint::SetETE(wxLongLong secs) { m_seg_ete = secs; }
527void RoutePoint::SetETD(
const wxDateTime &etd) {
532bool RoutePoint::SetETD(
const wxString &ts) {
534 m_seg_etd = wxInvalidDateTime;
535 m_manual_etd =
false;
539 wxString::const_iterator end;
540 if (tmp.ParseISOCombined(ts)) {
543 }
else if (tmp.ParseDateTime(ts, &end)) {
static std::function< void(unsigned, const unsigned *)> delete_gl_textures
Horrible Hack (tm).
bool AddRoutePoint(RoutePoint *prp)
Add a point to list which owns it.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.