예제 #1
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);
}
예제 #2
0
void Statistics::DrawBarChart(LKSurface& Surface, const RECT& rc, LeastSquares* lsdata) {
  int i;
LKColor Col;
  if (unscaled_x || unscaled_y) {
    return;
  }

if(INVERTCOLORS)
  Col = RGB_GREEN.ChangeBrightness(0.5);
else
  Col = RGB_WHITE;

  LKPen hpBar(PEN_SOLID, IBLSCALE(1), Col);
  LKBrush hbBar(Col);
  const auto oldpen = Surface.SelectObject(hpBar);
  const auto oldbrush = Surface.SelectObject(hbBar);


  int xmin, ymin, xmax, ymax;

  for (i= 0; i<lsdata->sum_n; i++) {
    xmin = (int)((i+1+0.2)*xscale)+rc.left+BORDER_X;
    ymin = (int)((y_max-y_min)*yscale)+rc.top;
    xmax = (int)((i+1+0.8)*xscale)+rc.left+BORDER_X;
    ymax = (int)((y_max-lsdata->ystore[i])*yscale)+rc.top;
    Surface.Rectangle(xmin, ymin, xmax, ymax);
  }

  Surface.SelectObject(oldpen);
  Surface.SelectObject(oldbrush);
}
예제 #3
0
static void OnPaintAirspacePicto(WindowControl * Sender, LKSurface& Surface){
	  (void)Sender;

	  WndFrame  *wPicto = ((WndFrame *)wf->FindByName(TEXT("frmAirspacePicto")));
	  LKASSERT(wPicto!=NULL);
	  const RECT rc = wPicto->GetClientRect();
	  Surface.SelectObject(LKPen_Petrol_C2);

	  Surface.SelectObject(LKBrush_Petrol);
	  Surface.Rectangle(rc.left,rc.top,rc.right,rc.bottom);


	  Surface.SetBkColor(RGB_LIGHTGREY);
      /****************************************************************
       * for drawing the airspace pictorial, we need the original data.
       * copy contain only base class property, not geo data, 
       * original data are shared ressources ! 
       * for that we need to grant all called methods are thread safe
       ****************************************************************/
   {
      CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef());
      CAirspace* airspace = CAirspaceManager::Instance().GetAirspacesForDetails();
      if(airspace) {
        airspace->DrawPicto(Surface, rc);
      }
   }
}
예제 #4
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);
			}
		}
	}
  }
}
예제 #5
0
static void OnAirspacePaintListItem(WindowControl * Sender, LKSurface& Surface){

  TCHAR label[40];
  (void)Sender;
  if (DrawListIndex < AIRSPACECLASSCOUNT){
    int i = DrawListIndex;
	LK_tcsncpy(label, CAirspaceManager::Instance().GetAirspaceTypeText(i), 39);
    int w0, w1, w2, x0;
    if (ScreenLandscape) {
      w0 = 202*ScreenScale;
    } else {
      w0 = 225*ScreenScale;
    }
	// LKTOKEN  _@M789_ = "Warn"
    w1 = Surface.GetTextWidth(MsgToken(789))+ScreenScale*10;
	// LKTOKEN  _@M241_ = "Display"
    w2 = Surface.GetTextWidth(MsgToken(241))+ScreenScale*10;
    x0 = w0-w1-w2;

    Surface.SetTextColor(RGB_BLACK);
    Surface.DrawTextClip(2*ScreenScale, 2*ScreenScale,
                   label, x0-ScreenScale*10);

    if (colormode) {

      Surface.SelectObject(LK_WHITE_PEN);
      Surface.SelectObject(LKBrush_White);
      Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale);
      Surface.SetTextColor(MapWindow::GetAirspaceColourByClass(i));
      Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF));
      Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(i));
      Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale);

    } else {

      bool iswarn;
      bool isdisplay;

      iswarn = (MapWindow::iAirspaceMode[i]>=2);
      isdisplay = ((MapWindow::iAirspaceMode[i]%2)>0);
      if (iswarn) {
	// LKTOKEN  _@M789_ = "Warn"
        _tcscpy(label, MsgToken(789));
        Surface.DrawText(w0-w1-w2, 2*ScreenScale, label);
      }
      if (isdisplay) {
	// LKTOKEN  _@M241_ = "Display"
        _tcscpy(label, MsgToken(241));
        Surface.DrawText(w0-w2, 2*ScreenScale, label);
      }

    }

  }
}
예제 #6
0
void Statistics::DrawXLabel(LKSurface& Surface, const RECT& rc, const TCHAR *text) {
  SIZE tsize;
  const auto hfOld = Surface.SelectObject(LK8GenericVar03Font);
  Surface.GetTextSize(text, _tcslen(text), &tsize);
  int x = rc.right-tsize.cx-IBLSCALE(3);
  int y = rc.bottom-tsize.cy;
  if(INVERTCOLORS)
    Surface.SelectObject(LK_BLACK_PEN);

  Surface.DrawText(x, y, text, _tcslen(text));
  Surface.SelectObject(hfOld);
}
예제 #7
0
static void OnAirspacePatternsPaintListItem(WindowControl * Sender, LKSurface& Surface) {
    (void) Sender;
    if ((DrawListIndex < NUMAIRSPACEBRUSHES) &&(DrawListIndex >= 0)) {
        int i = DrawListIndex;
        Surface.SelectObject(LKBrush_White);
        Surface.SelectObject(LK_BLACK_PEN);
        Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF));
        Surface.SelectObject(MapWindow::GetAirspaceBrush(i));
        Surface.SetTextColor(LKColor(0x00, 0x00, 0x00));
        Surface.Rectangle(100 * ScreenScale, 2 * ScreenScale, 180 * ScreenScale, 22 * ScreenScale);
    }
}
예제 #8
0
void Statistics::DrawYLabel(LKSurface& Surface, const RECT& rc, const TCHAR *text) {
  SIZE tsize;
  const auto hfOld = Surface.SelectObject(LK8GenericVar03Font);
  Surface.GetTextSize(text, _tcslen(text), &tsize);
  int x = max(2,(int)rc.left-(int)tsize.cx);
  int y = rc.top;
  if(INVERTCOLORS)
    Surface.SelectObject(LK_BLACK_PEN);


  Surface.DrawText(x, y, text, _tcslen(text));
  Surface.SelectObject(hfOld);
}
예제 #9
0
static void OnAirspaceColoursPaintListItem(WindowControl * Sender, LKSurface& Surface){
  (void)Sender;
  if ((DrawListIndex < NUMAIRSPACECOLORS) &&(DrawListIndex>=0)) {
    int i = DrawListIndex;
    Surface.SelectObject(LKBrush_White);
    Surface.SelectObject(LK_BLACK_PEN);
    Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF));
    Surface.SelectObject(MapWindow::GetAirspaceSldBrush(i)); // this is the solid brush
    Surface.SetTextColor(MapWindow::GetAirspaceColour(i));
    Surface.Rectangle(
              100*ScreenScale, 
              2*ScreenScale,
              180*ScreenScale,
              22*ScreenScale);
  }
}
예제 #10
0
//
// Draw bearing line to target
//
void MapWindow::DrawGreatCircle(LKSurface& Surface, double startLon, double startLat, double targetLon, double targetLat,
				const RECT& rc) {

  POINT pt[2];

  LatLon2Screen(startLon, startLat, pt[0]);
  LatLon2Screen(targetLon, targetLat, pt[1]);

    if(LKGeom::ClipLine(rc, pt[0], pt[1])) {
        const auto hpOld = Surface.SelectObject(LKPen_GABRG);
        Surface.Polyline(pt, 2);
        Surface.SelectObject(LK_BLACK_PEN);
        Surface.Polyline(pt, 2);
        Surface.SelectObject(hpOld);
    }
}
예제 #11
0
//
// Draw bearing line to target
//
void MapWindow::DrawGreatCircle(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj, 
        double startLon, double startLat, double targetLon, double targetLat) {

    POINT pt[2] = {
        _Proj.LonLat2Screen(startLon, startLat),
        _Proj.LonLat2Screen(targetLon, targetLat)
    };


    if(LKGeom::ClipLine(rc, pt[0], pt[1])) {
        const auto hpOld = Surface.SelectObject(LKPen_GABRG);
        Surface.Polyline(pt, 2);
        Surface.SelectObject(LK_BLACK_PEN);
        Surface.Polyline(pt, 2);
        Surface.SelectObject(hpOld);
    }
}
예제 #12
0
void MapWindow::DrawBestCruiseTrack(LKSurface& Surface, const POINT& Orig)
{
  if (OvertargetMode>OVT_TASK) return;

  if (!ValidTaskPoint(ActiveTaskPoint)) return;

  if (DerivedDrawInfo.WaypointDistance < 0.010) return;

  // dont draw bestcruise indicator if not needed
  if (fabs(DerivedDrawInfo.BestCruiseTrack-DerivedDrawInfo.WaypointBearing)<2) { // 091202 10 to 2
	return;
  } 


  const auto hpOld = Surface.SelectObject(LKPen_Blue_N1);
  const auto hbOld = Surface.SelectObject(LKBrush_Blue);

  if (Appearance.BestCruiseTrack == ctBestCruiseTrackDefault){

    int dy = (long)(70); 
    POINT Arrow[7] = { {-1,-40}, {1,-40}, {1,0}, {6,8}, {-6,8}, {-1,0}, {-1,-40}};

    Arrow[2].y -= dy;
    Arrow[3].y -= dy;
    Arrow[4].y -= dy;
    Arrow[5].y -= dy;

    PolygonRotateShift(Arrow, 7, Orig.x, Orig.y, 
                       DerivedDrawInfo.BestCruiseTrack-DisplayAngle);

    Surface.Polygon(Arrow,7);

  } else
  if (Appearance.BestCruiseTrack == ctBestCruiseTrackAltA){

    POINT Arrow[] = { {-1,-40}, {-1,-62}, {-6,-62}, {0,-70}, {6,-62}, {1,-62}, {1,-40}, {-1,-40}};

    PolygonRotateShift(Arrow, sizeof(Arrow)/sizeof(Arrow[0]),
                       Orig.x, Orig.y, 
                       DerivedDrawInfo.BestCruiseTrack-DisplayAngle);
    Surface.Polygon(Arrow, (sizeof(Arrow)/sizeof(Arrow[0])));
  }

  Surface.SelectObject(hpOld);
  Surface.SelectObject(hbOld);
}
예제 #13
0
void MapWindow::DrawAirSpaceBorders(LKSurface& Surface, const RECT& rc)
{
  CAirspaceList::const_iterator it;
  const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetNearAirspacesRef();
  int airspace_type;
  static bool asp_selected_flash = false;
  asp_selected_flash = !asp_selected_flash;
  LKBrush oldBrush = Surface.SelectObject(LKBrush_Hollow);
  
  CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef());
  //    for (it=airspaces_to_draw.end(); it != airspaces_to_draw.begin(); it--)

      /***********************************************************************
       * draw underlying aispaces first (reverse order) with bigger pen
       * *********************************************************************/
      it=airspaces_to_draw.end();
      if (it!=airspaces_to_draw.begin())
      do
      {
	it--;
        if ((*it)->DrawStyle()) {
          airspace_type = (*it)->Type();
          if ( asp_selected_flash && (*it)->Selected() ) {
            Surface.SelectObject(LK_BLACK_PEN);
          } else {
            Surface.SelectObject(hBigAirspacePens[airspace_type]);
          }
          if((*it)->DrawStyle()==adsDisabled)
            Surface.SelectObject(LKPen_Grey_N2 );

          (*it)->Draw(Surface, rc, false);
        }
      } while (it !=airspaces_to_draw.begin());

      /***********************************************************************
       * now draw aispaces on top (normal order) with thin pen
       ***********************************************************************/

      for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) {
        if ((*it)->DrawStyle()) {
          airspace_type = (*it)->Type();
          if ( asp_selected_flash && (*it)->Selected() ) {
            Surface.SelectObject(LK_BLACK_PEN);
          } else {
            Surface.SelectObject(hAirspacePens[airspace_type]);
          }
          if((*it)->DrawStyle()==adsDisabled)
            Surface.SelectObject(LKPen_Black_N0 );
          (*it)->Draw(Surface, rc, false);
        }
      }//for


  Surface.SelectObject(oldBrush);
}
예제 #14
0
void MapWindow::LKDrawLongTrail( LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) {
    static RasterPoint snail_polyline[array_size(LongSnailTrail)+1]; // +1 for last point of "normal" snail trail

    if (TrailActive != 3) return; // only when full trail is selected
    if (iLongSnailNext < 2) return; // no reason to draw a single point

    if (MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) {
        return;
    }

    // pixel manhattan distance
    // It is the sum of x and y differences between previous and next point on screen, in pixels.
    // below this distance, no painting
    const unsigned nearby=10;

    const LONG_SNAIL_POINT* end_iterator = std::begin(LongSnailTrail);
    const LONG_SNAIL_POINT* cur_iterator = std::prev(std::next(LongSnailTrail,iLongSnailNext));
    RasterPoint* polyline_iterator = std::begin(snail_polyline);

    const SNAIL_POINT* last_point = std::next(std::next(SnailTrail, iSnailNext));
    if(last_point == std::end(SnailTrail)) {
        last_point = std::begin(SnailTrail);
    }
    (*polyline_iterator) = _Proj.LonLat2Screen(last_point->Longitude, last_point->Latitude);

    polyline_iterator = std::next(polyline_iterator);

    const auto oldPen = Surface.SelectObject(hSnailPens[3]); // blue color

    while(cur_iterator != end_iterator) {

        (*polyline_iterator) = _Proj.LonLat2Screen(cur_iterator->Longitude, cur_iterator->Latitude);

        if(manhattan_distance(*std::prev(polyline_iterator),(*polyline_iterator)) > nearby) {
            polyline_iterator = std::next(polyline_iterator);
        }
        cur_iterator = std::prev(cur_iterator);
    }
    Surface.Polyline(snail_polyline, std::distance(snail_polyline, polyline_iterator) , rc);

    Surface.SelectObject(oldPen);
}
예제 #15
0
void MapWindow::DrawStartEndSector(LKSurface& Surface, const RECT& rc,
        const POINT &Start, const POINT &End, int Index,
        int Type, double Radius) {

    double tmp;
    LKSurface::OldPen oldpen;
    LKSurface::OldBrush oldbrush;

    switch (Type) {
        case 0: // CIRCLE
            tmp = Radius * zoom.ResScaleOverDistanceModify();
            oldpen = Surface.SelectObject(hpStartFinishThick);
            oldbrush = Surface.SelectObject(LKBrush_Hollow);
            Surface.Circle(WayPointList[Index].Screen.x,
                    WayPointList[Index].Screen.y, (int) tmp, rc, false, false);
            Surface.SelectObject(LKPen_Red_N1);
            Surface.Circle(WayPointList[Index].Screen.x,
                    WayPointList[Index].Screen.y, (int) tmp, rc, false, false);

            Surface.SelectObject(oldpen);
            Surface.SelectObject(oldbrush);
            break;
        case 1: // LINE
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), End, Start, taskcolor, rc);
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), End, Start, LKColor(255, 0, 0), rc);
            break;
        case 2: // SECTOR
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), WayPointList[Index].Screen,
                    Start, taskcolor, rc);
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), WayPointList[Index].Screen,
                    End, taskcolor, rc);
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), WayPointList[Index].Screen,
                    Start, LKColor(255, 0, 0), rc);
            Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), WayPointList[Index].Screen,
                    End, LKColor(255, 0, 0), rc);
            break;
    }

}
예제 #16
0
void Statistics::DrawLabel(LKSurface& Surface, const RECT& rc, const TCHAR *text,
			   const double xv, const double yv) {

  SIZE tsize;
  Surface.GetTextSize(text, _tcslen(text), &tsize);
  int x = (int)((xv-x_min)*xscale)+rc.left-tsize.cx/2+BORDER_X;
  int y = (int)((y_max-yv)*yscale)+rc.top-tsize.cy/2;
//  SetBkMode(hdc, OPAQUE);
  if(INVERTCOLORS)
    Surface.SelectObject(LK_BLACK_PEN);


  Surface.DrawText(x, y, text, _tcslen(text));
  Surface.SetBackgroundTransparent();
}
예제 #17
0
//
// Like DrawDashLine, but with two alternating colors
//
void MapWindow::DrawMulticolorDashLine(LKSurface& Surface, const int width,
			     const POINT& ptStart, const POINT& ptEnd, const LKColor& cr1, const LKColor& cr2,
			     const RECT& rc)
{
  int i;
  POINT pt[2];
  bool flipcol=false;
  #ifdef GTL2
  int Offset = ((width - 1) / 2) + 1;
               // amount to shift 1st line to center
               // the group of lines properly
  #endif

  //Create a dot pen
  LKPen hpDash1(PEN_DASH, 1, cr1);
  LKPen hpDash2(PEN_DASH, 1, cr2);
  const auto hpOld = Surface.SelectObject(hpDash1);

  #ifdef GTL2
  pt[0] = ptStart;
  pt[1] = ptEnd;
  #else
  pt[0].x = ptStart.x;
  pt[0].y = ptStart.y;
  pt[1].x = ptEnd.x;
  pt[1].y = ptEnd.y;
  #endif
  
  //increment on smallest variance
  if(abs(ptStart.x - ptEnd.x) < abs(ptStart.y - ptEnd.y)){
    #ifdef GTL2
    pt[0].x -= Offset;
    pt[1].x -= Offset;
    #endif
    for (i = 0; i < width; i++, flipcol=!flipcol){
      flipcol ?  Surface.SelectObject(hpDash2) : Surface.SelectObject(hpDash1);
      pt[0].x += 1;
      pt[1].x += 1;     
      Surface.Polyline(pt, 2, rc);
    }   
  } else {
    #ifdef GTL2
    pt[0].y -= Offset;
    pt[1].y -= Offset;
    #endif
    for (i = 0; i < width; i++, flipcol=!flipcol){
      flipcol ?  Surface.SelectObject(hpDash2) : Surface.SelectObject(hpDash1);
      pt[0].y += 1;
      pt[1].y += 1;     
      Surface.Polyline(pt, 2, rc);
    }   
  }
  
  Surface.SelectObject(hpOld);
  
} 
예제 #18
0
void MapWindow::DrawAirSpaceBorders(LKSurface& Surface, const RECT& rc)
{
  static bool asp_selected_flash = false;
  asp_selected_flash = !asp_selected_flash;
  const auto oldBrush = Surface.SelectObject(LKBrush_Hollow);
  
  ScopeLock guard(CAirspaceManager::Instance().MutexRef());
  const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetNearAirspacesRef();
  
      /***********************************************************************
       * draw underlying aispaces first (reverse order) with bigger pen
       * *********************************************************************/
      for (CAirspaceList::const_reverse_iterator it=airspaces_to_draw.rbegin(); it != airspaces_to_draw.rend(); ++it) {
        if ((*it)->DrawStyle()) {

          if ( asp_selected_flash && (*it)->Selected() ) {
            Surface.SelectObject(LK_BLACK_PEN);
          } else {
            Surface.SelectObject(hBigAirspacePens[(*it)->Type()]);
          }
          if((*it)->DrawStyle()==adsDisabled) {
            Surface.SelectObject(LKPen_Grey_N2 );
          }

          (*it)->Draw(Surface, false);
        }
      } // for

      /***********************************************************************
       * now draw airspaces on top (normal order) with thin pen
       ***********************************************************************/

      for (CAirspaceList::const_iterator it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) {
        if ((*it)->DrawStyle()) {
          if ( asp_selected_flash && (*it)->Selected() ) {
            Surface.SelectObject(LK_BLACK_PEN);
          } else {
            Surface.SelectObject(hAirspacePens[(*it)->Type()]);
          }
          if((*it)->DrawStyle() != adsDisabled)
            (*it)->Draw(Surface, false);
        }
      }//for


  Surface.SelectObject(oldBrush);
}
예제 #19
0
static void OnProgressPaint(WindowControl * Sender, LKSurface& Surface) {
  RECT PrintAreaR = Sender->GetClientRect();
    
  const auto oldFont = Surface.SelectObject(MapWindowBoldFont);

  Surface.FillRect(&PrintAreaR, LKBrush_Petrol);

  // Create text area

  // we cannot use LKPen here because they are not still initialised for startup menu. no problem
  LKPen hP(PEN_SOLID,NIBLSCALE(1),RGB_GREEN);
  auto ohP = Surface.SelectObject(hP);
  const auto ohB = Surface.SelectObject(LKBrush_Petrol);
  Surface.Rectangle(PrintAreaR.left,PrintAreaR.top,PrintAreaR.right,PrintAreaR.bottom);
  Surface.SelectObject(ohP);
  hP.Release();

  hP.Create(PEN_SOLID,NIBLSCALE(1),RGB_BLACK);
  ohP = Surface.SelectObject(hP);
  Surface.SelectObject(LK_HOLLOW_BRUSH);
  InflateRect(&PrintAreaR, -NIBLSCALE(2), -NIBLSCALE(2));
  Surface.Rectangle(PrintAreaR.left,PrintAreaR.top,PrintAreaR.right,PrintAreaR.bottom);

  Surface.SetTextColor(RGB_WHITE);
  Surface.SetBackgroundTransparent();

  InflateRect(&PrintAreaR, -NIBLSCALE(2), -NIBLSCALE(2));
  
  const TCHAR* text = Sender->GetCaption();
  Surface.DrawText(text, &PrintAreaR, DT_VCENTER|DT_SINGLELINE);

  Surface.SelectObject(ohB);
  Surface.SelectObject(ohP);
  Surface.SelectObject(oldFont);
   
}
예제 #20
0
void RawWrite(LKSurface& Surface, const TCHAR *text, int line, short fsize, const LKColor& rgbcolor, int wtmode) {
    const auto oldfont = Surface.SelectObject(MapWindowFont);
    switch (fsize) {
        case 0:
            Surface.SelectObject(TitleWindowFont);
            break;
        case 1:
            Surface.SelectObject(LK8MapFont);
            break;
        case 2:
            Surface.SelectObject(LK8MediumFont);
            break;
        case 3:
            Surface.SelectObject(LK8BigFont);
            break;
    }
    Surface.SetBackgroundTransparent();
    SIZE tsize;
    Surface.GetTextSize(text, &tsize);
    const int y = tsize.cy * (line - 1) + (tsize.cy / 2);

    MapWindow::LKWriteText(Surface, text, ScreenSizeX / 2, y, wtmode, WTALIGN_CENTER, rgbcolor, false);
    Surface.SelectObject(oldfont);
}
예제 #21
0
void MapWindow::DrawGlideThroughTerrain(LKSurface& Surface, const RECT& rc) {
  LKPen hpOld;

  //double h,dh;
  TCHAR hbuf[10];
  static bool doinit=true;
  static TextInBoxMode_t tmode = {0};
  bool wrotevalue=false;

  if (doinit) {
    memset((void*)&tmode, 0, sizeof(TextInBoxMode_t));
    tmode.Border=1;
    doinit=false;
  }

  #ifdef GTL2
  bool ValidTP = ValidTaskPoint(ActiveWayPoint);

  // draw glide terrain line around next WP
  bool DrawGTL2 = ValidTP && (FinalGlideTerrain > 2);
  static bool LastDrewGTL2 = false;

  if (DrawGTL2) {
    int wp_index = (DoOptimizeRoute() || ACTIVE_WP_IS_AAT_AREA) ? 
                   RESWP_OPTIMIZED : TASKINDEX;

    double alt_arriv = WayPointCalc[wp_index].AltArriv[AltArrivMode];
    
    // Calculate arrival altitude at the next waypoint relative to
    // the "terrain height" safety setting.

    if (CheckSafetyAltitudeApplies(wp_index))
      alt_arriv += SAFETYALTITUDEARRIVAL/10; // AGL
    alt_arriv -= SAFETYALTITUDETERRAIN/10;   // rel. to "terrain height"

    if (alt_arriv <= 0) DrawGTL2 = false;
  }
  
  if (LastDrewGTL2 != DrawGTL2) {
    LastDrewGTL2 = DrawGTL2;
    if (!DrawGTL2) ClearGTL2(); // clear next-WP glide terrain line
  }
  #endif

  hpOld = Surface.SelectObject(hpTerrainLineBg); 

  #ifdef GTL2
  // Draw the wide, solid part of the glide terrain line.
  #else
  // draw a dashed perimetral line first
  #endif
  Surface.Polyline(Groundline,NUMTERRAINSWEEPS+1, rc);

  // draw perimeter if selected and during a flight
  #ifdef GTL2
  if (((FinalGlideTerrain == 1) || (FinalGlideTerrain == 3)) || 
     ((!IsMultimapTerrain() || !DerivedDrawInfo.Flying) && FinalGlideTerrain)) { 
  #else
  if ((FinalGlideTerrain==1) || ((!IsMultimapTerrain() || !DerivedDrawInfo.Flying) && (FinalGlideTerrain==2))) { 
  #endif
	Surface.SelectObject(hpTerrainLine);
	Surface.Polyline(Groundline,NUMTERRAINSWEEPS+1, rc);
  }
  
  #ifdef GTL2  
  // draw glide terrain line around next waypoint
  if (DrawGTL2) {
    // Draw a solid white line.
    Surface.SelectObject(LKPen_White_N2);
    Surface.Polyline(Groundline2, NUMTERRAINSWEEPS+1, rc);

    // Draw a dashed red line.
    Surface.DrawDashPoly(NIBLSCALE(2), RGB_RED, Groundline2, NUMTERRAINSWEEPS+1, rc);
  }
  #endif

  // draw red cross obstacles only if destination looks reachable!
  // only if using OVT_TASK of course!

  #ifdef GTL2
  if ((OvertargetMode == OVT_TASK) && DerivedDrawInfo.Flying && ValidTP)
  #else
  if ( (OvertargetMode==OVT_TASK) && DerivedDrawInfo.Flying && ValidTaskPoint(ActiveWayPoint))
  #endif
  if (WayPointCalc[TASKINDEX].AltArriv[AltArrivMode] >0) { 

	POINT sc;
	// If calculations detected an obstacle...
	if ((DerivedDrawInfo.TerrainWarningLatitude != 0.0) &&(DerivedDrawInfo.TerrainWarningLongitude != 0.0)) {

		// only if valid position, and visible
		if (DerivedDrawInfo.FarObstacle_Lon >0) 
		if (PointVisible(DerivedDrawInfo.FarObstacle_Lon, DerivedDrawInfo.FarObstacle_Lat)) {
			LatLon2Screen(DerivedDrawInfo.FarObstacle_Lon, DerivedDrawInfo.FarObstacle_Lat, sc);
			DrawBitmapIn(Surface, sc, hTerrainWarning,true);

			if (DerivedDrawInfo.FarObstacle_AltArriv <=-50 ||  DerivedDrawInfo.FarObstacle_Dist<5000 ) {
				_stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.FarObstacle_AltArriv);
				TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); 
				wrotevalue=true;
			}
		} // visible far obstacle

		if (PointVisible(DerivedDrawInfo.TerrainWarningLongitude, DerivedDrawInfo.TerrainWarningLatitude)) {
			LatLon2Screen(DerivedDrawInfo.TerrainWarningLongitude, DerivedDrawInfo.TerrainWarningLatitude, sc);
			DrawBitmapIn(Surface, sc, hTerrainWarning,true);
#if 0
			// 091203 add obstacle altitude on moving map
			h =  max(0,RasterTerrain::GetTerrainHeight(DerivedDrawInfo.TerrainWarningLatitude, 
				DerivedDrawInfo.TerrainWarningLongitude)); 
			if (h==TERRAIN_INVALID) h=0; //@ 101027 FIX but unused
			dh = CALCULATED_INFO.NavAltitude - h - (SAFETYALTITUDETERRAIN/10);
			_stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*dh);
			TextInBox(hDC,&rc,hbuf,sc.x+NIBLSCALE(10), sc.y, 0, tmode,false); 
#else
			// if far obstacle was painted with value...
			if (wrotevalue) {
				// if it is not too near the nearest..
				if ( (fabs(DerivedDrawInfo.FarObstacle_Lon - DerivedDrawInfo.TerrainWarningLongitude) >0.02) &&
					(fabs(DerivedDrawInfo.FarObstacle_Lat - DerivedDrawInfo.TerrainWarningLatitude) >0.02)) {
					// and it the arrival altitude is actually negative (rounding terrain errors?)
					if ( DerivedDrawInfo.ObstacleAltArriv <=-50)
					// and there is a significant difference in the numbers, then paint value also for nearest
					if (  fabs(DerivedDrawInfo.ObstacleAltArriv - DerivedDrawInfo.FarObstacle_AltArriv) >100 ) {
						_stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.ObstacleAltArriv);
						TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); 
					}
				}
			} else {
				// else paint value only if meaningful or very close to us
				// -1 to 10m become -1 for rounding errors
				if ( (DerivedDrawInfo.ObstacleAltArriv >-1) && (DerivedDrawInfo.ObstacleAltArriv <10))
					DerivedDrawInfo.ObstacleAltArriv=-1;
				if (DerivedDrawInfo.ObstacleAltArriv <=-50 ||  
				 ((DerivedDrawInfo.ObstacleAltArriv<0) && (DerivedDrawInfo.ObstacleDistance<5000)) ) {

					_stprintf(hbuf,_T(" %.0f"),ALTITUDEMODIFY*DerivedDrawInfo.ObstacleAltArriv);
					TextInBox(Surface,&rc,hbuf,sc.x+NIBLSCALE(15), sc.y, 0, &tmode,false); 
				}
			}
#endif
		} // visible nearest obstacle
	} // obstacles detected
  } // within glide range

  Surface.SelectObject(hpOld);
}
예제 #22
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);
}
예제 #23
0
파일: TopView.cpp 프로젝트: brunotl/LK8000
int MapWindow::SharedTopView(LKSurface& Surface, DiagrammStruct* psDia , double fAS_Bearing, double fWP_Bearing)
{
    int iOldDisplayOrientation =  DisplayOrientation;
    DiagrammStruct m_Dia =	*psDia;
    const RECT& rct = m_Dia.rc;

    unsigned short getsideviewpage=GetSideviewPage();
    LKASSERT(getsideviewpage<NUMBER_OF_SHARED_MULTIMAPS);
    LKASSERT(Current_Multimap_SizeY!=SIZE0);

    DisplayOrientation = GetMMNorthUp(getsideviewpage);

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        break;

    case NORTHUP:
    default:
        m_Dia.fXMin = -m_Dia.fXMax;
        break;
    }

    double fOldScale  =  zoom.Scale();
    const auto hfOld = Surface.SelectObject(LK8PanelUnitFont);

    if(zoom.AutoZoom())
        zoom.AutoZoom(false);
    double fFact = 1.25 ;
#ifdef INIT_CASE


    switch(ScreenSize) {

    case ss800x480:
        fFact=0.750;
        break;
    case ss640x480:
        fFact=0.938;
        break;
    case ss480x272:
        fFact=0.708;
        break;
    case ss400x240:
        fFact=0.750;
        break;
    case ss320x240:
        fFact=0.938;
        break;
    case ss480x800:
        fFact=1.250;
        break;
    case ss480x640:
        fFact=1.250;
        break;
    case ss272x480:
        fFact=1.250;
        break;
    case ss240x400:
        fFact=1.250;
        break;
    case ss240x320:
        fFact=1.250;
        break;
    default:
        fFact=1.000;
        break;
    }
#endif


    if((ScreenSizeX > 0) && (ScreenSizeY > 0))
    {
        if(ScreenSizeX > ScreenSizeY)
            fFact = (double)ScreenSizeY/(double)ScreenSizeX * 1.250;

    }
    PanLatitude  = DrawInfo.Latitude;
    PanLongitude = DrawInfo.Longitude;

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        DisplayAngle = AngleLimit360(fAS_Bearing  +270.0);
        DisplayAircraftAngle = AngleLimit360(fWP_Bearing);
        break;

    case NORTHUP:
    default:
        DisplayAngle = 0;
        if( getsideviewpage == IM_HEADING || getsideviewpage==IM_VISUALGLIDE)
            DisplayAircraftAngle = AngleLimit360(fAS_Bearing);
        else
            DisplayAircraftAngle = AngleLimit360(DrawInfo.TrackBearing);
        break;
    }

    int iOldLocator = EnableThermalLocator;
    EnableThermalLocator =0;

    /*******/
#warning "wrong place for do that, always bad idea to change layout inside drawing fonctions !"
    MapWindow::ChangeDrawRect(rct);       // set new area for terrain and topology
    /*******/

    zoom.RequestedScale((m_Dia.fXMax -m_Dia.fXMin)  * fFact *  (DISTANCEMODIFY)/10.0f);

    POINT Orig           =  { CalcDistanceCoordinat(0.0,  (DiagrammStruct*) &m_Dia),(rct.bottom-rct.top)/2};
    POINT Orig_Aircraft= {0,0};

    zoom.ModifyMapScale();
    zoom.UpdateMapScale();

    const ScreenProjection _Proj = CalculateScreenPositions( Orig, rct, &Orig_Aircraft);

    CalculateScreenPositionsAirspace(rct, _Proj);

    bool terrainpainted=false;

    if (IsMultimapTerrain() &&  DerivedDrawInfo.TerrainValid && RasterTerrain::isTerrainLoaded() ) {
        LKTextBlack=false;
        BlackScreen=false;
        LockTerrainDataGraphics();
        DrawTerrain(Surface, rct, _Proj, GetAzimuth(), 40.0);
        UnlockTerrainDataGraphics();
        terrainpainted=true;
    } else {
        // We fill up the background wity chosen empty map color
        Surface.FillRect(&rct, hInvBackgroundBrush[BgMapColor]);
        // We force LK painting black values on screen depending on the background color in use
        // blackscreen would force everything to be painted white, instead
        LKTextBlack=BgMapColorTextBlack[BgMapColor];
        if (BgMapColor>6 ) BlackScreen=true;
        else BlackScreen=false;
    }

    ResetLabelDeclutter();

    // We reduce screen cluttering for some cases..
    short olddecluttermode=DeclutterMode;
    if (Current_Multimap_SizeY==SIZE4) goto _nomoredeclutter;
    if (Current_Multimap_SizeY<SIZE3) {
        DeclutterMode+=2;
    } else {
        if (Current_Multimap_SizeY==SIZE3)
            DeclutterMode++;
    }
    if (DeclutterMode>dmVeryHigh) DeclutterMode=dmVeryHigh;

_nomoredeclutter:

    if (IsMultimapTopology()) {
        // Do not print topology labels, to be used with another config later!
        // SaturateLabelDeclutter();
        DrawTopology(Surface, rct, _Proj);
    } else {
        // No topology is desired, but terrain requires water areas nevertheless
        if (terrainpainted) {
            DrawTopology(Surface, rct, _Proj, true); // water only!
        }
    }


    if (IsMultimapAirspace()) {
        DrawAirSpace(Surface, rct, _Proj);   // full screen, to hide clipping effect on low border
    }

    if (Flags_DrawTask && MapSpaceMode!=MSM_MAPASP && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTaskAAT(Surface, rct);
        DrawTask(Surface, rct, _Proj, Orig_Aircraft);
    }

    if (IsMultimapWaypoints()) {
        DrawWaypointsNew(Surface,rct);
    }
    if (Flags_DrawFAI)
        DrawFAIOptimizer(Surface, rct, _Proj, Orig_Aircraft);

    DeclutterMode=olddecluttermode; // set it back correctly

    /* THIS STUFF DOES NOT WORK IN SHARED MAPS, YET
       NEED FIXING LatLon2Screen for shared maps using Sideview
       #ifdef GTL2
       if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) &&
    DerivedDrawInfo.TerrainValid)
    DrawTerrainAbove(hdc, rct);
       #endif
     */


    //
    // Stuff for MAPTRK only (M1)
    if (MapSpaceMode==MSM_MAPTRK) {
        if(IsMultimapTerrain() || IsMultimapTopology() ) {
            if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid)
                DrawGlideThroughTerrain(Surface, rct, _Proj);
        }
        if (extGPSCONNECT)
            DrawBearing(Surface, rct, _Proj);
        // Wind arrow
        if (IsMultimapOverlaysGauges())
            DrawWindAtAircraft2(Surface, Orig_Aircraft, rct);
    }

    if (MapSpaceMode==MSM_MAPWPT) {
        if (extGPSCONNECT)
            DrawBearing(Surface, rct, _Proj);
    }

    switch(GetMMNorthUp(getsideviewpage)) {
    case NORTHUP:
    default:
        DrawCompass( Surface,  rct, 0);
        break;
    case TRACKUP:
        if(getsideviewpage ==  IM_HEADING || getsideviewpage == IM_VISUALGLIDE)
            DrawCompass( Surface,  rct, DrawInfo.TrackBearing-90.0);
        else
            DrawCompass( Surface,  rct, DisplayAngle);
        break;
    }


    /****************************************************************************************************
     * draw vertical line
     ****************************************************************************************************/
    POINT line[2];
    line[0].x = rct.left;
    line[0].y = Orig_Aircraft.y-1;
    line[1].x = rct.right;
    line[1].y = line[0].y;

    switch(GetMMNorthUp(getsideviewpage))
    {
    case TRACKUP:
        // Are we are not topview fullscreen?
        if (Current_Multimap_SizeY<SIZE4 && !(MapSpaceMode==MSM_VISUALGLIDE)) {
            Surface.DrawDashLine(NIBLSCALE(1), line[0], line[1],  Sideview_TextColor, rct);
        } else {
            if (TrackBar) {
                DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax);
                if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true);
            }
        }
        break;

    case NORTHUP:
    default:
        if (TrackBar) {
            DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax);
            if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true);
        }
        break;
    }
    DrawAircraft(Surface, Orig_Aircraft);

    // M3 has sideview always on, so wont apply here, and no need to check
    if (Current_Multimap_SizeY==SIZE4) {
        DrawMapScale(Surface,rct,0);
    }

    MapWindow::zoom.RequestedScale(fOldScale);
    EnableThermalLocator = iOldLocator;
    DisplayOrientation = iOldDisplayOrientation;
    Surface.SelectObject(hfOld);
    return 0;

}
예제 #24
0
void MapWindow::DrawVisualGlide(LKSurface& Surface, const DiagrammStruct& sDia) {

    const RECT& rci = sDia.rc;

    unsigned short numboxrows = 1;

#if BUGSTOP
    LKASSERT(Current_Multimap_SizeY < SIZE4);
#endif
    switch (Current_Multimap_SizeY) {
        case SIZE0:
        case SIZE1:
            numboxrows = 3;
            break;
        case SIZE2:
            numboxrows = 2;
            break;
        case SIZE3:
            numboxrows = 1;
            break;
        case SIZE4:
            return;
        default:
            LKASSERT(0);
            break;
    }

    if (!ScreenLandscape) {
        numboxrows++;
        if (numboxrows > 3) numboxrows = 3;
    }

    TCHAR tmpT[30];

    line1Font = LK8VisualTopFont;
    line2Font = LK8VisualBotFont;
    SIZE textSizeTop, textSizeBot;
    Surface.SelectObject(line1Font);
    _stprintf(tmpT, _T("MMMM"));
    Surface.GetTextSize(tmpT, &textSizeTop);
    Surface.SelectObject(line2Font);
    _stprintf(tmpT, _T("55.5%s 79%s%s "), Units::GetDistanceName(), MsgToken(2179), MsgToken(2183));
    Surface.GetTextSize(tmpT, &textSizeBot);

    // we can cut the waypoint name, but not the value data, so we use the second row of data
    // to size the box for everything.
    maxtSizeX = textSizeBot.cx;

    int a = (rci.right-rci.left) / (textSizeBot.cx+BOXINTERVAL);
    int b = (rci.right-rci.left) - a * (textSizeBot.cx)-(BOXINTERVAL * (a + 1));

    boxSizeX = textSizeBot.cx + (b / (a + 1));
    boxSizeY = textSizeTop.cy + 1; // single line (wp name) + distance from bottombar

    if (numboxrows > 1) {
        boxSizeY += (textSizeBot.cy * (numboxrows - 1)) - NIBLSCALE(2);
        if (numboxrows > 2) boxSizeY -= NIBLSCALE(1);
    }

#if DEBUG_SCR
    StartupStore(_T("boxX=%d boxY=%d  \n"), boxSizeX, boxSizeY);
#endif

#if DEBUG_SCR
    StartupStore(_T("VG AREA LTRB: %d,%d %d,%d\n"), rci.left, rci.top, rci.right, rci.bottom);
#endif

    const auto oldBrush = Surface.SelectObject(LKBrush_White);
    const auto oldPen = Surface.SelectObject(LK_BLACK_PEN);

    BrushReference brush_back;
    if (!INVERTCOLORS) {
        brush_back = LKBrush_Black;
    } else {
        brush_back = LKBrush_Nlight;
    }

    Surface.FillRect(&rci, brush_back);

    POINT center, p1, p2;
    center.y = rci.top + (rci.bottom - rci.top) / 2;
    center.x = rci.left + (rci.right - rci.left) / 2;

    // numSlotX is the number items we can print horizontally.
    unsigned short numSlotX = (rci.right - rci.left) / (boxSizeX + BOXINTERVAL);
    if (numSlotX > MAXBSLOT) numSlotX = MAXBSLOT;
#if BUGSTOP
    LKASSERT(numSlotX > 0);
#endif
    if (numSlotX == 0) return;

    unsigned short boxInterval = ((rci.right - rci.left)-(boxSizeX * numSlotX)) / (numSlotX + 1);
    unsigned short oddoffset = ( (rci.right-rci.left) - (boxSizeX * numSlotX) - boxInterval * (numSlotX + 1)) / 2;

    /*
    #if BUGSTOP
    // not really harmful
    LKASSERT(oddoffset<=boxInterval);
    #endif
     */

#if DEBUG_SCR
    StartupStore(_T("numSlotX=%d ScreenSizeX=%d boxSizeX=%d interval=%d offset=%d\n"), numSlotX, ScreenSizeX, boxSizeX, boxInterval, oddoffset);
#endif

    unsigned int t;

    // The horizontal grid
    unsigned int slotCenterX[MAXBSLOT + 1];
    for (t = 0; t < numSlotX; t++) {
        slotCenterX[t] = (t * boxSizeX) + boxInterval * (t + 1)+(boxSizeX / 2) + oddoffset+rci.left;
#if DEBUG_SCR
        StartupStore(_T("slotCenterX[%d]=%d\n"), t, slotCenterX[t]);
#endif
    }

    // Vertical coordinates of each up/down subwindow, excluding center line
    int upYtop = rci.top;
#if MIDCENTER
    int upYbottom = center.y + (boxSizeY / 2);
    int downYtop = center.y - (boxSizeY / 2);
#else
    int upYbottom = center.y - CENTERYSPACE;
    int downYtop = center.y + CENTERYSPACE;
#endif
    int upSizeY = upYbottom - upYtop - (boxSizeY);
    ;
    int downYbottom = rci.bottom;
    int downSizeY = downYbottom - downYtop - (boxSizeY);
    ;

#if 0
    // Reassign dynamically the vertical scale for each subwindow size
    double vscale = 1000 * (100 - Current_Multimap_SizeY) / 100;
#else
    // Set the vertical range
    double vscale;
    if (Units::GetUserAltitudeUnit() == unFeet)
        vscale = (1000 / TOFEET);
    else
        vscale = 300.0;
#endif



    Surface.SetBackgroundTransparent();

    RECT trc = rci;

    // Top part of visual rect, target is over us=unreachable=red
    trc.top = rci.top;
    trc.bottom = center.y - 1;
    #ifndef DITHER
    RenderSky(Surface, trc, RGB_WHITE, LKColor(150, 255, 150), GC_NO_COLOR_STEPS / 2);
    #else
    RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE, GC_NO_COLOR_STEPS / 2);
    #endif
    // Bottom part, target is below us=reachable=green
    trc.top = center.y + 1;
    trc.bottom = rci.bottom;
    #ifndef DITHER
    RenderSky(Surface, trc, LKColor(255, 150, 150), RGB_WHITE, GC_NO_COLOR_STEPS / 2);
    #else
    RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE,GC_NO_COLOR_STEPS / 2);
    #endif

    // Draw center line
    p1.x = rci.left + 1;
    p1.y = center.y;
    p2.x = rci.right - 1;
    p2.y = center.y;
    Surface.SelectObject(LKPen_Black_N1);
    Surface.DrawSolidLine(p1, p2, rci);

#if DEBUG_SCR
    StartupStore(_T("... Center line: Y=%d\n"), center.y);
#endif

    Surface.SelectObject(line1Font);
    Surface.SelectObject(LKPen_Black_N0);

    ResetVisualGlideGlobals();

    short res = GetVisualGlidePoints(numSlotX);

    if (res == INVALID_VALUE) {
#if DEBUG_DVG
        StartupStore(_T("...... GVGP says not ready, wait..\n"));
#endif
        return;
    }
    if (res == 0) {
#if DEBUG_DVG
        StartupStore(_T("...... GVGP says no data available!\n"));
#endif
        return;
    }

    // Print them all!
    int offset = (boxSizeY / 2) + CENTERYSPACE;

    LKBrush bcolor;
    LKColor rgbcolor, textcolor;
    int wp;

    unsigned short zeroslot = 0;
    double minbrgdiff = 999.0;
    double minabrgdiff = 999.0; // absolute never negative
    for (unsigned short n = 0; n < numSlotX; n++) {
        wp = slotWpIndex[n];
        if (!ValidWayPoint(wp)) {
            // empty slot nothing to print
            continue;
        }
        double brgdiff = WayPointCalc[wp].Bearing - DrawInfo.TrackBearing;
        // this check is worthless
        if (brgdiff < -180.0) {
            brgdiff += 360.0;
        } else {
            if (brgdiff > 180.0) brgdiff -= 360.0;
        }
        double abrgdiff = brgdiff;
        if (abrgdiff < 0) abrgdiff *= -1;

        if (abrgdiff < minabrgdiff) {
            zeroslot = n;
            minabrgdiff = abrgdiff;
            minbrgdiff = brgdiff;
        }
    }

    // Draw vertical line
#define DEGRANGE 10	// degrees left and right to perfect target
    if (minabrgdiff < 1) {
        p1.x = slotCenterX[zeroslot];
    } else {
        // set fullscale range
        if (minabrgdiff > DEGRANGE) {
            minabrgdiff = DEGRANGE;
            if (minbrgdiff < 0)
                minbrgdiff = -1 * DEGRANGE;
            else
                minbrgdiff = DEGRANGE;
        }
        // we shift of course in the opposite direction
        p1.x = slotCenterX[zeroslot]-(int) ((boxSizeX / (DEGRANGE * 2)) * minbrgdiff);
    }
    p2.x = p1.x;

    p1.y = rci.top + 1;
    p2.y = rci.bottom - 1;
    Surface.SelectObject(LKPen_Black_N1);
    Surface.DrawSolidLine(p1, p2, rci);



    for (unsigned short n = 0; n < numSlotX; n++) {

        wp = slotWpIndex[n];
        if (!ValidWayPoint(wp)) {
            // empty slot nothing to print
            continue;
        }
#if DEBUG_DVG
        StartupStore(_T("... DVG PRINT [%d]=%d <%s>\n"), n, wp, WayPointList[wp].Name);
#endif

        Sideview_VGWpt[n] = wp;

        double altdiff = WayPointCalc[wp].AltArriv[AltArrivMode];
        int ty;
#if DEBUG_SCR
        StartupStore(_T("... wp=<%s>\n"), WayPointList[wp].Name);
#endif

        // Since terrain can be approximated due to low precision maps, or waypoint position or altitude error,
        // we have a common problem: we get an obstacle to get to the waypoint because it is
        // positioned "BELOW" the terrain itself. We try to reduce this problem here.
#define SAFETERRAIN	50

        // Positive arrival altitude for the waypoint, upper window
        if (altdiff >= 0) {
            if (altdiff == 0)altdiff = 1;
            double d = vscale / altdiff;
            if (d == 0) d = 1;
            ty = upYbottom - (int) ((double) upSizeY / d)-(boxSizeY / 2);
#if DEBUG_SCR
            StartupStore(_T("... upYbottom=%d upSizeY=%d / (vscale=%f/altdiff=%f = %f) =- %d  ty=%d  offset=%d\n"),
                    upYbottom, upSizeY, vscale, altdiff, d, (int) ((double) upSizeY / d), ty, offset);
#endif
            if ((ty - offset) < upYtop) ty = upYtop + offset;
            if ((ty + offset) > upYbottom) ty = upYbottom - offset;
#if DEBUG_SCR
            StartupStore(_T("... upYtop=%d upYbottom=%d final ty=%d\n"), upYtop, upYbottom, ty);
#endif


            //
            // This is too confusing. We want simple colors, not shaded
            // rgbcolor = MixColors( LKColor(50,255,50), LKColor(230,255,230),  altdiff/(vscale-50));
            //

            if (altdiff <= SAFETERRAIN) {
                rgbcolor = RGB_LIGHTYELLOW;
            } else {
                if (!CheckLandableReachableTerrainNew(&DrawInfo, &DerivedDrawInfo,
                        WayPointCalc[wp].Distance, WayPointCalc[wp].Bearing)) {
                    rgbcolor = RGB_LIGHTRED;
                } else {
#ifdef DITHER
                    rgbcolor = RGB_WHITE;
#else
                    rgbcolor = RGB_LIGHTGREEN;
#endif
                }
            }
            bcolor.Create(rgbcolor);

        } else {
            double d = vscale / altdiff;
            if (d == 0) d = -1;
            ty = downYtop - (int) ((double) downSizeY / d)+(boxSizeY / 2); // - because the left part is negative, we are really adding.
            if ((ty - offset) < downYtop) ty = downYtop + offset;
            if ((ty + offset) > downYbottom) ty = downYbottom - offset;

#ifdef DITHER
            rgbcolor = RGB_WHITE; // negative part, no need to render dark
#else
            rgbcolor = RGB_LIGHTRED;
#endif
            bcolor.Create(rgbcolor);
        }

        TCHAR line2[40], line3[40];
        TCHAR value[40], unit[30];
        TCHAR name[NAME_SIZE + 1];
        double ar = (WayPointCalc[wp].AltArriv[AltArrivMode] * ALTITUDEMODIFY);
        _tcscpy(name, WayPointList[wp].Name);
        CharUpper(name);

        if (IsSafetyAltitudeInUse(wp))
            textcolor = RGB_DARKBLUE;
        else
            textcolor = RGB_BLACK;

        switch (numboxrows) {
            case 0:
#if BUGSTOP
                LKASSERT(0);
#endif
                return;

            case 1:
                // 1 line: waypoint name
                VGTextInBox(Surface, n, 1, name, NULL, NULL, slotCenterX[n], ty, textcolor, bcolor);
                break;

            case 2:
                // 2 lines: waypoint name + altdiff
                LKFormatAltDiff(wp, false, value, unit);
                // Should we print also the GR?
                if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) {
                    if (ar >= -999 && ar <= 999)
                        _stprintf(line2, _T("%s   "), value);
                    else
                        _stprintf(line2, _T("%s  "), value);
                    LKFormatGR(wp, false, value, unit);
                    _tcscat(line2, value);
                } else {
                    _stprintf(line2, _T("%s   ---"), value);
                }

                VGTextInBox(Surface, n, 2, name, line2, NULL, slotCenterX[n], ty, textcolor, bcolor);
                break;

            case 3:
                // 3 lines: waypoint name + dist + altdiff
                LKFormatDist(wp, false, value, unit);
                _stprintf(line2, _T("%s%s"), value, unit);

                LKFormatBrgDiff(wp, false, value, unit);
                _stprintf(tmpT, _T(" %s%s"), value, unit);
                _tcscat(line2, tmpT);

                LKFormatAltDiff(wp, false, value, unit);
                // Should we print also the GR?
                if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) {
                    if (ar >= -999 && ar <= 999)
                        _stprintf(line3, _T("%s   "), value);
                    else
                        _stprintf(line3, _T("%s  "), value);
                    LKFormatGR(wp, false, value, unit);
                    _tcscat(line3, value);
                } else {
                    _stprintf(line3, _T("%s   ---"), value);
                }

                VGTextInBox(Surface, n, 3, name, line2, line3, slotCenterX[n], ty, textcolor, bcolor);
                break;
            default:
#if BUGSTOP
                LKASSERT(0);
#endif
                return;
        }

    } // for numSlotX



    // Cleanup and return
    Surface.SelectObject(oldBrush);
    Surface.SelectObject(oldPen);
    return;
}
예제 #25
0
void MapWindow::VGTextInBox(LKSurface& Surface, unsigned short nslot, short numlines, const TCHAR* wText1, const TCHAR* wText2, const TCHAR *wText3, int x, int y, const LKColor& trgb, const LKBrush& bbrush) {

#if BUGSTOP
    LKASSERT(wText1 != NULL);
#endif
    if (!wText1) return;

    LKColor oldTextColor = Surface.SetTextColor(trgb);

    SIZE tsize;
    int tx, ty;


    Sideview_VGBox_Number++;

    Surface.SelectObject(line1Font);
    Surface.GetTextSize(wText1, &tsize);
    int line1fontYsize = tsize.cy;

    short vy = y + (boxSizeY / 2);
    Surface.SelectObject(bbrush);
    Surface.Rectangle(
            x - (boxSizeX / 2),
            y - (boxSizeY / 2)-1,
            x + (boxSizeX / 2),
            vy-1);

    Sideview_VGBox[nslot].top = y - (boxSizeY / 2);
    Sideview_VGBox[nslot].left = x - (boxSizeX / 2);
    Sideview_VGBox[nslot].bottom = vy;
    Sideview_VGBox[nslot].right = x + (boxSizeX / 2);

    PixelRect ClipRect(Sideview_VGBox[nslot]);
    ClipRect.Grow(-1*NIBLSCALE(2), 0); // text padding

    //
    // LINE 1
    //
    tx = max<PixelScalar>(ClipRect.left, x - (tsize.cx / 2));
    ty = y - (vy - y);

    Surface.DrawText(tx, ty, wText1, &ClipRect);

    if (numlines == 1) goto _end;
#if BUGSTOP
    LKASSERT(wText2 != NULL);
#endif
    if (!wText2) goto _end;

    //
    // LINE 2
    //
    Surface.SetTextColor(RGB_BLACK);
    Surface.SelectObject(line2Font);
    Surface.GetTextSize(wText2, &tsize);
    tx = x - (tsize.cx / 2);
    ty += line1fontYsize - NIBLSCALE(2);
    Surface.DrawText(tx, ty, wText2);

    if (numlines == 2) goto _end;
#if BUGSTOP
    LKASSERT(wText3 != NULL);
#endif
    if (!wText3) goto _end;

    //
    // LINE 3
    //
    Surface.SetTextColor(RGB_BLACK);
    Surface.GetTextSize(wText3, &tsize);
    tx = x - (tsize.cx / 2);
    ty += tsize.cy - NIBLSCALE(2);
    Surface.DrawText(tx, ty, wText3);

_end:
    Surface.SetTextColor(oldTextColor);
    return;
}
예제 #26
0
bool MapWindow::TextInBox(LKSurface& Surface, const RECT *clipRect,  const TCHAR* Value, int x, int y,
                          TextInBoxMode_t *Mode, bool noOverlap) {

  SIZE tsize;
  RECT brect;
  LKSurface::OldFont oldFont {};
  bool drawn=false;

  if ((x<clipRect->left-WPCIRCLESIZE) ||
      (x>clipRect->right+(WPCIRCLESIZE*3)) ||
      (y<clipRect->top-WPCIRCLESIZE) ||
      (y>clipRect->bottom+WPCIRCLESIZE)) {
    return drawn;
  }

  if (Mode == NULL) return false;

  const auto hbOld = Surface.SelectObject(LKBrush_White);
  const auto hpOld = Surface.SelectObject(LK_BLACK_PEN);

  if (Mode->Reachable){
    if (Appearance.IndLandable == wpLandableDefault){
      x += 5;  // make space for the green circle
    }else
      if (Appearance.IndLandable == wpLandableAltA){
	x += 0;
      }
  }

  // landable waypoint label inside white box
  if (!Mode->NoSetFont) {
    if (Mode->Border || Mode->WhiteBold){
      oldFont = Surface.SelectObject(MapWaypointBoldFont);
    } else {
      oldFont = Surface.SelectObject(MapWaypointFont);
    }
  }

  Surface.GetTextSize(Value, &tsize);

  if (Mode->AlligneRight){
    x -= tsize.cx;
  } else
    if (Mode->AlligneCenter){
      x -= tsize.cx/2;
      y -= tsize.cy/2;
    }

  bool notoverlapping = true;

  if (Mode->Border || Mode->WhiteBorder){

    POINT offset;

    brect.left = x-2;
    brect.right = brect.left+tsize.cx+4;
    brect.top = y+((tsize.cy+4)>>3)-2;
    brect.bottom = brect.top+3+tsize.cy-((tsize.cy+4)>>3);

    if (Mode->AlligneRight)
      x -= 3;

    if (TextInBoxMoveInView(clipRect, &offset, &brect)){
      x += offset.x;
      y += offset.y;
    }

    #if CLIP_TEXT
    if (y>=clipRect->bottom || brect.bottom>=clipRect->bottom ) return false;
    #endif

	notoverlapping = checkLabelBlock(&brect);


    if (!noOverlap || notoverlapping) {
      LKSurface::OldPen oldPen;
      if (Mode->Border) {
        oldPen = Surface.SelectObject(LKPen_Black_N1);
      } else {
        oldPen = Surface.SelectObject(LK_WHITE_PEN);
      }
      Surface.RoundRect(brect, NIBLSCALE(4), NIBLSCALE(4));
      Surface.SelectObject(oldPen);
      if (Mode->SetTextColor) Surface.SetTextColor(Mode->Color); else Surface.SetTextColor(RGB_BLACK);
#ifndef __linux__
      Surface.DrawText(x, y, Value);
#else
      Surface.DrawText(x, y+NIBLSCALE(1), Value);
#endif
      drawn=true;
    }


  } else if (Mode->FillBackground) {
예제 #27
0
void MapWindow::LKDrawTrail(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) {
    static RasterPoint snail_polyline[array_size(SnailTrail)];
    
    if (!TrailActive) return;

    const double display_time = DrawInfo.Time;
    const bool use_colors = (MapWindow::zoom.RealScale() < 2); // 1.5 is also quite good;

    //  Trail size
    int num_trail_max = TRAILSIZE;
    if (TrailActive == 2) {
        // scan only recently for lift magnitude (10 min)
        num_trail_max /= TRAILSHRINK;
    }
    if (MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) {
        num_trail_max /= TRAILSHRINK; // ( 2 min for short track ? )
    }    
    
    const SNAIL_POINT* end_iterator = std::next(SnailTrail,iSnailNext);
    const SNAIL_POINT* cur_iterator = end_iterator;
    if(cur_iterator != std::begin(SnailTrail)) {
        cur_iterator = std::prev(cur_iterator);
    } else {
        cur_iterator = std::prev(std::end(SnailTrail));
    }
        
    RasterPoint* polyline_iterator = &snail_polyline[0];

    unsigned short prev_color = 2;
    if(use_colors) {
        prev_color = cur_iterator->Colour;
    }
    Surface.SelectObject(hSnailPens[prev_color]);
    
    const bool trail_is_drifted = (EnableTrailDrift && MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING) && DerivedDrawInfo.WindSpeed >= 1);
    
    double traildrift_lat = 0;
    double traildrift_lon = 0;
    if(trail_is_drifted) {
        double tlat1, tlon1;
        FindLatitudeLongitude(DrawInfo.Latitude, DrawInfo.Longitude,
                DerivedDrawInfo.WindBearing, DerivedDrawInfo.WindSpeed,
                &tlat1, &tlon1);

        traildrift_lat = (DrawInfo.Latitude - tlat1);
        traildrift_lon = (DrawInfo.Longitude - tlon1);
    }
   
    while( (num_trail_max--) > 0 &&  cur_iterator->Time && cur_iterator != end_iterator) {
        
        double this_lat = cur_iterator->Latitude;
        double this_lon = cur_iterator->Longitude;
        if (trail_is_drifted) {
            double dt = std::max(0.0, (display_time - cur_iterator->Time) * cur_iterator->DriftFactor);
            this_lat += traildrift_lat * dt;
            this_lon += traildrift_lon * dt;
        }
        
        (*polyline_iterator) = _Proj.LonLat2Screen(this_lon, this_lat);

        if(use_colors && prev_color != cur_iterator->Colour) {
            // draw polyline before change color.
            Surface.Polyline(snail_polyline, std::distance(snail_polyline, polyline_iterator)+1 , rc);
            // reset polyline
            snail_polyline[0] = *polyline_iterator;
            polyline_iterator = &snail_polyline[1];
            
            // select new Color
            prev_color = cur_iterator->Colour;
            Surface.SelectObject(hSnailPens[prev_color]);
        } else {
            polyline_iterator = std::next(polyline_iterator);
        } 
        
        if(cur_iterator == std::begin(SnailTrail)) {
            cur_iterator = std::end(SnailTrail);
        } 
        cur_iterator = std::prev(cur_iterator);
    }
    Surface.Polyline(snail_polyline, std::distance(snail_polyline, polyline_iterator) , rc);
}
예제 #28
0
void Topology::Paint(LKSurface& Surface, const RECT& rc) {

  if (!shapefileopen) return;
  bool nolabels=false;
  // 130217 scaleCat 5 and 10 are the same! So careful..
  if (scaleCategory==10||scaleCategory==5) {
	// for water areas, use scaleDefault
	if ( MapWindow::zoom.RealScale()>scaleDefaultThreshold) {
		return;
	}
	// since we just checked category 10, if we are over scale we set nolabels
	if ( MapWindow::zoom.RealScale()>scaleThreshold) nolabels=true;
  } else 
  if (MapWindow::zoom.RealScale() > scaleThreshold) return;

  // TODO code: only draw inside screen!
  // this will save time with rendering pixmaps especially
  // checkVisible does only check lat lon , not screen pixels..
  // We need to check also screen.


  const auto hpOld = Surface.SelectObject(hPen);

  LKSurface::OldBrush hbOld {};
  if (hbBrush) {
    hbOld = Surface.SelectObject(hbBrush);
  }

  const auto hfOld = Surface.SelectObject(MapTopologyFont);

  // get drawing info
  int iskip = 1;
 
  // attempt to bugfix 100615 polyline glitch with zoom over 33Km
  // do not skip points, if drawing coast lines which have a scaleThreshold of 100km!
  // != 5 and != 10
  if (scaleCategory>10) { 
  if (MapWindow::zoom.RealScale()>0.25*scaleThreshold) {
    iskip = 2;
  } 
  if (MapWindow::zoom.RealScale()>0.5*scaleThreshold) {
    iskip = 3;
  }
  if (MapWindow::zoom.RealScale()>0.75*scaleThreshold) {
    iskip = 4;
  }
  }

  // use the already existing screenbounds_latlon, calculated by CalculateScreenPositions in MapWindow2
  rectObj screenRect = MapWindow::screenbounds_latlon;

  static POINT pt[MAXCLIPPOLYGON];

  for (int ixshp = 0; ixshp < shpfile.numshapes; ixshp++) {
    
    XShape *cshape = shpCache[ixshp];

    if (!cshape || cshape->hide) continue;    

    shapeObj *shape = &(cshape->shape);

    switch(shape->type) {


      case(MS_SHAPE_POINT):{

	#if 101016
	// -------------------------- NOT PRINTING ICONS ---------------------------------------------
	bool dobitmap=false;
	if (scaleCategory<90 || (MapWindow::zoom.RealScale()<2)) dobitmap=true;
	// first a latlon overlap check, only approximated because of fastcosine in latlon2screen
	if (checkVisible(*shape, screenRect))
		for (int tt = 0; tt < shape->numlines; tt++) {
			for (int jj=0; jj< shape->line[tt].numpoints; jj++) {
				POINT sc;
				MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc);
				if (dobitmap) {
					// bugfix 101212 missing case for scaleCategory 0 (markers)
					if (scaleCategory==0||cshape->renderSpecial(Surface, sc.x, sc.y, rc))
						MapWindow::DrawBitmapIn(Surface, sc, hBitmap,true);
				} else {
					cshape->renderSpecial(Surface, sc.x, sc.y, rc);
				}
			}
		}
	}

	#else
	// -------------------------- PRINTING ICONS ---------------------------------------------
	// no bitmaps for small town over a certain zoom level and no bitmap if no label at all levels
	bool nobitmap=false, noiconwithnolabel=false;
	if (scaleCategory==90 || scaleCategory==100) {
		noiconwithnolabel=true;
		if (MapWindow::MapScale>4) nobitmap=true;
	}

	if (checkVisible(*shape, screenRect))
		for (int tt = 0; tt < shape->numlines; tt++) {
			for (int jj=0; jj< shape->line[tt].numpoints; jj++) {
				POINT sc;
				MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc);
	
				if (!nobitmap)
				#if 101016
				// only paint icon if label is printed too
				if (noiconwithnolabel) {
					if (cshape->renderSpecial(Surface, sc.x, sc.y,labelprinted))
						MapWindow::DrawBitmapIn(Surface, sc, hBitmap,true);
				} else {
					MapWindow::DrawBitmapIn(Surface, sc, hBitmap,true);
					cshape->renderSpecial(Surface, sc.x, sc.y,labelprinted);
				}
				#else
				MapWindow::DrawBitmapIn(Surface, sc, hBitmap,true);
				cshape->renderSpecial(Surface, sc.x, sc.y);
				#endif
			}
		}

	}
	#endif // Use optimized point icons 1.23e
	break;

    case(MS_SHAPE_LINE):

      if (checkVisible(*shape, screenRect))
        for (int tt = 0; tt < shape->numlines; ++tt) {
          
          int minx = rc.right;
          int miny = rc.bottom;
          int msize = min(shape->line[tt].numpoints, MAXCLIPPOLYGON);

          MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize, 1);
          for (int jj=0; jj< msize; ++jj) {
            if (pt[jj].x<=minx) {
              minx = pt[jj].x;
              miny = pt[jj].y;
            }
	      }
          Surface.Polyline(pt, msize, rc);
          cshape->renderSpecial(Surface,minx,miny,rc);
        }
      break;
      
    case(MS_SHAPE_POLYGON):

	// if it's a water area (nolabels), print shape up to defaultShape, but print
	// labels only up to custom label levels
	if ( nolabels ) {
		if (checkVisible(*shape, screenRect)) {
			for (int tt = 0; tt < shape->numlines; ++tt) {
				int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON);
				MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip);
				Surface.Polygon(pt, msize, rc);
			}
		}
	} else 
	if (checkVisible(*shape, screenRect)) {
		for (int tt = 0; tt < shape->numlines; ++tt) {
			int minx = rc.right;
			int miny = rc.bottom;
			int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON);
			MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip);
			for (int jj=0; jj< msize; ++jj) {
				if (pt[jj].x<=minx) {
					minx = pt[jj].x;
					miny = pt[jj].y;
				}
			}
			Surface.Polygon(pt, msize, rc);
			cshape->renderSpecial(Surface,minx,miny,rc);
		}
	}
	break;
      
    default:
      break;
    }
  }
예제 #29
0
void Statistics::DrawYGrid(LKSurface& Surface, const RECT& rc,
			   const double tic_step,
			   const double zero,
                           const int Style,
			   const double unit_step, bool draw_units) {

  POINT line[2];
  SIZE tsize;
  double yval;

  if(INVERTCOLORS || IsDithered())
    Surface.SelectObject(LK_BLACK_PEN);


  int xmin, ymin, xmax, ymax;

  if (!tic_step) return;

  for (yval=zero; yval<= y_max; yval+= tic_step) {

    xmin = rc.left;
    ymin = (int)((y_max-yval)*yscale)+rc.top -BORDER_Y;
    xmax = rc.right;
    ymax = ymin;
    line[0].x = xmin+BORDER_X;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax;

    // STYLE_THINDASHPAPER
    if ((yval< y_max) &&
        (ymin>=rc.top) && (ymin<=rc.bottom-BORDER_Y)) {

      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, yval*unit_step/tic_step, unit_step);
	Surface.GetTextSize(unit_text, &tsize);
	Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin, ymin-tsize.cy/2, unit_text);
    Surface.SetBackgroundTransparent();
      }
    }
  }

  for (yval=zero-tic_step; yval>= y_min; yval-= tic_step) {

    xmin = rc.left;
    ymin = (int)((y_max-yval)*yscale)+rc.top-BORDER_Y;
    xmax = rc.right;
    ymax = ymin;
    line[0].x = xmin+BORDER_X;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax;

    // STYLE_THINDASHPAPER
    if ((yval> y_min) &&
        (ymin>=rc.top) && (ymin<=rc.bottom-BORDER_Y)) {

      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, yval*unit_step/tic_step, unit_step);
	Surface.GetTextSize(unit_text, &tsize);
    Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin, ymin-tsize.cy/2, unit_text);
    Surface.SetBackgroundTransparent();
      }
    }
  }
}
예제 #30
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);

}