QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
20#include "qgslogger.h"
21
22#include <QLocalSocket>
23#include <QMetaType>
24#include <QTimer>
25
26#include "moc_qgsqtlocationconnection.cpp"
27
29 : QgsGpsConnection( new QLocalSocket() )
30{
31 //needed to fix https://sourceforge.net/p/necessitas/tickets/146/
32 qRegisterMetaType< QList<QGeoSatelliteInfo> >( "QList<QGeoSatelliteInfo>" );
33
34 startSatelliteMonitor();
35 startGPS();
36
37 //HACK to signal the gpsinformationwidget that we have a QtLocationConnection
38 QTimer::singleShot( 500, this, &QgsQtLocationConnection::broadcastConnectionAvailable );
39}
40
41//Needed to make connection detectable (half HACK)
42//this signals that the device has started the GPS successfully,
43//not that it has a fix yet.
45{
46 if ( locationDataSource )
47 {
50 }
51}
52
53//TODO: Temporarily needed to workaround https://sourceforge.net/p/necessitas/tickets/147/
54void QgsQtLocationConnection::positionUpdated( const QGeoPositionInfo &info )
55{
56 mInfo = info;
57 parseData();
58}
59
61{
62 if ( locationDataSource )
63 {
65 //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition();
66 if ( mInfo.isValid() )
67 {
68 // mInfo.HorizontalAccuracy;
69 mLastGPSInformation.latitude = mInfo.coordinate().latitude();
70 mLastGPSInformation.longitude = mInfo.coordinate().longitude();
71 mLastGPSInformation.elevation = mInfo.coordinate().altitude();
72 mLastGPSInformation.speed = mInfo.attribute( QGeoPositionInfo::GroundSpeed ) * 3.6; // m/s to km/h
73 mLastGPSInformation.direction = mInfo.attribute( QGeoPositionInfo::Direction );
74 mLastGPSInformation.utcDateTime = mInfo.timestamp();
75 mLastGPSInformation.utcTime = mInfo.timestamp().time();
76 mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
77 switch ( mInfo.coordinate().type() )
78 {
79 case QGeoCoordinate::InvalidCoordinate:
81 break;
82 case QGeoCoordinate::Coordinate2D:
84 break;
85 case QGeoCoordinate::Coordinate3D:
87 break;
88 }
89
90 //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D)
91 //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D)
92 mLastGPSInformation.hacc = mInfo.attribute( QGeoPositionInfo::HorizontalAccuracy ); //< Horizontal dilution of precision
93 mLastGPSInformation.vacc = mInfo.attribute( QGeoPositionInfo::VerticalAccuracy ); //< Vertical dilution of precision
94
95 //TODO implement dop maybe by getting a
96 //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html
97 //http://doc.qt.nokia.com/qtmobility-1.1/qnmeapositioninfosource.html
98 //into QtLocation and subclass QgsNMEAConnection directly?
99 //mLastGPSInformation.pdop; //< Dilution of precision
100 //mLastGPSInformation.hdop; //< Horizontal dilution of precision
101 //mLastGPSInformation.vdop; //< Vertical dilution of precision
102
103 //mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D)
104 //mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive)
105 //mLastGPSInformation.status; //< Status (A = active or V = void)
106
108 QgsDebugMsgLevel( QStringLiteral( "Valid QGeoPositionInfo, positionUpdated" ), 2 );
109 }
110 }
111}
112
114 const QList<QGeoSatelliteInfo> &satellites )
115{
116 // The number of satellites in view is updated
117 mLastGPSInformation.satellitesInView.clear();
118 for ( int i = 0; i < satellites.size(); ++i )
119 {
120 const QGeoSatelliteInfo currentSatellite = satellites.at( i );
121 QgsSatelliteInfo satelliteInfo;
122 satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
123 satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
124 satelliteInfo.id = currentSatellite.satelliteIdentifier();
125 satelliteInfo.signal = currentSatellite.signalStrength();
126 mLastGPSInformation.satellitesInView.append( satelliteInfo );
127 }
128 mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
130 QgsDebugMsgLevel( QStringLiteral( "satellitesInViewUpdated" ), 2 );
131}
132
134 const QList<QGeoSatelliteInfo> &satellites )
135{
136 // The number of satellites in use is updated
137 mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
138
139 mLastGPSInformation.satPrn.clear();
140 for ( const QGeoSatelliteInfo &currentSatellite : satellites )
141 {
142 //add pnr to mLastGPSInformation.satPrn
143 mLastGPSInformation.satPrn.append( currentSatellite.satelliteIdentifier() );
144
145 //set QgsSatelliteInfo.inuse to true for the satellites in use
146 for ( QgsSatelliteInfo &satInView : mLastGPSInformation.satellitesInView )
147 {
148 if ( satInView.id == currentSatellite.satelliteIdentifier() )
149 {
150 satInView.inUse = true;
151 break;
152 }
153 }
154 }
155 mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
157 QgsDebugMsgLevel( QStringLiteral( "satellitesInUseUpdated" ), 2 );
158}
159
160void QgsQtLocationConnection::startGPS()
161{
162 QgsDebugMsgLevel( QStringLiteral( "Starting GPS QtLocation connection" ), 2 );
163 // Obtain the location data source if it is not obtained already
164 if ( !locationDataSource )
165 {
166 locationDataSource = QGeoPositionInfoSource::createDefaultSource( this );
167 if ( locationDataSource )
168 {
169 locationDataSource->setPreferredPositioningMethods( QGeoPositionInfoSource::SatellitePositioningMethods ); //QGeoPositionInfoSource::AllPositioningMethods
170 locationDataSource->setUpdateInterval( 1000 );
171 // Whenever the location data source signals that the current
172 // position is updated, the positionUpdated function is called.
173 QObject::connect( locationDataSource.data(),
174 &QGeoPositionInfoSource::positionUpdated,
175 this,
177 // Start listening for position updates
178 locationDataSource->startUpdates();
179 }
180 else
181 {
182 // Not able to obtain the location data source
183 QgsDebugError( QStringLiteral( "No QtLocation Position Source" ) );
184 }
185 }
186 else
187 {
188 // Start listening for position updates
189 locationDataSource->startUpdates();
190 }
191}
192
193void QgsQtLocationConnection::startSatelliteMonitor()
194{
195 QgsDebugMsgLevel( QStringLiteral( "Starting GPS QtLocation satellite monitor" ), 2 );
196
197 if ( !satelliteInfoSource )
198 {
199 satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
200 if ( satelliteInfoSource )
201 {
202 QgsDebugMsgLevel( QStringLiteral( "satelliteMonitor started" ), 2 );
203 // Whenever the satellite info source signals that the number of
204 // satellites in use is updated, the satellitesInUseUpdated function
205 // is called
206 QObject::connect( satelliteInfoSource.data(),
207 &QGeoSatelliteInfoSource::satellitesInUseUpdated,
208 this,
210
211 // Whenever the satellite info source signals that the number of
212 // satellites in view is updated, the satellitesInViewUpdated function
213 // is called
214 QObject::connect( satelliteInfoSource.data(),
215 &QGeoSatelliteInfoSource::satellitesInViewUpdated,
216 this,
218
219 // Start listening for satellite updates
220 satelliteInfoSource->startUpdates();
221 }
222 else
223 {
224 // Not able to obtain the Satellite data source
225 QgsDebugError( QStringLiteral( "No QtLocation Satellite Source" ) );
226 }
227 }
228 else
229 {
230 // Start listening for position updates
231 satelliteInfoSource->startUpdates();
232 }
233}
@ Unknown
Unknown/other system.
Definition qgis.h:1905
@ NoFix
GPS is not fixed.
Definition qgis.h:1891
@ Fix2D
2D fix
Definition qgis.h:1892
@ Fix3D
3D fix
Definition qgis.h:1893
QgsGpsInformation mLastGPSInformation
Last state of the gps related variables (e.g. position, time, ...).
QgsGpsConnection(QIODevice *dev)
Constructor.
Status mStatus
Connection status.
void stateChanged(const QgsGpsInformation &info)
Emitted whenever the GPS state is changed.
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 QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
#define QgsDebugError(str)
Definition qgslogger.h:57