// // Sollfarh / Dolphin Speed calculator // void SpeedToFly(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (((AutoMcMode == amcFinalGlide) || (AutoMcMode == amcFinalAndClimb)) && DoOptimizeRoute() && Calculated->NextAltitude > 0.) { // Special case for Conical end of Speed section int Type = -1; double ConeSlope = 0.0; LockTaskData(); if (ValidTaskPoint(ActiveWayPoint)) { GetTaskSectorParameter(ActiveWayPoint, &Type, NULL); ConeSlope = Task[ActiveWayPoint].PGConeSlope; } UnlockTaskData(); if (Type == CONE && ConeSlope > 0.0) { double VOpt = GlidePolar::FindSpeedForSlope(ConeSlope); double eqMC = GlidePolar::EquMC(VOpt); if(eqMC <= MACCREADY ) { Calculated->VOpt = VOpt; return; } } } double HeadWind = 0; if (Calculated->FinalGlide && ValidTaskPoint(ActiveWayPoint)) { // according to MC theory STF take account of wind only if on final Glide // TODO : for the future add config parameter for always use wind. if (Calculated->HeadWind != -999) { HeadWind = Calculated->HeadWind; } } // this is IAS for best Ground Glide ratio acounting current air mass ( wind / Netto vario ) double VOptnew = GlidePolar::STF(MACCREADY, Calculated->NettoVario, HeadWind); // apply cruises efficiency factor. VOptnew *= CRUISE_EFFICIENCY; if (Calculated->NettoVario > MACCREADY) { // this air mass is better than maccready, so don't fly at speed less than minimum sink speed adjusted for load factor double n = fabs((Basic->AccelerationAvailable) ? Basic->AccelZ : Calculated->Gload); VOptnew = max(VOptnew, GlidePolar::Vminsink() * sqrt(n)); } else { // never fly at speed less than min sink speed VOptnew = max(VOptnew, GlidePolar::Vminsink()); } // use low pass filter for avoid big jump of value. Calculated->VOpt = LowPassFilter(Calculated->VOpt, VOptnew, 0.6); }
void PGTaskMgr::Initialize() { std::for_each(m_Task.begin(), m_Task.end(), safe_delete()); m_Task.clear(); // build Mercator Reference Grid // find center of Task double minlat = 0.0, minlon = 0.0, maxlat = 0.0, maxlon = 0.0; for (int curwp = 0; ValidTaskPoint(curwp); ++curwp) { if (curwp == 0) { maxlat = minlat = WayPointList[Task[curwp].Index].Latitude; maxlon = minlon = WayPointList[Task[curwp].Index].Longitude; } else { minlat = std::min(minlat, WayPointList[Task[curwp].Index].Latitude); maxlat = std::max(maxlat, WayPointList[Task[curwp].Index].Latitude); minlon = std::min(minlon, WayPointList[Task[curwp].Index].Longitude); maxlon = std::max(maxlon, WayPointList[Task[curwp].Index].Longitude); } } m_Grid.lat0 = deg2rad(minlat + maxlat) * 1 / 2; m_Grid.lon0 = deg2rad(minlon + maxlon) * 1 / 2; m_Grid.k0 = 1; m_Grid.false_e = 0.0; // ???? m_Grid.false_n = 0.0; // ???? // build task point list for (int curwp = 0; ValidTaskPoint(curwp); ++curwp) { int TpType = 0; double Radius; GetTaskSectorParameter(curwp, &TpType, &Radius); switch (TpType) { case CIRCLE: AddCircle(curwp); break; case SECTOR: case DAe: AddSector(curwp); break; case LINE: AddLine(curwp); break; case CONE: AddCone(curwp); break; case ESS_CIRCLE: AddEssCircle(curwp); break; } } }
void DoAutoMacCready(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (!Calculated->AutoMacCready) return; bool is_final_glide = false; bool is_conical_ess = false; double ConeSlope = 0.0; // LockFlightData(); LockTaskData(); double mc_new = MACCREADY; static bool first_mc = true; if (AutoMcMode == amcEquivalent) { if ((!Calculated->Circling) && (!Calculated->OnGround)) { if (Calculated->EqMc >= 0) { // MACCREADY = LowPassFilter(MACCREADY,Calculated->EqMc,0.8); CheckSetMACCREADY(Calculated->EqMc); } else { // -1.0 is used as an invalid flag. Normally flying at -1 MC means almost flying // at stall speed, which is pretty unusual. Maybe in wave conditions? if (Calculated->EqMc >-1) { CheckSetMACCREADY(Calculated->EqMc*-1); } } } UnlockTaskData(); return; } // otherwise, if AutoMc for finalglide or "both", return if no goto if (ValidTaskPoint(ActiveWayPoint)) { if (Calculated->FinalGlide && ActiveIsFinalWaypoint()) { is_final_glide = true; } else { first_mc = true; } if (DoOptimizeRoute() && Calculated->NextAltitude > 0.) { // Special case for Conical end of Speed section int Type = -1; GetTaskSectorParameter(ActiveWayPoint, &Type, NULL); ConeSlope = Task[ActiveWayPoint].PGConeSlope; if (Type == CONE && ConeSlope > 0.0) { is_final_glide = true; is_conical_ess = true; } } } double av_thermal = -1; if (flightstats.ThermalAverage.y_ave > 0) { if (Calculated->Circling && (Calculated->AverageThermal > 0)) { #if BUGSTOP LKASSERT((flightstats.ThermalAverage.sum_n + 1) != 0); #endif if (flightstats.ThermalAverage.sum_n == -1) { flightstats.ThermalAverage.sum_n = -0.99; } av_thermal = (flightstats.ThermalAverage.y_ave * flightstats.ThermalAverage.sum_n + Calculated->AverageThermal) / (flightstats.ThermalAverage.sum_n + 1); } else { av_thermal = flightstats.ThermalAverage.y_ave; } } else if (Calculated->Circling && (Calculated->AverageThermal > 0)) { // insufficient stats, so use this/last thermal's average av_thermal = Calculated->AverageThermal; } if (!ValidTaskPoint(ActiveWayPoint)) { if (av_thermal > 0) { mc_new = av_thermal; } else { mc_new = 0; } } else if (((AutoMcMode == amcFinalGlide) || (AutoMcMode == amcFinalAndClimb)) && is_final_glide) { if (Calculated->TaskAltitudeDifference0 > 0) { // only change if above final glide with zero Mc // otherwise when we are well below, it will wind Mc back to // zero #if BUGSTOP LKASSERT((Calculated->WaypointDistance + 1) != 0); #endif if (Calculated->WaypointDistance < 0) Calculated->WaypointDistance = 0; // temporary but ok double slope = (Calculated->NavAltitude + Calculated->EnergyHeight - FAIFinishHeight(Basic, Calculated, ActiveWayPoint)) / (Calculated->WaypointDistance + 1); double mc_pirker = PirkerAnalysis(Basic, Calculated, Calculated->WaypointBearing, slope); mc_pirker = max(0.0, mc_pirker); if (first_mc) { // don't allow Mc to wind down to zero when first achieving // final glide; but do allow it to wind down after that if (mc_pirker >= mc_new) { mc_new = mc_pirker; first_mc = false; } else if (AutoMcMode == amcFinalAndClimb) { // revert to averager based auto Mc if (av_thermal > 0) { mc_new = av_thermal; } } } else { mc_new = mc_pirker; } if (is_conical_ess) { const double VOpt = GlidePolar::FindSpeedForSlope(ConeSlope); const double eqMC = GlidePolar::EquMC(VOpt); if(mc_new > eqMC) { mc_new = eqMC; } } } else { // below final glide at zero Mc, never achieved final glide if (first_mc && (AutoMcMode == amcFinalAndClimb)) { // revert to averager based auto Mc if (av_thermal > 0) { mc_new = av_thermal; } } } } else if ((AutoMcMode == amcAverageClimb) || ((AutoMcMode == amcFinalAndClimb)&& !is_final_glide)) { if (av_thermal > 0) { mc_new = av_thermal; } } CheckSetMACCREADY(LowPassFilter(MACCREADY, mc_new, 0.6)); UnlockTaskData(); // UnlockFlightData(); }
// // THIS FUNCTION IS THREAD SAFE, but not using optimized clipping // void MapWindow::DrawTaskPicto(HDC hdc,int TaskIdx, RECT rc, double fScaleFact) { int center_x = (rc.right-rc.left)/2; int center_y = (rc.bottom-rc.top)/2; int SecType = SectorType; int width = center_x-2; HPEN oldpen = 0; HBRUSH oldbrush = 0; if(AATEnabled) oldbrush = (HBRUSH) SelectObject(hdc, LKBrush_LightGrey); else oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); int finish=0; while( ValidTaskPoint(finish)) finish++; finish--; if(center_y < width) width = center_y-2; POINT startfinishline[2] = {{0,-width/ScreenScale}, {0,width/ScreenScale}}; POINT track[3] = {{0,-width/5/ScreenScale}, {width/2/ScreenScale,0}, {0,width/5/ScreenScale}}; if(TaskIdx == finish) { track[0].x = -width/2/ScreenScale; track[0].y= -width/5/ScreenScale; track[1].x = 0 ; track[1].y= 0; track[2].x = -width/2/ScreenScale ; track[2].y= width/5/ScreenScale; } LockTaskData(); // protect from external task changes double StartRadial = Task[TaskIdx].AATStartRadial; double FinishRadial = Task[TaskIdx].AATFinishRadial; if(TaskIdx==0) { FinishRadial = Task[TaskIdx].AATStartRadial; StartRadial = Task[TaskIdx].AATFinishRadial; } double LineBrg; double SecRadius; GetTaskSectorParameter( TaskIdx, &SecType,&SecRadius); switch (SecType) { case CIRCLE: CircleNoCliping(hdc, center_x, center_y, width-2, rc, true); break; case SECTOR: Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules CircleNoCliping(hdc, center_x, center_y, width/8, rc, true); Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); } break; default: case LINE: if (TaskIdx == 0) { LineBrg = Task[TaskIdx].OutBound-90; } else if (TaskIdx == finish) { LineBrg = Task[TaskIdx].InBound-90; } else { LineBrg = Task[TaskIdx].Bisector; } threadsafePolygonRotateShift(startfinishline, 2, center_x, center_y, LineBrg); Polygon(hdc, startfinishline, 2); if ((TaskIdx == 0) || (TaskIdx == finish)) { threadsafePolygonRotateShift(track, 3, center_x, center_y, LineBrg); Polygon(hdc, track, 3); } break; case CONE: if (DoOptimizeRoute()) { int radius = width-2; CircleNoCliping(hdc, center_x, center_y, radius, rc, true); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int i = 1; i < 4 && radius > (width/5); ++i) { CircleNoCliping(hdc, center_x, center_y, radius -= width/5, rc, true); } ::SelectObject(hdc, prevPen); } break; } UnlockTaskData(); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }
void MapWindow::DrawTask(HDC hdc, RECT rc, const POINT &Orig_Aircraft) { int i; double tmp; COLORREF whitecolor = RGB_WHITE; COLORREF origcolor = SetTextColor(hDCTemp, whitecolor); HPEN oldpen = 0; HBRUSH oldbrush = 0; static short size_tasklines=0; if (DoInit[MDI_DRAWTASK]) { switch (ScreenSize) { case ss480x272: case ss272x480: case ss320x240: case ss240x320: size_tasklines=NIBLSCALE(4); break; default: size_tasklines=NIBLSCALE(3); break; } DoInit[MDI_DRAWTASK]=false; } if (!WayPointList) return; oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); LockTaskData(); // protect from external task changes for (i = 1; ValidTaskPoint(i); i++) { if (!ValidTaskPoint(i + 1)) { // final waypoint if (ActiveWayPoint > 1 || !ValidTaskPoint(2)) { // only draw finish line when past the first // waypoint. FIXED 110307: or if task is with only 2 tps DrawStartEndSector(hdc, rc, Task[i].Start, Task[i].End, Task[i].Index, FinishLine, FinishRadius); } } else { // normal sector if (AATEnabled != TRUE) { //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); } int Type = 0; double Radius = 0.; GetTaskSectorParameter(i, &Type, &Radius); switch (Type) { case CIRCLE: tmp = Radius * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); break; case SECTOR: tmp = Radius * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules tmp = 500 * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); tmp = 10e3 * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); } break; case LINE: if (!AATEnabled) { // this Type exist only if not AAT task if(ISGAAIRCRAFT) { POINT start,end; double rotation=AngleLimit360(Task[i].Bisector-DisplayAngle); int length=14*ScreenScale; //Make intermediate WP lines always of the same size independent by zoom level start.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); start.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); rotation=Reciprocal(rotation); end.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); end.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), start, end, taskcolor, rc); } else _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), Task[i].Start, Task[i].End, taskcolor, rc); } break; case CONE: tmp = Radius * zoom.ResScaleOverDistanceModify(); int center_x = WayPointList[Task[i].Index].Screen.x; int center_y = WayPointList[Task[i].Index].Screen.y; Circle(hdc, center_x, center_y, (int) tmp, rc, false, false); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int j = 1; j < 5 && tmp > 0; ++j) { Circle(hdc, center_x, center_y, tmp -= NIBLSCALE(5), rc, true, true); } ::SelectObject(hdc, prevPen); break; } if (AATEnabled && !DoOptimizeRoute()) { // ELSE HERE IS *** AAT *** // JMW added iso lines if ((i == ActiveWayPoint) || (mode.Is(Mode::MODE_TARGET_PAN) && (i == TargetPanIndex))) { // JMW 20080616 flash arc line if very close to target static bool flip = false; if (DerivedDrawInfo.WaypointDistance < AATCloseDistance()*2.0) { flip = !flip; } else { flip = true; } if (flip) { for (int j = 0; j < MAXISOLINES - 1; j++) { if (TaskStats[i].IsoLine_valid[j] && TaskStats[i].IsoLine_valid[j + 1]) { _DrawLine(hdc, PS_SOLID, NIBLSCALE(2), TaskStats[i].IsoLine_Screen[j], TaskStats[i].IsoLine_Screen[j + 1], RGB(0, 0, 255), rc); } } } } } } } if ((ActiveWayPoint < 2) && ValidTaskPoint(0) && ValidTaskPoint(1)) { DrawStartEndSector(hdc, rc, Task[0].Start, Task[0].End, Task[0].Index, StartLine, StartRadius); if (EnableMultipleStartPoints) { for (i = 0; i < MAXSTARTPOINTS; i++) { if (StartPoints[i].Active && ValidWayPoint(StartPoints[i].Index)) { DrawStartEndSector(hdc, rc, StartPoints[i].Start, StartPoints[i].End, StartPoints[i].Index, StartLine, StartRadius); } } } } for (i = 0; ValidTaskPoint(i + 1); i++) { int imin = min(Task[i].Index, Task[i + 1].Index); int imax = max(Task[i].Index, Task[i + 1].Index); // JMW AAT! double bearing = Task[i].OutBound; POINT sct1, sct2; if (AATEnabled) { LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat, sct1); LatLon2Screen(Task[i + 1].AATTargetLon, Task[i + 1].AATTargetLat, sct2); DistanceBearing(Task[i].AATTargetLat, Task[i].AATTargetLon, Task[i + 1].AATTargetLat, Task[i + 1].AATTargetLon, NULL, &bearing); // draw nominal track line DrawDashLine(hdc, NIBLSCALE(1), // 091217 WayPointList[imin].Screen, WayPointList[imax].Screen, taskcolor, rc); } else { sct1 = WayPointList[imin].Screen; sct2 = WayPointList[imax].Screen; } if ((i >= ActiveWayPoint && DoOptimizeRoute()) || !DoOptimizeRoute()) { POINT ClipPt1 = sct1, ClipPt2 = sct2; if(LKGeom::ClipLine((POINT) {rc.left, rc.top}, (POINT) {rc.right, rc.bottom}, ClipPt1, ClipPt2)) { DrawMulticolorDashLine(hdc, size_tasklines, sct1, sct2, taskcolor, RGB_BLACK,rc); // draw small arrow along task direction POINT p_p; POINT Arrow[2] = { {6, 6}, {-6, 6} }; ScreenClosestPoint(sct1, sct2, Orig_Aircraft, &p_p, NIBLSCALE(25)); threadsafePolygonRotateShift(Arrow, 2, p_p.x, p_p.y, bearing - DisplayAngle); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[0], p_p, taskcolor, rc); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[1], p_p, taskcolor, rc); } } } // Draw DashLine From current position to Active TurnPoint center if(ValidTaskPoint(ActiveWayPoint)) { POINT ptStart; LatLon2Screen(DrawInfo.Longitude, DrawInfo.Latitude, ptStart); DrawDashLine(hdc, NIBLSCALE(1), ptStart, WayPointList[Task[ActiveWayPoint].Index].Screen, taskcolor, rc); } { UnlockTaskData(); } // restore original color SetTextColor(hDCTemp, origcolor); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }
void MapWindow::DrawTaskAAT(LKSurface& Surface, const RECT& rc) { int i; double tmp1 = 0.0; if (WayPointList.empty()) return; if (!AATEnabled) return; LockTaskData(); // protect from external task changes /**********************************************/ /* Check if not Validated Waypoint is visible */ bool bDraw = false; int maxTp = 1; rectObj rcrect = (rectObj){(double) rc.left, (double) rc.top, (double) rc.right, (double) rc.bottom}; RECT rcDraw = (RECT){rc.right, rc.bottom, rc.left, rc.top}; for (maxTp = std::max(1, ActiveTaskPoint); ValidTaskPoint(maxTp + 1); ++maxTp) { if (ValidTaskPoint(maxTp)) { int Type = 0; double Radius = 0.; GetTaskSectorParameter(maxTp, &Type, &Radius); switch (Type) { case CONE: case CIRCLE: tmp1 = Task[maxTp].AATCircleRadius * zoom.ResScaleOverDistanceModify(); break; case SECTOR: tmp1 = Task[maxTp].AATSectorRadius * zoom.ResScaleOverDistanceModify(); break; default: tmp1 = 0.0; break; } } PixelScalar x = WayPointList[Task[maxTp].Index].Screen.x; PixelScalar y = WayPointList[Task[maxTp].Index].Screen.y; rectObj rect = (rectObj){x - tmp1, y - tmp1, x + tmp1, y + tmp1}; if (msRectOverlap(&rect, &rcrect) == MS_TRUE) { rcDraw.top = std::min((PixelScalar)rect.miny, rcDraw.top); rcDraw.bottom = std::max((PixelScalar) rect.maxy, rcDraw.bottom); rcDraw.left = std::min((PixelScalar) rect.minx, rcDraw.left); rcDraw.right = std::max((PixelScalar) rect.maxx, rcDraw.right); bDraw = true; } } /**********************************************/ if (bDraw) { // Draw Only if one is Visible #ifdef USE_GDI rcDraw.top = std::max(rc.top, rcDraw.top); rcDraw.bottom = std::min(rc.bottom, rcDraw.bottom); rcDraw.left = std::max(rc.left, rcDraw.left); rcDraw.right = std::min(rc.right, rcDraw.right); LKColor whitecolor = RGB_WHITE; LKColor origcolor = TempSurface.SetTextColor(whitecolor); const auto oldpen = TempSurface.SelectObject(LK_WHITE_PEN); const auto oldbrush = TempSurface.SelectObject(LKBrush_White); if(LKSurface::AlphaBlendSupported()) { // copy original bitmap into temp (for saving fully transparent areas) TempSurface.Copy(rcDraw.left, rcDraw.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, Surface, rcDraw.left, rcDraw.top); } else { TempSurface.Rectangle(rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom); } TempSurface.SelectObject(LK_NULL_PEN); #ifdef HAVE_HATCHED_BRUSH TempSurface.SelectObject(hAirspaceBrushes[iAirspaceBrush[AATASK]]); #else TempSurface.SelectObject(LKBrush_Yellow); #endif // this color is used as the black bit TempSurface.SetTextColor(Colours[iAirspaceColour[AATASK]]); // this color is the transparent bit TempSurface.SetBkColor(whitecolor); LKSurface & AliasSurface = TempSurface; #else LKSurface & AliasSurface = Surface; Surface.SelectObject(LKBrush(LKColor(255U,255U,0U).WithAlpha(AlphaLevel))); #endif for (i = maxTp - 1; i > std::max(0, ActiveTaskPoint - 1); i--) { if (ValidTaskPoint(i)) { int Type = 0; double Radius = 0.; GetTaskSectorParameter(i, &Type, &Radius); switch (Type) { case CONE: case CIRCLE: tmp1 = Radius * zoom.ResScaleOverDistanceModify(); AliasSurface.DrawCircle( WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp1, rc, true); break; case SECTOR: tmp1 = Radius * zoom.ResScaleOverDistanceModify(); AliasSurface.Segment( WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp1, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); break; } } } #ifdef USE_GDI // restore original color TempSurface.SetTextColor(origcolor); TempSurface.SelectObject(oldpen); TempSurface.SelectObject(oldbrush); if(!Surface.AlphaBlend(rcDraw, TempSurface,rcDraw, AlphaLevel)) { // if AlphaBlend is not supported, use TransparentBld Surface.TransparentCopy( rcDraw.left, rcDraw.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, TempSurface, rcDraw.left, rcDraw.top); } #endif } { UnlockTaskData(); } }
void MapWindow::DrawTaskPicto(HDC hdc,int TaskIdx, RECT rc, double fScaleFact) { #ifdef PICTORIALS int center_x = (rc.right-rc.left)/2; int center_y = (rc.bottom-rc.top)/2; int SecType = SectorType; int width = center_x-2; HPEN oldpen = 0; HBRUSH oldbrush = 0; if(AATEnabled) oldbrush = (HBRUSH) SelectObject(hdc, LKBrush_LightGrey); else oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); int finish=0; while( ValidTaskPoint(finish)) finish++; finish--; if(center_y < width) width = center_y-2; fScaleFact /= (2500.0); //width = (int)((double)width*(fScaleFact)); POINT startfinishline[2] = {{0,-width/2}, {0,+width/2}}; POINT track[3] = {{0,-width/10}, {width/4,0}, {0,width/10}}; if(TaskIdx == finish) { track[0].x = -width/4 ; track[0].y= -width/10; track[1].x = 0 ; track[1].y= 0; track[2].x = -width/4 ; track[2].y= width/10; } LockTaskData(); // protect from external task changes double StartRadial = Task[TaskIdx].AATStartRadial; double FinishRadial = Task[TaskIdx].AATFinishRadial; if(TaskIdx==0) { FinishRadial = Task[TaskIdx].AATStartRadial; StartRadial = Task[TaskIdx].AATFinishRadial; } double SecRadius; GetTaskSectorParameter( TaskIdx, &SecType,&SecRadius); switch (SecType) { case CIRCLE: Circle(hdc, center_x, center_y, width-2, rc, true, true); break; case SECTOR: Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules Circle(hdc, center_x, center_y, width/8, rc, false, true); Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); } break; case LINE: default: PolygonRotateShift(startfinishline, 2, center_x, center_y, Task[TaskIdx].AATStartRadial); Polygon(hdc,startfinishline ,2 ); if((TaskIdx == 0) || (TaskIdx == finish)) { PolygonRotateShift(track, 3, center_x, center_y, Task[TaskIdx].AATStartRadial); Polygon(hdc,track ,3 ); } break; } UnlockTaskData(); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); #endif }
bool MapWindow::Event_NearestWaypointDetails(double lon, double lat) { double Dist; unsigned int i; const double range = zoom.RealScale()*500; double dyn_range = std::max(5000.0, range*3.5); //StartupStore(_T("RANGE=%f\n"),dyn_range); LKSound(TEXT("LK_BELL.WAV")); start_search: #ifdef BUTTONS_MS LockFlightData(); DistanceBearing(lat,lon, GPS_INFO.Latitude,GPS_INFO.Longitude, &Dist, NULL); UnlockFlightData(); if(Dist < dyn_range) { #ifdef OWN_POS_MS dlgAddMultiSelectListItem(NULL,0, IM_OWN_POS, Dist); #endif #ifdef ORACLE_MS dlgAddMultiSelectListItem(NULL,0, IM_ORACLE, Dist); #endif #ifdef TEAM_CODE_MS dlgAddMultiSelectListItem(NULL,0, IM_TEAM, Dist); #endif } #endif // BUTTONS_MS for(size_t i=NUMRESWP;i<WayPointList.size();++i) { // Consider only valid markers if ((WayPointCalc[i].WpType==WPT_AIRPORT)|| (WayPointCalc[i].WpType==WPT_OUTLANDING)) { DistanceBearing(lat,lon, WayPointList[i].Latitude, WayPointList[i].Longitude, &Dist, NULL); if(Dist < dyn_range) { dlgAddMultiSelectListItem(NULL,i, IM_WAYPOINT, Dist); } } } #ifdef FLARM_MS if((MapWindow::mode.Is(MapWindow::Mode::MODE_PAN) || MapWindow::mode.Is(MapWindow::Mode::MODE_TARGET_PAN))) { LastDoTraffic=0; DoTraffic(&DrawInfo,&DerivedDrawInfo); for (unsigned i=0; i<FLARM_MAX_TRAFFIC; ++i) { if (LKTraffic[i].Status != LKT_EMPTY) { DistanceBearing(lat,lon, LKTraffic[i].Latitude, LKTraffic[i].Longitude, &Dist, NULL); if(Dist < range) { dlgAddMultiSelectListItem((long*)&LKTraffic[i],i, IM_FLARM, Dist); } } } } #endif int HorDist=0, Bearing=0, VertDist=0; CAirspaceList reslist = CAirspaceManager::Instance().GetNearAirspacesAtPoint(lon, lat, (int)(dyn_range/2)); for (CAirspaceList::const_iterator it = reslist.begin(); it != reslist.end(); ++it) { LKASSERT((*it)); (*it)->CalculateDistance(&HorDist, &Bearing, &VertDist,lon, lat); dlgAddMultiSelectListItem((long*) (*it),0, IM_AIRSPACE, HorDist); } for(i=1;i<WayPointList.size();i++) { // Consider only valid markers if ((WayPointCalc[i].WpType != WPT_AIRPORT)|| (WayPointCalc[i].WpType != WPT_OUTLANDING)) { DistanceBearing(lat,lon, WayPointList[i].Latitude, WayPointList[i].Longitude, &Dist, NULL); if(Dist < (dyn_range)) { dlgAddMultiSelectListItem(NULL,i, IM_WAYPOINT, Dist); } } } // TASK MULTISELECT int SecType= DAe; double SecRadius =0; double Bear=0; bool Angleinside = false; LockTaskData(); for(i=0; ValidTaskPoint(i); i++) { LKASSERT(Task[i].Index <=(int)WayPointList.size()); DistanceBearing(lat,lon, WayPointList[Task[i].Index].Latitude, WayPointList[Task[i].Index].Longitude, &Dist, &Bear); GetTaskSectorParameter(i, &SecType, &SecRadius); Angleinside = true; if( SecRadius < (dyn_range)) SecRadius =dyn_range; if((Dist < SecRadius) && Angleinside) { dlgAddMultiSelectListItem(NULL,i, IM_TASK_PT, Dist); } } UnlockTaskData(); #if (WINDOWSPC>0) if (EnableSoundModes) Poco::Thread::sleep(1000); // let the sound be heard in sequence #endif if(dlgGetNoElements() ==0) { if(dyn_range < 120000) { dyn_range *=2; goto start_search; } else { DoStatusMessage(gettext(TEXT("_@M2248_"))); // _@M2248_ "No Near Object found!" } } else { LKSound(TEXT("LK_GREEN.WAV")); dlgMultiSelectListShowModal(); if(ValidTaskPoint(PanTaskEdit)) { MapWindow::Event_Pan(1); } return true; } return false; }