Beispiel #1
0
void
MapItemListBuilder::AddArrivalAltitudes(
    const ProtectedRoutePlanner &route_planner,
    const RasterTerrain *terrain, double safety_height)
{
  if (list.full())
    return;

  // Calculate terrain elevation if possible
  double elevation = LocationMapItem::UNKNOWN_ELEVATION;
  if (terrain != nullptr)
    elevation = terrain->GetTerrainHeight(location)
      .ToDouble(LocationMapItem::UNKNOWN_ELEVATION);

  // Calculate target altitude
  double safety_elevation(safety_height);
  if (elevation > ArrivalAltitudeMapItem::UNKNOWN_ELEVATION_THRESHOLD)
    safety_elevation += elevation;

  // Save destination point incl. elevation and safety height
  const AGeoPoint destination(location, safety_elevation);

  // Calculate arrival altitudes
  ReachResult reach;

  ProtectedRoutePlanner::Lease leased_route_planner(route_planner);
  if (!leased_route_planner->FindPositiveArrival(destination, reach))
    return;

  reach.Subtract(safety_height);

  list.append(new ArrivalAltitudeMapItem(elevation, reach));
}
Beispiel #2
0
void
MapItemListBuilder::AddArrivalAltitudes(
    const ProtectedRoutePlanner &route_planner,
    const RasterTerrain *terrain, fixed safety_height)
{
  if (list.full())
    return;

  // Calculate terrain elevation if possible
  short elevation;
  if (terrain != NULL)
    elevation = terrain->GetTerrainHeight(location);
  else
    elevation = RasterBuffer::TERRAIN_INVALID;

  // Calculate target altitude
  RoughAltitude safety_elevation(safety_height);
  if (!RasterBuffer::IsInvalid(elevation))
    safety_elevation += RoughAltitude(elevation);

  // Save destination point incl. elevation and safety height
  const AGeoPoint destination(location, safety_elevation);

  // Calculate arrival altitudes
  ReachResult reach;

  ProtectedRoutePlanner::Lease leased_route_planner(route_planner);
  if (!leased_route_planner->FindPositiveArrival(destination, reach))
    return;

  reach.Subtract(RoughAltitude(safety_height));

  list.append(new ArrivalAltitudeMapItem(RoughAltitude(elevation), reach));
}
Beispiel #3
0
  void CalculateReachability(const RoutePlannerGlue &route_planner,
                             const TaskBehaviour &task_behaviour)
  {
    CalculateRouteArrival(route_planner, task_behaviour);

    if (!reach.IsReachableDirect())
      reachable = WaypointRenderer::Unreachable;
    else if (task_behaviour.route_planner.IsReachEnabled() &&
             !reach.IsReachableTerrain())
      reachable = WaypointRenderer::ReachableStraight;
    else
      reachable = WaypointRenderer::ReachableTerrain;
  }
Beispiel #4
0
bool
ReachFan::FindPositiveArrival(const AGeoPoint dest, const RoutePolars &rpolars,
                              ReachResult &result_r) const
{
  if (root.IsEmpty())
    return false;

  const FlatGeoPoint d(task_proj.ProjectInteger(dest));
  const ReachFanParms parms(rpolars, task_proj, (int)terrain_base);

  result_r.Clear();

  // first calculate direct (terrain-independent height)
  result_r.direct = root.DirectArrival(d, parms);

  if (root.IsDummy())
    /* terrain reach is not available, stop here */
    return true;

  // if can't reach even with no terrain, exit early
  if (std::min(root.GetHeight(), result_r.direct) < dest.altitude) {
    result_r.terrain = result_r.direct;
    result_r.terrain_valid = ReachResult::Validity::UNREACHABLE;
    return true;
  }

  // now calculate turning solution
  result_r.terrain = dest.altitude - RoughAltitude(1);
  result_r.terrain_valid = root.FindPositiveArrival(d, parms, result_r.terrain)
    ? ReachResult::Validity::VALID
    : ReachResult::Validity::UNREACHABLE;

  return true;
}
Beispiel #5
0
 void Set(const WaypointPtr &_waypoint, PixelPoint &_point,
          bool _in_task) {
   waypoint = _waypoint;
   point = _point;
   reach.Clear();
   reachable = WaypointRenderer::Invalid;
   in_task = _in_task;
 }
Beispiel #6
0
 void CalculateRouteArrival(const RoutePlannerGlue &route_planner,
                            const TaskBehaviour &task_behaviour) {
   const double elevation = waypoint->elevation +
     task_behaviour.safety_height_arrival;
   const AGeoPoint p_dest (waypoint->location, elevation);
   if (route_planner.FindPositiveArrival(p_dest, reach))
     reach.Subtract(elevation);
 }
Beispiel #7
0
 void Set(const WaypointPtr &_waypoint, RasterPoint &_point,
          bool _in_task) {
   waypoint = _waypoint;
   point = _point;
   reach.Clear();
   reachable = WaypointRenderer::Unreachable;
   in_task = _in_task;
 }
Beispiel #8
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);
  }
Beispiel #9
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);
  }