QGIS API Documentation  2.99.0-Master (53aba61)
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 {
27  //needed to fix https://sourceforge.net/p/necessitas/tickets/146/
28  qRegisterMetaType< QList<QGeoSatelliteInfo> >( "QList<QGeoSatelliteInfo>" );
29 
30  startSatelliteMonitor();
31  startGPS();
32 
33  //HACK to signal the gpsinformationwidget that we have a QtLocationConnection
34  QTimer::singleShot( 500, this, SLOT( broadcastConnectionAvailable() ) );
35 }
36 
37 //Needed to make connection detectable (half HACK)
38 //this signals that the device has started the GPS successfully,
39 //not that it has a fix yet.
41 {
42  if ( locationDataSource )
43  {
46  }
47 }
48 
49 //TODO: Temporarely needed to workaround https://sourceforge.net/p/necessitas/tickets/147/
50 void QgsQtLocationConnection::positionUpdated( const QGeoPositionInfo &info )
51 {
52  mInfo = info;
53  parseData();
54 }
55 
57 {
58  if ( locationDataSource )
59  {
61  //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition();
62  if ( mInfo.isValid() )
63  {
64  // mInfo.HorizontalAccuracy;
65  mLastGPSInformation.latitude = mInfo.coordinate().latitude();
66  mLastGPSInformation.longitude = mInfo.coordinate().longitude();
67  mLastGPSInformation.elevation = mInfo.coordinate().altitude();
68  mLastGPSInformation.speed = mInfo.attribute( QGeoPositionInfo::GroundSpeed ) * 3.6; // m/s to km/h
69  mLastGPSInformation.direction = mInfo.attribute( QGeoPositionInfo::Direction );
70  mLastGPSInformation.utcDateTime = mInfo.timestamp();
71  mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
72  //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D)
73  //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D)
74  mLastGPSInformation.hacc = mInfo.attribute( QGeoPositionInfo::HorizontalAccuracy ); //< Horizontal dilution of precision
75  mLastGPSInformation.vacc = mInfo.attribute( QGeoPositionInfo::VerticalAccuracy ); //< Vertical dilution of precision
76 
77  //TODO implement dop maybe by getting a
78  //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html
79  //http://doc.qt.nokia.com/qtmobility-1.1/qnmeapositioninfosource.html
80  //into QtLocation and subclass QgsNMEAConnection directly?
81  //mLastGPSInformation.pdop; //< Dilution of precision
82  //mLastGPSInformation.hdop; //< Horizontal dilution of precision
83  //mLastGPSInformation.vdop; //< Vertical dilution of precision
84 
85  //mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D)
86  //mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive)
87  //mLastGPSInformation.status; //< Status (A = active or V = void)
88 
90  QgsDebugMsg( "Valid QGeoPositionInfo, positionUpdated" );
91  }
92  }
93 }
94 
96  const QList<QGeoSatelliteInfo> &satellites )
97 {
98  // The number of satellites in view is updated
100  for ( int i = 0; i < satellites.size(); ++i )
101  {
102  QGeoSatelliteInfo currentSatellite = satellites.at( i );
103  QgsSatelliteInfo satelliteInfo;
104  satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
105  satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
106 #if defined(HAVE_QT_MOBILITY_LOCATION )
107  satelliteInfo.id = currentSatellite.prnNumber();
108 #else // QtPositioning
109  satelliteInfo.id = currentSatellite.satelliteIdentifier();
110 #endif
111  satelliteInfo.signal = currentSatellite.signalStrength();
112  mLastGPSInformation.satellitesInView.append( satelliteInfo );
113  }
114  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
116  QgsDebugMsg( "satellitesInViewUpdated" );
117 }
118 
120  const QList<QGeoSatelliteInfo> &satellites )
121 {
122  // The number of satellites in use is updated
123  mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
124 
125  mLastGPSInformation.satPrn.clear();
126  for ( int i = 0; i < satellites.size(); ++i )
127  {
128  QGeoSatelliteInfo currentSatellite = satellites.at( i );
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
137  for ( int i = 0; i < mLastGPSInformation.satellitesInView.size(); ++i )
138  {
140 #if defined(HAVE_QT_MOBILITY_LOCATION )
141  if ( satInView.id == currentSatellite.prnNumber() )
142 #else // QtPositioning
143  if ( satInView.id == currentSatellite.satelliteIdentifier() )
144 #endif
145  {
146  satInView.inUse = true;
147  break;
148  }
149  }
150  }
151  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
153  QgsDebugMsg( "satellitesInUseUpdated" );
154 }
155 
156 void QgsQtLocationConnection::startGPS()
157 {
158  QgsDebugMsg( "Starting GPS QtLocation connection" );
159  // Obtain the location data source if it is not obtained already
160  if ( !locationDataSource )
161  {
162  locationDataSource = QGeoPositionInfoSource::createDefaultSource( this );
163  if ( locationDataSource )
164  {
165  locationDataSource->setPreferredPositioningMethods( QGeoPositionInfoSource::SatellitePositioningMethods ); //QGeoPositionInfoSource::AllPositioningMethods
166  locationDataSource->setUpdateInterval( 1000 );
167  // Whenever the location data source signals that the current
168  // position is updated, the positionUpdated function is called.
169  QObject::connect( locationDataSource.data(),
170  &QGeoPositionInfoSource::positionUpdated,
171  this,
173  // Start listening for position updates
174  locationDataSource->startUpdates();
175  }
176  else
177  {
178  // Not able to obtain the location data source
179  QgsDebugMsg( "No QtLocation Position Source" );
180  }
181  }
182  else
183  {
184  // Start listening for position updates
185  locationDataSource->startUpdates();
186  }
187 }
188 
189 void QgsQtLocationConnection::startSatelliteMonitor()
190 {
191  QgsDebugMsg( "Starting GPS QtLocation satellite monitor" );
192 
193  if ( !satelliteInfoSource )
194  {
195  satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
196  if ( satelliteInfoSource )
197  {
198  QgsDebugMsg( "satelliteMonitor started" );
199  // Whenever the satellite info source signals that the number of
200  // satellites in use is updated, the satellitesInUseUpdated function
201  // is called
202  QObject::connect( satelliteInfoSource.data(),
203  &QGeoSatelliteInfoSource::satellitesInUseUpdated,
204  this,
206 
207  // Whenever the satellite info source signals that the number of
208  // satellites in view is updated, the satellitesInViewUpdated function
209  // is called
210  QObject::connect( satelliteInfoSource.data(),
211  &QGeoSatelliteInfoSource::satellitesInViewUpdated,
212  this,
214 
215  // Start listening for satellite updates
216  satelliteInfoSource->startUpdates();
217  }
218  else
219  {
220  // Not able to obtain the Satellite data source
221  QgsDebugMsg( "No QtLocation Satellite Source" );
222  }
223  }
224  else
225  {
226  // Start listening for position updates
227  satelliteInfoSource->startUpdates();
228  }
229 }
void satellitesInUseUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in use is updated.
Status mStatus
Connection status.
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
void positionUpdated(const QGeoPositionInfo &info)
Called when the position updated.
QList< QgsSatelliteInfo > satellitesInView
QList< int > satPrn
Abstract base class for connection to a GPS device.
void satellitesInViewUpdated(const QList< QGeoSatelliteInfo > &satellites)
Called when the number of satellites in view is updated.
QgsGPSInformation mLastGPSInformation
Last state of the gps related variables (e.g. position, time, ...)
void broadcastConnectionAvailable()
Needed to make QtLocation detected.
void stateChanged(const QgsGPSInformation &info)
void parseData()
Parse available data source content.