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