Пример #1
0
void Statistics::RenderGlidePolar(HDC hdc, RECT rc)
{

  ResetScale();
  ScaleYFromValue(rc, 0);
  ScaleYFromValue(rc, GlidePolar::SinkRateFast(0,(int)(SAFTEYSPEED-1)));
  ScaleXFromValue(rc, 0); // GlidePolar::Vminsink);
  ScaleXFromValue(rc, SAFTEYSPEED);
  
  DrawXGrid(hdc, rc, 
            10.0/SPEEDMODIFY, 0,
            STYLE_THINDASHPAPER);
  DrawYGrid(hdc, rc, 
            1.0/LIFTMODIFY, 0,
            STYLE_THINDASHPAPER);
  
  int i;
  double sinkrate0, sinkrate1;
  for (i= GlidePolar::Vminsink; i< SAFTEYSPEED-1;
       i++) {
    
    sinkrate0 = GlidePolar::SinkRateFast(0,i);
    sinkrate1 = GlidePolar::SinkRateFast(0,i+1);
    DrawLine(hdc, rc,
             i, sinkrate0 , 
             i+1, sinkrate1, 
             STYLE_MEDIUMBLACK);
  }
  DrawXLabel(hdc, rc, TEXT("V"));
  DrawYLabel(hdc, rc, TEXT("w"));
}
Пример #2
0
void qp_graph_grid_draw(struct qp_graph *gr, struct qp_plot *p,
    cairo_t *cr, int width, int height)
{
  int64_t
        xmin_mat, xmax_mat, xinc,
	ymin_mat, ymax_mat, yinc;
  double xpow_part, ypow_part;
  PangoLayout *pangolayout = NULL;
  int view_width, view_height;
  
  ASSERT(gr);
  ASSERT(p);
  ASSERT(gr->drawing_area);
  ASSERT(gr->qp);
  ASSERT(gr->qp->window);

  if(!gr->show_grid) return;

  PreDrawGrid(gr, p,
	  &xmin_mat, &xmax_mat, &xinc, &xpow_part,
	  &ymin_mat, &ymax_mat, &yinc, &ypow_part,
          width, height);

  view_width = gtk_widget_get_allocated_width(gr->drawing_area);
  view_height = gtk_widget_get_allocated_height(gr->drawing_area);


  if(gr->grid_numbers)
    pangolayout = get_pangolayout(gr, cr);



#if 0
  DEBUG("\nxmin=%g xmax=%g\n",
      qp_plot_get_xval(p, 0), qp_plot_get_xval(p, width));
  APPEND("ymin=%g ymax=%g\n",
      qp_plot_get_yval(p, height), qp_plot_get_yval(p, 0));
  APPEND("xmin_mat=%ld xmax_mat=%ld xinc=%ld xpow_part=%g \n",
      xmin_mat, xmax_mat, xinc, xpow_part);
  APPEND("ymin_mat=%ld ymax_mat=%ld yinc=%ld ypow_part=%g \n",
      ymin_mat, ymax_mat, yinc, ypow_part);
  APPEND("delta_x pixels between lines=%d\n",
      qp_plot_get_xpixel(p, xpow_part*(xmin_mat + xinc)) -
      qp_plot_get_xpixel(p, xpow_part*(xmin_mat)));
  APPEND("delta_y pixels between lines=%d\n",
      qp_plot_get_ypixel(p, ypow_part*ymin_mat) -
      qp_plot_get_ypixel(p, ypow_part*(ymin_mat + yinc)));
#endif

  if(gr->same_x_scale)
      DrawXGrid(cr, pangolayout, gr, p,
	    xmin_mat, xmax_mat, xinc, xpow_part,
	    ymin_mat, ymax_mat, yinc, ypow_part,
            width, height, view_height);
  if(gr->same_y_scale)
      DrawYGrid(cr, pangolayout, gr, p,
	    xmin_mat, xmax_mat, xinc, xpow_part,
	    ymin_mat, ymax_mat, yinc, ypow_part,
            width, height, view_width);
}
Пример #3
0
void Statistics::RenderBarograph(HDC hdc, RECT rc)
{

  ResetScale();
  ScaleXFromData(rc, &flightstats.Altitude);
  ScaleYFromData(rc, &flightstats.Altitude);
  ScaleXFromData(rc, &flightstats.Altitude_Base);
  ScaleYFromData(rc, &flightstats.Altitude_Base);
  ScaleXFromData(rc, &flightstats.Altitude_Ceiling);
  ScaleYFromData(rc, &flightstats.Altitude_Ceiling);

  DrawXGrid(hdc, rc, 
            0.25, flightstats.Altitude.x_min,
            STYLE_THINDASHPAPER);

  DrawYGrid(hdc, rc, 1000/ALTITUDEMODIFY, 0, STYLE_THINDASHPAPER);

  DrawLineGraph(hdc, rc, &flightstats.Altitude,
                STYLE_MEDIUMBLACK);

  LockTaskData();
  for(int j=0;j<MAXTASKPOINTS;j++) {
    if (ValidTaskPoint(j) && (LegStartTime[j]>=0)) {
      double xx = (LegStartTime[j]-Calculated->TakeOffTime)/3600;
      if (xx>=0) {
        DrawLine(hdc, rc,
                 xx, flightstats.Altitude.y_min,
                 xx, flightstats.Altitude.y_max,
                 STYLE_THINDASHPAPER);
      }
    }
  }
  UnlockTaskData();

  DrawTrend(hdc, rc, &flightstats.Altitude_Base, STYLE_BLUETHIN);

  DrawTrend(hdc, rc, &flightstats.Altitude_Ceiling, STYLE_BLUETHIN);

  DrawXLabel(hdc, rc, TEXT("t"));
  DrawYLabel(hdc, rc, TEXT("h"));

}
Пример #4
0
/*--------------------------------------------------------------------------*/
void PegChart::Draw()
{
    BeginDraw();

    StandardBorder(muColors[PCI_NORMAL]);

    if(mwExStyle & CS_DRAWXGRID && (mwMajorXScale > 0 || mwMinorXScale > 0))
    {
        DrawXGrid();
    }

    if(mwExStyle & CS_DRAWYGRID && (mwMajorYScale > 0 || mwMinorYScale > 0))
    {
        DrawYGrid();
    }

    if(mwExStyle & CS_DRAWXTICS && (mwMajorXScale > 0 || mwMinorXScale > 0))
    {
        DrawXTics();
    }

    if(mwExStyle & CS_DRAWYTICS && (mwMajorYScale > 0 || mwMinorYScale > 0))
    {
        DrawYTics();
    }

    if(mwExStyle & CS_DRAWXLABELS && mwXLabelScale > 0)
    {
        DrawXLabels();
    }

    if(mwExStyle & CS_DRAWYLABELS && mwYLabelScale > 0)
    {
        DrawYLabels();
    }

    DrawChildren();
	
    EndDraw();
}
Пример #5
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);
}
Пример #6
0
void Statistics::RenderWind(HDC hdc, RECT rc) 
{
  int numsteps=10;
  int i;
  double h;
  Vector wind;
  bool found=true;
  double mag;

  LeastSquares windstats_mag;
  
  if (fabs(flightstats.Altitude_Ceiling.y_max
	   -flightstats.Altitude_Base.y_min)<1) return;

  for (i=0; i<numsteps ; i++) {

    h = (flightstats.Altitude_Ceiling.y_max-flightstats.Altitude_Base.y_min)*
      i/(double)(numsteps-1)+flightstats.Altitude_Base.y_min;

    wind = windanalyser->windstore.getWind(h, &found);
    mag = sqrt(wind.x*wind.x+wind.y*wind.y);

    windstats_mag.least_squares_update(mag, h);

  }
  
  //

  ResetScale();

  ScaleXFromValue(rc, 0);
  ScaleXFromData(rc, &windstats_mag);
  ScaleYFromData(rc, &windstats_mag);

  DrawYGrid(hdc, rc, 1000/ALTITUDEMODIFY, 0, STYLE_THINDASHPAPER);
  DrawXGrid(hdc, rc, 5/LIFTMODIFY, 0, STYLE_THINDASHPAPER);

  DrawLineGraph(hdc, rc, &windstats_mag,
                STYLE_MEDIUMBLACK);

#define WINDVECTORMAG 25

  numsteps = (int)((rc.bottom-rc.top)/WINDVECTORMAG)-1;

  // draw direction vectors

  POINT wv[4];
  double dX, dY;
  double angle;
  double hfact;
  for (i=0; i<numsteps ; i++) {
    hfact = (i+1)/(double)(numsteps+1);
    h = (flightstats.Altitude_Ceiling.y_max-flightstats.Altitude_Base.y_min)*
      hfact+flightstats.Altitude_Base.y_min;

    wind = windanalyser->windstore.getWind(h, &found);
    if (windstats_mag.x_max == 0)
      windstats_mag.x_max=1;  // prevent /0 problems
    wind.x /= windstats_mag.x_max;
    wind.y /= windstats_mag.x_max;
    mag = sqrt(wind.x*wind.x+wind.y*wind.y);
    if (mag<= 0.0) continue;

    angle = atan2(wind.x,-wind.y)*RAD_TO_DEG;

    wv[0].y = (int)((1-hfact)*(rc.bottom-rc.top))+rc.top;
    wv[0].x = (rc.right+rc.left)/2;

    dX = (mag*WINDVECTORMAG);
    dY = 0;
    rotate(dX,dY,angle);
    wv[1].x = (int)(wv[0].x + dX);
    wv[1].y = (int)(wv[0].y + dY);
    StyleLine(hdc, wv[0], wv[1], STYLE_MEDIUMBLACK);

    dX = (mag*WINDVECTORMAG-5);
    dY = -3;
    rotate(dX,dY,angle);
    wv[2].x = (int)(wv[0].x + dX);
    wv[2].y = (int)(wv[0].y + dY);
    StyleLine(hdc, wv[1], wv[2], STYLE_MEDIUMBLACK);

    dX = (mag*WINDVECTORMAG-5);
    dY = 3;
    rotate(dX,dY,angle);
    wv[3].x = (int)(wv[0].x + dX);
    wv[3].y = (int)(wv[0].y + dY);

    StyleLine(hdc, wv[1], wv[3], STYLE_MEDIUMBLACK);


  }

  DrawXLabel(hdc, rc, TEXT("w"));
  DrawYLabel(hdc, rc, TEXT("h"));

}
Пример #7
0
void Statistics::RenderSpeed(LKSurface& Surface, const RECT& rc)
{

  if ((flightstats.Task_Speed.sum_n<2)
      || !ValidTaskPoint(ActiveTaskPoint)) {
    DrawNoData(Surface, rc);
    return;
  }

  ResetScale();

  ScaleXFromData(rc, &flightstats.Task_Speed);
  ScaleYFromData(rc, &flightstats.Task_Speed);
  ScaleYFromValue(rc, 0);
  ScaleXFromValue(rc, flightstats.Task_Speed.x_min+1.0); // in case no data
  ScaleXFromValue(rc, flightstats.Task_Speed.x_min); 

  for(int j=1;j<MAXTASKPOINTS;j++) {
    if (ValidTaskPoint(j) && (flightstats.LegStartTime[j]>=0)) {
      double xx = 
        (flightstats.LegStartTime[j]-CALCULATED_INFO.TaskStartTime)/3600.0;
      if (xx>=0) {
        DrawLine(Surface, rc,
                 xx, y_min,
                 xx, y_max,
                 STYLE_REDTHICK);
      }
    }
  }

  DrawXGrid(Surface, rc,
            0.5, flightstats.Task_Speed.x_min,
            STYLE_THINDASHPAPER, 0.5, true);

 /* DrawYGrid(hdc, rc, 10/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER,
            10, true);*/
  if(Units::GetUserHorizontalSpeedUnit() == unStatuteMilesPerHour) {
    DrawYGrid(Surface, rc, 5.0/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER, 5.0, true);
  } else {
    DrawYGrid(Surface, rc, 10/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER, 10, true);
  }

  DrawLineGraph(Surface, rc, &flightstats.Task_Speed,STYLE_MEDIUMBLACK);

  DrawTrend(Surface, rc, &flightstats.Task_Speed, STYLE_BLUETHIN);


  if(INVERTCOLORS || IsDithered())
    Surface.SetTextColor(RGB_DARKGREEN);
  else
    Surface.SetTextColor(RGB_GREEN);

  Surface.SetBackgroundOpaque();

  TCHAR text[80];
  DrawXLabel(Surface, rc, TEXT(" t/h "));
  _stprintf(text,TEXT(" v/%s "),Units::GetHorizontalSpeedName());
  DrawYLabel(Surface, rc, text);


//  DrawXLabel(hdc, rc, TEXT("t"));
//  DrawYLabel(hdc, rc, TEXT("V"));

}
Пример #8
0
void
ChartRenderer::DrawXGrid(const double tic_step, ChartLook::Style style,
                         const double unit_step, bool draw_units)
{
  DrawXGrid(tic_step, look.GetPen(style), unit_step, draw_units);
}
Пример #9
0
void PD_2DXYPS::DrawPlotAxes()
{

    if (!plotAnnotation.DoAnno())
    {
        SetClipPlanes();
        return;
    }

    SetIncrFont();

    ClearClipPlanes();

    SetAxesLocals();
    SetLineSolid();

    xAxis.SetMajorIncs();
    xAxis.SetMinorIncs();
    yAxis.SetMajorIncs();
    yAxis.SetMinorIncs();

    SC_DoubleArray xMajorIncs, xMinorIncs, yMajorIncs, yMinorIncs;
    xAxis.GetAxesMajorIncs(xMajorIncs);
    xAxis.GetAxesMinorIncs(xMinorIncs);
    yAxis.GetAxesMajorIncs(yMajorIncs);
    yAxis.GetAxesMinorIncs(yMinorIncs);

    Point2D axesOffComp, labelOffComp;
    bool dummy;
    GetAxesOffsets(axesOffComp, labelOffComp, dummy);

    Point2D majorTicLength = GetPixelComponents(plotAnnotation.majorTicLength);
    Point2D minorTicLength = GetPixelComponents(plotAnnotation.minorTicLength);
    Point2D majorTicOffset = GetPixelComponents(plotAnnotation.majorTicOffset);
    Point2D minorTicOffset = GetPixelComponents(plotAnnotation.minorTicOffset);

    // set Z val
    SetAnnoLow();

    if (plotAnnotation.drawAxesLines)
    {
        AxesDrawSetup();
        HardCopyBlockStart(24);         // 4 axes + 2 caps per axes * 2

        // x axis
        if (plotAnnotation.DoXAxis())
        {
            DrawXAxes(convYaxisMin, -axesOffComp.pY);
            if (plotAnnotation.framePlot)
                DrawXAxes(convYaxisMax, axesOffComp.pY);
        }

        // y axis
        if (plotAnnotation.DoYAxis())
        {
            DrawYAxes(convXaxisMin, -axesOffComp.pX);
            if (plotAnnotation.framePlot)
                DrawYAxes(convXaxisMax, axesOffComp.pX);
        }

        if (plotAnnotation.axesOffset > 0)
        {
            // slight kluge -- tic routines require untransformed X&Ys
            double xmin, xmax, ymin, ymax;
            xAxis.GetAxisLimits(xmin, xmax);
            yAxis.GetAxisLimits(ymin, ymax);

            // draw caps on axes

            if (plotAnnotation.DoXAxis())
            {
                DrawXTic(xmin, convYaxisMin, -axesOffComp.pY, axesOffComp.pY, 0.0);
                DrawXTic(xmax, convYaxisMin, -axesOffComp.pY, axesOffComp.pY, 0.0);

                if (plotAnnotation.framePlot)
                {
                    DrawXTic(xmin, convYaxisMax, axesOffComp.pY, -axesOffComp.pY, 0.0);
                    DrawXTic(xmax, convYaxisMax, axesOffComp.pY, -axesOffComp.pY, 0.0);
                }
            }

            if (plotAnnotation.DoYAxis())
            {
                DrawYTic(convXaxisMin, ymin, -axesOffComp.pX, axesOffComp.pX, 0.0);
                DrawYTic(convXaxisMin, ymax, -axesOffComp.pX, axesOffComp.pX, 0.0);

                if (plotAnnotation.framePlot)
                {
                    DrawYTic(convXaxisMax, ymin, axesOffComp.pX, -axesOffComp.pX, 0.0);
                    DrawYTic(convXaxisMax, ymax, axesOffComp.pX, -axesOffComp.pX, 0.0);
                }
            }
        }
        HardCopyBlockEnd();
        SetAnnoLow();
    }

    double axmaxOffset = 0.0;

    if (plotAnnotation.DoXAxis() && (xAxis.axisMajorIncs != PC_Axes::aitNone))
        if (xAxis.axisMajorIncs == PC_Axes::aitGrid)
        {
            MajorGridDrawSetup();
            HardCopyBlockStart(xMajorIncs.Size() * 2);

            if (plotAnnotation.framePlot)
                axmaxOffset = axesOffComp.pY;

            for (int i = 0; i < xMajorIncs.Size(); i++)
                DrawXGrid(xMajorIncs[i], -axesOffComp.pY, axmaxOffset, majorTicOffset.pY);

            HardCopyBlockEnd();
            SetAnnoLow();
        }
        else
        {
            MajorTicDrawSetup();
            HardCopyBlockStart(xMajorIncs.Size() * 4);
            int i;
            for (i = 0; i < xMajorIncs.Size(); i++)
            {
                DrawXTic(xMajorIncs[i], convYaxisMin, -axesOffComp.pY, majorTicLength.pY, majorTicOffset.pY);
                if (plotAnnotation.framePlot)
                    DrawXTic(xMajorIncs[i], convYaxisMax, axesOffComp.pY, -majorTicLength.pY, -majorTicOffset.pY);
            }
            HardCopyBlockEnd();
        }

    if (plotAnnotation.DoYAxis() && (yAxis.axisMajorIncs != PC_Axes::aitNone))
        if (yAxis.axisMajorIncs == PC_Axes::aitGrid)
        {
            MajorGridDrawSetup();

            if (plotAnnotation.framePlot)
                axmaxOffset = axesOffComp.pX;
            HardCopyBlockStart(yMajorIncs.Size() * 2);

            for (int i = 0; i < yMajorIncs.Size(); i++)
            {

                DrawYGrid(yMajorIncs[i], -axesOffComp.pX, axmaxOffset, majorTicOffset.pX);
            }

            HardCopyBlockEnd();
            SetAnnoLow();
        }
        else
        {
            MajorTicDrawSetup();
            HardCopyBlockStart(yMajorIncs.Size() * 4);
            for (int i = 0; i < yMajorIncs.Size(); i++)
            {
                DrawYTic(convXaxisMin, yMajorIncs[i], -axesOffComp.pX, majorTicLength.pX, majorTicOffset.pX);
                if (plotAnnotation.framePlot)
                    DrawYTic(convXaxisMax, yMajorIncs[i],  axesOffComp.pX, -majorTicLength.pX, -majorTicOffset.pX);
            }
            HardCopyBlockEnd();
        }


    if (plotAnnotation.DoXAxis() && (xAxis.axisMinorIncs != PC_Axes::aitNone))
        if (xAxis.axisMinorIncs == PC_Axes::aitGrid)
        {
            MinorGridDrawSetup();

            if (plotAnnotation.framePlot)
                axmaxOffset = axesOffComp.pY;

            HardCopyBlockStart((xMajorIncs.Size() + 1) * xMinorIncs.Size() * 2);

            for (int i = -1; i < xMajorIncs.Size(); i++)
                for (int j = 0; j < xMinorIncs.Size(); j++)
                    DrawXGrid(GetMinorIncVal(xMajorIncs, xMinorIncs, i, j, doLogX, convXaxisMax < convXaxisMin),
                                            -axesOffComp.pY, axmaxOffset, minorTicOffset.pX);

            HardCopyBlockEnd();
            SetAnnoLow();
        }
        else
        {
            MinorTicDrawSetup();
            HardCopyBlockStart((xMajorIncs.Size() + 1) * xMinorIncs.Size() * 4);
            for (int i = -1; i < xMajorIncs.Size(); i++)
                for (int j = 0; j < xMinorIncs.Size(); j++)
                {
                    double incVal = GetMinorIncVal(xMajorIncs, xMinorIncs, i, j, doLogX, convXaxisMax < convXaxisMin);
                    DrawXTic(incVal, convYaxisMin, -axesOffComp.pY, minorTicLength.pY, minorTicOffset.pY);
                    if (plotAnnotation.framePlot)
                        DrawXTic(incVal, convYaxisMax, axesOffComp.pY, -minorTicLength.pY, -minorTicOffset.pY);
                }
            HardCopyBlockEnd();
        }


    if (plotAnnotation.DoYAxis() && (yAxis.axisMinorIncs != PC_Axes::aitNone))
        if (yAxis.axisMinorIncs == PC_Axes::aitGrid)
        {
            MinorGridDrawSetup();

            if (plotAnnotation.framePlot)
                axmaxOffset = axesOffComp.pX;
            HardCopyBlockStart((yMajorIncs.Size() + 1) * yMinorIncs.Size() * 2);

            for (int i = -1; i < yMajorIncs.Size(); i++)
                for (int j = 0; j < yMinorIncs.Size(); j++)
                    DrawYGrid(GetMinorIncVal(yMajorIncs, yMinorIncs, i, j, doLogY, convYaxisMax < convYaxisMin),
                                    -axesOffComp.pX, axmaxOffset, minorTicOffset.pX);

            HardCopyBlockEnd();
            SetAnnoLow();
        }
        else
        {
            MinorTicDrawSetup();
            HardCopyBlockStart((yMajorIncs.Size() + 1) * yMinorIncs.Size() * 4);
            for (int i = -1; i < yMajorIncs.Size(); i++)
                for (int j = 0; j < yMinorIncs.Size(); j++)
                {
                    double incVal = GetMinorIncVal(yMajorIncs, yMinorIncs, i, j, doLogY, convYaxisMax < convYaxisMin);
                    DrawYTic(convXaxisMin, incVal,  -axesOffComp.pX, minorTicLength.pX, minorTicOffset.pX);
                    if (plotAnnotation.framePlot)
                        DrawYTic(convXaxisMax, incVal,  axesOffComp.pX, -minorTicLength.pX, -minorTicOffset.pX);
                }
            HardCopyBlockEnd();
        }

    double maxHeight = 0.0;
    double xaxYpos = convYaxisMin - axesOffComp.pY - labelOffComp.pY - majorTicOffset.pY;
    double maxWidth = 0.0;
    double yaxXpos = convXaxisMin - axesOffComp.pX - labelOffComp.pX - majorTicOffset.pX;

    if (plotAnnotation.labelIncrements)
    {
        SetDrawColor(defaultPenSet->GetColor(plotAnnotation.axesDataPen));

        char labStr[80];
        ExtendedLabelData labInfo;

        if (plotAnnotation.DoXAxis())
        {
            // need to go through all labels once to calc over top on exponents if horiz
            double exponentShift = 0.0;
            for (int i = 0; i < xMajorIncs.Size(); i++)
            {
                double xTran = TransformX(xMajorIncs[i]);
                if (Limit::WithinOneLimit(convXaxisMin, convXaxisMax, xTran))
                {
                    xAxis.axisIncFormat.RealToString(xMajorIncs[i], labStr, 80);

                    if (xAxis.incrFont.fontRotation == PSC_Font::fr_Horiz)
                    {
                        if (GetExtendedStringSizeInfo(xAxis.incrFont, labStr, labInfo))
                        {
                            if (labInfo.aboveTop > exponentShift)
                                exponentShift = labInfo.aboveTop;
                            double totHeight = labInfo.height + labInfo.aboveTop;
                            if ((fabs(totHeight) > fabs(maxHeight)))
                                maxHeight = totHeight;
                        }
                    }
                    else
                    {
                        double w, h;
                        if (GetStringSizeInfo(xAxis.incrFont, labStr, w, h))
                        {
                            if (fabs(w) > fabs(maxHeight))
                                maxHeight = w;
                        }
                    }
                }
            }

            //set alignment for printing
            HorizontalTextAlignment halign;
            VerticalTextAlignment valign;
            if (xAxis.incrFont.fontRotation == PSC_Font::fr_Horiz)
            {
                halign = hta_Center;
                valign = vta_Top;
            }
            else
            {
                valign = vta_Center;
                if (xAxis.incrFont.fontRotation == PSC_Font::fr_VertLeft)
                    halign = hta_Right;
                else
                    halign = hta_Left;
            }

            // now print label
            double xincLabYPos = xaxYpos - exponentShift;
            for (int i = 0; i < xMajorIncs.Size(); i++)
            {
                double xTran = TransformX(xMajorIncs[i]);
                if (Limit::WithinOneLimit(convXaxisMin, convXaxisMax, xTran))
                {
                    xAxis.axisIncFormat.RealToString(xMajorIncs[i], labStr, 80);

                    PrintString(xAxis.incrFont, labStr, halign, valign,
                                xTran, xincLabYPos);
                }
            }
        }

        if (plotAnnotation.DoYAxis())
        {
            // need to go through all labels once to calc over top on exponents if not horiz
            double exponentShift = 0.0;
            for (int i = 0; i < yMajorIncs.Size(); i++)
            {
                double yTran = TransformY(yMajorIncs[i]);
                if (Limit::WithinOneLimit(convYaxisMin, convYaxisMax, yTran))
                {
                    yAxis.axisIncFormat.RealToString(yMajorIncs[i], labStr, 80);

                    if (yAxis.incrFont.fontRotation != PSC_Font::fr_Horiz)
                    {
                        if (GetExtendedStringSizeInfo(yAxis.incrFont, labStr, labInfo))
                        {
                            if (labInfo.aboveTop > exponentShift)
                                exponentShift = labInfo.aboveTop;
                            double totHeight = labInfo.height + labInfo.aboveTop;
                            if ((fabs(totHeight) > fabs(maxWidth)))
                                maxWidth = totHeight;
                        }
                    }
                    else
                    {
                        double w, h;
                        if ((GetStringSizeInfo(yAxis.incrFont, labStr, w, h))
                            && (fabs(w) > fabs(maxWidth)))
                                maxWidth = w;
                    }
                }
            }

            //set alignment for printing
            HorizontalTextAlignment halign;
            VerticalTextAlignment valign;
            if (yAxis.incrFont.fontRotation == PSC_Font::fr_Horiz)
            {
                halign = hta_Right;
                valign = vta_Center;
            }
            else
            {
                halign = hta_Center;
                if (yAxis.incrFont.fontRotation == PSC_Font::fr_VertLeft)
                    valign = vta_Bottom;
                else
                    valign = vta_Top;
            }

            for (int i = 0; i < yMajorIncs.Size(); i++)
            {
                double yTran = TransformY(yMajorIncs[i]);
                if (Limit::WithinOneLimit(convYaxisMin, convYaxisMax, yTran))
                {
                    yAxis.axisIncFormat.RealToString(yMajorIncs[i], labStr, 80);
                    PrintString(yAxis.incrFont, labStr, halign, valign,
                                yaxXpos, yTran);
                }
            }
        }
    }

    plotAnnotation.xaxesLabelPos.pX = (convXaxisMin + convXaxisMax) / 2.0;
    plotAnnotation.xaxesLabelPos.pY = xaxYpos - maxHeight - labelOffComp.pY;
    plotAnnotation.yaxesLabelPos.pX = yaxXpos - maxWidth - labelOffComp.pX * 2.0;
    plotAnnotation.yaxesLabelPos.pY = (convYaxisMin + convYaxisMax) / 2.0;

    if (plotAnnotation.labelAxes)
    {
        if (plotAnnotation.DoXAxis() && IsNotNull(plotAnnotation.xaxesLabel))
        {
            PrintString(plotAnnotation.labelFont, plotAnnotation.xaxesLabel,
                hta_Center, vta_Top,
                plotAnnotation.xaxesLabelPos.pX, plotAnnotation.xaxesLabelPos.pY);
        }

        if (plotAnnotation.DoYAxis() && IsNotNull(plotAnnotation.yaxesLabel))
        {
            PSC_Font yLabFont(plotAnnotation.labelFont);
            yLabFont.fontRotation = PSC_Font::fr_VertLeft;

            PrintString(yLabFont, plotAnnotation.yaxesLabel, hta_Center, vta_Bottom,
                plotAnnotation.yaxesLabelPos.pX, plotAnnotation.yaxesLabelPos.pY);
        }
    }

    SetClipPlanes();
}
Пример #10
0
/*****************************************************************
 * Alpha Lima splitted RenderContest from Render Task for CC
 * adding FAI Sector display
 ****************************************************************/
void Statistics::RenderFAIOptimizer(LKSurface& Surface, const RECT& rc)
{

unsigned int ui;
double fXY_Scale = 1.0;
double lat0 = 0;
double lon0 = 0;
double lat1 = 0;
double lon1 = 0;
double lat2 = 0;
double lon2 = 0;
double x0, y0, x1, y1, x2=0, y2=0;
double lat_c, lon_c;
double  lat_p = GPS_INFO.Latitude;
double  lon_p = GPS_INFO.Longitude;
BOOL bFlat = false;
#define DRAWPERCENT
#ifdef DRAWPERCENT
double fTotalPercent = 1.0;
#endif

ResetScale();


  CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true);
  const CPointGPSArray &points = result.PointArray();
  if(contestType == CContestMgr::TYPE_FAI_TRIANGLE)
     fXY_Scale = 1.5;

  // find center
  double fTotalDistance = result.Distance();
 if (fTotalDistance < 1) fTotalDistance =1;
  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(LK8PanelUnitFont);
  BOOL bFAITri =  CContestMgr::Instance().FAI();
  double fDist, fAngle;
  lat_c = (y_max+y_min)/2;
  lon_c = (x_max+x_min)/2;

  double  xp = (lon_p-lon_c)*fastcosine(lat_p);
  double  yp = (lat_p-lat_c);

  // 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(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);

  if(result.Type() == contestType)
  {
    for(ui=0; ui<points.size()-1; ui++)
    {
      lat1 = points[ui].Latitude();
      lon1 = points[ui].Longitude();
      lat2 = points[ui+1].Latitude();
      lon2 = points[ui+1].Longitude();

      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      x2 = (lon2-lon_c)*fastcosine(lat2);
      y2 = (lat2-lat_c);
      DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle);

      if( (ui <points.size()-2) && !bFlat && ((fDist / fTotalDistance ) > 0.05) )
      {
		if(fDist > 5000)
		{
                  #ifndef UNDITHER
		  LKColor rgbCol = RGB_BLUE;
		  switch(ui)
		  {
			case 0: rgbCol = RGB_LIGHTYELLOW; break;
			case 1: rgbCol = RGB_LIGHTCYAN  ; break;
			case 2: rgbCol = RGB_LIGHTGREEN ; break;
			default:
			break;
		  }
                  #else
                  LKColor rgbCol = RGB_DARKBLUE;
                  switch(ui)
                  {
                      case 0: rgbCol = RGB_LIGHTGREY; break;
                      case 1: rgbCol = RGB_GREY  ; break;
                      case 2: rgbCol = RGB_MIDDLEGREY ; break;
                      default:
                      break;
                  }
                  #endif
		  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, rgbCol );
		  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, rgbCol );
		}
      }
      if((fDist / fTotalDistance ) > 0.45) /* prevent drawing almost same sectors */
    	bFlat = true;
    }

    // draw track
    for(ui=0; trace.size() && ui<trace.size()-1; ui++)
    {
      lat1 = trace[ui].Latitude();
      lon1 = trace[ui].Longitude();
      lat2 = trace[ui+1].Latitude();
      lon2 = trace[ui+1].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_MEDIUMBLACK);
    }



	for(ui=0; ui<points.size()-1; ui++)
	{
	  lat1 = points[ui].Latitude();
	  lon1 = points[ui].Longitude();
	  lat2 = points[ui+1].Latitude();
	  lon2 = points[ui+1].Longitude();

	  x1 = (lon1-lon_c)*fastcosine(lat1);
	  y1 = (lat1-lat_c);
	  x2 = (lon2-lon_c)*fastcosine(lat2);
	  y2 = (lat2-lat_c);
	  int style = STYLE_REDTHICK;

	  if((ui > 0) && (ui < 3))
	  {
		style = STYLE_BLUETHIN;
		DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle);
	#ifdef DRAWPERCENT

		if((result.Distance()> 5000) && bFAITri)
		{
		  TCHAR text[180];
		  SIZE tsize;
		  fTotalPercent -= fDist/result.Distance();
		  _stprintf(text, TEXT("%3.1f%%"), (fDist/result.Distance()*100.0));
		  Surface.GetTextSize(text, _tcslen(text), &tsize);
                  #ifndef UNDITHER
		  Surface.SetTextColor(RGB_BLUE);
                  #else
		  Surface.SetTextColor(RGB_BLACK);
                  #endif
	      Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2,   ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text));
	    }
	#endif

	    DrawLine(Surface, rc, x1, y1, x2, y2, style);
	  }
	}

    if(bFAITri)
    {
	  if(points.size() >3)
	  {

        if(ISPARAGLIDER)
        {
		  lat0 = CContestMgr::Instance().GetBestNearClosingPoint().Latitude();
		  lon0 = CContestMgr::Instance().GetBestNearClosingPoint().Longitude();
		  lat1 = CContestMgr::Instance().GetBestClosingPoint().Latitude();
		  lon1 = CContestMgr::Instance().GetBestClosingPoint().Longitude();
		  x1 = (lon0-lon_c)*fastcosine(lat0);
		  y1 = (lat0-lat_c);
		  x2 = (lon1-lon_c)*fastcosine(lat1);
		  y2 = (lat1-lat_c);
		  DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_ORANGETHIN ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK);
        }

	    lat1 = points[1].Latitude();
	    lon1 = points[1].Longitude();
	    lat2 = points[3].Latitude();
	    lon2 = points[3].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_THINDASHPAPER ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK);
#ifdef DRAWPERCENT
	    TCHAR text[180];
	    SIZE tsize;
	    _stprintf(text, TEXT("%3.1f%%"), (fTotalPercent*100.0));
	    Surface.GetTextSize(text, _tcslen(text), &tsize);
            #ifndef UNDITHER
	    Surface.SetTextColor(RGB_LIGHTBLUE);
            #else
	    Surface.SetTextColor(RGB_RED);
            #endif
	    Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2,   ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text));
#endif

	    lat0 = CContestMgr::Instance().GetClosingPoint().Latitude();
	    lon0 = CContestMgr::Instance().GetClosingPoint().Longitude();
	    x0 = (lon0-lon_c)*fastcosine(lat0);
	    y0 = (lat0-lat_c);
	    DrawLine(Surface, rc, xp, yp, x0, y0, 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.SetBackgroundTransparent();
#ifndef UNDITHER
Surface.SetTextColor(RGB_MAGENTA);
#else
Surface.SetTextColor(RGB_BLACK);
#endif
DrawLabel(Surface, rc, TEXT("O"), xp, yp);
Surface.SelectObject(hfOldU);

}
Пример #11
0
/*****************************************************************
 * Alpha Lima splitted RenderContest from Render Task for CC
 * adding FAI Sector display
 ****************************************************************/
void Statistics::RenderContest(LKSurface& Surface, const RECT& rc)
{
if(contestType == CContestMgr::TYPE_FAI_TRIANGLE)
   RenderFAIOptimizer(Surface, rc);
else
{
  unsigned int ui;
  double fXY_Scale = 1.0;


  double lat1 = 0;
  double lon1 = 0;
  double lat2 = 0;
  double lon2 = 0;
  double  x1, y1, x2=0, y2=0;
  double lat_c, lon_c;

  ResetScale();


  CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true);
  const CPointGPSArray &points = result.PointArray();


  // find center

  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(LK8PanelUnitFont);
  lat_c = (y_max+y_min)/2;
  lon_c = (x_max+x_min)/2;


  // 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(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 track
  for(ui=0; trace.size() && ui<trace.size()-1; ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    lat2 = trace[ui+1].Latitude();
    lon2 = trace[ui+1].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_MEDIUMBLACK);
  }
  // Draw aircraft on top
double  lat_p = GPS_INFO.Latitude;
double  lon_p = GPS_INFO.Longitude;
double  xp = (lon_p-lon_c)*fastcosine(lat_p);
double  yp = (lat_p-lat_c);


  if(result.Type() == contestType)
  {
    for(ui=0; ui<points.size()-1; ui++)
    {
      lat1 = points[ui].Latitude();
      lon1 = points[ui].Longitude();
      lat2 = points[ui+1].Latitude();
      lon2 = points[ui+1].Longitude();

      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      x2 = (lon2-lon_c)*fastcosine(lat2);
      y2 = (lat2-lat_c);
      int style = STYLE_REDTHICK;
      if((result.Type() == CContestMgr::TYPE_OLC_FAI ||
          result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED) &&
         (ui==0 || ui==3))
      {
        // triangle start and finish
        style = STYLE_DASHGREEN;
      }
      else if(result.Predicted() &&
              (result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED ||
               ui == points.size() - 2))
      {
        // predicted edge
        style = STYLE_BLUETHIN;
      }

      if((result.Type() == CContestMgr::TYPE_FAI_3_TPS) ||// TYPE_FAI_3_TPS_PREDICTED
       (result.Type() == CContestMgr::TYPE_FAI_3_TPS_PREDICTED) )
      {
      }

      if((contestType != CContestMgr::TYPE_FAI_TRIANGLE) )
        DrawLine(Surface, rc, x1, y1, x2, y2, style);
    }


  if(result.Type() == CContestMgr::TYPE_OLC_FAI ||
     result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED)
  {
    // draw the last edge of a triangle
    lat1 = points[1].Latitude();
    lon1 = points[1].Longitude();
    lat2 = points[3].Latitude();
    lon2 = points[3].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, result.Predicted() ? STYLE_BLUETHIN : 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);
  #ifndef UNDITHER
  Surface.SetTextColor(RGB_MAGENTA);
  #else
  Surface.SetTextColor(RGB_BLACK);
  #endif
  Surface.SetBackgroundTransparent();
  DrawLabel(Surface, rc, TEXT("O"), xp, yp);
}
}
}
Пример #12
0
void  MapWindow::RenderNearAirspace(LKSurface& Surface, const RECT rci)
{
RECT rc  = rci; /* rectangle for sideview */
RECT rct = rc; /* rectangle for topview */

rc.top     = (int)((double)(rci.bottom-rci.top  )*fSplitFact);
rct.bottom = rc.top ;
// Expose the topview rect size in use..
Current_Multimap_TopRect=rct;

LKFont	 hfOldFnt = Surface.SelectObject(LK8PanelUnitFont/* Sender->GetFont()*/);

int *iSplit = &Multimap_SizeY[Get_Current_Multimap_Type()];

int  k;
static double fHeigtScaleFact = 1.0;


  double GPSlat, GPSlon, GPSalt, GPSbrg;
  double calc_terrainalt;
  double calc_altitudeagl;

 // double alt;
  TCHAR text[TBSIZE+1];
  TCHAR buffer[TBSIZE+1];

  CAirspaceBase near_airspace;
  CAirspace *found = NULL;
//  bool bFound = false;
  DiagrammStruct sDia;
  bool bAS_Inside=false;
  int iAS_Bearing=0;
  int iAS_HorDistance=15000;
  int iABS_AS_HorDistance=0;
  int iAS_VertDistance=0;
  bool   bValid;
static  bool bHeightScale = false;
  long wpt_brg = 0;
  POINT line[2];
  POINT TxYPt;
  POINT TxXPt;
  SIZE tsize;
  LKColor GREEN_COL     = RGB_GREEN;
  LKColor BLUE_COL      = RGB_BLUE;
  LKColor LIGHTBLUE_COL = RGB_LIGHTBLUE;
  BOOL bInvCol = true; //INVERTCOLORS

  unsigned short getsideviewpage=GetSideviewPage();
  LKASSERT(getsideviewpage<3);

  if(bInvCol)
    Sideview_TextColor = INV_GROUND_TEXT_COLOUR;
  else
    Sideview_TextColor = RGB_WHITE;

	  switch(LKevent) {
		case LKEVENT_NEWRUN:
			// CALLED ON ENTRY: when we select this page coming from another mapspace
			bHeightScale = false;
			// fZOOMScale[getsideviewpage] = 1.0;
			fHeigtScaleFact = 1.0;
			if (IsMultimapTopology()) ForceVisibilityScan=true;
		break;
		case LKEVENT_UP:
			// click on upper part of screen, excluding center
			if(bHeightScale)
			  fHeigtScaleFact /= ZOOMFACTOR;
			else
			  fZOOMScale[getsideviewpage] /= ZOOMFACTOR;

			if (IsMultimapTopology()) ForceVisibilityScan=true;
			break;

		case LKEVENT_DOWN:
			// click on lower part of screen,  excluding center
			if(bHeightScale)
			  fHeigtScaleFact *= ZOOMFACTOR;
			else
		  	  fZOOMScale[getsideviewpage] *= ZOOMFACTOR;
			if (IsMultimapTopology()) ForceVisibilityScan=true;
			break;

		case LKEVENT_LONGCLICK:
		     for (k=0 ; k <= Sideview_iNoHandeldSpaces; k++)
			 {
			   if( Sideview_pHandeled[k].psAS != NULL)
			   {
				 if (PtInRect(&(Sideview_pHandeled[k].rc), startScreen))
				 {	
				   #if 1 // MULTISELECT
				     dlgAddMultiSelectListItem((long*) Sideview_pHandeled[k].psAS, 0, IM_AIRSPACE, 0);
				   #else 	
				     if (EnableSoundModes)PlayResource(TEXT("IDR_WAV_BTONE4"));
				     dlgAirspaceDetails(Sideview_pHandeled[k].psAS);       // dlgA
                   #endif
				   LKevent=LKEVENT_NONE;
				 }
			   }
			 }
			 dlgMultiSelectListShowModal();

		     if ( LKevent != LKEVENT_NONE ) {
			 if (PtInRect(&rc, startScreen))
			   bHeightScale = !bHeightScale;
			 if (PtInRect(&rct, startScreen))
			   bHeightScale = false;
		     }
	     break;

		case LKEVENT_PAGEUP:
#ifdef OFFSET_SETP
			if(bHeightScale)
			  fOffset -= OFFSET_SETP;
			else
#endif
			{
			  if(*iSplit == SIZE1) *iSplit = SIZE0;
			  if(*iSplit == SIZE2) *iSplit = SIZE1;
			  if(*iSplit == SIZE3) *iSplit = SIZE2;
			}
		break;
		case LKEVENT_PAGEDOWN:
#ifdef OFFSET_SETP
			if(bHeightScale)
			  fOffset += OFFSET_SETP;
			else
#endif
			{
			  if(*iSplit == SIZE2) *iSplit = SIZE3;
			  if(*iSplit == SIZE1) *iSplit = SIZE2;
			  if(*iSplit == SIZE0) *iSplit = SIZE1;
			}
		break;

	  }

	  LKASSERT(((*iSplit==SIZE0)||(*iSplit==SIZE1)||(*iSplit==SIZE2)||(*iSplit==SIZE3)||(*iSplit==SIZE4)));

	  LKevent=LKEVENT_NONE;

	  // Current_Multimap_SizeY is global, and must be used by all multimaps!
	  // It is defined in Multimap.cpp and as an external in Multimap.h
	  // It is important that it is updated, because we should resize terrain
	  // only if needed! Resizing terrain takes some cpu and some time.
	  // So we need to know when this is not necessary, having the same size of previous
	  // multimap, if we are switching.
	  // The current implementation is terribly wrong by managing resizing of sideview in
	  // each multimap: it should be done by a common layer.
	  // CAREFUL:
	  // If for any reason DrawTerrain() is called after resizing to 0 (full sideview)
	  // LK WILL CRASH with no hope to recover.
	  if(Current_Multimap_SizeY != *iSplit)
	  {
		Current_Multimap_SizeY=*iSplit;
		SetSplitScreenSize(*iSplit);
		rc.top     = (long)((double)(rci.bottom-rci.top  )*fSplitFact);
		rct.bottom = rc.top ;
	  }


  if(bInvCol)
  {
    GREEN_COL     = GREEN_COL.ChangeBrightness(0.6);
    BLUE_COL      = BLUE_COL.ChangeBrightness(0.6);;
    LIGHTBLUE_COL = LIGHTBLUE_COL.ChangeBrightness(0.4);;
  }

    GPSlat = DrawInfo.Latitude;
    GPSlon = DrawInfo.Longitude;
    GPSalt = DrawInfo.Altitude;
    GPSbrg = DrawInfo.TrackBearing;
    calc_terrainalt  = DerivedDrawInfo.TerrainAlt;
    calc_altitudeagl = DerivedDrawInfo.AltitudeAGL;
    GPSalt =  DerivedDrawInfo.NavAltitude;

  bValid = false;
  iAS_HorDistance = 5000;
  iAS_Bearing     = (int)GPSbrg;
  iAS_VertDistance= 0;
  found = CAirspaceManager::Instance().GetNearestAirspaceForSideview();
  if(found != NULL) {
    near_airspace = CAirspaceManager::Instance().GetAirspaceCopy(found);
    bValid = near_airspace.GetDistanceInfo(bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance);
  }
  iABS_AS_HorDistance = abs( iAS_HorDistance);
  wpt_brg = (long)AngleLimit360(GPSbrg - iAS_Bearing + 90.0);


  // Variables from ASP system here contain the following informations:
  // fAS_HorDistance - always contains horizontal distance from the asp, negative if horizontally inside (This does not mean that we're inside vertically as well!)
  // fAS_Bearing - always contains bearing to the nearest horizontal point
  // bValid - true if bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance contains valid informations
  //          this will be true if the asp border is close enough to be tracked by the warning system
  // bAS_Inside - current position is inside in the asp, calculated by the warning system
  // iAS_HorDistance - horizontal distance to the nearest horizontal border, negative if horizontally inside, calculated by the warning system
  // iAS_Bearing - bearing to the nearest horizontal border, calculated by the warning system
  // iAS_VertDistance - vertical distance to the nearest asp border, negative if the border is above us, positive if the border below us, calculated by the warning system
  // near_airspace.WarningLevel():
  //           awNone - no warning condition exists
  //           awYellow - current position is near to a warning position
  //           awRed - current posisiton is forbidden by asp system, we are in a warning position


  /*********************************************************************
   * calc the horizontal zoom
   *********************************************************************/
  sDia.fXMin = -5000.0;
  sDia.fXMax =  5000.0;
  /* even when invalid the horizontal distance is calculated correctly */


  if(bValid)
  {
	double fScaleDist = iABS_AS_HorDistance;

	sDia.fXMin = min(-2500.0 , fScaleDist * 1.5 );
	sDia.fXMax = max( 2500.0 , fScaleDist * 1.5 );

	#ifdef NEAR_AS_ZOOM_1000M
	if(((iABS_AS_HorDistance) < 900) && (bValid)) // 1km zoom
	{
	  sDia.fXMin = min(-900.0, fScaleDist * 1.5 );
	  sDia.fXMax = max( 900.0, fScaleDist * 1.5 );

	}
	#endif
	#ifdef NEAR_AS_ZOOM_1000FT
	  if((abs(iABS_AS_HorDistance) < 333)) // 1000ft zoom
	  {
		sDia.fXMin = min(-333.0, fScaleDist * 1.5 );
		sDia.fXMax = max( 333.0, fScaleDist * 1.5 );
	  }
	#endif

  }


#define RND_FACT 10.0


   if( ( sDia.fXMax  *fZOOMScale[getsideviewpage]) > 100000)
	  fZOOMScale[getsideviewpage] /= ZOOMFACTOR;

   if(( sDia.fXMax *fZOOMScale[getsideviewpage]) < 500)
   {
	  fZOOMScale[getsideviewpage] *= ZOOMFACTOR;
   }

  double fOldZoomScale=-1;
  if(fZOOMScale[getsideviewpage] != fOldZoomScale)
  {
   fOldZoomScale =  fZOOMScale[getsideviewpage];
   sDia.fXMax = sDia.fXMax *fZOOMScale[getsideviewpage];
   sDia.fXMin = -sDia.fXMax /5;
  }


  /*********************************************************************
   * calc the vertical zoom
   *********************************************************************/
sDia.fYMin = max(0.0, GPSalt-2300);
sDia.fYMax = max(MAXALTTODAY, GPSalt+1000);

if(bValid)
{
  double fBottom = near_airspace.Base()->Altitude;
  sDia.fYMin = min(fBottom*0.8, sDia.fYMin );
  sDia.fYMin = max(0.0, sDia.fYMin );
  if(sDia.fYMin < 300) sDia.fYMin =0;
  sDia.fYMax = max((fBottom*1.2f), sDia.fYMax );

  if(abs(iAS_VertDistance) < 250)
  {
    sDia.fYMax =  ((int)((GPSalt+abs(iAS_VertDistance))/400) + 2) *400 ;
    sDia.fYMin =  ((int)((GPSalt-abs(iAS_VertDistance))/400) - 1) *400 ;
    if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0;
  }

#ifdef VERTICAL_ZOOM_50
  if(abs(iAS_VertDistance) < 50)
  {
    sDia.fYMax =  ((int)((GPSalt+abs(iAS_VertDistance))/100) + 2) *100 ;
    sDia.fYMin =  ((int)((GPSalt-abs(iAS_VertDistance))/100) - 1) *100 ;
    if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0;
  }
#endif
  sDia.fYMin = max((double)0.0f,(double) sDia.fYMin);

#ifdef OFFSET_SETP
	  if(( sDia.fYMax + fOffset) > MAX_ALTITUDE)
		fOffset -= OFFSET_SETP;
	  if(( sDia.fYMin + fOffset) < 0.0)
		fOffset += OFFSET_SETP;

	  sDia.fYMin +=  fOffset;
	  sDia.fYMax +=  fOffset;
#endif
//  if(fHeigtScaleFact * sDia.fYMax > MAX_ALTITUDE )
//    fHeigtScaleFact /=ZOOMFACTOR;

  if(fHeigtScaleFact * sDia.fYMax < MIN_ALTITUDE )
	  fHeigtScaleFact *=ZOOMFACTOR;
  sDia.fYMax *= fHeigtScaleFact;
}


/****************************************************************************************************
 * draw topview first
 ****************************************************************************************************/

  if(fSplitFact > 0.0)
  {
    sDia.rc = rct;
    sDia.rc.bottom-=1;
    SharedTopView(Surface, &sDia, (double) iAS_Bearing, (double) wpt_brg);

  }

  /****************************************************************************************************
   * draw airspace and terrain elements
   ****************************************************************************************************/
  RECT rcc = rc;          /* rc corrected      */
  if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE)
    rcc.bottom -= SV_BORDER_Y; /* scale witout sea  */
  sDia.rc = rcc;

  RenderAirspaceTerrain(Surface, GPSlat, GPSlon, iAS_Bearing, &sDia );

  LKFont hfOld = Surface.SelectObject(LK8InfoNormalFont);
  if(bValid) {
    LKASSERT(_tcslen(near_airspace.Name())<TBSIZE); // Diagnostic only in 3.1j, to be REMOVED
    LK_tcsncpy(Sideview_szNearAS, near_airspace.Name(), TBSIZE );
  } else
  {
	_stprintf(text,TEXT("%s"), MsgToken(1259)); 	 // LKTOKEN _@M1259_ "Too far, not calculated"
	Surface.GetTextSize(text, _tcslen(text), &tsize);
	TxYPt.x = (rc.right-rc.left-tsize.cx)/2;
	TxYPt.y = (rc.bottom-rc.top)/2;

	Surface.SetBkMode(TRANSPARENT);
	Surface.DrawText(TxYPt.x, TxYPt.y-20, text, _tcslen(text));

	_stprintf(Sideview_szNearAS,TEXT("%s"), text);

  }
  Surface.SelectObject(hfOld);
  /****************************************************************************************************
   * draw airspace and terrain elements
   ****************************************************************************************************/

  /****************************************************************************************************
   * draw diagram
   ****************************************************************************************************/
  double xtick = 1.0;
  double fRange =fabs(sDia.fXMax - sDia.fXMin) ;
  if (fRange>3.0*1000.0) xtick = 2.0;
  if (fRange>15*1000.0) xtick = 5.0;
  if (fRange>50.0*1000.0) xtick = 10.0;
  if (fRange>100.0*1000.0) xtick = 20.0;
  if (fRange>200.0*1000.0) xtick = 25.0;
  if (fRange>250.0*1000.0) xtick = 50.0;
  if (fRange>500.0*1000.0) xtick = 100.0;
  if (fRange>1000.0*1000.0) xtick = 1000.0;

  if(bInvCol)
  {
    Surface.SelectObject(LK_BLACK_PEN);
    Surface.SelectObject(LKBrush_Black);
  }
  else
  {
    Surface.SelectObject(LK_WHITE_PEN);
    Surface.SelectObject(LKBrush_White);
  }

  LKColor txtCol = GROUND_TEXT_COLOUR;
  if(bInvCol)
    if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE)
    	txtCol = INV_GROUND_TEXT_COLOUR;
  Surface.SetBkMode(TRANSPARENT);
  Surface.SetTextColor(txtCol);
  _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserDistanceUnit()));

  switch(GetMMNorthUp(getsideviewpage))
  {
	 case NORTHUP:
	 default:
	   DrawXGrid(Surface, rc , xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK,  &sDia,text);
     break;

	 case TRACKUP:
	   DrawXGrid(Surface, rci, xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK,  &sDia,text);
     break;
  }

  Surface.SetTextColor(Sideview_TextColor);

  double  fHeight = (sDia.fYMax-sDia.fYMin);
  double  ytick = 100.0;
  if (fHeight >500.0) ytick = 200.0;
  if (fHeight >1000.0) ytick = 500.0;
  if (fHeight >2000.0) ytick = 1000.0;
  if (fHeight >4000.0) ytick = 2000.0;
  if (fHeight >8000.0) ytick = 4000.0;

  if(Units::GetUserAltitudeUnit() == unFeet)
	 ytick = ytick * FEET_FACTOR;

  _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserAltitudeUnit()));
  if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE)
	  rc.bottom -= SV_BORDER_Y; /* scale witout sea  */
  DrawYGrid(Surface, rc, ytick/ALTITUDEMODIFY,ytick, 0,TEXT_UNDER_RIGHT ,Sideview_TextColor,  &sDia, text);


  if(!bInvCol)
    Surface.SetBkMode(OPAQUE);
  /****************************************************************************************************
   * draw AGL
   ****************************************************************************************************/
  if(calc_altitudeagl - sDia.fYMin  > 500)
  {
    Surface.SetTextColor(LIGHTBLUE_COL);
    Units::FormatUserAltitude(calc_altitudeagl, buffer, 7);
    LK_tcsncpy(text, MsgToken(1742), TBSIZE-_tcslen(buffer)); // AGL:
    _tcscat(text,buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);
    TxYPt.x = CalcDistanceCoordinat(0,  &sDia)- tsize.cx/2;
    TxYPt.y  = CalcHeightCoordinat(  (calc_terrainalt + calc_altitudeagl )*0.8,  &sDia );
    if((tsize.cy) < ( CalcHeightCoordinat(  calc_terrainalt, &sDia )- TxYPt.y )) {
      Surface.DrawText(TxYPt.x+IBLSCALE(1),  TxYPt.y , text, _tcslen(text));
    }
  }

  Surface.SetBkMode(TRANSPARENT);

  /****************************************************************************************************
   * Print current Elevation
   ****************************************************************************************************/
  Surface.SetTextColor(RGB_BLACK);
  int x,y;
  if((calc_terrainalt-  sDia.fYMin)  > 0)
  {
	Units::FormatUserAltitude(calc_terrainalt, buffer, 7);
    LK_tcsncpy(text, MsgToken(1743), TBSIZE-_tcslen(buffer));   // ELV:
    _tcscat(text,buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);
    x = CalcDistanceCoordinat(0, &sDia) - tsize.cx/2;
    y = CalcHeightCoordinat( calc_terrainalt,  &sDia  );
    if ((ELV_FACT*tsize.cy) < abs(rc.bottom - y)) {
      Surface.DrawText(x, rc.bottom -(int)(ELV_FACT * tsize.cy), text, _tcslen(text));
    }
  }


  /****************************************************************************************************
   * draw side elements
   ****************************************************************************************************/
  Surface.SetTextColor(Sideview_TextColor);
  Surface.SetBkMode(OPAQUE);
  LKFont hfOld2 = Surface.SelectObject(LK8InfoNormalFont);

  //  DrawTelescope      ( hdc, iAS_Bearing-90.0, rc.right  - NIBLSCALE(13),  rc.top   + NIBLSCALE(58));

  Surface.SelectObject(hfOld2);
  Surface.SetBkMode(TRANSPARENT);

  Surface.SelectObject(hfOld);
  Surface.SetTextColor(GROUND_TEXT_COLOUR);
  if(bInvCol)
    if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE)
	  Surface.SetTextColor(INV_GROUND_TEXT_COLOUR);



  /****************************************************************************************************/
  /****************************************************************************************************/
  /****************************************************************************************************
   * draw distances to next airspace
   ****************************************************************************************************/
  /****************************************************************************************************/
  /****************************************************************************************************/
  if (bValid)
  {

	/****************************************************************************************************
	 * draw horizontal distance to next airspace
	 ****************************************************************************************************/
	Surface.SetTextColor(Sideview_TextColor);
	Surface.SetBkMode(OPAQUE);
	LKFont hfOldU = Surface.SelectObject(LK8InfoNormalFont);
    // horizontal distance
    line[0].x = CalcDistanceCoordinat(0, &sDia);
    line[0].y = CalcHeightCoordinat(  GPSalt,  &sDia );
    line[1].x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia);
    line[1].y = line[0].y;
    Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    if(iAS_HorDistance < 0)
    {
      line[0].y = CalcHeightCoordinat(  GPSalt - (double)iAS_VertDistance, &sDia );
      line[1].y = line[0].y;

      Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    }

    bool bLeft = false;
    if( line[0].x < line[1].x)
      bLeft = false;
    else
      bLeft = true;

    Units::FormatUserDistance(iABS_AS_HorDistance, buffer, 7);
    _stprintf(text,_T(" %s"),buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);

    if((GPSalt- sDia.fYMin /*-calc_terrainalt */) < 300)
      TxXPt.y = CalcHeightCoordinat(  GPSalt, &sDia ) -  tsize.cy;
    else
      TxXPt.y = CalcHeightCoordinat(  GPSalt, &sDia ) +  NIBLSCALE(3);


    if(tsize.cx > (line[1].x - line[0].x) )
      TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance ,&sDia) -tsize.cx-  NIBLSCALE(3);
    else
      TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance / 2.0, &sDia) -tsize.cx/2;
    Surface.DrawText(TxXPt.x,  TxXPt.y, text, _tcslen(text));



	/****************************************************************************************************
	 * draw vertical distance to next airspace
	 ****************************************************************************************************/
    line[0].x = CalcDistanceCoordinat( iABS_AS_HorDistance , &sDia);
    line[0].y = CalcHeightCoordinat( GPSalt, &sDia );
    line[1].x = line[0].x;
    line[1].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia );

    Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    Units::FormatUserAltitude( (double)abs(iAS_VertDistance), buffer, 7);
    _stprintf(text,_T(" %s"),buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);

    if ( bLeft )
      TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance,  &sDia)- tsize.cx - NIBLSCALE(3);
    else
      TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance,  &sDia)+ NIBLSCALE(5);
    if( abs( line[0].y -  line[1].y) > tsize.cy)
      TxYPt.y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance/2.0, &sDia) -tsize.cy/2 ;
    else
      TxYPt.y = min( line[0].y ,  line[1].y) - tsize.cy ;
    Surface.DrawText(TxYPt.x,  TxYPt.y , text, _tcslen(text));
	Surface.SelectObject(hfOldU);
  }

 /****************************************************************************************************
  * draw plane sideview at least
  ****************************************************************************************************/
  RenderPlaneSideview(Surface, 0.0 , GPSalt,wpt_brg, &sDia );

  hfOldFnt = Surface.SelectObject(LK8InfoNormalFont/* Sender->GetFont()*/);

  DrawMultimap_SideTopSeparator(Surface,rct);

  /****************************************************************************************************
   * draw selection frame
   ****************************************************************************************************/
  if(bHeightScale)
	DrawSelectionFrame(Surface,  rc);
#ifdef TOP_SELECTION_FRAME
  else
	DrawSelectionFrame(hdc,  rci);
#endif
  Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/);
  Surface.SetBkMode(TRANSPARENT);
  Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/);
}