31#include "nav_object_database.h"
34#include "base_platform.h"
39 pSelectList =
new SelectableItemList;
40 pixelRadius = g_BasePlatform->GetSelectRadiusPix();
44 pSelectList->DeleteContents(
true);
49bool Select::IsSelectableRoutePointValid(
RoutePoint *pRoutePoint) {
53 wxSelectableItemListNode *node = pSelectList->GetFirst();
56 pFindSel = node->GetData();
57 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT &&
58 (
RoutePoint *)pFindSel->m_pData1 == pRoutePoint)
60 node = node->GetNext();
65bool Select::AddSelectableRoutePoint(
float slat,
float slon,
68 pSelItem->m_slat = slat;
69 pSelItem->m_slon = slon;
70 pSelItem->m_seltype = SELTYPE_ROUTEPOINT;
71 pSelItem->m_bIsSelected =
false;
72 pSelItem->m_pData1 = pRoutePointAdd;
74 wxSelectableItemListNode *node;
76 if (pRoutePointAdd->m_bIsInLayer)
77 node = pSelectList->Append(pSelItem);
79 node = pSelectList->Insert(pSelItem);
81 pRoutePointAdd->SetSelectNode(node);
86bool Select::AddSelectableRouteSegment(
float slat1,
float slon1,
float slat2,
91 pSelItem->m_slat = slat1;
92 pSelItem->m_slon = slon1;
93 pSelItem->m_slat2 = slat2;
94 pSelItem->m_slon2 = slon2;
95 pSelItem->m_seltype = SELTYPE_ROUTESEGMENT;
96 pSelItem->m_bIsSelected =
false;
97 pSelItem->m_pData1 = pRoutePointAdd1;
98 pSelItem->m_pData2 = pRoutePointAdd2;
99 pSelItem->m_pData3 = pRoute;
101 if (pRoute->m_bIsInLayer)
102 pSelectList->Append(pSelItem);
104 pSelectList->Insert(pSelItem);
109bool Select::DeleteAllSelectableRouteSegments(
Route *pr) {
113 wxSelectableItemListNode *node = pSelectList->GetFirst();
116 pFindSel = node->GetData();
117 if (pFindSel->m_seltype == SELTYPE_ROUTESEGMENT &&
118 (
Route *)pFindSel->m_pData3 == pr) {
120 wxSelectableItemListNode *d = node;
121 node = node->GetNext();
122 pSelectList->DeleteNode(d);
124 node = node->GetNext();
130bool Select::DeleteAllSelectableRoutePoints(
Route *pr) {
134 wxSelectableItemListNode *node = pSelectList->GetFirst();
137 pFindSel = node->GetData();
138 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT) {
142 wxRoutePointListNode *pnode = (pr->pRoutePointList)->GetFirst();
148 pSelectList->DeleteNode(node);
149 prp->SetSelectNode(NULL);
151 node = pSelectList->GetFirst();
153 goto got_next_outer_node;
155 pnode = pnode->GetNext();
159 node = node->GetNext();
166bool Select::AddAllSelectableRoutePoints(
Route *pr) {
167 if (pr->pRoutePointList->GetCount()) {
168 wxRoutePointListNode *node = (pr->pRoutePointList)->GetFirst();
172 AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
173 node = node->GetNext();
180bool Select::AddAllSelectableRouteSegments(
Route *pr) {
182 float slat1, slon1, slat2, slon2;
184 if (pr->pRoutePointList->GetCount()) {
185 wxRoutePointListNode *node = (pr->pRoutePointList)->GetFirst();
191 node = node->GetNext();
198 AddSelectableRouteSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
204 node = node->GetNext();
211bool Select::AddAllSelectableTrackSegments(
Track *pr) {
213 float slat1, slon1, slat2, slon2;
215 if (pr->GetnPoints()) {
220 for (
int i = 1; i < pr->GetnPoints(); i++) {
225 AddSelectableTrackSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
236bool Select::UpdateSelectableRouteSegments(
RoutePoint *prp) {
241 wxSelectableItemListNode *node = pSelectList->GetFirst();
244 pFindSel = node->GetData();
245 if (pFindSel->m_seltype == SELTYPE_ROUTESEGMENT) {
246 if (pFindSel->m_pData1 == prp) {
247 pFindSel->m_slat = prp->m_lat;
248 pFindSel->m_slon = prp->m_lon;
253 else if (pFindSel->m_pData2 == prp) {
254 pFindSel->m_slat2 = prp->m_lat;
255 pFindSel->m_slon2 = prp->m_lon;
259 node = node->GetNext();
265SelectItem *Select::AddSelectablePoint(
float slat,
float slon,
266 const void *pdata,
int fseltype) {
269 pSelItem->m_slat = slat;
270 pSelItem->m_slon = slon;
271 pSelItem->m_seltype = fseltype;
272 pSelItem->m_bIsSelected =
false;
273 pSelItem->m_pData1 = pdata;
275 pSelectList->Append(pSelItem);
290bool Select::DeleteSelectablePoint(
void *pdata,
int SeltypeToDelete) {
295 wxSelectableItemListNode *node = pSelectList->GetFirst();
298 pFindSel = node->GetData();
299 if (pFindSel->m_seltype == SeltypeToDelete) {
300 if (pdata == pFindSel->m_pData1) {
304 if (SELTYPE_ROUTEPOINT == SeltypeToDelete) {
306 prp->SetSelectNode(NULL);
312 node = node->GetNext();
318bool Select::DeleteAllSelectableTypePoints(
int SeltypeToDelete) {
322 wxSelectableItemListNode *node = pSelectList->GetFirst();
325 pFindSel = node->GetData();
326 if (pFindSel->m_seltype == SeltypeToDelete) {
329 if (SELTYPE_ROUTEPOINT == SeltypeToDelete) {
331 prp->SetSelectNode(NULL);
335 node = pSelectList->GetFirst();
339 node = node->GetNext();
346bool Select::DeleteSelectableRoutePoint(
RoutePoint *prp) {
348 wxSelectableItemListNode *node =
349 (wxSelectableItemListNode *)prp->GetSelectNode();
355 prp->SetSelectNode(NULL);
359 return DeleteSelectablePoint(prp, SELTYPE_ROUTEPOINT);
364bool Select::ModifySelectablePoint(
float lat,
float lon,
void *data,
365 int SeltypeToModify) {
369 wxSelectableItemListNode *node = pSelectList->GetFirst();
372 pFindSel = node->GetData();
373 if (pFindSel->m_seltype == SeltypeToModify) {
374 if (data == pFindSel->m_pData1) {
375 pFindSel->m_slat = lat;
376 pFindSel->m_slon = lon;
381 node = node->GetNext();
386bool Select::AddSelectableTrackSegment(
float slat1,
float slon1,
float slat2,
391 pSelItem->m_slat = slat1;
392 pSelItem->m_slon = slon1;
393 pSelItem->m_slat2 = slat2;
394 pSelItem->m_slon2 = slon2;
395 pSelItem->m_seltype = SELTYPE_TRACKSEGMENT;
396 pSelItem->m_bIsSelected =
false;
397 pSelItem->m_pData1 = pTrackPointAdd1;
398 pSelItem->m_pData2 = pTrackPointAdd2;
399 pSelItem->m_pData3 = pTrack;
401 if (pTrack->m_bIsInLayer)
402 pSelectList->Append(pSelItem);
404 pSelectList->Insert(pSelItem);
409bool Select::DeleteAllSelectableTrackSegments(
Track *pt) {
413 wxSelectableItemListNode *node = pSelectList->GetFirst();
416 pFindSel = node->GetData();
417 if (pFindSel->m_seltype == SELTYPE_TRACKSEGMENT &&
418 (
Track *)pFindSel->m_pData3 == pt) {
420 wxSelectableItemListNode *d = node;
421 node = node->GetNext();
422 pSelectList->DeleteNode(d);
424 node = node->GetNext();
429bool Select::DeletePointSelectableTrackSegments(
TrackPoint *pt) {
433 wxSelectableItemListNode *node = pSelectList->GetFirst();
436 pFindSel = node->GetData();
437 if (pFindSel->m_seltype == SELTYPE_TRACKSEGMENT &&
441 wxSelectableItemListNode *d = node;
442 node = node->GetNext();
443 pSelectList->DeleteNode(d);
445 node = node->GetNext();
450bool Select::IsSegmentSelected(
float a,
float b,
float c,
float d,
float slat,
456 if (a > 90.0) a -= 180.0;
457 if (b > 90.0) b -= 180.0;
458 if (c > 180.0) c -= 360.0;
459 if (d > 180.0) d -= 360.0;
460 if (slat > 90.0) slat -= 180.0;
461 if (slon > 180.0) slon -= 360.0;
466 DistanceBearingMercator(a, c, b, d, &brg, &dist);
480 if (slon < 0.) adder = 360.;
485 if ((slat >= (fmin(a, b) - selectRadius)) &&
486 (slat <= (fmax(a, b) + selectRadius)) &&
487 ((slon + adder) >= (fmin(c, d) - selectRadius)) &&
488 ((slon + adder) <= (fmax(c, d) + selectRadius))) {
494 toSM(a, c, 0., 0., &cp, &ap);
496 toSM(b, d, 0., 0., &dp, &bp);
498 toSM(slat, slon + adder, 0., 0., &slonp, &slatp);
505 double delta = vGetLengthOfNormal(&va, &vb, &vn);
506 if (fabs(delta) < (selectRadius * 1852 * 60))
return true;
511void Select::CalcSelectRadius(
SelectCtx& ctx) {
512 selectRadius = pixelRadius / (ctx.scale * 1852 * 60);
520 CalcSelectRadius(ctx);
523 wxSelectableItemListNode *node = pSelectList->GetFirst();
526 pFindSel = node->GetData();
527 if (pFindSel->m_seltype == fseltype) {
529 case SELTYPE_ROUTEPOINT:
530 case SELTYPE_TIDEPOINT:
531 case SELTYPE_CURRENTPOINT:
532 case SELTYPE_AISTARGET:
533 a = fabs(slat - pFindSel->m_slat);
534 b = fabs(slon - pFindSel->m_slon);
536 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
537 (fabs(slon - pFindSel->m_slon) < selectRadius))
540 case SELTYPE_ROUTESEGMENT:
541 case SELTYPE_TRACKSEGMENT: {
542 a = pFindSel->m_slat;
543 b = pFindSel->m_slat2;
544 c = pFindSel->m_slon;
545 d = pFindSel->m_slon2;
547 if (IsSegmentSelected(a, b, c, d, slat, slon))
goto find_ok;
555 node = node->GetNext();
563bool Select::IsSelectableSegmentSelected(
SelectCtx& ctx,
float slat,
566 wxSelectableItemListNode *node = pSelectList->GetFirst();
569 if (pFindSel == node->GetData()) {
573 node = node->GetNext();
576 if (valid ==
false) {
580 CalcSelectRadius(ctx);
582 float a = pFindSel->m_slat;
583 float b = pFindSel->m_slat2;
584 float c = pFindSel->m_slon;
585 float d = pFindSel->m_slon2;
587 return IsSegmentSelected(a, b, c, d, slat, slon);
591 if (ctx.show_nav_objects)
return true;
593 if (wp->m_bIsActive)
return true;
596 rte = FindRouteContainingWaypoint(wp);
597 if (rte && rte->IsActive())
return true;
602SelectableItemList Select::FindSelectionList(
SelectCtx& ctx,
float slat,
603 float slon,
int fseltype) {
606 SelectableItemList ret_list;
608 CalcSelectRadius(ctx);
611 wxSelectableItemListNode *node = pSelectList->GetFirst();
614 pFindSel = node->GetData();
615 if (pFindSel->m_seltype == fseltype) {
617 case SELTYPE_ROUTEPOINT:
618 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
619 (fabs(slon - pFindSel->m_slon) < selectRadius))
620 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
621 if (((
RoutePoint *)pFindSel->m_pData1)->IsVisibleSelectable(ctx.scale))
622 ret_list.Append(pFindSel);
624 case SELTYPE_TIDEPOINT:
625 case SELTYPE_CURRENTPOINT:
626 case SELTYPE_AISTARGET:
627 case SELTYPE_DRAGHANDLE:
628 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
629 (fabs(slon - pFindSel->m_slon) < selectRadius)) {
630 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
631 ret_list.Append(pFindSel);
634 case SELTYPE_ROUTESEGMENT:
635 case SELTYPE_TRACKSEGMENT: {
636 a = pFindSel->m_slat;
637 b = pFindSel->m_slat2;
638 c = pFindSel->m_slon;
639 d = pFindSel->m_slon2;
641 if (IsSegmentSelected(a, b, c, d, slat, slon)) {
642 if (ctx.show_nav_objects ||
643 (fseltype == SELTYPE_ROUTESEGMENT &&
644 ((
Route *)pFindSel->m_pData3)->m_bRtIsActive)) {
645 ret_list.Append(pFindSel);
656 node = node->GetNext();