Add compass icon to map showing bearing, and allow reset to north up

This commit is contained in:
Dan Paulat 2024-01-13 23:19:34 -06:00
parent b3e035c53d
commit 9c7e3eb7e6

View file

@ -1,5 +1,6 @@
#include <scwx/qt/map/overlay_layer.hpp> #include <scwx/qt/map/overlay_layer.hpp>
#include <scwx/qt/gl/draw/geo_icons.hpp> #include <scwx/qt/gl/draw/geo_icons.hpp>
#include <scwx/qt/gl/draw/icons.hpp>
#include <scwx/qt/gl/draw/rectangle.hpp> #include <scwx/qt/gl/draw/rectangle.hpp>
#include <scwx/qt/manager/position_manager.hpp> #include <scwx/qt/manager/position_manager.hpp>
#include <scwx/qt/types/texture_types.hpp> #include <scwx/qt/types/texture_types.hpp>
@ -14,6 +15,7 @@
#include <imgui.h> #include <imgui.h>
#include <QGeoPositionInfo> #include <QGeoPositionInfo>
#include <QMouseEvent>
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
# include <date/date.h> # include <date/date.h>
@ -39,7 +41,11 @@ public:
explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) : explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) :
activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context)}, activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context)},
activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context)}, activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context)},
icons_ {std::make_shared<gl::draw::GeoIcons>(context)}, geoIcons_ {std::make_shared<gl::draw::GeoIcons>(context)},
icons_ {std::make_shared<gl::draw::Icons>(context)},
cardinalPointIconName_ {
types::GetTextureName(types::ImageTexture::CardinalPoint24)},
compassIconName_ {types::GetTextureName(types::ImageTexture::Compass24)},
locationIconName_ { locationIconName_ {
types::GetTextureName(types::ImageTexture::Crosshairs24)} types::GetTextureName(types::ImageTexture::Crosshairs24)}
{ {
@ -52,11 +58,21 @@ public:
std::shared_ptr<gl::draw::Rectangle> activeBoxOuter_; std::shared_ptr<gl::draw::Rectangle> activeBoxOuter_;
std::shared_ptr<gl::draw::Rectangle> activeBoxInner_; std::shared_ptr<gl::draw::Rectangle> activeBoxInner_;
std::shared_ptr<gl::draw::GeoIcons> icons_; std::shared_ptr<gl::draw::GeoIcons> geoIcons_;
std::shared_ptr<gl::draw::Icons> icons_;
const std::string& locationIconName_; const std::string& locationIconName_;
std::shared_ptr<gl::draw::GeoIconDrawItem> locationIcon_ {}; std::shared_ptr<gl::draw::GeoIconDrawItem> locationIcon_ {};
const std::string& cardinalPointIconName_;
const std::string& compassIconName_;
std::shared_ptr<gl::draw::IconDrawItem> compassIcon_ {};
bool compassIconDirty_ {false};
double lastBearing_ {0.0};
double lastWidth_ {0.0};
double lastHeight_ {0.0};
std::string sweepTimeString_ {}; std::string sweepTimeString_ {};
bool sweepTimeNeedsUpdate_ {true}; bool sweepTimeNeedsUpdate_ {true};
bool sweepTimePicked_ {false}; bool sweepTimePicked_ {false};
@ -67,6 +83,7 @@ OverlayLayer::OverlayLayer(std::shared_ptr<MapContext> context) :
{ {
AddDrawItem(p->activeBoxOuter_); AddDrawItem(p->activeBoxOuter_);
AddDrawItem(p->activeBoxInner_); AddDrawItem(p->activeBoxInner_);
AddDrawItem(p->geoIcons_);
AddDrawItem(p->icons_); AddDrawItem(p->icons_);
p->activeBoxOuter_->SetPosition(0.0f, 0.0f); p->activeBoxOuter_->SetPosition(0.0f, 0.0f);
@ -93,18 +110,68 @@ void OverlayLayer::Initialize()
p->currentPosition_ = p->positionManager_->position(); p->currentPosition_ = p->positionManager_->position();
auto coordinate = p->currentPosition_.coordinate(); auto coordinate = p->currentPosition_.coordinate();
p->icons_->StartIconSheets(); // Geo Icons
p->icons_->AddIconSheet(p->locationIconName_); p->geoIcons_->StartIconSheets();
p->icons_->FinishIconSheets(); p->geoIcons_->AddIconSheet(p->locationIconName_);
p->geoIcons_->FinishIconSheets();
p->icons_->StartIcons(); p->geoIcons_->StartIcons();
p->locationIcon_ = p->icons_->AddIcon(); p->locationIcon_ = p->geoIcons_->AddIcon();
gl::draw::GeoIcons::SetIconTexture( gl::draw::GeoIcons::SetIconTexture(
p->locationIcon_, p->locationIconName_, 0); p->locationIcon_, p->locationIconName_, 0);
gl::draw::GeoIcons::SetIconAngle(p->locationIcon_, gl::draw::GeoIcons::SetIconAngle(p->locationIcon_,
units::angle::degrees<double> {45.0}); units::angle::degrees<double> {45.0});
gl::draw::GeoIcons::SetIconLocation( gl::draw::GeoIcons::SetIconLocation(
p->locationIcon_, coordinate.latitude(), coordinate.longitude()); p->locationIcon_, coordinate.latitude(), coordinate.longitude());
p->geoIcons_->FinishIcons();
// Icons
p->icons_->StartIconSheets();
p->icons_->AddIconSheet(p->cardinalPointIconName_);
p->icons_->AddIconSheet(p->compassIconName_);
p->icons_->FinishIconSheets();
p->icons_->StartIcons();
p->compassIcon_ = p->icons_->AddIcon();
gl::draw::Icons::SetIconTexture(
p->compassIcon_, p->cardinalPointIconName_, 0);
gl::draw::Icons::RegisterEventHandler(
p->compassIcon_,
[this](QEvent* ev)
{
switch (ev->type())
{
case QEvent::Type::Enter:
gl::draw::Icons::SetIconModulate(
p->compassIcon_,
boost::gil::rgba32f_pixel_t {1.5f, 1.5f, 1.5f, 1.0f});
p->compassIconDirty_ = true;
break;
case QEvent::Type::Leave:
gl::draw::Icons::SetIconModulate(
p->compassIcon_,
boost::gil::rgba32f_pixel_t {1.0f, 1.0f, 1.0f, 1.0f});
p->compassIconDirty_ = true;
break;
case QEvent::Type::MouseButtonPress:
{
QMouseEvent* mouseEvent = reinterpret_cast<QMouseEvent*>(ev);
if (mouseEvent->buttons() == Qt::MouseButton::LeftButton &&
p->lastBearing_ != 0.0)
{
auto map = context()->map().lock();
if (map != nullptr)
{
map->setBearing(0.0);
}
ev->accept();
}
break;
}
}
});
p->icons_->FinishIcons(); p->icons_->FinishIcons();
connect(p->positionManager_.get(), connect(p->positionManager_.get(),
@ -123,7 +190,7 @@ void OverlayLayer::Initialize()
gl::draw::GeoIcons::SetIconLocation(p->locationIcon_, gl::draw::GeoIcons::SetIconLocation(p->locationIcon_,
coordinate.latitude(), coordinate.latitude(),
coordinate.longitude()); coordinate.longitude());
p->icons_->FinishIcons(); p->geoIcons_->FinishIcons();
Q_EMIT NeedsRendering(); Q_EMIT NeedsRendering();
} }
p->currentPosition_ = position; p->currentPosition_ = position;
@ -176,9 +243,40 @@ void OverlayLayer::Render(
} }
// Location Icon // Location Icon
p->icons_->SetVisible(p->currentPosition_.isValid() && p->geoIcons_->SetVisible(p->currentPosition_.isValid() &&
p->positionManager_->IsLocationTracked()); p->positionManager_->IsLocationTracked());
// Compass Icon
if (params.width != p->lastWidth_ || params.height != p->lastHeight_)
{
gl::draw::Icons::SetIconLocation(
p->compassIcon_, params.width - 24, params.height - 48);
p->compassIconDirty_ = true;
}
if (params.bearing != p->lastBearing_)
{
if (params.bearing == 0.0)
{
gl::draw::Icons::SetIconTexture(
p->compassIcon_, p->cardinalPointIconName_, 0);
gl::draw::Icons::SetIconAngle(p->compassIcon_,
units::angle::degrees<double> {0.0});
}
else
{
gl::draw::Icons::SetIconTexture(
p->compassIcon_, p->compassIconName_, 0);
gl::draw::Icons::SetIconAngle(
p->compassIcon_,
units::angle::degrees<double> {-45 - params.bearing});
}
p->compassIconDirty_ = true;
}
if (p->compassIconDirty_)
{
p->icons_->FinishIcons();
}
DrawLayer::Render(params); DrawLayer::Render(params);
if (radarProductView != nullptr) if (radarProductView != nullptr)
@ -242,6 +340,10 @@ void OverlayLayer::Render(
ImGui::End(); ImGui::End();
} }
p->lastWidth_ = params.width;
p->lastHeight_ = params.height;
p->lastBearing_ = params.bearing;
SCWX_GL_CHECK_ERROR(); SCWX_GL_CHECK_ERROR();
} }