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->Append(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->Append(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->Append(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->GetCount()) {
695 wxHyperlinkListNode *linknode = linklist->GetFirst();
701 wxCharBuffer buffer = link->Link.ToUTF8();
702 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
704 buffer = link->DescrText.ToUTF8();
706 child = child_link.append_child(
"text");
707 child.append_child(pugi::node_pcdata).set_value(buffer.data());
710 buffer = link->LType.ToUTF8();
711 if (buffer.data() && strlen(buffer.data()) > 0) {
712 child = child_link.append_child(
"type");
713 child.append_child(pugi::node_pcdata).set_value(buffer.data());
716 linknode = linknode->GetNext();
721 if (flags & OUT_SYM_FORCE) {
722 child = node.append_child(
"sym");
723 if (!pr->GetIconName().IsEmpty()) {
724 child.append_child(pugi::node_pcdata)
725 .set_value(pr->GetIconName().mb_str());
727 child.append_child(
"empty");
731 if (flags & OUT_TYPE) {
732 child = node.append_child(
"type");
733 child.append_child(pugi::node_pcdata).set_value(
"WPT");
736 if ((flags & OUT_GUID) || (flags & OUT_VIZ) || (flags & OUT_VIZ_NAME) ||
737 (flags & OUT_SHARED) || (flags & OUT_EXTENSION) ||
738 (flags & OUT_TIDE_STATION) || (flags & OUT_RTE_PROPERTIES)) {
741 if (!pr->
m_GUID.IsEmpty() && (flags & OUT_GUID)) {
742 child = child_ext.append_child(
"opencpn:guid");
743 child.append_child(pugi::node_pcdata).set_value(pr->
m_GUID.mb_str());
747 child = child_ext.append_child(
"opencpn:viz");
748 child.append_child(pugi::node_pcdata).set_value(
"0");
752 child = child_ext.append_child(
"opencpn:viz_name");
753 child.append_child(pugi::node_pcdata).set_value(
"1");
756 if ((flags & OUT_SHARED) && pr->IsShared()) {
757 child = child_ext.append_child(
"opencpn:shared");
758 child.append_child(pugi::node_pcdata).set_value(
"1");
760 if (flags & OUT_ARRIVAL_RADIUS) {
761 child = child_ext.append_child(
"opencpn:arrival_radius");
762 s.Printf(_T(
"%.3f"), pr->GetWaypointArrivalRadius());
763 child.append_child(pugi::node_pcdata).set_value(s.mbc_str());
765 if (flags & OUT_WAYPOINT_RANGE_RINGS) {
766 child = child_ext.append_child(
"opencpn:waypoint_range_rings");
791 if (flags & OUT_WAYPOINT_SCALE) {
792 child = child_ext.append_child(
"opencpn:scale_min_max");
794 use.set_value(pr->GetUseSca());
796 sca.set_value(pr->GetScaMin());
798 max.set_value(pr->GetScaMax());
800 if ((flags & OUT_TIDE_STATION) && !pr->
m_TideStation.IsEmpty()) {
801 child = child_ext.append_child(
"opencpn:tidestation");
802 child.append_child(pugi::node_pcdata)
805 if ((flags & OUT_RTE_PROPERTIES) &&
807 child = child_ext.append_child(
"opencpn:rte_properties");
819 use.set_value(pr->
GetManualETD().FormatISOCombined().mb_str());
828 unsigned int flags) {
833 s.Printf(_T(
"%.9f"), pt->m_lat);
834 node.append_attribute(
"lat") = s.mb_str();
835 s.Printf(_T(
"%.9f"), pt->m_lon);
836 node.append_attribute(
"lon") = s.mb_str();
838 if (flags & OUT_TIME && pt->HasValidTimestamp()) {
839 child = node.append_child(
"time");
840 child.append_child(pugi::node_pcdata).set_value(pt->GetTimeString());
847 unsigned int flags) {
850 if (pTrack->GetName().Len()) {
851 wxCharBuffer buffer = pTrack->GetName().ToUTF8();
853 child = node.append_child(
"name");
854 child.append_child(pugi::node_pcdata).set_value(buffer.data());
858 if (pTrack->m_TrackDescription.Len()) {
859 wxCharBuffer buffer = pTrack->m_TrackDescription.ToUTF8();
861 child = node.append_child(
"desc");
862 child.append_child(pugi::node_pcdata).set_value(buffer.data());
867 HyperlinkList *linklist = pTrack->m_TrackHyperlinkList;
868 if (linklist && linklist->GetCount()) {
869 wxHyperlinkListNode *linknode = linklist->GetFirst();
874 wxCharBuffer buffer = link->Link.ToUTF8();
875 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
877 buffer = link->DescrText.ToUTF8();
879 child = child_link.append_child(
"text");
880 child.append_child(pugi::node_pcdata).set_value(buffer.data());
883 buffer = link->LType.ToUTF8();
884 if (buffer.data() && strlen(buffer.data()) > 0) {
885 child = child_link.append_child(
"type");
886 child.append_child(pugi::node_pcdata).set_value(buffer.data());
889 linknode = linknode->GetNext();
895 child = child_ext.append_child(
"opencpn:guid");
896 child.append_child(pugi::node_pcdata).set_value(pTrack->m_GUID.mb_str());
898 child = child_ext.append_child(
"opencpn:viz");
899 child.append_child(pugi::node_pcdata)
900 .set_value(pTrack->IsVisible() ==
true ?
"1" :
"0");
902 if (pTrack->m_TrackStartString.Len()) {
903 wxCharBuffer buffer = pTrack->m_TrackStartString.ToUTF8();
905 child = child_ext.append_child(
"opencpn:start");
906 child.append_child(pugi::node_pcdata).set_value(buffer.data());
910 if (pTrack->m_TrackEndString.Len()) {
911 wxCharBuffer buffer = pTrack->m_TrackEndString.ToUTF8();
913 child = child_ext.append_child(
"opencpn:end");
914 child.append_child(pugi::node_pcdata).set_value(buffer.data());
918 if (pTrack->m_width != WIDTH_UNDEFINED ||
919 pTrack->m_style != wxPENSTYLE_INVALID) {
920 child = child_ext.append_child(
"opencpn:style");
922 if (pTrack->m_width != WIDTH_UNDEFINED)
923 child.append_attribute(
"width") = pTrack->m_width;
924 if (pTrack->m_style != wxPENSTYLE_INVALID)
925 child.append_attribute(
"style") = pTrack->m_style;
928 if (pTrack->m_Colour != wxEmptyString) {
929 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:TrackExtension");
930 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
931 child.append_child(pugi::node_pcdata).set_value(pTrack->m_Colour.mb_str());
934 if (flags & RT_OUT_NO_RTPTS)
return true;
939 unsigned short int GPXTrkSegNo1 = 1;
942 unsigned short int GPXTrkSegNo2 = GPXTrkSegNo1;
946 while (node2 < pTrack->GetnPoints()) {
947 prp = pTrack->GetPoint(node2);
948 GPXTrkSegNo1 = prp->m_GPXTrkSegNo;
949 if (GPXTrkSegNo1 != GPXTrkSegNo2)
break;
951 GPXCreateTrkpt(seg.append_child(
"trkpt"), prp, OPT_TRACKPT);
955 }
while (node2 < pTrack->GetnPoints());
966 child = node.append_child(
"name");
967 child.append_child(pugi::node_pcdata).set_value(buffer.data());
974 child = node.append_child(
"desc");
975 child.append_child(pugi::node_pcdata).set_value(buffer.data());
981 if (linklist && linklist->GetCount()) {
982 wxHyperlinkListNode *linknode = linklist->GetFirst();
987 wxCharBuffer buffer = link->Link.ToUTF8();
988 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
990 buffer = link->DescrText.ToUTF8();
992 child = child_link.append_child(
"text");
993 child.append_child(pugi::node_pcdata).set_value(buffer.data());
996 buffer = link->LType.ToUTF8();
997 if (buffer.data() && strlen(buffer.data()) > 0) {
998 child = child_link.append_child(
"type");
999 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1002 linknode = linknode->GetNext();
1008 child = child_ext.append_child(
"opencpn:guid");
1009 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_GUID.mb_str());
1011 child = child_ext.append_child(
"opencpn:viz");
1012 child.append_child(pugi::node_pcdata)
1013 .set_value(pRoute->IsVisible() ==
true ?
"1" :
"0");
1015 if (pRoute->ContainsSharedWP()) {
1016 child = child_ext.append_child(
"opencpn:sharedWPviz");
1017 child.append_child(pugi::node_pcdata)
1018 .set_value(pRoute->GetSharedWPViz() ==
true ?
"1" :
"0");
1023 if (buffer.data()) {
1024 child = child_ext.append_child(
"opencpn:start");
1025 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1031 if (buffer.data()) {
1032 child = child_ext.append_child(
"opencpn:end");
1033 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1038 child = child_ext.append_child(
"opencpn:planned_speed");
1041 child.append_child(pugi::node_pcdata).set_value(s.mb_str());
1045 child = child_ext.append_child(
"opencpn:planned_departure");
1050 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
1053 child = child_ext.append_child(
"opencpn:time_display");
1054 child.append_child(pugi::node_pcdata)
1057 if (pRoute->
m_width != WIDTH_UNDEFINED ||
1058 pRoute->
m_style != wxPENSTYLE_INVALID) {
1059 child = child_ext.append_child(
"opencpn:style");
1061 if (pRoute->
m_width != WIDTH_UNDEFINED)
1062 child.append_attribute(
"width") = pRoute->
m_width;
1063 if (pRoute->
m_style != wxPENSTYLE_INVALID)
1064 child.append_attribute(
"style") = pRoute->
m_style;
1067 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:RouteExtension");
1068 child = gpxx_ext.append_child(
"gpxx:IsAutoNamed");
1069 child.append_child(pugi::node_pcdata).set_value(
"false");
1071 if (pRoute->
m_Colour != wxEmptyString) {
1072 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
1073 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_Colour.mb_str());
1077 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1081 prp = node2->GetData();
1083 GPXCreateWpt(node.append_child(
"rtept"), prp, OPT_ROUTEPT);
1085 node2 = node2->GetNext();
1092 if (!pTentRoute)
return false;
1094 bool bAddroute =
true;
1096 if (pTentRoute->GetnPoints() < 2) bAddroute =
false;
1101 pRouteList->Append(pTentRoute);
1104 pTentRoute->FinalizeForRendering();
1109 float prev_rlat = 0., prev_rlon = 0.;
1117 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1118 prp->m_lon, prev_pConfPoint, prp,
1120 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1121 prev_rlat = prp->m_lat;
1122 prev_rlon = prp->m_lon;
1123 prev_pConfPoint = prp;
1127 node = node->GetNext();
1131 wxRoutePointListNode *pnode = (pTentRoute->
pRoutePointList)->GetFirst();
1136 Route *pcontainer_route = g_pRouteMan->FindRouteContainingWaypoint(prp);
1138 if (pcontainer_route == NULL) {
1141 if (!prp->IsShared()) {
1148 pnode = pnode->GetNext();
1156bool InsertTrack(
Track *pTentTrack,
bool bApplyChanges) {
1157 if (!pTentTrack)
return false;
1159 bool bAddtrack =
true;
1162 if (!bApplyChanges && pTentTrack->GetnPoints() < 2) bAddtrack =
false;
1167 g_TrackList.push_back(pTentTrack);
1174 float prev_rlat = 0., prev_rlon = 0.;
1177 for (
int i = 0; i < pTentTrack->GetnPoints(); i++) {
1181 pSelect->AddSelectableTrackSegment(prev_rlat, prev_rlon, prp->m_lat,
1182 prp->m_lon, prev_pConfPoint, prp,
1185 prev_rlat = prp->m_lat;
1186 prev_rlon = prp->m_lon;
1187 prev_pConfPoint = prp;
1195bool InsertWpt(
RoutePoint *pWp,
bool overwrite) {
1198 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1199 if (!pExisting || overwrite) {
1200 if (NULL != pWayPointMan) {
1202 pWayPointMan->DestroyWaypoint(pExisting);
1207 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1213 if (!pTentRoute)
return;
1214 if (pTentRoute->GetnPoints() < 2)
return;
1217 Route *pExisting = ::RouteExists(pTentRoute->
m_GUID);
1224 pRouteList->Append(pChangeRoute);
1231 pChangeRoute->SetVisible(pTentRoute->IsVisible());
1235 float prev_rlat = 0., prev_rlon = 0.;
1246 pSelect->DeleteSelectableRoutePoint(ex_rp);
1247 ex_rp->m_lat = prp->m_lat;
1248 ex_rp->m_lon = prp->m_lon;
1249 ex_rp->SetIconName(prp->GetIconName());
1251 ex_rp->SetName(prp->GetName());
1254 pChangeRoute->AddPoint(ex_rp);
1255 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, ex_rp);
1258 pChangeRoute->AddPoint(prp);
1259 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1264 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1265 prp->m_lon, prev_pConfPoint, prp,
1267 prev_rlat = prp->m_lat;
1268 prev_rlon = prp->m_lon;
1269 prev_pConfPoint = prp;
1273 node = node->GetNext();
1276 pChangeRoute->FinalizeForRendering();
1280 wxRouteListNode *node = pRouteList->GetFirst();
1282 Route *proute = node->GetData();
1287 if (prp == pWP)
return proute;
1288 pnode = pnode->GetNext();
1291 node = node->GetNext();
1297bool NavObjectCollection1::CreateNavObjGPXPoints(
void) {
1302 if (!pWayPointMan)
return false;
1304 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1309 pr = node->GetData();
1316 GPXCreateWpt(new_node, pr, OPT_WPT);
1318 node = node->GetNext();
1324bool NavObjectCollection1::CreateNavObjGPXRoutes(
void) {
1326 if (!pRouteList)
return false;
1328 wxRouteListNode *node1 = pRouteList->GetFirst();
1330 Route *pRoute = node1->GetData();
1337 GPXCreateRoute(new_node, pRoute);
1340 node1 = node1->GetNext();
1346bool NavObjectCollection1::CreateNavObjGPXTracks(
void) {
1348 for (
Track *pTrack : g_TrackList) {
1349 if (pTrack->GetnPoints()) {
1350 if (!pTrack->m_bIsInLayer && !pTrack->m_btemp) {
1355 GPXCreateTrk(new_node, pTrack, 0);
1363bool NavObjectCollection1::CreateAllGPXObjects() {
1373bool NavObjectCollection1::AddGPXRoute(
Route *pRoute) {
1379 GPXCreateRoute(new_node, pRoute);
1383bool NavObjectCollection1::AddGPXTrack(
Track *pTrk) {
1389 GPXCreateTrk(new_node, pTrk, 0);
1393bool NavObjectCollection1::AddGPXWaypoint(
RoutePoint *pWP) {
1399 GPXCreateWpt(new_node, pWP, OPT_WPT);
1403void NavObjectCollection1::AddGPXRoutesList(RouteList *pRoutes) {
1406 wxRouteListNode *pRoute = pRoutes->GetFirst();
1408 Route *pRData = pRoute->GetData();
1409 AddGPXRoute(pRData);
1410 pRoute = pRoute->GetNext();
1414void NavObjectCollection1::AddGPXTracksList(std::vector<Track *> *pTracks) {
1417 for (
Track *pRData : *pTracks) {
1418 AddGPXTrack(pRData);
1422bool NavObjectCollection1::AddGPXPointsList(RoutePointList *pRoutePoints) {
1425 wxRoutePointListNode *pRoutePointNode = pRoutePoints->GetFirst();
1426 while (pRoutePointNode) {
1427 RoutePoint *pRP = pRoutePointNode->GetData();
1428 AddGPXWaypoint(pRP);
1429 pRoutePointNode = pRoutePointNode->GetNext();
1435void NavObjectCollection1::SetRootGPXNode(
void) {
1436 if (!strlen(first_child().name())) {
1438 gpx_root.append_attribute(
"version") =
"1.1";
1439 gpx_root.append_attribute(
"creator") =
"OpenCPN";
1440 gpx_root.append_attribute(
"xmlns:xsi") =
1441 "http://www.w3.org/2001/XMLSchema-instance";
1442 gpx_root.append_attribute(
"xmlns") =
"http://www.topografix.com/GPX/1/1";
1443 gpx_root.append_attribute(
"xmlns:gpxx") =
1444 "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
1445 gpx_root.append_attribute(
"xsi:schemaLocation") =
1446 "http://www.topografix.com/GPX/1/1 "
1447 "http://www.topografix.com/GPX/1/1/gpx.xsd "
1448 "http://www.garmin.com/xmlschemas/GpxExtensions/v3 "
1449 "http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd";
1450 gpx_root.append_attribute(
"xmlns:opencpn") =
"http://www.opencpn.org";
1454bool NavObjectCollection1::IsOpenCPN() {
1456 attr = attr.next_attribute())
1457 if (!strcmp(attr.name(),
"creator") && !strcmp(attr.value(),
"OpenCPN"))
1462bool NavObjectCollection1::SaveFile(
const wxString filename) {
1463 wxString tmp_filename = filename +
".tmp";
1464 if (wxFileExists(tmp_filename)) {
1465 wxRemoveFile(tmp_filename);
1467 save_file(tmp_filename.fn_str(),
" ");
1468 wxRenameFile(tmp_filename.fn_str(), filename.fn_str(),
true);
1472bool NavObjectCollection1::LoadAllGPXObjects(
bool b_full_viz,
1473 int &wpt_duplicates,
1474 bool b_compute_bbox) {
1479 object =
object.next_sibling()) {
1480 if (!strcmp(
object.name(),
"wpt")) {
1481 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1482 b_full_viz,
false,
false, 0);
1486 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1489 NavObj_dB::GetInstance().InsertRoutePoint(pWp);
1490 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1492 wptbox.Set(pWp->m_lat, pWp->m_lon, pWp->m_lat, pWp->m_lon);
1493 BBox.Expand(wptbox);
1498 }
else if (!strcmp(
object.name(),
"trk")) {
1499 Track *pTrack = GPXLoadTrack1(
object, b_full_viz,
false,
false, 0);
1500 if (InsertTrack(pTrack)) {
1501 NavObj_dB::GetInstance().InsertTrack(pTrack);
1503 }
else if (!strcmp(
object.name(),
"rte")) {
1504 Route *pRoute = GPXLoadRoute1(
object, b_full_viz,
false,
false, 0,
false);
1505 if (InsertRouteA(pRoute,
this)) {
1506 NavObj_dB::GetInstance().InsertRoute(pRoute);
1507 if (b_compute_bbox && pRoute->IsVisible())
1508 BBox.Expand(pRoute->GetBBox());
1516int NavObjectCollection1::LoadAllGPXObjectsAsLayer(
int layer_id,
1518 wxCheckBoxState b_namesviz) {
1519 if (!pWayPointMan)
return 0;
1525 object =
object.next_sibling()) {
1526 if (!strcmp(
object.name(),
"wpt")) {
1527 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1528 b_namesviz != wxCHK_UNDETERMINED,
1529 true, b_layerviz, layer_id);
1530 if (b_namesviz != wxCHK_UNDETERMINED) {
1531 pWp->SetNameShown(b_namesviz == wxCHK_CHECKED);
1535 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1538 if (!strcmp(
object.name(),
"trk")) {
1540 GPXLoadTrack1(
object,
false,
true, b_layerviz, layer_id);
1542 InsertTrack(pTrack);
1543 }
else if (!strcmp(
object.name(),
"rte")) {
1545 GPXLoadRoute1(
object,
true,
true, b_layerviz, layer_id,
false);
1547 InsertRouteA(pRoute,
this);
1555bool NavObjectCollection1::LoadAllGPXTrackObjects() {
1559 object =
object.next_sibling()) {
1560 if (!strcmp(
object.name(),
"trk")) {
1561 Track *pTrack = GPXLoadTrack1(
object,
true,
false,
false, 0);
1562 InsertTrack(pTrack);
1569bool NavObjectCollection1::LoadAllGPXRouteObjects() {
1573 object =
object.next_sibling()) {
1574 if (!strcmp(
object.name(),
"rte")) {
1575 Route *route = GPXLoadRoute1(
object,
true,
false,
false, 0,
false,
true);
1576 InsertRouteA(route,
nullptr);
1583bool NavObjectCollection1::LoadAllGPXPointObjects() {
1587 object =
object.next_sibling()) {
1588 if (!strcmp(
object.name(),
"wpt")) {
1590 GPXLoadWaypoint1(
object,
"circle",
"",
false,
false,
false, 0);
1598RoutePoint *WaypointExists(
const wxString &name,
double lat,
double lon) {
1601 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1607 if (name == pr->GetName()) {
1608 if (fabs(lat - pr->m_lat) < 1.e-6 && fabs(lon - pr->m_lon) < 1.e-6) {
1613 node = node->GetNext();
1619RoutePoint *WaypointExists(
const wxString &guid) {
1620 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1626 if (guid == pr->
m_GUID) {
1629 node = node->GetNext();
1636 bool IsInList =
false;
1638 wxRouteListNode *node1 = pRouteList->GetFirst();
1640 Route *pRoute = node1->GetData();
1643 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1647 prp = node2->GetData();
1649 if (pr->IsSame(prp)) {
1654 node2 = node2->GetNext();
1656 node1 = node1->GetNext();
1661Route *RouteExists(
const wxString &guid) {
1662 wxRouteListNode *route_node = pRouteList->GetFirst();
1664 while (route_node) {
1665 Route *proute = route_node->GetData();
1667 if (guid == proute->
m_GUID)
return proute;
1669 route_node = route_node->GetNext();
1675 wxRouteListNode *route_node = pRouteList->GetFirst();
1676 while (route_node) {
1677 Route *proute = route_node->GetData();
1679 if (proute->IsEqualTo(pTentRoute))
return proute;
1681 route_node = route_node->GetNext();
1686Track *TrackExists(
const wxString &guid) {
1687 for (
Track *ptrack : g_TrackList) {
1688 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.