QGIS API Documentation  2.99.0-Master (e077efd)
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 
38 {
39  //connection will be closed by base class
40 }
41 
42 //Needed to make connection detectable (half HACK)
43 //this signals that the device has started the GPS successfully,
44 //not that it has a fix yet.
46 {
47  if ( locationDataSource )
48  {
51  }
52 }
53 
54 //TODO: Temporarely needed to workaround https://sourceforge.net/p/necessitas/tickets/147/
55 void QgsQtLocationConnection::positionUpdated( const QGeoPositionInfo &info )
56 {
57  mInfo = info;
58  parseData();
59 }
60 
62 {
63  if ( locationDataSource )
64  {
66  //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition();
67  if ( mInfo.isValid() )
68  {
69  // mInfo.HorizontalAccuracy;
70  mLastGPSInformation.latitude = mInfo.coordinate().latitude();
71  mLastGPSInformation.longitude = mInfo.coordinate().longitude();
72  mLastGPSInformation.elevation = mInfo.coordinate().altitude();
73  mLastGPSInformation.speed = mInfo.attribute( QGeoPositionInfo::GroundSpeed ) * 3.6; // m/s to km/h
74  mLastGPSInformation.direction = mInfo.attribute( QGeoPositionInfo::Direction );
75  mLastGPSInformation.utcDateTime = mInfo.timestamp();
76  mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
77  //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D)
78  //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D)
79  mLastGPSInformation.hacc = mInfo.attribute( QGeoPositionInfo::HorizontalAccuracy ); //< Horizontal dilution of precision
80  mLastGPSInformation.vacc = mInfo.attribute( QGeoPositionInfo::VerticalAccuracy ); //< Vertical dilution of precision
81 
82  //TODO implement dop maybe by getting a
83  //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html
84  //http://doc.qt.nokia.com/qtmobility-1.1/qnmeapositioninfosource.html
85  //into QtLocation and subclass QgsNMEAConnection directly?
86  //mLastGPSInformation.pdop; //< Dilution of precision
87  //mLastGPSInformation.hdop; //< Horizontal dilution of precision
88  //mLastGPSInformation.vdop; //< Vertical dilution of precision
89 
90  //mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D)
91  //mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive)
92  //mLastGPSInformation.status; //< Status (A = active or V = void)
93 
95  QgsDebugMsg( "Valid QGeoPositionInfo, positionUpdated" );
96  }
97  }
98 }
99 
101  const QList<QGeoSatelliteInfo>& satellites )
102 {
103  // The number of satellites in view is updated
105  for ( int i = 0; i < satellites.size(); ++i )
106  {
107  QGeoSatelliteInfo currentSatellite = satellites.at( i );
108  QgsSatelliteInfo satelliteInfo;
109  satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
110  satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
111 #if defined(HAVE_QT_MOBILITY_LOCATION )
112  satelliteInfo.id = currentSatellite.prnNumber();
113 #else // QtPositioning
114  satelliteInfo.id = currentSatellite.satelliteIdentifier();
115 #endif
116  satelliteInfo.signal = currentSatellite.signalStrength();
117  mLastGPSInformation.satellitesInView.append( satelliteInfo );
118  }
119  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
121  QgsDebugMsg( "satellitesInViewUpdated" );
122 }
123 
125  const QList<QGeoSatelliteInfo>& satellites )
126 {
127  // The number of satellites in use is updated
128  mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
129 
130  mLastGPSInformation.satPrn.clear();
131  for ( int i = 0; i < satellites.size(); ++i )
132  {
133  QGeoSatelliteInfo currentSatellite = satellites.at( i );
134  //add pnr to mLastGPSInformation.satPrn
135 #if defined(HAVE_QT_MOBILITY_LOCATION )
136  mLastGPSInformation.satPrn.append( currentSatellite.prnNumber() );
137 #else // QtPositioning
138  mLastGPSInformation.satPrn.append( currentSatellite.satelliteIdentifier() );
139 #endif
140 
141  //set QgsSatelliteInfo.inuse to true for the satellites in use
142  for ( int i = 0; i < mLastGPSInformation.satellitesInView.size(); ++i )
143  {
145 #if defined(HAVE_QT_MOBILITY_LOCATION )
146  if ( satInView.id == currentSatellite.prnNumber() )
147 #else // QtPositioning
148  if ( satInView.id == currentSatellite.satelliteIdentifier() )
149 #endif
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  QgsDebugMsg( "satellitesInUseUpdated" );
159 }
160 
161 void QgsQtLocationConnection::startGPS()
162 {
163  QgsDebugMsg( "Starting GPS QtLocation connection" );
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,
175  SIGNAL( positionUpdated( QGeoPositionInfo ) ),
176  this,
177  SLOT( positionUpdated( QGeoPositionInfo ) ) );
178  // Start listening for position updates
179  locationDataSource->startUpdates();
180  }
181  else
182  {
183  // Not able to obtain the location data source
184  QgsDebugMsg( "No QtLocation Position Source" );
185  }
186  }
187  else
188  {
189  // Start listening for position updates
190  locationDataSource->startUpdates();
191  }
192 }
193 
194 void QgsQtLocationConnection::startSatelliteMonitor()
195 {
196  QgsDebugMsg( "Starting GPS QtLocation satellite monitor" );
197 
198  if ( !satelliteInfoSource )
199  {
200  satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
201  if ( satelliteInfoSource )
202  {
203  QgsDebugMsg( "satelliteMonitor started" );
204  // Whenever the satellite info source signals that the number of
205  // satellites in use is updated, the satellitesInUseUpdated function
206  // is called
207  QObject::connect( satelliteInfoSource,
208  SIGNAL( satellitesInUseUpdated(
209  const QList<QGeoSatelliteInfo>& ) ),
210  this,
212  const QList<QGeoSatelliteInfo>& ) ) );
213 
214  // Whenever the satellite info source signals that the number of
215  // satellites in view is updated, the satellitesInViewUpdated function
216  // is called
217  QObject::connect( satelliteInfoSource,
218  SIGNAL( satellitesInViewUpdated(
219  const QList<QGeoSatelliteInfo>& ) ),
220  this,
222  const QList<QGeoSatelliteInfo>& ) ) );
223 
224  // Start listening for satellite updates
225  satelliteInfoSource->startUpdates();
226  }
227  else
228  {
229  // Not able to obtain the Satellite data source
230  QgsDebugMsg( "No QtLocation Satellite Source" );
231  }
232  }
233  else
234  {
235  // Start listening for position updates
236  satelliteInfoSource->startUpdates();
237  }
238 }
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:33
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.