QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 }
Abstract base class for connection to a GPS device.
QgsGpsInformation mLastGPSInformation
Last state of the gps related variables (e.g. position, time, ...)
Status mStatus
Connection status.
void stateChanged(const QgsGpsInformation &info)
double direction
The bearing measured in degrees clockwise from true north to the direction of travel.
int fixType
Contains the fix type, where 1 = no fix, 2 = 2d fix, 3 = 3d fix.
double speed
Ground speed, in km/h.
double vacc
Vertical accuracy in meters.
double latitude
Latitude in decimal degrees, using the WGS84 datum.
double longitude
Longitude in decimal degrees, using the WGS84 datum.
QList< QgsSatelliteInfo > satellitesInView
Contains a list of information relating to the current satellites in view.
QDateTime utcDateTime
The date and time at which this position was reported, in UTC time.
QList< int > satPrn
IDs of satellites used in the position fix.
double elevation
Altitude (in meters) above or below the mean sea level.
bool satInfoComplete
true if satellite information is complete.
int satellitesUsed
Count of satellites used in obtaining the fix.
double hacc
Horizontal accuracy in meters.
void satellitesInViewUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in view is updated.
void broadcastConnectionAvailable()
Needed to make QtLocation detected.
void positionUpdated(const QGeoPositionInfo &info)
Called when the position updated.
void satellitesInUseUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in use is updated.
void parseData() override
Parse available data source content.
Encapsulates information relating to a GPS satellite.
double elevation
Elevation of the satellite, in degrees.
bool inUse
true if satellite was used in obtaining the position fix.
int signal
Signal strength (0-99dB), or -1 if not available.
int id
Contains the satellite identifier number.
double azimuth
The azimuth of the satellite to true north, in degrees.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38