From a0701df13fba7c0d4e896a44e435137d95c18861 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 17 Feb 2024 08:47:15 -0600 Subject: [PATCH] Add ticks to linked vectors --- .../source/scwx/qt/gl/draw/linked_vectors.cpp | 95 +++++++++++++++++-- .../source/scwx/qt/util/geographic_lib.cpp | 17 ++++ .../source/scwx/qt/util/geographic_lib.hpp | 17 +++- 3 files changed, 120 insertions(+), 9 deletions(-) diff --git a/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp index 6843477a..2d59b524 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/linked_vectors.cpp @@ -69,6 +69,10 @@ public: std::vector> vectorList_ {}; std::shared_ptr geoLines_; + + bool ticksEnabled_ {false}; + units::length::nautical_miles tickRadius_ {1.0}; + units::length::nautical_miles tickRadiusIncrement_ {1.0}; }; LinkedVectors::LinkedVectors(std::shared_ptr context) : @@ -179,14 +183,19 @@ void LinkedVectors::FinishVectors() { for (auto& di : p->vectorList_) { + auto tickRadius = p->tickRadius_; + 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_; + const common::Coordinate& coordinate1 = di->coordinates_[i]; + const common::Coordinate& coordinate2 = di->coordinates_[i + 1]; + + const double& latitude1 = coordinate1.latitude_; + const double& longitude1 = coordinate1.longitude_; + const double& latitude2 = coordinate2.latitude_; + const double& longitude2 = coordinate2.longitude_; GeoLines::SetLineLocation( borderLine, latitude1, longitude1, latitude2, longitude2); @@ -197,6 +206,36 @@ void LinkedVectors::FinishVectors() GeoLines::SetLineHoverText(borderLine, di->hoverText_); di->borderDrawItems_.emplace_back(std::move(borderLine)); + + if (p->ticksEnabled_) + { + auto angle = util::GeographicLib::GetAngle( + latitude1, longitude1, latitude2, longitude2); + auto angle1 = angle + units::angle::degrees(90.0); + auto angle2 = angle - units::angle::degrees(90.0); + + auto tickCoord1 = util::GeographicLib::GetCoordinate( + coordinate2, angle1, tickRadius); + auto tickCoord2 = util::GeographicLib::GetCoordinate( + coordinate2, angle2, tickRadius); + + const double& tickLat1 = tickCoord1.latitude_; + const double& tickLon1 = tickCoord1.longitude_; + const double& tickLat2 = tickCoord2.latitude_; + const double& tickLon2 = tickCoord2.longitude_; + + auto tickBorderLine = p->geoLines_->AddLine(); + + GeoLines::SetLineLocation( + tickBorderLine, tickLat1, tickLon1, tickLat2, tickLon2); + + GeoLines::SetLineModulate(tickBorderLine, kBlack); + GeoLines::SetLineWidth(tickBorderLine, di->width_ + 2.0f); + GeoLines::SetLineVisible(tickBorderLine, di->visible_); + GeoLines::SetLineHoverText(tickBorderLine, di->hoverText_); + + tickRadius += p->tickRadiusIncrement_; + } } } } @@ -204,14 +243,19 @@ void LinkedVectors::FinishVectors() // Generate geo lines for (auto& di : p->vectorList_) { + auto tickRadius = p->tickRadius_; + 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_; + const common::Coordinate& coordinate1 = di->coordinates_[i]; + const common::Coordinate& coordinate2 = di->coordinates_[i + 1]; + + const double& latitude1 = coordinate1.latitude_; + const double& longitude1 = coordinate1.longitude_; + const double& latitude2 = coordinate2.latitude_; + const double& longitude2 = coordinate2.longitude_; GeoLines::SetLineLocation( geoLine, latitude1, longitude1, latitude2, longitude2); @@ -227,6 +271,41 @@ void LinkedVectors::FinishVectors() } di->lineDrawItems_.emplace_back(std::move(geoLine)); + + if (p->ticksEnabled_) + { + auto angle = util::GeographicLib::GetAngle( + latitude1, longitude1, latitude2, longitude2); + auto angle1 = angle + units::angle::degrees(90.0); + auto angle2 = angle - units::angle::degrees(90.0); + + auto tickCoord1 = util::GeographicLib::GetCoordinate( + coordinate2, angle1, tickRadius); + auto tickCoord2 = util::GeographicLib::GetCoordinate( + coordinate2, angle2, tickRadius); + + const double& tickLat1 = tickCoord1.latitude_; + const double& tickLon1 = tickCoord1.longitude_; + const double& tickLat2 = tickCoord2.latitude_; + const double& tickLon2 = tickCoord2.longitude_; + + auto tickGeoLine = p->geoLines_->AddLine(); + + GeoLines::SetLineLocation( + tickGeoLine, tickLat1, tickLon1, tickLat2, tickLon2); + + GeoLines::SetLineModulate(tickGeoLine, di->modulate_); + GeoLines::SetLineWidth(tickGeoLine, di->width_); + GeoLines::SetLineVisible(tickGeoLine, di->visible_); + + // If the border is not enabled, this line must have hover text + if (!p->borderEnabled_) + { + GeoLines::SetLineHoverText(tickGeoLine, di->hoverText_); + } + + tickRadius += p->tickRadiusIncrement_; + } } } diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 20323eb8..89466975 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -92,6 +92,23 @@ GetAngle(double lat1, double lon1, double lat2, double lon2) return units::angle::degrees {azi1}; } +common::Coordinate GetCoordinate(const common::Coordinate& center, + units::angle::degrees angle, + units::length::meters distance) +{ + double latitude; + double longitude; + + DefaultGeodesic().Direct(center.latitude_, + center.longitude_, + angle.value(), + distance.value(), + latitude, + longitude); + + return {latitude, longitude}; +} + common::Coordinate GetCoordinate(const common::Coordinate& center, units::meters i, units::meters j) diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp index 7f3f64bd..30f7a63c 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp @@ -49,13 +49,28 @@ bool AreaContainsPoint(const std::vector& area, units::angle::degrees GetAngle(double lat1, double lon1, double lat2, double lon2); +/** + * Get a coordinate from a polar coordinate offset. + * + * @param [in] center The center coordinate from which the angle and distance + * are given + * @param [in] angle The angle at which the destination coordinate lies + * @param [in] distance The distance from the center coordinate to the + * destination coordinate + * + * @return offset coordinate + */ +common::Coordinate GetCoordinate(const common::Coordinate& center, + units::angle::degrees angle, + units::length::meters distance); + /** * Get a coordinate from an (i, j) offset. * * @param [in] center The center coordinate from which i and j are offset * @param [in] i The easting offset in meters * @param [in] j The northing offset in meters - * + * * @return offset coordinate */ common::Coordinate GetCoordinate(const common::Coordinate& center,