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)); }
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)); }
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; }
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; }
void Set(const WaypointPtr &_waypoint, PixelPoint &_point, bool _in_task) { waypoint = _waypoint; point = _point; reach.Clear(); reachable = WaypointRenderer::Invalid; in_task = _in_task; }
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); }
void Set(const WaypointPtr &_waypoint, RasterPoint &_point, bool _in_task) { waypoint = _waypoint; point = _point; reach.Clear(); reachable = WaypointRenderer::Unreachable; in_task = _in_task; }
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); }
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); }