Esempio n. 1
0
  void
  FormatLabel(TCHAR *buffer, const Waypoint &way_point,
              const ReachResult &reach)
  {
    FormatTitle(buffer, way_point);

    if (!way_point.IsLandable() && !way_point.flags.watched)
      return;

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::REQUIRED_GR) {
      if (!basic.location_available || !basic.NavAltitudeAvailable())
        return;

      const fixed safety_height = task_behaviour.safety_height_arrival;
      const fixed target_altitude = way_point.elevation + safety_height;
      const fixed delta_h = basic.nav_altitude - target_altitude;
      if (!positive(delta_h))
        /* no L/D if below waypoint */
        return;

      const fixed distance = basic.location.Distance(way_point.location);
      const fixed gr = distance / delta_h;
      if (!GradientValid(gr))
        return;

      size_t length = _tcslen(buffer);
      if (length > 0)
        buffer[length++] = _T(':');
      _stprintf(buffer + length, _T("%.1f"), (double) gr);
      return;
    }

    if (!reach.IsReachableDirect() && !way_point.flags.watched)
      return;

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::NONE)
      return;

    size_t length = _tcslen(buffer);
    int uah_glide = (int)Units::ToUserAltitude(fixed(reach.direct));
    int uah_terrain = (int)Units::ToUserAltitude(fixed(reach.terrain));

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::TERRAIN) {
      if (reach.IsReachableTerrain()) {
        if (length > 0)
          buffer[length++] = _T(':');
        _stprintf(buffer + length, _T("%d%s"), uah_terrain, sAltUnit);
      }
      return;
    }

    if (length > 0)
      buffer[length++] = _T(':');

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::GLIDE_AND_TERRAIN &&
        reach.IsReachableDirect() && reach.IsReachableTerrain() &&
        reach.IsDeltaConsiderable()) {
      _stprintf(buffer + length, _T("%d/%d%s"), uah_glide,
                uah_terrain, sAltUnit);
      return;
    }

    _stprintf(buffer + length, _T("%d%s"), uah_glide, sAltUnit);
  }
Esempio n. 2
0
  void FormatLabel(TCHAR *buffer, size_t buffer_size,
                   const Waypoint &way_point,
                   WaypointRenderer::Reachability reachable,
                   const ReachResult &reach) const {
    FormatTitle(buffer, buffer_size - 20, way_point);

    if (!way_point.IsLandable() && !way_point.flags.watched)
      return;

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::REQUIRED_GR) {
      if (!basic.location_available || !basic.NavAltitudeAvailable())
        return;

      const auto safety_height = task_behaviour.safety_height_arrival;
      const auto target_altitude = way_point.elevation + safety_height;
      const auto delta_h = basic.nav_altitude - target_altitude;
      if (delta_h <= 0)
        /* no L/D if below waypoint */
        return;

      const auto distance = basic.location.DistanceS(way_point.location);
      const auto gr = distance / delta_h;
      if (!GradientValid(gr))
        return;

      size_t length = _tcslen(buffer);
      if (length > 0)
        buffer[length++] = _T(':');
      StringFormatUnsafe(buffer + length, _T("%.1f"), (double) gr);
      return;
    }

    if (reachable == WaypointRenderer::Invalid)
      return;

    if (!reach.IsReachableDirect() && !way_point.flags.watched)
      return;

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::NONE)
      return;

    size_t length = _tcslen(buffer);
    int uah_glide = (int)Units::ToUserAltitude(reach.direct);
    int uah_terrain = (int)Units::ToUserAltitude(reach.terrain);

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::TERRAIN) {
      if (reach.IsReachableTerrain()) {
        if (length > 0)
          buffer[length++] = _T(':');
        StringFormatUnsafe(buffer + length, _T("%d%s"),
                           uah_terrain, altitude_unit);
      }
      return;
    }

    if (length > 0)
      buffer[length++] = _T(':');

    if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::GLIDE_AND_TERRAIN &&
        reach.IsReachableDirect() && reach.IsReachableTerrain() &&
        reach.IsDeltaConsiderable()) {
      StringFormatUnsafe(buffer + length, _T("%d/%d%s"), uah_glide,
                         uah_terrain, altitude_unit);
      return;
    }

    StringFormatUnsafe(buffer + length, _T("%d%s"), uah_glide, altitude_unit);
  }
Esempio n. 3
0
void
WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  const MoreData &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const ComputerSettings &settings = CommonInterface::GetComputerSettings();

  StaticString<64> buffer;

  if (!waypoint.comment.empty())
    AddMultiLine(waypoint.comment.c_str());

  if (waypoint.radio_frequency.IsDefined() &&
      waypoint.radio_frequency.Format(buffer.buffer(),
                                      buffer.MAX_SIZE) != nullptr) {
    buffer += _T(" MHz");
    AddReadOnly(_("Radio frequency"), nullptr, buffer);
  }

  if (waypoint.runway.IsDirectionDefined())
    buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName());
  else
    buffer.clear();

  if (waypoint.runway.IsLengthDefined()) {
    if (!buffer.empty())
      buffer += _T("; ");

    TCHAR length_buffer[16];
    FormatSmallUserDistance(length_buffer,
                                   fixed(waypoint.runway.GetLength()));
    buffer += length_buffer;
  }

  if (!buffer.empty())
    AddReadOnly(_("Runway"), nullptr, buffer);

  if (FormatGeoPoint(waypoint.location,
                     buffer.buffer(), buffer.MAX_SIZE) != nullptr)
    AddReadOnly(_("Location"), nullptr, buffer);

  FormatUserAltitude(waypoint.elevation,
                            buffer.buffer(), buffer.MAX_SIZE);
  AddReadOnly(_("Elevation"), nullptr, buffer);

  if (basic.time_available && basic.date_time_utc.IsDatePlausible()) {
    const SunEphemeris::Result sun =
      SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc,
                                 settings.utc_offset);

    const BrokenTime sunrise = BreakHourOfDay(sun.time_of_sunrise);
    const BrokenTime sunset = BreakHourOfDay(sun.time_of_sunset);

    buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"),
                        sunrise.hour, sunrise.minute,
                        sunset.hour, sunset.minute);
    AddReadOnly(_("Daylight time"), nullptr, buffer);
  }

  if (basic.location_available) {
    const GeoVector vector = basic.location.DistanceBearing(waypoint.location);

    TCHAR distance_buffer[32];
    FormatUserDistanceSmart(vector.distance, distance_buffer,
                                   ARRAY_SIZE(distance_buffer));

    FormatBearing(buffer.buffer(), buffer.MAX_SIZE,
                  vector.bearing, distance_buffer);
    AddReadOnly(_("Bearing and Distance"), nullptr, buffer);
  }

  if (basic.location_available && basic.NavAltitudeAvailable() &&
      settings.polar.glide_polar_task.IsValid()) {
    const GlideState glide_state(basic.location.DistanceBearing(waypoint.location),
                                 waypoint.elevation + settings.task.safety_height_arrival,
                                 basic.nav_altitude,
                                 calculated.GetWindOrZero());

    GlidePolar gp0 = settings.polar.glide_polar_task;
    gp0.SetMC(fixed(0));
    AddGlideResult(_("Alt. diff. MC 0"),
                   MacCready::Solve(settings.task.glide,
                                    gp0, glide_state));

    AddGlideResult(_("Alt. diff. MC safety"),
                   MacCready::Solve(settings.task.glide,
                                    calculated.glide_polar_safety,
                                    glide_state));

    AddGlideResult(_("Alt. diff. MC current"),
                   MacCready::Solve(settings.task.glide,
                                    settings.polar.glide_polar_task,
                                    glide_state));
  }

  if (basic.location_available && basic.NavAltitudeAvailable()) {
    const TaskBehaviour &task_behaviour =
      CommonInterface::GetComputerSettings().task;

    const fixed safety_height = task_behaviour.safety_height_arrival;
    const fixed target_altitude = waypoint.elevation + safety_height;
    const fixed delta_h = basic.nav_altitude - target_altitude;
    if (positive(delta_h)) {
      const fixed distance = basic.location.Distance(waypoint.location);
      const fixed gr = distance / delta_h;
      if (GradientValid(gr)) {
        buffer.UnsafeFormat(_T("%.1f"), (double)gr);
        AddReadOnly(_("Required glide ratio"), nullptr, buffer);
      }
    }
  }
}