QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  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  QgsDebugMsg( "entered." );
41 }
42 
43 //Needed to make connection detectable (half HACK)
44 //this signals that the device has started the GPS sucessfully,
45 //not that it has a fix yet.
47 {
48  if ( locationDataSource )
49  {
52  }
53 }
54 
55 //TODO: Temporarely needed to workaround https://sourceforge.net/p/necessitas/tickets/147/
56 void QgsQtLocationConnection::positionUpdated( const QGeoPositionInfo &info )
57 {
58  mInfo = info;
59  parseData();
60 }
61 
63 {
64  if ( locationDataSource )
65  {
67  //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition();
68  qDebug() << mInfo;
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 );
78  mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
79  //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D)
80  //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D)
81  mLastGPSInformation.hacc = mInfo.attribute( QGeoPositionInfo::HorizontalAccuracy ); //< Horizontal dilution of precision
82  mLastGPSInformation.vacc = mInfo.attribute( QGeoPositionInfo::VerticalAccuracy ); //< Vertical dilution of precision
83 
84  //TODO implement dop maybe by getting a
85  //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html
86  //http://doc.qt.nokia.com/qtmobility-1.1/qnmeapositioninfosource.html
87  //into QtLocation and subclass QgsNMEAConnection directly?
88  mLastGPSInformation.pdop; //< Dilution of precision
89  mLastGPSInformation.hdop; //< Horizontal dilution of precision
90  mLastGPSInformation.vdop; //< Vertical dilution of precision
91 
92  mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D)
93  mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive)
94  mLastGPSInformation.status; //< Status (A = active or V = void)
95 
97  QgsDebugMsg( "Valid QGeoPositionInfo, positionUpdated" );
98  }
99  }
100 }
101 
103  const QList<QGeoSatelliteInfo>& satellites )
104 {
105  // The number of satellites in view is updated
107  for ( int i = 0; i < satellites.size(); ++i )
108  {
109  QGeoSatelliteInfo currentSatellite = satellites.at( i );
110  QgsSatelliteInfo satelliteInfo;
111  satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth );
112  satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation );
113  satelliteInfo.id = currentSatellite.prnNumber();
114  satelliteInfo.signal = currentSatellite.signalStrength();
115  mLastGPSInformation.satellitesInView.append( satelliteInfo );
116  }
117  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
119  QgsDebugMsg( "satellitesInViewUpdated" );
120 }
121 
123  const QList<QGeoSatelliteInfo>& satellites )
124 {
125  // The number of satellites in use is updated
126  mLastGPSInformation.satellitesUsed = QString::number( satellites.count() ).toInt();
127 
128  mLastGPSInformation.satPrn.clear();
129  for ( int i = 0; i < satellites.size(); ++i )
130  {
131  QGeoSatelliteInfo currentSatellite = satellites.at( i );
132  //add pnr to mLastGPSInformation.satPrn
133  mLastGPSInformation.satPrn.append( currentSatellite.prnNumber() );
134 
135  //set QgsSatelliteInfo.inuse to true for the satellites in use
136  for ( int i = 0; i < mLastGPSInformation.satellitesInView.size(); ++i )
137  {
139  if ( satInView.id == currentSatellite.prnNumber() )
140  {
141  satInView.inUse = true;
142  break;
143  }
144  }
145  }
146  mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position
148  QgsDebugMsg( "satellitesInUseUpdated" );
149 }
150 
152 {
153  QgsDebugMsg( "Starting GPS QtLocation connection" );
154  // Obtain the location data source if it is not obtained already
155  if ( !locationDataSource )
156  {
157  locationDataSource = QGeoPositionInfoSource::createDefaultSource( this );
158  if ( locationDataSource )
159  {
160  locationDataSource->setPreferredPositioningMethods( QGeoPositionInfoSource::SatellitePositioningMethods ); //QGeoPositionInfoSource::AllPositioningMethods
161  locationDataSource->setUpdateInterval( 1000 );
162  // Whenever the location data source signals that the current
163  // position is updated, the positionUpdated function is called.
165  SIGNAL( positionUpdated( QGeoPositionInfo ) ),
166  this,
167  SLOT( positionUpdated( QGeoPositionInfo ) ) );
168  // Start listening for position updates
169  locationDataSource->startUpdates();
170  }
171  else
172  {
173  // Not able to obtain the location data source
174  QgsDebugMsg( "No QtLocation Position Source" );
175  }
176  }
177  else
178  {
179  // Start listening for position updates
180  locationDataSource->startUpdates();
181  }
182 }
183 
185 {
186  QgsDebugMsg( "Starting GPS QtLocation satellite monitor" );
187  if ( !satelliteInfoSource )
188  {
189  satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource( this );
190  if ( satelliteInfoSource )
191  {
192  QgsDebugMsg( "satelliteMonitor started" );
193  // Whenever the satellite info source signals that the number of
194  // satellites in use is updated, the satellitesInUseUpdated function
195  // is called
197  SIGNAL( satellitesInUseUpdated(
198  const QList<QGeoSatelliteInfo>& ) ),
199  this,
201  const QList<QGeoSatelliteInfo>& ) ) );
202 
203  // Whenever the satellite info source signals that the number of
204  // satellites in view is updated, the satellitesInViewUpdated function
205  // is called
207  SIGNAL( satellitesInViewUpdated(
208  const QList<QGeoSatelliteInfo>& ) ),
209  this,
211  const QList<QGeoSatelliteInfo>& ) ) );
212 
213  // Start listening for satellite updates
214  satelliteInfoSource->startUpdates();
215  }
216  else
217  {
218  // Not able to obtain the Satellite data source
219  QgsDebugMsg( "No QtLocation Satellite Source" );
220  }
221  }
222  else
223  {
224  // Start listening for position updates
225  satelliteInfoSource->startUpdates();
226  }
227 }