void MapWindow::CalculateScreenPositionsThermalSources() {
    for (int i=0; i<MAX_THERMAL_SOURCES; i++) {
        if (DerivedDrawInfo.ThermalSources[i].LiftRate>0) {
            double dh = DerivedDrawInfo.NavAltitude
                        -DerivedDrawInfo.ThermalSources[i].GroundHeight;
            if (dh<0) {
                DerivedDrawInfo.ThermalSources[i].Visible = false;
                continue;
            }

            double t = dh/DerivedDrawInfo.ThermalSources[i].LiftRate;
            double lat, lon;
            FindLatitudeLongitude(DerivedDrawInfo.ThermalSources[i].Latitude,
                                  DerivedDrawInfo.ThermalSources[i].Longitude,
                                  DerivedDrawInfo.WindBearing,
                                  -DerivedDrawInfo.WindSpeed*t,
                                  &lat, &lon);
            if (PointVisible(lon,lat)) {
                LatLon2Screen(lon,
                              lat,
                              DerivedDrawInfo.ThermalSources[i].Screen);
                DerivedDrawInfo.ThermalSources[i].Visible =
                    PointVisible(DerivedDrawInfo.ThermalSources[i].Screen);
            } else {
                DerivedDrawInfo.ThermalSources[i].Visible = false;
            }
        } else {
            DerivedDrawInfo.ThermalSources[i].Visible = false;
        }
    }
}
Beispiel #2
0
void MapWindow::DrawTeammate(HDC hdc, RECT rc)
{
  POINT point;

  if (TeammateCodeValid)
    {
      if(PointVisible(TeammateLongitude, TeammateLatitude) )
	{
	  LatLon2Screen(TeammateLongitude, TeammateLatitude, point);

	  SelectObject(hDCTemp,hBmpTeammatePosition);
	  DrawBitmapX(hdc,
		      point.x-NIBLSCALE(10), 
		      point.y-NIBLSCALE(10),
		      20,20,
		      hDCTemp,0,0,SRCPAINT,true);
	
	  DrawBitmapX(hdc,
		      point.x-NIBLSCALE(10), 
		      point.y-NIBLSCALE(10),
		      20,20,
		      hDCTemp,20,0,SRCAND,true);
	}
    }
}
Beispiel #3
0
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));
        }
    }
}
Beispiel #4
0
void MapWindow::DrawBitmapIn(LKSurface& Surface, const POINT &sc, const LKIcon& Icon, const bool autostretch) {
    if (!Icon) return; // don't draw Bitmap if no bitmap
    if (!PointVisible(sc)) return;

    assert(Icon.GetSize().cx == 10);
    assert(Icon.GetSize().cy == 10);
    
    if (autostretch) {
        Icon.Draw(Surface, sc.x - NIBLSCALE(5), sc.y - NIBLSCALE(5), IBLSCALE(10), IBLSCALE(10));
    } else {
        Icon.Draw(Surface, sc.x - NIBLSCALE(5), sc.y - NIBLSCALE(5), 10, 10);
    }
}
Beispiel #5
0
void MapWindow::DrawBitmapIn(const HDC hdc, const POINT &sc, const HBITMAP h, const bool autostretch) {
  if (!PointVisible(sc)) return;

  SelectObject(hDCTemp, h);

  DrawBitmapX(hdc,
              sc.x-NIBLSCALE(5),
              sc.y-NIBLSCALE(5),
              10,10,
	      hDCTemp,0,0,SRCPAINT, autostretch);
  DrawBitmapX(hdc,
              sc.x-NIBLSCALE(5),
              sc.y-NIBLSCALE(5),
              10,10,
              hDCTemp,10,0,SRCAND, autostretch);
}
Beispiel #6
0
void MapWindow::DrawAirspaceLabels(HDC hdc, const RECT rc, const POINT Orig_Aircraft)
{
  static short int label_sequencing_divider = 0;
  CAirspaceList::const_iterator it;
  const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetAirspacesForWarningLabels();
  
  if (label_sequencing_divider) --label_sequencing_divider;

  // Draw warning position and label on top of all airspaces
  if (1) {
  CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef());
  for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) {
        if ((*it)->WarningLevel() > awNone) {
          POINT sc;
          double lon;
          double lat;
          int vdist;
          AirspaceWarningDrawStyle_t vlabeldrawstyle, hlabeldrawstyle;
          bool distances_ready = (*it)->GetWarningPoint(lon, lat, hlabeldrawstyle, vdist, vlabeldrawstyle);
          TCHAR hbuf[NAME_SIZE+16], vDistanceText[16];
          TextInBoxMode_t TextDisplayMode = {0};
          bool hlabel_draws = false;
          bool vlabel_draws = false;
          
          // Horizontal warning point
          if (distances_ready && (hlabeldrawstyle > awsHidden) && PointVisible(lon, lat)) {

              LatLon2Screen(lon, lat, sc);
              DrawBitmapIn(hdc, sc, hAirspaceWarning,true);
              
              Units::FormatUserAltitude(vdist, vDistanceText, sizeof(vDistanceText)/sizeof(vDistanceText[0]));
              _tcscpy(hbuf, (*it)->Name());
              wcscat(hbuf, TEXT(" "));
              wcscat(hbuf, vDistanceText);
              
              switch (hlabeldrawstyle) {
                default:
                case awsHidden:
                case awsBlack:
                  TextDisplayMode.Color = RGB_BLACK;
                  break;
                case awsAmber:
                  TextDisplayMode.Color = RGB_ORANGE;
                  break;
                case awsRed:
                  TextDisplayMode.Color = RGB_RED;
                  break;
              } // sw
              TextDisplayMode.SetTextColor = 1;
              TextDisplayMode.AlligneCenter = 1;
              if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) {
                  TextDisplayMode.Border = 1;
              } else {
		  if (TextDisplayMode.Color==RGB_BLACK)
                     TextDisplayMode.WhiteBold = 0; // no black outline for black background..
                  else
                     TextDisplayMode.WhiteBold = 1; // outlined  
              }

              hlabel_draws = TextInBox(hdc, &rc, hbuf, sc.x, sc.y+NIBLSCALE(15), 0, &TextDisplayMode, true);
           }
           
          // Vertical warning point
          if (distances_ready && vlabeldrawstyle > awsHidden) {

              //DrawBitmapIn(hdc, Orig_Aircraft, hAirspaceWarning);
              
              Units::FormatUserAltitude(vdist, vDistanceText, sizeof(vDistanceText)/sizeof(vDistanceText[0]));
              _tcscpy(hbuf, (*it)->Name());
              wcscat(hbuf, TEXT(" "));
              wcscat(hbuf, vDistanceText);
              
              switch (vlabeldrawstyle) {
                default:
                case awsHidden:
                case awsBlack:
                  TextDisplayMode.Color = RGB_BLACK;
                  break;
                case awsAmber:
                  TextDisplayMode.Color = RGB_ORANGE;
                  break;
                case awsRed:
                  TextDisplayMode.Color = RGB_RED;
                  break;
              } // sw
              TextDisplayMode.SetTextColor = 1;
              TextDisplayMode.AlligneCenter = 1;
              if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) {
                  TextDisplayMode.Border = 1;
              } else {
		  if (TextDisplayMode.Color==RGB_BLACK)
                     TextDisplayMode.WhiteBold = 0; // no black outline for black background..
                  else
                     TextDisplayMode.WhiteBold = 1; // outlined  
              }

              vlabel_draws = TextInBox(hdc, &rc, hbuf, Orig_Aircraft.x, Orig_Aircraft.y+NIBLSCALE(15), 0, &TextDisplayMode, true);
           }
           if (!label_sequencing_divider) CAirspaceManager::Instance().AirspaceWarningLabelPrinted(**it, hlabel_draws || vlabel_draws);
           
         }// if warnlevel>awnone
  }//for
  }// if(1) mutex
  if (!label_sequencing_divider) label_sequencing_divider=3;		// Do label sequencing slower than update rate
}
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);
}
void MapWindow::CalculateScreenPositions(POINT Orig, RECT rc,
        POINT *Orig_Aircraft)
{

    unsigned int i;

    Orig_Screen = Orig;

    if (!mode.AnyPan()) {

        if (GliderCenter
                && DerivedDrawInfo.Circling
                && (EnableThermalLocator==2)) {

            if (DerivedDrawInfo.ThermalEstimate_R>0) {
                PanLongitude = DerivedDrawInfo.ThermalEstimate_Longitude;
                PanLatitude = DerivedDrawInfo.ThermalEstimate_Latitude;
                // TODO enhancement: only pan if distance of center to
                // aircraft is smaller than one third screen width

                POINT screen;
                LatLon2Screen(PanLongitude,
                              PanLatitude,
                              screen);

                LatLon2Screen(DrawInfo.Longitude,
                              DrawInfo.Latitude,
                              *Orig_Aircraft);
                if ((fabs((double)Orig_Aircraft->x-screen.x)<(rc.right-rc.left)/3)
                        && (fabs((double)Orig_Aircraft->y-screen.y)<(rc.bottom-rc.top)/3)) {

                } else {
                    // out of bounds, center on aircraft
                    PanLongitude = DrawInfo.Longitude;
                    PanLatitude = DrawInfo.Latitude;
                }
            } else {
                PanLongitude = DrawInfo.Longitude;
                PanLatitude = DrawInfo.Latitude;
            }
        } else {
            // Pan is off
            PanLongitude = DrawInfo.Longitude;
            PanLatitude = DrawInfo.Latitude;
        }
    }

    LatLon2Screen(DrawInfo.Longitude,
                  DrawInfo.Latitude,
                  *Orig_Aircraft);

    // very important
    screenbounds_latlon = CalculateScreenBounds(0.0, rc);

    // Old note obsoleted 121111:
    // preserve this calculation for 0.0 until next round!
    // This is already done since screenbounds_latlon is global. Beware that DrawTrail will change it later on
    // to expand boundaries by 1 minute

    // get screen coordinates for all task waypoints

    LockTaskData();

    if (!WayPointList.empty()) {
        for (i=0; i<MAXTASKPOINTS; i++) {
            unsigned index = Task[i].Index;
            if (index < WayPointList.size()) {

                LatLon2Screen(WayPointList[index].Longitude,
                              WayPointList[index].Latitude,
                              WayPointList[index].Screen);
                WayPointList[index].Visible =
                    PointVisible(WayPointList[index].Screen);
            } else {
                // No need to continue.
                break;
            }
        }
        if (EnableMultipleStartPoints) {
            for(i=0; i<MAXSTARTPOINTS-1; i++) {
                unsigned index = StartPoints[i].Index;
                if (StartPoints[i].Active && (index < WayPointList.size())) {

                    LatLon2Screen(WayPointList[index].Longitude,
                                  WayPointList[index].Latitude,
                                  WayPointList[index].Screen);
                    WayPointList[index].Visible =
                        PointVisible(WayPointList[index].Screen);
                } else {
                    // No Need to continue.
                    break;
                }
            }
        }

        // only calculate screen coordinates for waypoints that are visible

        // TODO 110203 OPTIMIZE THIS !
        for(i=0; i<WayPointList.size(); i++)
        {
            WayPointList[i].Visible = false;
            if (!WayPointList[i].FarVisible) continue;
            if(PointVisible(WayPointList[i].Longitude, WayPointList[i].Latitude) )
            {
                LatLon2Screen(WayPointList[i].Longitude, WayPointList[i].Latitude,
                              WayPointList[i].Screen);
                WayPointList[i].Visible = PointVisible(WayPointList[i].Screen);
            }
        }
    }

    if(TrailActive)
    {
        iSnailNext = SnailNext;
        iLongSnailNext = LongSnailNext;
        // set this so that new data doesn't arrive between calculating
        // this and the screen updates
    }

    if (EnableMultipleStartPoints) {
        for(i=0; i<MAXSTARTPOINTS-1; i++) {
            if (StartPoints[i].Active && ValidWayPointFast(StartPoints[i].Index)) {
                LatLon2Screen(StartPoints[i].SectorEndLon,
                              StartPoints[i].SectorEndLat, StartPoints[i].End);
                LatLon2Screen(StartPoints[i].SectorStartLon,
                              StartPoints[i].SectorStartLat, StartPoints[i].Start);
            }
        }
    }

    for(i=0; i<MAXTASKPOINTS-1; i++)
    {
        bool this_valid = ValidTaskPointFast(i);
        bool next_valid = ValidTaskPointFast(i+1);
        if (AATEnabled && this_valid) {
            LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat,
                          Task[i].Target);
        }

        if(this_valid && !next_valid)
        {
            // finish
            LatLon2Screen(Task[i].SectorEndLon, Task[i].SectorEndLat, Task[i].End);
            LatLon2Screen(Task[i].SectorStartLon, Task[i].SectorStartLat, Task[i].Start);

            // No need to continue.
            break;
        }
        if(this_valid && next_valid)
        {
            LatLon2Screen(Task[i].SectorEndLon, Task[i].SectorEndLat, Task[i].End);
            LatLon2Screen(Task[i].SectorStartLon, Task[i].SectorStartLat, Task[i].Start);

            if((AATEnabled) && (Task[i].AATType == SECTOR))
            {
                LatLon2Screen(Task[i].AATStartLon, Task[i].AATStartLat, Task[i].AATStart);
                LatLon2Screen(Task[i].AATFinishLon, Task[i].AATFinishLat, Task[i].AATFinish);
            }
            if (AATEnabled && (((int)i==ActiveWayPoint) ||
                               (mode.Is(Mode::MODE_TARGET_PAN) && ((int)i==TargetPanIndex)))) {

                for (int j=0; j<MAXISOLINES; j++) {
                    if (TaskStats[i].IsoLine_valid[j]) {
                        LatLon2Screen(TaskStats[i].IsoLine_Longitude[j],
                                      TaskStats[i].IsoLine_Latitude[j],
                                      TaskStats[i].IsoLine_Screen[j]);
                    }
                }
            }
        }
    }

    UnlockTaskData();

}
Beispiel #9
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) ) {


		double target_lon;
		double target_lat;

		target_lon = DrawInfo.FLARM_Traffic[i].Longitude;
		target_lat = DrawInfo.FLARM_Traffic[i].Latitude;

                if (!PointVisible(target_lon, target_lat)) {
                   // StartupStore(_T("... This traffic is not visible on map with current zoom%s"),NEWLINE);
                   continue;
                }

		painted++;

		#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.ToRasterPoint(target_lat, target_lon);

		sc_name = sc;

		sc_name.y -= NIBLSCALE(16);
		sc_av = sc_name;

		_tcscpy(lbuffer,_T(""));
		if (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);
		}
#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);

}