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