コード例 #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
//
// 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);
			}
		}
	}
  }
}
コード例 #3
0
ファイル: DrawTeamMate.cpp プロジェクト: PhilColbert/LK8000
void MapWindow::DrawTeammate(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) {
    if (TeammateCodeValid) {
        if (PointVisible(TeammateLongitude, TeammateLatitude)) {
            const POINT point = _Proj.LonLat2Screen(TeammateLongitude, TeammateLatitude);
            hBmpTeammatePosition.Draw(Surface, point.x - NIBLSCALE(10), point.y - NIBLSCALE(10), IBLSCALE(20), IBLSCALE(20));
        }
    }
}
コード例 #4
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);
    }
}
コード例 #5
0
ファイル: LKDrawLongTrail.cpp プロジェクト: brunotl/LK8000
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);
}
コード例 #6
0
ファイル: MapWindow_Events.cpp プロジェクト: jaaaaf/LK8000
void MapWindow::Event_PanCursor(int dx, int dy) {
  const ScreenProjection _Proj;
  RasterPoint pt = {
    (MapRect.right+MapRect.left)/2,
    (MapRect.bottom+MapRect.top)/2
  };
  double Xstart, Ystart, Xnew, Ynew;

  _Proj.Screen2LonLat(pt, Xstart, Ystart);

  pt.x += (MapRect.right-MapRect.left)*dx/4;
  pt.y += (MapRect.bottom-MapRect.top)*dy/4;
  _Proj.Screen2LonLat(pt, Xnew, Ynew);

  if(mode.AnyPan()) {
    PanLongitude += Xstart-Xnew;
    PanLatitude += Ystart-Ynew;
  }
  RefreshMap();
}
コード例 #7
0
void GLShapeRenderer::renderPolygon(LKSurface& Surface, const XShape& shape, Brush& brush, const ScreenProjection& _Proj) {
  /*
   OpenGL cannot draw complex polygons so we need to use a Tessallator to draw the polygon using a GL_TRIANGLE_FAN
   */  
#ifdef USE_GLSL
  OpenGL::solid_shader->Use();
#endif
  
  brush.Bind();
    
  std::unique_ptr<const GLBlend> blend; 
  if(!brush.IsOpaque()) {
    blend = std::make_unique<const GLBlend>(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }
  
  curr_LabelPos = clipRect.GetBottomRight();
  
  const shapeObj& shp = shape.shape;

  gluTessBeginPolygon(tess, this );
  for (int j = 0; j < shp.numlines; j++) {
    gluTessBeginContour(tess);
    for (int i = 0; i < shp.line[j].numpoints; i++) {
      const RasterPoint pt = _Proj.LonLat2Screen(shp.line[j].point[i]);
      if (!noLabel &&  (pt.x<=curr_LabelPos.x)) {
        curr_LabelPos = pt;
      }  
      vertex_t& vertex = *(pointers.insert(pointers.end(), vertex_t({{(GLdouble)pt.x, (GLdouble)pt.y, 0.}})));
      gluTessVertex(tess, vertex.data(), vertex.data());
    }
    gluTessEndContour(tess);
  }
  gluTessEndPolygon(tess);
  
  if(shape.HasLabel() && clipRect.IsInside(curr_LabelPos)) {
    shape.renderSpecial(Surface, curr_LabelPos.x, curr_LabelPos.y, clipRect);
  }
  
  pointers.clear();
}
コード例 #8
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);
}
コード例 #9
0
ファイル: LKDrawFLARMTraffic.cpp プロジェクト: jaaaaf/LK8000
// 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);

}