29#include "model/nav_object_database.h"
40 pSelectList =
new SelectableItemList;
50bool Select::IsSelectableRoutePointValid(
RoutePoint *pRoutePoint) {
55 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT &&
56 (
RoutePoint *)pFindSel->m_pData1 == pRoutePoint)
62bool Select::AddSelectableRoutePoint(
float slat,
float slon,
65 pSelItem->m_slat = slat;
66 pSelItem->m_slon = slon;
67 pSelItem->m_seltype = SELTYPE_ROUTEPOINT;
68 pSelItem->m_bIsSelected =
false;
69 pSelItem->m_pData1 = pRoutePointAdd;
72 pSelectList->push_back(pSelItem);
74 pSelectList->insert(pSelectList->begin(), pSelItem);
76 pRoutePointAdd->SetSelectNode(pSelItem);
81bool Select::AddSelectableRouteSegment(
float slat1,
float slon1,
float slat2,
86 pSelItem->m_slat = slat1;
87 pSelItem->m_slon = slon1;
88 pSelItem->m_slat2 = slat2;
89 pSelItem->m_slon2 = slon2;
90 pSelItem->m_seltype = SELTYPE_ROUTESEGMENT;
91 pSelItem->m_bIsSelected =
false;
92 pSelItem->m_pData1 = pRoutePointAdd1;
93 pSelItem->m_pData2 = pRoutePointAdd2;
94 pSelItem->m_pData3 = pRoute;
97 pSelectList->push_back(pSelItem);
99 pSelectList->insert(pSelectList->begin(), pSelItem);
104bool Select::DeleteAllSelectableRouteSegments(
Route *pr) {
105 auto removed_begin = std::remove_if(
106 pSelectList->begin(), pSelectList->end(), [pr](
SelectItem *si) {
107 bool is_pr = (Route *)si->m_pData3 == pr;
108 if (is_pr) delete si;
111 pSelectList->erase(removed_begin, pSelectList->end());
115bool Select::DeleteAllSelectableRoutePoints(
Route *pr) {
119 auto node = pSelectList->begin();
121 while (node != pSelectList->end()) {
123 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT) {
126 bool is_restarted =
false;
127 for (
RoutePoint *prp : *pr->pRoutePointList) {
130 std::find(pSelectList->begin(), pSelectList->end(), pFindSel);
131 if (pos != pSelectList->end()) pSelectList->erase(pos);
133 prp->SetSelectNode(
nullptr);
134 node = pSelectList->begin();
139 if (!is_restarted) ++node;
147bool Select::AddAllSelectableRoutePoints(
Route *pr) {
149 for (
RoutePoint *prp : *pr->pRoutePointList) {
150 AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
157bool Select::AddAllSelectableRouteSegments(
Route *pr) {
159 float slat1, slon1, slat2, slon2;
171 AddSelectableRouteSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
182bool Select::AddAllSelectableTrackSegments(
Track *pr) {
184 float slat1, slon1, slat2, slon2;
186 if (pr->GetnPoints()) {
191 for (
int i = 1; i < pr->GetnPoints(); i++) {
196 AddSelectableTrackSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
207bool Select::UpdateSelectableRouteSegments(
RoutePoint *prp) {
210 if (pFindSel->m_seltype == SELTYPE_ROUTESEGMENT) {
211 if (pFindSel->m_pData1 == prp) {
212 pFindSel->m_slat = prp->m_lat;
213 pFindSel->m_slon = prp->m_lon;
215 }
else if (pFindSel->m_pData2 == prp) {
216 pFindSel->m_slat2 = prp->m_lat;
217 pFindSel->m_slon2 = prp->m_lon;
226SelectItem *Select::AddSelectablePoint(
float slat,
float slon,
227 const void *pdata,
int fseltype) {
230 pSelItem->m_slat = slat;
231 pSelItem->m_slon = slon;
232 pSelItem->m_seltype = fseltype;
233 pSelItem->m_bIsSelected =
false;
234 pSelItem->m_pData1 = pdata;
236 pSelectList->push_back(pSelItem);
251bool Select::DeleteSelectablePoint(
void *pdata,
int SeltypeToDelete) {
252 if (!pdata)
return false;
255 std::remove_if(pSelectList->begin(), pSelectList->end(),
257 bool is_victim = si->m_seltype == SeltypeToDelete &&
258 si->m_pData1 == pdata;
259 if (is_victim) delete si;
260 if (is_victim && SELTYPE_ROUTEPOINT == SeltypeToDelete) {
261 RoutePoint *prp = (RoutePoint *)pdata;
262 prp->SetSelectNode(NULL);
266 pSelectList->erase(removed_begin, pSelectList->end());
270bool Select::DeleteAllSelectableTypePoints(
int SeltypeToDelete) {
272 std::remove_if(pSelectList->begin(), pSelectList->end(),
274 bool is_match = si->m_seltype == SeltypeToDelete;
275 if (is_match && SELTYPE_ROUTEPOINT == SeltypeToDelete) {
276 RoutePoint *prp = (RoutePoint *)si->m_pData1;
277 prp->SetSelectNode(NULL);
279 if (is_match)
delete si;
282 pSelectList->erase(removed_begin, pSelectList->end());
287bool Select::DeleteSelectableRoutePoint(
RoutePoint *prp) {
288 if (!prp)
return false;
289 auto *pFindSel = (
SelectItem *)prp->GetSelectNode();
291 auto pos = std::find(pSelectList->begin(), pSelectList->end(), pFindSel);
292 if (pos != pSelectList->end()) pSelectList->erase(pos);
294 prp->SetSelectNode(
nullptr);
297 return DeleteSelectablePoint(prp, SELTYPE_ROUTEPOINT);
301bool Select::ModifySelectablePoint(
float lat,
float lon,
void *data,
302 int SeltypeToModify) {
307 if (pFindSel->m_seltype == SeltypeToModify) {
308 if (data == pFindSel->m_pData1) {
309 pFindSel->m_slat = lat;
310 pFindSel->m_slon = lon;
318bool Select::AddSelectableTrackSegment(
float slat1,
float slon1,
float slat2,
323 pSelItem->m_slat = slat1;
324 pSelItem->m_slon = slon1;
325 pSelItem->m_slat2 = slat2;
326 pSelItem->m_slon2 = slon2;
327 pSelItem->m_seltype = SELTYPE_TRACKSEGMENT;
328 pSelItem->m_bIsSelected =
false;
329 pSelItem->m_pData1 = pTrackPointAdd1;
330 pSelItem->m_pData2 = pTrackPointAdd2;
331 pSelItem->m_pData3 = pTrack;
333 if (pTrack->m_bIsInLayer)
334 pSelectList->push_back(pSelItem);
336 pSelectList->insert(pSelectList->begin(), pSelItem);
341bool Select::DeleteAllSelectableTrackSegments(
Track *pt) {
342 auto removed_begin = std::remove_if(
343 pSelectList->begin(), pSelectList->end(), [pt](
SelectItem *si) {
344 bool is_victim = si->m_seltype == SELTYPE_TRACKSEGMENT &&
345 (Track *)si->m_pData3 == pt;
346 if (is_victim) delete si;
349 pSelectList->erase(removed_begin, pSelectList->end());
353bool Select::DeletePointSelectableTrackSegments(
TrackPoint *pt) {
354 auto removed_begin = std::remove_if(
355 pSelectList->begin(), pSelectList->end(), [pt](
SelectItem *si) {
356 bool is_victim = si->m_seltype == SELTYPE_TRACKSEGMENT &&
357 ((TrackPoint *)si->m_pData1 == pt ||
358 (TrackPoint *)si->m_pData2 == pt);
359 if (is_victim) delete si;
362 pSelectList->erase(removed_begin, pSelectList->end());
366bool Select::IsSegmentSelected(
float a,
float b,
float c,
float d,
float slat,
372 if (a > 90.0) a -= 180.0;
373 if (b > 90.0) b -= 180.0;
374 if (c > 180.0) c -= 360.0;
375 if (d > 180.0) d -= 360.0;
376 if (slat > 90.0) slat -= 180.0;
377 if (slon > 180.0) slon -= 360.0;
382 DistanceBearingMercator(a, c, b, d, &brg, &dist);
396 if (slon < 0.) adder = 360.;
401 if ((slat >= (fmin(a, b) - selectRadius)) &&
402 (slat <= (fmax(a, b) + selectRadius)) &&
403 ((slon + adder) >= (fmin(c, d) - selectRadius)) &&
404 ((slon + adder) <= (fmax(c, d) + selectRadius))) {
410 toSM(a, c, 0., 0., &cp, &ap);
412 toSM(b, d, 0., 0., &dp, &bp);
414 toSM(slat, slon + adder, 0., 0., &slonp, &slatp);
421 double delta = vGetLengthOfNormal(&va, &vb, &vn);
422 if (fabs(delta) < (selectRadius * 1852 * 60))
return true;
427void Select::CalcSelectRadius(
SelectCtx &ctx) {
428 selectRadius = pixelRadius / (ctx.scale * 1852 * 60);
436 CalcSelectRadius(ctx);
441 if (pFindSel->m_seltype == fseltype) {
443 case SELTYPE_ROUTEPOINT:
444 case SELTYPE_TIDEPOINT:
445 case SELTYPE_CURRENTPOINT:
446 case SELTYPE_AISTARGET:
447 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
448 (fabs(slon - pFindSel->m_slon) < selectRadius)) {
449 if (fseltype == SELTYPE_ROUTEPOINT) {
451 ->IsVisibleSelectable(ctx.chart_scale))
458 case SELTYPE_ROUTESEGMENT:
459 case SELTYPE_TRACKSEGMENT: {
460 a = pFindSel->m_slat;
461 b = pFindSel->m_slat2;
462 c = pFindSel->m_slon;
463 d = pFindSel->m_slon2;
465 if (IsSegmentSelected(a, b, c, d, slat, slon))
goto find_ok;
479bool Select::IsSelectableSegmentSelected(
SelectCtx &ctx,
float slat,
float slon,
483 if (pFindSel == si) {
489 if (valid ==
false) {
493 CalcSelectRadius(ctx);
495 float a = pFindSel->m_slat;
496 float b = pFindSel->m_slat2;
497 float c = pFindSel->m_slon;
498 float d = pFindSel->m_slon2;
500 return IsSegmentSelected(a, b, c, d, slat, slon);
504 if (ctx.show_nav_objects)
return true;
509 rte = FindRouteContainingWaypoint(wp);
510 if (rte && rte->IsActive())
return true;
515SelectableItemList Select::FindSelectionList(
SelectCtx &ctx,
float slat,
516 float slon,
int fseltype) {
519 SelectableItemList ret_list;
521 CalcSelectRadius(ctx);
526 if (pFindSel->m_seltype == fseltype) {
528 case SELTYPE_ROUTEPOINT:
529 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
530 (fabs(slon - pFindSel->m_slon) < selectRadius))
531 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
533 ->IsVisibleSelectable(ctx.chart_scale))
534 ret_list.push_back(pFindSel);
536 case SELTYPE_TIDEPOINT:
537 case SELTYPE_CURRENTPOINT:
538 case SELTYPE_AISTARGET:
539 case SELTYPE_DRAGHANDLE:
540 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
541 (fabs(slon - pFindSel->m_slon) < selectRadius)) {
542 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
543 ret_list.push_back(pFindSel);
546 case SELTYPE_ROUTESEGMENT:
547 case SELTYPE_TRACKSEGMENT: {
548 a = pFindSel->m_slat;
549 b = pFindSel->m_slat2;
550 c = pFindSel->m_slon;
551 d = pFindSel->m_slon2;
553 if (IsSegmentSelected(a, b, c, d, slat, slon)) {
554 if (ctx.show_nav_objects ||
555 (fseltype == SELTYPE_ROUTESEGMENT &&
556 ((
Route *)pFindSel->m_pData3)->m_bRtIsActive)) {
557 ret_list.push_back(pFindSel);
Represents a waypoint or mark within the navigation system.
bool m_bIsActive
Flag indicating if this waypoint is active for navigation.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
Represents a single point in a track.
Represents a track, which is a series of connected track points.
Select * pSelect
Global instance.
Select * pSelectTC
Global instance.
Selected route, segment, waypoint, etc.
Recorded track abstraction.