// // Draw circles and gadgets for thermals // void MapWindow::DrawThermalEstimate(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) { if (!EnableThermalLocator) return; if (mode.Is(Mode::MODE_CIRCLING)) { if (DerivedDrawInfo.ThermalEstimate_R>0) { const POINT screen = _Proj.LonLat2Screen(DerivedDrawInfo.ThermalEstimate_Longitude, DerivedDrawInfo.ThermalEstimate_Latitude); DrawBitmapIn(Surface, screen, hBmpThermalSource); const auto oldBrush = Surface.SelectObject(LKBrush_Hollow); double tradius; if (ISPARAGLIDER) tradius=50; else tradius=100; const auto oldPen = Surface.SelectObject(LKPen_White_N3); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify()), rc, true); Surface.SelectObject(LKPen_Black_N1); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify())+NIBLSCALE(2), rc, true); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify()), rc, true); Surface.SelectObject(oldPen); Surface.SelectObject(oldBrush); } } else { if (zoom.RealScale() <= 4) { for (int i=0; i<MAX_THERMAL_SOURCES; i++) { if (DerivedDrawInfo.ThermalSources[i].Visible) { DrawBitmapIn(Surface, DerivedDrawInfo.ThermalSources[i].Screen, hBmpThermalSource); } } } } }
// // Paint a circle around thermal multitarget // Called only during map mode L> // void MapWindow::DrawThermalEstimateMultitarget(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) { int idx=0; // do not mix old and new thermals if (mode.Is(Mode::MODE_CIRCLING)) return; // draw only when visible , at high zoom level if ( MapWindow::zoom.RealScale() >1 ) return; idx=GetThermalMultitarget(); // no L> target destination if (idx <0) return; const POINT screen = _Proj.LonLat2Screen( ThermalHistory[idx].Longitude, ThermalHistory[idx].Latitude); double tradius; if (ISPARAGLIDER) tradius=100; else tradius=200; const auto oldPen = Surface.SelectObject(LKPen_White_N3); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify()), rc, false); Surface.SelectObject(LKPen_White_N2); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify())+NIBLSCALE(2), rc, false); Surface.DrawCircle(screen.x, screen.y, (int)(tradius*zoom.ResScaleOverDistanceModify()), rc, false); Surface.SelectObject(oldPen); }
void Statistics::RenderTask(LKSurface& Surface, const RECT& rc, const bool olcmode) { int i, j; unsigned int ui; double fXY_Scale = 1.5; double lat1 = 0; double lon1 = 0; double lat2 = 0; double lon2 = 0; double x1, y1, x2=0, y2=0; double lat_c, lon_c; double aatradius[MAXTASKPOINTS]; // find center ResetScale(); if ( (!ValidTaskPoint(0) || !ValidTaskPoint(1)) && !olcmode) { DrawNoData(Surface,rc); return; } for (i=0; i<MAXTASKPOINTS; i++) { aatradius[i]=0; } bool nowaypoints = true; for (i=0; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { lat1 = WayPointList[Task[i].Index].Latitude; lon1 = WayPointList[Task[i].Index].Longitude; ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); nowaypoints = false; } } if (nowaypoints ) { DrawNoData(Surface, rc); return; } CPointGPSArray trace; CContestMgr::Instance().Trace(trace); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); } const auto hfOldU = Surface.SelectObject(LK8InfoNormalFont); lat_c = (y_max+y_min)/2; lon_c = (x_max+x_min)/2; int nwps = 0; // find scale ResetScale(); lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); for (i=0; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { nwps++; lat1 = WayPointList[Task[i].Index].Latitude; lon1 = WayPointList[Task[i].Index].Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); if (AATEnabled) { double aatlat; double aatlon; double bearing; double radius; if (ValidTaskPoint(i+1)) { if (Task[i].AATType == SECTOR) radius = Task[i].AATSectorRadius; else radius = Task[i].AATCircleRadius; for (j=0; j<4; j++) { bearing = j*360.0/4; FindLatitudeLongitude(WayPointList[Task[i].Index].Latitude, WayPointList[Task[i].Index].Longitude, bearing, radius, &aatlat, &aatlon); x1 = (aatlon-lon_c)*fastcosine(aatlat); y1 = (aatlat-lat_c); ScaleXFromValue(rc, x1); ScaleYFromValue(rc, y1); if (j==0) { aatradius[i] = fabs(aatlat-WayPointList[Task[i].Index].Latitude); } } } else { aatradius[i] = 0; } } } } for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); } ScaleMakeSquare(rc); // draw aat areas if (AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); #ifdef HAVE_HATCHED_BRUSH Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(AATASK)); #else Surface.SelectObject(LKBrush_Yellow); #endif Surface.SelectObject(LK_WHITE_PEN); if (Task[i].AATType == SECTOR) { Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc, Task[i].AATStartRadial, Task[i].AATFinishRadial); } else { Surface.DrawCircle((long)((x2-x_min)*xscale+rc.left+BORDER_X), (long)((y_max-y2)*yscale+rc.top), (long)(aatradius[i]*yscale), true); } } } } if (!AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; if (!ValidTaskPoint(1) ) { lat2 = GPS_INFO.Latitude; lon2 = GPS_INFO.Longitude; } else { lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; } x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); // DrawLine(hdc, rc, x1, y1, x2, y2, STYLE_DASHGREEN); if( ValidTaskPoint(4) && i <2) goto skip_FAI; #ifndef UNDITHER RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN ); #else RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY ); #endif skip_FAI: DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_DASHGREEN); Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc, Task[i].AATStartRadial, Task[i].AATFinishRadial); } } if( ValidTaskPoint(1) && ValidTaskPoint(3)) { lat1 = WayPointList[Task[3].Index].Latitude; lon1 = WayPointList[Task[3].Index].Longitude; lat2 = WayPointList[Task[1].Index].Latitude; lon2 = WayPointList[Task[1].Index].Longitude; #ifndef UNDITHER RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN ); #else RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY ); #endif } } // draw task lines and label for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; if (!ValidTaskPoint(1) ) { lat2 = GPS_INFO.Latitude; lon2 = GPS_INFO.Longitude; } else { lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; } x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_BLUETHIN); #if (WINDOWSPC>0) Surface.SetBackgroundOpaque(); #endif TCHAR text[100]; Surface.SetTextColor(RGB_BLUE); /* if ((i==nwps-1) && (Task[i].Index == Task[0].Index)) { _stprintf(text,TEXT("%0d"),1); DrawLabel(hdc, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2); } else */ { _stprintf(text,TEXT("%0d"),i); DrawLabel(Surface, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2); } if ((i==ActiveTaskPoint)&&(!AATEnabled)) { lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_REDTHICK); } } } // draw aat task line if (AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { if (i==1) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; } else { lat1 = Task[i-1].AATTargetLat; lon1 = Task[i-1].AATTargetLon; } lat2 = Task[i].AATTargetLat; lon2 = Task[i].AATTargetLon; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_REDTHICK); } } } DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); Surface.SelectObject(hfOldU); // Draw aircraft on top lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); Surface.SetBackgroundTransparent(); DrawLabel(Surface, rc, TEXT("+"), x1, y1); }
// This is painting traffic icons on the screen. void MapWindow::LKDrawFLARMTraffic(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj, const POINT& Orig_Aircraft) { if (!EnableFLARMMap) return; if (!DrawInfo.FLARM_Available) return; // init scaled coords for traffic icon static int iCircleSize = 7; static int iRectangleSize = 4; static short tscaler=0; if (DoInit[MDI_DRAWFLARMTRAFFIC]) { switch (ScreenSize) { case ss480x640: case ss480x800: case ss800x480: case ss640x480: iCircleSize = 9; iRectangleSize = 5; tscaler=NIBLSCALE(7)-2; break; case ss240x320: case ss272x480: case ss320x240: case ss480x272: case ss480x234: case ss400x240: iCircleSize = 7; iRectangleSize = 4; tscaler=NIBLSCALE(13)-2; break; default: iCircleSize = 7; iRectangleSize = 4; tscaler=NIBLSCALE(7); break; } DoInit[MDI_DRAWFLARMTRAFFIC]=false; } POINT Arrow[5]; TCHAR lbuffer[50]; const auto hpold = Surface.SelectObject(LKPen_Black_N1); int i; int painted=0; // double dX, dY; TextInBoxMode_t displaymode = {0}; displaymode.NoSetFont = 1; #if 0 double screenrange = GetApproxScreenRange(); double scalefact = screenrange/6000.0; // FIX 100820 #endif const auto oldfont = Surface.SelectObject(LK8MapFont); for (i=0,painted=0; i<FLARM_MAX_TRAFFIC; i++) { // limit to 10 icons map traffic if (painted>=10) { i=FLARM_MAX_TRAFFIC; continue; } if ( (DrawInfo.FLARM_Traffic[i].ID !=0) && (DrawInfo.FLARM_Traffic[i].Status != LKT_ZOMBIE) ) { painted++; double target_lon; double target_lat; target_lon = DrawInfo.FLARM_Traffic[i].Longitude; target_lat = DrawInfo.FLARM_Traffic[i].Latitude; #if (0) // No scaling, wrong if ((EnableFLARMMap==2)&&(scalefact>1.0)) { double distance; double bearing; DistanceBearing(DrawInfo.Latitude, DrawInfo.Longitude, target_lat, target_lon, &distance, &bearing); FindLatitudeLongitude(DrawInfo.Latitude, DrawInfo.Longitude, bearing, distance*scalefact, &target_lat, &target_lon); } #endif POINT sc, sc_name, sc_av; sc = _Proj.LonLat2Screen(target_lon, target_lat); sc_name = sc; sc_name.y -= NIBLSCALE(16); sc_av = sc_name; _tcscpy(lbuffer,_T("")); if (DrawInfo.FLARM_Traffic[i].Cn && DrawInfo.FLARM_Traffic[i].Cn[0]!=_T('?')) { // 100322 _tcscat(lbuffer,DrawInfo.FLARM_Traffic[i].Cn); } if (DrawInfo.FLARM_Traffic[i].Average30s>=0.1) { size_t len = _tcslen(lbuffer); if (len > 0) _stprintf(lbuffer + len,_T(":%.1f"),LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); else _stprintf(lbuffer,_T("%.1f"),LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); } displaymode.Border=1; if (_tcslen(lbuffer)>0) TextInBox(Surface, &rc, lbuffer, sc.x+tscaler, sc.y+tscaler, &displaymode, false); // red circle if ((DrawInfo.FLARM_Traffic[i].AlarmLevel>0) && (DrawInfo.FLARM_Traffic[i].AlarmLevel<4)) { DrawBitmapIn(Surface, sc, hFLARMTraffic,true); } #if 1 // 1 Arrow[0].x = -4; Arrow[0].y = 5; Arrow[1].x = 0; Arrow[1].y = -6; Arrow[2].x = 4; Arrow[2].y = 5; Arrow[3].x = 0; Arrow[3].y = 2; Arrow[4].x = -4; Arrow[4].y = 5; for (int q=0; q < 5; q++) { Arrow[q].x = (LONG) ((double)Arrow[q].x * 1.7); Arrow[q].y = (LONG) ((double)Arrow[q].y * 1.7); } #else Arrow[0].x = scaler[0]; Arrow[0].y = scaler[1]; Arrow[1].x = 0; Arrow[1].y = scaler[2]; Arrow[2].x = scaler[3]; Arrow[2].y = scaler[1]; Arrow[3].x = 0; Arrow[3].y = scaler[4]; Arrow[4].x = scaler[0]; Arrow[4].y = scaler[1]; #endif /* switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: Surface.SelectObject(yellowBrush); break; case LKT_ZOMBIE: Surface.SelectObject(redBrush); break; default: Surface.SelectObject(greenBrush); break; } */ /************************************************************************* * calculate climb color *************************************************************************/ int iVarioIdx = (int)(2*DrawInfo.FLARM_Traffic[i].Average30s -0.5)+NO_VARIO_COLORS/2; if(iVarioIdx < 0) iVarioIdx =0; if(iVarioIdx >= NO_VARIO_COLORS) iVarioIdx =NO_VARIO_COLORS-1; Surface.SelectObject(*variobrush[iVarioIdx]); switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: Surface.Rectangle(sc.x-iRectangleSize, sc.y-iRectangleSize,sc.x+iRectangleSize, sc.y+iRectangleSize); break; case LKT_ZOMBIE: Surface.DrawCircle(sc.x, sc.x, iCircleSize, rc, true ); break; default: PolygonRotateShift(Arrow, 5, sc.x, sc.y, DrawInfo.FLARM_Traffic[i].TrackBearing - DisplayAngle); Surface.Polygon(Arrow,5); break; } } } Surface.SelectObject(oldfont); Surface.SelectObject(hpold); }
void MapWindow::DrawRunway(LKSurface& Surface, const WAYPOINT* wp, const RECT& rc, const ScreenProjection* _Proj, double fScaleFact, BOOL picto) { if(!picto && !_Proj) { // if we don't draw picto ScreenProjection parameter are mandatory. assert(false); return; } int solid= false; bool bGlider = false; bool bOutland = false; bool bRunway = false; static double rwl = 8; static double rwb = 1; static double cir = 6; static double scale_drawradio=0; static double scale_bigfont=0; static double scale_fullinfos=0; RasterPoint Center; if(picto) { Center.x = rc.left+ (rc.right- rc.left)/2; Center.y = rc.bottom +(rc.top-rc.bottom)/2; } else { Center = _Proj->ToRasterPoint(wp->Latitude, wp->Longitude); } int l,p,b; if(picto) fScaleFact /=2000; else fScaleFact /=1600; if (DoInit[MDI_MAPWPVECTORS]) { // // How long and thick is the runway drawn, and how big is the circle. // No rule possible, it depends on how we are dealing with many other // custom things on screen, because LK is drawing differently depending // on geometry, resolution, orientation. We dont split bits. // switch(ScreenSize) { case ss240x320: rwl = 9.0; rwb = 2.0;cir = 4.0; break; // 43 case ss240x400: rwl = 9.0; rwb = 1.0;cir = 4.0; break; // 53 case ss272x480: rwl = 9.0; rwb = 2.5;cir = 4.0; break; // 169 case ss480x640: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 43 case ss600x800: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 43 case ss480x800: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 53 case sslandscape: rwl = 6.0; rwb = 1.0;cir = 5.0; break; // sslandscape is never assigned! case ss320x240: rwl = 9.0; rwb = 2.0;cir = 4.0; break; // 43 case ss400x240: rwl = 9.0; rwb = 1.0;cir = 4.0; break; // 53 case ss480x234: rwl = 9.0; rwb = 1.0;cir = 4.0; break; // 21 case ss480x272: rwl = 9.0; rwb = 2.5;cir = 4.0; break; // 169 case ss640x480: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 43 case ss800x600: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 43 case ss800x480: rwl = 6.0; rwb = 2.5;cir = 5.0; break; // 53 case ssnone: #if defined(ANDROID) || defined(KOBO) rwl = 6.0; rwb = 2.5; cir = 5.0; break; #else // the line above is only a workaround to avoid runaway to be tool long on Anrtoid and Kobo // waiting for a definitive and more elegant solution. // #define X ScreenSizeX== #define Y ScreenSizeY== // Ok this doesnt look nice, but lets remember we are inside a DoInit. // Generally the generic setup is good for everyone, but in case we // can make it custom for any resolution. if (X 1024 && Y 768) {; rwl = 4.5; rwb = 2.5; cir = 5.0; } else if (X 1014 && Y 758) {; rwl = 4.5; rwb = 2.5; cir = 5.0; } else if (X 720 && Y 408) {; rwl = 10.0; rwb = 6.0; cir = 5.0; } else if (X 720 && Y 432) {; rwl = 10.0; rwb = 4.0; cir = 5.0; } else // .. and this is the rule of thumb, I could not find a better idea // I think it is easier to redesign the drawing approach and make it // really scalable. // // This hack works for: 800x600 960x540 1280x720 (and relative portrait modes) // These are the screen resolutions used by kobo, samsung s4 mini and s5 mini // if (ScreenLandscape) { if (ScreenSizeX<=480) { // testlk> Ok: t5 Bad for: - rwl = 9.0*(480.0/ScreenSizeX); rwb = 2.5*(480.0/ScreenSizeX); cir = 4.0; } else { // testlk> Ok: 3,13,14,22 Bad: t4, t15, t23 rwl = 6.0; rwb = 2.5; cir = 5.0; } } else { if (ScreenSizeX<480) { // testlk> Ok: 10,19 Bad for: 20 rwl = 6.0*(480.0/ScreenSizeX); rwb = 2.5*(480.0/ScreenSizeX); cir = 4.0; } else { // testlk> Ok: 8,28 Bad for: - rwl = 6.0; rwb = 2.5; cir = 5.0; } } break; #endif } // // These are the (absolute) scale thresholds for painting informations // For example, paint just radio starting from 5.0km (3.6abs) etc. // There is no rule possible, it matters only testing. // switch(ScreenSize) { case ss480x272: scale_drawradio=2.6; scale_bigfont=1.1; scale_fullinfos=0.8; break; case ss800x480: scale_drawradio=2.6; scale_bigfont=1.5; scale_fullinfos=1.5; break; case ss640x480: scale_drawradio=3.6; scale_bigfont=1.5; scale_fullinfos=1.5; break; default: scale_drawradio=3.6; scale_bigfont=1.5; scale_fullinfos=1.5; break; } DoInit[MDI_MAPWPVECTORS]=false; } if( wp->RunwayLen > 100) /* square if no runway defined */ { if (picto) l = (int) (rwl); else { #ifndef __linux__ // We cant rescale runways , no method found. if (ScreenSize==ssnone) l = (int) (rwl * (1.0+ (680.0/800.0-1.0)/4.0)); // wtf..! else #endif l = (int) (rwl * (1.0+ ((double)wp->RunwayLen/800.0-1.0)/4.0)); } b = (int) (rwb/1.5 ); } else { l = (int)( rwl*0.5); b = l ; } #if defined(ANDROID) || defined(KOBO) l = (int)(l * 2.0 * fScaleFact / ScreenScale); if(l==0) l=1; b = (int)(b * 2.0 * fScaleFact / ScreenScale); if(b==0) b=1; p = (int)(cir * 2.0 * fScaleFact); if(p==0) p=1; #else l = (int)(l * fScaleFact); if(l==0) l=1; b = (int)(b * fScaleFact); if(b==0) b=1; p = (int)(cir * 2.0 * fScaleFact); if(p==0) p=1; #endif switch(wp->Style) { case STYLE_AIRFIELDSOLID: solid = true; bRunway = true; bOutland = false; bGlider = false; break; case STYLE_AIRFIELDGRASS: solid = false; bRunway = true; bOutland = false; bGlider = false; break; case STYLE_OUTLANDING : solid = false; bRunway = true; bOutland = true; bGlider = false; b*=2; break; case STYLE_GLIDERSITE : solid = false; bRunway = true; bOutland = false; bGlider = true; break; default: return; break; } // Do not print glidersite at low zoom levels, in any case // not useful on some resolutions // if( !picto && (MapWindow::zoom.RealScale() > 3) ) // bGlider=false; const auto oldPen = Surface.SelectObject(LK_BLACK_PEN); const auto oldBrush = Surface.SelectObject(LKBrush_Red); if( wp->Reachable == TRUE) Surface.SelectObject(LKBrush_Green); if(!bOutland) { if (picto) Surface.DrawCircle(Center.x, Center.y, p, true); else Surface.DrawCircle(Center.x, Center.y, p, rc, true); } if(bRunway) { POINT Runway[5] = { { b, l }, // 1 {-b, l }, // 2 {-b,-l }, // 3 { b,-l }, // 4 { b,l } // 5 }; if(!bOutland) { #ifndef DITHER if(solid) Surface.SelectObject(LKBrush_DarkGrey ); else Surface.SelectObject(LKBrush_White); #else if(solid) Surface.SelectObject(LKBrush_Black); else Surface.SelectObject(LKBrush_White); #endif } if(picto) { threadsafePolygonRotateShift(Runway, 5, Center.x, Center.y, wp->RunwayDir); } else { PolygonRotateShift(Runway, 5, Center.x, Center.y, wp->RunwayDir- (int)MapWindow::GetDisplayAngle()); } Surface.Polygon(Runway ,5 ); } // bRunway if(fScaleFact >= 0.9) { if(bGlider) { int iScale = (int)(fScaleFact*2.0); double fFact = 0.04*fScaleFact/1.5; if(iScale==0) iScale=1; POINT WhiteWing [17] = { { (long)(-228 * fFact ) , (long)(13 * fFact)}, //1 { (long) (-221 * fFact ) , (long)(-5 * fFact)}, //2 { (long) (-102 * fFact ) , (long)(-50 * fFact)}, //3 { (long) (8 * fFact ) , (long)( 5 * fFact)}, //4 { (long) (149 * fFact ) , (long)(-55 * fFact)}, //5 { (long) (270 * fFact ) , (long)(-12 * fFact)}, //6 { (long) (280 * fFact ) , (long)( 5 * fFact)}, //7 { (long) (152 * fFact ) , (long)(-30 * fFact)}, //8 { (long) (48 * fFact ) , (long)( 27 * fFact)}, //9 { (long) (37 * fFact ) , (long)( 44 * fFact)}, //10 { (long)(-20 * fFact ) , (long)( 65 * fFact)}, //11 { (long)(-29 * fFact ) , (long)( 80 * fFact)}, //12 { (long)(-56 * fFact ) , (long)( 83 * fFact)}, //13 { (long)(-50 * fFact ) , (long)( 40 * fFact)}, //14 { (long)(-30 * fFact ) , (long)( 27 * fFact)}, //15 { (long)(-103 * fFact ) , (long)(-26 * fFact)}, //16 { (long)(-228 * fFact ) , (long)( 13 * fFact)} //17 }; if (picto) threadsafePolygonRotateShift(WhiteWing, 17, Center.x, Center.y, 0/*+ wp->RunwayDir-Brg*/); else PolygonRotateShift(WhiteWing, 17, Center.x, Center.y, 0/*+ wp->RunwayDir-Brg*/); Surface.Polygon(WhiteWing ,17 ); } } // StartupStore(_T(".......fscale=%f *1600=%f realscale = %f\n"), fScaleFact, fScaleFact*1600, MapWindow::zoom.RealScale()); if( !picto && (MapWindow::zoom.RealScale() <= scale_drawradio) ) { const auto hfOld = Surface.SelectObject(MapWindow::zoom.RealScale() <= scale_bigfont ? LK8PanelUnitFont : LK8GenericVar02Font); #ifndef DITHER if (INVERTCOLORS) Surface.SelectObject(LKBrush_Petrol); else Surface.SelectObject(LKBrush_LightCyan); #else if (INVERTCOLORS) Surface.SelectObject(LKBrush_Black); else Surface.SelectObject(LKBrush_White); #endif unsigned int offset = p + NIBLSCALE(1) ; { if ( _tcslen(wp->Freq)>0 ) { MapWindow::LKWriteBoxedText(Surface,rc,wp->Freq, Center.x- offset, Center.y -offset, WTALIGN_RIGHT, RGB_WHITE, RGB_BLACK); } // // Full infos! 1.5km scale // if (MapWindow::zoom.RealScale() <=scale_fullinfos) { if ( _tcslen(wp->Code)==4 ) { MapWindow::LKWriteBoxedText(Surface,rc,wp->Code,Center.x + offset, Center.y - offset, WTALIGN_LEFT, RGB_WHITE,RGB_BLACK); } if (wp->Altitude >0) { TCHAR tAlt[20]; _stprintf(tAlt,_T("%.0f %s"),wp->Altitude*ALTITUDEMODIFY,Units::GetUnitName(Units::GetUserAltitudeUnit())); MapWindow::LKWriteBoxedText(Surface,rc,tAlt, Center.x + offset, Center.y + offset, WTALIGN_LEFT, RGB_WHITE, RGB_BLACK); } } } Surface.SelectObject(hfOld); } Surface.SelectObject(oldPen); Surface.SelectObject(oldBrush); }