8#include <QtCore/QApplicationStatic>
9#include <QtCore/QPermissions>
10#include <QtPositioning/QNmeaPositionInfoSource>
19 qCDebug(QGCPositionManagerLog) <<
this;
24 qCDebug(QGCPositionManagerLog) <<
this;
29 return _positionManager();
36 _setPositionSource(QGCPositionSource::Simulated);
42void QGCPositionManager::_setupPositionSources()
46 _usingPluginSource =
true;
48 qCDebug(QGCPositionManagerLog) << Q_FUNC_INFO << QGeoPositionInfoSource::availableSources();
50 _defaultSource = QGeoPositionInfoSource::createDefaultSource(
this);
51 if (!_defaultSource) {
52 qCWarning(QGCPositionManagerLog) << Q_FUNC_INFO <<
"No default source available";
57 _setPositionSource(QGCPositionSource::InternalGPS);
60void QGCPositionManager::_handlePermissionStatus(Qt::PermissionStatus permissionStatus)
62 if (permissionStatus == Qt::PermissionStatus::Granted) {
63 _setupPositionSources();
65 qCWarning(QGCPositionManagerLog) << Q_FUNC_INFO <<
"Location Permission Denied";
69void QGCPositionManager::_checkPermission()
71 QLocationPermission locationPermission;
72 locationPermission.setAccuracy(QLocationPermission::Precise);
74 const Qt::PermissionStatus permissionStatus = QCoreApplication::instance()->checkPermission(locationPermission);
75 if (permissionStatus == Qt::PermissionStatus::Undetermined) {
76 QCoreApplication::instance()->requestPermission(locationPermission,
this, [
this](
const QPermission &permission) {
77 _handlePermissionStatus(permission.status());
80 _handlePermissionStatus(permissionStatus);
87 _nmeaSource->stopUpdates();
88 (void) disconnect(_nmeaSource);
90 if (_currentSource == _nmeaSource) {
91 _currentSource =
nullptr;
95 _nmeaSource =
nullptr;
98 _nmeaSource =
new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode,
this);
99 _nmeaSource->setDevice(device);
100 _nmeaSource->setUserEquivalentRangeError(5.1);
101 _setPositionSource(QGCPositionManager::NmeaGPS);
104void QGCPositionManager::_positionUpdated(
const QGeoPositionInfo &update)
106 _geoPositionInfo = update;
107 _gcsPositioningError = QGeoPositionInfoSource::NoError;
109 QGeoCoordinate newGCSPosition(_gcsPosition);
111 if (update.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
112 if ((qAbs(update.coordinate().latitude()) > 0.001) && (qAbs(update.coordinate().longitude()) > 0.001)) {
113 _gcsPositionHorizontalAccuracy = update.attribute(QGeoPositionInfo::HorizontalAccuracy);
114 if (_gcsPositionHorizontalAccuracy <= kMinHorizonalAccuracyMeters) {
115 newGCSPosition.setLatitude(update.coordinate().latitude());
116 newGCSPosition.setLongitude(update.coordinate().longitude());
122 if (update.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
123 _gcsPositionVerticalAccuracy = update.attribute(QGeoPositionInfo::VerticalAccuracy);
124 if (_gcsPositionVerticalAccuracy <= kMinVerticalAccuracyMeters) {
125 newGCSPosition.setAltitude(update.coordinate().altitude());
129 _gcsPositionAccuracy = sqrt(pow(_gcsPositionHorizontalAccuracy, 2) + pow(_gcsPositionVerticalAccuracy, 2));
131 _setGCSPosition(newGCSPosition);
133 if (update.hasAttribute(QGeoPositionInfo::DirectionAccuracy)) {
134 _gcsDirectionAccuracy = update.attribute(QGeoPositionInfo::DirectionAccuracy);
135 if (_gcsDirectionAccuracy <= kMinDirectionAccuracyDegrees) {
136 _setGCSHeading(update.attribute(QGeoPositionInfo::Direction));
138 }
else if (_usingPluginSource) {
139 _setGCSHeading(update.attribute(QGeoPositionInfo::Direction));
145void QGCPositionManager::_positionError(QGeoPositionInfoSource::Error gcsPositioningError)
147 qCWarning(QGCPositionManagerLog) << Q_FUNC_INFO <<
"Positioning error:" <<
gcsPositioningError;
151void QGCPositionManager::_setGCSHeading(qreal newGCSHeading)
153 if (newGCSHeading != _gcsHeading) {
154 _gcsHeading = newGCSHeading;
159void QGCPositionManager::_setGCSPosition(
const QGeoCoordinate& newGCSPosition)
161 if (newGCSPosition != _gcsPosition) {
162 _gcsPosition = newGCSPosition;
167void QGCPositionManager::_setPositionSource(QGCPositionSource source)
169 if (_currentSource !=
nullptr) {
170 _currentSource->stopUpdates();
171 (void) disconnect(_currentSource);
173 _geoPositionInfo = QGeoPositionInfo();
176 _setGCSPosition(QGeoCoordinate());
178 _setGCSHeading(qQNaN());
180 _gcsPositionHorizontalAccuracy = std::numeric_limits<qreal>::infinity();
185 case QGCPositionManager::Log:
187 case QGCPositionManager::Simulated:
188 _currentSource = _simulatedSource;
190 case QGCPositionManager::NmeaGPS:
191 _currentSource = _nmeaSource;
193 case QGCPositionManager::InternalGPS:
194 _currentSource = _defaultSource;
196 case QGCPositionManager::ExternalGPS:
199 _currentSource = _defaultSource;
203 if (_currentSource !=
nullptr) {
204 _currentSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
205 _updateInterval = _currentSource->minimumUpdateInterval();
206 #if !defined(Q_OS_DARWIN) && !defined(Q_OS_IOS)
207 _currentSource->setUpdateInterval(_updateInterval);
210 (void) connect(_currentSource, &QGeoPositionInfoSource::positionUpdated,
this, &QGCPositionManager::_positionUpdated);
211 (void) connect(_currentSource, &QGeoPositionInfoSource::errorOccurred,
this, &QGCPositionManager::_positionError);
215 _currentSource->startUpdates();
Q_APPLICATION_STATIC(QGCPositionManager, _positionManager)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
virtual QGeoPositionInfoSource * createPositionSource(QObject *parent)
static QGCCorePlugin * instance()
static QGCPositionManager * instance()
void gcsPositionChanged(QGeoCoordinate gcsPosition)
QGeoPositionInfoSource::Error gcsPositioningError() const
void setNmeaSourceDevice(QIODevice *device)
void gcsPositionHorizontalAccuracyChanged(qreal gcsPositionHorizontalAccuracy)
void positionInfoUpdated(QGeoPositionInfo update)
void gcsHeadingChanged(qreal gcsHeading)