26#include "model/nav_object_database.h"
27#include "model/routeman.h"
28#include "model/navutil_base.h"
29#include "model/select.h"
30#include "model/track.h"
31#include "model/route.h"
38NavObjectCollection1::NavObjectCollection1() : pugi::xml_document() {}
40NavObjectCollection1::~NavObjectCollection1() {}
43 wxString GUID,
bool b_fullviz,
bool b_layer,
44 bool b_layerviz,
int layer_id,
bool b_nameviz) {
46 bool bviz_name =
false;
48 bool b_propvizname =
false;
49 bool b_propviz =
false;
51 wxString SymString = def_symbol_name;
55 double plan_speed = 0.0;
58 wxString GuidString = GUID;
63 HyperlinkList *linklist = NULL;
65 double rlat = wpt_node.attribute(
"lat").as_double();
66 double rlon = wpt_node.attribute(
"lon").as_double();
67 double ArrivalRadius = 0;
68 int l_iWaypointRangeRingsNumber = -1;
69 float l_fWaypointRangeRingsStep = -1;
70 int l_pWaypointRangeRingsStepUnits = -1;
71 bool l_bWaypointRangeRingsVisible =
false;
72 long l_iWaypointScaleMin = 2147483646;
73 long l_iWaypoinScaleMax = 0;
74 bool l_bWaypointUseScale =
false;
75 wxColour l_wxcWaypointRangeRingsColour;
76 l_wxcWaypointRangeRingsColour.Set(_T(
"#FFFFFF" ));
79 child = child.next_sibling()) {
80 const char *pcn = child.name();
82 if (!strcmp(pcn,
"sym")) {
83 SymString = wxString::FromUTF8(child.first_child().value());
84 }
else if (!strcmp(pcn,
"time"))
85 TimeString = wxString::FromUTF8(child.first_child().value());
87 else if (!strcmp(pcn,
"name")) {
88 NameString = wxString::FromUTF8(child.first_child().value());
89 if (NameString.StartsWith(
"@~~")) {
93 TideStation = NameString.Right(NameString.length() - 3);
94 NameString.Replace(
"@~~",
"@-~");
98 else if (!strcmp(pcn,
"desc")) {
99 DescString = wxString::FromUTF8(child.first_child().value());
102 else if (!strcmp(pcn,
"type")) {
103 TypeString = wxString::FromUTF8(child.first_child().value());
107 if (!strcmp(pcn,
"link")) {
109 wxString HrefTextString;
110 wxString HrefTypeString;
111 if (linklist == NULL) linklist =
new HyperlinkList;
112 HrefString = wxString::FromUTF8(child.first_attribute().value());
115 child1 = child1.next_sibling()) {
116 wxString LinkString = wxString::FromUTF8(child1.name());
118 if (LinkString == _T (
"text" ))
119 HrefTextString = wxString::FromUTF8(child1.first_child().value());
120 if (LinkString == _T (
"type" ))
121 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
125 link->Link = HrefString;
126 link->DescrText = HrefTextString;
127 link->LType = HrefTypeString;
128 linklist->push_back(link);
132 else if (!strcmp(pcn,
"extensions")) {
134 ext_child = ext_child.next_sibling()) {
135 wxString ext_name = wxString::FromUTF8(ext_child.name());
136 if (ext_name == _T (
"opencpn:guid" )) {
137 GuidString = wxString::FromUTF8(ext_child.first_child().value());
138 }
else if (ext_name == _T (
"opencpn:viz" )) {
140 wxString s = wxString::FromUTF8(ext_child.first_child().value());
142 if (s.ToLong(&v)) bviz = (v != 0);
143 }
else if (ext_name == _T (
"opencpn:viz_name" )) {
144 b_propvizname =
true;
145 wxString s = wxString::FromUTF8(ext_child.first_child().value());
147 if (s.ToLong(&v)) bviz_name = (v != 0);
148 }
else if (ext_name == _T (
"opencpn:shared" )) {
149 wxString s = wxString::FromUTF8(ext_child.first_child().value());
151 if (s.ToLong(&v)) bshared = (v != 0);
153 if (ext_name == _T (
"opencpn:arrival_radius" )) {
154 wxString::FromUTF8(ext_child.first_child().value())
155 .ToDouble(&ArrivalRadius);
157 if (ext_name == _T(
"opencpn:waypoint_range_rings")) {
159 attr = attr.next_attribute()) {
160 if (wxString::FromUTF8(attr.name()) == _T(
"number"))
161 l_iWaypointRangeRingsNumber = attr.as_int();
162 else if (wxString::FromUTF8(attr.name()) == _T(
"step"))
163 l_fWaypointRangeRingsStep = attr.as_float();
164 else if (wxString::FromUTF8(attr.name()) == _T(
"units"))
165 l_pWaypointRangeRingsStepUnits = attr.as_int();
166 else if (wxString::FromUTF8(attr.name()) == _T(
"visible"))
167 l_bWaypointRangeRingsVisible = attr.as_bool();
168 else if (wxString::FromUTF8(attr.name()) == _T(
"colour"))
169 l_wxcWaypointRangeRingsColour.Set(
170 wxString::FromUTF8(attr.as_string()));
173 if (ext_name == _T(
"opencpn:scale_min_max")) {
175 attr = attr.next_attribute()) {
176 if (wxString::FromUTF8(attr.name()) == _T(
"UseScale"))
177 l_bWaypointUseScale = attr.as_bool();
178 else if (wxString::FromUTF8(attr.name()) == _T(
"ScaleMin"))
179 l_iWaypointScaleMin = attr.as_int();
180 else if (wxString::FromUTF8(attr.name()) == _T(
"ScaleMax"))
181 l_iWaypoinScaleMax = attr.as_float();
184 if (ext_name == _T (
"opencpn:tidestation" )) {
185 TideStation = wxString::FromUTF8(ext_child.first_child().value());
187 if (ext_name == _T (
"opencpn:rte_properties" )) {
189 attr = attr.next_attribute()) {
190 if (!strcmp(attr.name(),
"planned_speed"))
191 plan_speed = attr.as_double();
192 else if (!strcmp(attr.name(),
"etd"))
196 etd = attr.as_string();
206 if (GuidString.IsEmpty()) GuidString = pWayPointMan->CreateGUID(NULL);
209 pWP =
new RoutePoint(rlat, rlon, SymString, NameString, GuidString,
214 pWP->SetWaypointArrivalRadius(ArrivalRadius);
215 pWP->SetWaypointRangeRingsNumber(l_iWaypointRangeRingsNumber);
216 pWP->SetWaypointRangeRingsStep(l_fWaypointRangeRingsStep);
217 pWP->SetWaypointRangeRingsStepUnits(l_pWaypointRangeRingsStepUnits);
218 pWP->SetShowWaypointRangeRings(l_bWaypointRangeRingsVisible);
224 if (!l_bWaypointRangeRingsVisible) pWP->SetWaypointRangeRingsNumber(0);
226 pWP->SetWaypointRangeRingsColour(l_wxcWaypointRangeRingsColour);
227 pWP->SetScaMin(l_iWaypointScaleMin);
228 pWP->SetScaMax(l_iWaypoinScaleMax);
229 pWP->SetUseSca(l_bWaypointUseScale);
230 pWP->SetPlannedSpeed(plan_speed);
242 if (!b_nameviz && !b_propvizname) pWP->
m_bShowName =
false;
253 pWP->SetListed(
false);
256 pWP->SetShared(bshared);
258 if (TimeString.Len()) {
274 double rlat = wpt_node.attribute(
"lat").as_double();
275 double rlon = wpt_node.attribute(
"lon").as_double();
278 child = child.next_sibling()) {
279 const char *pcn = child.name();
280 if (!strcmp(pcn,
"time"))
281 TimeString = wxString::FromUTF8(child.first_child().value());
284 else if (!strcmp(pcn,
"extensions")) {
286 ext_child = ext_child.next_sibling()) {
287 wxString ext_name = wxString::FromUTF8(ext_child.name());
288 if (ext_name == _T (
"opencpn:action" )) {
295 return new TrackPoint(rlat, rlon, TimeString);
299 bool b_layerviz,
int layer_id) {
302 unsigned short int GPXSeg;
303 bool b_propviz =
false;
305 Track *pTentTrack = NULL;
306 HyperlinkList *linklist = NULL;
308 wxString Name = wxString::FromUTF8(trk_node.name());
309 if (Name == _T (
"trk" )) {
310 pTentTrack =
new Track();
316 tschild = tschild.next_sibling()) {
317 wxString ChildName = wxString::FromUTF8(tschild.name());
318 if (ChildName == _T (
"trkseg" )) {
323 tpchild = tpchild.next_sibling()) {
324 wxString tpChildName = wxString::FromUTF8(tpchild.name());
325 if (tpChildName == _T(
"trkpt")) {
326 pWp = ::GPXLoadTrackPoint1(tpchild);
328 pTentTrack->AddPoint(pWp);
329 pWp->m_GPXTrkSegNo = GPXSeg;
333 }
else if (ChildName == _T (
"name" ))
334 TrackName = wxString::FromUTF8(tschild.first_child().value());
335 else if (ChildName == _T (
"desc" ))
336 DescString = wxString::FromUTF8(tschild.first_child().value());
339 if (ChildName == _T (
"link")) {
341 wxString HrefTextString;
342 wxString HrefTypeString;
343 if (linklist == NULL) linklist =
new HyperlinkList;
344 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
347 child1 = child1.next_sibling()) {
348 wxString LinkString = wxString::FromUTF8(child1.name());
350 if (LinkString == _T (
"text" ))
351 HrefTextString = wxString::FromUTF8(child1.first_child().value());
352 if (LinkString == _T (
"type" ))
353 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
357 link->Link = HrefString;
358 link->DescrText = HrefTextString;
359 link->LType = HrefTypeString;
360 linklist->push_back(link);
363 else if (ChildName == _T (
"extensions" )) {
365 ext_child = ext_child.next_sibling()) {
366 wxString ext_name = wxString::FromUTF8(ext_child.name());
367 if (ext_name == _T (
"opencpn:start" )) {
368 pTentTrack->m_TrackStartString =
369 wxString::FromUTF8(ext_child.first_child().value());
370 }
else if (ext_name == _T (
"opencpn:end" )) {
371 pTentTrack->m_TrackEndString =
372 wxString::FromUTF8(ext_child.first_child().value());
375 else if (ext_name == _T (
"opencpn:viz" )) {
376 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
378 b_viz = (viz == _T(
"1"));
379 }
else if (ext_name == _T (
"opencpn:style" )) {
381 attr = attr.next_attribute()) {
382 if (!strcmp(attr.name(),
"style"))
383 pTentTrack->m_style = (wxPenStyle)attr.as_int();
384 else if (!strcmp(attr.name(),
"width"))
385 pTentTrack->m_width = attr.as_int();
389 else if (ext_name == _T (
"opencpn:guid" )) {
391 wxString::FromUTF8(ext_child.first_child().value());
394 else if (ext_name.EndsWith(
395 _T (
"TrackExtension" )))
398 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
399 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
400 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
401 pTentTrack->m_Colour =
402 wxString::FromUTF8(gpxx_child.first_child().value());
409 pTentTrack->SetName(TrackName);
410 pTentTrack->m_TrackDescription = DescString;
413 pTentTrack->SetVisible(b_viz);
415 if (b_fullviz) pTentTrack->SetVisible();
419 pTentTrack->SetVisible(b_layerviz);
420 pTentTrack->m_bIsInLayer =
true;
421 pTentTrack->m_LayerID = layer_id;
422 pTentTrack->SetListed(
false);
425 pTentTrack->SetCurrentTrackSeg(GPXSeg);
429 delete pTentTrack->m_TrackHyperlinkList;
430 pTentTrack->m_TrackHyperlinkList = linklist;
437 bool b_layerviz,
int layer_id,
bool b_change,
441 bool b_propviz =
false;
442 bool b_propSWPviz =
false;
445 Route *pTentRoute = NULL;
447 wxString Name = wxString::FromUTF8(wpt_node.name());
448 if (Name == _T (
"rte" )) {
449 pTentRoute =
new Route();
450 HyperlinkList *linklist = NULL;
453 bool route_existing =
false;
457 tschild = tschild.next_sibling()) {
458 wxString ChildName = wxString::FromUTF8(tschild.name());
461 if (ChildName == _T (
"extensions" )) {
463 ext_child = ext_child.next_sibling()) {
464 wxString ext_name = wxString::FromUTF8(ext_child.name());
466 if (ext_name == _T (
"opencpn:start" )) {
468 wxString::FromUTF8(ext_child.first_child().value());
469 }
else if (ext_name == _T (
"opencpn:end" )) {
471 wxString::FromUTF8(ext_child.first_child().value());
474 else if (ext_name == _T (
"opencpn:viz" )) {
475 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
477 b_viz = (viz == _T(
"1"));
480 else if (ext_name == _T (
"opencpn:sharedWPviz" )) {
481 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
483 swpViz = (viz == _T(
"1"));
484 }
else if (ext_name == _T (
"opencpn:style" )) {
486 attr = attr.next_attribute()) {
487 if (!strcmp(attr.name(),
"style"))
488 pTentRoute->
m_style = (wxPenStyle)attr.as_int();
489 else if (!strcmp(attr.name(),
"width"))
490 pTentRoute->
m_width = attr.as_int();
494 else if (ext_name == _T (
"opencpn:guid" )) {
496 wxString::FromUTF8(ext_child.first_child().value());
499 else if (ext_name == _T (
"opencpn:planned_speed" )) {
500 pTentRoute->
m_PlannedSpeed = atof(ext_child.first_child().value());
503 else if (ext_name == _T (
"opencpn:planned_departure" )) {
506 wxString::FromUTF8(ext_child.first_child().value()));
509 else if (ext_name == _T (
"opencpn:time_display" )) {
511 wxString::FromUTF8(ext_child.first_child().value());
512 }
else if (ext_name.EndsWith(
513 _T (
"RouteExtension" )))
516 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
517 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
518 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
520 wxString::FromUTF8(gpxx_child.first_child().value());
525 if (RouteExists(pTentRoute->
m_GUID)) {
531 pTentRoute->
m_GUID = pWayPointMan->CreateGUID(NULL);
532 route_existing =
true;
536 else if (load_points && ChildName == _T (
"rtept" )) {
538 ::GPXLoadWaypoint1(tschild, _T(
"square"), _T(
""), b_fullviz,
539 b_layer, b_layerviz, layer_id,
false);
541 if (!b_layer) erp = ::WaypointExists(tpWp->
m_GUID);
555 (!route_existing || (route_existing && tpWp->IsShared()))) {
559 if (route_existing) tpWp->
m_GUID = pWayPointMan->CreateGUID(NULL);
564 pTentRoute->AddPoint(pWp,
false,
true);
574 }
else if (ChildName == _T (
"name" )) {
575 RouteName = wxString::FromUTF8(tschild.first_child().value());
576 }
else if (ChildName == _T (
"desc" )) {
577 DescString = wxString::FromUTF8(tschild.first_child().value());
580 if (ChildName == _T (
"link")) {
582 wxString HrefTextString;
583 wxString HrefTypeString;
584 if (linklist == NULL) linklist =
new HyperlinkList;
585 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
588 child1 = child1.next_sibling()) {
589 wxString LinkString = wxString::FromUTF8(child1.name());
591 if (LinkString == _T (
"text" ))
592 HrefTextString = wxString::FromUTF8(child1.first_child().value());
593 if (LinkString == _T (
"type" ))
594 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
598 link->Link = HrefString;
599 link->DescrText = HrefTextString;
600 link->LType = HrefTypeString;
601 linklist->push_back(link);
607 if (ChildName.EndsWith(_T (
"RouteExtension" )))
609 for (
pugi::xml_node gpxx_child = tschild.first_child(); gpxx_child;
610 gpxx_child = gpxx_child.next_sibling()) {
611 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
612 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
614 wxString::FromUTF8(gpxx_child.first_child().value());
626 pTentRoute->SetVisible(b_viz);
627 }
else if (b_fullviz) {
628 pTentRoute->SetVisible();
631 if (b_propSWPviz) pTentRoute->SetSharedWPViz(swpViz);
634 pTentRoute->SetVisible(b_layerviz);
637 pTentRoute->SetListed(
false);
645 unsigned int flags) {
650 s.Printf(_T(
"%.9f"), pr->m_lat);
651 node.append_attribute(
"lat") = s.mb_str();
652 s.Printf(_T(
"%.9f"), pr->m_lon);
653 node.append_attribute(
"lon") = s.mb_str();
655 if (flags & OUT_TIME) {
656 child = node.append_child(
"time");
658 child.append_child(pugi::node_pcdata)
662 if (!dt.IsValid()) dt = wxDateTime::Now();
664 wxString t = dt.ToUTC()
667 .Append(dt.ToUTC().FormatISOTime())
669 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
673 if ((!pr->GetName().IsEmpty() && (flags & OUT_NAME)) ||
674 (flags & OUT_NAME_FORCE)) {
675 wxCharBuffer buffer = pr->GetName().ToUTF8();
677 child = node.append_child(
"name");
678 child.append_child(pugi::node_pcdata).set_value(buffer.data());
682 if ((!pr->GetDescription().IsEmpty() && (flags & OUT_DESC)) ||
683 (flags & OUT_DESC_FORCE)) {
684 wxCharBuffer buffer = pr->GetDescription().ToUTF8();
686 child = node.append_child(
"desc");
687 child.append_child(pugi::node_pcdata).set_value(buffer.data());
692 if (flags & OUT_HYPERLINKS) {
694 if (linklist && linklist->size()) {
695 for (
Hyperlink *link : *pr->m_HyperlinkList) {
698 wxCharBuffer buffer = link->Link.ToUTF8();
699 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
701 buffer = link->DescrText.ToUTF8();
703 child = child_link.append_child(
"text");
704 child.append_child(pugi::node_pcdata).set_value(buffer.data());
707 buffer = link->LType.ToUTF8();
708 if (buffer.data() && strlen(buffer.data()) > 0) {
709 child = child_link.append_child(
"type");
710 child.append_child(pugi::node_pcdata).set_value(buffer.data());
716 if (flags & OUT_SYM_FORCE) {
717 child = node.append_child(
"sym");
718 if (!pr->GetIconName().IsEmpty()) {
719 child.append_child(pugi::node_pcdata)
720 .set_value(pr->GetIconName().mb_str());
722 child.append_child(
"empty");
726 if (flags & OUT_TYPE) {
727 child = node.append_child(
"type");
728 child.append_child(pugi::node_pcdata).set_value(
"WPT");
731 if ((flags & OUT_GUID) || (flags & OUT_VIZ) || (flags & OUT_VIZ_NAME) ||
732 (flags & OUT_SHARED) || (flags & OUT_EXTENSION) ||
733 (flags & OUT_TIDE_STATION) || (flags & OUT_RTE_PROPERTIES)) {
736 if (!pr->
m_GUID.IsEmpty() && (flags & OUT_GUID)) {
737 child = child_ext.append_child(
"opencpn:guid");
738 child.append_child(pugi::node_pcdata).set_value(pr->
m_GUID.mb_str());
742 child = child_ext.append_child(
"opencpn:viz");
743 child.append_child(pugi::node_pcdata).set_value(
"0");
747 child = child_ext.append_child(
"opencpn:viz_name");
748 child.append_child(pugi::node_pcdata).set_value(
"1");
751 if ((flags & OUT_SHARED) && pr->IsShared()) {
752 child = child_ext.append_child(
"opencpn:shared");
753 child.append_child(pugi::node_pcdata).set_value(
"1");
755 if (flags & OUT_ARRIVAL_RADIUS) {
756 child = child_ext.append_child(
"opencpn:arrival_radius");
757 s.Printf(_T(
"%.3f"), pr->GetWaypointArrivalRadius());
758 child.append_child(pugi::node_pcdata).set_value(s.mbc_str());
760 if (flags & OUT_WAYPOINT_RANGE_RINGS) {
761 child = child_ext.append_child(
"opencpn:waypoint_range_rings");
786 if (flags & OUT_WAYPOINT_SCALE) {
787 child = child_ext.append_child(
"opencpn:scale_min_max");
789 use.set_value(pr->GetUseSca());
791 sca.set_value(pr->GetScaMin());
793 max.set_value(pr->GetScaMax());
795 if ((flags & OUT_TIDE_STATION) && !pr->
m_TideStation.IsEmpty()) {
796 child = child_ext.append_child(
"opencpn:tidestation");
797 child.append_child(pugi::node_pcdata)
800 if ((flags & OUT_RTE_PROPERTIES) &&
802 child = child_ext.append_child(
"opencpn:rte_properties");
814 use.set_value(pr->
GetManualETD().FormatISOCombined().mb_str());
823 unsigned int flags) {
828 s.Printf(_T(
"%.9f"), pt->m_lat);
829 node.append_attribute(
"lat") = s.mb_str();
830 s.Printf(_T(
"%.9f"), pt->m_lon);
831 node.append_attribute(
"lon") = s.mb_str();
833 if (flags & OUT_TIME && pt->HasValidTimestamp()) {
834 child = node.append_child(
"time");
835 child.append_child(pugi::node_pcdata).set_value(pt->GetTimeString());
842 unsigned int flags) {
845 if (pTrack->GetName().Len()) {
846 wxCharBuffer buffer = pTrack->GetName().ToUTF8();
848 child = node.append_child(
"name");
849 child.append_child(pugi::node_pcdata).set_value(buffer.data());
853 if (pTrack->m_TrackDescription.Len()) {
854 wxCharBuffer buffer = pTrack->m_TrackDescription.ToUTF8();
856 child = node.append_child(
"desc");
857 child.append_child(pugi::node_pcdata).set_value(buffer.data());
862 HyperlinkList *linklist = pTrack->m_TrackHyperlinkList;
863 if (linklist && linklist->size()) {
866 wxCharBuffer buffer = link->Link.ToUTF8();
867 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
869 buffer = link->DescrText.ToUTF8();
871 child = child_link.append_child(
"text");
872 child.append_child(pugi::node_pcdata).set_value(buffer.data());
875 buffer = link->LType.ToUTF8();
876 if (buffer.data() && strlen(buffer.data()) > 0) {
877 child = child_link.append_child(
"type");
878 child.append_child(pugi::node_pcdata).set_value(buffer.data());
885 child = child_ext.append_child(
"opencpn:guid");
886 child.append_child(pugi::node_pcdata).set_value(pTrack->m_GUID.mb_str());
888 child = child_ext.append_child(
"opencpn:viz");
889 child.append_child(pugi::node_pcdata)
890 .set_value(pTrack->IsVisible() ==
true ?
"1" :
"0");
892 if (pTrack->m_TrackStartString.Len()) {
893 wxCharBuffer buffer = pTrack->m_TrackStartString.ToUTF8();
895 child = child_ext.append_child(
"opencpn:start");
896 child.append_child(pugi::node_pcdata).set_value(buffer.data());
900 if (pTrack->m_TrackEndString.Len()) {
901 wxCharBuffer buffer = pTrack->m_TrackEndString.ToUTF8();
903 child = child_ext.append_child(
"opencpn:end");
904 child.append_child(pugi::node_pcdata).set_value(buffer.data());
908 if (pTrack->m_width != WIDTH_UNDEFINED ||
909 pTrack->m_style != wxPENSTYLE_INVALID) {
910 child = child_ext.append_child(
"opencpn:style");
912 if (pTrack->m_width != WIDTH_UNDEFINED)
913 child.append_attribute(
"width") = pTrack->m_width;
914 if (pTrack->m_style != wxPENSTYLE_INVALID)
915 child.append_attribute(
"style") = pTrack->m_style;
918 if (pTrack->m_Colour != wxEmptyString) {
919 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:TrackExtension");
920 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
921 child.append_child(pugi::node_pcdata).set_value(pTrack->m_Colour.mb_str());
924 if (flags & RT_OUT_NO_RTPTS)
return true;
929 unsigned short int GPXTrkSegNo1 = 1;
932 unsigned short int GPXTrkSegNo2 = GPXTrkSegNo1;
936 while (node2 < pTrack->GetnPoints()) {
937 prp = pTrack->GetPoint(node2);
938 GPXTrkSegNo1 = prp->m_GPXTrkSegNo;
939 if (GPXTrkSegNo1 != GPXTrkSegNo2)
break;
941 GPXCreateTrkpt(seg.append_child(
"trkpt"), prp, OPT_TRACKPT);
945 }
while (node2 < pTrack->GetnPoints());
956 child = node.append_child(
"name");
957 child.append_child(pugi::node_pcdata).set_value(buffer.data());
964 child = node.append_child(
"desc");
965 child.append_child(pugi::node_pcdata).set_value(buffer.data());
971 if (linklist && linklist->size()) {
974 wxCharBuffer buffer = link->Link.ToUTF8();
975 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
977 buffer = link->DescrText.ToUTF8();
979 child = child_link.append_child(
"text");
980 child.append_child(pugi::node_pcdata).set_value(buffer.data());
982 buffer = link->LType.ToUTF8();
983 if (buffer.data() && strlen(buffer.data()) > 0) {
984 child = child_link.append_child(
"type");
985 child.append_child(pugi::node_pcdata).set_value(buffer.data());
992 child = child_ext.append_child(
"opencpn:guid");
993 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_GUID.mb_str());
995 child = child_ext.append_child(
"opencpn:viz");
996 child.append_child(pugi::node_pcdata)
997 .set_value(pRoute->IsVisible() ==
true ?
"1" :
"0");
999 if (pRoute->ContainsSharedWP()) {
1000 child = child_ext.append_child(
"opencpn:sharedWPviz");
1001 child.append_child(pugi::node_pcdata)
1002 .set_value(pRoute->GetSharedWPViz() ==
true ?
"1" :
"0");
1007 if (buffer.data()) {
1008 child = child_ext.append_child(
"opencpn:start");
1009 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1015 if (buffer.data()) {
1016 child = child_ext.append_child(
"opencpn:end");
1017 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1022 child = child_ext.append_child(
"opencpn:planned_speed");
1025 child.append_child(pugi::node_pcdata).set_value(s.mb_str());
1029 child = child_ext.append_child(
"opencpn:planned_departure");
1034 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
1037 child = child_ext.append_child(
"opencpn:time_display");
1038 child.append_child(pugi::node_pcdata)
1041 if (pRoute->
m_width != WIDTH_UNDEFINED ||
1042 pRoute->
m_style != wxPENSTYLE_INVALID) {
1043 child = child_ext.append_child(
"opencpn:style");
1045 if (pRoute->
m_width != WIDTH_UNDEFINED)
1046 child.append_attribute(
"width") = pRoute->
m_width;
1047 if (pRoute->
m_style != wxPENSTYLE_INVALID)
1048 child.append_attribute(
"style") = pRoute->
m_style;
1051 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:RouteExtension");
1052 child = gpxx_ext.append_child(
"gpxx:IsAutoNamed");
1053 child.append_child(pugi::node_pcdata).set_value(
"false");
1055 if (pRoute->
m_Colour != wxEmptyString) {
1056 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
1057 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_Colour.mb_str());
1061 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1065 prp = node2->GetData();
1067 GPXCreateWpt(node.append_child(
"rtept"), prp, OPT_ROUTEPT);
1069 node2 = node2->GetNext();
1076 if (!pTentRoute)
return false;
1078 bool bAddroute =
true;
1080 if (pTentRoute->GetnPoints() < 2) bAddroute =
false;
1085 pRouteList->Append(pTentRoute);
1088 pTentRoute->FinalizeForRendering();
1093 float prev_rlat = 0., prev_rlon = 0.;
1101 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1102 prp->m_lon, prev_pConfPoint, prp,
1104 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1105 prev_rlat = prp->m_lat;
1106 prev_rlon = prp->m_lon;
1107 prev_pConfPoint = prp;
1111 node = node->GetNext();
1115 wxRoutePointListNode *pnode = (pTentRoute->
pRoutePointList)->GetFirst();
1120 Route *pcontainer_route = g_pRouteMan->FindRouteContainingWaypoint(prp);
1122 if (pcontainer_route == NULL) {
1125 if (!prp->IsShared()) {
1132 pnode = pnode->GetNext();
1140bool InsertTrack(
Track *pTentTrack,
bool bApplyChanges) {
1141 if (!pTentTrack)
return false;
1143 bool bAddtrack =
true;
1146 if (!bApplyChanges && pTentTrack->GetnPoints() < 2) bAddtrack =
false;
1151 g_TrackList.push_back(pTentTrack);
1158 float prev_rlat = 0., prev_rlon = 0.;
1161 for (
int i = 0; i < pTentTrack->GetnPoints(); i++) {
1165 pSelect->AddSelectableTrackSegment(prev_rlat, prev_rlon, prp->m_lat,
1166 prp->m_lon, prev_pConfPoint, prp,
1169 prev_rlat = prp->m_lat;
1170 prev_rlon = prp->m_lon;
1171 prev_pConfPoint = prp;
1179bool InsertWpt(
RoutePoint *pWp,
bool overwrite) {
1182 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1183 if (!pExisting || overwrite) {
1184 if (NULL != pWayPointMan) {
1186 pWayPointMan->DestroyWaypoint(pExisting);
1191 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1197 if (!pTentRoute)
return;
1198 if (pTentRoute->GetnPoints() < 2)
return;
1201 Route *pExisting = ::RouteExists(pTentRoute->
m_GUID);
1208 pRouteList->Append(pChangeRoute);
1215 pChangeRoute->SetVisible(pTentRoute->IsVisible());
1219 float prev_rlat = 0., prev_rlon = 0.;
1230 pSelect->DeleteSelectableRoutePoint(ex_rp);
1231 ex_rp->m_lat = prp->m_lat;
1232 ex_rp->m_lon = prp->m_lon;
1233 ex_rp->SetIconName(prp->GetIconName());
1235 ex_rp->SetName(prp->GetName());
1238 pChangeRoute->AddPoint(ex_rp);
1239 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, ex_rp);
1242 pChangeRoute->AddPoint(prp);
1243 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1248 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1249 prp->m_lon, prev_pConfPoint, prp,
1251 prev_rlat = prp->m_lat;
1252 prev_rlon = prp->m_lon;
1253 prev_pConfPoint = prp;
1257 node = node->GetNext();
1260 pChangeRoute->FinalizeForRendering();
1264 wxRouteListNode *node = pRouteList->GetFirst();
1266 Route *proute = node->GetData();
1271 if (prp == pWP)
return proute;
1272 pnode = pnode->GetNext();
1275 node = node->GetNext();
1281bool NavObjectCollection1::CreateNavObjGPXPoints(
void) {
1286 if (!pWayPointMan)
return false;
1288 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1293 pr = node->GetData();
1300 GPXCreateWpt(new_node, pr, OPT_WPT);
1302 node = node->GetNext();
1308bool NavObjectCollection1::CreateNavObjGPXRoutes(
void) {
1310 if (!pRouteList)
return false;
1312 wxRouteListNode *node1 = pRouteList->GetFirst();
1314 Route *pRoute = node1->GetData();
1321 GPXCreateRoute(new_node, pRoute);
1324 node1 = node1->GetNext();
1330bool NavObjectCollection1::CreateNavObjGPXTracks(
void) {
1332 for (
Track *pTrack : g_TrackList) {
1333 if (pTrack->GetnPoints()) {
1334 if (!pTrack->m_bIsInLayer && !pTrack->m_btemp) {
1339 GPXCreateTrk(new_node, pTrack, 0);
1347bool NavObjectCollection1::CreateAllGPXObjects() {
1357bool NavObjectCollection1::AddGPXRoute(
Route *pRoute) {
1363 GPXCreateRoute(new_node, pRoute);
1367bool NavObjectCollection1::AddGPXTrack(
Track *pTrk) {
1373 GPXCreateTrk(new_node, pTrk, 0);
1377bool NavObjectCollection1::AddGPXWaypoint(
RoutePoint *pWP) {
1383 GPXCreateWpt(new_node, pWP, OPT_WPT);
1387void NavObjectCollection1::AddGPXRoutesList(RouteList *pRoutes) {
1390 wxRouteListNode *pRoute = pRoutes->GetFirst();
1392 Route *pRData = pRoute->GetData();
1393 AddGPXRoute(pRData);
1394 pRoute = pRoute->GetNext();
1398void NavObjectCollection1::AddGPXTracksList(std::vector<Track *> *pTracks) {
1401 for (
Track *pRData : *pTracks) {
1402 AddGPXTrack(pRData);
1406bool NavObjectCollection1::AddGPXPointsList(RoutePointList *pRoutePoints) {
1409 wxRoutePointListNode *pRoutePointNode = pRoutePoints->GetFirst();
1410 while (pRoutePointNode) {
1411 RoutePoint *pRP = pRoutePointNode->GetData();
1412 AddGPXWaypoint(pRP);
1413 pRoutePointNode = pRoutePointNode->GetNext();
1419void NavObjectCollection1::SetRootGPXNode(
void) {
1420 if (!strlen(first_child().name())) {
1422 gpx_root.append_attribute(
"version") =
"1.1";
1423 gpx_root.append_attribute(
"creator") =
"OpenCPN";
1424 gpx_root.append_attribute(
"xmlns:xsi") =
1425 "http://www.w3.org/2001/XMLSchema-instance";
1426 gpx_root.append_attribute(
"xmlns") =
"http://www.topografix.com/GPX/1/1";
1427 gpx_root.append_attribute(
"xmlns:gpxx") =
1428 "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
1429 gpx_root.append_attribute(
"xsi:schemaLocation") =
1430 "http://www.topografix.com/GPX/1/1 "
1431 "http://www.topografix.com/GPX/1/1/gpx.xsd "
1432 "http://www.garmin.com/xmlschemas/GpxExtensions/v3 "
1433 "http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd";
1434 gpx_root.append_attribute(
"xmlns:opencpn") =
"http://www.opencpn.org";
1438bool NavObjectCollection1::IsOpenCPN() {
1440 attr = attr.next_attribute())
1441 if (!strcmp(attr.name(),
"creator") && !strcmp(attr.value(),
"OpenCPN"))
1446bool NavObjectCollection1::SaveFile(
const wxString filename) {
1447 wxString tmp_filename = filename +
".tmp";
1448 if (wxFileExists(tmp_filename)) {
1449 wxRemoveFile(tmp_filename);
1451 save_file(tmp_filename.fn_str(),
" ");
1452 wxRenameFile(tmp_filename.fn_str(), filename.fn_str(),
true);
1456bool NavObjectCollection1::LoadAllGPXObjects(
bool b_full_viz,
1457 int &wpt_duplicates,
1458 bool b_compute_bbox) {
1463 object =
object.next_sibling()) {
1464 if (!strcmp(
object.name(),
"wpt")) {
1465 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1466 b_full_viz,
false,
false, 0);
1470 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1473 NavObj_dB::GetInstance().InsertRoutePoint(pWp);
1474 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1476 wptbox.Set(pWp->m_lat, pWp->m_lon, pWp->m_lat, pWp->m_lon);
1477 BBox.Expand(wptbox);
1482 }
else if (!strcmp(
object.name(),
"trk")) {
1483 Track *pTrack = GPXLoadTrack1(
object, b_full_viz,
false,
false, 0);
1484 if (InsertTrack(pTrack)) {
1485 NavObj_dB::GetInstance().InsertTrack(pTrack);
1487 }
else if (!strcmp(
object.name(),
"rte")) {
1488 Route *pRoute = GPXLoadRoute1(
object, b_full_viz,
false,
false, 0,
false);
1489 if (InsertRouteA(pRoute,
this)) {
1490 NavObj_dB::GetInstance().InsertRoute(pRoute);
1491 if (b_compute_bbox && pRoute->IsVisible())
1492 BBox.Expand(pRoute->GetBBox());
1500int NavObjectCollection1::LoadAllGPXObjectsAsLayer(
int layer_id,
1502 wxCheckBoxState b_namesviz) {
1503 if (!pWayPointMan)
return 0;
1509 object =
object.next_sibling()) {
1510 if (!strcmp(
object.name(),
"wpt")) {
1511 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1512 b_namesviz != wxCHK_UNDETERMINED,
1513 true, b_layerviz, layer_id);
1514 if (b_namesviz != wxCHK_UNDETERMINED) {
1515 pWp->SetNameShown(b_namesviz == wxCHK_CHECKED);
1519 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1522 if (!strcmp(
object.name(),
"trk")) {
1524 GPXLoadTrack1(
object,
false,
true, b_layerviz, layer_id);
1526 InsertTrack(pTrack);
1527 }
else if (!strcmp(
object.name(),
"rte")) {
1529 GPXLoadRoute1(
object,
true,
true, b_layerviz, layer_id,
false);
1531 InsertRouteA(pRoute,
this);
1539bool NavObjectCollection1::LoadAllGPXTrackObjects() {
1543 object =
object.next_sibling()) {
1544 if (!strcmp(
object.name(),
"trk")) {
1545 Track *pTrack = GPXLoadTrack1(
object,
true,
false,
false, 0);
1546 InsertTrack(pTrack);
1553bool NavObjectCollection1::LoadAllGPXRouteObjects() {
1557 object =
object.next_sibling()) {
1558 if (!strcmp(
object.name(),
"rte")) {
1559 Route *route = GPXLoadRoute1(
object,
true,
false,
false, 0,
false,
true);
1560 InsertRouteA(route,
nullptr);
1567bool NavObjectCollection1::LoadAllGPXPointObjects() {
1571 object =
object.next_sibling()) {
1572 if (!strcmp(
object.name(),
"wpt")) {
1574 GPXLoadWaypoint1(
object,
"circle",
"",
false,
false,
false, 0);
1582RoutePoint *WaypointExists(
const wxString &name,
double lat,
double lon) {
1585 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1591 if (name == pr->GetName()) {
1592 if (fabs(lat - pr->m_lat) < 1.e-6 && fabs(lon - pr->m_lon) < 1.e-6) {
1597 node = node->GetNext();
1603RoutePoint *WaypointExists(
const wxString &guid) {
1604 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1610 if (guid == pr->
m_GUID) {
1613 node = node->GetNext();
1620 bool IsInList =
false;
1622 wxRouteListNode *node1 = pRouteList->GetFirst();
1624 Route *pRoute = node1->GetData();
1627 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1631 prp = node2->GetData();
1633 if (pr->IsSame(prp)) {
1638 node2 = node2->GetNext();
1640 node1 = node1->GetNext();
1645Route *RouteExists(
const wxString &guid) {
1646 wxRouteListNode *route_node = pRouteList->GetFirst();
1648 while (route_node) {
1649 Route *proute = route_node->GetData();
1651 if (guid == proute->
m_GUID)
return proute;
1653 route_node = route_node->GetNext();
1659 wxRouteListNode *route_node = pRouteList->GetFirst();
1660 while (route_node) {
1661 Route *proute = route_node->GetData();
1663 if (proute->IsEqualTo(pTentRoute))
return proute;
1665 route_node = route_node->GetNext();
1670Track *TrackExists(
const wxString &guid) {
1671 for (
Track *ptrack : g_TrackList) {
1672 if (guid == ptrack->m_GUID)
return ptrack;
Represents a waypoint or mark within the navigation system.
HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this waypoint.
wxColour m_wxcWaypointRangeRingsColour
Color for the range rings display.
wxString m_MarkDescription
Description text for the waypoint.
int m_iWaypointRangeRingsNumber
Number of range rings to display around the waypoint.
void SetCreateTime(wxDateTime dt)
Sets the create time of this RoutePoint in UTC.
wxString m_GUID
Globally Unique Identifier for the waypoint.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowNameData
Flag indicating if waypoint data should be shown with the name.
wxDateTime GetManualETD()
Retrieves the manually set Estimated Time of Departure for this waypoint, in UTC.
bool m_bIsInRoute
Flag indicating if this waypoint is part of a route.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
wxString m_timestring
String representation of the waypoint creation time.
double GetPlannedSpeed()
Return the planned speed associated with this waypoint.
bool m_bIsVisible
Flag indicating if the waypoint should be drawn on the chart.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
bool m_btemp
Flag indicating if this is a temporary waypoint.
bool m_manual_etd
Flag indicating whether the ETD has been manually set by the user.
int m_LayerID
Layer identifier if the waypoint belongs to a layer.
int m_iWaypointRangeRingsStepUnits
Units for the range rings step (0=nm, 1=km).
wxDateTime GetCreateTime(void)
Returns the Create Time of this RoutePoint in UTC.
float m_fWaypointRangeRingsStep
Distance between consecutive range rings.
wxString m_TideStation
Associated tide station identifier.
bool m_bShowWaypointRangeRings
Flag indicating if range rings should be shown around the waypoint.
void SetETD(const wxDateTime &etd)
Sets the Estimated Time of Departure for this waypoint, in UTC.
Represents a navigational route in the navigation system.
double m_PlannedSpeed
Default planned speed for the route in knots.
wxString m_RouteStartString
Name or description of the route's starting point.
wxString m_RouteDescription
Additional descriptive information about the route.
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
wxString m_Colour
Color name for rendering the route on the chart.
wxString m_RouteEndString
Name or description of the route's ending point.
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.
HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this route.
int m_LayerID
Identifier of the layer containing this route.
bool DeleteRoute(Route *pRoute)
Represents a single point in a track.
Represents a track, which is a series of connected track points.
bool AddRoutePoint(RoutePoint *prp)
Add a point to list which owns it.