diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp index 42d59624..88e8f232 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp @@ -61,6 +61,24 @@ public: PlacefileManager::PlacefileManager() : p(std::make_unique(this)) {} PlacefileManager::~PlacefileManager() = default; +std::vector> +PlacefileManager::GetActivePlacefiles() +{ + std::vector> placefiles; + + std::shared_lock lock {p->placefileRecordLock_}; + + for (const auto& record : p->placefileRecords_) + { + if (record->enabled_) + { + placefiles.emplace_back(record->placefile_); + } + } + + return placefiles; +} + void PlacefileManager::LoadFile(const std::string& filename) { logger_->debug("LoadFile: {}", filename); diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp index 1a61d65d..55be1e90 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp @@ -1,7 +1,6 @@ #pragma once -#include -#include +#include #include @@ -20,6 +19,13 @@ public: explicit PlacefileManager(); ~PlacefileManager(); + /** + * @brief Gets a list of active placefiles + * + * @return Vector of placefile pointers + */ + std::vector> GetActivePlacefiles(); + void LoadFile(const std::string& filename); static std::shared_ptr Instance(); diff --git a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp index 76578e66..9db91381 100644 --- a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp @@ -1,8 +1,12 @@ #include +#include +#include +#include #include #include #include +#include namespace scwx { @@ -20,13 +24,21 @@ public: explicit Impl(std::shared_ptr context) {}; ~Impl() = default; - void RenderText(const std::string& text, - const std::string& hoverText, - boost::gil::rgba8_pixel_t color, - float x, - float y); + void RenderPlace(const QMapLibreGL::CustomLayerRenderParameters& params, + std::shared_ptr place); + + void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params, + const std::string& text, + const std::string& hoverText, + boost::gil::rgba8_pixel_t color, + float x, + float y); std::uint32_t textId_ {}; + glm::vec2 mapScreenCoordLocation_ {}; + float mapScale_ {1.0f}; + float halfWidth_ {}; + float halfHeight_ {}; }; PlacefileLayer::PlacefileLayer(std::shared_ptr context) : @@ -43,14 +55,43 @@ void PlacefileLayer::Initialize() DrawLayer::Initialize(); } -void PlacefileLayer::Impl::RenderText(const std::string& text, - const std::string& hoverText, - boost::gil::rgba8_pixel_t color, - float x, - float y) +void PlacefileLayer::Impl::RenderPlace( + const QMapLibreGL::CustomLayerRenderParameters& params, + std::shared_ptr place) +{ + auto distance = util::GeographicLib::GetDistance( + params.latitude, params.longitude, place->latitude_, place->longitude_); + + if (distance < place->threshold_) + { + const auto screenCoordinates = + (util::maplibre::LatLongToScreenCoordinate( + {place->latitude_, place->longitude_}) - + mapScreenCoordLocation_) * + mapScale_; + + RenderText(params, + place->text_, + "", + place->color_, + screenCoordinates.x + place->x_ + halfWidth_, + screenCoordinates.y + place->y_ + halfHeight_); + } +} + +void PlacefileLayer::Impl::RenderText( + const QMapLibreGL::CustomLayerRenderParameters& params, + const std::string& text, + const std::string& hoverText, + boost::gil::rgba8_pixel_t color, + float x, + float y) { const std::string windowName {fmt::format("PlacefileText-{}", ++textId_)}; + // Convert screen to ImGui coordinates + y = params.height - y; + // Setup "window" to hold text ImGui::SetNextWindowPos( ImVec2 {x, y}, ImGuiCond_Always, ImVec2 {0.5f, 0.5f}); @@ -87,7 +128,33 @@ void PlacefileLayer::Render( // Reset text ID per frame p->textId_ = 0; + // Update map screen coordinate and scale information + p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( + {params.latitude, params.longitude}); + p->mapScale_ = std::pow(2.0, params.zoom) * mbgl::util::tileSize_D / + mbgl::util::DEGREES_MAX; + p->halfWidth_ = params.width * 0.5f; + p->halfHeight_ = params.height * 0.5f; + + std::shared_ptr placefileManager = + manager::PlacefileManager::Instance(); + // Render text + for (auto& placefile : placefileManager->GetActivePlacefiles()) + { + for (auto& drawItem : placefile->GetDrawItems()) + { + switch (drawItem->itemType_) + { + case gr::Placefile::ItemType::Place: + p->RenderPlace( + params, + std::static_pointer_cast( + drawItem)); + break; + } + } + } SCWX_GL_CHECK_ERROR(); } diff --git a/wxdata/include/scwx/gr/placefile.hpp b/wxdata/include/scwx/gr/placefile.hpp index c7f1335a..91f8cb28 100644 --- a/wxdata/include/scwx/gr/placefile.hpp +++ b/wxdata/include/scwx/gr/placefile.hpp @@ -6,6 +6,8 @@ #include #include +#include +#include namespace scwx { @@ -33,8 +35,46 @@ public: Placefile(Placefile&&) noexcept; Placefile& operator=(Placefile&&) noexcept; + enum class ItemType + { + Place, + Icon, + Font, + Text, + Line, + Triangles, + Image, + Polygon, + Unknown + }; + + struct DrawItem + { + ItemType itemType_ {ItemType::Unknown}; + boost::units::quantity threshold_ {}; + }; + + struct PlaceDrawItem : DrawItem + { + PlaceDrawItem() { itemType_ = ItemType::Place; } + + boost::gil::rgba8_pixel_t color_ {}; + double latitude_ {}; + double longitude_ {}; + double x_ {}; + double y_ {}; + std::string text_ {}; + }; + bool IsValid() const; + /** + * @brief Gets the list of draw items defined in the placefile + * + * @return vector of draw item pointers + */ + std::vector> GetDrawItems(); + static std::shared_ptr Load(const std::string& filename); static std::shared_ptr Load(std::istream& is); diff --git a/wxdata/source/scwx/gr/placefile.cpp b/wxdata/source/scwx/gr/placefile.cpp index e6fb1a6f..2622f143 100644 --- a/wxdata/source/scwx/gr/placefile.cpp +++ b/wxdata/source/scwx/gr/placefile.cpp @@ -10,8 +10,6 @@ #include #include -#include -#include namespace scwx { @@ -42,21 +40,6 @@ public: double y_ {}; }; - struct DrawItem - { - boost::units::quantity threshold_ {}; - }; - - struct PlaceDrawItem : DrawItem - { - boost::gil::rgba8_pixel_t color_ {}; - double latitude_ {}; - double longitude_ {}; - double x_ {}; - double y_ {}; - std::string text_ {}; - }; - void ParseLocation(const std::string& latitudeToken, const std::string& longitudeToken, double& latitude, @@ -93,6 +76,11 @@ bool Placefile::IsValid() const return p->drawItems_.size() > 0; } +std::vector> Placefile::GetDrawItems() +{ + return p->drawItems_; +} + std::shared_ptr Placefile::Load(const std::string& filename) { logger_->debug("Loading placefile: {}", filename);