Beispiel #1
0
//
// 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);
			}
		}
	}
  }
}
Beispiel #2
0
//
// 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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
// 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);

}
Beispiel #5
0
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);

}