mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 16:10: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/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/common/geographic.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <mutex> | ||||||
| #include <set> | #include <set> | ||||||
| 
 | 
 | ||||||
| #include <boost/uuid/random_generator.hpp> | #include <boost/uuid/random_generator.hpp> | ||||||
|  | @ -23,37 +26,37 @@ public: | ||||||
|    explicit Impl(PositionManager* self) : |    explicit Impl(PositionManager* self) : | ||||||
|        self_ {self}, trackingUuid_ {boost::uuids::random_generator()()} |        self_ {self}, trackingUuid_ {boost::uuids::random_generator()()} | ||||||
|    { |    { | ||||||
|       // TODO: macOS requires permission
 |       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
|       geoPositionInfoSource_ = |  | ||||||
|          QGeoPositionInfoSource::createDefaultSource(self); |  | ||||||
| 
 | 
 | ||||||
|       if (geoPositionInfoSource_ != nullptr) |       logger_->debug( | ||||||
|       { |          "Available sources: {}", | ||||||
|          logger_->debug("Using position source: {}", |          QGeoPositionInfoSource::availableSources().join(", ").toStdString()); | ||||||
|                         geoPositionInfoSource_->sourceName().toStdString()); |  | ||||||
| 
 | 
 | ||||||
|          QObject::connect(geoPositionInfoSource_, |       CreatePositionSource(); | ||||||
|                           &QGeoPositionInfoSource::positionUpdated, |  | ||||||
|                           self_, |  | ||||||
|                           [this](const QGeoPositionInfo& info) |  | ||||||
|                           { |  | ||||||
|                              auto coordinate = info.coordinate(); |  | ||||||
| 
 | 
 | ||||||
|                              if (coordinate != position_.coordinate()) |       positioningPluginCallbackUuid_ = | ||||||
|                              { |          generalSettings.positioning_plugin().RegisterValueChangedCallback( | ||||||
|                                 logger_->debug("Position updated: {}, {}", |             [this](const std::string&) { CreatePositionSource(); }); | ||||||
|                                                coordinate.latitude(), |       nmeaBaudRateCallbackUuid_ = | ||||||
|                                                coordinate.longitude()); |          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; |       generalSettings.positioning_plugin().UnregisterValueChangedCallback( | ||||||
| 
 |          positioningPluginCallbackUuid_); | ||||||
|                              Q_EMIT self_->PositionUpdated(info); |       generalSettings.nmea_baud_rate().UnregisterValueChangedCallback( | ||||||
|                           }); |          nmeaBaudRateCallbackUuid_); | ||||||
|       } |       generalSettings.nmea_source().UnregisterValueChangedCallback( | ||||||
|  |          nmeaSourceCallbackUuid_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ~Impl() {} |    void CreatePositionSource(); | ||||||
| 
 | 
 | ||||||
|    PositionManager* self_; |    PositionManager* self_; | ||||||
| 
 | 
 | ||||||
|  | @ -62,8 +65,19 @@ public: | ||||||
| 
 | 
 | ||||||
|    std::set<boost::uuids::uuid> uuids_ {}; |    std::set<boost::uuids::uuid> uuids_ {}; | ||||||
| 
 | 
 | ||||||
|  |    std::mutex positionSourceMutex_ {}; | ||||||
|  | 
 | ||||||
|    QGeoPositionInfoSource* geoPositionInfoSource_ {}; |    QGeoPositionInfoSource* geoPositionInfoSource_ {}; | ||||||
|    QGeoPositionInfo        position_ {}; |    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)) {} | PositionManager::PositionManager() : p(std::make_unique<Impl>(this)) {} | ||||||
|  | @ -79,9 +93,94 @@ bool PositionManager::IsLocationTracked() | ||||||
|    return p->trackingEnabled_; |    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, | void PositionManager::EnablePositionUpdates(boost::uuids::uuid uuid, | ||||||
|                                             bool               enabled) |                                             bool               enabled) | ||||||
| { | { | ||||||
|  |    std::unique_lock lock {p->positionSourceMutex_}; | ||||||
|  | 
 | ||||||
|    if (p->geoPositionInfoSource_ == nullptr) |    if (p->geoPositionInfoSource_ == nullptr) | ||||||
|    { |    { | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat