26 #include <wx/gdicmn.h>
28 #include "model/base_platform.h"
29 #include "model/georef.h"
30 #include "model/nav_object_database.h"
31 #include "model/route.h"
32 #include "model/select.h"
33 #include "model/track.h"
40 pSelectList =
new SelectableItemList;
41 pixelRadius = g_BasePlatform->GetSelectRadiusPix();
45 pSelectList->DeleteContents(
true);
50 bool Select::IsSelectableRoutePointValid(
RoutePoint *pRoutePoint) {
54 wxSelectableItemListNode *node = pSelectList->GetFirst();
57 pFindSel = node->GetData();
58 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT &&
59 (
RoutePoint *)pFindSel->m_pData1 == pRoutePoint)
61 node = node->GetNext();
66 bool Select::AddSelectableRoutePoint(
float slat,
float slon,
69 pSelItem->m_slat = slat;
70 pSelItem->m_slon = slon;
71 pSelItem->m_seltype = SELTYPE_ROUTEPOINT;
72 pSelItem->m_bIsSelected =
false;
73 pSelItem->m_pData1 = pRoutePointAdd;
75 wxSelectableItemListNode *node;
77 if (pRoutePointAdd->m_bIsInLayer)
78 node = pSelectList->Append(pSelItem);
80 node = pSelectList->Insert(pSelItem);
82 pRoutePointAdd->SetSelectNode(node);
87 bool Select::AddSelectableRouteSegment(
float slat1,
float slon1,
float slat2,
92 pSelItem->m_slat = slat1;
93 pSelItem->m_slon = slon1;
94 pSelItem->m_slat2 = slat2;
95 pSelItem->m_slon2 = slon2;
96 pSelItem->m_seltype = SELTYPE_ROUTESEGMENT;
97 pSelItem->m_bIsSelected =
false;
98 pSelItem->m_pData1 = pRoutePointAdd1;
99 pSelItem->m_pData2 = pRoutePointAdd2;
100 pSelItem->m_pData3 = pRoute;
102 if (pRoute->m_bIsInLayer)
103 pSelectList->Append(pSelItem);
105 pSelectList->Insert(pSelItem);
110 bool Select::DeleteAllSelectableRouteSegments(
Route *pr) {
114 wxSelectableItemListNode *node = pSelectList->GetFirst();
117 pFindSel = node->GetData();
118 if (pFindSel->m_seltype == SELTYPE_ROUTESEGMENT &&
119 (
Route *)pFindSel->m_pData3 == pr) {
121 wxSelectableItemListNode *d = node;
122 node = node->GetNext();
123 pSelectList->DeleteNode(d);
125 node = node->GetNext();
131 bool Select::DeleteAllSelectableRoutePoints(
Route *pr) {
135 wxSelectableItemListNode *node = pSelectList->GetFirst();
138 pFindSel = node->GetData();
139 if (pFindSel->m_seltype == SELTYPE_ROUTEPOINT) {
143 wxRoutePointListNode *pnode = (pr->pRoutePointList)->GetFirst();
149 pSelectList->DeleteNode(node);
150 prp->SetSelectNode(NULL);
152 node = pSelectList->GetFirst();
154 goto got_next_outer_node;
156 pnode = pnode->GetNext();
160 node = node->GetNext();
167 bool Select::AddAllSelectableRoutePoints(
Route *pr) {
168 if (pr->pRoutePointList->GetCount()) {
169 wxRoutePointListNode *node = (pr->pRoutePointList)->GetFirst();
173 AddSelectableRoutePoint(prp->m_lat, prp->m_lon, prp);
174 node = node->GetNext();
181 bool Select::AddAllSelectableRouteSegments(
Route *pr) {
183 float slat1, slon1, slat2, slon2;
185 if (pr->pRoutePointList->GetCount()) {
186 wxRoutePointListNode *node = (pr->pRoutePointList)->GetFirst();
192 node = node->GetNext();
199 AddSelectableRouteSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
205 node = node->GetNext();
212 bool Select::AddAllSelectableTrackSegments(
Track *pr) {
214 float slat1, slon1, slat2, slon2;
216 if (pr->GetnPoints()) {
221 for (
int i = 1; i < pr->GetnPoints(); i++) {
226 AddSelectableTrackSegment(slat1, slon1, slat2, slon2, prp0, prp, pr);
237 bool Select::UpdateSelectableRouteSegments(
RoutePoint *prp) {
242 wxSelectableItemListNode *node = pSelectList->GetFirst();
245 pFindSel = node->GetData();
246 if (pFindSel->m_seltype == SELTYPE_ROUTESEGMENT) {
247 if (pFindSel->m_pData1 == prp) {
248 pFindSel->m_slat = prp->m_lat;
249 pFindSel->m_slon = prp->m_lon;
254 else if (pFindSel->m_pData2 == prp) {
255 pFindSel->m_slat2 = prp->m_lat;
256 pFindSel->m_slon2 = prp->m_lon;
260 node = node->GetNext();
266 SelectItem *Select::AddSelectablePoint(
float slat,
float slon,
267 const void *pdata,
int fseltype) {
270 pSelItem->m_slat = slat;
271 pSelItem->m_slon = slon;
272 pSelItem->m_seltype = fseltype;
273 pSelItem->m_bIsSelected =
false;
274 pSelItem->m_pData1 = pdata;
276 pSelectList->Append(pSelItem);
291 bool Select::DeleteSelectablePoint(
void *pdata,
int SeltypeToDelete) {
296 wxSelectableItemListNode *node = pSelectList->GetFirst();
299 pFindSel = node->GetData();
300 if (pFindSel->m_seltype == SeltypeToDelete) {
301 if (pdata == pFindSel->m_pData1) {
305 if (SELTYPE_ROUTEPOINT == SeltypeToDelete) {
307 prp->SetSelectNode(NULL);
313 node = node->GetNext();
319 bool Select::DeleteAllSelectableTypePoints(
int SeltypeToDelete) {
323 wxSelectableItemListNode *node = pSelectList->GetFirst();
326 pFindSel = node->GetData();
327 if (pFindSel->m_seltype == SeltypeToDelete) {
330 if (SELTYPE_ROUTEPOINT == SeltypeToDelete) {
332 prp->SetSelectNode(NULL);
336 node = pSelectList->GetFirst();
340 node = node->GetNext();
347 bool Select::DeleteSelectableRoutePoint(
RoutePoint *prp) {
349 wxSelectableItemListNode *node =
350 (wxSelectableItemListNode *)prp->GetSelectNode();
356 prp->SetSelectNode(NULL);
360 return DeleteSelectablePoint(prp, SELTYPE_ROUTEPOINT);
365 bool Select::ModifySelectablePoint(
float lat,
float lon,
void *data,
366 int SeltypeToModify) {
370 wxSelectableItemListNode *node = pSelectList->GetFirst();
373 pFindSel = node->GetData();
374 if (pFindSel->m_seltype == SeltypeToModify) {
375 if (data == pFindSel->m_pData1) {
376 pFindSel->m_slat = lat;
377 pFindSel->m_slon = lon;
382 node = node->GetNext();
387 bool Select::AddSelectableTrackSegment(
float slat1,
float slon1,
float slat2,
392 pSelItem->m_slat = slat1;
393 pSelItem->m_slon = slon1;
394 pSelItem->m_slat2 = slat2;
395 pSelItem->m_slon2 = slon2;
396 pSelItem->m_seltype = SELTYPE_TRACKSEGMENT;
397 pSelItem->m_bIsSelected =
false;
398 pSelItem->m_pData1 = pTrackPointAdd1;
399 pSelItem->m_pData2 = pTrackPointAdd2;
400 pSelItem->m_pData3 = pTrack;
402 if (pTrack->m_bIsInLayer)
403 pSelectList->Append(pSelItem);
405 pSelectList->Insert(pSelItem);
410 bool Select::DeleteAllSelectableTrackSegments(
Track *pt) {
414 wxSelectableItemListNode *node = pSelectList->GetFirst();
417 pFindSel = node->GetData();
418 if (pFindSel->m_seltype == SELTYPE_TRACKSEGMENT &&
419 (
Track *)pFindSel->m_pData3 == pt) {
421 wxSelectableItemListNode *d = node;
422 node = node->GetNext();
423 pSelectList->DeleteNode(d);
425 node = node->GetNext();
430 bool Select::DeletePointSelectableTrackSegments(
TrackPoint *pt) {
434 wxSelectableItemListNode *node = pSelectList->GetFirst();
437 pFindSel = node->GetData();
438 if (pFindSel->m_seltype == SELTYPE_TRACKSEGMENT &&
442 wxSelectableItemListNode *d = node;
443 node = node->GetNext();
444 pSelectList->DeleteNode(d);
446 node = node->GetNext();
451 bool Select::IsSegmentSelected(
float a,
float b,
float c,
float d,
float slat,
457 if (a > 90.0) a -= 180.0;
458 if (b > 90.0) b -= 180.0;
459 if (c > 180.0) c -= 360.0;
460 if (d > 180.0) d -= 360.0;
461 if (slat > 90.0) slat -= 180.0;
462 if (slon > 180.0) slon -= 360.0;
467 DistanceBearingMercator(a, c, b, d, &brg, &dist);
481 if (slon < 0.) adder = 360.;
486 if ((slat >= (fmin(a, b) - selectRadius)) &&
487 (slat <= (fmax(a, b) + selectRadius)) &&
488 ((slon + adder) >= (fmin(c, d) - selectRadius)) &&
489 ((slon + adder) <= (fmax(c, d) + selectRadius))) {
495 toSM(a, c, 0., 0., &cp, &ap);
497 toSM(b, d, 0., 0., &dp, &bp);
499 toSM(slat, slon + adder, 0., 0., &slonp, &slatp);
506 double delta = vGetLengthOfNormal(&va, &vb, &vn);
507 if (fabs(delta) < (selectRadius * 1852 * 60))
return true;
512 void Select::CalcSelectRadius(
SelectCtx& ctx) {
513 selectRadius = pixelRadius / (ctx.scale * 1852 * 60);
521 CalcSelectRadius(ctx);
524 wxSelectableItemListNode *node = pSelectList->GetFirst();
527 pFindSel = node->GetData();
528 if (pFindSel->m_seltype == fseltype) {
530 case SELTYPE_ROUTEPOINT:
531 case SELTYPE_TIDEPOINT:
532 case SELTYPE_CURRENTPOINT:
533 case SELTYPE_AISTARGET:
534 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
535 (fabs(slon - pFindSel->m_slon) < selectRadius)) {
536 if(fseltype == SELTYPE_ROUTEPOINT) {
537 if (((
RoutePoint *)pFindSel->m_pData1)->IsVisibleSelectable(ctx.chart_scale))
544 case SELTYPE_ROUTESEGMENT:
545 case SELTYPE_TRACKSEGMENT: {
546 a = pFindSel->m_slat;
547 b = pFindSel->m_slat2;
548 c = pFindSel->m_slon;
549 d = pFindSel->m_slon2;
551 if (IsSegmentSelected(a, b, c, d, slat, slon))
goto find_ok;
559 node = node->GetNext();
567 bool Select::IsSelectableSegmentSelected(
SelectCtx& ctx,
float slat,
570 wxSelectableItemListNode *node = pSelectList->GetFirst();
573 if (pFindSel == node->GetData()) {
577 node = node->GetNext();
580 if (valid ==
false) {
584 CalcSelectRadius(ctx);
586 float a = pFindSel->m_slat;
587 float b = pFindSel->m_slat2;
588 float c = pFindSel->m_slon;
589 float d = pFindSel->m_slon2;
591 return IsSegmentSelected(a, b, c, d, slat, slon);
595 if (ctx.show_nav_objects)
return true;
597 if (wp->m_bIsActive)
return true;
600 rte = FindRouteContainingWaypoint(wp);
601 if (rte && rte->IsActive())
return true;
606 SelectableItemList Select::FindSelectionList(
SelectCtx& ctx,
float slat,
607 float slon,
int fseltype) {
610 SelectableItemList ret_list;
612 CalcSelectRadius(ctx);
615 wxSelectableItemListNode *node = pSelectList->GetFirst();
618 pFindSel = node->GetData();
619 if (pFindSel->m_seltype == fseltype) {
621 case SELTYPE_ROUTEPOINT:
622 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
623 (fabs(slon - pFindSel->m_slon) < selectRadius))
624 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
625 if (((
RoutePoint *)pFindSel->m_pData1)->IsVisibleSelectable(ctx.chart_scale))
626 ret_list.Append(pFindSel);
628 case SELTYPE_TIDEPOINT:
629 case SELTYPE_CURRENTPOINT:
630 case SELTYPE_AISTARGET:
631 case SELTYPE_DRAGHANDLE:
632 if ((fabs(slat - pFindSel->m_slat) < selectRadius) &&
633 (fabs(slon - pFindSel->m_slon) < selectRadius)) {
634 if (is_selectable_wp(ctx, (
RoutePoint *)pFindSel->m_pData1))
635 ret_list.Append(pFindSel);
638 case SELTYPE_ROUTESEGMENT:
639 case SELTYPE_TRACKSEGMENT: {
640 a = pFindSel->m_slat;
641 b = pFindSel->m_slat2;
642 c = pFindSel->m_slon;
643 d = pFindSel->m_slon2;
645 if (IsSegmentSelected(a, b, c, d, slat, slon)) {
646 if (ctx.show_nav_objects ||
647 (fseltype == SELTYPE_ROUTESEGMENT &&
648 ((
Route *)pFindSel->m_pData3)->m_bRtIsActive)) {
649 ret_list.Append(pFindSel);
660 node = node->GetNext();