QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsqtlocationconnection.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsQtLocationConnection.cpp - description
3  ---------------------
4  begin : December 7th, 2011
5  copyright : (C) 2011 by Marco Bernasocchi, Bernawebdesign.ch
6  email : marco at bernawebdesign dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgslogger.h"
20 
21 #include <QLocalSocket>
22 #include <QTimer>
23 #include <QMetaType>
24 
26  : QgsGpsConnection( new QLocalSocket() )
27 {
28  //needed to fix https://sourceforge.net/p/necessitas/tickets/146/
29  qRegisterMetaType< QList<QGeoSatelliteInfo> >( "QList<QGeoSatelliteInfo>" );
30 
31  startSatelliteMonitor();
32  startGPS();
33 
34  //HACK to signal the gpsinformationwidget that we have a QtLocationConnection
35  QTimer::singleShot( 500, this, SLOT( broadcastConnectionAvailable() ) );
36 }
37 
38 //Needed to make connection detectable (half HACK)
39 //this signals that the device has started the GPS successfully,
40 //not that it has a fix yet.
42 {
43  if ( locationDataSource )
44  {
47  }
48 }
49 
50 //TODO: Temporarily needed to workaround https://sourceforge.net/p/necessitas/tickets/147/
51 void QgsQtLocationConnection::positionUpdated( const QGeoPositionInfo &info )
52 {
53  mInfo = info;
54  parseData();
55 }
56 
58 {
59  if ( locationDataSource )
60  {
62  //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition();
63  if ( mInfo.isValid() )
64  {
65  // mInfo.HorizontalAccuracy;
66  mLastGPSInformation.latitude = mInfo.coordinate().latitude();
67  mLastGPSInformation.longitude = mInfo.coordinate().longitude();
68  mLastGPSInformation.elevation = mInfo.coordinate().altitude();
69  mLastGPSInformation.speed = mInfo.attribute( QGeoPositionInfo::GroundSpeed ) * 3.6; // m/s to km/h
70  mLastGPSInformation.direction = mInfo.attribute( QGeoPositionInfo::Direction );
71  mLastGPSInformation.utcDateTime = mInfo.timestamp();
72  mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
73  //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D)
74  //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D)
75  mLastGPSInformation.hacc = mInfo.attribute( QGeoPositionInfo::HorizontalAccuracy ); //< Horizontal dilution of precision
76  mLastGPSInformation.vacc = mInfo.attribute( QGeoPositionInfo::VerticalAccuracy ); //< Vertical dilution of precision
77 
78  //TODO implement dop maybe by getting a
79  //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html
80  //http://doc.qt.nokia.com/qtmobility-1.1/qnmeapositioninfosource.html
81  //into QtLocation and subclass QgsNMEAConnection directly?
82  //mLastGPSInformation.pdop; //< Dilution of precision
83  //mLastGPSInformation.hdop; //< Horizontal dilution of precision
84  //mLastGPSInformation.vdop; //< Vertical dilution of precision
85 
86  //mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D)
87  //mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive)
88  //mLastGPSInformation.status; //< Status (A = active or V = void)
89 
91  QgsDebugMsg( QStringLiteral( "Valid QGeoPositionInfo, positionUpdated" ) );
92  }
93  }
94 }
95 
97  const QList<QGeoSatelliteInfo> &satellites )
98 {
99  // The number of satellites in view is updated
101  for ( int i = 0; i < satellites.size(); ++i )
102  {
103  QGeoSatelliteInfo currentSatellite = satellites.at( i );
104  QgsSatelliteInfo satelliteInfo;
105  satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
106  satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
107 #if defined(HAVE_QT_MOBILITY_LOCATION )
108  satelliteInfo.id = currentSatellite.prnNumber();
109 #else // QtPositioning
110  satelliteInfo.id = currentSatellite.satelliteIdentifier();
111 #endif
112  satelliteInfo.signal = currentSatellite.signalStrength();
113  mLastGPSInformation.satellitesInView.append( satelliteInfo );
114  }
115  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
117  QgsDebugMsg( QStringLiteral( "satellitesInViewUpdated" ) );
118 }
119 
121  const QList<QGeoSatelliteInfo> &satellites )
122 {
123  // The number of satellites in use is updated
124  mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
125 
126  mLastGPSInformation.satPrn.clear();
127  for ( const QGeoSatelliteInfo &currentSatellite : satellites )
128  {
129  //add pnr to mLastGPSInformation.satPrn
130 #if defined(HAVE_QT_MOBILITY_LOCATION )
131  mLastGPSInformation.satPrn.append( currentSatellite.prnNumber() );
132 #else // QtPositioning
133  mLastGPSInformation.satPrn.append( currentSatellite.satelliteIdentifier() );
134 #endif
135 
136  //set QgsSatelliteInfo.inuse to true for the satellites in use
138  {
139 #if defined(HAVE_QT_MOBILITY_LOCATION )
140  if ( satInView.id == currentSatellite.prnNumber() )
141 #else // QtPositioning
142  if ( satInView.id == currentSatellite.satelliteIdentifier() )
143 #endif
144  {
145  satInView.inUse = true;
146  break;
147  }
148  }
149  }
150  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
152  QgsDebugMsg( QStringLiteral( "satellitesInUseUpdated" ) );
153 }
154 
155 void QgsQtLocationConnection::startGPS()
156 {
157  QgsDebugMsg( QStringLiteral( "Starting GPS QtLocation connection" ) );
158  // Obtain the location data source if it is not obtained already
159  if ( !locationDataSource )
160  {
161  locationDataSource = QGeoPositionInfoSource::createDefaultSource( this );
162  if ( locationDataSource )
163  {
164  locationDataSource->setPreferredPositioningMethods( QGeoPositionInfoSource::SatellitePositioningMethods ); //QGeoPositionInfoSource::AllPositioningMethods
165  locationDataSource->setUpdateInterval( 1000 );
166  // Whenever the location data source signals that the current
167  // position is updated, the positionUpdated function is called.
168  QObject::connect( locationDataSource.data(),
169  &QGeoPositionInfoSource::positionUpdated,
170  this,
172  // Start listening for position updates
173  locationDataSource->startUpdates();
174  }
175  else
176  {
177  // Not able to obtain the location data source
178  QgsDebugMsg( QStringLiteral( "No QtLocation Position Source" ) );
179  }
180  }
181  else
182  {
183  // Start listening for position updates
184  locationDataSource->startUpdates();
185  }
186 }
187 
188 void QgsQtLocationConnection::startSatelliteMonitor()
189 {
190  QgsDebugMsg( QStringLiteral( "Starting GPS QtLocation satellite monitor" ) );
191 
192  if ( !satelliteInfoSource )
193  {
194  satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
195  if ( satelliteInfoSource )
196  {
197  QgsDebugMsg( QStringLiteral( "satelliteMonitor started" ) );
198  // Whenever the satellite info source signals that the number of
199  // satellites in use is updated, the satellitesInUseUpdated function
200  // is called
201  QObject::connect( satelliteInfoSource.data(),
202  &QGeoSatelliteInfoSource::satellitesInUseUpdated,
203  this,
205 
206  // Whenever the satellite info source signals that the number of
207  // satellites in view is updated, the satellitesInViewUpdated function
208  // is called
209  QObject::connect( satelliteInfoSource.data(),
210  &QGeoSatelliteInfoSource::satellitesInViewUpdated,
211  this,
213 
214  // Start listening for satellite updates
215  satelliteInfoSource->startUpdates();
216  }
217  else
218  {
219  // Not able to obtain the Satellite data source
220  QgsDebugMsg( QStringLiteral( "No QtLocation Satellite Source" ) );
221  }
222  }
223  else
224  {
225  // Start listening for position updates
226  satelliteInfoSource->startUpdates();
227  }
228 }
QgsGpsConnection::stateChanged
void stateChanged(const QgsGpsInformation &info)
QgsQtLocationConnection::QgsQtLocationConnection
QgsQtLocationConnection()
Definition: qgsqtlocationconnection.cpp:25
QgsQtLocationConnection::positionUpdated
void positionUpdated(const QGeoPositionInfo &info)
Called when the position updated.
Definition: qgsqtlocationconnection.cpp:51
QgsQtLocationConnection::satellitesInUseUpdated
void satellitesInUseUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in use is updated.
Definition: qgsqtlocationconnection.cpp:120
QgsGpsConnection::mStatus
Status mStatus
Connection status.
Definition: qgsgpsconnection.h:306
QgsQtLocationConnection::parseData
void parseData() override
Parse available data source content.
Definition: qgsqtlocationconnection.cpp:57
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsGpsInformation::vacc
double vacc
Vertical accuracy in meters.
Definition: qgsgpsconnection.h:174
QgsSatelliteInfo
Encapsulates information relating to a GPS satellite.
Definition: qgsgpsconnection.h:42
QgsGpsInformation::satellitesUsed
int satellitesUsed
Count of satellites used in obtaining the fix.
Definition: qgsgpsconnection.h:205
QgsSatelliteInfo::signal
int signal
Signal strength (0-99dB), or -1 if not available.
Definition: qgsgpsconnection.h:90
QgsGpsInformation::utcDateTime
QDateTime utcDateTime
The date and time at which this position was reported, in UTC time.
Definition: qgsgpsconnection.h:185
QgsSatelliteInfo::elevation
double elevation
Elevation of the satellite, in degrees.
Definition: qgsgpsconnection.h:64
QgsGpsInformation::fixType
int fixType
Contains the fix type, where 1 = no fix, 2 = 2d fix, 3 = 3d fix.
Definition: qgsgpsconnection.h:195
QgsSatelliteInfo::inUse
bool inUse
true if satellite was used in obtaining the position fix.
Definition: qgsgpsconnection.h:57
QgsQtLocationConnection::satellitesInViewUpdated
void satellitesInViewUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in view is updated.
Definition: qgsqtlocationconnection.cpp:96
qgsqtlocationconnection.h
QgsGpsConnection::mLastGPSInformation
QgsGpsInformation mLastGPSInformation
Last state of the gps related variables (e.g. position, time, ...)
Definition: qgsgpsconnection.h:304
QgsSatelliteInfo::id
int id
Contains the satellite identifier number.
Definition: qgsgpsconnection.h:52
QgsGpsInformation::satInfoComplete
bool satInfoComplete
true if satellite information is complete.
Definition: qgsgpsconnection.h:220
QgsSatelliteInfo::azimuth
double azimuth
The azimuth of the satellite to true north, in degrees.
Definition: qgsgpsconnection.h:78
QgsGpsInformation::speed
double speed
Ground speed, in km/h.
Definition: qgsgpsconnection.h:134
QgsGpsInformation::latitude
double latitude
Latitude in decimal degrees, using the WGS84 datum.
Definition: qgsgpsconnection.h:118
QgsGpsConnection
Abstract base class for connection to a GPS device.
Definition: qgsgpsconnection.h:247
QgsGpsInformation::satPrn
QList< int > satPrn
IDs of satellites used in the position fix.
Definition: qgsgpsconnection.h:215
QgsQtLocationConnection::broadcastConnectionAvailable
void broadcastConnectionAvailable()
Needed to make QtLocation detected.
Definition: qgsqtlocationconnection.cpp:41
QgsGpsInformation::satellitesInView
QList< QgsSatelliteInfo > satellitesInView
Contains a list of information relating to the current satellites in view.
Definition: qgsgpsconnection.h:153
qgslogger.h
QgsGpsInformation::elevation
double elevation
Altitude (in meters) above or below the mean sea level.
Definition: qgsgpsconnection.h:129
QgsGpsConnection::GPSDataReceived
@ GPSDataReceived
Definition: qgsgpsconnection.h:273
QgsGpsInformation::longitude
double longitude
Longitude in decimal degrees, using the WGS84 datum.
Definition: qgsgpsconnection.h:124
QgsGpsInformation::hacc
double hacc
Horizontal accuracy in meters.
Definition: qgsgpsconnection.h:172
QgsGpsInformation::direction
double direction
The bearing measured in degrees clockwise from true north to the direction of travel.
Definition: qgsgpsconnection.h:141