bool CTaskFileHelper::SaveOption(XMLNode node) { if (!node) { return false; } XMLNode OptNode = node.AddChild(ToString(_T("options")), false); if (!OptNode) { return false; } switch (AutoAdvance) { case 0: SetAttribute(OptNode, _T("auto-advance"), _T("Manual")); break; case 1: SetAttribute(OptNode, _T("auto-advance"), _T("Auto")); break; case 2: SetAttribute(OptNode, _T("auto-advance"), _T("Arm")); break; case 3: SetAttribute(OptNode, _T("auto-advance"), _T("ArmStart")); break; case 4: SetAttribute(OptNode, _T("auto-advance"), _T("ArmTPs")); break; } if (AATEnabled && !DoOptimizeRoute()) { // AAT Task SetAttribute(node, _T("type"), _T("AAT")); if (!SaveOptionAAT(OptNode)) { return false; } } else if (DoOptimizeRoute()) { // Paraglider optimized Task SetAttribute(node, _T("type"), _T("Race")); if (!SaveOptionRace(OptNode)) { return false; } } else { // default Task SetAttribute(node, _T("type"), _T("Default")); if (!SaveOptionDefault(OptNode)) { return false; } } if (!SaveTaskRule(OptNode.AddChild(ToString(_T("rules")), false))) { return false; } return true; }
void UpdateTargetAltitude(TASK_POINT& TskPt) { TskPt.AATTargetAltitude = AltitudeFromTerrain(TskPt.AATTargetLat, TskPt.AATTargetLon); if(!DoOptimizeRoute() && AATEnabled) { // for AAT task, use center Alt if target point alt is less than center... TskPt.AATTargetAltitude = std::max(WayPointList[TskPt.Index].Altitude, TskPt.AATTargetAltitude); } if(TskPt.AATTargetAltitude <= 0) { TskPt.AATTargetAltitude = WayPointList[TskPt.Index].Altitude; } }
bool DoCalculations(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { // first thing: assign navaltitude! EnergyHeightNavAltitude(Basic, Calculated); // second thing: if available, get external wind precalculated! if ( (Basic->ExternalWindAvailable==TRUE) && (AutoWindMode==D_AUTOWIND_EXTERNAL)) { if (Basic->ExternalWindSpeed>0 && Basic->ExternalWindSpeed<35) { Calculated->WindSpeed = Basic->ExternalWindSpeed; Calculated->WindBearing = Basic->ExternalWindDirection; } } Heading(Basic, Calculated); DistanceToNext(Basic, Calculated); DistanceToHome(Basic, Calculated); DetectFreeFlying(Basic,Calculated); // check ongoing powerless flight DoLogging(Basic, Calculated); Vario(Basic,Calculated); TerrainHeight(Basic, Calculated); AltitudeRequired(Basic, Calculated, MACCREADY); DoAlternates(Basic,Calculated,TASKINDEX); if (IsMultiMapShared()) { DoAlternates(Basic,Calculated,RESWP_LASTTHERMAL); DoAlternates(Basic,Calculated,RESWP_TEAMMATE); DoAlternates(Basic,Calculated,RESWP_FLARMTARGET); DoAlternates(Basic,Calculated,HomeWaypoint); #ifdef GTL2 if (DoOptimizeRoute() || ACTIVE_WP_IS_AAT_AREA) DoAlternates(Basic, Calculated, RESWP_OPTIMIZED); #else if (DoOptimizeRoute()) DoAlternates(Basic,Calculated,RESWP_OPTIMIZED); #endif for (int i=RESWP_FIRST_MARKER; i<=RESWP_LAST_MARKER; i++) { if (WayPointList[i].Latitude==RESWP_INVALIDNUMBER) continue; DoAlternates(Basic,Calculated,i); } #ifndef GTL2 } #else } else {
bool CTaskFileHelper::SaveTaskPoint(XMLNode node, const TASK_POINT& TaskPt) { SetAttribute(node, _T("code"), WayPointList[TaskPt.Index].Code); if (AATEnabled || DoOptimizeRoute()) { switch (TaskPt.AATType) { case CIRCLE: SetAttribute(node, _T("type"), _T("circle")); SetAttribute(node, _T("radius"), TaskPt.AATCircleRadius); if (DoOptimizeRoute() && TaskPt.OutCircle) { SetAttribute(node, _T("Exit"), _T("true")); } break; case SECTOR: SetAttribute(node, _T("type"), _T("sector")); SetAttribute(node, _T("radius"), TaskPt.AATSectorRadius); SetAttribute(node, _T("start-radial"), TaskPt.AATStartRadial); SetAttribute(node, _T("end-radial"), TaskPt.AATFinishRadial); break; case LINE: SetAttribute(node, _T("type"), _T("line")); SetAttribute(node, _T("radius"), TaskPt.AATCircleRadius); break; case DAe: // not Used in AAT and PGTask default: LKASSERT(false); break; } if (AATEnabled && !DoOptimizeRoute()) { SetAttribute(node, _T("lock"), TaskPt.AATTargetLocked); if (TaskPt.AATTargetLocked) { SetAttribute(node, _T("target-lat"), TaskPt.AATTargetLat); SetAttribute(node, _T("target-lon"), TaskPt.AATTargetLon); } SetAttribute(node, _T("offset-radius"), TaskPt.AATTargetOffsetRadius); SetAttribute(node, _T("offset-radial"), TaskPt.AATTargetOffsetRadial); } } mWayPointToSave.insert(TaskPt.Index); return true; }
// // 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 ResetTaskWaypoint(int j) { Task[j].Index = -1; if (DoOptimizeRoute()) Task[j].AATTargetOffsetRadius = -100.0; else Task[j].AATTargetOffsetRadius = 0.0; Task[j].AATTargetOffsetRadial = 0.0; Task[j].AATTargetLocked = false; Task[j].AATSectorRadius = SectorRadius; Task[j].AATCircleRadius = SectorRadius; Task[j].AATStartRadial = 0; Task[j].AATFinishRadial = 360; }
bool CTaskFileHelper::LoadTaskPointList(XMLNode node) { mFinishIndex = 0; if (node) { int i = 0; XMLNode nodePoint = node.getChildNode(_T("point"), &i); while (nodePoint) { if (!LoadTaskPoint(nodePoint)) { return false; } nodePoint = node.getChildNode(_T("point"), &i); } } /////////////////////////////////////////////////////////////// // TODO : this code is temporary before rewriting task system if (AATEnabled || DoOptimizeRoute()) { if (ValidTaskPoint(mFinishIndex)) { switch (Task[mFinishIndex].AATType) { case CIRCLE: FinishRadius = (DWORD)Task[mFinishIndex].AATCircleRadius; FinishLine = 0; break; case LINE: FinishRadius = (DWORD)Task[mFinishIndex].AATCircleRadius; FinishLine = 1; case SECTOR: FinishRadius = (DWORD)Task[mFinishIndex].AATSectorRadius; FinishLine = 2; } } if (ValidTaskPoint(0)) { switch (Task[0].AATType) { case CIRCLE: StartRadius = (DWORD)Task[0].AATCircleRadius; StartLine = 0; break; case LINE: StartRadius = (DWORD)Task[0].AATCircleRadius; StartLine = 1; case SECTOR: StartRadius = (DWORD)Task[0].AATSectorRadius; StartLine = 2; } } } /////////////////////////////////////////////////////////////// return true; }
bool CheckCondition(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (DoOptimizeRoute() || !AATEnabled || !ValidTaskPoint(ActiveWayPoint) || !(Calculated->ValidStart && !Calculated->ValidFinish) || !Calculated->Flying) { return false; } bool OnFinalWaypoint = !ValidTaskPoint(ActiveWayPoint); if (OnFinalWaypoint) { // can't do much about it now, so don't give a warning return false; } if (Calculated->TaskTimeToGo < Calculated->AATTimeToGo) { return true; } else { return false; } };
/* * Used by Alternates and BestAlternate * Colors VGR are used by DrawNearest &c. */ void DoAlternates(NMEA_INFO *Basic, DERIVED_INFO *Calculated, int AltWaypoint) { CScopeLock(LockTaskData, UnlockTaskData); #ifdef GTL2 // If flying an AAT and working on the RESWP_OPTIMIZED waypoint, then use // this "optimized" waypoint to store data for the AAT virtual waypoint. if ((AltWaypoint == RESWP_OPTIMIZED) && (!ISPARAGLIDER || (AATEnabled && !DoOptimizeRoute()))) { WayPointList[RESWP_OPTIMIZED].Latitude = Task[ActiveWayPoint].AATTargetLat; WayPointList[RESWP_OPTIMIZED].Longitude = Task[ActiveWayPoint].AATTargetLon; WayPointList[RESWP_OPTIMIZED].Altitude = WayPointList[Task[ActiveWayPoint].Index].Altitude; WaypointAltitudeFromTerrain(&WayPointList[RESWP_OPTIMIZED]); _stprintf(WayPointList[RESWP_OPTIMIZED].Name, _T("!%s"),WayPointList[Task[ActiveWayPoint].Index].Name); } #endif // handle virtual wps as alternates if (AltWaypoint<=RESWP_END) { if (!ValidResWayPoint(AltWaypoint)) return; } else { if (!ValidWayPoint(AltWaypoint)) return; } double *altwp_dist = &WayPointCalc[AltWaypoint].Distance; double *altwp_gr = &WayPointCalc[AltWaypoint].GR; double *altwp_arrival = &WayPointCalc[AltWaypoint].AltArriv[AltArrivMode]; DistanceBearing(WayPointList[AltWaypoint].Latitude, WayPointList[AltWaypoint].Longitude, Basic->Latitude, Basic->Longitude, altwp_dist, NULL); *altwp_gr = CalculateGlideRatio( *altwp_dist, Calculated->NavAltitude - WayPointList[AltWaypoint].Altitude - GetSafetyAltitude(AltWaypoint)); // We need to calculate arrival also for BestAlternate, since the last "reachable" could be // even 60 seconds old and things may have changed drastically *altwp_arrival = CalculateWaypointArrivalAltitude(Basic, Calculated, AltWaypoint); WayPointCalc[AltWaypoint].VGR = GetVisualGlideRatio(*altwp_arrival, *altwp_gr); }
void CalculateOptimizedTargetPos(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (!DoOptimizeRoute()) return; LockTaskData(); gPGTask.Optimize(Basic, Calculated); for(size_t i=0; i<gPGTask.Count(); ++i) { gPGTask.UpdateTaskPoint(i, Task[i]); } int stdwp=Task[ActiveTaskPoint].Index; WayPointList[RESWP_OPTIMIZED].Latitude = Task[ActiveTaskPoint].AATTargetLat; WayPointList[RESWP_OPTIMIZED].Longitude = Task[ActiveTaskPoint].AATTargetLon; WayPointList[RESWP_OPTIMIZED].Altitude = Task[ActiveTaskPoint].AATTargetAltitude; _stprintf(WayPointList[RESWP_OPTIMIZED].Name, _T("!%s"),WayPointList[stdwp].Name); UnlockTaskData(); }
// Clear PG void ClearOptimizedTargetPos() { if (!DoOptimizeRoute()) return; LockTaskData(); WayPointList[RESWP_OPTIMIZED].Latitude=RESWP_INVALIDNUMBER; WayPointList[RESWP_OPTIMIZED].Longitude=RESWP_INVALIDNUMBER; WayPointList[RESWP_OPTIMIZED].Altitude=RESWP_INVALIDNUMBER; // name will be assigned by function dynamically _tcscpy(WayPointList[RESWP_OPTIMIZED].Name, _T("OPTIMIZED") ); for(int i = 0; ValidWayPoint(Task[i].Index); ++i) { Task[i].AATTargetLat = WayPointList[Task[i].Index].Latitude; Task[i].AATTargetLon = WayPointList[Task[i].Index].Longitude; Task[i].AATTargetAltitude = WayPointList[Task[i].Index].Altitude; Task[i].AATTargetLocked = false; } gPGTask.Initialize(); UnlockTaskData(); }
void MapWindow::DrawBearing(HDC hdc, const RECT rc) { int overindex=GetOvertargetIndex(); if (overindex<0) return; double startLat = DrawInfo.Latitude; double startLon = DrawInfo.Longitude; double targetLat; double targetLon; if (OvertargetMode>OVT_TASK) { LockTaskData(); targetLat = WayPointList[overindex].Latitude; targetLon = WayPointList[overindex].Longitude; UnlockTaskData(); DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); } else { if (!ValidTaskPoint(ActiveWayPoint)) { return; } LockTaskData(); if (AATEnabled && ( DoOptimizeRoute() || ((ActiveWayPoint>0) && ValidTaskPoint(ActiveWayPoint+1))) ) { targetLat = Task[ActiveWayPoint].AATTargetLat; targetLon = Task[ActiveWayPoint].AATTargetLon; } else { targetLat = WayPointList[Task[ActiveWayPoint].Index].Latitude; targetLon = WayPointList[Task[ActiveWayPoint].Index].Longitude; } UnlockTaskData(); DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); if (mode.Is(Mode::MODE_TARGET_PAN)) { // Draw all of task if in target pan mode startLat = targetLat; startLon = targetLon; LockTaskData(); for (int i=ActiveWayPoint+1; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { if (AATEnabled && ValidTaskPoint(i+1)) { targetLat = Task[i].AATTargetLat; targetLon = Task[i].AATTargetLon; } else { targetLat = WayPointList[Task[i].Index].Latitude; targetLon = WayPointList[Task[i].Index].Longitude; } DrawGreatCircle(hdc, startLon, startLat, targetLon, targetLat, rc); startLat = targetLat; startLon = targetLon; } } UnlockTaskData(); } } if (AATEnabled) { // draw symbol at target, makes it easier to see LockTaskData(); if(mode.Is(Mode::MODE_TARGET_PAN)) { for(int i=ActiveWayPoint+1; i<MAXTASKPOINTS; i++) { if(ValidTaskPoint(i) && ValidTaskPoint(i+1)) { if(i>= ActiveWayPoint) { POINT sct; LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat, sct); DrawBitmapIn(hdc, sct, hBmpTarget,true); } } } } if(ValidTaskPoint(ActiveWayPoint+1) && (DoOptimizeRoute() || (ActiveWayPoint>0)) ) { POINT sct; LatLon2Screen(Task[ActiveWayPoint].AATTargetLon, Task[ActiveWayPoint].AATTargetLat, sct); DrawBitmapIn(hdc, sct, hBmpTarget,true); } UnlockTaskData(); } }
void MapWindow::DrawWaypointsNew(HDC hdc, const RECT rc) { unsigned int i; int bestwp=-1; TCHAR Buffer[LKSIZEBUFFER]; TCHAR Buffer2[LKSIZEBUFFER]; TCHAR sAltUnit[LKSIZEBUFFERUNIT]; TextInBoxMode_t TextDisplayMode = {0}; static int resizer[10]={ 20,20,20,3,5,8,10,12,0 }; // if pan mode, show full names int pDisplayTextType = DisplayTextType; if (!WayPointList) return; _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelListCount = 0; int arrivalcutoff=0, foundairport=0; bool isairport; bool islandpoint; // setting decluttericons will not paint outlanding, and use minrunway to declutter even more bool decluttericons=false; // inrange : max scale allowed to print non-landable waypoints bool inrange=true; // minimal size of a runway to paint it while decluttering int minrunway=0; // // RealScale // // 2km 1.42 // 3.5km 2.5 // 5km 3.57 // 7.5km 5.35 // 10km 7.14 // 15km 10.71 // 20km 14.28 // 25km 17.85 // 40km 28.57 // 50km 35.71 // 75km 53.57 switch(DeclutterMode) { case dmDisabled: //inrange=(MapWindow::zoom.RealScale() <=18 ? true:false); // 17.85, 25km scale inrange=(MapWindow::zoom.RealScale() <=15 ? true:false); // 14.28, 20km scale decluttericons=false; break; case dmLow: inrange=(MapWindow::zoom.RealScale() <=11 ? true:false); // 10.71, 15km scale decluttericons=(MapWindow::zoom.RealScale() >=14 ? true : false); minrunway=200; break; case dmMedium: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=400; break; case dmHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=800; break; case dmVeryHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=1600; break; default: LKASSERT(0); break; } if (MapWindow::zoom.RealScale() <=20) for(i=0;i<NumberOfWayPoints;i++) { if (WayPointList[i].Visible != TRUE ) continue; // false may not be FALSE? if (WayPointCalc[i].IsAirport) { if (WayPointList[i].Reachable == FALSE) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpAirportReachable); if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) { arrivalcutoff = (int)(WayPointList[i].AltArivalAGL); bestwp=i; foundairport++; } } } else { if ( WayPointCalc[i].IsOutlanding ) { // outlanding if (WayPointList[i].Reachable == FALSE) SelectObject(hDCTemp,hBmpFieldUnReachable); else { SelectObject(hDCTemp,hBmpFieldReachable); // get the outlanding as bestwp only if no other choice if (foundairport == 0) { // do not set arrivalcutoff: any next reachable airport is better than an outlanding if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) bestwp=i; } } } else continue; // do not draw icons for normal turnpoints here } if(Appearance.IndLandable == wpLandableDefault) { double fScaleFact =MapWindow::zoom.RealScale(); if(fScaleFact < 0.1) fScaleFact = 0.1; // prevent division by zero fScaleFact = zoom.DrawScale(); if(fScaleFact > 20000.0) fScaleFact = 20000.0; // limit to prevent huge airfiel symbols if(fScaleFact < 1600) fScaleFact = 1600; // limit to prevent tiny airfiel symbols if (decluttericons) { if (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0)) { DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } } else DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } else { DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } // for all waypoints if (foundairport==0 && bestwp>=0) arrivalcutoff = (int)WayPointList[bestwp].AltArivalAGL; for(i=0;i<NumberOfWayPoints;i++) { if(WayPointList[i].Visible ) { bool irange = false; bool intask = false; bool islandable; // isairport+islandpoint bool excluded=false; bool dowrite; intask = WaypointInTask(i); dowrite = intask; // initially set only for intask memset((void*)&TextDisplayMode, 0, sizeof(TextDisplayMode)); // airports are also landpoints. should be better handled isairport=((WayPointList[i].Flags & AIRPORT) == AIRPORT); islandpoint=((WayPointList[i].Flags & LANDPOINT) == LANDPOINT); islandable=WayPointCalc[i].IsLandable; // always in range if MapScale <=10 irange = inrange; if(MapWindow::zoom.RealScale() > 20) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; // with compliments } if (decluttericons) { if (! (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0))) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; } } if( islandable ) { if(WayPointList[i].Reachable){ TextDisplayMode.Reachable = 1; if ( isairport ) SelectObject(hDCTemp,hBmpAirportReachable); else SelectObject(hDCTemp,hBmpFieldReachable); if ((GetMultimap_Labels()<MAPLABELS_ALLOFF)||intask) { dowrite = true; // exclude outlandings worst than visible airports, only when there are visible reachable airports! if ( isairport==false && islandpoint==true ) { if ( (int)WayPointList[i].AltArivalAGL >=2000 ) { // more filter excluded=true; } else { if ( (bestwp>=0) && (i==(unsigned)bestwp) && (foundairport==0) ) { // this outlanding is the best option isairport=true; islandpoint=false; // make it an airport TODO paint it as best } else { if ( foundairport >0 ) { if ( (int)WayPointList[i].AltArivalAGL <= arrivalcutoff ) { excluded=true; } } } } } else // do not display airport arrival if close to the best so far. // ex: best arrival is 1200m, include onlye below 1200/4 (prevent division by zero) // This way we only display far points, and skip closer points // WE NEED MORE INFO ABOUT LANDING POINTS: THE .CUP FORMAT WILL LET US KNOW WHAT IS // BEST TO SHOW AND WHAT IS NOT. Winpilot format is useless here. { dowrite=true;// TEST FIX not necessary probably // it's an airport if ( (bestwp>=0) && (i != (unsigned)bestwp) && (arrivalcutoff>600) ) { if ( (arrivalcutoff / ((int)WayPointList[i].AltArivalAGL+1))<4 ) { excluded=true; } } } } } else // landable waypoint is unreachable { dowrite=true; if ( isairport ) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpFieldUnReachable); } } } else { // waypoint is an ordinary turnpoint if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } } // end landable-not landable NiklausWirth: if (intask || (OutlinedTp==(OutlinedTp_t)otAll) ) { TextDisplayMode.WhiteBold = 1; TextDisplayMode.Color=RGB_WHITE; } // No matter of how we thought to draw it, let it up to the user.. switch(NewMapDeclutter) { case 0: excluded=false; // no decluttering: show all airports and outlandings break; case 1: if ( isairport ) excluded=false; // show all airports, declutter outlandings break; default: break; // else work normally } // here come both turnpoints and landables.. if( intask || irange || dowrite) { // irange always set when MapScale <=10 bool draw_alt = TextDisplayMode.Reachable && ((GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask); // 100711 reachable landing point! if (excluded==true) draw_alt=false; // exclude close outlandings switch(pDisplayTextType) { case DISPLAYNAME: case DISPLAYFIRSTTHREE: case DISPLAYFIRSTFIVE: case DISPLAYFIRST8: case DISPLAYFIRST10: case DISPLAYFIRST12: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; // 100711 if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further // 101215 if (DisplayTextType == DISPLAYNAME) { _tcscpy(Buffer2,WayPointList[i].Name); } else { LK_tcsncpy(Buffer2, WayPointList[i].Name, resizer[DisplayTextType]); } // ConvToUpper(Buffer2); if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)WayPointCalc[i].GR); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { //wsprintf(Buffer, TEXT("%s"),Buffer2); _tcscpy(Buffer,Buffer2); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNUMBER: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d:%d%s"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%d"),WayPointList[i].Number); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNAMEIFINTASK: dowrite = intask; if (intask) { if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%s"),WayPointList[i].Name); // TODO CHECK THIS, UNTESTED.. if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } } else { wsprintf(Buffer, TEXT(" ")); dowrite=true; } break; case DISPLAYNONE: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d%s"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d"), (int)(WayPointCalc[i].GR) ); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT(" ")); } break; default: #if (WINDOWSPC<1) //ASSERT(0); #endif break; } // end intask/irange/dowrite if (MapWindow::zoom.RealScale()<20 && islandable && dowrite) { TextInBox(hdc, &rc, Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, 0, &TextDisplayMode, true); dowrite=false; // do not pass it along } // Do not show takeoff for gliders, check TakeOffWayPoint if (i==RESWP_TAKEOFF) { if (TakeOffWayPoint) { intask=false; // 091031 let TAKEOFF be decluttered WayPointList[i].Visible=TRUE; } else { WayPointList[i].Visible=FALSE; dowrite=false; } } if(i==RESWP_OPTIMIZED) { dowrite = DoOptimizeRoute(); } if (dowrite) { MapWaypointLabelAdd( Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, &TextDisplayMode, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), intask,islandable,isairport,excluded,i,WayPointList[i].Style); } } // end if intask { ; } } // if visible } // for all waypoints qsort(&MapWaypointLabelList, MapWaypointLabelListCount, sizeof(MapWaypointLabel_t), MapWaypointLabelListCompare); int j; // now draw task/landable waypoints in order of range (closest last) // writing unconditionally for (j=MapWaypointLabelListCount-1; j>=0; j--){ MapWaypointLabel_t *E = &MapWaypointLabelList[j]; // draws if they are in task unconditionally, // otherwise, does comparison if ( E->inTask || (E->isLandable && !E->isExcluded) ) { TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), false); // At low zoom, dont print the bitmap because drawn task would make it look offsetted if(MapWindow::zoom.RealScale() > 2) continue; // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 1) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } // wp in task } // for all waypoint, searching for those in task // now draw normal waypoints in order of range (furthest away last) // without writing over each other (or the task ones) for (j=0; j<MapWaypointLabelListCount; j++) { MapWaypointLabel_t *E = &MapWaypointLabelList[j]; if (!E->inTask && !E->isLandable ) { if ( TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), true) == true) { // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { // We switch all styles in the correct order, to force a jump table by the compiler // It would be much better to use an array of bitmaps, but no time to do it for 3.0 switch(E->style) { case STYLE_NORMAL: goto turnpoint; break; // These are not used here in fact case STYLE_AIRFIELDGRASS: case STYLE_OUTLANDING: case STYLE_GLIDERSITE: case STYLE_AIRFIELDSOLID: goto turnpoint; break; case STYLE_MTPASS: SelectObject(hDCTemp,hMountpass); break; case STYLE_MTTOP: SelectObject(hDCTemp,hMountop); break; case STYLE_SENDER: SelectObject(hDCTemp,hSender); break; case STYLE_VOR: goto turnpoint; break; case STYLE_NDB: SelectObject(hDCTemp,hNdb); break; case STYLE_COOLTOWER: goto turnpoint; break; case STYLE_DAM: SelectObject(hDCTemp,hDam); break; case STYLE_TUNNEL: goto turnpoint; break; case STYLE_BRIDGE: SelectObject(hDCTemp,hBridge); break; case STYLE_POWERPLANT: case STYLE_CASTLE: goto turnpoint; break; case STYLE_INTERSECTION: SelectObject(hDCTemp,hIntersect); break; case STYLE_TRAFFIC: goto turnpoint; break; case STYLE_THERMAL: SelectObject(hDCTemp,hLKThermal); break; case STYLE_MARKER: SelectObject(hDCTemp,hBmpMarker); break; default: turnpoint: if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); break; } // switch estyle } // below zoom threshold // We dont do stretching here. We are using different bitmaps for hi res. // The 20x20 size is large enough to make much bigger icons than the old ones. DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } } } // end DrawWaypoint
void AATDistance::AddPoint(double longitude, double latitude, int taskwaypoint) { if (taskwaypoint<0) return; bool was_entered = has_entered[taskwaypoint]; has_entered[taskwaypoint] = true; if (!AATEnabled || DoOptimizeRoute()) return; // nothing else to do for non-AAT tasks LockTaskData(); // should only add ONE point to start. // If restart, need to reset if (num_points[taskwaypoint]<MAXNUM_AATDISTANCE) { int n = num_points[taskwaypoint]; bool new_point= false; if (n>1) { double dist; DistanceBearing(lat_points[taskwaypoint][n-2], lon_points[taskwaypoint][n-2], latitude, longitude, &dist, NULL); if (dist>distancethreshold[taskwaypoint]) { new_point = true; } } else { // first point in sector new_point = true; if ((!was_entered) && (taskwaypoint>0) && !Task[taskwaypoint].AATTargetLocked) { double qdist, bearing0, bearing1; DistanceBearing(Task[taskwaypoint-1].AATTargetLat, Task[taskwaypoint-1].AATTargetLon, latitude, longitude, &qdist, &bearing0); DistanceBearing(Task[taskwaypoint-1].AATTargetLat, Task[taskwaypoint-1].AATTargetLon, Task[taskwaypoint].AATTargetLat, Task[taskwaypoint].AATTargetLon, &qdist, &bearing1); // JMWAAT Task[taskwaypoint].AATTargetOffsetRadial = 0.0; // 20080615 JMW // was AngleLimit180(bearing1-bearing0); // now project along track line // target will be moved by ShiftTargetFromBehind } } if (taskwaypoint==0) { // force updating of start point new_point = true; } if (new_point) { if (taskwaypoint>0) { num_points[taskwaypoint]++; if (num_points[taskwaypoint]==MAXNUM_AATDISTANCE) { ThinData(taskwaypoint); } } else { // just replace current start num_points[taskwaypoint]= 1; } } // always replace last point lat_points[taskwaypoint][max(0,num_points[taskwaypoint]-1)]= latitude; lon_points[taskwaypoint][max(0,num_points[taskwaypoint]-1)]= longitude; // update max search for this and future waypoints if (taskwaypoint>0) { for (int i= taskwaypoint; i<MAXTASKPOINTS-1; i++) { UpdateSearch(i); } if (taskwaypoint == ActiveTaskPoint) { DistanceCovered_internal(longitude, latitude, true); } } } UnlockTaskData(); }
// return current overtarget waypoint index, or -1 if not available int GetOvertargetIndex(void) { int index; switch (OvertargetMode) { case OVT_TASK: // task if ( ValidTaskPoint(ActiveWayPoint) != false ) { if (DoOptimizeRoute()) index=RESWP_OPTIMIZED; else { index = Task[ActiveWayPoint].Index; } if ( index >=0 ) return index; } return -1; break; case OVT_ALT1: // alternate 1 if ( ValidWayPoint(Alternate1) != false ) { index = Alternate1; if ( index >=0 ) return index; } return -1; break; case OVT_ALT2: // alternate 2 if ( ValidWayPoint(Alternate2) != false ) { index = Alternate2; if ( index >=0 ) return index; } return -1; break; case OVT_BALT: // bestalternate if ( ValidWayPoint(BestAlternate) != false ) { index = BestAlternate; if ( index >=0 ) return index; } return -1; break; case OVT_HOME: // home waypoint if (ValidWayPoint(HomeWaypoint)) { index = HomeWaypoint; if ( index >=0 ) return index; } return -1; break; case OVT_THER: index=RESWP_LASTTHERMAL; if (ValidResWayPoint(index)) return index; return -1; break; case OVT_MATE: index=RESWP_TEAMMATE; if (ValidResWayPoint(index)) return index; return -1; break; case OVT_FLARM: index=RESWP_FLARMTARGET; if (ValidResWayPoint(index)) return index; return -1; break; // 4: home, 5: traffic, 6: mountain pass, last thermal, etc. default: return -1; break; } }
bool TaskAltitudeRequired(NMEA_INFO *Basic, DERIVED_INFO *Calculated, double this_maccready, double *Vfinal, double *TotalTime, double *TotalDistance, int *ifinal) { int i; double w1lat; double w1lon; double w0lat; double w0lon; double LegTime, LegDistance, LegBearing, LegAltitude; bool retval = false; // Calculate altitude required from start of task bool isfinal=true; LegAltitude = 0; double TotalAltitude = 0; *TotalTime = 0; *TotalDistance = 0; *ifinal = 0; LockTaskData(); double heightFinal = FAIFinishHeight(Basic, Calculated, -1); double height_above_finish = FAIFinishHeight(Basic, Calculated, 0) - heightFinal; for(i=MAXTASKPOINTS-2;i>=0;i--) { if (!ValidTaskPoint(i) || !ValidTaskPoint(i+1)) continue; w1lat = WayPointList[Task[i].Index].Latitude; w1lon = WayPointList[Task[i].Index].Longitude; w0lat = WayPointList[Task[i+1].Index].Latitude; w0lon = WayPointList[Task[i+1].Index].Longitude; if (AATEnabled) { w1lat = Task[i].AATTargetLat; w1lon = Task[i].AATTargetLon; // also use optimized finish point for PG optimized task. if (!isfinal || DoOptimizeRoute()) { w0lat = Task[i+1].AATTargetLat; w0lon = Task[i+1].AATTargetLon; } } DistanceBearing(w1lat, w1lon, w0lat, w0lon, &LegDistance, &LegBearing); *TotalDistance += LegDistance; LegAltitude = GlidePolar::MacCreadyAltitude(this_maccready, LegDistance, LegBearing, Calculated->WindSpeed, Calculated->WindBearing, 0, 0, true, &LegTime, height_above_finish, CRUISE_EFFICIENCY ); // JMW CHECK FGAMT height_above_finish-= LegAltitude; TotalAltitude += LegAltitude; if( ISPARAGLIDER ) { // if required altitude is less than previous turpoint altitude, // use previous turn point altitude double w1Alt = FAIFinishHeight(Basic, Calculated, i); if( (TotalAltitude+heightFinal) < w1Alt ) { TotalAltitude = w1Alt; } } if (LegTime<0) { retval = false; goto OnExit; } else { *TotalTime += LegTime; } if (isfinal) { *ifinal = i+1; if (LegTime>0) { *Vfinal = LegDistance/LegTime; } } isfinal = false; } if (*ifinal==0) { retval = false; goto OnExit; } TotalAltitude += FAIFinishHeight(Basic, Calculated, -1); if (!ValidTaskPoint(*ifinal)) { Calculated->TaskAltitudeRequiredFromStart = TotalAltitude; retval = false; } else { Calculated->TaskAltitudeRequiredFromStart = TotalAltitude; retval = true; } OnExit: UnlockTaskData(); return retval; }
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 DistanceToNext(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { // LockFlightData(); LockTaskData(); if(ValidTaskPoint(ActiveWayPoint)) { double w1lat, w1lon; double w0lat, w0lon; if(DoOptimizeRoute()) { w0lat = Task[ActiveWayPoint].AATTargetLat; w0lon = Task[ActiveWayPoint].AATTargetLon; } else { w0lat = WayPointList[TASKINDEX].Latitude; w0lon = WayPointList[TASKINDEX].Longitude; } DistanceBearing(Basic->Latitude, Basic->Longitude, w0lat, w0lon, &Calculated->WaypointDistance, &Calculated->WaypointBearing); Calculated->ZoomDistance = Calculated->WaypointDistance; if (AATEnabled && (ActiveWayPoint>0) && ValidTaskPoint(ActiveWayPoint+1)) { w1lat = Task[ActiveWayPoint].AATTargetLat; w1lon = Task[ActiveWayPoint].AATTargetLon; DistanceBearing(Basic->Latitude, Basic->Longitude, w1lat, w1lon, &Calculated->WaypointDistance, &Calculated->WaypointBearing); if (Calculated->WaypointDistance>AATCloseDistance()*3.0) { Calculated->ZoomDistance = max(Calculated->WaypointDistance, Calculated->ZoomDistance); } else { Calculated->WaypointBearing = AATCloseBearing(Basic, Calculated); } } else if ((ActiveWayPoint==0) && (ValidTaskPoint(ActiveWayPoint+1)) && (Calculated->IsInSector) ) { // JMW set waypoint bearing to start direction if in start sector if (AATEnabled) { w1lat = Task[ActiveWayPoint+1].AATTargetLat; w1lon = Task[ActiveWayPoint+1].AATTargetLon; } else { w1lat = WayPointList[Task[ActiveWayPoint+1].Index].Latitude; w1lon = WayPointList[Task[ActiveWayPoint+1].Index].Longitude; } DistanceBearing(Basic->Latitude, Basic->Longitude, w1lat, w1lon, NULL, &Calculated->WaypointBearing); } } else { Calculated->ZoomDistance = 0; Calculated->WaypointDistance = 0; Calculated->WaypointBearing = 0; } UnlockTaskData(); // UnlockFlightData(); }
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 = SectorType; double Radius = SectorRadius; if (AATEnabled) { Type = Task[i].AATType; Radius = Task[i].AATCircleRadius; } 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 2: 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; } 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++) { bool is_first = (Task[i].Index < Task[i + 1].Index); 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[Task[i].Index].Screen; sct2 = WayPointList[Task[i + 1].Index].Screen; } if ((i >= ActiveWayPoint && DoOptimizeRoute()) || !DoOptimizeRoute()) { if (is_first) { DrawMulticolorDashLine(hdc, size_tasklines, sct1, sct2, taskcolor, RGB_BLACK,rc); } else { DrawMulticolorDashLine(hdc, size_tasklines, sct2, sct1, 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)); PolygonRotateShift(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); } } { UnlockTaskData(); } // restore original color SetTextColor(hDCTemp, origcolor); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }
static void ReadValues(void) { WndProperty* wp; bool changed = false; LockTaskData(); wp = (WndProperty*)wf->FindByName(TEXT("prpEnableMultipleStartPoints")); if (wp) { CHECK_CHANGED(EnableMultipleStartPoints, wp->GetDataField()->GetAsBoolean()); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATEnabled")); if (wp) { CHECK_CHANGED(AATEnabled, wp->GetDataField()->GetAsInteger()); if (DoOptimizeRoute()) AATEnabled=true; // force it on } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFinishLine")); if (wp) { CHECK_CHANGED(FinishLine, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFinishRadius")); if (wp) { CHECK_CHANGED(FinishRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskStartLine")); if (wp) { CHECK_CHANGED(StartLine, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskStartRadius")); if (wp) { CHECK_CHANGED(StartRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskFAISector")); if (wp) { CHECK_CHANGED(SectorType, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpTaskSectorRadius")); if (wp) { CHECK_CHANGED(SectorRadius, (DWORD)iround(wp->GetDataField()->GetAsFloat() /DISTANCEMODIFY)); } wp = (WndProperty*)wf->FindByName(TEXT("prpAutoAdvance")); if (wp) { CHECK_CHANGED(AutoAdvance, wp->GetDataField()->GetAsInteger()); } wp = (WndProperty*)wf->FindByName(TEXT("prpMinTime")); if (wp) { CHECK_CHANGED(AATTaskLength, wp->GetDataField()->GetAsInteger()); if (changed) CALCULATED_INFO.AATTimeToGo=AATTaskLength*60; } if (changed) { TaskModified = true; } UnlockTaskData(); }
static void OnTaskPaintListItem(WindowControl * Sender, LKSurface& Surface){ int n = UpLimit - LowLimit; TCHAR sTmp[120]; TCHAR wpName[120]; TCHAR landableStr[5] = TEXT(" [X]"); // LKTOKEN _@M1238_ "L" landableStr[2] = MsgToken(1238)[0]; LockTaskData(); const PixelRect rcClient(Sender->GetClientRect()); const int w0 = rcClient.GetSize().cx - DLGSCALE(1); const int w1 = Surface.GetTextWidth(TEXT(" 000km")); _stprintf(sTmp, _T(" 000%s"), MsgToken(2179)); const int w2 = Surface.GetTextWidth(sTmp); const int TextMargin = (rcClient.GetSize().cy - Surface.GetTextHeight(TEXT("A"))) / 2; const int p1 = w0-w1-w2- rcClient.GetSize().cy - DLGSCALE(2); const int p2 = w0-w2- rcClient.GetSize().cy - DLGSCALE(2); const PixelRect rc = { 0, 0, rcClient.GetSize().cy, rcClient.GetSize().cy }; if (DrawListIndex < n){ int i = LowLimit + DrawListIndex; // if ((WayPointList[Task[i].Index].Flags & LANDPOINT) >0) // MapWindow::DrawRunway(hDC, &WayPointList[Task[i].Index], rc, 3000,true); MapWindow::DrawTaskPicto(Surface, DrawListIndex, rc, 2500); if (Task[i].Index>=0) { _stprintf(wpName, TEXT("%s%s"), WayPointList[Task[i].Index].Name, (WayPointList[Task[i].Index].Flags & LANDPOINT) ? landableStr : TEXT("")); if (AATEnabled && ValidTaskPoint(i+1) && (i>0)) { if (Task[i].AATType==0 || Task[i].AATType==3) { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATCircleRadius*DISTANCEMODIFY); } else { if(Task[i].AATType==2 && DoOptimizeRoute()) { _stprintf(sTmp, TEXT("%s %.1f/1"), wpName, Task[i].PGConeSlope); } else { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATSectorRadius*DISTANCEMODIFY); } } } else { _stprintf(sTmp, TEXT("%s"), wpName); } Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(rc.right + DLGSCALE(2), TextMargin, sTmp, p1-DLGSCALE(4)); _stprintf(sTmp, TEXT("%.0f %s"),Task[i].Leg*DISTANCEMODIFY,Units::GetDistanceName()); Surface.DrawText(rc.right+p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); _stprintf(sTmp, TEXT("%d%s"), iround(Task[i].InBound),MsgToken(2179)); Surface.DrawText(rc.right +p2+w2-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } } else { Surface.SetTextColor(RGB_BLACK); // if (DrawListIndex==n) { // patchout 091126 if (DrawListIndex==n && UpLimit < MAXTASKPOINTS) { // patch 091126 // LKTOKEN _@M832_ = "add waypoint" _stprintf(sTmp, TEXT(" (%s)"), MsgToken(832)); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } else if ((DrawListIndex==n+1) && ValidTaskPoint(0)) { if (!AATEnabled || ISPARAGLIDER) { // LKTOKEN _@M735_ = "Total:" Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, MsgToken(735)); _stprintf(sTmp, TEXT("%.0f %s%s"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName(), fai_ok?_T(" FAI"):_T("")); Surface.DrawText(rc.right +p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } else { double d1 = CALCULATED_INFO.TaskDistanceToGo; if ((CALCULATED_INFO.TaskStartTime>0.0) && (CALCULATED_INFO.Flying) && (ActiveTaskPoint>0)) { d1 += CALCULATED_INFO.TaskDistanceCovered; } if (d1==0.0) { d1 = CALCULATED_INFO.AATTargetDistance; } _stprintf(sTmp, TEXT("%s %.0f min %.0f (%.0f) %s"), // LKTOKEN _@M735_ = "Total:" MsgToken(735), AATTaskLength*1.0, DISTANCEMODIFY*lengthtotal, DISTANCEMODIFY*d1, Units::GetDistanceName()); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } } } UnlockTaskData(); }
static void OnTaskPaintListItem(WindowControl * Sender, HDC hDC){ (void)Sender; int n = UpLimit - LowLimit; TCHAR sTmp[120]; TCHAR wpName[120]; TCHAR landableStr[5] = TEXT(" [X]"); // LKTOKEN _@M1238_ "L" landableStr[2] = gettext(TEXT("_@M1238_"))[0]; LockTaskData(); int w0 = Sender->GetWidth()-1; int w1 = GetTextWidth(hDC, TEXT(" 000km")); int w2 = GetTextWidth(hDC, TEXT(" 000")TEXT(DEG)); int TextMargin = (Sender->GetHeight() - GetTextHeight(hDC, TEXT("A"))) / 2; int p1 = w0-w1-w2- Sender->GetHeight()-2; int p2 = w0-w2- Sender->GetHeight()-2; RECT rc = {0*ScreenScale, 0*ScreenScale, Sender->GetHeight(), Sender->GetHeight()}; if (DrawListIndex < n){ int i = LowLimit + DrawListIndex; // if ((WayPointList[Task[i].Index].Flags & LANDPOINT) >0) // MapWindow::DrawRunway(hDC, &WayPointList[Task[i].Index], rc, 3000,true); MapWindow::DrawTaskPicto(hDC, DrawListIndex, rc, 2500); if (Task[i].Index>=0) { _stprintf(wpName, TEXT("%s%s"), WayPointList[Task[i].Index].Name, (WayPointList[Task[i].Index].Flags & LANDPOINT) ? landableStr : TEXT("")); if (AATEnabled && ValidTaskPoint(i+1) && (i>0)) { if (Task[i].AATType==0) { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATCircleRadius*DISTANCEMODIFY); } else { if(Task[i].AATType==2 && DoOptimizeRoute()) { _stprintf(sTmp, TEXT("%s %.1f/1"), wpName, Task[i].PGConeSlope); } else { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATSectorRadius*DISTANCEMODIFY); } } } else { _stprintf(sTmp, TEXT("%s"), wpName); } ExtTextOutClip(hDC, Sender->GetHeight()+2*ScreenScale, TextMargin, sTmp, p1-4*ScreenScale); _stprintf(sTmp, TEXT("%.0f %s"), Task[i].Leg*DISTANCEMODIFY, Units::GetDistanceName()); ExtTextOut(hDC, Sender->GetHeight()+p1+w1-GetTextWidth(hDC, sTmp), TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); _stprintf(sTmp, TEXT("%d")TEXT(DEG), iround(Task[i].InBound)); ExtTextOut(hDC, Sender->GetHeight()+p2+w2-GetTextWidth(hDC, sTmp), TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); } } else { // if (DrawListIndex==n) { // patchout 091126 if (DrawListIndex==n && UpLimit < MAXTASKPOINTS) { // patch 091126 // LKTOKEN _@M832_ = "add waypoint" _stprintf(sTmp, TEXT(" (%s)"), gettext(TEXT("_@M832_"))); ExtTextOut(hDC, Sender->GetHeight()+2*ScreenScale, TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); } else if ((DrawListIndex==n+1) && ValidTaskPoint(0)) { if (!AATEnabled || ISPARAGLIDER) { // LKTOKEN _@M735_ = "Total:" _stprintf(sTmp, gettext(TEXT("_@M735_"))); ExtTextOut(hDC, Sender->GetHeight()+2*ScreenScale, TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); if (fai_ok) { _stprintf(sTmp, TEXT("%.0f %s FAI"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName()); } else { _stprintf(sTmp, TEXT("%.0f %s"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName()); } ExtTextOut(hDC, Sender->GetHeight()+p1+w1-GetTextWidth(hDC, sTmp), TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); } else { double d1 = CALCULATED_INFO.TaskDistanceToGo; if ((CALCULATED_INFO.TaskStartTime>0.0) && (CALCULATED_INFO.Flying) && (ActiveWayPoint>0)) { d1 += CALCULATED_INFO.TaskDistanceCovered; } if (d1==0.0) { d1 = CALCULATED_INFO.AATTargetDistance; } _stprintf(sTmp, TEXT("%s %.0f min %.0f (%.0f) %s"), // LKTOKEN _@M735_ = "Total:" gettext(TEXT("_@M735_")), AATTaskLength*1.0, DISTANCEMODIFY*lengthtotal, DISTANCEMODIFY*d1, Units::GetDistanceName()); ExtTextOut(hDC, Sender->GetHeight()+2*ScreenScale, TextMargin, ETO_OPAQUE, NULL, sTmp, _tcslen(sTmp), NULL); } } } UnlockTaskData(); }
void MapWindow::DrawGlideThroughTerrain(LKSurface& Surface, const RECT& rc) { LKPen hpOld; //double h,dh; TCHAR hbuf[10]; static bool doinit=true; static TextInBoxMode_t tmode = {0}; bool wrotevalue=false; if (doinit) { memset((void*)&tmode, 0, sizeof(TextInBoxMode_t)); tmode.Border=1; doinit=false; } #ifdef GTL2 bool ValidTP = ValidTaskPoint(ActiveWayPoint); // draw glide terrain line around next WP bool DrawGTL2 = ValidTP && (FinalGlideTerrain > 2); static bool LastDrewGTL2 = false; if (DrawGTL2) { int wp_index = (DoOptimizeRoute() || ACTIVE_WP_IS_AAT_AREA) ? RESWP_OPTIMIZED : TASKINDEX; double alt_arriv = WayPointCalc[wp_index].AltArriv[AltArrivMode]; // Calculate arrival altitude at the next waypoint relative to // the "terrain height" safety setting. if (CheckSafetyAltitudeApplies(wp_index)) alt_arriv += SAFETYALTITUDEARRIVAL/10; // AGL alt_arriv -= SAFETYALTITUDETERRAIN/10; // rel. to "terrain height" if (alt_arriv <= 0) DrawGTL2 = false; } if (LastDrewGTL2 != DrawGTL2) { LastDrewGTL2 = DrawGTL2; if (!DrawGTL2) ClearGTL2(); // clear next-WP glide terrain line } #endif hpOld = Surface.SelectObject(hpTerrainLineBg); #ifdef GTL2 // Draw the wide, solid part of the glide terrain line. #else // draw a dashed perimetral line first #endif Surface.Polyline(Groundline,NUMTERRAINSWEEPS+1, rc); // draw perimeter if selected and during a flight #ifdef GTL2 if (((FinalGlideTerrain == 1) || (FinalGlideTerrain == 3)) || ((!IsMultimapTerrain() || !DerivedDrawInfo.Flying) && FinalGlideTerrain)) { #else if ((FinalGlideTerrain==1) || ((!IsMultimapTerrain() || !DerivedDrawInfo.Flying) && (FinalGlideTerrain==2))) { #endif Surface.SelectObject(hpTerrainLine); Surface.Polyline(Groundline,NUMTERRAINSWEEPS+1, rc); } #ifdef GTL2 // draw glide terrain line around next waypoint if (DrawGTL2) { // Draw a solid white line. Surface.SelectObject(LKPen_White_N2); Surface.Polyline(Groundline2, NUMTERRAINSWEEPS+1, rc); // Draw a dashed red line. Surface.DrawDashPoly(NIBLSCALE(2), RGB_RED, Groundline2, NUMTERRAINSWEEPS+1, rc); } #endif // draw red cross obstacles only if destination looks reachable! // only if using OVT_TASK of course! #ifdef GTL2 if ((OvertargetMode == OVT_TASK) && DerivedDrawInfo.Flying && ValidTP) #else if ( (OvertargetMode==OVT_TASK) && DerivedDrawInfo.Flying && ValidTaskPoint(ActiveWayPoint)) #endif if (WayPointCalc[TASKINDEX].AltArriv[AltArrivMode] >0) { POINT sc; // If calculations detected an obstacle... if ((DerivedDrawInfo.TerrainWarningLatitude != 0.0) &&(DerivedDrawInfo.TerrainWarningLongitude != 0.0)) { // only if valid position, and visible if (DerivedDrawInfo.FarObstacle_Lon >0) if (PointVisible(DerivedDrawInfo.FarObstacle_Lon, DerivedDrawInfo.FarObstacle_Lat)) { LatLon2Screen(DerivedDrawInfo.FarObstacle_Lon, DerivedDrawInfo.FarObstacle_Lat, sc); DrawBitmapIn(Surface, sc, hTerrainWarning,true); if (DerivedDrawInfo.FarObstacle_AltArriv <=-50 || DerivedDrawInfo.FarObstacle_Dist<5000 ) { _stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.FarObstacle_AltArriv); TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); wrotevalue=true; } } // visible far obstacle if (PointVisible(DerivedDrawInfo.TerrainWarningLongitude, DerivedDrawInfo.TerrainWarningLatitude)) { LatLon2Screen(DerivedDrawInfo.TerrainWarningLongitude, DerivedDrawInfo.TerrainWarningLatitude, sc); DrawBitmapIn(Surface, sc, hTerrainWarning,true); #if 0 // 091203 add obstacle altitude on moving map h = max(0,RasterTerrain::GetTerrainHeight(DerivedDrawInfo.TerrainWarningLatitude, DerivedDrawInfo.TerrainWarningLongitude)); if (h==TERRAIN_INVALID) h=0; //@ 101027 FIX but unused dh = CALCULATED_INFO.NavAltitude - h - (SAFETYALTITUDETERRAIN/10); _stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*dh); TextInBox(hDC,&rc,hbuf,sc.x+NIBLSCALE(10), sc.y, 0, tmode,false); #else // if far obstacle was painted with value... if (wrotevalue) { // if it is not too near the nearest.. if ( (fabs(DerivedDrawInfo.FarObstacle_Lon - DerivedDrawInfo.TerrainWarningLongitude) >0.02) && (fabs(DerivedDrawInfo.FarObstacle_Lat - DerivedDrawInfo.TerrainWarningLatitude) >0.02)) { // and it the arrival altitude is actually negative (rounding terrain errors?) if ( DerivedDrawInfo.ObstacleAltArriv <=-50) // and there is a significant difference in the numbers, then paint value also for nearest if ( fabs(DerivedDrawInfo.ObstacleAltArriv - DerivedDrawInfo.FarObstacle_AltArriv) >100 ) { _stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.ObstacleAltArriv); TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); } } } else { // else paint value only if meaningful or very close to us // -1 to 10m become -1 for rounding errors if ( (DerivedDrawInfo.ObstacleAltArriv >-1) && (DerivedDrawInfo.ObstacleAltArriv <10)) DerivedDrawInfo.ObstacleAltArriv=-1; if (DerivedDrawInfo.ObstacleAltArriv <=-50 || ((DerivedDrawInfo.ObstacleAltArriv<0) && (DerivedDrawInfo.ObstacleDistance<5000)) ) { _stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.ObstacleAltArriv); TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); } } #endif } // visible nearest obstacle } // obstacles detected } // within glide range Surface.SelectObject(hpOld); }
static void OnTaskListEnter(WindowControl * Sender, WndListFrame::ListInfo_t *ListInfo) { (void)Sender; bool isfinish = false; ItemIndex = ListInfo->ItemIndex+ListInfo->ScrollIndex; // If we are clicking on Add Waypoint if ((ItemIndex>=0) && (ItemIndex == UpLimit) && (UpLimit<MAXTASKPOINTS)) { // add new waypoint if (CheckDeclaration()) { if (ItemIndex>0) { #ifdef LAST_TASKPOINT_QUESTION if (MessageBoxX( // LKTOKEN _@M817_ = "Will this be the finish?" MsgToken(817), // LKTOKEN _@M54_ = "Add Waypoint" MsgToken(54), mbYesNo) == IdYes) #else if(0) #endif { isfinish = true; // Set initial wp as the finish by default, or home if nonex LockTaskData(); // ItemIndex is already checked for > 0 no need to test twice Task[ItemIndex].Index = Task[0].Index; UnlockTaskData(); } else { isfinish = false; } } int res; res = dlgWayPointSelect(); if (ValidWayPoint(res)){ LockTaskData(); ResetTaskWaypoint(ItemIndex); Task[ItemIndex].Index = res; Task[ItemIndex].PGConeBase = WayPointList[res].Altitude; UnlockTaskData(); if (ItemIndex==0) { dlgTaskWaypointShowModal(ItemIndex, 0, true); // start waypoint } else if (isfinish) { dlgTaskWaypointShowModal(ItemIndex, 2, true); // finish waypoint } else { if (AATEnabled || DoOptimizeRoute()) { // only need to set properties for finish dlgTaskWaypointShowModal(ItemIndex, 1, true); // normal waypoint } } } // ValidWaypoint OverviewRefreshTask(); } // CheckDeclaration return; } // Index==UpLimit, clicking on Add Waypoint if (ItemIndex<UpLimit) { if (ItemIndex==0) { dlgTaskWaypointShowModal(ItemIndex, 0); // start waypoint } else { if (ItemIndex==UpLimit-1) { dlgTaskWaypointShowModal(ItemIndex, 2); // finish waypoint } else { dlgTaskWaypointShowModal(ItemIndex, 1); // turnpoint } } OverviewRefreshTask(); } } // OnTaskListEnter
int GetTaskSectorParameter(int TskIdx, int *SecType, double *SecRadius) { *SecType = LINE; if(TskIdx ==0 ) { *SecType = StartLine; if(StartLine ==0) *SecType = CIRCLE; if(StartLine ==1) *SecType = LINE; if(StartLine ==2) *SecType = SECTOR; if(SecRadius) *SecRadius = (double)StartRadius; } else { if(!ValidTaskPoint(TskIdx+1) ) { *SecType = FinishLine; if(FinishLine ==0) *SecType = CIRCLE; if(FinishLine ==1) *SecType = LINE; if(FinishLine ==2) *SecType = SECTOR; if(SecRadius) *SecRadius = (double)FinishRadius; } else { if(AATEnabled || DoOptimizeRoute()) { LKASSERT(ValidTaskPoint(TskIdx)); // could be -1 *SecType = Task[TskIdx].AATType; if(SecRadius) *SecRadius = Task[TskIdx].AATCircleRadius; switch(Task[TskIdx].AATType) { case 0: *SecType = CIRCLE; break; case 1: *SecType = SECTOR; if(SecRadius) *SecRadius = Task[TskIdx].AATSectorRadius; break; case 2: *SecType = CONE; break; } } else { *SecType = SectorType; /* if(SectorType ==0) *SecType = CIRCLE; if(SectorType ==1) *SecType = SECTOR; if(SectorType ==2) *SecType = DAe; if(SectorType ==3) *SecType = LINE; */ if(SecRadius) *SecRadius = SectorRadius; } } } return 0; }
static void SetWaypointValues(bool first=false) { WndProperty* wp; wp = (WndProperty*)wf->FindByName(TEXT("prpAATType")); if (wp) { DataFieldEnum* dfe; dfe = (DataFieldEnum*)wp->GetDataField(); if (first) { // LKTOKEN _@M210_ = "Cylinder" dfe->addEnumText(gettext(TEXT("_@M210_"))); // LKTOKEN _@M590_ = "Sector" dfe->addEnumText(gettext(TEXT("_@M590_"))); } dfe->SetDetachGUI(true); // disable call to OnAATEnabled dfe->Set(Task[twItemIndex].AATType); dfe->SetDetachGUI(false); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATCircleRadius")); if (wp) { wp->GetDataField()->SetAsFloat(lround(Task[twItemIndex].AATCircleRadius *DISTANCEMODIFY*DISTANCE_ROUNDING)/DISTANCE_ROUNDING); wp->GetDataField()->SetUnits(Units::GetDistanceName()); wp->SetVisible(Task[twItemIndex].AATType==0); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATSectorRadius")); if (wp) { wp->GetDataField()->SetAsFloat(lround(Task[twItemIndex].AATSectorRadius *DISTANCEMODIFY*DISTANCE_ROUNDING)/DISTANCE_ROUNDING); wp->GetDataField()->SetUnits(Units::GetDistanceName()); wp->SetVisible(Task[twItemIndex].AATType>0); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATStartRadial")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].AATStartRadial); wp->SetVisible(Task[twItemIndex].AATType>0); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATFinishRadial")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].AATFinishRadial); wp->SetVisible(Task[twItemIndex].AATType>0); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpOutCircle")); if (wp) { DataFieldEnum* dfe; dfe = (DataFieldEnum*)wp->GetDataField(); if (dfe) { if (first) { // LKTOKEN _@M2226_ = "Enter" dfe->addEnumText(gettext(TEXT("_@M2145_"))); // LKTOKEN _@M2227_ = "Exit" dfe->addEnumText(gettext(TEXT("_@M2146_"))); } dfe->Set(Task[twItemIndex].OutCircle); } wp->SetVisible(Task[twItemIndex].AATType==0 && DoOptimizeRoute()); wp->RefreshDisplay(); } }
static void SetWaypointValues(bool first=false) { WndProperty* wp; wp = (WndProperty*)wf->FindByName(TEXT("prpAATType")); if (wp) { DataField* dfe = wp->GetDataField(); if (first) { // LKTOKEN _@M210_ = "Cylinder" dfe->addEnumText(MsgToken(210)); // LKTOKEN _@M590_ = "Sector" dfe->addEnumText(MsgToken(590)); if(DoOptimizeRoute()) { // Conical ESS dfe->addEnumText(MsgToken(2175)); // Circle ESS dfe->addEnumText(MsgToken(2189)); } } dfe->SetDetachGUI(true); // disable call to OnAATEnabled dfe->Set(Task[twItemIndex].AATType); dfe->SetDetachGUI(false); wp->RefreshDisplay(); } WindowControl* pFrm = wf->FindByName(_T("frmCircle")); if(pFrm) { pFrm->SetVisible((Task[twItemIndex].AATType==0) || (Task[twItemIndex].AATType==3)); } pFrm = wf->FindByName(_T("frmSector")); if(pFrm) { pFrm->SetVisible(Task[twItemIndex].AATType==1); } pFrm = wf->FindByName(_T("frmCone")); if(pFrm) { pFrm->SetVisible(Task[twItemIndex].AATType==2); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATCircleRadius")); if (wp) { wp->GetDataField()->SetAsFloat(round(Task[twItemIndex].AATCircleRadius *DISTANCEMODIFY*DISTANCE_ROUNDING)/DISTANCE_ROUNDING); wp->GetDataField()->SetUnits(Units::GetDistanceName()); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATSectorRadius")); if (wp) { wp->GetDataField()->SetAsFloat(round(Task[twItemIndex].AATSectorRadius *DISTANCEMODIFY*DISTANCE_ROUNDING)/DISTANCE_ROUNDING); wp->GetDataField()->SetUnits(Units::GetDistanceName()); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATStartRadial")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].AATStartRadial); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpAATFinishRadial")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].AATFinishRadial); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpOutCircle")); if (wp) { DataField* dfe = wp->GetDataField(); if (dfe) { if (first) { // LKTOKEN _@M2226_ = "Enter" dfe->addEnumText(MsgToken(2145)); // LKTOKEN _@M2227_ = "Exit" dfe->addEnumText(MsgToken(2146)); } dfe->Set(Task[twItemIndex].OutCircle); } wp->SetVisible(DoOptimizeRoute()); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpConeSlope")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].PGConeSlope); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpConeBase")); if (wp) { wp->GetDataField()->SetAsFloat(Task[twItemIndex].PGConeBase*ALTITUDEMODIFY); wp->GetDataField()->SetUnits(Units::GetAltitudeName()); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpConeRadius")); if (wp) { wp->GetDataField()->SetAsFloat(round(Task[twItemIndex].PGConeBaseRadius *DISTANCEMODIFY*DISTANCE_ROUNDING)/DISTANCE_ROUNDING); wp->GetDataField()->SetUnits(Units::GetDistanceName()); wp->RefreshDisplay(); } }
void dlgTaskWaypointShowModal(int itemindex, int tasktype, bool addonly){ wf = NULL; if (!ScreenLandscape) { char filename[MAX_PATH]; LocalPathS(filename, TEXT("dlgTaskWaypoint_L.xml")); wf = dlgLoadFromXML(CallBackTable, filename, hWndMainWindow, TEXT("IDR_XML_TASKWAYPOINT_L")); } else { char filename[MAX_PATH]; LocalPathS(filename, TEXT("dlgTaskWaypoint.xml")); wf = dlgLoadFromXML(CallBackTable, filename, hWndMainWindow, TEXT("IDR_XML_TASKWAYPOINT")); } if (ISPARAGLIDER) { if(DoOptimizeRoute()) AATEnabled=TRUE; EnableMultipleStartPoints=false; } twItemIndex = itemindex; twType = tasktype; if (!wf) return; //ASSERT(wf!=NULL); // wf->SetKeyDownNotify(FormKeyDown); wStart = ((WndFrame *)wf->FindByName(TEXT("frmStart"))); wTurnpoint = ((WndFrame *)wf->FindByName(TEXT("frmTurnpoint"))); wAATTurnpoint = ((WndFrame *)wf->FindByName(TEXT("frmAATTurnpoint"))); wFinish = ((WndFrame *)wf->FindByName(TEXT("frmFinish"))); //ASSERT(wStart!=NULL); //ASSERT(wTurnpoint!=NULL); //ASSERT(wAATTurnpoint!=NULL); //ASSERT(wFinish!=NULL); WndButton* wb; if (addonly) { wb = (WndButton *)wf->FindByName(TEXT("butSelect")); if (wb) { wb->SetVisible(false); } wb = (WndButton *)wf->FindByName(TEXT("butRemove")); if (wb) { wb->SetVisible(false); } wb = (WndButton *)wf->FindByName(TEXT("butDetails")); if (wb) { wb->SetVisible(false); } wb = (WndButton *)wf->FindByName(TEXT("butDown")); if (wb) { wb->SetVisible(false); } wb = (WndButton *)wf->FindByName(TEXT("butUp")); if (wb) { wb->SetVisible(false); } } else { if (!ValidTaskPoint(twItemIndex-1)) { wb = (WndButton *)wf->FindByName(TEXT("butUp")); if (wb) { wb->SetVisible(false); } } if (!ValidTaskPoint(twItemIndex+1)) { wb = (WndButton *)wf->FindByName(TEXT("butDown")); if (wb) { wb->SetVisible(false); } } } SetWaypointValues(true); switch (twType) { case 0: wStart->SetVisible(1); wTurnpoint->SetVisible(0); wAATTurnpoint->SetVisible(0); wFinish->SetVisible(0); break; case 1: wStart->SetVisible(0); if (AATEnabled) { wTurnpoint->SetVisible(0); wAATTurnpoint->SetVisible(1); } else { wTurnpoint->SetVisible(1); wAATTurnpoint->SetVisible(0); } wFinish->SetVisible(0); break; case 2: wStart->SetVisible(0); wTurnpoint->SetVisible(0); wAATTurnpoint->SetVisible(0); wFinish->SetVisible(1); break; } // set properties... SetValues(true); UpdateCaption(); wf->ShowModal(); // now retrieve changes GetWaypointValues(); ReadValues(); delete wf; wf = NULL; }
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); }