QGIS API Documentation  3.23.0-Master (b5237dafc3)
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
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  const QGeoSatelliteInfo currentSatellite = satellites.at( i );
104  QgsSatelliteInfo satelliteInfo;
105  satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
106  satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
107  satelliteInfo.id = currentSatellite.satelliteIdentifier();
108  satelliteInfo.signal = currentSatellite.signalStrength();
109  mLastGPSInformation.satellitesInView.append( satelliteInfo );
110  }
111  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
113  QgsDebugMsg( QStringLiteral( "satellitesInViewUpdated" ) );
114 }
115 
117  const QList<QGeoSatelliteInfo> &satellites )
118 {
119  // The number of satellites in use is updated
120  mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
121 
122  mLastGPSInformation.satPrn.clear();
123  for ( const QGeoSatelliteInfo &currentSatellite : satellites )
124  {
125  //add pnr to mLastGPSInformation.satPrn
126  mLastGPSInformation.satPrn.append( currentSatellite.satelliteIdentifier() );
127 
128  //set QgsSatelliteInfo.inuse to true for the satellites in use
130  {
131  if ( satInView.id == currentSatellite.satelliteIdentifier() )
132  {
133  satInView.inUse = true;
134  break;
135  }
136  }
137  }
138  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
140  QgsDebugMsg( QStringLiteral( "satellitesInUseUpdated" ) );
141 }
142 
143 void QgsQtLocationConnection::startGPS()
144 {
145  QgsDebugMsg( QStringLiteral( "Starting GPS QtLocation connection" ) );
146  // Obtain the location data source if it is not obtained already
147  if ( !locationDataSource )
148  {
149  locationDataSource = QGeoPositionInfoSource::createDefaultSource( this );
150  if ( locationDataSource )
151  {
152  locationDataSource->setPreferredPositioningMethods( QGeoPositionInfoSource::SatellitePositioningMethods ); //QGeoPositionInfoSource::AllPositioningMethods
153  locationDataSource->setUpdateInterval( 1000 );
154  // Whenever the location data source signals that the current
155  // position is updated, the positionUpdated function is called.
156  QObject::connect( locationDataSource.data(),
157  &QGeoPositionInfoSource::positionUpdated,
158  this,
160  // Start listening for position updates
161  locationDataSource->startUpdates();
162  }
163  else
164  {
165  // Not able to obtain the location data source
166  QgsDebugMsg( QStringLiteral( "No QtLocation Position Source" ) );
167  }
168  }
169  else
170  {
171  // Start listening for position updates
172  locationDataSource->startUpdates();
173  }
174 }
175 
176 void QgsQtLocationConnection::startSatelliteMonitor()
177 {
178  QgsDebugMsg( QStringLiteral( "Starting GPS QtLocation satellite monitor" ) );
179 
180  if ( !satelliteInfoSource )
181  {
182  satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
183  if ( satelliteInfoSource )
184  {
185  QgsDebugMsg( QStringLiteral( "satelliteMonitor started" ) );
186  // Whenever the satellite info source signals that the number of
187  // satellites in use is updated, the satellitesInUseUpdated function
188  // is called
189  QObject::connect( satelliteInfoSource.data(),
190  &QGeoSatelliteInfoSource::satellitesInUseUpdated,
191  this,
193 
194  // Whenever the satellite info source signals that the number of
195  // satellites in view is updated, the satellitesInViewUpdated function
196  // is called
197  QObject::connect( satelliteInfoSource.data(),
198  &QGeoSatelliteInfoSource::satellitesInViewUpdated,
199  this,
201 
202  // Start listening for satellite updates
203  satelliteInfoSource->startUpdates();
204  }
205  else
206  {
207  // Not able to obtain the Satellite data source
208  QgsDebugMsg( QStringLiteral( "No QtLocation Satellite Source" ) );
209  }
210  }
211  else
212  {
213  // Start listening for position updates
214  satelliteInfoSource->startUpdates();
215  }
216 }
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