mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 08:30:04 +00:00 
			
		
		
		
	Calculate distance to each radar site from current location
This commit is contained in:
		
							parent
							
								
									6e7a13494a
								
							
						
					
					
						commit
						3a4819aeff
					
				
					 7 changed files with 192 additions and 70 deletions
				
			
		|  | @ -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,46 +334,87 @@ void MainWindowImpl::ConfigureMapLayout() | |||
| 
 | ||||
| void MainWindowImpl::ConnectMapSignals() | ||||
| { | ||||
|    std::for_each(maps_.cbegin(), | ||||
|                  maps_.cend(), | ||||
|                  [&](auto& mapWidget) | ||||
|                  { | ||||
|                     connect(mapWidget, | ||||
|                             &map::MapWidget::MapParametersChanged, | ||||
|                             this, | ||||
|                             &MainWindowImpl::UpdateMapParameters); | ||||
|    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, | ||||
|                        &map::MapWidget::RadarSweepUpdated, | ||||
|                        this, | ||||
|                        [&]() | ||||
|                        { | ||||
|                           if (mapWidget == activeMap_) | ||||
|                           { | ||||
|                              UpdateRadarProductSelection( | ||||
|                                 mapWidget->GetRadarProductGroup(), | ||||
|                                 mapWidget->GetRadarProductName()); | ||||
|                              UpdateRadarProductSettings(); | ||||
|                              UpdateRadarSite(); | ||||
|                              UpdateVcp(); | ||||
|                           } | ||||
|                        }, | ||||
|                        Qt::QueuedConnection); | ||||
|       connect( | ||||
|          mapWidget, | ||||
|          &map::MapWidget::RadarSweepUpdated, | ||||
|          this, | ||||
|          [&]() | ||||
|          { | ||||
|             if (mapWidget == activeMap_) | ||||
|             { | ||||
|                UpdateRadarProductSelection(mapWidget->GetRadarProductGroup(), | ||||
|                                            mapWidget->GetRadarProductName()); | ||||
|                UpdateRadarProductSettings(); | ||||
|                UpdateRadarSite(); | ||||
|                UpdateVcp(); | ||||
|             } | ||||
|          }, | ||||
|          Qt::QueuedConnection); | ||||
| 
 | ||||
|                     connect( | ||||
|                        mapWidget, | ||||
|                        &map::MapWidget::Level3ProductsChanged, | ||||
|                        this, | ||||
|                        [&]() | ||||
|                        { | ||||
|                           if (mapWidget == activeMap_) | ||||
|                           { | ||||
|                              UpdateAvailableLevel3Products(); | ||||
|                           } | ||||
|                        }, | ||||
|                        Qt::QueuedConnection); | ||||
|                  }); | ||||
|       connect( | ||||
|          mapWidget, | ||||
|          &map::MapWidget::Level3ProductsChanged, | ||||
|          this, | ||||
|          [&]() | ||||
|          { | ||||
|             if (mapWidget == activeMap_) | ||||
|             { | ||||
|                UpdateAvailableLevel3Products(); | ||||
|             } | ||||
|          }, | ||||
|          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) | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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)); | ||||
|    } | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat