示例#1
0
  /**
   * Check whether this intersection should be added to, or updated in, the warning manager
   *
   * @param airspace Airspace corresponding to current intersection
   */
  void Intersection(const AbstractAirspace& airspace) {
    if (!airspace.IsActive())
      return; // ignore inactive airspaces completely

    if (!warning_manager.GetConfig().IsClassEnabled(airspace.GetType()) ||
        ExcludeAltitude(airspace))
      return;

    AirspaceWarning *warning = warning_manager.GetWarningPtr(airspace);
    if (warning == NULL || warning->IsStateAccepted(warning_state)) {

      AirspaceInterceptSolution solution;

      if (mode_inside) {
        airspace.Intercept(state, perf, solution, state.location, state.location);
      } else {
        solution = Intercept(airspace, state, perf);
      }
      if (!solution.IsValid())
        return;
      if (solution.elapsed_time > max_time)
        return;

      if (warning == NULL)
        warning = warning_manager.GetNewWarningPtr(airspace);

      warning->UpdateSolution(warning_state, solution);
      found = true;
    }
  }
示例#2
0
  virtual void Visit(const AirspaceWarning& as) {
    if (as.get_warning_state() == m_state) {
#ifdef DO_PRINT
    *fout << as;
    *fout << as.get_airspace();
#endif
    }
  }
示例#3
0
bool 
AirspaceWarning::operator<(const AirspaceWarning &other) const
{
  // compare bother.ack
  if (get_ack_expired() != other.get_ack_expired())
    // least expired top
    return get_ack_expired() > other.get_ack_expired();

  // compare bother.state
  if (get_warning_state() != other.get_warning_state())
    // most severe top
    return get_warning_state() > other.get_warning_state();

  // state and ack equal, compare bother.time to intersect
  return get_solution().elapsed_time < other.get_solution().elapsed_time;
}
示例#4
0
bool
AirspaceWarning::operator<(const AirspaceWarning &other) const
{
  // compare bother.ack
  if (IsAckExpired() != other.IsAckExpired())
    // least expired top
    return IsAckExpired() > other.IsAckExpired();

  // compare bother.state
  if (GetWarningState() != other.GetWarningState())
    // most severe top
    return GetWarningState() > other.GetWarningState();

  // state and ack equal, compare bother.time to intersect
  return GetSolution().elapsed_time < other.GetSolution().elapsed_time;
}
示例#5
0
static void
Enable()
{
  const AbstractAirspace *airspace = GetSelectedAirspace();
  if (airspace == NULL)
    return;

  {
    ProtectedAirspaceWarningManager::ExclusiveLease lease(*airspace_warnings);
    AirspaceWarning *warning = lease->GetWarningPtr(*airspace);
    if (warning == NULL)
      return;

    warning->AcknowledgeInside(false);
    warning->AcknowledgeWarning(false);
    warning->AcknowledgeDay(false);
  }

  UpdateList();
}
bool 
AirspaceWarningManager::UpdateInside(const AircraftState& state,
                                     const GlidePolar &glide_polar)
{
  if (!glide_polar.IsValid())
    return false;

  bool found = false;

  AirspacePredicateAircraftInside condition(state);

  Airspaces::AirspaceVector results = airspaces.FindInside(state, condition);
  for (const auto &i : results) {
    const AbstractAirspace &airspace = i.GetAirspace();

    if (!airspace.IsActive())
      continue; // ignore inactive airspaces

    if (!config.IsClassEnabled(airspace.GetType()))
      continue;

    AirspaceWarning *warning = GetWarningPtr(airspace);

    if (warning == nullptr ||
        warning->IsStateAccepted(AirspaceWarning::WARNING_INSIDE)) {
      GeoPoint c = airspace.ClosestPoint(state.location, GetProjection());
      const AirspaceAircraftPerformance perf_glide(glide_polar);
      AirspaceInterceptSolution solution;
      airspace.Intercept(state, c, GetProjection(), perf_glide, solution);

      if (warning == nullptr)
        warning = GetNewWarningPtr(airspace);

      warning->UpdateSolution(AirspaceWarning::WARNING_INSIDE, solution);
      found = true;
    }
  }

  return found;
}
示例#7
0
  void Visit(const AirspaceWarning& as) {
    if (as.GetWarningState() == AirspaceWarning::WARNING_INSIDE) {
      ids_inside.checked_append(&as.GetAirspace());
    } else if (as.GetWarningState() > AirspaceWarning::WARNING_CLEAR) {
      ids_warning.checked_append(&as.GetAirspace());
      locations.checked_append(as.GetSolution().location);
    }

    if (!as.IsAckExpired())
      ids_acked.checked_append(&as.GetAirspace());
  }
示例#8
0
 void Visit(const AirspaceWarning& as) {
   if (as.get_warning_state()== AirspaceWarning::WARNING_INSIDE) {
     ids_inside.checked_append(&as.get_airspace());
   } else if (as.get_warning_state()> AirspaceWarning::WARNING_CLEAR) {
     ids_warning.checked_append(&as.get_airspace());
     locs.checked_append(as.get_solution().location);
   }
   if (!as.get_ack_expired()) {
     ids_acked.checked_append(&as.get_airspace());
   }
 }
示例#9
0
文件: Builder.cpp 项目: rkohel/XCSoar
 void Add(const AirspaceWarning& as) {
   if (as.GetWarningState() > AirspaceWarning::WARNING_CLEAR)
     list.checked_append(&as.GetAirspace());
 }
示例#10
0
static void
OnAirspaceListItemPaint(Canvas &canvas, const PixelRect paint_rc, unsigned i)
{
  TCHAR sTmp[128];
  const int paint_rc_margin = 2;   ///< This constant defines the margin that should be respected for renderring within the paint_rc area.

  bool ack1_vis;
  bool ack2_vis;
  bool ack_vis;
  bool enable_vis;
  bool update_vis = false;

  {
    ProtectedAirspaceWarningManager::Lease lease(*airspace_warnings);
    if (lease->empty()) {
      // the warnings were emptied between the opening of the dialog
      // and this refresh, so only need to display "No Warnings" for
      // top item, otherwise exit immediately
      if (i==0) {
        canvas.text(paint_rc.left + IBLSCALE(paint_rc_margin),
                    paint_rc.top + IBLSCALE(paint_rc_margin), _("No Warnings"));
      }
      return;
    }
    
    if (i >= lease->size())
      /* this cannot be an assertion, because another thread may have
         modified the AirspaceWarningManager */
      return;
    
    const AirspaceWarning warning = *(lease->get_warning(i));
    const AbstractAirspace& as = warning.get_airspace();
    const AirspaceInterceptSolution& solution = warning.get_solution();
    
    tstring sName = as.get_name_text(false);
    tstring sTop = as.get_top_text(true);
    tstring sBase = as.get_base_text(true);
    tstring sType = as.get_type_text(true);
    
    const int TextHeight = 12, TextTop = 1;

    const int statusColWidth = canvas.text_width(_T("inside"));     //<-- word "inside" is used as the etalon, because it is longer than "near" and currently (9.4.2011) there is no other possibility for the status text.
    const int heightColWidth = canvas.text_width(_T("1888 m AGL")); // <-- "1888" is used in order to have enough space for 4-digit heights with "AGL"


    /// Dynamic columns scaling - "name" column is flexible, altitude and state columns are fixed-width.
    const int Col0LeftScreenCoords = Layout::FastScale(paint_rc_margin),
        Col2LeftScreenCoords = paint_rc.right - Layout::FastScale(paint_rc_margin) - (statusColWidth + 2 * Layout::FastScale(paint_rc_margin)),
        Col1LeftScreenCoords = Col2LeftScreenCoords - Layout::FastScale(paint_rc_margin) - heightColWidth;

    PixelRect rcTextClip;
    
    rcTextClip = paint_rc;
    rcTextClip.right = Col1LeftScreenCoords - Layout::FastScale(paint_rc_margin);
    
    Color old_text_color = canvas.get_text_color();
    if (!warning.get_ack_expired())
      canvas.set_text_color(COLOR_GRAY);
    
    { // name, altitude info
      _stprintf(sTmp, _T("%-20s"), sName.c_str());
      
      canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords,
                          paint_rc.top + IBLSCALE(TextTop),
                          rcTextClip, sTmp);
      
      _stprintf(sTmp, _T("%-20s"), sTop.c_str());
      canvas.text(paint_rc.left + Col1LeftScreenCoords,
                  paint_rc.top + IBLSCALE(TextTop), sTmp);
      
      _stprintf(sTmp, _T("%-20s"), sBase.c_str());
      canvas.text(paint_rc.left + Col1LeftScreenCoords,
                  paint_rc.top + IBLSCALE(TextTop + TextHeight),
                  sTmp);
    }
    
    if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE &&
        warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
      
      _stprintf(sTmp, _T("%d secs dist %d m"),
                (int)solution.elapsed_time,
                (int)solution.distance);
      
      canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords,
                          paint_rc.top + IBLSCALE(TextTop + TextHeight),
                          rcTextClip, sTmp);
    }
    
    /* draw the warning state indicator */
    
    Brush *state_brush;
    const TCHAR *state_text;
    
    if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) {
      if (warning.get_ack_expired())
        state_brush = &hBrushInsideBk;
      else
        state_brush = &hBrushInsideAckBk;
      state_text = _T("inside");
    } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
      if (warning.get_ack_expired())
        state_brush = &hBrushNearBk;
      else
        state_brush = &hBrushNearAckBk;
      state_text = _T("near");
    } else {
      state_brush = NULL;
      state_text = NULL;
    }
    
    const PixelSize state_text_size =
      canvas.text_size(state_text != NULL ? state_text : _T("W"));
    
    if (state_brush != NULL) {
      /* colored background */
      PixelRect rc;
      
      rc.left = paint_rc.left + Col2LeftScreenCoords;
      rc.top = paint_rc.top + Layout::FastScale(paint_rc_margin);
      rc.right = paint_rc.right - Layout::FastScale(paint_rc_margin);
      rc.bottom = paint_rc.bottom - Layout::FastScale(paint_rc_margin);
      
      canvas.fill_rectangle(rc, *state_brush);
    }
    
    if (state_text != NULL) {
      // -- status text will be centered inside its table cell:
      canvas.text(paint_rc.left + Col2LeftScreenCoords + Layout::FastScale(paint_rc_margin) + (statusColWidth / 2)  - (canvas.text_width(state_text) / 2),
                  (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2,
                  state_text);
    }
    
    if (!warning.get_ack_expired())
      canvas.set_text_color(old_text_color);
        
    if (CursorAirspace == &as) {
      update_vis = true;
      if (!warning.get_ack_expired()) {
        ack1_vis = false;
        ack_vis = false;
      } else {
        if (warning.get_warning_state() == 
            AirspaceWarning::WARNING_INSIDE) {
          ack_vis = true;
          ack1_vis = false;
        } else {
          ack_vis = false;
          ack1_vis = true;
        }
      }
      ack2_vis = !warning.get_ack_day();
      enable_vis = !warning.get_ack_expired();
    }
  } // close scope
  if (update_vis) {
    wbAck1->set_visible(ack1_vis);
    wbAck2->set_visible(ack2_vis);
    wbAck->set_visible(ack_vis);
    wbEnable->set_visible(enable_vis);
  }
}
示例#11
0
 WarningItem(const AirspaceWarning &warning)
   :airspace(&warning.GetAirspace()),
    state(warning.GetWarningState()),
    solution(warning.GetSolution()),
    ack_expired(warning.IsAckExpired()), ack_day(warning.GetAckDay()) {}
示例#12
0
 void Add(const AirspaceWarning& as) {
   if (as.GetWarningState() == AirspaceWarning::WARNING_INSIDE)
     ids_inside.checked_append(&as.GetAirspace());
   else if (as.GetWarningState() > AirspaceWarning::WARNING_CLEAR)
     ids_warning.checked_append(&as.GetAirspace());
 }
示例#13
0
static void
OnAirspaceListItemPaint(Canvas &canvas, const RECT paint_rc, unsigned i)
{
  TCHAR sTmp[128];

  ProtectedAirspaceWarningManager::Lease lease(airspace_warnings);
  if (lease->empty()) {
    assert(i == 0);

    canvas.text(paint_rc.left + IBLSCALE(2),
                paint_rc.top + IBLSCALE(2), _("No Warnings"));
    return;
  }

  assert(i < lease->size());

  const AirspaceWarning* _warning = lease->get_warning(i);

  const AirspaceWarning warning = *_warning;

  const AbstractAirspace& as = warning.get_airspace();
  const AirspaceInterceptSolution& solution = warning.get_solution();

  tstring sName = as.get_name_text(false);
  tstring sTop = as.get_top_text(true);
  tstring sBase = as.get_base_text(true);
  tstring sType = as.get_type_text(true);

  const int TextHeight = 12, TextTop = 1;
  const int Col0Left = 3, Col1Left = 120, Col2Left = 200;

  RECT         rcTextClip;
    
  rcTextClip = paint_rc;
  rcTextClip.right = IBLSCALE(Col1Left - 2);

  Color old_text_color = canvas.get_text_color();
  if (!warning.get_ack_expired())
    canvas.set_text_color(Color::GRAY);

  { // name, altitude info
    _stprintf(sTmp, _T("%-20s"), sName.c_str());

    canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                        paint_rc.top + IBLSCALE(TextTop),
                        rcTextClip, sTmp);
    
    _stprintf(sTmp, _T("%-20s"), sTop.c_str());
    canvas.text(paint_rc.left + IBLSCALE(Col1Left),
                paint_rc.top + IBLSCALE(TextTop), sTmp);
    
    _stprintf(sTmp, _T("%-20s"), sBase.c_str());
    canvas.text(paint_rc.left + IBLSCALE(Col1Left),
                paint_rc.top + IBLSCALE(TextTop + TextHeight),
                sTmp);
  }

  if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE &&
      warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {

    _stprintf(sTmp, _T("%d secs dist %d m"),
              (int)solution.elapsed_time,
              (int)solution.distance);

    canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                        paint_rc.top + IBLSCALE(TextTop + TextHeight),
                        rcTextClip, sTmp);
  }

  /* draw the warning state indicator */

  Brush *state_brush;
  const TCHAR *state_text;

  if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) {
    if (warning.get_ack_expired())
      state_brush = &hBrushInsideBk;
    else
      state_brush = &hBrushInsideAckBk;
    state_text = _T("inside");
  } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
    if (warning.get_ack_expired())
      state_brush = &hBrushNearBk;
    else
      state_brush = &hBrushNearAckBk;
    state_text = _T("near");
  } else {
    state_brush = NULL;
    state_text = NULL;
  }

  const SIZE state_text_size = canvas.text_size(state_text != NULL
                                                ? state_text : _T("W"));

  if (state_brush != NULL) {
    /* colored background */
    RECT rc;

    rc.left = paint_rc.left + Layout::FastScale(Col2Left);
    rc.top = paint_rc.top + Layout::FastScale(2);
    rc.right = rc.left + state_text_size.cx + Layout::FastScale(4);
    rc.bottom = paint_rc.bottom - Layout::FastScale(2);

    canvas.fill_rectangle(rc, *state_brush);
  }

  if (state_text != NULL)
    canvas.text(paint_rc.left + Layout::FastScale(Col2Left + 2),
                (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2,
                state_text);

/*  
  
  TCHAR sAckIndicator[6] = _T(" -++*");

  if (pAS.Inside){
    
    _stprintf(sTmp, _T("> %c %s"), sAckIndicator[pAS.Acknowledge], sType);
    
  } else {
    
    TCHAR DistanceText[MAX_PATH];
    if (pAS.hDistance == 0) {
      
      // Directly above or below airspace
      
      Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
      if (pAS.vDistance > 0) {
        _stprintf(sTmp, _T("< %c %s ab %s"),
                  sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      }
      if (pAS.vDistance < 0) {
        Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
        _stprintf(sTmp, _T("< %c %s bl %s"),
                  sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      }
    } else {
      if ((pAS.vDistance == 0) ||
          (pAS.hDistance < abs(pAS.vDistance)*30 )) {
        
        // Close to airspace altitude, horizontally separated
        
        Units::FormatUserDistance(fabs((double)pAS.hDistance),DistanceText, 7);
        _stprintf(sTmp, _T("< %c %s H %s"), sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      } else {
        
        // Effectively above or below airspace, steep climb or descent
        // necessary to enter
        
        Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
        if (pAS.vDistance > 0) {
          _stprintf(sTmp, _T("< %c %s ab %s"),
                    sAckIndicator[pAS.Acknowledge],
                    sType, DistanceText);
        } else {
          _stprintf(sTmp, _T("< %c %s bl %s"),
                    sAckIndicator[pAS.Acknowledge], sType,
                    DistanceText);
        }
      }
    }
  }
  canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                      paint_rc.top + IBLSCALE(TextTop + TextHeight),
                      rcTextClip, sTmp);
*/  

  if (!warning.get_ack_expired())
    canvas.set_text_color(old_text_color);
}