From 6e7a13494a9dcb98c75aefa8eb5594c018311b08 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 7 Oct 2022 22:29:30 -0500 Subject: [PATCH] Updating radar site display fields to be more human-friendly - Latitude/longitude in degrees N/S/E/W - Radar types with hyphens - Sort by raw decimal values --- scwx-qt/scwx-qt.cmake | 3 + scwx-qt/source/scwx/qt/common/types.hpp | 19 +++++ scwx-qt/source/scwx/qt/config/radar_site.cpp | 16 ++++ scwx-qt/source/scwx/qt/config/radar_site.hpp | 1 + .../source/scwx/qt/model/radar_site_model.cpp | 27 ++++++- .../source/scwx/qt/ui/radar_site_dialog.cpp | 2 + wxdata/include/scwx/common/characters.hpp | 11 +++ wxdata/include/scwx/common/geographic.hpp | 15 ++++ wxdata/source/scwx/common/characters.cpp | 16 ++++ wxdata/source/scwx/common/geographic.cpp | 77 +++++++++++++++++++ wxdata/wxdata.cmake | 4 +- 11 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/common/types.hpp create mode 100644 wxdata/source/scwx/common/characters.cpp create mode 100644 wxdata/source/scwx/common/geographic.cpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 6aa180b5..58583a06 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -38,6 +38,7 @@ set(SRC_EXE_MAIN source/scwx/qt/main/main.cpp) set(HDR_MAIN source/scwx/qt/main/main_window.hpp) set(SRC_MAIN source/scwx/qt/main/main_window.cpp) set(UI_MAIN source/scwx/qt/main/main_window.ui) +set(HDR_COMMON source/scwx/qt/common/types.hpp) set(HDR_CONFIG source/scwx/qt/config/radar_site.hpp) set(SRC_CONFIG source/scwx/qt/config/radar_site.cpp) set(SRC_EXTERNAL source/scwx/qt/external/stb_rect_pack.cpp) @@ -153,6 +154,7 @@ set(TS_FILES ts/scwx_en_US.ts) set(PROJECT_SOURCES ${HDR_MAIN} ${SRC_MAIN} + ${HDR_COMMON} ${HDR_CONFIG} ${SRC_CONFIG} ${SRC_EXTERNAL} @@ -189,6 +191,7 @@ set(EXECUTABLE_SOURCES ${SRC_EXE_MAIN}) source_group("Header Files\\main" FILES ${HDR_MAIN}) source_group("Source Files\\main" FILES ${SRC_MAIN}) +source_group("Header Files\\common" FILES ${HDR_COMMON}) source_group("Header Files\\config" FILES ${HDR_CONFIG}) source_group("Source Files\\config" FILES ${SRC_CONFIG}) source_group("Source Files\\external" FILES ${SRC_EXTERNAL}) diff --git a/scwx-qt/source/scwx/qt/common/types.hpp b/scwx-qt/source/scwx/qt/common/types.hpp new file mode 100644 index 00000000..1347e2e4 --- /dev/null +++ b/scwx-qt/source/scwx/qt/common/types.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace scwx +{ +namespace qt +{ +namespace common +{ + +enum ItemDataRole +{ + SortRole = Qt::UserRole +}; + +} // namespace common +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/config/radar_site.cpp b/scwx-qt/source/scwx/qt/config/radar_site.cpp index e275fb64..1e82f3de 100644 --- a/scwx-qt/source/scwx/qt/config/radar_site.cpp +++ b/scwx-qt/source/scwx/qt/config/radar_site.cpp @@ -20,6 +20,9 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); static const std::string defaultRadarSiteFile_ = ":/res/config/radar_sites.json"; +static const std::unordered_map typeNameMap_ { + {"wsr88d", "WSR-88D"}, {"tdwr", "TDWR"}, {"?", "?"}}; + static std::unordered_map> radarSiteMap_; static std::unordered_map siteIdMap_; @@ -63,6 +66,19 @@ std::string RadarSite::type() const return p->type_; } +std::string RadarSite::type_name() const +{ + auto it = typeNameMap_.find(p->type_); + if (it != typeNameMap_.cend()) + { + return it->second; + } + else + { + return typeNameMap_.at("?"); + } +} + std::string RadarSite::id() const { return p->id_; diff --git a/scwx-qt/source/scwx/qt/config/radar_site.hpp b/scwx-qt/source/scwx/qt/config/radar_site.hpp index 548772b8..279e8c13 100644 --- a/scwx-qt/source/scwx/qt/config/radar_site.hpp +++ b/scwx-qt/source/scwx/qt/config/radar_site.hpp @@ -26,6 +26,7 @@ public: RadarSite& operator=(RadarSite&&) noexcept; std::string type() const; + std::string type_name() const; std::string id() const; double latitude() const; double longitude() const; diff --git a/scwx-qt/source/scwx/qt/model/radar_site_model.cpp b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp index 961ac430..74491cc0 100644 --- a/scwx-qt/source/scwx/qt/model/radar_site_model.cpp +++ b/scwx-qt/source/scwx/qt/model/radar_site_model.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include #include namespace scwx @@ -42,7 +44,8 @@ int RadarSiteModel::columnCount(const QModelIndex& parent) const QVariant RadarSiteModel::data(const QModelIndex& index, int role) const { if (index.isValid() && index.row() >= 0 && - index.row() < p->radarSites_.size() && role == Qt::DisplayRole) + index.row() < p->radarSites_.size() && + (role == Qt::DisplayRole || role == common::SortRole)) { const auto& site = p->radarSites_.at(index.row()); @@ -57,11 +60,27 @@ QVariant RadarSiteModel::data(const QModelIndex& index, int role) const case 3: return QString::fromStdString(site->country()); case 4: - return QString("%1").arg(site->latitude()); + if (role == Qt::DisplayRole) + { + return QString::fromStdString( + scwx::common::GetLatitudeString(site->latitude())); + } + else + { + return site->latitude(); + } case 5: - return QString("%1").arg(site->longitude()); + if (role == Qt::DisplayRole) + { + return QString::fromStdString( + scwx::common::GetLongitudeString(site->longitude())); + } + else + { + return site->longitude(); + } case 6: - return QString::fromStdString(site->type()); + return QString::fromStdString(site->type_name()); default: break; } diff --git a/scwx-qt/source/scwx/qt/ui/radar_site_dialog.cpp b/scwx-qt/source/scwx/qt/ui/radar_site_dialog.cpp index 48953899..79b600a4 100644 --- a/scwx-qt/source/scwx/qt/ui/radar_site_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/radar_site_dialog.cpp @@ -1,6 +1,7 @@ #include "radar_site_dialog.hpp" #include "./ui_radar_site_dialog.h" +#include #include #include @@ -25,6 +26,7 @@ public: proxyModel_ {new QSortFilterProxyModel(self_)} { proxyModel_->setSourceModel(radarSiteModel_); + proxyModel_->setSortRole(common::SortRole); proxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); proxyModel_->setFilterKeyColumn(-1); } diff --git a/wxdata/include/scwx/common/characters.hpp b/wxdata/include/scwx/common/characters.hpp index 896992cf..f958d2fd 100644 --- a/wxdata/include/scwx/common/characters.hpp +++ b/wxdata/include/scwx/common/characters.hpp @@ -1,9 +1,12 @@ #pragma once +#include + namespace scwx { namespace common { + namespace Characters { @@ -11,5 +14,13 @@ constexpr char DEGREE = static_cast(0xb0); constexpr char ETX = static_cast(0x03); } // namespace Characters + +namespace Unicode +{ + +extern const std::string kDegree; + +} // namespace Unicode + } // namespace common } // namespace scwx diff --git a/wxdata/include/scwx/common/geographic.hpp b/wxdata/include/scwx/common/geographic.hpp index 66a9233f..71065109 100644 --- a/wxdata/include/scwx/common/geographic.hpp +++ b/wxdata/include/scwx/common/geographic.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace scwx { namespace common @@ -26,5 +28,18 @@ struct Coordinate } }; +enum class DegreeStringType +{ + Decimal, + DegreesMinutesSeconds +}; + +std::string +GetLatitudeString(double latitude, + DegreeStringType type = DegreeStringType::Decimal); +std::string +GetLongitudeString(double longitude, + DegreeStringType type = DegreeStringType::Decimal); + } // namespace common } // namespace scwx diff --git a/wxdata/source/scwx/common/characters.cpp b/wxdata/source/scwx/common/characters.cpp new file mode 100644 index 00000000..4b7b536d --- /dev/null +++ b/wxdata/source/scwx/common/characters.cpp @@ -0,0 +1,16 @@ +#include + +namespace scwx +{ +namespace common +{ + +namespace Unicode +{ + +const std::string kDegree {"\302\260"}; + +} // namespace Unicode + +} // namespace common +} // namespace scwx diff --git a/wxdata/source/scwx/common/geographic.cpp b/wxdata/source/scwx/common/geographic.cpp new file mode 100644 index 00000000..b1981df1 --- /dev/null +++ b/wxdata/source/scwx/common/geographic.cpp @@ -0,0 +1,77 @@ +#include +#include + +#include + +namespace scwx +{ +namespace common +{ + +static std::string GetDegreeString(double degrees, + DegreeStringType type, + const std::string& suffix); + +std::string GetLatitudeString(double latitude, DegreeStringType type) +{ + std::string suffix {}; + + if (latitude > 0.0) + { + suffix = " N"; + } + else if (latitude < 0.0) + { + suffix = " S"; + } + + return GetDegreeString(latitude, type, suffix); +} + +std::string GetLongitudeString(double longitude, DegreeStringType type) +{ + std::string suffix {}; + + if (longitude > 0.0) + { + suffix = " E"; + } + else if (longitude < 0.0) + { + suffix = " W"; + } + + return GetDegreeString(longitude, type, suffix); +} + +static std::string GetDegreeString(double degrees, + DegreeStringType type, + const std::string& suffix) +{ + std::string degreeString {}; + + degrees = std::fabs(degrees); + + switch (type) + { + case DegreeStringType::Decimal: + degreeString = + std::format("{:.6f}{}{}", degrees, Unicode::kDegree, suffix); + break; + case DegreeStringType::DegreesMinutesSeconds: + { + uint32_t dd = static_cast(degrees); + degrees = (degrees - dd) * 60.0; + uint32_t mm = static_cast(degrees); + double ss = (degrees - mm) * 60.0; + degreeString = std::format( + "{}{} {}' {:.2f}\"{}", dd, Unicode::kDegree, mm, ss, suffix); + break; + } + } + + return degreeString; +} + +} // namespace common +} // namespace scwx diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index 778f74e1..e2234524 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -32,7 +32,9 @@ set(HDR_COMMON include/scwx/common/characters.hpp include/scwx/common/sites.hpp include/scwx/common/types.hpp include/scwx/common/vcp.hpp) -set(SRC_COMMON source/scwx/common/color_table.cpp +set(SRC_COMMON source/scwx/common/characters.cpp + source/scwx/common/color_table.cpp + source/scwx/common/geographic.cpp source/scwx/common/products.cpp source/scwx/common/sites.cpp source/scwx/common/vcp.cpp)