Add radar line and radar distance/altitude tooltip

This commit is contained in:
AdenKoperczak 2025-05-03 10:16:20 -04:00
parent d21a11963f
commit 33f92bcda5
No known key found for this signature in database
GPG key ID: 9843017036F62EE7
2 changed files with 141 additions and 10 deletions

View file

@ -1,6 +1,9 @@
#include <scwx/qt/map/radar_product_layer.hpp>
#include <scwx/qt/map/map_settings.hpp>
#include <scwx/qt/gl/shader_program.hpp>
#include <scwx/qt/settings/unit_settings.hpp>
#include <scwx/qt/types/unit_types.hpp>
#include <scwx/qt/util/geographic_lib.hpp>
#include <scwx/qt/util/maplibre.hpp>
#include <scwx/qt/util/tooltip.hpp>
#include <scwx/qt/view/radar_product_view.hpp>
@ -353,11 +356,66 @@ bool RadarProductLayer::RunMousePicking(
std::shared_ptr<view::RadarProductView> radarProductView =
context()->radar_product_view();
if (radarProductView == nullptr)
if (context()->radar_site() == nullptr)
{
return itemPicked;
}
// Get distance and altitude of point
const double radarLatitude = context()->radar_site()->latitude();
const double radarLongitude = context()->radar_site()->longitude();
const auto distanceMeters = util::GeographicLib::GetDistance(
mouseGeoCoords.latitude_,
mouseGeoCoords.longitude_,
radarLatitude,
radarLongitude);
const std::string distanceUnitName =
settings::UnitSettings::Instance().distance_units().GetValue();
const types::DistanceUnits distanceUnits =
types::GetDistanceUnitsFromName(distanceUnitName);
const double distanceScale = types::GetDistanceUnitsScale(distanceUnits);
const std::string distanceAbbrev =
types::GetDistanceUnitsAbbreviation(distanceUnits);
const double distance = distanceMeters.value() *
scwx::common::kKilometersPerMeter * distanceScale;
std::string distanceHeightStr =
fmt::format("{:.2f} {}", distance, distanceAbbrev);
if (radarProductView == nullptr)
{
util::tooltip::Show(distanceHeightStr, mouseGlobalPos);
itemPicked = true;
return itemPicked;
}
std::optional<float> elevation = radarProductView->elevation();
if (elevation.has_value())
{
const auto altitudeMeters =
util::GeographicLib::GetRadarBeamAltititude(
distanceMeters,
units::angle::degrees<double>(*elevation),
context()->radar_site()->altitude());
const std::string heightUnitName =
settings::UnitSettings::Instance().echo_tops_units().GetValue();
const types::EchoTopsUnits heightUnits =
types::GetEchoTopsUnitsFromName(heightUnitName);
const double heightScale = types::GetEchoTopsUnitsScale(heightUnits);
const std::string heightAbbrev =
types::GetEchoTopsUnitsAbbreviation(heightUnits);
const double altitude = altitudeMeters.value() *
scwx::common::kKilometersPerMeter *
heightScale;
distanceHeightStr = fmt::format(
"{}\n{:.2f} {}", distanceHeightStr, altitude, heightAbbrev);
}
std::optional<std::uint16_t> binLevel =
radarProductView->GetBinLevel(mouseGeoCoords);
@ -383,12 +441,13 @@ bool RadarProductLayer::RunMousePicking(
if (codeName != codeShortName && !codeShortName.empty())
{
// There is a unique long and short name for the code
hoverText = fmt::format("{}: {}", codeShortName, codeName);
hoverText = fmt::format(
"{}: {}\n{}", codeShortName, codeName, distanceHeightStr);
}
else
{
// Otherwise, only use the long name (always present)
hoverText = codeName;
hoverText = fmt::format("{}\n{}", codeName, distanceHeightStr);
}
// Show the tooltip
@ -439,17 +498,20 @@ bool RadarProductLayer::RunMousePicking(
{
// Don't display a units value that wasn't intended to be
// displayed
hoverText = fmt::format("{}{}", f, suffix);
hoverText =
fmt::format("{}{}\n{}", f, suffix, distanceHeightStr);
}
else if (std::isalpha(static_cast<unsigned char>(units.at(0))))
{
// dBZ, Kts, etc.
hoverText = fmt::format("{} {}{}", f, units, suffix);
hoverText = fmt::format(
"{} {}{}\n{}", f, units, suffix, distanceHeightStr);
}
else
{
// %, etc.
hoverText = fmt::format("{}{}{}", f, units, suffix);
hoverText = fmt::format(
"{}{}{}\n{}", f, units, suffix, distanceHeightStr);
}
// Show the tooltip
@ -458,6 +520,12 @@ bool RadarProductLayer::RunMousePicking(
itemPicked = true;
}
}
else
{
// Always show tooltip for distance and altitude
util::tooltip::Show(distanceHeightStr, mouseGlobalPos);
itemPicked = true;
}
}
return itemPicked;

View file

@ -1,5 +1,6 @@
#include <scwx/qt/map/radar_site_layer.hpp>
#include <scwx/qt/config/radar_site.hpp>
#include <scwx/qt/gl/draw/geo_lines.hpp>
#include <scwx/qt/settings/general_settings.hpp>
#include <scwx/qt/settings/text_settings.hpp>
#include <scwx/qt/util/maplibre.hpp>
@ -10,6 +11,8 @@
#include <imgui.h>
#include <mbgl/util/constants.hpp>
#include <QGuiApplication>
namespace scwx
{
namespace qt
@ -23,11 +26,32 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class RadarSiteLayer::Impl
{
public:
explicit Impl(RadarSiteLayer* self) : self_ {self} {}
explicit Impl(RadarSiteLayer* self, std::shared_ptr<MapContext>& context) :
self_ {self},
geoLines_ {std::make_shared<gl::draw::GeoLines>(context)}
{
geoLines_->StartLines();
radarSiteLines_[0] = geoLines_->AddLine();
radarSiteLines_[1] = geoLines_->AddLine();
geoLines_->FinishLines();
static const boost::gil::rgba32f_pixel_t color0 {0.0f, 0.0f, 0.0f, 1.0f};
static const boost::gil::rgba32f_pixel_t color1 {1.0f, 1.0f, 1.0f, 1.0f};
static const float width = 1;
geoLines_->SetLineModulate(radarSiteLines_[0], color0);
geoLines_->SetLineWidth(radarSiteLines_[0], width + 2);
geoLines_->SetLineModulate(radarSiteLines_[1], color1);
geoLines_->SetLineWidth(radarSiteLines_[1], width);
self_->AddDrawItem(geoLines_);
geoLines_->set_thresholded(false);
}
~Impl() = default;
void RenderRadarSite(const QMapLibre::CustomLayerRenderParameters& params,
std::shared_ptr<config::RadarSite>& radarSite);
void RenderRadarLine();
RadarSiteLayer* self_;
@ -41,10 +65,13 @@ public:
float halfHeight_ {};
std::string hoverText_ {};
std::shared_ptr<gl::draw::GeoLines> geoLines_;
std::array<std::shared_ptr<gl::draw::GeoLineDrawItem>, 2> radarSiteLines_;
};
RadarSiteLayer::RadarSiteLayer(std::shared_ptr<MapContext> context) :
DrawLayer(context, "RadarSiteLayer"), p(std::make_unique<Impl>(this))
DrawLayer(context, "RadarSiteLayer"), p(std::make_unique<Impl>(this, context))
{
}
@ -56,7 +83,7 @@ void RadarSiteLayer::Initialize()
p->radarSites_ = config::RadarSite::GetAll();
ImGuiInitialize();
DrawLayer::Initialize();
}
void RadarSiteLayer::Render(
@ -96,8 +123,12 @@ void RadarSiteLayer::Render(
}
ImGui::PopStyleVar();
ImGuiFrameEnd();
p->RenderRadarLine();
DrawLayer::RenderWithoutImGui(params);
ImGuiFrameEnd();
SCWX_GL_CHECK_ERROR();
}
@ -163,6 +194,38 @@ void RadarSiteLayer::Impl::RenderRadarSite(
}
}
void RadarSiteLayer::Impl::RenderRadarLine()
{
// TODO check if state is updated.
if ((QGuiApplication::keyboardModifiers() &
Qt::KeyboardModifier::ShiftModifier) &&
self_->context()->radar_site() != nullptr)
{
const auto& mouseCoord = self_->context()->mouse_coordinate();
const double radarLatitude = self_->context()->radar_site()->latitude();
const double radarLongitude = self_->context()->radar_site()->longitude();
geoLines_->SetLineLocation(radarSiteLines_[0],
static_cast<float>(mouseCoord.latitude_),
static_cast<float>(mouseCoord.longitude_),
static_cast<float>(radarLatitude),
static_cast<float>(radarLongitude));
geoLines_->SetLineVisible(radarSiteLines_[0], true);
geoLines_->SetLineLocation(radarSiteLines_[1],
static_cast<float>(mouseCoord.latitude_),
static_cast<float>(mouseCoord.longitude_),
static_cast<float>(radarLatitude),
static_cast<float>(radarLongitude));
geoLines_->SetLineVisible(radarSiteLines_[1], true);
}
else
{
geoLines_->SetLineVisible(radarSiteLines_[0], false);
geoLines_->SetLineVisible(radarSiteLines_[1], false);
}
}
void RadarSiteLayer::Deinitialize()
{
logger_->debug("Deinitialize()");