mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:40:06 +00:00 
			
		
		
		
	Create an NMEA position source if configured to do so
This commit is contained in:
		
							parent
							
								
									8270153957
								
							
						
					
					
						commit
						4545d87670
					
				
					 1 changed files with 124 additions and 25 deletions
				
			
		|  | @ -1,7 +1,10 @@ | |||
| #include <scwx/qt/manager/position_manager.hpp> | ||||
| #include <scwx/qt/settings/general_settings.hpp> | ||||
| #include <scwx/qt/types/location_types.hpp> | ||||
| #include <scwx/common/geographic.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <mutex> | ||||
| #include <set> | ||||
| 
 | ||||
| #include <boost/uuid/random_generator.hpp> | ||||
|  | @ -23,37 +26,37 @@ public: | |||
|    explicit Impl(PositionManager* self) : | ||||
|        self_ {self}, trackingUuid_ {boost::uuids::random_generator()()} | ||||
|    { | ||||
|       // TODO: macOS requires permission
 | ||||
|       geoPositionInfoSource_ = | ||||
|          QGeoPositionInfoSource::createDefaultSource(self); | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|       if (geoPositionInfoSource_ != nullptr) | ||||
|       { | ||||
|          logger_->debug("Using position source: {}", | ||||
|                         geoPositionInfoSource_->sourceName().toStdString()); | ||||
|       logger_->debug( | ||||
|          "Available sources: {}", | ||||
|          QGeoPositionInfoSource::availableSources().join(", ").toStdString()); | ||||
| 
 | ||||
|          QObject::connect(geoPositionInfoSource_, | ||||
|                           &QGeoPositionInfoSource::positionUpdated, | ||||
|                           self_, | ||||
|                           [this](const QGeoPositionInfo& info) | ||||
|                           { | ||||
|                              auto coordinate = info.coordinate(); | ||||
|       CreatePositionSource(); | ||||
| 
 | ||||
|                              if (coordinate != position_.coordinate()) | ||||
|                              { | ||||
|                                 logger_->debug("Position updated: {}, {}", | ||||
|                                                coordinate.latitude(), | ||||
|                                                coordinate.longitude()); | ||||
|                              } | ||||
|       positioningPluginCallbackUuid_ = | ||||
|          generalSettings.positioning_plugin().RegisterValueChangedCallback( | ||||
|             [this](const std::string&) { CreatePositionSource(); }); | ||||
|       nmeaBaudRateCallbackUuid_ = | ||||
|          generalSettings.nmea_baud_rate().RegisterValueChangedCallback( | ||||
|             [this](const std::int64_t&) { CreatePositionSource(); }); | ||||
|       nmeaSourceCallbackUuid_ = | ||||
|          generalSettings.nmea_source().RegisterValueChangedCallback( | ||||
|             [this](const std::string&) { CreatePositionSource(); }); | ||||
|    } | ||||
|    ~Impl() | ||||
|    { | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|                              position_ = info; | ||||
| 
 | ||||
|                              Q_EMIT self_->PositionUpdated(info); | ||||
|                           }); | ||||
|       } | ||||
|       generalSettings.positioning_plugin().UnregisterValueChangedCallback( | ||||
|          positioningPluginCallbackUuid_); | ||||
|       generalSettings.nmea_baud_rate().UnregisterValueChangedCallback( | ||||
|          nmeaBaudRateCallbackUuid_); | ||||
|       generalSettings.nmea_source().UnregisterValueChangedCallback( | ||||
|          nmeaSourceCallbackUuid_); | ||||
|    } | ||||
| 
 | ||||
|    ~Impl() {} | ||||
|    void CreatePositionSource(); | ||||
| 
 | ||||
|    PositionManager* self_; | ||||
| 
 | ||||
|  | @ -62,8 +65,19 @@ public: | |||
| 
 | ||||
|    std::set<boost::uuids::uuid> uuids_ {}; | ||||
| 
 | ||||
|    std::mutex positionSourceMutex_ {}; | ||||
| 
 | ||||
|    QGeoPositionInfoSource* geoPositionInfoSource_ {}; | ||||
|    QGeoPositionInfo        position_ {}; | ||||
| 
 | ||||
|    types::PositioningPlugin lastPositioningPlugin_ { | ||||
|       types::PositioningPlugin::Unknown}; | ||||
|    std::int64_t lastNmeaBaudRate_ {-1}; | ||||
|    std::string  lastNmeaSource_ {"?"}; | ||||
| 
 | ||||
|    boost::uuids::uuid positioningPluginCallbackUuid_ {}; | ||||
|    boost::uuids::uuid nmeaBaudRateCallbackUuid_ {}; | ||||
|    boost::uuids::uuid nmeaSourceCallbackUuid_ {}; | ||||
| }; | ||||
| 
 | ||||
| PositionManager::PositionManager() : p(std::make_unique<Impl>(this)) {} | ||||
|  | @ -79,9 +93,94 @@ bool PositionManager::IsLocationTracked() | |||
|    return p->trackingEnabled_; | ||||
| } | ||||
| 
 | ||||
| void PositionManager::Impl::CreatePositionSource() | ||||
| { | ||||
|    auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|    types::PositioningPlugin positioningPlugin = types::GetPositioningPlugin( | ||||
|       generalSettings.positioning_plugin().GetValue()); | ||||
|    std::int64_t nmeaBaudRate = generalSettings.nmea_baud_rate().GetValue(); | ||||
|    std::string  nmeaSource   = generalSettings.nmea_source().GetValue(); | ||||
| 
 | ||||
|    if (positioningPlugin == lastPositioningPlugin_ && | ||||
|        nmeaBaudRate == lastNmeaBaudRate_ && nmeaSource == lastNmeaSource_) | ||||
|    { | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    QGeoPositionInfoSource* positionSource = nullptr; | ||||
| 
 | ||||
|    // TODO: macOS requires permission
 | ||||
|    if (positioningPlugin == types::PositioningPlugin::Default) | ||||
|    { | ||||
|       positionSource = QGeoPositionInfoSource::createDefaultSource(self_); | ||||
|    } | ||||
|    else if (positioningPlugin == types::PositioningPlugin::Nmea) | ||||
|    { | ||||
|       QVariantMap params {}; | ||||
|       params["nmea.source"]   = QString::fromStdString(nmeaSource); | ||||
|       params["nmea.baudrate"] = static_cast<int>(nmeaBaudRate); | ||||
| 
 | ||||
|       positionSource = | ||||
|          QGeoPositionInfoSource::createSource("nmea", params, self_); | ||||
|    } | ||||
| 
 | ||||
|    if (positionSource != nullptr) | ||||
|    { | ||||
|       logger_->debug("Using position source: {}", | ||||
|                      positionSource->sourceName().toStdString()); | ||||
| 
 | ||||
|       QObject::connect(positionSource, | ||||
|                        &QGeoPositionInfoSource::positionUpdated, | ||||
|                        self_, | ||||
|                        [this](const QGeoPositionInfo& info) | ||||
|                        { | ||||
|                           auto coordinate = info.coordinate(); | ||||
| 
 | ||||
|                           if (coordinate != position_.coordinate()) | ||||
|                           { | ||||
|                              logger_->debug("Position updated: {}, {}", | ||||
|                                             coordinate.latitude(), | ||||
|                                             coordinate.longitude()); | ||||
|                           } | ||||
| 
 | ||||
|                           position_ = info; | ||||
| 
 | ||||
|                           Q_EMIT self_->PositionUpdated(info); | ||||
|                        }); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       logger_->error("Unable to create position source for plugin: {}", | ||||
|                      types::GetPositioningPluginName(positioningPlugin)); | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    lastPositioningPlugin_ = positioningPlugin; | ||||
|    lastNmeaBaudRate_      = nmeaBaudRate; | ||||
|    lastNmeaSource_        = nmeaSource; | ||||
| 
 | ||||
|    std::unique_lock lock {positionSourceMutex_}; | ||||
| 
 | ||||
|    if (geoPositionInfoSource_ != nullptr) | ||||
|    { | ||||
|       geoPositionInfoSource_->stopUpdates(); | ||||
|       delete geoPositionInfoSource_; | ||||
|    } | ||||
| 
 | ||||
|    geoPositionInfoSource_ = positionSource; | ||||
| 
 | ||||
|    if (!uuids_.empty()) | ||||
|    { | ||||
|       positionSource->startUpdates(); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PositionManager::EnablePositionUpdates(boost::uuids::uuid uuid, | ||||
|                                             bool               enabled) | ||||
| { | ||||
|    std::unique_lock lock {p->positionSourceMutex_}; | ||||
| 
 | ||||
|    if (p->geoPositionInfoSource_ == nullptr) | ||||
|    { | ||||
|       return; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat