QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsgpsdetector.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgpsdetector.cpp - description
3  --------------------
4  begin : January 13th, 2009
5  copyright : (C) 2009 by Juergen E. Fischer
6  email : jef at norbit dot de
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 "qgsgpsdetector.h"
19 #include "qgslogger.h"
20 #include "qgsgpsconnection.h"
21 #include "qgsnmeaconnection.h"
22 #include "qgsgpsdconnection.h"
23 
24 
25 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
27 #endif
28 
29 #include <QStringList>
30 #include <QFileInfo>
31 #include <QTimer>
32 #include <QSerialPortInfo>
33 
34 QList< QPair<QString, QString> > QgsGpsDetector::availablePorts()
35 {
36  QList< QPair<QString, QString> > devs;
37 
38  // try local QtLocation first
39 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
40  devs << QPair<QString, QString>( QStringLiteral( "internalGPS" ), tr( "internal GPS" ) );
41 #endif
42 
43  // try local gpsd first
44  devs << QPair<QString, QString>( QStringLiteral( "localhost:2947:" ), tr( "local gpsd" ) );
45 
46  for ( auto p : QSerialPortInfo::availablePorts() )
47  {
48  devs << QPair<QString, QString>( p.portName(), tr( "%1: %2" ).arg( p.portName(), p.description() ) );
49  }
50 
51  return devs;
52 }
53 
54 QgsGpsDetector::QgsGpsDetector( const QString &portName )
55 {
56  mConn = nullptr;
57  mBaudList << QSerialPort::Baud4800 << QSerialPort::Baud9600 << QSerialPort::Baud38400 << QSerialPort::Baud57600 << QSerialPort::Baud115200; //add 57600 for SXBlueII GPS unit
58 
59  if ( portName.isEmpty() )
60  {
61  mPortList = availablePorts();
62  }
63  else
64  {
65  mPortList << QPair<QString, QString>( portName, portName );
66  }
67 
68  mPortIndex = 0;
69  mBaudIndex = -1;
70 }
71 
73 {
74  delete mConn;
75 }
76 
78 {
79  delete mConn;
80 
81  mConn = nullptr;
82 
83  while ( !mConn )
84  {
85  mBaudIndex++;
86  if ( mBaudIndex == mBaudList.size() )
87  {
88  mBaudIndex = 0;
89  mPortIndex++;
90  }
91 
92  if ( mPortIndex == mPortList.size() )
93  {
94  emit detectionFailed();
95  deleteLater();
96  return;
97  }
98 
99  if ( mPortList.at( mPortIndex ).first.contains( ':' ) )
100  {
101  mBaudIndex = mBaudList.size() - 1;
102 
103  QStringList gpsParams = mPortList.at( mPortIndex ).first.split( ':' );
104 
105  Q_ASSERT( gpsParams.size() >= 3 );
106 
107  mConn = new QgsGpsdConnection( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] );
108  }
109  else if ( mPortList.at( mPortIndex ).first.contains( QLatin1String( "internalGPS" ) ) )
110  {
111 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
112  mConn = new QgsQtLocationConnection();
113 #else
114  qWarning( "QT_MOBILITY_LOCATION not found and mPortList matches internalGPS, this should never happen" );
115 #endif
116  }
117  else
118  {
119  QSerialPort *serial = new QSerialPort( mPortList.at( mPortIndex ).first );
120 
121  serial->setBaudRate( mBaudList[ mBaudIndex ] );
122  serial->setFlowControl( QSerialPort::NoFlowControl );
123  serial->setParity( QSerialPort::NoParity );
124  serial->setDataBits( QSerialPort::Data8 );
125  serial->setStopBits( QSerialPort::OneStop );
126 
127  if ( serial->open( QIODevice::ReadOnly ) )
128  {
129  mConn = new QgsNmeaConnection( serial );
130  }
131  else
132  {
133  delete serial;
134  }
135  }
136  }
137 
138  connect( mConn, &QgsGpsConnection::stateChanged, this, static_cast < void ( QgsGpsDetector::* )( const QgsGpsInformation & ) >( &QgsGpsDetector::detected ) );
139  connect( mConn, &QObject::destroyed, this, &QgsGpsDetector::connDestroyed );
140 
141  // leave 2s to pickup a valid string
142  QTimer::singleShot( 2000, this, &QgsGpsDetector::advance );
143 }
144 
146 {
147  Q_UNUSED( info );
148 
149  if ( !mConn )
150  {
151  // advance if connection was destroyed
152  advance();
153  }
154  else if ( mConn->status() == QgsGpsConnection::GPSDataReceived )
155  {
156  // signal detection
157  QgsGpsConnection *conn = mConn;
158  mConn = nullptr;
159  emit detected( conn );
160  deleteLater();
161  }
162 }
163 
164 void QgsGpsDetector::connDestroyed( QObject *obj )
165 {
166  if ( obj == mConn )
167  {
168  mConn = nullptr;
169  }
170 }
Evaluates NMEA sentences coming from gpsd.
Class to detect the GPS port.
void detected(const QgsGpsInformation &)
~QgsGpsDetector() override
void connDestroyed(QObject *)
void stateChanged(const QgsGpsInformation &info)
void detectionFailed()
Evaluates NMEA sentences coming from a GPS device.
static QList< QPair< QString, QString > > availablePorts()
QgsGpsDetector(const QString &portName)
Abstract base class for connection to a GPS device.
Status status() const
Returns the status. Possible state are not connected, connected, data received.