26#include "nav_object_database.h"
28#include "navutil_base.h"
29#include "nav_object_database.h"
41extern RouteList *pRouteList;
42extern std::vector<Track*> g_TrackList;
45NavObjectCollection1::NavObjectCollection1()
46 : pugi::xml_document(), m_bSkipChangeSetUpdate(false) {}
48NavObjectCollection1::~NavObjectCollection1() {}
50RoutePoint *GPXLoadWaypoint1(pugi::xml_node &wpt_node,
51 wxString def_symbol_name, wxString GUID,
52 bool b_fullviz,
bool b_layer,
53 bool b_layerviz,
int layer_id) {
55 bool bviz_name =
false;
56 bool bauto_name =
false;
58 bool b_propvizname =
false;
59 bool b_propviz =
false;
61 wxString SymString = def_symbol_name;
65 double plan_speed = 0.0;
68 wxString GuidString = GUID;
73 HyperlinkList *linklist = NULL;
75 double rlat = wpt_node.attribute(
"lat").as_double();
76 double rlon = wpt_node.attribute(
"lon").as_double();
77 double ArrivalRadius = 0;
78 int l_iWaypointRangeRingsNumber = -1;
79 float l_fWaypointRangeRingsStep = -1;
80 int l_pWaypointRangeRingsStepUnits = -1;
81 bool l_bWaypointRangeRingsVisible =
false;
82 long l_iWaypointScaleMin = 2147483646;
83 long l_iWaypoinScaleMax = 0;
84 bool l_bWaypointUseScale =
false;
85 wxColour l_wxcWaypointRangeRingsColour;
86 l_wxcWaypointRangeRingsColour.Set(_T(
"#FFFFFF" ));
88 for (pugi::xml_node child = wpt_node.first_child(); child != 0;
89 child = child.next_sibling()) {
90 const char *pcn = child.name();
92 if (!strcmp(pcn,
"sym")) {
93 SymString = wxString::FromUTF8(child.first_child().value());
94 }
else if (!strcmp(pcn,
"time"))
95 TimeString = wxString::FromUTF8(child.first_child().value());
97 else if (!strcmp(pcn,
"name")) {
98 NameString = wxString::FromUTF8(child.first_child().value());
99 if (NameString.StartsWith(
"@~~")) {
103 TideStation = NameString.Right(NameString.length() - 3);
104 NameString.Replace(
"@~~",
"@-~");
108 else if (!strcmp(pcn,
"desc")) {
109 DescString = wxString::FromUTF8(child.first_child().value());
112 else if (!strcmp(pcn,
"type")) {
113 TypeString = wxString::FromUTF8(child.first_child().value());
117 if (!strcmp(pcn,
"link")) {
119 wxString HrefTextString;
120 wxString HrefTypeString;
121 if (linklist == NULL) linklist =
new HyperlinkList;
122 HrefString = wxString::FromUTF8(child.first_attribute().value());
124 for (pugi::xml_node child1 = child.first_child(); child1;
125 child1 = child1.next_sibling()) {
126 wxString LinkString = wxString::FromUTF8(child1.name());
128 if (LinkString == _T (
"text" ))
129 HrefTextString = wxString::FromUTF8(child1.first_child().value());
130 if (LinkString == _T (
"type" ))
131 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
135 link->Link = HrefString;
136 link->DescrText = HrefTextString;
137 link->LType = HrefTypeString;
138 linklist->Append(link);
142 else if (!strcmp(pcn,
"extensions")) {
143 for (pugi::xml_node ext_child = child.first_child(); ext_child;
144 ext_child = ext_child.next_sibling()) {
145 wxString ext_name = wxString::FromUTF8(ext_child.name());
146 if (ext_name == _T (
"opencpn:guid" )) {
147 GuidString = wxString::FromUTF8(ext_child.first_child().value());
148 }
else if (ext_name == _T (
"opencpn:viz" )) {
150 wxString s = wxString::FromUTF8(ext_child.first_child().value());
152 if (s.ToLong(&v)) bviz = (v != 0);
153 }
else if (ext_name == _T (
"opencpn:viz_name" )) {
154 b_propvizname =
true;
155 wxString s = wxString::FromUTF8(ext_child.first_child().value());
157 if (s.ToLong(&v)) bviz_name = (v != 0);
158 }
else if (ext_name == _T (
"opencpn:auto_name" )) {
159 wxString s = wxString::FromUTF8(ext_child.first_child().value());
161 if (s.ToLong(&v)) bauto_name = (v != 0);
162 }
else if (ext_name == _T (
"opencpn:shared" )) {
163 wxString s = wxString::FromUTF8(ext_child.first_child().value());
165 if (s.ToLong(&v)) bshared = (v != 0);
167 if (ext_name == _T (
"opencpn:arrival_radius" )) {
168 wxString::FromUTF8(ext_child.first_child().value())
169 .ToDouble(&ArrivalRadius);
171 if (ext_name == _T(
"opencpn:waypoint_range_rings")) {
172 for (pugi::xml_attribute attr = ext_child.first_attribute(); attr;
173 attr = attr.next_attribute()) {
174 if (wxString::FromUTF8(attr.name()) == _T(
"number"))
175 l_iWaypointRangeRingsNumber = attr.as_int();
176 else if (wxString::FromUTF8(attr.name()) == _T(
"step"))
177 l_fWaypointRangeRingsStep = attr.as_float();
178 else if (wxString::FromUTF8(attr.name()) == _T(
"units"))
179 l_pWaypointRangeRingsStepUnits = attr.as_int();
180 else if (wxString::FromUTF8(attr.name()) == _T(
"visible"))
181 l_bWaypointRangeRingsVisible = attr.as_bool();
182 else if (wxString::FromUTF8(attr.name()) == _T(
"colour"))
183 l_wxcWaypointRangeRingsColour.Set(
184 wxString::FromUTF8(attr.as_string()));
187 if (ext_name == _T(
"opencpn:scale_min_max")) {
188 for (pugi::xml_attribute attr = ext_child.first_attribute(); attr;
189 attr = attr.next_attribute()) {
190 if (wxString::FromUTF8(attr.name()) == _T(
"UseScale"))
191 l_bWaypointUseScale = attr.as_bool();
192 else if (wxString::FromUTF8(attr.name()) == _T(
"ScaleMin"))
193 l_iWaypointScaleMin = attr.as_int();
194 else if (wxString::FromUTF8(attr.name()) == _T(
"ScaleMax"))
195 l_iWaypoinScaleMax = attr.as_float();
198 if (ext_name == _T (
"opencpn:tidestation" )) {
199 TideStation = wxString::FromUTF8(ext_child.first_child().value());
201 if (ext_name == _T (
"opencpn:rte_properties" )) {
202 for (pugi::xml_attribute attr = ext_child.first_attribute(); attr;
203 attr = attr.next_attribute()) {
204 if (!strcmp(attr.name(),
"planned_speed"))
205 plan_speed = attr.as_double();
206 else if (!strcmp(attr.name(),
"etd"))
207 etd = attr.as_string();
217 if (GuidString.IsEmpty()) GuidString = pWayPointMan->CreateGUID(NULL);
220 pWP =
new RoutePoint(rlat, rlon, SymString, NameString, GuidString,
222 pWP->m_MarkDescription = DescString;
223 pWP->m_TideStation = TideStation;
224 pWP->m_bIsolatedMark = bshared;
225 pWP->SetWaypointArrivalRadius(ArrivalRadius);
226 pWP->SetWaypointRangeRingsNumber(l_iWaypointRangeRingsNumber);
227 pWP->SetWaypointRangeRingsStep(l_fWaypointRangeRingsStep);
228 pWP->SetWaypointRangeRingsStepUnits(l_pWaypointRangeRingsStepUnits);
229 pWP->SetShowWaypointRangeRings(l_bWaypointRangeRingsVisible);
235 if (!l_bWaypointRangeRingsVisible) pWP->SetWaypointRangeRingsNumber(0);
237 pWP->SetWaypointRangeRingsColour(l_wxcWaypointRangeRingsColour);
238 pWP->SetScaMin(l_iWaypointScaleMin);
239 pWP->SetScaMax(l_iWaypoinScaleMax);
240 pWP->SetUseSca(l_bWaypointUseScale);
241 pWP->SetPlannedSpeed(plan_speed);
244 pWP->m_bShowNameData = bviz_name;
246 pWP->m_bShowName = bviz_name;
248 pWP->m_bShowName =
true;
250 pWP->m_bShowName =
false;
253 pWP->m_bIsVisible = bviz;
255 pWP->m_bIsVisible =
true;
258 pWP->m_bIsInLayer =
true;
259 pWP->m_LayerID = layer_id;
260 pWP->m_bIsVisible = b_layerviz;
261 pWP->SetListed(
false);
264 pWP->SetShared(bshared);
265 pWP->m_bDynamicName = bauto_name;
267 if (TimeString.Len()) {
268 pWP->m_timestring = TimeString;
269 pWP->SetCreateTime(wxInvalidDateTime);
273 delete pWP->m_HyperlinkList;
274 pWP->m_HyperlinkList = linklist;
280static TrackPoint *GPXLoadTrackPoint1(pugi::xml_node &wpt_node) {
283 double rlat = wpt_node.attribute(
"lat").as_double();
284 double rlon = wpt_node.attribute(
"lon").as_double();
286 for (pugi::xml_node child = wpt_node.first_child(); child != 0;
287 child = child.next_sibling()) {
288 const char *pcn = child.name();
289 if (!strcmp(pcn,
"time"))
290 TimeString = wxString::FromUTF8(child.first_child().value());
293 else if (!strcmp(pcn,
"extensions")) {
294 for (pugi::xml_node ext_child = child.first_child(); ext_child;
295 ext_child = ext_child.next_sibling()) {
296 wxString ext_name = wxString::FromUTF8(ext_child.name());
297 if (ext_name == _T (
"opencpn:action" )) {
304 return new TrackPoint(rlat, rlon, TimeString);
307Track *GPXLoadTrack1(pugi::xml_node &trk_node,
bool b_fullviz,
308 bool b_layer,
bool b_layerviz,
int layer_id) {
311 unsigned short int GPXSeg;
312 bool b_propviz =
false;
314 Track *pTentTrack = NULL;
315 HyperlinkList *linklist = NULL;
317 wxString Name = wxString::FromUTF8(trk_node.name());
318 if (Name == _T (
"trk" )) {
319 pTentTrack =
new Track();
324 for (pugi::xml_node tschild = trk_node.first_child(); tschild;
325 tschild = tschild.next_sibling()) {
326 wxString ChildName = wxString::FromUTF8(tschild.name());
327 if (ChildName == _T (
"trkseg" )) {
331 for (pugi::xml_node tpchild = tschild.first_child(); tpchild;
332 tpchild = tpchild.next_sibling()) {
333 wxString tpChildName = wxString::FromUTF8(tpchild.name());
334 if (tpChildName == _T(
"trkpt")) {
335 pWp = ::GPXLoadTrackPoint1(tpchild);
337 pTentTrack->AddPoint(pWp);
338 pWp->m_GPXTrkSegNo = GPXSeg;
342 }
else if (ChildName == _T (
"name" ))
343 TrackName = wxString::FromUTF8(tschild.first_child().value());
344 else if (ChildName == _T (
"desc" ))
345 DescString = wxString::FromUTF8(tschild.first_child().value());
348 if (ChildName == _T (
"link")) {
350 wxString HrefTextString;
351 wxString HrefTypeString;
352 if (linklist == NULL) linklist =
new HyperlinkList;
353 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
355 for (pugi::xml_node child1 = tschild.first_child(); child1;
356 child1 = child1.next_sibling()) {
357 wxString LinkString = wxString::FromUTF8(child1.name());
359 if (LinkString == _T (
"text" ))
360 HrefTextString = wxString::FromUTF8(child1.first_child().value());
361 if (LinkString == _T (
"type" ))
362 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
366 link->Link = HrefString;
367 link->DescrText = HrefTextString;
368 link->LType = HrefTypeString;
369 linklist->Append(link);
372 else if (ChildName == _T (
"extensions" )) {
373 for (pugi::xml_node ext_child = tschild.first_child(); ext_child;
374 ext_child = ext_child.next_sibling()) {
375 wxString ext_name = wxString::FromUTF8(ext_child.name());
376 if (ext_name == _T (
"opencpn:start" )) {
377 pTentTrack->m_TrackStartString =
378 wxString::FromUTF8(ext_child.first_child().value());
379 }
else if (ext_name == _T (
"opencpn:end" )) {
380 pTentTrack->m_TrackEndString =
381 wxString::FromUTF8(ext_child.first_child().value());
384 else if (ext_name == _T (
"opencpn:viz" )) {
385 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
387 b_viz = (viz == _T(
"1"));
388 }
else if (ext_name == _T (
"opencpn:style" )) {
389 for (pugi::xml_attribute attr = ext_child.first_attribute(); attr;
390 attr = attr.next_attribute()) {
391 if (!strcmp(attr.name(),
"style"))
392 pTentTrack->m_style = (wxPenStyle)attr.as_int();
393 else if (!strcmp(attr.name(),
"width"))
394 pTentTrack->m_width = attr.as_int();
398 else if (ext_name == _T (
"opencpn:guid" )) {
400 wxString::FromUTF8(ext_child.first_child().value());
403 else if (ext_name.EndsWith(
404 _T (
"TrackExtension" )))
406 for (pugi::xml_node gpxx_child = ext_child.first_child();
407 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
408 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
409 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
410 pTentTrack->m_Colour =
411 wxString::FromUTF8(gpxx_child.first_child().value());
418 pTentTrack->SetName(TrackName);
419 pTentTrack->m_TrackDescription = DescString;
422 pTentTrack->SetVisible(b_viz);
424 if (b_fullviz) pTentTrack->SetVisible();
428 pTentTrack->SetVisible(b_layerviz);
429 pTentTrack->m_bIsInLayer =
true;
430 pTentTrack->m_LayerID = layer_id;
431 pTentTrack->SetListed(
false);
434 pTentTrack->SetCurrentTrackSeg(GPXSeg);
438 delete pTentTrack->m_HyperlinkList;
439 pTentTrack->m_HyperlinkList = linklist;
445Route *GPXLoadRoute1(pugi::xml_node &wpt_node,
bool b_fullviz,
446 bool b_layer,
bool b_layerviz,
int layer_id,
450 bool b_propviz =
false;
451 bool b_propSWPviz =
false;
454 Route *pTentRoute = NULL;
456 wxString Name = wxString::FromUTF8(wpt_node.name());
457 if (Name == _T (
"rte" )) {
458 pTentRoute =
new Route();
459 HyperlinkList *linklist = NULL;
462 bool route_existing =
false;
463 pTentRoute->m_TimeDisplayFormat = RTE_TIME_DISP_UTC;
465 for (pugi::xml_node tschild = wpt_node.first_child(); tschild;
466 tschild = tschild.next_sibling()) {
467 wxString ChildName = wxString::FromUTF8(tschild.name());
470 if (ChildName == _T (
"extensions" )) {
471 for (pugi::xml_node ext_child = tschild.first_child(); ext_child;
472 ext_child = ext_child.next_sibling()) {
473 wxString ext_name = wxString::FromUTF8(ext_child.name());
475 if (ext_name == _T (
"opencpn:start" )) {
476 pTentRoute->m_RouteStartString =
477 wxString::FromUTF8(ext_child.first_child().value());
478 }
else if (ext_name == _T (
"opencpn:end" )) {
479 pTentRoute->m_RouteEndString =
480 wxString::FromUTF8(ext_child.first_child().value());
483 else if (ext_name == _T (
"opencpn:viz" )) {
484 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
486 b_viz = (viz == _T(
"1"));
489 else if (ext_name == _T (
"opencpn:sharedWPviz" )) {
490 wxString viz = wxString::FromUTF8(ext_child.first_child().value());
492 swpViz = (viz == _T(
"1"));
493 }
else if (ext_name == _T (
"opencpn:style" )) {
494 for (pugi::xml_attribute attr = ext_child.first_attribute(); attr;
495 attr = attr.next_attribute()) {
496 if (!strcmp(attr.name(),
"style"))
497 pTentRoute->m_style = (wxPenStyle)attr.as_int();
498 else if (!strcmp(attr.name(),
"width"))
499 pTentRoute->m_width = attr.as_int();
503 else if (ext_name == _T (
"opencpn:guid" )) {
506 wxString::FromUTF8(ext_child.first_child().value());
509 else if (ext_name == _T (
"opencpn:planned_speed" )) {
510 pTentRoute->m_PlannedSpeed = atof(ext_child.first_child().value());
513 else if (ext_name == _T (
"opencpn:planned_departure" )) {
515 pTentRoute->m_PlannedDeparture,
516 wxString::FromUTF8(ext_child.first_child().value()));
519 else if (ext_name == _T (
"opencpn:time_display" )) {
520 pTentRoute->m_TimeDisplayFormat =
521 wxString::FromUTF8(ext_child.first_child().value());
522 }
else if (ext_name.EndsWith(
523 _T (
"RouteExtension" )))
525 for (pugi::xml_node gpxx_child = ext_child.first_child();
526 gpxx_child; gpxx_child = gpxx_child.next_sibling()) {
527 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
528 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
529 pTentRoute->m_Colour =
530 wxString::FromUTF8(gpxx_child.first_child().value());
535 if (RouteExists(pTentRoute->m_GUID)) {
538 pTentRoute->m_GUID = pWayPointMan->CreateGUID(NULL);
539 route_existing =
true;
543 else if (ChildName == _T (
"rtept" )) {
545 ::GPXLoadWaypoint1(tschild, _T(
"square"), _T(
""), b_fullviz,
546 b_layer, b_layerviz, layer_id);
548 if (!b_layer) erp = ::WaypointExists(tpWp->m_GUID);
562 (!route_existing || (route_existing && tpWp->IsShared()))) {
566 if (route_existing) tpWp->m_GUID = pWayPointMan->CreateGUID(NULL);
571 pTentRoute->AddPoint(pWp,
false,
true);
572 pWp->m_bIsInRoute =
true;
576 pWayPointMan->AddRoutePoint(pWp);
580 }
else if (ChildName == _T (
"name" )) {
581 RouteName = wxString::FromUTF8(tschild.first_child().value());
582 }
else if (ChildName == _T (
"desc" )) {
583 DescString = wxString::FromUTF8(tschild.first_child().value());
586 if (ChildName == _T (
"link")) {
588 wxString HrefTextString;
589 wxString HrefTypeString;
590 if (linklist == NULL) linklist =
new HyperlinkList;
591 HrefString = wxString::FromUTF8(tschild.first_attribute().value());
593 for (pugi::xml_node child1 = tschild.first_child(); child1;
594 child1 = child1.next_sibling()) {
595 wxString LinkString = wxString::FromUTF8(child1.name());
597 if (LinkString == _T (
"text" ))
598 HrefTextString = wxString::FromUTF8(child1.first_child().value());
599 if (LinkString == _T (
"type" ))
600 HrefTypeString = wxString::FromUTF8(child1.first_child().value());
604 link->Link = HrefString;
605 link->DescrText = HrefTextString;
606 link->LType = HrefTypeString;
607 linklist->Append(link);
613 if (ChildName.EndsWith(_T (
"RouteExtension" )))
615 for (pugi::xml_node gpxx_child = tschild.first_child(); gpxx_child;
616 gpxx_child = gpxx_child.next_sibling()) {
617 wxString gpxx_name = wxString::FromUTF8(gpxx_child.name());
618 if (gpxx_name.EndsWith(_T (
"DisplayColor" )))
619 pTentRoute->m_Colour =
620 wxString::FromUTF8(gpxx_child.first_child().value());
625 pTentRoute->m_RouteNameString = RouteName;
626 pTentRoute->m_RouteDescription = DescString;
628 pTentRoute->m_HyperlinkList = linklist;
632 pTentRoute->SetVisible(b_viz);
633 }
else if (b_fullviz) {
634 pTentRoute->SetVisible();
637 if (b_propSWPviz) pTentRoute->SetSharedWPViz(swpViz);
640 pTentRoute->SetVisible(b_layerviz);
641 pTentRoute->m_bIsInLayer =
true;
642 pTentRoute->m_LayerID = layer_id;
643 pTentRoute->SetListed(
false);
650static bool GPXCreateWpt(pugi::xml_node node,
RoutePoint *pr,
651 unsigned int flags) {
653 pugi::xml_node child;
654 pugi::xml_attribute attr;
656 s.Printf(_T(
"%.9f"), pr->m_lat);
657 node.append_attribute(
"lat") = s.mb_str();
658 s.Printf(_T(
"%.9f"), pr->m_lon);
659 node.append_attribute(
"lon") = s.mb_str();
661 if (flags & OUT_TIME) {
662 child = node.append_child(
"time");
663 if (pr->m_timestring.Len())
664 child.append_child(pugi::node_pcdata)
665 .set_value(pr->m_timestring.mb_str());
667 wxDateTime dt = pr->GetCreateTime();
669 dt = wxDateTime::Now();
671 wxString t = dt.FormatISODate()
673 .Append(dt.FormatISOTime())
675 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
679 if ((!pr->GetName().IsEmpty() && (flags & OUT_NAME)) ||
680 (flags & OUT_NAME_FORCE)) {
681 wxCharBuffer buffer = pr->GetName().ToUTF8();
683 child = node.append_child(
"name");
684 child.append_child(pugi::node_pcdata).set_value(buffer.data());
688 if ((!pr->GetDescription().IsEmpty() && (flags & OUT_DESC)) ||
689 (flags & OUT_DESC_FORCE)) {
690 wxCharBuffer buffer = pr->GetDescription().ToUTF8();
692 child = node.append_child(
"desc");
693 child.append_child(pugi::node_pcdata).set_value(buffer.data());
698 if (flags & OUT_HYPERLINKS) {
699 HyperlinkList *linklist = pr->m_HyperlinkList;
700 if (linklist && linklist->GetCount()) {
701 wxHyperlinkListNode *linknode = linklist->GetFirst();
705 pugi::xml_node child_link = node.append_child(
"link");
707 wxCharBuffer buffer = link->Link.ToUTF8();
708 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
710 buffer = link->DescrText.ToUTF8();
712 child = child_link.append_child(
"text");
713 child.append_child(pugi::node_pcdata).set_value(buffer.data());
716 buffer = link->LType.ToUTF8();
717 if (buffer.data() && strlen(buffer.data()) > 0) {
718 child = child_link.append_child(
"type");
719 child.append_child(pugi::node_pcdata).set_value(buffer.data());
722 linknode = linknode->GetNext();
727 if (flags & OUT_SYM_FORCE) {
728 child = node.append_child(
"sym");
729 if (!pr->GetIconName().IsEmpty()) {
730 child.append_child(pugi::node_pcdata)
731 .set_value(pr->GetIconName().mb_str());
733 child.append_child(
"empty");
737 if (flags & OUT_TYPE) {
738 child = node.append_child(
"type");
739 child.append_child(pugi::node_pcdata).set_value(
"WPT");
742 if ((flags & OUT_GUID) || (flags & OUT_VIZ) || (flags & OUT_VIZ_NAME) ||
743 (flags & OUT_SHARED) || (flags & OUT_AUTO_NAME) ||
744 (flags & OUT_EXTENSION) || (flags & OUT_TIDE_STATION) ||
745 (flags & OUT_RTE_PROPERTIES)) {
746 pugi::xml_node child_ext = node.append_child(
"extensions");
748 if (!pr->m_GUID.IsEmpty() && (flags & OUT_GUID)) {
749 child = child_ext.append_child(
"opencpn:guid");
750 child.append_child(pugi::node_pcdata).set_value(pr->m_GUID.mb_str());
753 if ((flags & OUT_VIZ) && !pr->m_bIsVisible) {
754 child = child_ext.append_child(
"opencpn:viz");
755 child.append_child(pugi::node_pcdata).set_value(
"0");
758 if ((flags & OUT_VIZ_NAME) && pr->m_bShowName) {
759 child = child_ext.append_child(
"opencpn:viz_name");
760 child.append_child(pugi::node_pcdata).set_value(
"1");
763 if ((flags & OUT_AUTO_NAME) && pr->m_bDynamicName) {
764 child = child_ext.append_child(
"opencpn:auto_name");
765 child.append_child(pugi::node_pcdata).set_value(
"1");
767 if ((flags & OUT_SHARED) && pr->IsShared()) {
768 child = child_ext.append_child(
"opencpn:shared");
769 child.append_child(pugi::node_pcdata).set_value(
"1");
771 if (flags & OUT_ARRIVAL_RADIUS) {
772 child = child_ext.append_child(
"opencpn:arrival_radius");
773 s.Printf(_T(
"%.3f"), pr->GetWaypointArrivalRadius());
774 child.append_child(pugi::node_pcdata).set_value(s.mbc_str());
776 if (flags & OUT_WAYPOINT_RANGE_RINGS) {
777 child = child_ext.append_child(
"opencpn:waypoint_range_rings");
778 pugi::xml_attribute viz = child.append_attribute(
"visible");
779 viz.set_value(pr->m_bShowWaypointRangeRings);
780 pugi::xml_attribute number = child.append_attribute(
"number");
781 number.set_value(pr->m_iWaypointRangeRingsNumber);
782 pugi::xml_attribute step = child.append_attribute(
"step");
783 step.set_value(pr->m_fWaypointRangeRingsStep);
784 pugi::xml_attribute units = child.append_attribute(
"units");
785 units.set_value(pr->m_iWaypointRangeRingsStepUnits);
786 pugi::xml_attribute colour = child.append_attribute(
"colour");
788 pr->m_wxcWaypointRangeRingsColour.GetAsString(wxC2S_HTML_SYNTAX)
791 if (flags & OUT_WAYPOINT_SCALE) {
792 child = child_ext.append_child(
"opencpn:scale_min_max");
793 pugi::xml_attribute use = child.append_attribute(
"UseScale");
794 use.set_value(pr->GetUseSca());
795 pugi::xml_attribute sca = child.append_attribute(
"ScaleMin");
796 sca.set_value(pr->GetScaMin());
797 pugi::xml_attribute max = child.append_attribute(
"ScaleMax");
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)
803 .set_value(pr->m_TideStation.mb_str());
805 if ((flags & OUT_RTE_PROPERTIES) &&
806 (pr->GetPlannedSpeed() > 0.0001 || pr->m_manual_etd)) {
807 child = child_ext.append_child(
"opencpn:rte_properties");
808 if (pr->GetPlannedSpeed() > 0.0001) {
809 pugi::xml_attribute use = child.append_attribute(
"planned_speed");
811 wxString::Format(_T(
"%.1lf"), pr->GetPlannedSpeed()).mb_str());
813 if (pr->m_manual_etd) {
814 pugi::xml_attribute use = child.append_attribute(
"etd");
815 use.set_value(pr->GetManualETD().FormatISOCombined().mb_str());
823static bool GPXCreateTrkpt(pugi::xml_node node,
TrackPoint *pt,
824 unsigned int flags) {
826 pugi::xml_node child;
827 pugi::xml_attribute attr;
829 s.Printf(_T(
"%.9f"), pt->m_lat);
830 node.append_attribute(
"lat") = s.mb_str();
831 s.Printf(_T(
"%.9f"), pt->m_lon);
832 node.append_attribute(
"lon") = s.mb_str();
834 if (flags & OUT_TIME && pt->HasValidTimestamp()) {
835 child = node.append_child(
"time");
836 child.append_child(pugi::node_pcdata).set_value(pt->GetTimeString());
842static bool GPXCreateTrk(pugi::xml_node node,
Track *pTrack,
843 unsigned int flags) {
844 pugi::xml_node child;
846 if (pTrack->GetName().Len()) {
847 wxCharBuffer buffer = pTrack->GetName().ToUTF8();
849 child = node.append_child(
"name");
850 child.append_child(pugi::node_pcdata).set_value(buffer.data());
854 if (pTrack->m_TrackDescription.Len()) {
855 wxCharBuffer buffer = pTrack->m_TrackDescription.ToUTF8();
857 child = node.append_child(
"desc");
858 child.append_child(pugi::node_pcdata).set_value(buffer.data());
863 HyperlinkList *linklist = pTrack->m_HyperlinkList;
864 if (linklist && linklist->GetCount()) {
865 wxHyperlinkListNode *linknode = linklist->GetFirst();
869 pugi::xml_node child_link = node.append_child(
"link");
870 wxCharBuffer buffer = link->Link.ToUTF8();
871 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
873 buffer = link->DescrText.ToUTF8();
875 child = child_link.append_child(
"text");
876 child.append_child(pugi::node_pcdata).set_value(buffer.data());
879 buffer = link->LType.ToUTF8();
880 if (buffer.data() && strlen(buffer.data()) > 0) {
881 child = child_link.append_child(
"type");
882 child.append_child(pugi::node_pcdata).set_value(buffer.data());
885 linknode = linknode->GetNext();
889 pugi::xml_node child_ext = node.append_child(
"extensions");
891 child = child_ext.append_child(
"opencpn:guid");
892 child.append_child(pugi::node_pcdata).set_value(pTrack->m_GUID.mb_str());
894 child = child_ext.append_child(
"opencpn:viz");
895 child.append_child(pugi::node_pcdata)
896 .set_value(pTrack->IsVisible() ==
true ?
"1" :
"0");
898 if (pTrack->m_TrackStartString.Len()) {
899 wxCharBuffer buffer = pTrack->m_TrackStartString.ToUTF8();
901 child = child_ext.append_child(
"opencpn:start");
902 child.append_child(pugi::node_pcdata).set_value(buffer.data());
906 if (pTrack->m_TrackEndString.Len()) {
907 wxCharBuffer buffer = pTrack->m_TrackEndString.ToUTF8();
909 child = child_ext.append_child(
"opencpn:end");
910 child.append_child(pugi::node_pcdata).set_value(buffer.data());
914 if (pTrack->m_width != WIDTH_UNDEFINED ||
915 pTrack->m_style != wxPENSTYLE_INVALID) {
916 child = child_ext.append_child(
"opencpn:style");
918 if (pTrack->m_width != WIDTH_UNDEFINED)
919 child.append_attribute(
"width") = pTrack->m_width;
920 if (pTrack->m_style != wxPENSTYLE_INVALID)
921 child.append_attribute(
"style") = pTrack->m_style;
924 if (pTrack->m_Colour != wxEmptyString) {
925 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:TrackExtension");
926 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
927 child.append_child(pugi::node_pcdata).set_value(pTrack->m_Colour.mb_str());
930 if (flags & RT_OUT_NO_RTPTS)
return true;
935 unsigned short int GPXTrkSegNo1 = 1;
938 unsigned short int GPXTrkSegNo2 = GPXTrkSegNo1;
940 pugi::xml_node seg = node.append_child(
"trkseg");
942 while (node2 < pTrack->GetnPoints()) {
943 prp = pTrack->GetPoint(node2);
944 GPXTrkSegNo1 = prp->m_GPXTrkSegNo;
945 if (GPXTrkSegNo1 != GPXTrkSegNo2)
break;
947 GPXCreateTrkpt(seg.append_child(
"trkpt"), prp, OPT_TRACKPT);
951 }
while (node2 < pTrack->GetnPoints());
956static bool GPXCreateRoute(pugi::xml_node node,
Route *pRoute) {
957 pugi::xml_node child;
959 if (pRoute->m_RouteNameString.Len()) {
960 wxCharBuffer buffer = pRoute->m_RouteNameString.ToUTF8();
962 child = node.append_child(
"name");
963 child.append_child(pugi::node_pcdata).set_value(buffer.data());
967 if (pRoute->m_RouteDescription.Len()) {
968 wxCharBuffer buffer = pRoute->m_RouteDescription.ToUTF8();
970 child = node.append_child(
"desc");
971 child.append_child(pugi::node_pcdata).set_value(buffer.data());
976 HyperlinkList *linklist = pRoute->m_HyperlinkList;
977 if (linklist && linklist->GetCount()) {
978 wxHyperlinkListNode *linknode = linklist->GetFirst();
982 pugi::xml_node child_link = node.append_child(
"link");
983 wxCharBuffer buffer = link->Link.ToUTF8();
984 if (buffer.data()) child_link.append_attribute(
"href") = buffer.data();
986 buffer = link->DescrText.ToUTF8();
988 child = child_link.append_child(
"text");
989 child.append_child(pugi::node_pcdata).set_value(buffer.data());
992 buffer = link->LType.ToUTF8();
993 if (buffer.data() && strlen(buffer.data()) > 0) {
994 child = child_link.append_child(
"type");
995 child.append_child(pugi::node_pcdata).set_value(buffer.data());
998 linknode = linknode->GetNext();
1002 pugi::xml_node child_ext = node.append_child(
"extensions");
1004 child = child_ext.append_child(
"opencpn:guid");
1005 child.append_child(pugi::node_pcdata).set_value(pRoute->m_GUID.mb_str());
1007 child = child_ext.append_child(
"opencpn:viz");
1008 child.append_child(pugi::node_pcdata)
1009 .set_value(pRoute->IsVisible() ==
true ?
"1" :
"0");
1011 if (pRoute->ContainsSharedWP()) {
1012 child = child_ext.append_child(
"opencpn:sharedWPviz");
1013 child.append_child(pugi::node_pcdata)
1014 .set_value(pRoute->GetSharedWPViz() ==
true ?
"1" :
"0");
1017 if (pRoute->m_RouteStartString.Len()) {
1018 wxCharBuffer buffer = pRoute->m_RouteStartString.ToUTF8();
1019 if (buffer.data()) {
1020 child = child_ext.append_child(
"opencpn:start");
1021 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1025 if (pRoute->m_RouteEndString.Len()) {
1026 wxCharBuffer buffer = pRoute->m_RouteEndString.ToUTF8();
1027 if (buffer.data()) {
1028 child = child_ext.append_child(
"opencpn:end");
1029 child.append_child(pugi::node_pcdata).set_value(buffer.data());
1033 if (pRoute->m_PlannedSpeed != ROUTE_DEFAULT_SPEED) {
1034 child = child_ext.append_child(
"opencpn:planned_speed");
1036 s.Printf(_T(
"%.2f"), pRoute->m_PlannedSpeed);
1037 child.append_child(pugi::node_pcdata).set_value(s.mb_str());
1040 if (pRoute->m_PlannedDeparture.IsValid()) {
1041 child = child_ext.append_child(
"opencpn:planned_departure");
1042 wxString t = pRoute->m_PlannedDeparture.FormatISODate()
1044 .Append(pRoute->m_PlannedDeparture.FormatISOTime())
1046 child.append_child(pugi::node_pcdata).set_value(t.mb_str());
1049 child = child_ext.append_child(
"opencpn:time_display");
1050 child.append_child(pugi::node_pcdata)
1051 .set_value(pRoute->m_TimeDisplayFormat.mb_str());
1053 if (pRoute->m_width != WIDTH_UNDEFINED ||
1054 pRoute->m_style != wxPENSTYLE_INVALID) {
1055 child = child_ext.append_child(
"opencpn:style");
1057 if (pRoute->m_width != WIDTH_UNDEFINED)
1058 child.append_attribute(
"width") = pRoute->m_width;
1059 if (pRoute->m_style != wxPENSTYLE_INVALID)
1060 child.append_attribute(
"style") = pRoute->m_style;
1063 pugi::xml_node gpxx_ext = child_ext.append_child(
"gpxx:RouteExtension");
1064 child = gpxx_ext.append_child(
"gpxx:IsAutoNamed");
1065 child.append_child(pugi::node_pcdata).set_value(
"false");
1067 if (pRoute->m_Colour != wxEmptyString) {
1068 child = gpxx_ext.append_child(
"gpxx:DisplayColor");
1069 child.append_child(pugi::node_pcdata).set_value(pRoute->m_Colour.mb_str());
1072 RoutePointList *pRoutePointList = pRoute->pRoutePointList;
1073 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1077 prp = node2->GetData();
1079 GPXCreateWpt(node.append_child(
"rtept"), prp, OPT_ROUTEPT);
1081 node2 = node2->GetNext();
1088 if (!pTentRoute)
return false;
1090 bool bAddroute =
true;
1092 if (pTentRoute->GetnPoints() < 2) bAddroute =
false;
1097 pRouteList->Append(pTentRoute);
1100 pTentRoute->FinalizeForRendering();
1105 float prev_rlat = 0., prev_rlon = 0.;
1108 wxRoutePointListNode *node = pTentRoute->pRoutePointList->GetFirst();
1113 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1114 prp->m_lon, prev_pConfPoint, prp,
1116 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1117 prev_rlat = prp->m_lat;
1118 prev_rlon = prp->m_lon;
1119 prev_pConfPoint = prp;
1123 node = node->GetNext();
1127 wxRoutePointListNode *pnode = (pTentRoute->pRoutePointList)->GetFirst();
1132 Route *pcontainer_route = g_pRouteMan->FindRouteContainingWaypoint(prp);
1134 if (pcontainer_route == NULL) {
1137 if (!prp->IsShared()) {
1138 navobj->m_bSkipChangeSetUpdate =
true;
1139 NavObjectChanges::getInstance()->DeleteWayPoint(prp);
1140 navobj->m_bSkipChangeSetUpdate =
false;
1145 pnode = pnode->GetNext();
1153bool InsertTrack(
Track *pTentTrack,
bool bApplyChanges =
false) {
1154 if (!pTentTrack)
return false;
1156 bool bAddtrack =
true;
1159 if (!bApplyChanges && pTentTrack->GetnPoints() < 2) bAddtrack =
false;
1164 g_TrackList.push_back(pTentTrack);
1171 float prev_rlat = 0., prev_rlon = 0.;
1174 for (
int i = 0; i < pTentTrack->GetnPoints(); i++) {
1178 pSelect->AddSelectableTrackSegment(prev_rlat, prev_rlon, prp->m_lat,
1179 prp->m_lon, prev_pConfPoint, prp,
1182 prev_rlat = prp->m_lat;
1183 prev_rlon = prp->m_lon;
1184 prev_pConfPoint = prp;
1192bool InsertWpt(
RoutePoint *pWp,
bool overwrite) {
1195 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1196 if (!pExisting || overwrite) {
1197 if (NULL != pWayPointMan) {
1199 pWayPointMan->DestroyWaypoint(pExisting);
1201 pWayPointMan->AddRoutePoint(pWp);
1204 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1209static void UpdateRouteA(
Route* pTentRoute,
1212 if (!pTentRoute)
return;
1213 if (pTentRoute->GetnPoints() < 2)
return;
1216 Route *pExisting = ::RouteExists(pTentRoute->m_GUID);
1218 navobj->m_bSkipChangeSetUpdate =
true;
1219 g_pRouteMan->
DeleteRoute(pExisting, nav_obj_changes);
1220 navobj->m_bSkipChangeSetUpdate =
false;
1225 pRouteList->Append(pChangeRoute);
1228 pChangeRoute->m_GUID = pTentRoute->m_GUID;
1229 pChangeRoute->m_RouteNameString = pTentRoute->m_RouteNameString;
1230 pChangeRoute->m_RouteStartString = pTentRoute->m_RouteStartString;
1231 pChangeRoute->m_RouteEndString = pTentRoute->m_RouteEndString;
1232 pChangeRoute->SetVisible(pTentRoute->IsVisible());
1236 float prev_rlat = 0., prev_rlon = 0.;
1239 wxRoutePointListNode *node = pTentRoute->pRoutePointList->GetFirst();
1245 RoutePoint *ex_rp = ::WaypointExists(prp->m_GUID);
1247 pSelect->DeleteSelectableRoutePoint(ex_rp);
1248 ex_rp->m_lat = prp->m_lat;
1249 ex_rp->m_lon = prp->m_lon;
1250 ex_rp->SetIconName(prp->GetIconName());
1251 ex_rp->m_MarkDescription = prp->m_MarkDescription;
1252 ex_rp->SetName(prp->GetName());
1253 ex_rp->m_TideStation = prp->m_TideStation;
1254 ex_rp->SetPlannedSpeed(prp->GetPlannedSpeed());
1255 pChangeRoute->AddPoint(ex_rp);
1256 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, ex_rp);
1259 pChangeRoute->AddPoint(prp);
1260 pSelect->AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
1261 pWayPointMan->AddRoutePoint(prp);
1265 pSelect->AddSelectableRouteSegment(prev_rlat, prev_rlon, prp->m_lat,
1266 prp->m_lon, prev_pConfPoint, prp,
1268 prev_rlat = prp->m_lat;
1269 prev_rlon = prp->m_lon;
1270 prev_pConfPoint = prp;
1274 node = node->GetNext();
1277 pChangeRoute->FinalizeForRendering();
1281 wxRouteListNode *node = pRouteList->GetFirst();
1283 Route *proute = node->GetData();
1285 wxRoutePointListNode *pnode = (proute->pRoutePointList)->GetFirst();
1288 if (prp == pWP)
return proute;
1289 pnode = pnode->GetNext();
1292 node = node->GetNext();
1299bool NavObjectCollection1::CreateNavObjGPXPoints(
void) {
1304 if (!pWayPointMan)
return false;
1306 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1311 pr = node->GetData();
1313 if ((pr->m_bIsolatedMark) && !(pr->m_bIsInLayer) && !(pr->m_btemp)) {
1314 pugi::xml_node doc = root();
1315 pugi::xml_node gpx = doc.first_child();
1316 pugi::xml_node new_node = gpx.append_child(
"wpt");
1318 GPXCreateWpt(new_node, pr, OPT_WPT);
1320 node = node->GetNext();
1326bool NavObjectCollection1::CreateNavObjGPXRoutes(
void) {
1328 if (!pRouteList)
return false;
1330 wxRouteListNode *node1 = pRouteList->GetFirst();
1332 Route *pRoute = node1->GetData();
1334 if (!pRoute->m_bIsInLayer && !pRoute->m_btemp){
1335 pugi::xml_node doc = root();
1336 pugi::xml_node gpx = doc.first_child();
1337 pugi::xml_node new_node = gpx.append_child(
"rte");
1339 GPXCreateRoute(new_node, pRoute);
1342 node1 = node1->GetNext();
1348bool NavObjectCollection1::CreateNavObjGPXTracks(
void) {
1350 for (
Track *pTrack : g_TrackList) {
1351 if (pTrack->GetnPoints()) {
1352 if (!pTrack->m_bIsInLayer && !pTrack->m_btemp){
1353 pugi::xml_node doc = root();
1354 pugi::xml_node gpx = doc.first_child();
1355 pugi::xml_node new_node = gpx.append_child(
"trk");
1357 GPXCreateTrk(new_node, pTrack, 0);
1365bool NavObjectCollection1::CreateAllGPXObjects() {
1368 CreateNavObjGPXPoints();
1369 CreateNavObjGPXRoutes();
1370 CreateNavObjGPXTracks();
1375bool NavObjectCollection1::AddGPXRoute(
Route *pRoute) {
1377 pugi::xml_node doc = root();
1378 pugi::xml_node gpx = doc.first_child();
1379 pugi::xml_node new_node = gpx.append_child(
"rte");
1381 GPXCreateRoute(new_node, pRoute);
1385bool NavObjectCollection1::AddGPXTrack(
Track *pTrk) {
1387 pugi::xml_node doc = root();
1388 pugi::xml_node gpx = doc.first_child();
1389 pugi::xml_node new_node = gpx.append_child(
"trk");
1391 GPXCreateTrk(new_node, pTrk, 0);
1395bool NavObjectCollection1::AddGPXWaypoint(
RoutePoint *pWP) {
1397 pugi::xml_node doc = root();
1398 pugi::xml_node gpx = doc.first_child();
1399 pugi::xml_node new_node = gpx.append_child(
"wpt");
1401 GPXCreateWpt(new_node, pWP, OPT_WPT);
1405void NavObjectCollection1::AddGPXRoutesList(RouteList *pRoutes) {
1408 wxRouteListNode *pRoute = pRoutes->GetFirst();
1410 Route *pRData = pRoute->GetData();
1411 AddGPXRoute(pRData);
1412 pRoute = pRoute->GetNext();
1416void NavObjectCollection1::AddGPXTracksList(std::vector<Track*> *pTracks) {
1419 for (
Track *pRData : *pTracks) {
1420 AddGPXTrack(pRData);
1424bool NavObjectCollection1::AddGPXPointsList(RoutePointList *pRoutePoints) {
1427 wxRoutePointListNode *pRoutePointNode = pRoutePoints->GetFirst();
1428 while (pRoutePointNode) {
1429 RoutePoint *pRP = pRoutePointNode->GetData();
1430 AddGPXWaypoint(pRP);
1431 pRoutePointNode = pRoutePointNode->GetNext();
1437void NavObjectCollection1::SetRootGPXNode(
void) {
1438 if (!strlen(first_child().name())) {
1439 pugi::xml_node gpx_root = append_child(
"gpx");
1440 gpx_root.append_attribute(
"version") =
"1.1";
1441 gpx_root.append_attribute(
"creator") =
"OpenCPN";
1442 gpx_root.append_attribute(
"xmlns:xsi") =
1443 "http://www.w3.org/2001/XMLSchema-instance";
1444 gpx_root.append_attribute(
"xmlns") =
"http://www.topografix.com/GPX/1/1";
1445 gpx_root.append_attribute(
"xmlns:gpxx") =
1446 "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
1447 gpx_root.append_attribute(
"xsi:schemaLocation") =
1448 "http://www.topografix.com/GPX/1/1 "
1449 "http://www.topografix.com/GPX/1/1/gpx.xsd "
1450 "http://www.garmin.com/xmlschemas/GpxExtensions/v3 "
1451 "http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd";
1452 gpx_root.append_attribute(
"xmlns:opencpn") =
"http://www.opencpn.org";
1456bool NavObjectCollection1::IsOpenCPN() {
1457 for (pugi::xml_attribute attr = root().first_child().first_attribute(); attr;
1458 attr = attr.next_attribute())
1459 if (!strcmp(attr.name(),
"creator") && !strcmp(attr.value(),
"OpenCPN"))
1464bool NavObjectCollection1::SaveFile(
const wxString filename) {
1465 save_file(filename.fn_str(),
" ");
1468bool NavObjectCollection1::LoadAllGPXObjects(
bool b_full_viz,
1469 int &wpt_duplicates,
1470 bool b_compute_bbox) {
1472 pugi::xml_node objects = this->child(
"gpx");
1474 for (pugi::xml_node
object = objects.first_child();
object;
1475 object =
object.next_sibling()) {
1476 if (!strcmp(
object.name(),
"wpt")) {
1477 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1478 b_full_viz,
false,
false, 0);
1480 pWp->m_bIsolatedMark =
true;
1482 WaypointExists(pWp->GetName(), pWp->m_lat, pWp->m_lon);
1484 if (NULL != pWayPointMan) pWayPointMan->AddRoutePoint(pWp);
1485 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1487 wptbox.Set(pWp->m_lat, pWp->m_lon, pWp->m_lat, pWp->m_lon);
1488 BBox.Expand(wptbox);
1493 }
else if (!strcmp(
object.name(),
"trk")) {
1494 Track *pTrack = GPXLoadTrack1(
object, b_full_viz,
false,
false, 0);
1495 if (InsertTrack(pTrack) && b_compute_bbox && pTrack->IsVisible()) {
1498 }
else if (!strcmp(
object.name(),
"rte")) {
1499 Route *pRoute = GPXLoadRoute1(
object, b_full_viz,
false,
false, 0,
false);
1500 if (InsertRouteA(pRoute,
this) && b_compute_bbox && pRoute->IsVisible()) {
1501 BBox.Expand(pRoute->GetBBox());
1510int NavObjectCollection1::LoadAllGPXObjectsAsLayer(
int layer_id,
1512 wxCheckBoxState b_namesviz) {
1513 if (!pWayPointMan)
return 0;
1516 pugi::xml_node objects = this->child(
"gpx");
1518 for (pugi::xml_node
object = objects.first_child();
object;
1519 object =
object.next_sibling()) {
1520 if (!strcmp(
object.name(),
"wpt")) {
1521 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
1522 b_namesviz != wxCHK_UNDETERMINED,
1523 true, b_layerviz, layer_id);
1524 if (b_namesviz != wxCHK_UNDETERMINED) {
1525 pWp->SetNameShown(b_namesviz == wxCHK_CHECKED);
1527 pWp->m_bIsolatedMark =
true;
1528 pWayPointMan->AddRoutePoint(pWp);
1529 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1532 if (!strcmp(
object.name(),
"trk")) {
1534 GPXLoadTrack1(
object,
false,
true, b_layerviz, layer_id);
1536 InsertTrack(pTrack);
1537 }
else if (!strcmp(
object.name(),
"rte")) {
1539 GPXLoadRoute1(
object,
true,
true, b_layerviz, layer_id,
false);
1541 InsertRouteA(pRoute,
this);
1549NavObjectChanges::NavObjectChanges(wxString file_name)
1551 m_filename = file_name;
1552 m_changes_file = fopen(m_filename.mb_str(),
"a");
1556NavObjectChanges::~NavObjectChanges() {
1557 if (m_changes_file) fclose(m_changes_file);
1558 if (::wxFileExists(m_filename)) ::wxRemoveFile(m_filename);
1561void NavObjectChanges::AddRoute(
Route *pr,
const char *action) {
1564 pugi::xml_node
object = root().append_child(
"rte");
1565 GPXCreateRoute(
object, pr);
1567 pugi::xml_node xchild =
object.child(
"extensions");
1569 pugi::xml_node child = xchild.append_child(
"opencpn:action");
1570 child.append_child(pugi::node_pcdata).set_value(action);
1572 pugi::xml_writer_file writer(m_changes_file);
1573 object.print(writer,
" ");
1574 fflush(m_changes_file);
1578void NavObjectChanges::AddTrack(
Track *pr,
const char *action) {
1581 pugi::xml_node
object = root().append_child(
"trk");
1582 GPXCreateTrk(
object, pr, RT_OUT_NO_RTPTS);
1584 pugi::xml_node xchild =
object.child(
"extensions");
1585 pugi::xml_node child = xchild.append_child(
"opencpn:action");
1586 child.append_child(pugi::node_pcdata).set_value(action);
1588 pugi::xml_writer_file writer(m_changes_file);
1589 object.print(writer,
" ");
1590 fflush(m_changes_file);
1594void NavObjectChanges::AddWP(
RoutePoint *pWP,
const char *action) {
1597 pugi::xml_node
object = root().append_child(
"wpt");
1598 GPXCreateWpt(
object, pWP, OPT_WPT);
1600 pugi::xml_node xchild =
object.child(
"extensions");
1601 pugi::xml_node child = xchild.append_child(
"opencpn:action");
1602 child.append_child(pugi::node_pcdata).set_value(action);
1604 pugi::xml_writer_file writer(m_changes_file);
1605 object.print(writer,
" ");
1606 fflush(m_changes_file);
1610void NavObjectChanges::AddTrackPoint(
TrackPoint *pWP,
const char *action,
1611 const wxString &parent_GUID) {
1614 pugi::xml_node
object = root().append_child(
"tkpt");
1615 GPXCreateTrkpt(
object, pWP, OPT_TRACKPT);
1617 pugi::xml_node xchild =
object.append_child(
"extensions");
1619 pugi::xml_node child = xchild.append_child(
"opencpn:action");
1620 child.append_child(pugi::node_pcdata).set_value(action);
1622 pugi::xml_node gchild = xchild.append_child(
"opencpn:track_GUID");
1623 gchild.append_child(pugi::node_pcdata).set_value(parent_GUID.mb_str());
1625 pugi::xml_writer_file writer(m_changes_file);
1626 object.print(writer,
" ");
1627 fflush(m_changes_file);
1631bool NavObjectChanges::ApplyChanges(
void) {
1634 pugi::xml_node
object = this->first_child();
1636 while (strlen(
object.name())) {
1637 if (!strcmp(
object.name(),
"wpt") && pWayPointMan) {
1638 RoutePoint *pWp = ::GPXLoadWaypoint1(
object, _T(
"circle"), _T(
""),
false,
1641 pWp->m_bIsolatedMark =
true;
1642 RoutePoint *pExisting = WaypointExists(pWp->m_GUID);
1644 pugi::xml_node xchild =
object.child(
"extensions");
1645 pugi::xml_node child = xchild.child(
"opencpn:action");
1647 if (!strcmp(child.first_child().value(),
"add")) {
1648 if (!pExisting) pWayPointMan->AddRoutePoint(pWp);
1649 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1652 else if (!strcmp(child.first_child().value(),
"update")) {
1653 if (pExisting) pWayPointMan->RemoveRoutePoint(pExisting);
1654 pWayPointMan->AddRoutePoint(pWp);
1655 pSelect->AddSelectableRoutePoint(pWp->m_lat, pWp->m_lon, pWp);
1658 else if (!strcmp(child.first_child().value(),
"delete")) {
1659 if (pExisting) pWayPointMan->DestroyWaypoint(pExisting,
false);
1662 }
else if (!strcmp(
object.name(),
"trk") && g_pRouteMan) {
1663 Track *pTrack = GPXLoadTrack1(
object,
false,
false,
false, 0);
1666 pugi::xml_node xchild =
object.child(
"extensions");
1667 pugi::xml_node child = xchild.child(
"opencpn:action");
1669 Track *pExisting = TrackExists(pTrack->m_GUID);
1670 if (!strcmp(child.first_child().value(),
"update")) {
1672 pExisting->SetName(pTrack->GetName());
1673 pExisting->m_TrackStartString = pTrack->m_TrackStartString;
1674 pExisting->m_TrackEndString = pTrack->m_TrackEndString;
1678 else if (!strcmp(child.first_child().value(),
"delete")) {
1684 else if (!strcmp(child.first_child().value(),
"add")) {
1685 if (!pExisting) ::InsertTrack(pTrack,
true);
1693 else if (!strcmp(
object.name(),
"rte") && g_pRouteMan) {
1694 Route *pRoute = GPXLoadRoute1(
object,
false,
false,
false, 0,
true);
1697 pugi::xml_node xchild =
object.child(
"extensions");
1698 pugi::xml_node child = xchild.child(
"opencpn:action");
1700 if (!strcmp(child.first_child().value(),
"add")) {
1701 ::UpdateRouteA(pRoute,
this,
this);
1704 else if (!strcmp(child.first_child().value(),
"update")) {
1705 ::UpdateRouteA(pRoute,
this,
this);
1708 else if (!strcmp(child.first_child().value(),
"delete")) {
1709 Route *pExisting = RouteExists(pRoute->m_GUID);
1711 m_bSkipChangeSetUpdate =
true;
1713 m_bSkipChangeSetUpdate =
false;
1720 }
else if (!strcmp(
object.name(),
"tkpt") && pWayPointMan) {
1721 TrackPoint *pWp = ::GPXLoadTrackPoint1(
object);
1726 pugi::xml_node xchild =
object.child(
"extensions");
1727 pugi::xml_node child = xchild.child(
"opencpn:action");
1729 pugi::xml_node guid_child = xchild.child(
"opencpn:track_GUID");
1730 wxString track_GUID(guid_child.first_child().value(), wxConvUTF8);
1732 Track *pExistingTrack = TrackExists(track_GUID);
1734 if (!strcmp(child.first_child().value(),
"add") && pExistingTrack && pWp) {
1735 pExistingTrack->AddPoint(pWp);
1736 pWp->m_GPXTrkSegNo = pExistingTrack->GetCurrentTrackSeg() + 1;
1741 object =
object.next_sibling();
1744 auto it = g_TrackList.begin();
1745 while (it != g_TrackList.end()) {
1746 Track *pTrack = *it;
1747 if (pTrack->GetnPoints() < 2) {
1750 g_TrackList.erase(to_erase);
1760void NavObjectChanges::AddNewRoute(
Route *pr) {
1763 if (!m_bSkipChangeSetUpdate) AddRoute(pr,
"add");
1766void NavObjectChanges::UpdateRoute(
Route *pr) {
1768 if (!m_bSkipChangeSetUpdate) AddRoute(pr,
"update");
1771void NavObjectChanges::DeleteConfigRoute(
Route *pr) {
1774 if (!m_bSkipChangeSetUpdate) AddRoute(pr,
"delete");
1777void NavObjectChanges::AddNewTrack(
Track *pt) {
1778 if (!pt->m_bIsInLayer && !m_bSkipChangeSetUpdate) AddTrack(pt,
"add");
1781void NavObjectChanges::UpdateTrack(
Track *pt) {
1782 if (pt->m_bIsInLayer && !m_bSkipChangeSetUpdate) AddTrack(pt,
"update");
1785void NavObjectChanges::DeleteConfigTrack(
Track *pt) {
1786 if (!pt->m_bIsInLayer && !m_bSkipChangeSetUpdate) AddTrack(pt,
"delete");
1789void NavObjectChanges::AddNewWayPoint(
RoutePoint *pWP,
int crm) {
1790 if (!pWP->m_bIsInLayer && pWP->m_bIsolatedMark && !m_bSkipChangeSetUpdate)
1794void NavObjectChanges::UpdateWayPoint(
RoutePoint *pWP) {
1795 if (!pWP->m_bIsInLayer && !m_bSkipChangeSetUpdate) AddWP(pWP,
"update");
1798void NavObjectChanges::DeleteWayPoint(
RoutePoint *pWP) {
1799 if (!pWP->m_bIsInLayer && !m_bSkipChangeSetUpdate) AddWP(pWP,
"delete");
1802void NavObjectChanges::AddNewTrackPoint(
TrackPoint *pWP,
1803 const wxString &parent_GUID) {
1804 if (!m_bSkipChangeSetUpdate) AddTrackPoint(pWP,
"add", parent_GUID);
1807RoutePoint *WaypointExists(
const wxString &name,
double lat,
double lon) {
1810 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1816 if (name == pr->GetName()) {
1817 if (fabs(lat - pr->m_lat) < 1.e-6 && fabs(lon - pr->m_lon) < 1.e-6) {
1822 node = node->GetNext();
1828RoutePoint *WaypointExists(
const wxString &guid) {
1829 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1835 if (guid == pr->m_GUID) {
1838 node = node->GetNext();
1845 bool IsInList =
false;
1847 wxRouteListNode *node1 = pRouteList->GetFirst();
1849 Route *pRoute = node1->GetData();
1850 RoutePointList *pRoutePointList = pRoute->pRoutePointList;
1852 wxRoutePointListNode *node2 = pRoutePointList->GetFirst();
1856 prp = node2->GetData();
1858 if (pr->IsSame(prp)) {
1863 node2 = node2->GetNext();
1865 node1 = node1->GetNext();
1870Route *RouteExists(
const wxString &guid) {
1871 wxRouteListNode *route_node = pRouteList->GetFirst();
1873 while (route_node) {
1874 Route *proute = route_node->GetData();
1876 if (guid == proute->m_GUID)
return proute;
1878 route_node = route_node->GetNext();
1884 wxRouteListNode *route_node = pRouteList->GetFirst();
1885 while (route_node) {
1886 Route *proute = route_node->GetData();
1888 if (proute->IsEqualTo(pTentRoute))
return proute;
1890 route_node = route_node->GetNext();
1895Track *TrackExists(
const wxString &guid) {
1896 for (
Track* ptrack : g_TrackList) {
1897 if (guid == ptrack->m_GUID)
return ptrack;
const void Notify()
Notify all listeners, no data supplied.
EventVar evt_delete_track
Notified when Routeman (?) should delete a track.
EventVar evt_delete_route
Notified when Routeman (?) should delete a Route*.
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)