From 58c7b9accbdfc01b6b78e818f81bd3c582f7c738 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 10 Feb 2024 00:11:19 -0600 Subject: [PATCH] Initial LinkedVectors draw item implementation --- scwx-qt/scwx-qt.cmake | 2 + scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp | 11 + .../source/scwx/qt/gl/draw/linked_vectors.cpp | 249 ++++++++++++++++++ .../source/scwx/qt/gl/draw/linked_vectors.hpp | 147 +++++++++++ 4 files changed, 409 insertions(+) create mode 100644 scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp create mode 100644 scwx-qt/source/scwx/qt/gl/draw/linked_vectors.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index a90645e9..475b69c8 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -63,6 +63,7 @@ set(HDR_GL_DRAW source/scwx/qt/gl/draw/draw_item.hpp source/scwx/qt/gl/draw/geo_icons.hpp source/scwx/qt/gl/draw/geo_lines.hpp source/scwx/qt/gl/draw/icons.hpp + source/scwx/qt/gl/draw/linked_vectors.hpp source/scwx/qt/gl/draw/placefile_icons.hpp source/scwx/qt/gl/draw/placefile_images.hpp source/scwx/qt/gl/draw/placefile_lines.hpp @@ -74,6 +75,7 @@ set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp source/scwx/qt/gl/draw/geo_icons.cpp source/scwx/qt/gl/draw/geo_lines.cpp source/scwx/qt/gl/draw/icons.cpp + source/scwx/qt/gl/draw/linked_vectors.cpp source/scwx/qt/gl/draw/placefile_icons.cpp source/scwx/qt/gl/draw/placefile_images.cpp source/scwx/qt/gl/draw/placefile_lines.cpp diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp index bcf6214b..32125039 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp @@ -123,6 +123,17 @@ GeoLines::~GeoLines() = default; GeoLines::GeoLines(GeoLines&&) noexcept = default; GeoLines& GeoLines::operator=(GeoLines&&) noexcept = default; +void GeoLines::set_selected_time( + std::chrono::system_clock::time_point selectedTime) +{ + p->selectedTime_ = selectedTime; +} + +void GeoLines::set_thresholded(bool thresholded) +{ + p->thresholded_ = thresholded; +} + void GeoLines::Initialize() { gl::OpenGLFunctions& gl = p->context_->gl(); diff --git a/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp new file mode 100644 index 00000000..00bcd3e3 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp @@ -0,0 +1,249 @@ +#include +#include +#include +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace gl +{ +namespace draw +{ + +static const std::string logPrefix_ = "scwx::qt::gl::draw::linked_vectors"; + +static const boost::gil::rgba32f_pixel_t kBlack {0.0f, 0.0f, 0.0f, 1.0f}; + +struct LinkedVectorDrawItem +{ + LinkedVectorDrawItem( + const common::Coordinate& center, + const std::shared_ptr& vectorPacket) + { + coordinates_.push_back(util::GeographicLib::GetCoordinate( + center, vectorPacket->start_i_km(), vectorPacket->start_j_km())); + + const auto endI = vectorPacket->end_i_km(); + const auto endJ = vectorPacket->end_j_km(); + + std::for_each( + boost::make_zip_iterator( + boost::make_tuple(endI.begin(), endJ.begin())), + boost::make_zip_iterator(boost::make_tuple(endI.end(), endJ.end())), + [this, ¢er](const auto& p) + { + coordinates_.push_back(util::GeographicLib::GetCoordinate( + center, p.get<0>(), p.get<1>())); + }); + } + + std::vector> borderDrawItems_ {}; + std::vector> lineDrawItems_ {}; + + std::vector coordinates_ {}; + + boost::gil::rgba32f_pixel_t modulate_ {1.0f, 1.0f, 1.0f, 1.0f}; + float width_ {5.0f}; + bool visible_ {true}; + std::string hoverText_ {}; +}; + +class LinkedVectors::Impl +{ +public: + explicit Impl(std::shared_ptr context) : + context_ {context}, geoLines_ {std::make_shared(context)} + { + } + + ~Impl() {} + + std::shared_ptr context_; + + bool borderEnabled_ {true}; + bool visible_ {true}; + + std::vector> vectorList_ {}; + std::shared_ptr geoLines_; +}; + +LinkedVectors::LinkedVectors(std::shared_ptr context) : + DrawItem(context->gl()), p(std::make_unique(context)) +{ +} +LinkedVectors::~LinkedVectors() = default; + +LinkedVectors::LinkedVectors(LinkedVectors&&) noexcept = default; +LinkedVectors& LinkedVectors::operator=(LinkedVectors&&) noexcept = default; + +void LinkedVectors::set_selected_time( + std::chrono::system_clock::time_point selectedTime) +{ + p->geoLines_->set_selected_time(selectedTime); +} + +void LinkedVectors::set_thresholded(bool thresholded) +{ + p->geoLines_->set_thresholded(thresholded); +} + +void LinkedVectors::Initialize() +{ + p->geoLines_->Initialize(); +} + +void LinkedVectors::Render( + const QMapLibreGL::CustomLayerRenderParameters& params) +{ + if (!p->visible_) + { + return; + } + + p->geoLines_->Render(params); +} + +void LinkedVectors::Deinitialize() +{ + p->geoLines_->Deinitialize(); +} + +void LinkedVectors::SetBorderEnabled(bool enabled) +{ + p->borderEnabled_ = enabled; +} + +void LinkedVectors::SetVisible(bool visible) +{ + p->visible_ = visible; +} + +void LinkedVectors::StartVectors() +{ + // Start a new set of geo lines + p->geoLines_->StartLines(); +} + +std::shared_ptr LinkedVectors::AddVector( + const common::Coordinate& center, + const std::shared_ptr& vectorPacket) +{ + return p->vectorList_.emplace_back( + std::make_shared(center, vectorPacket)); +} + +void LinkedVectors::SetVectorModulate( + const std::shared_ptr& di, + boost::gil::rgba8_pixel_t modulate) +{ + di->modulate_ = {modulate[0] / 255.0f, + modulate[1] / 255.0f, + modulate[2] / 255.0f, + modulate[3] / 255.0f}; +} + +void LinkedVectors::SetVectorModulate( + const std::shared_ptr& di, + boost::gil::rgba32f_pixel_t modulate) +{ + di->modulate_ = modulate; +} + +void LinkedVectors::SetVectorWidth( + const std::shared_ptr& di, float width) +{ + di->width_ = width; +} + +void LinkedVectors::SetVectorVisible( + const std::shared_ptr& di, bool visible) +{ + di->visible_ = visible; +} + +void LinkedVectors::SetVectorHoverText( + const std::shared_ptr& di, const std::string& text) +{ + di->hoverText_ = text; +} + +void LinkedVectors::FinishVectors() +{ + // Generate borders + if (p->borderEnabled_) + { + for (auto& di : p->vectorList_) + { + for (std::size_t i = 0; i < di->coordinates_.size() - 1; ++i) + { + auto borderLine = p->geoLines_->AddLine(); + + const double& latitude1 = di->coordinates_[i].latitude_; + const double& longitude1 = di->coordinates_[i].longitude_; + const double& latitude2 = di->coordinates_[i + 1].latitude_; + const double& longitude2 = di->coordinates_[i + 1].longitude_; + + GeoLines::SetLineLocation( + borderLine, latitude1, longitude1, latitude2, longitude2); + + GeoLines::SetLineModulate(borderLine, kBlack); + GeoLines::SetLineWidth(borderLine, di->width_ + 2.0f); + GeoLines::SetLineVisible(borderLine, di->visible_); + + di->borderDrawItems_.emplace_back(std::move(borderLine)); + } + } + } + + // Generate geo lines + for (auto& di : p->vectorList_) + { + for (std::size_t i = 0; i < di->coordinates_.size() - 1; ++i) + { + auto geoLine = p->geoLines_->AddLine(); + + const double& latitude1 = di->coordinates_[i].latitude_; + const double& longitude1 = di->coordinates_[i].longitude_; + const double& latitude2 = di->coordinates_[i + 1].latitude_; + const double& longitude2 = di->coordinates_[i + 1].longitude_; + + GeoLines::SetLineLocation( + geoLine, latitude1, longitude1, latitude2, longitude2); + + GeoLines::SetLineModulate(geoLine, di->modulate_); + GeoLines::SetLineWidth(geoLine, di->width_); + GeoLines::SetLineVisible(geoLine, di->visible_); + GeoLines::SetLineHoverText(geoLine, di->hoverText_); + + di->lineDrawItems_.emplace_back(std::move(geoLine)); + } + } + + // Finish geo lines + p->geoLines_->FinishLines(); +} + +bool LinkedVectors::RunMousePicking( + const QMapLibreGL::CustomLayerRenderParameters& params, + const QPointF& mouseLocalPos, + const QPointF& mouseGlobalPos, + const glm::vec2& mouseCoords, + const common::Coordinate& mouseGeoCoords, + std::shared_ptr& eventHandler) +{ + return p->geoLines_->RunMousePicking(params, + mouseLocalPos, + mouseGlobalPos, + mouseCoords, + mouseGeoCoords, + eventHandler); +} + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.hpp b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.hpp new file mode 100644 index 00000000..2dd9c898 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.hpp @@ -0,0 +1,147 @@ +#pragma once + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class LinkedVectorPacket; + +} // namespace rpg +} // namespace wsr88d + +namespace qt +{ +namespace gl +{ +namespace draw +{ + +struct LinkedVectorDrawItem; + +class LinkedVectors : public DrawItem +{ +public: + explicit LinkedVectors(std::shared_ptr context); + ~LinkedVectors(); + + LinkedVectors(const LinkedVectors&) = delete; + LinkedVectors& operator=(const LinkedVectors&) = delete; + + LinkedVectors(LinkedVectors&&) noexcept; + LinkedVectors& operator=(LinkedVectors&&) noexcept; + + void set_selected_time(std::chrono::system_clock::time_point selectedTime); + void set_thresholded(bool thresholded); + + void Initialize() override; + void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; + void Deinitialize() override; + + bool + RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, + const QPointF& mouseLocalPos, + const QPointF& mouseGlobalPos, + const glm::vec2& mouseCoords, + const common::Coordinate& mouseGeoCoords, + std::shared_ptr& eventHandler) override; + + /** + * Enables or disables the border around each line in a linked vector. + * + * @param [in] enabled Border visibility + */ + void SetBorderEnabled(bool enabled); + + /** + * Sets the visibility of the linked vectors. + * + * @param [in] visible Line visibility + */ + void SetVisible(bool visible); + + /** + * Resets and prepares the draw item for adding a new set of linked vectors. + */ + void StartVectors(); + + /** + * Adds a linked vector to the internal draw list. + * + * @param [in] center Center coordinate on which the linked vectors are based + * @param [in] vectorPacket Linked vector packet containing start and end + * points + * + * @return Linked vector draw item + */ + std::shared_ptr AddVector( + const common::Coordinate& center, + const std::shared_ptr& vectorPacket); + + /** + * Sets the modulate color of a linked vector. + * + * @param [in] di Linked vector draw item + * @param [in] modulate Modulate color + */ + static void + SetVectorModulate(const std::shared_ptr& di, + boost::gil::rgba8_pixel_t color); + + /** + * Sets the modulate color of a linked vector. + * + * @param [in] di Linked vector draw item + * @param [in] modulate Modulate color + */ + static void + SetVectorModulate(const std::shared_ptr& di, + boost::gil::rgba32f_pixel_t modulate); + + /** + * Sets the width of the linked vector. + * + * @param [in] width Width in pixels + */ + static void SetVectorWidth(const std::shared_ptr& di, + float width); + + /** + * Sets the visibility of the linked vector. + * + * @param [in] visible + */ + static void SetVectorVisible(const std::shared_ptr& di, + bool visible); + + /** + * Sets the hover text of a linked vector. + * + * @param [in] di Linked vector draw item + * @param [in] text Hover text + */ + static void + SetVectorHoverText(const std::shared_ptr& di, + const std::string& text); + + /** + * Finalizes the draw item after adding new linked vectors. + */ + void FinishVectors(); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx