OpenCPN Partial API docs
Loading...
Searching...
No Matches
api_121.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2024 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
24#include <algorithm>
25#include <map>
26#include <memory>
27#include <string>
28#include <vector>
29
30#include <wx/wx.h>
31#include <wx/event.h>
32#include <wx/string.h>
33#include <wx/window.h>
34
35#include "model/ais_decoder.h"
37#include "model/gui_events.h"
38#include "model/gui_vars.h"
39#include "model/navobj_db.h"
41#include "model/own_ship.h"
42#include "model/route.h"
43#include "model/track.h"
44
45#include "chcanv.h"
46#include "ocpn_plugin.h"
47
48// translate O route class to PlugIn_Waypoint_ExV2
49static void PlugInExV2FromRoutePoint(PlugIn_Waypoint_ExV2* dst,
50 /* const*/ RoutePoint* src) {
51 dst->m_lat = src->m_lat;
52 dst->m_lon = src->m_lon;
53 dst->IconName = src->GetIconName();
54 dst->m_MarkName = src->GetName();
55 dst->m_MarkDescription = src->GetDescription();
56 dst->IconDescription = pWayPointMan->GetIconDescription(src->GetIconName());
57 dst->IsVisible = src->IsVisible();
58 dst->m_CreateTime = src->GetCreateTime(); // not const
59 dst->m_GUID = src->m_GUID;
60
61 // Transcribe (clone) the html HyperLink List, if present
62 if (src->m_HyperlinkList) {
63 delete dst->m_HyperlinkList;
64 dst->m_HyperlinkList = nullptr;
65
66 if (src->m_HyperlinkList->size() > 0) {
67 dst->m_HyperlinkList = new Plugin_HyperlinkList;
68
69 for (Hyperlink* link : *src->m_HyperlinkList) {
71 h->DescrText = link->DescrText;
72 h->Link = link->Link;
73 h->Type = link->LType;
74 dst->m_HyperlinkList->Append(h);
75 }
76 }
77 }
78
79 // Get the range ring info
84 dst->m_TideStation = src->m_TideStation;
85
86 // Get other extended info
87 dst->IsNameVisible = src->m_bShowName;
88 dst->scamin = src->GetScaMin();
89 dst->b_useScamin = src->GetUseSca();
90 dst->IsActive = src->m_bIsActive;
91
92 dst->scamax = src->GetScaMax();
93 dst->m_PlannedSpeed = src->GetPlannedSpeed();
94 dst->m_ETD = src->GetManualETD();
95 dst->m_WaypointArrivalRadius = src->GetWaypointArrivalRadius();
96 dst->m_bShowWaypointRangeRings = src->GetShowWaypointRangeRings();
97}
98
99static void cloneHyperlinkListExV2(RoutePoint* dst,
100 const PlugIn_Waypoint_ExV2* src) {
101 // Transcribe (clone) the html HyperLink List, if present
102 if (src->m_HyperlinkList == nullptr) return;
103
104 if (src->m_HyperlinkList->GetCount() > 0) {
105 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
106 while (linknode) {
107 Plugin_Hyperlink* link = linknode->GetData();
108
109 Hyperlink* h = new Hyperlink();
110 h->DescrText = link->DescrText;
111 h->Link = link->Link;
112 h->LType = link->Type;
113
114 dst->m_HyperlinkList->push_back(h);
115
116 linknode = linknode->GetNext();
117 }
118 }
119}
120
121static RoutePoint* CreateNewPoint(const PlugIn_Waypoint_ExV2* src,
122 bool b_permanent) {
123 RoutePoint* pWP = new RoutePoint(src->m_lat, src->m_lon, src->IconName,
124 src->m_MarkName, src->m_GUID);
125
126 pWP->m_bIsolatedMark = true; // This is an isolated mark
127
128 cloneHyperlinkListExV2(pWP, src);
129
131
132 if (src->m_CreateTime.IsValid())
133 pWP->SetCreateTime(src->m_CreateTime);
134 else {
135 pWP->SetCreateTime(wxDateTime::Now().ToUTC());
136 }
137
138 pWP->m_btemp = (b_permanent == false);
139
140 // Extended fields
141 pWP->SetIconName(src->IconName);
142 pWP->SetWaypointRangeRingsNumber(src->nrange_rings);
143 pWP->SetWaypointRangeRingsStep(src->RangeRingSpace);
144 pWP->SetWaypointRangeRingsStepUnits(src->RangeRingSpaceUnits);
145 pWP->SetWaypointRangeRingsColour(src->RangeRingColor);
146 pWP->SetTideStation(src->m_TideStation);
147 pWP->SetScaMin(src->scamin);
148 pWP->SetUseSca(src->b_useScamin);
149 pWP->SetNameShown(src->IsNameVisible);
150 pWP->SetVisible(src->IsVisible);
151
152 pWP->SetWaypointArrivalRadius(src->m_WaypointArrivalRadius);
153 pWP->SetShowWaypointRangeRings(src->m_bShowWaypointRangeRings);
154 pWP->SetScaMax(src->scamax);
155 pWP->SetPlannedSpeed(src->m_PlannedSpeed);
156 if (src->m_ETD.IsValid())
157 pWP->SetETD(src->m_ETD);
158 else
159 pWP->SetETD(wxEmptyString);
160 return pWP;
161}
162
163static bool AddPlugInRouteExV3(HostApi121::Route* proute, bool b_permanent) {
164 ::Route* route = new ::Route();
165
166 PlugIn_Waypoint_ExV2* pwaypointex;
167 RoutePoint *pWP, *pWP_src;
168 int ip = 0;
169 wxDateTime plannedDeparture;
170
171 wxPlugin_WaypointExV2ListNode* pwpnode = proute->pWaypointList->GetFirst();
172 while (pwpnode) {
173 pwaypointex = pwpnode->GetData();
174
175 pWP = pWayPointMan->FindRoutePointByGUID(pwaypointex->m_GUID);
176 if (!pWP) {
177 pWP = CreateNewPoint(pwaypointex, b_permanent);
178 pWP->m_bIsolatedMark = false;
179 }
180
181 route->AddPoint(pWP);
182
183 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
184
185 if (ip > 0)
186 pSelect->AddSelectableRouteSegment(pWP_src->m_lat, pWP_src->m_lon,
187 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
188 route);
189
190 plannedDeparture = pwaypointex->m_CreateTime;
191 ip++;
192 pWP_src = pWP;
193
194 pwpnode = pwpnode->GetNext(); // PlugInWaypoint
195 }
196
197 route->m_PlannedDeparture = plannedDeparture;
198
199 route->m_RouteNameString = proute->m_NameString;
200 route->m_RouteStartString = proute->m_StartString;
201 route->m_RouteEndString = proute->m_EndString;
202 if (!proute->m_GUID.IsEmpty()) {
203 route->m_GUID = proute->m_GUID;
204 }
205 route->m_btemp = (b_permanent == false);
206 route->SetVisible(proute->m_isVisible);
207 route->m_RouteDescription = proute->m_Description;
208
209 route->m_PlannedSpeed = proute->m_PlannedSpeed;
210 route->m_Colour = proute->m_Colour;
211 route->m_style = proute->m_style;
212 route->m_PlannedDeparture = proute->m_PlannedDeparture;
213 route->m_TimeDisplayFormat = proute->m_TimeDisplayFormat;
214
215 pRouteList->push_back(route);
216
217 if (b_permanent) {
218 // pConfig->AddNewRoute(route);
219 NavObj_dB::GetInstance().InsertRoute(route);
220 }
221
222 GuiEvents::GetInstance().on_routes_update.Notify();
223
224 return true;
225}
226
227static bool UpdatePlugInRouteExV3(HostApi121::Route* proute) {
228 bool b_found = false;
229
230 // Find the Route
231 Route* pRoute = g_pRouteMan->FindRouteByGUID(proute->m_GUID);
232 if (pRoute) b_found = true;
233
234 if (b_found) {
235 bool b_permanent = !pRoute->m_btemp;
236 g_pRouteMan->DeleteRoute(pRoute);
237
238 b_found = AddPlugInRouteExV3(proute, b_permanent);
239 }
240
241 return b_found;
242}
243
244// translate O route class to PlugIn_Waypoint_Ex
245static void PlugInExFromRoutePoint(PlugIn_Waypoint_Ex* dst,
246 /* const*/ RoutePoint* src) {
247 dst->m_lat = src->m_lat;
248 dst->m_lon = src->m_lon;
249 dst->IconName = src->GetIconName();
250 dst->m_MarkName = src->GetName();
251 dst->m_MarkDescription = src->GetDescription();
252 dst->IconDescription = pWayPointMan->GetIconDescription(src->GetIconName());
253 dst->IsVisible = src->IsVisible();
254 dst->m_CreateTime = src->GetCreateTime(); // not const
255 dst->m_GUID = src->m_GUID;
256
257 // Transcribe (clone) the html HyperLink List, if present
258 if (src->m_HyperlinkList) {
259 delete dst->m_HyperlinkList;
260 dst->m_HyperlinkList = nullptr;
261
262 if (src->m_HyperlinkList->size() > 0) {
263 dst->m_HyperlinkList = new Plugin_HyperlinkList;
264 for (Hyperlink* link : *src->m_HyperlinkList) {
266 h->DescrText = link->DescrText;
267 h->Link = link->Link;
268 h->Type = link->LType;
269 dst->m_HyperlinkList->Append(h);
270 }
271 }
272 }
273
274 // Get the range ring info
278
279 // Get other extended info
280 dst->IsNameVisible = src->m_bShowName;
281 dst->scamin = src->GetScaMin();
282 dst->b_useScamin = src->GetUseSca();
283 dst->IsActive = src->m_bIsActive;
284}
285
286static void cloneHyperlinkListEx(RoutePoint* dst,
287 const PlugIn_Waypoint_Ex* src) {
288 // Transcribe (clone) the html HyperLink List, if present
289 if (src->m_HyperlinkList == nullptr) return;
290
291 if (src->m_HyperlinkList->GetCount() > 0) {
292 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
293 while (linknode) {
294 Plugin_Hyperlink* link = linknode->GetData();
295
296 Hyperlink* h = new Hyperlink();
297 h->DescrText = link->DescrText;
298 h->Link = link->Link;
299 h->LType = link->Type;
300
301 dst->m_HyperlinkList->push_back(h);
302
303 linknode = linknode->GetNext();
304 }
305 }
306}
307
308static wxString DropMarkPI(double lat, double lon) {
309 if ((fabs(lat) > 80.0) || (fabs(lon) > 180.)) return "";
310
311 RoutePoint* pWP =
312 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
313 pWP->m_bIsolatedMark = true; // This is an isolated mark
314 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
315 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
316 return pWP->m_GUID;
317}
318
319static wxString RouteCreatePI(int canvas_index, bool start) {
320 if ((size_t)canvas_index < g_canvasArray.GetCount()) {
321 ChartCanvas* cc = g_canvasArray.Item(canvas_index);
322 if (cc) {
323 if (start) {
324 cc->StartRoute();
325 return "0";
326 } else {
327 return cc->FinishRoute();
328 }
329 }
330 }
331 return "-1";
332}
333
334static bool DoMeasurePI(int canvas_index, bool start) {
335 if ((size_t)canvas_index < g_canvasArray.GetCount()) {
336 ChartCanvas* cc = g_canvasArray.Item(canvas_index);
337 if (cc) {
338 if (start) {
339 cc->StartMeasureRoute();
340 return true;
341 } else {
342 cc->CancelMeasureRoute();
343 cc->Refresh(false);
344 return true;
345 }
346 }
347 }
348 return false;
349}
350
351static void EnableDefaultConsole(bool enable) {
352 g_bhide_route_console = !enable;
353}
354
355static wxString NavToHerePI(double lat, double lon) {
356 RoutePoint* pWP_dest =
357 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
358 pSelect->AddSelectableRoutePoint(lat, lon, pWP_dest);
359
360 RoutePoint* pWP_src = new RoutePoint(gLat, gLon, g_default_wp_icon,
361 wxEmptyString, wxEmptyString);
362 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
363
364 Route* temp_route = new Route();
365 pRouteList->push_back(temp_route);
366
367 temp_route->AddPoint(pWP_src);
368 temp_route->AddPoint(pWP_dest);
369
370 pSelect->AddSelectableRouteSegment(gLat, gLon, lat, lon, pWP_src, pWP_dest,
371 temp_route);
372
373 temp_route->m_RouteNameString = _("Temporary GOTO Route");
374 temp_route->m_RouteStartString = _("Here");
375 temp_route->m_RouteEndString = _("There");
376 temp_route->m_bDeleteOnArrival = true;
377
378 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
379
380 g_pRouteMan->ActivateRoute(temp_route, pWP_dest);
381 return temp_route->m_GUID;
382}
383
384static bool ActivateRoutePI(wxString route_guid, bool activate) {
385 Route* route = g_pRouteMan->FindRouteByGUID(route_guid);
386 if (!route) return false;
387
388 if (activate) {
389 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
390 RoutePoint* best_point =
391 g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
392 g_pRouteMan->ActivateRoute(route, best_point);
393 route->m_bRtIsSelected = false;
394 return true;
395 } else {
396 g_pRouteMan->DeactivateRoute();
397 route->m_bRtIsSelected = false;
398 return true;
399 }
400 return false;
401}
402
403static void SetMaxZoomScale(double max_scale) {
404 g_maxzoomin = wxRound(wxMax(max_scale, 100.));
405}
406
407static void EnableDefaultContextMenus(bool enable) {
408 g_bhide_context_menus = !enable;
409}
410
411static void SetMinZoomScale(double min_scale) {
412 for (unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
413 ChartCanvas* cc = g_canvasArray.Item(i);
414 cc->SetAbsoluteMinScale(min_scale);
415 }
416}
417
418static std::shared_ptr<HostApi121::PiPointContext> GetContextAtPoint(
419 int x, int y, int canvas_index) {
420 ChartCanvas* cc = g_canvasArray.Item(canvas_index);
421 if (cc) {
422 return cc->GetCanvasContextAtPoint(x, y);
423 } else {
424 auto rstruct = std::make_shared<HostApi121::PiPointContext>();
425 rstruct->object_type = HostApi121::PiContextObjectType::kObjectUnknown;
426 rstruct->object_ident = "";
427 return rstruct;
428 }
429}
430
431static wxBitmap GetObjectIcon_PlugIn(const wxString& name) {
432 if (pWayPointMan)
433 return *pWayPointMan->GetIconBitmap(name);
434 else
435 return wxNullBitmap;
436}
437
438static bool IsRouteActive(wxString route_guid) {
439 if (g_pRouteMan->GetpActiveRoute())
440 return (route_guid.IsSameAs(g_pRouteMan->GetpActiveRoute()->m_GUID));
441 else
442 return false;
443}
444
445static void SetBoatPosition(double zlat, double zlon) {
446 gLat = zlat;
447 gLon = zlon;
448 GuiEvents::GetInstance().gframe_update_status_bar.Notify();
449}
450
451static void RouteInsertWaypoint(int canvas_index, wxString route_guid,
452 double zlat, double zlon) {
453 ChartCanvas* parent =
454 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
455 if (!parent) return;
456
457 Route* route = g_pRouteMan->FindRouteByGUID(route_guid);
458 if (!route) return;
459
460 if (route->m_bIsInLayer) return;
461
462 int seltype = parent->PrepareContextSelections(zlat, zlon);
463 if ((seltype & SELTYPE_ROUTESEGMENT) != SELTYPE_ROUTESEGMENT) return;
464
465 bool rename = false;
466 route->InsertPointAfter(parent->GetFoundRoutepoint(), zlat, zlon, rename);
467
468 pSelect->DeleteAllSelectableRoutePoints(route);
469 pSelect->DeleteAllSelectableRouteSegments(route);
470 pSelect->AddAllSelectableRouteSegments(route);
471 pSelect->AddAllSelectableRoutePoints(route);
472
473 NavObj_dB::GetInstance().UpdateRoute(route);
474}
475
476static void RouteAppendWaypoint(int canvas_index, wxString route_guid) {
477 Route* route = g_pRouteMan->FindRouteByGUID(route_guid);
478 if (!route) return;
479
480 ChartCanvas* parent =
481 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
482 if (!parent) return;
483
484 parent->m_pMouseRoute = route;
485 parent->m_routeState = route->GetnPoints() + 1;
486 parent->m_pMouseRoute->m_lastMousePointIndex = route->GetnPoints();
487 parent->m_pMouseRoute->SetHiLite(50);
488
489 auto pLast = route->GetLastPoint();
490
491 parent->m_prev_rlat = pLast->m_lat;
492 parent->m_prev_rlon = pLast->m_lon;
493 parent->m_prev_pMousePoint = pLast;
494
495 parent->m_bAppendingRoute = true;
496}
497
498static void FinishRoute(int canvas_index) {
499 ChartCanvas* parent =
500 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
501 if (!parent) return;
502
503 parent->FinishRoute();
504}
505
506static bool IsRouteBeingCreated(int canvas_index) {
507 ChartCanvas* parent =
508 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
509 if (!parent) return false;
510 return !(parent->m_pMouseRoute == NULL);
511}
512
513static bool AreRouteWaypointNamesVisible(wxString route_guid) {
514 Route* route = g_pRouteMan->FindRouteByGUID(route_guid);
515 if (!route) return false;
516 return route->AreWaypointNamesVisible();
517}
518
519static void ShowRouteWaypointNames(wxString route_guid, bool show) {
520 Route* route = g_pRouteMan->FindRouteByGUID(route_guid);
521 if (!route) return;
522 route->ShowWaypointNames(show);
523}
524
525static void NavigateToWaypoint(wxString waypoint_guid) {
526 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(waypoint_guid);
527 if (!prp) return;
528
529 RoutePoint* pWP_src = new RoutePoint(gLat, gLon, g_default_wp_icon,
530 wxEmptyString, wxEmptyString);
531 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
532
533 Route* temp_route = new Route();
534 pRouteList->push_back(temp_route);
535
536 temp_route->AddPoint(pWP_src);
537 temp_route->AddPoint(prp);
538 prp->SetShared(true);
539
540 pSelect->AddSelectableRouteSegment(gLat, gLon, prp->m_lat, prp->m_lon,
541 pWP_src, prp, temp_route);
542
543 wxString name = prp->GetName();
544 if (name.IsEmpty()) name = _("(Unnamed Waypoint)");
545 wxString rteName = _("Go to ");
546 rteName.Append(name);
547 temp_route->m_RouteNameString = rteName;
548 temp_route->m_RouteStartString = _("Here");
549 temp_route->m_RouteEndString = name;
550 temp_route->m_bDeleteOnArrival = true;
551
552 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
553 g_pRouteMan->ActivateRoute(temp_route, prp);
554}
555
556// AIS related
557static bool IsAISTrackVisible(wxString ais_mmsi) {
558 long mmsi = 0;
559 ais_mmsi.ToLong(&mmsi);
560 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
561 if (myptarget)
562 return myptarget->b_show_track;
563 else
564 return false;
565}
566
567static void AISToggleShowTrack(wxString ais_mmsi) {
568 long mmsi = 0;
569 ais_mmsi.ToLong(&mmsi);
570 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
571 if (myptarget) myptarget->ToggleShowTrack();
572}
573
574static void AISToggleShowCPA(wxString ais_mmsi) {
575 long mmsi = 0;
576 ais_mmsi.ToLong(&mmsi);
577 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
578 if (myptarget) myptarget->Toggle_AIS_CPA();
579}
580
581static void ShowAISTargetQueryDialog(int canvas_index, wxString ais_mmsi) {
582 ChartCanvas* parent =
583 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
584 if (!parent) return;
585
586 long mmsi = 0;
587 ais_mmsi.ToLong(&mmsi);
588 ShowAISTargetQueryDialog(parent, mmsi);
589}
590
591static void ShowAISTargetList(int canvas_index) {
592 ChartCanvas* parent =
593 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
594 if (!parent) return;
595 parent->ShowAISTargetList();
596}
597
598static bool IsMeasureActive(int canvas_index) {
599 ChartCanvas* parent =
600 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
601 if (!parent) return false;
602 return parent->m_bMeasure_Active;
603}
604
605static void CancelMeasure(int canvas_index) {
606 ChartCanvas* parent =
607 static_cast<ChartCanvas*>(GetCanvasByIndex(canvas_index));
608 if (!parent) return;
609 parent->CancelMeasureRoute();
610}
611
612static void SetDepthUnitVisible(bool bviz) { g_bhide_depth_units = !bviz; }
613
614static void SetOverzoomFlagVisible(bool bviz) { g_bhide_overzoom_flag = !bviz; }
615
616// Extended Chart table management support
617static void AddNoShowDirectory(std::string chart_dir) {
618 ChartDirectoryExcludedVector.push_back(chart_dir);
619}
620
621static void RemoveNoShowDirectory(std::string chart_dir) {
622 auto it = std::find(ChartDirectoryExcludedVector.begin(),
623 ChartDirectoryExcludedVector.end(), chart_dir);
624 if (it != ChartDirectoryExcludedVector.end())
625 ChartDirectoryExcludedVector.erase(it); // Erase the element
626}
627
628static void ClearNoShowVector() { ChartDirectoryExcludedVector.clear(); }
629
630static const std::vector<std::string>& GetNoShowVector() {
632}
633
634static bool SelectChartFamily(int CanvasIndex, ChartFamilyEnumPI Family) {
635 auto window = GetCanvasByIndex(CanvasIndex);
636 auto oCanvas = dynamic_cast<ChartCanvas*>(window);
637 if (oCanvas) {
638 // Chose the "best" chart in the new family
639 // Strategy: Chose a chart from the new family that is the same native scale
640 // as the current refernce chart.
641 // If this chart is not present in the new family. chose the next larger
642 // scale chart.
643 // If there are no larger scale charts available in the new family,
644 // chose the next smaller scale chart.
645 int ref_index = oCanvas->GetQuiltReferenceChartIndex();
646 if (ref_index == -1) return false; // No chart loaded yet
647 const ChartTableEntry& cte_ref = ChartData->GetChartTableEntry(ref_index);
648
649 // No action needed if ref chart is already same as target
650 // unless the ref chart is a basemep
651 if (cte_ref.GetChartFamily() == Family) {
652 if (!cte_ref.IsBasemap()) return false;
653 }
654
655 int target_scale = cte_ref.GetScale();
656
657 int target_index = -1;
658 for (auto index : oCanvas->GetQuiltExtendedStackdbIndexArray()) {
659 const ChartTableEntry& cte = ChartData->GetChartTableEntry(index);
660 if (cte.GetChartFamily() != Family) continue;
661
662 if (cte.GetScale() == target_scale) {
663 target_index = index;
664 break;
665 }
666 }
667
668 if (target_index < 0) {
669 // Find the largest scale chart that is lower than the reference chart
670 for (auto index : oCanvas->GetQuiltExtendedStackdbIndexArray()) {
671 const ChartTableEntry& cte = ChartData->GetChartTableEntry(index);
672 if (cte.GetChartFamily() != Family) continue;
673 if (cte.GetScale() <= target_scale) {
674 target_index = index;
675 }
676 }
677 }
678
679 if (target_index < 0) {
680 // Find the largest scale chart that is higher than the reference chart
681 for (auto index : oCanvas->GetQuiltExtendedStackdbIndexArray()) {
682 const ChartTableEntry& cte = ChartData->GetChartTableEntry(index);
683 if (cte.GetChartFamily() != Family) continue;
684 if (cte.GetScale() > target_scale) {
685 target_index = index;
686 break;
687 }
688 }
689 }
690
691 if (target_index >= 0) {
692 // Found a suitable scale chart in the new family
693
694 if (oCanvas->IsChartQuiltableRef(target_index)) {
695 // if( ChartData ) ChartData->PurgeCache();
696
697 // If the chart is a vector chart, and of very large scale,
698 // then we had better set the new scale directly to avoid excessive
699 // underzoom on, eg, Inland ENCs
700 bool set_scale = false;
701 if (CHART_TYPE_S57 == ChartData->GetDBChartType(target_index)) {
702 if (ChartData->GetDBChartScale(target_index) < 5000) {
703 set_scale = true;
704 }
705 }
706
707 if (!set_scale) {
708 oCanvas->SelectQuiltRefdbChart(target_index, true); // autoscale
709 } else {
710 oCanvas->SelectQuiltRefdbChart(target_index, false); // no autoscale
711
712 // Adjust scale so that the selected chart is underzoomed/overzoomed
713 // by a controlled amount
714 ChartBase* pc = ChartData->OpenChartFromDB(target_index, FULL_INIT);
715 if (pc) {
716 double proposed_scale_onscreen =
717 oCanvas->GetCanvasScaleFactor() / oCanvas->GetVPScale();
718
719 if (g_bPreserveScaleOnX) {
720 proposed_scale_onscreen = wxMin(
721 proposed_scale_onscreen,
722 100 * pc->GetNormalScaleMax(oCanvas->GetCanvasScaleFactor(),
723 oCanvas->GetCanvasWidth()));
724 } else {
725 proposed_scale_onscreen = wxMin(
726 proposed_scale_onscreen,
727 20 * pc->GetNormalScaleMax(oCanvas->GetCanvasScaleFactor(),
728 oCanvas->GetCanvasWidth()));
729
730 proposed_scale_onscreen =
731 wxMax(proposed_scale_onscreen,
732 pc->GetNormalScaleMin(oCanvas->GetCanvasScaleFactor(),
734 }
735
736 oCanvas->SetVPScale(oCanvas->GetCanvasScaleFactor() /
737 proposed_scale_onscreen);
738 }
739 }
740 }
741 oCanvas->DoCanvasUpdate();
742 oCanvas->ReloadVP(); // Pick up the new selections
743 return true;
744 }
745 }
746 return false;
747}
748
749static void CenterToAisTarget(wxString ais_mmsi) {
750 long mmsi = 0;
751 if (ais_mmsi.ToLong(&mmsi)) {
752 std::shared_ptr<AisTargetData> pAISTarget = nullptr;
753 if (g_pAIS) pAISTarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
754
755 if (pAISTarget)
756 GuiEvents::GetInstance().on_center_ais_target.Notify(pAISTarget);
757 }
758} // same as AISTargetListDialog::CenterToTarget ( false )
759
760static void AisTargetCreateWpt(wxString ais_mmsi) {
761 long mmsi = 0;
762 if (ais_mmsi.ToLong(&mmsi)) {
763 std::shared_ptr<AisTargetData> pAISTarget = NULL;
764 if (g_pAIS) pAISTarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
765
766 if (pAISTarget) {
767 RoutePoint* pWP =
768 new RoutePoint(pAISTarget->Lat, pAISTarget->Lon, g_default_wp_icon,
769 wxEmptyString, wxEmptyString);
770 pWP->m_bIsolatedMark = true; // This is an isolated mark
771 pSelect->AddSelectableRoutePoint(pAISTarget->Lat, pAISTarget->Lon, pWP);
772 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
773
774 GuiEvents::GetInstance().on_routes_update.Notify();
775 }
776 }
777} // same as AISTargetListDialog::OnTargetCreateWpt
778
779static void AisShowAllTracks(bool show) {
780 if (g_pAIS) {
781 for (const auto& it : g_pAIS->GetTargetList()) {
782 auto pAISTarget = it.second;
783 if (NULL != pAISTarget) {
784 pAISTarget->b_show_track = show;
785
786 // Check for any persistently tracked target, force b_show_track_old
787 std::map<int, Track*>::iterator itt;
788 itt = g_pAIS->m_persistent_tracks.find(pAISTarget->MMSI);
789 if (itt != g_pAIS->m_persistent_tracks.end()) {
790 pAISTarget->b_show_track_old = show;
791 }
792 }
793 }
794 } // same as AISTargetListDialog::OnHideAllTracks /
795 // AISTargetListDialog::OnShowAllTracks
796}
797
798static void AisToggleTrack(wxString ais_mmsi) {
799 long mmsi = 0;
800 if (ais_mmsi.ToLong(&mmsi)) {
801 std::shared_ptr<AisTargetData> pAISTarget = NULL;
802 if (g_pAIS) pAISTarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
803
804 if (pAISTarget) {
805 pAISTarget->b_show_track_old =
806 pAISTarget->b_show_track; // Store current state before toggling
807 pAISTarget->b_show_track =
808 !pAISTarget->b_show_track; // Toggle visibility
809 }
810 }
811}
812
813static int GetContextMenuMask() { return g_canvas_context_menu_disable_mask; }
814
815static void SetContextMenuMask(int mask) {
816 g_canvas_context_menu_disable_mask = mask;
817}
818
819static bool IsAIS_CPAVisible(wxString ais_mmsi) {
820 long mmsi = 0;
821 ais_mmsi.ToLong(&mmsi);
822 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(mmsi);
823 if (myptarget)
824 return myptarget->b_show_AIS_CPA;
825 else
826 return false;
827}
828
829static void SetTrackVisibility(const wxString& track_GUID, bool viz) {
830 for (Track* ptrack : g_TrackList) {
831 if (ptrack->m_GUID == track_GUID) {
832 ptrack->SetVisible(viz);
833 break;
834 }
835 }
836}
837
838std::unique_ptr<HostApi> GetHostApi() {
839 return std::make_unique<HostApi121>(HostApi121());
840}
841
842bool HostApi121::AddRoute(HostApi121::Route* route, bool permanent) {
843 return ::AddPlugInRouteExV3(route, permanent);
844}
845
847 return ::UpdatePlugInRouteExV3(route);
848}
849
850std::unique_ptr<HostApi121::Route> HostApi121::GetRoute(const wxString& guid) {
851 ::Route* route = g_pRouteMan->FindRouteByGUID(guid);
852 if (!route) return nullptr;
853
854 auto dst_route = std::make_unique<HostApi121::Route>();
855
856 for (RoutePoint* src_wp : *route->pRoutePointList) {
858 PlugInExV2FromRoutePoint(dst_wp, src_wp);
859 dst_route->pWaypointList->Append(dst_wp);
860 }
861 dst_route->m_NameString = route->m_RouteNameString;
862 dst_route->m_StartString = route->m_RouteStartString;
863 dst_route->m_EndString = route->m_RouteEndString;
864 dst_route->m_GUID = route->m_GUID;
865 dst_route->m_isActive = g_pRouteMan->GetpActiveRoute() == route;
866 dst_route->m_isVisible = route->IsVisible();
867 dst_route->m_Description = route->m_RouteDescription;
868 dst_route->m_PlannedSpeed = route->m_PlannedSpeed;
869 dst_route->m_Colour = route->m_Colour;
870 dst_route->m_style = route->m_style;
871 dst_route->m_PlannedDeparture = route->m_PlannedDeparture;
872 dst_route->m_TimeDisplayFormat = route->m_TimeDisplayFormat;
873
874 return dst_route;
875}
876
877wxString HostApi121::DropMarkPI(double lat, double lon) {
878 return ::DropMarkPI(lat, lon);
879}
880
881wxString HostApi121::RouteCreatePI(int canvas_index, bool start) {
882 return ::RouteCreatePI(canvas_index, start);
883}
884
885bool HostApi121::DoMeasurePI(int canvas_index, bool start) {
886 return ::DoMeasurePI(canvas_index, start);
887}
888
889wxString HostApi121::NavToHerePI(double lat, double lon) {
890 return ::NavToHerePI(lat, lon);
891}
892
893bool HostApi121::ActivateRoutePI(wxString route_guid, bool activate) {
894 return ::ActivateRoutePI(route_guid, activate);
895}
896
897void HostApi121::EnableDefaultConsole(bool enable) {
898 ::EnableDefaultConsole(enable);
899}
900
901void HostApi121::EnableDefaultContextMenus(bool enable) {
902 ::EnableDefaultContextMenus(enable);
903}
904
905void HostApi121::SetMinZoomScale(double min_scale) {
906 ::SetMinZoomScale(min_scale);
907}
908
909void HostApi121::SetMaxZoomScale(double max_scale) {
910 ::SetMaxZoomScale(max_scale);
911}
912
913std::shared_ptr<HostApi121::PiPointContext> HostApi121::GetContextAtPoint(
914 int x, int y, int canvas_index) {
915 return ::GetContextAtPoint(x, y, canvas_index);
916}
917
918wxBitmap HostApi121::GetObjectIcon_PlugIn(const wxString& name) {
919 return ::GetObjectIcon_PlugIn(name);
920}
921
922bool HostApi121::IsRouteActive(wxString route_guid) {
923 return ::IsRouteActive(route_guid);
924}
925
926void HostApi121::SetBoatPosition(double zlat, double zlon) {
927 ::SetBoatPosition(zlat, zlon);
928}
929
930void HostApi121::RouteInsertWaypoint(int canvas_index, wxString route_guid,
931 double zlat, double zlon) {
932 ::RouteInsertWaypoint(canvas_index, route_guid, zlat, zlon);
933}
934
935void HostApi121::RouteAppendWaypoint(int canvas_index, wxString route_guid) {
936 ::RouteAppendWaypoint(canvas_index, route_guid);
937}
938
939void HostApi121::FinishRoute(int canvas_index) { ::FinishRoute(canvas_index); }
940
941bool HostApi121::IsRouteBeingCreated(int canvas_index) {
942 return ::IsRouteBeingCreated(canvas_index);
943}
944
945bool HostApi121::AreRouteWaypointNamesVisible(wxString route_guid) {
946 return ::AreRouteWaypointNamesVisible(route_guid);
947}
948
949void HostApi121::ShowRouteWaypointNames(wxString route_guid, bool show) {
950 ::ShowRouteWaypointNames(route_guid, show);
951}
952
953void HostApi121::NavigateToWaypoint(wxString waypoint_guid) {
954 ::NavigateToWaypoint(waypoint_guid);
955}
956
957bool HostApi121::IsAISTrackVisible(const wxString& ais_mmsi) const {
958 return ::IsAISTrackVisible(ais_mmsi);
959}
960
961void HostApi121::AISToggleShowTrack(const wxString& ais_mmsi) {
962 ::AISToggleShowTrack(ais_mmsi);
963}
964
965bool HostApi121::IsAIS_CPAVisible(const wxString& ais_mmsi) const {
966 return ::IsAIS_CPAVisible(ais_mmsi);
967}
968
969void HostApi121::AISToggleShowCPA(const wxString& ais_mmsi) {
970 ::AISToggleShowCPA(ais_mmsi);
971}
972
973void HostApi121::ShowAISTargetQueryDialog(int canvas_index,
974 const wxString& ais_mmsi) {
975 ::ShowAISTargetQueryDialog(canvas_index, ais_mmsi);
976}
977
978void HostApi121::ShowAISTargetList(int canvas_index) {
979 ::ShowAISTargetList(canvas_index);
980}
981
982bool HostApi121::IsMeasureActive(int canvas_index) {
983 return ::IsMeasureActive(canvas_index);
984}
985
986void HostApi121::CancelMeasure(int canvas_index) {
987 ::CancelMeasure(canvas_index);
988}
989
990void HostApi121::SetDepthUnitVisible(bool bviz) { ::SetDepthUnitVisible(bviz); }
991
992void HostApi121::SetOverzoomFlagVisible(bool viz) {
993 ::SetOverzoomFlagVisible(viz);
994}
995
996void HostApi121::AddNoShowDirectory(std::string chart_dir) {
997 ::AddNoShowDirectory(chart_dir);
998}
999
1000void HostApi121::RemoveNoShowDirectory(std::string chart_dir) {
1001 ::RemoveNoShowDirectory(chart_dir);
1002}
1003
1004void HostApi121::ClearNoShowVector() { ::ClearNoShowVector(); }
1005
1006const std::vector<std::string>& HostApi121::GetNoShowVector() {
1007 return ::GetNoShowVector();
1008}
1009
1010bool HostApi121::SelectChartFamily(int CanvasIndex, ChartFamilyEnumPI Family) {
1011 return ::SelectChartFamily(CanvasIndex, Family);
1012};
1013
1014// Enhanced AIS Target List support
1015
1016void HostApi121::CenterToAisTarget(wxString ais_mmsi) {
1017 ::CenterToAisTarget(ais_mmsi);
1018}
1019
1020void HostApi121::AisTargetCreateWpt(wxString ais_mmsi) {
1021 ::AisTargetCreateWpt(ais_mmsi);
1022}
1023
1024void HostApi121::AisShowAllTracks(bool show) { ::AisShowAllTracks(show); }
1025
1026void HostApi121::AisToggleTrack(wxString ais_mmsi) {
1027 ::AisToggleTrack(ais_mmsi);
1028}
1029
1030// Context menu enable/disable, by object type
1031int HostApi121::GetContextMenuMask() { return ::GetContextMenuMask(); }
1032
1033void HostApi121::SetContextMenuMask(int mask) { ::SetContextMenuMask(mask); }
1034
1035void HostApi121::SetTrackVisibiiity(const wxString& track_GUID, bool viz) {
1036 ::SetTrackVisibility(track_GUID, viz);
1037}
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
AIS target definitions.
std::unique_ptr< HostApi > GetHostApi()
HostApi factory,.
Definition api_121.cpp:838
std::vector< std::string > ChartDirectoryExcludedVector
Global instance.
Definition chartdb.cpp:73
ChartDB * ChartData
Global instance.
Definition chartdb.cpp:71
arrayofCanvasPtr g_canvasArray
Global instance.
Definition chcanv.cpp:173
Generic Chart canvas base.
Base class for all chart types.
Definition chartbase.h:126
ChartCanvas - Main chart display and interaction component.
Definition chcanv.h:173
int PrepareContextSelections(double lat, double lon)
Definition chcanv.cpp:7999
void Notify() override
Notify all listeners, no data supplied.
EventVar on_center_ais_target
Notified with a shared_ptr<const AisTargetData> when gFrame should center the given AIS target.
Definition gui_events.h:56
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
Definition gui_events.h:65
EventVar gframe_update_status_bar
Notified when the top level status bas should be updated by gFrame.
Definition gui_events.h:50
virtual bool AddRoute(Route *route, bool permanent=true)
Add route to database, updated version of AddPlugInRouteExV2.
Definition api_121.cpp:842
virtual std::unique_ptr< HostApi121::Route > GetRoute(const wxString &guid)
Retrieve route from database.
Definition api_121.cpp:850
virtual bool UpdateRoute(Route *route)
Update database route, updated version of UpdatePlugInRouteExV2.
Definition api_121.cpp:846
bool m_isVisible
True if route should be displayed.
Plugin_WaypointExV2List * pWaypointList
List of waypoints making up this route in order.
wxString m_StartString
Description of route start point.
wxString m_Description
Optional route description/notes.
wxString m_NameString
User-visible name of the route.
wxString m_GUID
Globally unique identifier.
wxString m_EndString
Description of route end point.
wxDateTime m_ETD
Estimated departure time in UTC, or wxInvalidDateTime if not set.
wxString m_MarkDescription
Optional description text.
wxString m_GUID
Globally unique identifier.
wxString m_TideStation
Tide Station Identifier.
wxDateTime m_CreateTime
Creation timestamp in UTC.
bool m_bShowWaypointRangeRings
True to show range rings on chart.
wxString IconDescription
User-friendly description of icon.
double m_lat
Latitude in decimal degrees.
wxColour RangeRingColor
Color to draw range rings.
bool IsActive
Active state (e.g. destination)
Plugin_HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this waypoint.
double scamin
Minimum display scale (1:X) for waypoint visibility.
double scamax
Maximum display scale (1:X) for waypoint visibility.
bool b_useScamin
True to enable scale-dependent visibility.
wxString IconName
Name of icon to use for waypoint symbol.
bool IsNameVisible
True to show waypoint name on chart.
double m_PlannedSpeed
Planned speed for next leg (knots)
double RangeRingSpace
Distance between range rings in preferred units.
double m_lon
Longitude in decimal degrees.
double m_WaypointArrivalRadius
Arrival radius in nautical miles.
int RangeRingSpaceUnits
Units for range ring spacing - 0:nm, 1:km.
wxString m_MarkName
Display name of waypoint.
bool IsVisible
Visibility state on chart.
int nrange_rings
Number of range rings to display around waypoint.
Extended waypoint class with additional navigation features.
wxDateTime m_CreateTime
Creation timestamp in UTC.
wxColour RangeRingColor
Color to draw range rings.
int nrange_rings
Number of range rings to display around waypoint.
wxString IconDescription
User-friendly description of icon.
bool b_useScamin
True to enable scale-dependent visibility.
double RangeRingSpace
Distance between range rings in preferred units.
Plugin_HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this waypoint.
wxString m_MarkName
Display name of waypoint.
wxString m_GUID
Globally unique identifier.
double m_lon
Longitude in decimal degrees.
wxString IconName
Name of icon to use for waypoint symbol.
double scamin
Minimum display scale (1:X) for waypoint visibility.
bool IsNameVisible
True to show waypoint name on chart.
double m_lat
Latitude in decimal degrees.
wxString m_MarkDescription
Optional description text.
bool IsActive
Active state (e.g. destination)
bool IsVisible
Visibility state on chart.
Represents a waypoint or mark within the navigation system.
Definition route_point.h:71
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_bIsActive
Flag indicating if this waypoint is active for navigation.
wxDateTime GetManualETD()
Retrieves the manually set Estimated Time of Departure for this waypoint, in UTC.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
double GetPlannedSpeed()
Return the planned speed associated with this waypoint.
bool m_btemp
Flag indicating if this is a temporary waypoint.
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.
void SetETD(const wxDateTime &etd)
Sets the Estimated Time of Departure for this waypoint, in UTC.
Represents a navigational route in the navigation system.
Definition route.h:99
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
Definition route.h:203
double m_PlannedSpeed
Default planned speed for the route in knots.
Definition route.h:321
wxString m_RouteStartString
Name or description of the route's starting point.
Definition route.h:252
wxString m_RouteDescription
Additional descriptive information about the route.
Definition route.h:262
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
Definition route.h:336
wxString m_Colour
Color name for rendering the route on the chart.
Definition route.h:346
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
Definition route.h:268
wxString m_RouteEndString
Name or description of the route's ending point.
Definition route.h:257
bool m_btemp
Flag indicating if this is a temporary route.
Definition route.h:351
wxPenStyle m_style
Style of the route line when rendered on the chart.
Definition route.h:293
wxString m_TimeDisplayFormat
Format for displaying times in the UI.
Definition route.h:331
wxString m_RouteNameString
User-assigned name for the route.
Definition route.h:247
wxString m_GUID
Globally unique identifier for this route.
Definition route.h:273
wxDateTime m_PlannedDeparture
Planned departure time for the route, in UTC.
Definition route.h:326
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
Definition route.h:278
int m_lastMousePointIndex
Index of the most recently interacted with route point.
Definition route.h:298
bool DeleteRoute(Route *pRoute)
Definition routeman.cpp:762
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Definition routeman.cpp:222
Represents a track, which is a series of connected track points.
Definition track.h:117
Misc GUI event vars, a singleton.
bool g_b_overzoom_x
Allow high overzoom.
Definition gui_vars.cpp:52
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
MySQL based storage for routes, tracks, etc.
User notifications manager.
PlugIn Object Definition/API.
ChartFamilyEnumPI
Enumeration of chart families (broad categories).
wxWindow * GetCanvasByIndex(int canvasIndex)
Gets chart canvas window by index.
double gLat
Vessel's current latitude in decimal degrees.
Definition own_ship.cpp:26
double gCog
Course over ground in degrees (0-359.99).
Definition own_ship.cpp:28
double gSog
Speed over ground in knots.
Definition own_ship.cpp:29
double gLon
Vessel's current longitude in decimal degrees.
Definition own_ship.cpp:27
Position, course, speed, etc.
Route abstraction.
Routeman * g_pRouteMan
Global instance.
Definition routeman.cpp:60
RouteList * pRouteList
Global instance.
Definition routeman.cpp:66
Select * pSelect
Global instance.
Definition select.cpp:36
Represents an entry in the chart table, containing information about a single chart.
Definition chartdbs.h:187
std::vector< Track * > g_TrackList
Global instance.
Definition track.cpp:96
Recorded track abstraction.