Calculate distance to each radar site from current location

This commit is contained in:
Dan Paulat 2022-10-07 23:48:39 -05:00
parent 6e7a13494a
commit 3a4819aeff
7 changed files with 192 additions and 70 deletions

View file

@ -77,6 +77,7 @@ public:
void ConfigureMapLayout();
void ConnectMapSignals();
void ConnectOtherSignals();
void HandleFocusChange(QWidget* focused);
void SelectElevation(map::MapWidget* mapWidget, float elevation);
void SelectRadarProduct(map::MapWidget* mapWidget,
@ -180,35 +181,7 @@ MainWindow::MainWindow(QWidget* parent) :
}
p->ConnectMapSignals();
connect(qApp,
&QApplication::focusChanged,
this,
[=](QWidget* /*old*/, QWidget* now) { p->HandleFocusChange(now); });
connect(p->level2ProductsWidget_,
&ui::Level2ProductsWidget::RadarProductSelected,
this,
[&](common::RadarProductGroup group,
const std::string& productName,
int16_t productCode) {
p->SelectRadarProduct(
p->activeMap_, group, productName, productCode);
});
connect(p->level3ProductsWidget_,
&ui::Level3ProductsWidget::RadarProductSelected,
this,
[&](common::RadarProductGroup group,
const std::string& productName,
int16_t productCode) {
p->SelectRadarProduct(
p->activeMap_, group, productName, productCode);
});
connect(p->level2SettingsWidget_,
&ui::Level2SettingsWidget::ElevationSelected,
this,
[&](float elevation)
{ p->SelectElevation(p->activeMap_, elevation); });
p->ConnectOtherSignals();
p->HandleFocusChange(p->activeMap_);
}
@ -361,14 +334,24 @@ void MainWindowImpl::ConfigureMapLayout()
void MainWindowImpl::ConnectMapSignals()
{
std::for_each(maps_.cbegin(),
maps_.cend(),
[&](auto& mapWidget)
for (const auto& mapWidget : maps_)
{
connect(mapWidget,
&map::MapWidget::MapParametersChanged,
this,
&MainWindowImpl::UpdateMapParameters);
connect(
mapWidget,
&map::MapWidget::MapParametersChanged,
this,
[&](double latitude, double longitude)
{
if (mapWidget == activeMap_)
{
emit mainWindow_->ActiveMapMoved(latitude, longitude);
}
},
Qt::QueuedConnection);
connect(
mapWidget,
@ -378,8 +361,7 @@ void MainWindowImpl::ConnectMapSignals()
{
if (mapWidget == activeMap_)
{
UpdateRadarProductSelection(
mapWidget->GetRadarProductGroup(),
UpdateRadarProductSelection(mapWidget->GetRadarProductGroup(),
mapWidget->GetRadarProductName());
UpdateRadarProductSettings();
UpdateRadarSite();
@ -400,7 +382,39 @@ void MainWindowImpl::ConnectMapSignals()
}
},
Qt::QueuedConnection);
}
}
void MainWindowImpl::ConnectOtherSignals()
{
connect(qApp,
&QApplication::focusChanged,
mainWindow_,
[=](QWidget* /*old*/, QWidget* now) { HandleFocusChange(now); });
connect(level2ProductsWidget_,
&ui::Level2ProductsWidget::RadarProductSelected,
mainWindow_,
[&](common::RadarProductGroup group,
const std::string& productName,
int16_t productCode) {
SelectRadarProduct(activeMap_, group, productName, productCode);
});
connect(level3ProductsWidget_,
&ui::Level3ProductsWidget::RadarProductSelected,
mainWindow_,
[&](common::RadarProductGroup group,
const std::string& productName,
int16_t productCode) {
SelectRadarProduct(activeMap_, group, productName, productCode);
});
connect(level2SettingsWidget_,
&ui::Level2SettingsWidget::ElevationSelected,
mainWindow_,
[&](float elevation) { SelectElevation(activeMap_, elevation); });
connect(mainWindow_,
&MainWindow::ActiveMapMoved,
radarSiteDialog_,
&ui::RadarSiteDialog::HandleMapUpdate);
}
void MainWindowImpl::HandleFocusChange(QWidget* focused)

View file

@ -28,6 +28,9 @@ public:
void showEvent(QShowEvent* event) override;
signals:
void ActiveMapMoved(double latitude, double longitude);
private slots:
void on_actionOpen_triggered();
void on_actionExit_triggered();

View file

@ -4,6 +4,10 @@
#include <scwx/common/geographic.hpp>
#include <scwx/util/logger.hpp>
#include <format>
#include <GeographicLib/Geodesic.hpp>
namespace scwx
{
namespace qt
@ -14,7 +18,7 @@ namespace model
static const std::string logPrefix_ = "scwx::qt::model::radar_site_model";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
static constexpr size_t kNumColumns = 7u;
static constexpr size_t kNumColumns = 8u;
class RadarSiteModelImpl
{
@ -23,6 +27,12 @@ public:
~RadarSiteModelImpl() = default;
QList<std::shared_ptr<config::RadarSite>> radarSites_;
GeographicLib::Geodesic geodesic_;
std::unordered_map<std::string, double> distanceMap_;
scwx::common::DistanceType distanceDisplay_;
scwx::common::Coordinate previousPosition_;
};
RadarSiteModel::RadarSiteModel(QObject* parent) :
@ -81,6 +91,26 @@ QVariant RadarSiteModel::data(const QModelIndex& index, int role) const
}
case 6:
return QString::fromStdString(site->type_name());
case 7:
if (role == Qt::DisplayRole)
{
if (p->distanceDisplay_ == scwx::common::DistanceType::Miles)
{
return QString("%1 mi").arg(
static_cast<uint32_t>(p->distanceMap_.at(site->id()) *
scwx::common::kMilesPerMeter));
}
else
{
return QString("%1 km").arg(
static_cast<uint32_t>(p->distanceMap_.at(site->id()) *
scwx::common::kKilometersPerMeter));
}
}
else
{
return p->distanceMap_.at(site->id());
}
default:
break;
}
@ -113,6 +143,8 @@ QVariant RadarSiteModel::headerData(int section,
return tr("Longitude");
case 6:
return tr("Type");
case 7:
return tr("Distance");
default:
break;
}
@ -122,7 +154,30 @@ QVariant RadarSiteModel::headerData(int section,
return QVariant();
}
RadarSiteModelImpl::RadarSiteModelImpl() : radarSites_ {}
void RadarSiteModel::HandleMapUpdate(double latitude, double longitude)
{
logger_->trace("Handle map update: {}, {}", latitude, longitude);
double distanceInMeters;
for (const auto& site : p->radarSites_)
{
p->geodesic_.Inverse(latitude,
longitude,
site->latitude(),
site->longitude(),
distanceInMeters);
p->distanceMap_[site->id()] = distanceInMeters;
}
}
RadarSiteModelImpl::RadarSiteModelImpl() :
radarSites_ {},
geodesic_(GeographicLib::Constants::WGS84_a(),
GeographicLib::Constants::WGS84_f()),
distanceMap_ {},
distanceDisplay_ {scwx::common::DistanceType::Miles},
previousPosition_ {}
{
// Get all loaded radar sites
std::vector<std::shared_ptr<config::RadarSite>> radarSites =
@ -131,6 +186,7 @@ RadarSiteModelImpl::RadarSiteModelImpl() : radarSites_ {}
// Setup radar site list
for (auto& site : radarSites)
{
distanceMap_[site->id()] = 0.0;
radarSites_.emplace_back(std::move(site));
}
}

View file

@ -28,6 +28,8 @@ public:
Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
void HandleMapUpdate(double latitude, double longitude);
private:
std::unique_ptr<RadarSiteModelImpl> p;

View file

@ -3,6 +3,7 @@
#include <scwx/qt/common/types.hpp>
#include <scwx/qt/model/radar_site_model.hpp>
#include <scwx/common/geographic.hpp>
#include <scwx/util/logger.hpp>
#include <QSortFilterProxyModel>
@ -23,7 +24,9 @@ public:
explicit RadarSiteDialogImpl(RadarSiteDialog* self) :
self_ {self},
radarSiteModel_ {new model::RadarSiteModel(self_)},
proxyModel_ {new QSortFilterProxyModel(self_)}
proxyModel_ {new QSortFilterProxyModel(self_)},
mapPosition_ {},
mapUpdateDeferred_ {false}
{
proxyModel_->setSourceModel(radarSiteModel_);
proxyModel_->setSortRole(common::SortRole);
@ -35,6 +38,9 @@ public:
RadarSiteDialog* self_;
model::RadarSiteModel* radarSiteModel_;
QSortFilterProxyModel* proxyModel_;
scwx::common::Coordinate mapPosition_;
bool mapUpdateDeferred_;
};
RadarSiteDialog::RadarSiteDialog(QWidget* parent) :
@ -63,6 +69,32 @@ RadarSiteDialog::~RadarSiteDialog()
delete ui;
}
void RadarSiteDialog::showEvent(QShowEvent* event)
{
if (p->mapUpdateDeferred_)
{
p->radarSiteModel_->HandleMapUpdate(p->mapPosition_.latitude_,
p->mapPosition_.longitude_);
p->mapUpdateDeferred_ = false;
}
QDialog::showEvent(event);
}
void RadarSiteDialog::HandleMapUpdate(double latitude, double longitude)
{
p->mapPosition_ = {latitude, longitude};
if (isVisible())
{
p->radarSiteModel_->HandleMapUpdate(latitude, longitude);
}
else
{
p->mapUpdateDeferred_ = true;
}
}
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -24,6 +24,12 @@ public:
explicit RadarSiteDialog(QWidget* parent = nullptr);
~RadarSiteDialog();
protected:
void showEvent(QShowEvent*) override;
public slots:
void HandleMapUpdate(double latitude, double longitude);
private:
std::unique_ptr<RadarSiteDialogImpl> p;
Ui::RadarSiteDialog* ui;

View file

@ -7,6 +7,9 @@ namespace scwx
namespace common
{
constexpr double kMilesPerMeter = 0.00062137119;
constexpr double kKilometersPerMeter = 0.001;
/**
* @brief Coordinate type to hold latitude and longitude of a location.
*/
@ -34,6 +37,12 @@ enum class DegreeStringType
DegreesMinutesSeconds
};
enum class DistanceType
{
Kilometers,
Miles
};
std::string
GetLatitudeString(double latitude,
DegreeStringType type = DegreeStringType::Decimal);