Example #1
0
void MapWindow::CalculateScreenPositionsWaypoints() {
  // only calculate screen coordinates for waypoints that are visible
  for (unsigned i = 0; way_points.verify_index(i); ++i) {
    WPCALC &wpcalc = way_points.set_calc(i);
    if (wpcalc.InTask) {
      LonLat2Screen(way_points.get(i).Location, wpcalc.Screen);
    } else {
      wpcalc.Visible = wpcalc.FarVisible &&
        LonLat2ScreenIfVisible(way_points.get(i).Location, &wpcalc.Screen);
    }
  }
}
Example #2
0
/**
 * Draws the FLARM traffic icons onto the given canvas
 * @param canvas Canvas for drawing
 */
void
MapWindow::DrawFLARMTraffic(Canvas &canvas)
{
  // Return if FLARM icons on moving map are disabled
  if (!SettingsMap().EnableFLARMMap) return;

  // Return if FLARM data is not available
  if (!Basic().FLARM_Available) return;

  // Create pen for icon outlines
  Pen thinBlackPen(IBLSCALE(1), Color(0, 0, 0));
  canvas.select(thinBlackPen);

  // Create point array that will form that arrow polygon
  POINT Arrow[5];

  // double dX, dY;
  TextInBoxMode_t displaymode;
  displaymode.AsInt = 0;

  // Determine scale factor for use in Scaled mode
  double screenrange = GetScreenDistanceMeters();
  double scalefact = screenrange/6000.0;

  // Create the brushes for filling the arrow (red/yellow/green)
  Brush redBrush(Color(0xFF,0x00,0x00));
  Brush yellowBrush(Color(0xFF,0xFF,0x00));
  Brush greenBrush(Color(0x00,0xFF,0x00));

  // Saves the MacCready value
  const double MACCREADY = GlidePolar::GetMacCready();

  // Circle through the FLARM targets
  for (int i = 0; i < FLARM_MAX_TRAFFIC; i++) {
    // if FLARM target i exists
    if (Basic().FLARM_Traffic[i].ID!=0) {
      // Save the location of the FLARM target
      GEOPOINT target_loc;
      target_loc = Basic().FLARM_Traffic[i].Location;

      // If Scaled mode is chosen, recalculate the
      // targets virtual position using the scale factor
      if ((SettingsMap().EnableFLARMMap == 2) && (scalefact > 1.0)) {
        double distance;
        double bearing;

        DistanceBearing(Basic().Location, target_loc, &distance, &bearing);

        FindLatitudeLongitude(Basic().Location, bearing, distance * scalefact,
            &target_loc);
      }

      // TODO feature: draw direction, rel height?

      // Points for the screen coordinates for the icon, name and average climb
      POINT sc, sc_name, sc_av;

      // If FLARM target not on the screen, move to the next one
      if (!LonLat2ScreenIfVisible(target_loc, &sc)) {
        continue;
      }

      // Draw the name 16 points below the icon
      sc_name = sc;
      sc_name.y -= IBLSCALE(16);

      // Draw the average climb value above the icon
      sc_av = sc;
      sc_av.y += IBLSCALE(16);

#ifndef FLARM_AVERAGE
      if (Basic().FLARM_Traffic[i].Name) {
        TextInBox(hDC, Basic().FLARM_Traffic[i].Name, sc.x+IBLSCALE(3),
                  sc.y, 0, displaymode,
                  true);
      }
#else
      TCHAR label_name[100];
      TCHAR label_avg[100];

      sc_av.x += IBLSCALE(3);

      if (Basic().FLARM_Traffic[i].Name) {
        sc_name.y -= IBLSCALE(8);
        _stprintf(label_name, TEXT("%s"), Basic().FLARM_Traffic[i].Name);
      } else {
        label_name[0]= _T('\0');
      }

      if (Basic().FLARM_Traffic[i].Average30s >= 0.1) {
        _stprintf(label_avg, TEXT("%.1f"),
            LIFTMODIFY * Basic().FLARM_Traffic[i].Average30s);
      } else {
        label_avg[0]= _T('\0');
      }

#ifndef NDEBUG
      // for testing only!
      _stprintf(label_avg, TEXT("2.3"));
      _stprintf(label_name, TEXT("WUE"));
#endif

      // JMW TODO enhancement: decluttering of FLARM altitudes (sort by max lift)

      int dx = (sc_av.x-Orig_Aircraft.x);
      int dy = (sc_av.y-Orig_Aircraft.y);

      // only draw labels if not close to aircraft
      if (dx*dx+dy*dy > IBLSCALE(30)*IBLSCALE(30)) {
        // Select the MapLabelFont and black color
        canvas.select(MapLabelFont);
        canvas.set_text_color(Color(0,0,0));

        // If FLARM callsign/name available draw it to the canvas
        if (_tcslen(label_name) > 0) {
          canvas.text_opaque(sc_name.x, sc_name.y, label_name);
        }

        // If average climb data available draw it to the canvas
        if (_tcslen(label_avg)>0) {
          SIZE tsize;
          RECT brect;

          // Calculate the size of the average climb indicator
          tsize = canvas.text_size(label_avg);
          brect.left = sc_av.x-2;
          brect.right = brect.left+tsize.cx+6;
          brect.top = sc_av.y+((tsize.cy+4)>>3)-2;
          brect.bottom = brect.top+3+tsize.cy-((tsize.cy+4)>>3);

          // Determine the background color for the average climb indicator
          float vmax = (float)(1.5*min(5.0, max(MACCREADY,0.5)));
          float vmin = (float)(-1.5*min(5.0, max(MACCREADY,2.0)));

          float cv = Basic().FLARM_Traffic[i].Average30s;
          if (cv < 0) {
            cv /= (-vmin); // JMW fixed bug here
          } else {
            cv /= vmax;
          }

          int colourIndex = fSnailColour(cv);
          // Select the appropriate background color determined before
          canvas.select(MapGfx.hSnailPens[colourIndex]);
          Brush hVarioBrush(MapGfx.hSnailColours[colourIndex]);
          canvas.select(hVarioBrush);

          // Draw the rounded background rectangle
          canvas.round_rectangle(brect.left, brect.top,
              brect.right, brect.bottom,
              IBLSCALE(8), IBLSCALE(8));

#ifdef WINDOWSPC
          canvas.background_transparent();
          canvas.text(sc_av.x, sc_av.y, label_avg);
#else
          // Draw the average climb value on top
          canvas.text_opaque(sc_av.x, sc_av.y, label_avg);
#endif
        }
      }