static std::pair<double, double> GetMinMax(TrailSettings::Type type, const TracePointVector &trace) { double value_min, value_max; if (type == TrailSettings::Type::ALTITUDE) { value_max = 1000; value_min = 500; for (auto it = trace.begin(); it != trace.end(); ++it) { value_max = std::max(it->GetAltitude(), value_max); value_min = std::min(it->GetAltitude(), value_min); } } else { value_max = 0.75; value_min = -2.0; for (auto it = trace.begin(); it != trace.end(); ++it) { value_max = std::max(it->GetVario(), value_max); value_min = std::min(it->GetVario(), value_min); } value_max = std::min(7.5, value_max); value_min = std::max(-5.0, value_min); } return std::make_pair(value_min, value_max); }
static std::pair<fixed, fixed> GetMinMax(TrailSettings::Type type, const TracePointVector &trace) { fixed value_min, value_max; if (type == TrailSettings::Type::ALTITUDE) { value_max = fixed(1000); value_min = fixed(500); for (auto it = trace.begin(); it != trace.end(); ++it) { value_max = std::max(it->GetAltitude(), value_max); value_min = std::min(it->GetAltitude(), value_min); } } else { value_max = fixed(0.75); value_min = fixed(-2.0); for (auto it = trace.begin(); it != trace.end(); ++it) { value_max = std::max(it->GetVario(), value_max); value_min = std::min(it->GetVario(), value_min); } value_max = std::min(fixed(7.5), value_max); value_min = std::max(fixed(-5.0), value_min); } return std::make_pair(value_min, value_max); }
void TrailRenderer::Draw(Canvas &canvas, const TraceComputer &trace_computer, const WindowProjection &projection, unsigned min_time, bool enable_traildrift, const RasterPoint pos, const NMEAInfo &basic, const DerivedInfo &calculated, const TrailSettings &settings) { if (settings.length == TrailSettings::Length::OFF) return; if (!LoadTrace(trace_computer, min_time, projection)) return; if (!calculated.wind_available) enable_traildrift = false; GeoPoint traildrift; if (enable_traildrift) { GeoPoint tp1 = FindLatitudeLongitude(basic.location, calculated.wind.bearing, calculated.wind.norm); traildrift = basic.location - tp1; } auto minmax = GetMinMax(settings.type, trace); auto value_min = minmax.first; auto value_max = minmax.second; bool scaled_trail = settings.scaling_enabled && projection.GetMapScale() <= 6000; const GeoBounds bounds = projection.GetScreenBounds().Scale(4); RasterPoint last_point = RasterPoint(0, 0); bool last_valid = false; for (auto it = trace.begin(), end = trace.end(); it != end; ++it) { const GeoPoint gp = enable_traildrift ? it->GetLocation().Parametric(traildrift, it->CalculateDrift(basic.time)) : it->GetLocation(); if (!bounds.IsInside(gp)) { /* the point is outside of the MapWindow; don't paint it */ last_valid = false; continue; } RasterPoint pt = projection.GeoToScreen(gp); if (last_valid) { if (settings.type == TrailSettings::Type::ALTITUDE) { unsigned index = GetAltitudeColorIndex(it->GetAltitude(), value_min, value_max); canvas.Select(look.trail_pens[index]); canvas.DrawLinePiece(last_point, pt); } else { unsigned color_index = GetSnailColorIndex(it->GetVario(), value_min, value_max); if (it->GetVario() < 0 && (settings.type == TrailSettings::Type::VARIO_1_DOTS || settings.type == TrailSettings::Type::VARIO_2_DOTS || settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES)) { canvas.SelectNullPen(); canvas.Select(look.trail_brushes[color_index]); canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2, look.trail_widths[color_index]); } else { // positive vario case if (settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES) { canvas.Select(look.trail_brushes[color_index]); canvas.Select(look.trail_pens[color_index]); //fixed-width pen canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2, look.trail_widths[color_index]); } else if (scaled_trail) // width scaled to vario canvas.Select(look.scaled_trail_pens[color_index]); else // fixed-width pen canvas.Select(look.trail_pens[color_index]); canvas.DrawLinePiece(last_point, pt); } } } last_point = pt; last_valid = true; } if (last_valid) canvas.DrawLine(last_point, pos); }