21#include "model/nav_object_database.h"
32NavObjectCollection1::NavObjectCollection1() : pugi::xml_document() {}
34NavObjectCollection1::~NavObjectCollection1() {}
37 wxString GUID,
bool b_fullviz,
bool b_layer,
38 bool b_layerviz,
int layer_id,
bool b_nameviz) {
40 bool bviz_name =
false;
42 bool b_propvizname =
false;
43 bool b_propviz =
false;
45 wxString SymString = def_symbol_name;
49 double plan_speed = 0.0;
52 wxString GuidString = GUID;
57 HyperlinkList *linklist = NULL;
59 double rlat = wpt_node.attribute(
"lat").as_double();
60 double rlon = wpt_node.attribute(
"lon").as_double();
61 double ArrivalRadius = 0;
62 int l_iWaypointRangeRingsNumber = -1;
63 float l_fWaypointRangeRingsStep = -1;
64 int l_pWaypointRangeRingsStepUnits = -1;
65 bool l_bWaypointRangeRingsVisible =
false;
66 long l_iWaypointScaleMin = 2147483646;
67 long l_iWaypoinScaleMax = 0;
68 bool l_bWaypointUseScale =
false;
69 wxColour l_wxcWaypointRangeRingsColour;
70 l_wxcWaypointRangeRingsColour.Set(
"#FFFFFF");
73 child = child.next_sibling()) {
74 const char *pcn = child.name();
76 if (!strcmp(pcn,
"sym")) {
77 SymString = wxString::FromUTF8(child.first_child().value());
78 }
else if (!strcmp(pcn,
"time"))
79 TimeString = wxString::FromUTF8(child.first_child().value());
81 else if (!strcmp(pcn,
"name")) {
82 NameString = wxString::FromUTF8(child.first_child().value());
83 if (NameString.StartsWith(
"@~~")) {
87 TideStation = NameString.Right(NameString.length() - 3);
88 NameString.Replace(
"@~~",
"@-~");
92 else if (!strcmp(pcn,
"desc")) {
93 DescString = wxString::FromUTF8(child.first_child().value());
96 else if (!strcmp(pcn,
"type")) {
97 TypeString = wxString::FromUTF8(child.first_child().value());
101 if (!strcmp(pcn,
"link")) {
103 wxString HrefTextString;
104 wxString HrefTypeString;
105 if (linklist == NULL) linklist =
new HyperlinkList;
106 HrefString = wxString::FromUTF8(child.first_attribute().value());
109 child1 = child1.next_sibling()) {
110 wxString LinkString = wxString::FromUTF8(child1.name());
112 if (LinkString ==
"text")
113 HrefTextString = wxString::FromUTF8(child1.first_child().value());
114 if (LinkString ==
"type")
115 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
119 link->Link = HrefString;
120 link->DescrText = HrefTextString;
121 link->LType = HrefTypeString;
122 linklist->push_back(link);
126 else if (!strcmp(pcn,
"extensions")) {
128 ext_child = ext_child.next_sibling()) {
129 wxString ext_name = wxString::FromUTF8(ext_child.name());
130 if (ext_name ==
"opencpn:guid") {
131 GuidString = wxString::FromUTF8(ext_child.first_child().value());
132 }
else if (ext_name ==
"opencpn:viz") {
134 wxString s = wxString::FromUTF8(ext_child.first_child().value());
136 if (s.ToLong(&v)) bviz = (v != 0);
137 }
else if (ext_name ==
"opencpn:viz_name") {
138 b_propvizname =
true;
139 wxString s = wxString::FromUTF8(ext_child.first_child().value());
141 if (s.ToLong(&v)) bviz_name = (v != 0);
142 }
else if (ext_name ==
"opencpn:shared") {
143 wxString s = wxString::FromUTF8(ext_child.first_child().value());
145 if (s.ToLong(&v)) bshared = (v != 0);
147 if (ext_name ==
"opencpn:arrival_radius") {
148 wxString::FromUTF8(ext_child.first_child().value())
149 .ToDouble(&ArrivalRadius);
151 if (ext_name ==
"opencpn:waypoint_range_rings") {
153 attr = attr.next_attribute()) {
154 if (wxString::FromUTF8(attr.name()) ==
"number")
155 l_iWaypointRangeRingsNumber = attr.as_int();
156 else if (wxString::FromUTF8(attr.name()) ==
"step")
157 l_fWaypointRangeRingsStep = attr.as_float();
158 else if (wxString::FromUTF8(attr.name()) ==
"units")
159 l_pWaypointRangeRingsStepUnits = attr.as_int();
160 else if (wxString::FromUTF8(attr.name()) ==
"visible")
161 l_bWaypointRangeRingsVisible = attr.as_bool();
162 else if (wxString::FromUTF8(attr.name()) ==
"colour")
163 l_wxcWaypointRangeRingsColour.Set(
164 wxString::FromUTF8(attr.as_string()));
167 if (ext_name ==
"opencpn:scale_min_max") {
169 attr = attr.next_attribute()) {
170 if (wxString::FromUTF8(attr.name()) ==
"UseScale")
171 l_bWaypointUseScale = attr.as_bool();
172 else if (wxString::FromUTF8(attr.name()) ==
"ScaleMin")
173 l_iWaypointScaleMin = attr.as_int();
174 else if (wxString::FromUTF8(attr.name()) ==
"ScaleMax")
175 l_iWaypoinScaleMax = attr.as_float();
178 if (ext_name ==
"opencpn:tidestation") {
179 TideStation = wxString::FromUTF8(ext_child.first_child().value());
181 if (ext_name ==
"opencpn:rte_properties") {
183 attr = attr.next_attribute()) {
184 if (!strcmp(attr.name(),
"planned_speed"))
185 plan_speed = attr.as_double();
186 else if (!strcmp(attr.name(),
"etd"))
190 etd = attr.as_string();
200 if (GuidString.IsEmpty()) GuidString = pWayPointMan->CreateGUID(NULL);
203 pWP =
new RoutePoint(rlat, rlon, SymString, NameString, GuidString,
208 pWP->SetWaypointArrivalRadius(ArrivalRadius);
209 pWP->SetWaypointRangeRingsNumber(l_iWaypointRangeRingsNumber);
210 pWP->SetWaypointRangeRingsStep(l_fWaypointRangeRingsStep);
211 pWP->SetWaypointRangeRingsStepUnits(l_pWaypointRangeRingsStepUnits);
212 pWP->SetShowWaypointRangeRings(l_bWaypointRangeRingsVisible);
218 if (!l_bWaypointRangeRingsVisible) pWP->SetWaypointRangeRingsNumber(0);
220 pWP->SetWaypointRangeRingsColour(l_wxcWaypointRangeRingsColour);
221 pWP->SetScaMin(l_iWaypointScaleMin);
222 pWP->SetScaMax(l_iWaypoinScaleMax);
223 pWP->SetUseSca(l_bWaypointUseScale);
224 pWP->SetPlannedSpeed(plan_speed);
236 if (!b_nameviz && !b_propvizname) pWP->
m_bShowName =
false;
247 pWP->SetListed(
false);
250 pWP->SetShared(bshared);
252 if (TimeString.Len()) {
268 double rlat = wpt_node.attribute(
"lat").as_double();
269 double rlon = wpt_node.attribute(
"lon").as_double();
272 child = child.next_sibling()) {
273 const char *pcn = child.name();
274 if (!strcmp(pcn,
"time"))
275 TimeString = wxString::FromUTF8(child.first_child().value());
278 else if (!strcmp(pcn,
"extensions")) {
280 ext_child = ext_child.next_sibling()) {
281 wxString ext_name = wxString::FromUTF8(ext_child.name());
282 if (ext_name ==
"opencpn:action") {
289 return new TrackPoint(rlat, rlon, TimeString);
293 bool b_layerviz,
int layer_id) {
296 unsigned short int GPXSeg;
297 bool b_propviz =
false;
299 Track *pTentTrack = NULL;
300 HyperlinkList *linklist = NULL;
302 wxString Name = wxString::FromUTF8(trk_node.name());
304 pTentTrack =
new Track();
310 tschild = tschild.next_sibling()) {
311 wxString ChildName = wxString::FromUTF8(tschild.name());
312 if (ChildName ==
"trkseg") {
317 tpchild = tpchild.next_sibling()) {
318 wxString tpChildName = wxString::FromUTF8(tpchild.name());
319 if (tpChildName ==
"trkpt") {
320 pWp = ::GPXLoadTrackPoint1(tpchild);
322 pTentTrack->AddPoint(pWp);
323 pWp->m_GPXTrkSegNo = GPXSeg;
327 }
else if (ChildName ==
"name")
328 TrackName = wxString::FromUTF8(tschild.first_child().value());
329 else if (ChildName ==
"desc")
330 DescString = wxString::FromUTF8(tschild.first_child().value());
333 if (ChildName ==
"link") {
335 wxString HrefTextString;
336 wxString HrefTypeString;
337 if (linklist == NULL) linklist =
new HyperlinkList;
338 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
341 child1 = child1.next_sibling()) {
342 wxString LinkString = wxString::FromUTF8(child1.name());
344 if (LinkString ==
"text")
345 HrefTextString = wxString::FromUTF8(child1.first_child().value());
346 if (LinkString ==
"type")
347 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
351 link->Link = HrefString;
352 link->DescrText = HrefTextString;
353 link->LType = HrefTypeString;
354 linklist->push_back(link);
357 else if (ChildName ==
"extensions") {
359 ext_child = ext_child.next_sibling()) {
360 wxString ext_name = wxString::FromUTF8(ext_child.name());
361 if (ext_name ==
"opencpn:start") {
362 pTentTrack->m_TrackStartString =
363 wxString::FromUTF8(ext_child.first_child().value());
364 }
else if (ext_name ==
"opencpn:end") {
365 pTentTrack->m_TrackEndString =
366 wxString::FromUTF8(ext_child.first_child().value());
369 else if (ext_name ==
"opencpn:viz") {
370 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
372 b_viz = (viz ==
"1");
373 }
else if (ext_name ==
"opencpn:style") {
375 attr = attr.next_attribute()) {
376 if (!strcmp(attr.name(),
"style"))
377 pTentTrack->m_style = (wxPenStyle)attr.as_int();
378 else if (!strcmp(attr.name(),
"width"))
379 pTentTrack->m_width = attr.as_int();
383 else if (ext_name ==
"opencpn:guid") {
385 wxString::FromUTF8(ext_child.first_child().value());
388 else if (ext_name.EndsWith(
"TrackExtension"))
391 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
392 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
393 if (gpxx_name.EndsWith(
"DisplayColor"))
394 pTentTrack->m_Colour =
395 wxString::FromUTF8(gpxx_child.first_child().value());
402 pTentTrack->SetName(TrackName);
403 pTentTrack->m_TrackDescription = DescString;
406 pTentTrack->SetVisible(b_viz);
408 if (b_fullviz) pTentTrack->SetVisible();
412 pTentTrack->SetVisible(b_layerviz);
413 pTentTrack->m_bIsInLayer =
true;
414 pTentTrack->m_LayerID = layer_id;
415 pTentTrack->SetListed(
false);
418 pTentTrack->SetCurrentTrackSeg(GPXSeg);
422 delete pTentTrack->m_TrackHyperlinkList;
423 pTentTrack->m_TrackHyperlinkList = linklist;
430 bool b_layerviz,
int layer_id,
bool b_change,
434 bool b_propviz =
false;
435 bool b_propSWPviz =
false;
438 Route *pTentRoute = NULL;
440 wxString Name = wxString::FromUTF8(wpt_node.name());
442 pTentRoute =
new Route();
443 HyperlinkList *linklist = NULL;
446 bool route_existing =
false;
450 tschild = tschild.next_sibling()) {
451 wxString ChildName = wxString::FromUTF8(tschild.name());
454 if (ChildName ==
"extensions") {
456 ext_child = ext_child.next_sibling()) {
457 wxString ext_name = wxString::FromUTF8(ext_child.name());
459 if (ext_name ==
"opencpn:start") {
461 wxString::FromUTF8(ext_child.first_child().value());
462 }
else if (ext_name ==
"opencpn:end") {
464 wxString::FromUTF8(ext_child.first_child().value());
467 else if (ext_name ==
"opencpn:viz") {
468 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
470 b_viz = (viz ==
"1");
473 else if (ext_name ==
"opencpn:sharedWPviz") {
474 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
476 swpViz = (viz ==
"1");
477 }
else if (ext_name ==
"opencpn:style") {
479 attr = attr.next_attribute()) {
480 if (!strcmp(attr.name(),
"style"))
481 pTentRoute->
m_style = (wxPenStyle)attr.as_int();
482 else if (!strcmp(attr.name(),
"width"))
483 pTentRoute->
m_width = attr.as_int();
487 else if (ext_name ==
"opencpn:guid") {
489 wxString::FromUTF8(ext_child.first_child().value());
492 else if (ext_name ==
"opencpn:planned_speed") {
493 pTentRoute->
m_PlannedSpeed = atof(ext_child.first_child().value());
496 else if (ext_name ==
"opencpn:planned_departure") {
499 wxString::FromUTF8(ext_child.first_child().value()));
502 else if (ext_name ==
"opencpn:time_display") {
504 wxString::FromUTF8(ext_child.first_child().value());
505 }
else if (ext_name.EndsWith(
"RouteExtension"))
508 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
509 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
510 if (gpxx_name.EndsWith(
"DisplayColor"))
512 wxString::FromUTF8(gpxx_child.first_child().value());
517 if (RouteExists(pTentRoute->
m_GUID)) {
523 pTentRoute->
m_GUID = pWayPointMan->CreateGUID(NULL);
524 route_existing =
true;
528 else if (load_points && ChildName ==
"rtept") {
530 ::GPXLoadWaypoint1(tschild,
"square",
"", b_fullviz, b_layer,
531 b_layerviz, layer_id,
false);
533 if (!b_layer) erp = ::WaypointExists(tpWp->
m_GUID);
547 (!route_existing || (route_existing && tpWp->IsShared()))) {
551 if (route_existing) tpWp->
m_GUID = pWayPointMan->CreateGUID(NULL);
556 pTentRoute->AddPoint(pWp,
false,
true);
566 }
else if (ChildName ==
"name") {
567 RouteName = wxString::FromUTF8(tschild.first_child().value());
568 }
else if (ChildName ==
"desc") {
569 DescString = wxString::FromUTF8(tschild.first_child().value());
572 if (ChildName ==
"link") {
574 wxString HrefTextString;
575 wxString HrefTypeString;
576 if (linklist == NULL) linklist =
new HyperlinkList;
577 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
580 child1 = child1.next_sibling()) {
581 wxString LinkString = wxString::FromUTF8(child1.name());
583 if (LinkString ==
"text")
584 HrefTextString = wxString::FromUTF8(child1.first_child().value());
585 if (LinkString ==
"type")
586 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
590 link->Link = HrefString;
591 link->DescrText = HrefTextString;
592 link->LType = HrefTypeString;
593 linklist->push_back(link);
599 if (ChildName.EndsWith(
"RouteExtension"))
601 for (
pugi::xml_node gpxx_child = tschild.first_child(); gpxx_child;
602 gpxx_child = gpxx_child.next_sibling()) {
603 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
604 if (gpxx_name.EndsWith(
"DisplayColor"))
606 wxString::FromUTF8(gpxx_child.first_child().value());
618 pTentRoute->SetVisible(b_viz);
619 }
else if (b_fullviz) {
620 pTentRoute->SetVisible();
623 if (b_propSWPviz) pTentRoute->SetSharedWPViz(swpViz);
626 pTentRoute->SetVisible(b_layerviz);
629 pTentRoute->SetListed(
false);
637 unsigned int flags) {
642 s.Printf(
"%.9f", pr->m_lat);
643 node.append_attribute(
"lat") = s.mb_str();
644 s.Printf(
"%.9f", pr->m_lon);
645 node.append_attribute(
"lon") = s.mb_str();
647 if (flags & OUT_TIME) {
648 child = node.append_child(
"time");
650 child.append_child(pugi::node_pcdata)
654 if (!dt.IsValid()) dt = wxDateTime::Now();
656 wxString t = dt.ToUTC()
659 .Append(dt.ToUTC().FormatISOTime())
661 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
665 if ((!pr->GetName().IsEmpty() && (flags & OUT_NAME)) ||
666 (flags & OUT_NAME_FORCE)) {
667 wxCharBuffer buffer = pr->GetName().ToUTF8();
669 child = node.append_child(
"name");
670 child.append_child(pugi::node_pcdata).set_value(buffer.data());
674 if ((!pr->GetDescription().IsEmpty() && (flags & OUT_DESC)) ||
675 (flags & OUT_DESC_FORCE)) {
676 wxCharBuffer buffer = pr->GetDescription().ToUTF8();
678 child = node.append_child(
"desc");
679 child.append_child(pugi::node_pcdata).set_value(buffer.data());
684 if (flags & OUT_HYPERLINKS) {
686 if (linklist && linklist->size()) {
687 for (
Hyperlink *link : *pr->m_HyperlinkList) {
690 wxCharBuffer buffer = link->Link.ToUTF8();
691 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
693 buffer = link->DescrText.ToUTF8();
695 child = child_link.append_child(
"text");
696 child.append_child(pugi::node_pcdata).set_value(buffer.data());
699 buffer = link->LType.ToUTF8();
700 if (buffer.data() && strlen(buffer.data()) > 0) {
701 child = child_link.append_child(
"type");
702 child.append_child(pugi::node_pcdata).set_value(buffer.data());
708 if (flags & OUT_SYM_FORCE) {
709 child = node.append_child(
"sym");
710 if (!pr->GetIconName().IsEmpty()) {
711 child.append_child(pugi::node_pcdata)
712 .set_value(pr->GetIconName().mb_str());
714 child.append_child(
"empty");
718 if (flags & OUT_TYPE) {
719 child = node.append_child(
"type");
720 child.append_child(pugi::node_pcdata).set_value(
"WPT");
723 if ((flags & OUT_GUID) || (flags & OUT_VIZ) || (flags & OUT_VIZ_NAME) ||
724 (flags & OUT_SHARED) || (flags & OUT_EXTENSION) ||
725 (flags & OUT_TIDE_STATION) || (flags & OUT_RTE_PROPERTIES)) {
728 if (!pr->
m_GUID.IsEmpty() && (flags & OUT_GUID)) {
729 child = child_ext.append_child(
"opencpn:guid");
730 child.append_child(pugi::node_pcdata).set_value(pr->
m_GUID.mb_str());
734 child = child_ext.append_child(
"opencpn:viz");
735 child.append_child(pugi::node_pcdata).set_value(
"0");
739 child = child_ext.append_child(
"opencpn:viz_name");
740 child.append_child(pugi::node_pcdata).set_value(
"1");
743 if ((flags & OUT_SHARED) && pr->IsShared()) {
744 child = child_ext.append_child(
"opencpn:shared");
745 child.append_child(pugi::node_pcdata).set_value(
"1");
747 if (flags & OUT_ARRIVAL_RADIUS) {
748 child = child_ext.append_child(
"opencpn:arrival_radius");
749 s.Printf(
"%.3f", pr->GetWaypointArrivalRadius());
750 child.append_child(pugi::node_pcdata).set_value(s.mbc_str());
752 if (flags & OUT_WAYPOINT_RANGE_RINGS) {
753 child = child_ext.append_child(
"opencpn:waypoint_range_rings");
778 if (flags & OUT_WAYPOINT_SCALE) {
779 child = child_ext.append_child(
"opencpn:scale_min_max");
781 use.set_value(pr->GetUseSca());
783 sca.set_value(pr->GetScaMin());
785 max.set_value(pr->GetScaMax());
787 if ((flags & OUT_TIDE_STATION) && !pr->
m_TideStation.IsEmpty()) {
788 child = child_ext.append_child(
"opencpn:tidestation");
789 child.append_child(pugi::node_pcdata)
792 if ((flags & OUT_RTE_PROPERTIES) &&
794 child = child_ext.append_child(
"opencpn:rte_properties");
806 use.set_value(pr->
GetManualETD().FormatISOCombined().mb_str());
815 unsigned int flags) {
820 s.Printf(
"%.9f", pt->m_lat);
821 node.append_attribute(
"lat") = s.mb_str();
822 s.Printf(
"%.9f", pt->m_lon);
823 node.append_attribute(
"lon") = s.mb_str();
825 if (flags & OUT_TIME && pt->HasValidTimestamp()) {
826 child = node.append_child(
"time");
827 child.append_child(pugi::node_pcdata).set_value(pt->GetTimeString());
834 unsigned int flags) {
837 if (pTrack->GetName().Len()) {
838 wxCharBuffer buffer = pTrack->GetName().ToUTF8();
840 child = node.append_child(
"name");
841 child.append_child(pugi::node_pcdata).set_value(buffer.data());
845 if (pTrack->m_TrackDescription.Len()) {
846 wxCharBuffer buffer = pTrack->m_TrackDescription.ToUTF8();
848 child = node.append_child(
"desc");
849 child.append_child(pugi::node_pcdata).set_value(buffer.data());
854 HyperlinkList *linklist = pTrack->m_TrackHyperlinkList;
855 if (linklist && linklist->size()) {
858 wxCharBuffer buffer = link->Link.ToUTF8();
859 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
861 buffer = link->DescrText.ToUTF8();
863 child = child_link.append_child(
"text");
864 child.append_child(pugi::node_pcdata).set_value(buffer.data());
867 buffer = link->LType.ToUTF8();
868 if (buffer.data() && strlen(buffer.data()) > 0) {
869 child = child_link.append_child(
"type");
870 child.append_child(pugi::node_pcdata).set_value(buffer.data());
877 child = child_ext.append_child(
"opencpn:guid");
878 child.append_child(pugi::node_pcdata).set_value(pTrack->m_GUID.mb_str());
880 child = child_ext.append_child(
"opencpn:viz");
881 child.append_child(pugi::node_pcdata)
882 .set_value(pTrack->IsVisible() ==
true ?
"1" :
"0");
884 if (pTrack->m_TrackStartString.Len()) {
885 wxCharBuffer buffer = pTrack->m_TrackStartString.ToUTF8();
887 child = child_ext.append_child(
"opencpn:start");
888 child.append_child(pugi::node_pcdata).set_value(buffer.data());
892 if (pTrack->m_TrackEndString.Len()) {
893 wxCharBuffer buffer = pTrack->m_TrackEndString.ToUTF8();
895 child = child_ext.append_child(
"opencpn:end");
896 child.append_child(pugi::node_pcdata).set_value(buffer.data());
900 if (pTrack->m_width != WIDTH_UNDEFINED ||
901 pTrack->m_style != wxPENSTYLE_INVALID) {
902 child = child_ext.append_child(
"opencpn:style");
904 if (pTrack->m_width != WIDTH_UNDEFINED)
905 child.append_attribute(
"width") = pTrack->m_width;
906 if (pTrack->m_style != wxPENSTYLE_INVALID)
907 child.append_attribute(
"style") = pTrack->m_style;
910 if (pTrack->m_Colour !=
"") {
911 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:TrackExtension");
912 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
913 child.append_child(pugi::node_pcdata).set_value(pTrack->m_Colour.mb_str());
916 if (flags & RT_OUT_NO_RTPTS)
return true;
921 unsigned short int GPXTrkSegNo1 = 1;
924 unsigned short int GPXTrkSegNo2 = GPXTrkSegNo1;
928 while (node2 < pTrack->GetnPoints()) {
929 prp = pTrack->GetPoint(node2);
930 GPXTrkSegNo1 = prp->m_GPXTrkSegNo;
931 if (GPXTrkSegNo1 != GPXTrkSegNo2)
break;
933 GPXCreateTrkpt(seg.append_child(
"trkpt"), prp, OPT_TRACKPT);
937 }
while (node2 < pTrack->GetnPoints());
948 child = node.append_child(
"name");
949 child.append_child(pugi::node_pcdata).set_value(buffer.data());
956 child = node.append_child(
"desc");
957 child.append_child(pugi::node_pcdata).set_value(buffer.data());
963 if (linklist && linklist->size()) {
966 wxCharBuffer buffer = link->Link.ToUTF8();
967 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
969 buffer = link->DescrText.ToUTF8();
971 child = child_link.append_child(
"text");
972 child.append_child(pugi::node_pcdata).set_value(buffer.data());
974 buffer = link->LType.ToUTF8();
975 if (buffer.data() && strlen(buffer.data()) > 0) {
976 child = child_link.append_child(
"type");
977 child.append_child(pugi::node_pcdata).set_value(buffer.data());
984 child = child_ext.append_child(
"opencpn:guid");
985 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_GUID.mb_str());
987 child = child_ext.append_child(
"opencpn:viz");
988 child.append_child(pugi::node_pcdata)
989 .set_value(pRoute->IsVisible() ==
true ?
"1" :
"0");
991 if (pRoute->ContainsSharedWP()) {
992 child = child_ext.append_child(
"opencpn:sharedWPviz");
993 child.append_child(pugi::node_pcdata)
994 .set_value(pRoute->GetSharedWPViz() ==
true ?
"1" :
"0");
1000 child = child_ext.append_child(
"opencpn:start");
1001 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1007 if (buffer.data()) {
1008 child = child_ext.append_child(
"opencpn:end");
1009 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1014 child = child_ext.append_child(
"opencpn:planned_speed");
1017 child.append_child(pugi::node_pcdata).set_value(s.mb_str());
1021 child = child_ext.append_child(
"opencpn:planned_departure");
1026 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
1029 child = child_ext.append_child(
"opencpn:time_display");
1030 child.append_child(pugi::node_pcdata)
1033 if (pRoute->
m_width != WIDTH_UNDEFINED ||
1034 pRoute->
m_style != wxPENSTYLE_INVALID) {
1035 child = child_ext.append_child(
"opencpn:style");
1037 if (pRoute->
m_width != WIDTH_UNDEFINED)
1038 child.append_attribute(
"width") = pRoute->
m_width;
1039 if (pRoute->
m_style != wxPENSTYLE_INVALID)
1040 child.append_attribute(
"style") = pRoute->
m_style;
1043 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:RouteExtension");
1044 child = gpxx_ext.append_child(
"gpxx:IsAutoNamed");
1045 child.append_child(pugi::node_pcdata).set_value(
"false");
1048 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
1049 child.append_child(pugi::node_pcdata).set_value(pRoute->
m_Colour.mb_str());
1054 GPXCreateWpt(node.append_child(
"rtept"), prp, OPT_ROUTEPT);
1060 if (!pTentRoute)
return false;
1062 bool bAddroute =
true;
1064 if (pTentRoute->GetnPoints() < 2) bAddroute =
false;
1072 pTentRoute->FinalizeForRendering();
1077 float prev_rlat = 0., prev_rlon = 0.;
1080 for (
RoutePoint *prp : *pTentRoute->pRoutePointList) {
1082 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1083 prp->m_lon, prev_pConfPoint, prp,
1085 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1086 prev_rlat = prp->m_lat;
1087 prev_rlon = prp->m_lon;
1088 prev_pConfPoint = prp;
1094 for (
RoutePoint *prp : *pTentRoute->pRoutePointList) {
1097 if (pcontainer_route == NULL) {
1099 prp->m_bIsInRoute =
false;
1100 if (!prp->IsShared()) {
1113bool InsertTrack(
Track *pTentTrack,
bool bApplyChanges) {
1114 if (!pTentTrack)
return false;
1116 bool bAddtrack =
true;
1119 if (!bApplyChanges && pTentTrack->GetnPoints() < 2) bAddtrack =
false;
1131 float prev_rlat = 0., prev_rlon = 0.;
1134 for (
int i = 0; i < pTentTrack->GetnPoints(); i++) {
1138 pSelect->AddSelectableTrackSegment(prev_rlat, prev_rlon, prp->m_lat,
1139 prp->m_lon, prev_pConfPoint, prp,
1142 prev_rlat = prp->m_lat;
1143 prev_rlon = prp->m_lon;
1144 prev_pConfPoint = prp;
1152bool InsertWpt(
RoutePoint *pWp,
bool overwrite) {
1155 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1156 if (!pExisting || overwrite) {
1157 if (NULL != pWayPointMan) {
1159 pWayPointMan->DestroyWaypoint(pExisting);
1164 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1170 if (!pTentRoute)
return;
1171 if (pTentRoute->GetnPoints() < 2)
return;
1174 Route *pExisting = ::RouteExists(pTentRoute->
m_GUID);
1188 pChangeRoute->SetVisible(pTentRoute->IsVisible());
1192 float prev_rlat = 0., prev_rlon = 0.;
1195 for (
RoutePoint *prp : *pTentRoute->pRoutePointList) {
1198 RoutePoint *ex_rp = ::WaypointExists(prp->m_GUID);
1200 pSelect->DeleteSelectableRoutePoint(ex_rp);
1201 ex_rp->m_lat = prp->m_lat;
1202 ex_rp->m_lon = prp->m_lon;
1203 ex_rp->SetIconName(prp->GetIconName());
1205 ex_rp->SetName(prp->GetName());
1207 ex_rp->SetPlannedSpeed(prp->GetPlannedSpeed());
1208 pChangeRoute->AddPoint(ex_rp);
1209 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, ex_rp);
1212 pChangeRoute->AddPoint(prp);
1213 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1218 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1219 prp->m_lon, prev_pConfPoint, prp,
1221 prev_rlat = prp->m_lat;
1222 prev_rlon = prp->m_lon;
1223 prev_pConfPoint = prp;
1228 pChangeRoute->FinalizeForRendering();
1233 for (
RoutePoint *prp : *proute->pRoutePointList) {
1234 if (prp == pWP)
return proute;
1241bool NavObjectCollection1::CreateNavObjGPXPoints() {
1246 if (!pWayPointMan)
return false;
1248 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1254 GPXCreateWpt(new_node, pr, OPT_WPT);
1261bool NavObjectCollection1::CreateNavObjGPXRoutes() {
1270 GPXCreateRoute(new_node, pRoute);
1277bool NavObjectCollection1::CreateNavObjGPXTracks() {
1280 if (pTrack->GetnPoints()) {
1281 if (!pTrack->m_bIsInLayer && !pTrack->m_btemp) {
1286 GPXCreateTrk(new_node, pTrack, 0);
1294bool NavObjectCollection1::CreateAllGPXObjects() {
1304bool NavObjectCollection1::AddGPXRoute(
Route *pRoute) {
1310 GPXCreateRoute(new_node, pRoute);
1314bool NavObjectCollection1::AddGPXTrack(
Track *pTrk) {
1320 GPXCreateTrk(new_node, pTrk, 0);
1324bool NavObjectCollection1::AddGPXWaypoint(
RoutePoint *pWP) {
1330 GPXCreateWpt(new_node, pWP, OPT_WPT);
1334void NavObjectCollection1::AddGPXRoutesList(RouteList *pRoutes) {
1337 for (
Route *pRData : *pRoutes) {
1338 AddGPXRoute(pRData);
1342void NavObjectCollection1::AddGPXTracksList(std::vector<Track *> *pTracks) {
1345 for (
Track *pRData : *pTracks) {
1346 AddGPXTrack(pRData);
1350bool NavObjectCollection1::AddGPXPointsList(RoutePointList *pRoutePoints) {
1354 AddGPXWaypoint(pRP);
1360void NavObjectCollection1::SetRootGPXNode() {
1361 if (!strlen(first_child().name())) {
1363 gpx_root.append_attribute(
"version") =
"1.1";
1364 gpx_root.append_attribute(
"creator") =
"OpenCPN";
1365 gpx_root.append_attribute(
"xmlns:xsi") =
1366 "http://www.w3.org/2001/XMLSchema-instance";
1367 gpx_root.append_attribute(
"xmlns") =
"http://www.topografix.com/GPX/1/1";
1368 gpx_root.append_attribute(
"xmlns:gpxx") =
1369 "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
1370 gpx_root.append_attribute(
"xsi:schemaLocation") =
1371 "http://www.topografix.com/GPX/1/1 "
1372 "http://www.topografix.com/GPX/1/1/gpx.xsd "
1373 "http://www.garmin.com/xmlschemas/GpxExtensions/v3 "
1374 "http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd";
1375 gpx_root.append_attribute(
"xmlns:opencpn") =
"http://www.opencpn.org";
1379bool NavObjectCollection1::IsOpenCPN() {
1381 attr = attr.next_attribute())
1382 if (!strcmp(attr.name(),
"creator") && !strcmp(attr.value(),
"OpenCPN"))
1387bool NavObjectCollection1::SaveFile(
const wxString filename) {
1388 wxString tmp_filename = filename +
".tmp";
1389 if (wxFileExists(tmp_filename)) {
1390 wxRemoveFile(tmp_filename);
1392 save_file(tmp_filename.fn_str(),
" ");
1393 wxRenameFile(tmp_filename.fn_str(), filename.fn_str(),
true);
1397bool NavObjectCollection1::LoadAllGPXObjects(
bool b_full_viz,
1398 int &wpt_duplicates,
1399 bool b_compute_bbox) {
1404 object =
object.next_sibling()) {
1405 if (!strcmp(
object.name(),
"wpt")) {
1407 ::GPXLoadWaypoint1(
object,
"circle",
"", b_full_viz,
false,
false, 0);
1411 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1414 NavObj_dB::GetInstance().InsertRoutePoint(pWp);
1415 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1417 wptbox.Set(pWp->m_lat, pWp->m_lon, pWp->m_lat, pWp->m_lon);
1418 BBox.Expand(wptbox);
1423 }
else if (!strcmp(
object.name(),
"trk")) {
1424 Track *pTrack = GPXLoadTrack1(
object, b_full_viz,
false,
false, 0);
1425 if (InsertTrack(pTrack)) {
1426 NavObj_dB::GetInstance().InsertTrack(pTrack);
1428 }
else if (!strcmp(
object.name(),
"rte")) {
1429 Route *pRoute = GPXLoadRoute1(
object, b_full_viz,
false,
false, 0,
false);
1430 if (InsertRouteA(pRoute,
this)) {
1431 NavObj_dB::GetInstance().InsertRoute(pRoute);
1432 if (b_compute_bbox && pRoute->IsVisible())
1433 BBox.Expand(pRoute->GetBBox());
1441int NavObjectCollection1::LoadAllGPXObjectsAsLayer(
int layer_id,
1443 wxCheckBoxState b_namesviz) {
1444 if (!pWayPointMan)
return 0;
1450 object =
object.next_sibling()) {
1451 if (!strcmp(
object.name(),
"wpt")) {
1452 RoutePoint *pWp = ::GPXLoadWaypoint1(
object,
"circle",
"",
1453 b_namesviz != wxCHK_UNDETERMINED,
1454 true, b_layerviz, layer_id);
1455 if (b_namesviz != wxCHK_UNDETERMINED) {
1456 pWp->SetNameShown(b_namesviz == wxCHK_CHECKED);
1460 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1463 if (!strcmp(
object.name(),
"trk")) {
1465 GPXLoadTrack1(
object,
false,
true, b_layerviz, layer_id);
1467 InsertTrack(pTrack);
1468 }
else if (!strcmp(
object.name(),
"rte")) {
1470 GPXLoadRoute1(
object,
true,
true, b_layerviz, layer_id,
false);
1472 InsertRouteA(pRoute,
this);
1480bool NavObjectCollection1::LoadAllGPXTrackObjects() {
1484 object =
object.next_sibling()) {
1485 if (!strcmp(
object.name(),
"trk")) {
1486 Track *pTrack = GPXLoadTrack1(
object,
true,
false,
false, 0);
1487 InsertTrack(pTrack);
1494bool NavObjectCollection1::LoadAllGPXRouteObjects() {
1498 object =
object.next_sibling()) {
1499 if (!strcmp(
object.name(),
"rte")) {
1500 Route *route = GPXLoadRoute1(
object,
true,
false,
false, 0,
false,
true);
1501 InsertRouteA(route,
nullptr);
1508bool NavObjectCollection1::LoadAllGPXPointObjects() {
1512 object =
object.next_sibling()) {
1513 if (!strcmp(
object.name(),
"wpt")) {
1515 GPXLoadWaypoint1(
object,
"circle",
"",
false,
false,
false, 0);
1523RoutePoint *WaypointExists(
const wxString &name,
double lat,
double lon) {
1526 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1527 if (name == pr->GetName()) {
1528 if (fabs(lat - pr->m_lat) < 1.e-6 && fabs(lon - pr->m_lon) < 1.e-6) {
1538RoutePoint *WaypointExists(
const wxString &guid) {
1539 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1540 if (guid == pr->
m_GUID) {
1548 bool IsInList =
false;
1553 if (pr->IsSame(prp)) {
1562Route *RouteExists(
const wxString &guid) {
1564 if (guid == proute->m_GUID)
return proute;
1571 if (proute->IsEqualTo(pTentRoute))
return proute;
1576Track *TrackExists(
const wxString &guid) {
1578 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.
MySQL based storage for routes, tracks, etc.
const wxChar * ParseGPXDateTime(wxDateTime &dt, const wxChar *datetime)
This function parses a string containing a GPX time representation and returns a wxDateTime containin...
Navigation Utility Functions without GUI dependencies.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.