void TerrainPreviewWindow::OnPaint(Canvas &canvas) { const GlueMapWindow *map = UIGlobals::GetMap(); if (map == nullptr) return; MapWindowProjection projection = map->VisibleProjection(); if (!projection.IsValid()) { /* TODO: initialise projection to middle of map instead of bailing out */ canvas.ClearWhite(); return; } projection.SetScreenSize(canvas.GetSize()); projection.SetScreenOrigin(canvas.GetWidth() / 2, canvas.GetHeight() / 2); Angle sun_azimuth(Angle::Degrees(-45)); if (renderer.GetSettings().slope_shading == SlopeShading::SUN && CommonInterface::Calculated().sun_data_available) sun_azimuth = CommonInterface::Calculated().sun_azimuth; renderer.Generate(projection, sun_azimuth); #ifdef ENABLE_OPENGL /* enable clipping because the OpenGL terrain renderer uses a large texture that exceeds the window dimensions */ GLCanvasScissor scissor(canvas); #endif renderer.Draw(canvas, projection); }
void TerrainDisplayConfigPanel::OnPreviewPaint(Canvas &canvas) { TerrainRenderer renderer(terrain); renderer.SetSettings(terrain_settings); MapWindowProjection projection = XCSoarInterface::main_window.GetProjection(); projection.SetScreenSize(canvas.get_width(), canvas.get_height()); projection.SetScreenOrigin(canvas.get_width() / 2, canvas.get_height() / 2); Angle sun_azimuth(Angle::Degrees(fixed(-45))); if (terrain_settings.slope_shading == SlopeShading::SUN && XCSoarInterface::Calculated().sun_data_available) sun_azimuth = XCSoarInterface::Calculated().sun_azimuth; renderer.Generate(projection, sun_azimuth); renderer.Draw(canvas, projection); }
void WaypointRenderer::render(Canvas &canvas, LabelBlock &label_block, const MapWindowProjection &projection, const struct WaypointRendererSettings &settings, const PolarSettings &polar_settings, const TaskBehaviour &task_behaviour, const MoreData &basic, const DerivedInfo &calculated, const ProtectedTaskManager *task, const ProtectedRoutePlanner *route_planner) { if (way_points == nullptr || way_points->IsEmpty()) return; WaypointVisitorMap v(projection, settings, look, task_behaviour, basic); if (task != nullptr) { ProtectedTaskManager::Lease task_manager(*task); const TaskStats &task_stats = task_manager->GetStats(); // task items come first, this is the only way we know that an item is in task, // and we won't add it if it is already there if (task_stats.task_valid) v.SetTaskValid(); const AbstractTask *atask = task_manager->GetActiveTask(); if (atask != nullptr) atask->AcceptTaskPointVisitor(v); } way_points->VisitWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), v); v.Calculate(route_planner, polar_settings, task_behaviour, calculated); v.Draw(canvas); MapWaypointLabelRender(canvas, projection.GetScreenWidth(), projection.GetScreenHeight(), label_block, v.labels, look); }
int FindNearestWayPoint(const WayPointList &way_points, MapWindowProjection &map_projection, const GEOPOINT &loc, double MaxRange, bool exhaustive) { int NearestIndex = -1; double NearestDistance, Dist; NearestDistance = MaxRange; for (unsigned i = 0; way_points.verify_index(i); ++i) { if (way_points.get_calc(i).Visible) { if (map_projection.WaypointInScaleFilter(i)) { // only look for visible waypoints // feature added by Samuel Gisiger Dist = Distance(loc, way_points.get(i).Location); if(Dist < NearestDistance) { NearestIndex = i; NearestDistance = Dist; } } } } // JMW allow exhaustive check for when looking up in status dialog if (exhaustive && (NearestIndex == -1)) { for (unsigned i = 0; way_points.verify_index(i); ++i) { Dist = Distance(loc, way_points.get(i).Location); if(Dist < NearestDistance) { NearestIndex = i; NearestDistance = Dist; } } } if(NearestDistance < MaxRange) return NearestIndex; else return -1; }
void Topology::updateCache(MapWindowProjection &map_projection, rectObj thebounds, bool purgeonly) { if (!triggerUpdateCache) return; if (!shapefileopen) return; in_scale = CheckScale(map_projection.GetMapScaleUser()); if (!in_scale) { // not visible, so flush the cache // otherwise we waste time on looking up which shapes are in bounds flushCache(); triggerUpdateCache = false; return; } if (purgeonly) return; triggerUpdateCache = false; msSHPWhichShapes(&shpfile, thebounds, 0); if (!shpfile.status) { // this happens if entire shape is out of range // so clear buffer. flushCache(); return; } shapes_visible_count = 0; for (int i=0; i<shpfile.numshapes; i++) { if (msGetBit(shpfile.status, i)) { if (shpCache[i]==NULL) { // shape is now in range, and wasn't before shpCache[i] = addShape(i); } shapes_visible_count++; } else { removeShape(i); } } }
void GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc, const MapWindowProjection &projection) const { TCHAR buffer[80]; fixed MapWidth = projection.GetScreenWidthMeters(); canvas.select(Fonts::MapBold); Units::FormatUserMapScale(MapWidth, buffer, sizeof(buffer) / sizeof(TCHAR), true); PixelSize TextSize = canvas.text_size(buffer); int Height = Fonts::MapBold.get_capital_height() + Layout::Scale(2); // 2: add 1pix border canvas.fill_rectangle(Layout::Scale(4), rc.bottom - Height, TextSize.cx + Layout::Scale(11), rc.bottom, COLOR_WHITE); canvas.background_transparent(); canvas.set_text_color(COLOR_BLACK); canvas.text(Layout::Scale(7), rc.bottom - Fonts::MapBold.get_ascent_height() - Layout::Scale(1), buffer); Graphics::hBmpMapScaleLeft.draw(canvas, 0, rc.bottom - Height); Graphics::hBmpMapScaleRight.draw(canvas, Layout::Scale(9) + TextSize.cx, rc.bottom - Height); buffer[0] = '\0'; if (SettingsMap().AutoZoom) _tcscat(buffer, _T("AUTO ")); switch (follow_mode) { case FOLLOW_SELF: break; case FOLLOW_PAN: _tcscat(buffer, _T("PAN ")); break; } const UIState &ui_state = CommonInterface::GetUIState(); if (ui_state.auxiliary_enabled) { _tcscat(buffer, InfoBoxManager::GetCurrentPanelName()); _tcscat(buffer, _T(" ")); } if (Basic().gps.replay) _tcscat(buffer, _T("REPLAY ")); else if (Basic().gps.simulator) { _tcscat(buffer, _("Simulator")); _tcscat(buffer, _T(" ")); } if (SettingsComputer().BallastTimerActive) { TCHAR TEMP[20]; _stprintf(TEMP, _T("BALLAST %d LITERS "), (int)SettingsComputer().glide_polar_task.GetBallastLitres()); _tcscat(buffer, TEMP); } if (weather != NULL && weather->GetParameter() > 0) { const TCHAR *label = weather->ItemLabel(weather->GetParameter()); if (label != NULL) _tcscat(buffer, label); } if (buffer[0]) { int y = rc.bottom - Height; canvas.select(Fonts::Title); canvas.background_opaque(); canvas.set_background_color(COLOR_WHITE); canvas.text(0, y - canvas.text_size(buffer).cy, buffer); } }
void GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc, const MapWindowProjection &projection) const { if (!projection.IsValid()) return; StaticString<80> buffer; fixed map_width = projection.GetScreenWidthMeters(); const Font &font = *look.overlay_font; canvas.Select(font); FormatUserMapScale(map_width, buffer.buffer(), true); PixelSize text_size = canvas.CalcTextSize(buffer); const PixelScalar text_padding_x = Layout::GetTextPadding(); const PixelScalar height = font.GetCapitalHeight() + Layout::GetTextPadding(); PixelScalar x = 0; look.map_scale_left_icon.Draw(canvas, 0, rc.bottom - height); x += look.map_scale_left_icon.GetSize().cx; canvas.DrawFilledRectangle(x, rc.bottom - height, x + 2 * text_padding_x + text_size.cx, rc.bottom, COLOR_WHITE); canvas.SetBackgroundTransparent(); canvas.SetTextColor(COLOR_BLACK); x += text_padding_x; canvas.DrawText(x, rc.bottom - font.GetAscentHeight() - Layout::Scale(1), buffer); x += text_padding_x + text_size.cx; look.map_scale_right_icon.Draw(canvas, x, rc.bottom - height); buffer.clear(); if (GetMapSettings().auto_zoom_enabled) buffer = _T("AUTO "); switch (follow_mode) { case FOLLOW_SELF: break; case FOLLOW_PAN: buffer += _T("PAN "); break; } const UIState &ui_state = GetUIState(); if (ui_state.auxiliary_enabled) { buffer += ui_state.panel_name; buffer += _T(" "); } if (Basic().gps.replay) buffer += _T("REPLAY "); else if (Basic().gps.simulator) { buffer += _("Simulator"); buffer += _T(" "); } if (GetComputerSettings().polar.ballast_timer_active) buffer.AppendFormat( _T("BALLAST %d LITERS "), (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres()); if (weather != nullptr && weather->GetParameter() > 0) { const TCHAR *label = weather->ItemLabel(weather->GetParameter()); if (label != nullptr) buffer += label; } if (!buffer.empty()) { int y = rc.bottom - height; TextInBoxMode mode; mode.vertical_position = TextInBoxMode::VerticalPosition::ABOVE; mode.shape = LabelShape::OUTLINED; TextInBox(canvas, buffer, 0, y, mode, rc, nullptr); } }
void UpdateScreenBounds() { visible_projection.UpdateScreenBounds(); }
void SetLocation(const GeoPoint location) { visible_projection.SetGeoLocation(location); }
gcc_pure GeoPoint GetLocation() const { return visible_projection.IsValid() ? visible_projection.GetGeoLocation() : GeoPoint::Invalid(); }
void GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc, const MapWindowProjection &projection) const { StaticString<80> buffer; fixed map_width = projection.GetScreenWidthMeters(); canvas.Select(Fonts::map_bold); FormatUserMapScale(map_width, buffer.buffer(), true); PixelSize text_size = canvas.CalcTextSize(buffer); const PixelScalar text_padding_x = Layout::Scale(2); const PixelScalar height = Fonts::map_bold.GetCapitalHeight() + Layout::Scale(2); PixelScalar x = 0; look.map_scale_left_icon.Draw(canvas, 0, rc.bottom - height); x += look.map_scale_left_icon.GetSize().cx; canvas.DrawFilledRectangle(x, rc.bottom - height, x + 2 * text_padding_x + text_size.cx, rc.bottom, COLOR_WHITE); canvas.SetBackgroundTransparent(); canvas.SetTextColor(COLOR_BLACK); x += text_padding_x; canvas.text(x, rc.bottom - Fonts::map_bold.GetAscentHeight() - Layout::Scale(1), buffer); x += text_padding_x + text_size.cx; look.map_scale_right_icon.Draw(canvas, x, rc.bottom - height); buffer.clear(); if (GetMapSettings().auto_zoom_enabled) buffer = _T("AUTO "); switch (follow_mode) { case FOLLOW_SELF: break; case FOLLOW_PAN: buffer += _T("PAN "); break; } const UIState &ui_state = GetUIState(); if (ui_state.auxiliary_enabled) { buffer += ui_state.panel_name; buffer += _T(" "); } if (Basic().gps.replay) buffer += _T("REPLAY "); else if (Basic().gps.simulator) { buffer += _("Simulator"); buffer += _T(" "); } if (GetComputerSettings().polar.ballast_timer_active) buffer.AppendFormat( _T("BALLAST %d LITERS "), (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres()); if (weather != NULL && weather->GetParameter() > 0) { const TCHAR *label = weather->ItemLabel(weather->GetParameter()); if (label != NULL) buffer += label; } if (!buffer.empty()) { int y = rc.bottom - height; canvas.Select(Fonts::title); canvas.SetBackgroundOpaque(); canvas.SetBackgroundColor(COLOR_WHITE); canvas.text(0, y - canvas.CalcTextSize(buffer).cy, buffer); } }
void GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc, const MapWindowProjection &projection) const { RenderMapScale(canvas, projection, rc, look.overlay); if (!projection.IsValid()) return; StaticString<80> buffer; buffer.clear(); if (GetMapSettings().auto_zoom_enabled) buffer = _T("AUTO "); switch (follow_mode) { case FOLLOW_SELF: break; case FOLLOW_PAN: buffer += _T("PAN "); break; } const UIState &ui_state = GetUIState(); if (ui_state.auxiliary_enabled) { buffer += ui_state.panel_name; buffer += _T(" "); } if (Basic().gps.replay) buffer += _T("REPLAY "); else if (Basic().gps.simulator) { buffer += _("Simulator"); buffer += _T(" "); } if (GetComputerSettings().polar.ballast_timer_active) buffer.AppendFormat( _T("BALLAST %d LITERS "), (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres()); if (rasp_renderer != nullptr) { const TCHAR *label = rasp_renderer->GetLabel(); if (label != nullptr) buffer += gettext(label); } if (!buffer.empty()) { const Font &font = *look.overlay.overlay_font; canvas.Select(font); const unsigned height = font.GetCapitalHeight() + Layout::GetTextPadding(); int y = rc.bottom - height; TextInBoxMode mode; mode.vertical_position = TextInBoxMode::VerticalPosition::ABOVE; mode.shape = LabelShape::OUTLINED; TextInBox(canvas, buffer, 0, y, mode, rc, nullptr); } }
void Topology::TriggerIfScaleNowVisible(MapWindowProjection &map_projection) { triggerUpdateCache |= (CheckScale(map_projection.GetMapScaleUser()) != in_scale); }
gcc_pure const GeoPoint &GetLocation() const { return visible_projection.GetGeoLocation(); }
TriangleCompound(const MapWindowProjection& _proj) :proj(_proj), clip(_proj.GetScreenBounds().Scale(fixed(1.1))) { }