QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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 "qgsgpsconnection.h"
20#include "qgsnmeaconnection.h"
21#include "qgsgpsdconnection.h"
22#include "qgssettingstree.h"
24
25
26#if defined(QT_POSITIONING_LIB)
28#endif
29
30#include <QStringList>
31#include <QFileInfo>
32#include <QTimer>
33
34#if defined( HAVE_QTSERIALPORT )
35#include <QSerialPortInfo>
36#include <QSerialPort>
37
38const QgsSettingsEntryEnumFlag<QSerialPort::FlowControl> *QgsGpsDetector::settingsGpsFlowControl = new QgsSettingsEntryEnumFlag<QSerialPort::FlowControl>( QStringLiteral( "flow-control" ), QgsSettingsTree::sTreeGps, QSerialPort::NoFlowControl );
39const QgsSettingsEntryEnumFlag<QSerialPort::StopBits> *QgsGpsDetector::settingsGpsStopBits = new QgsSettingsEntryEnumFlag<QSerialPort::StopBits>( QStringLiteral( "stop-bits" ), QgsSettingsTree::sTreeGps, QSerialPort::OneStop );
40const QgsSettingsEntryEnumFlag<QSerialPort::DataBits> *QgsGpsDetector::settingsGpsDataBits = new QgsSettingsEntryEnumFlag<QSerialPort::DataBits>( QStringLiteral( "data-bits" ), QgsSettingsTree::sTreeGps, QSerialPort::Data8 );
41const QgsSettingsEntryEnumFlag<QSerialPort::Parity> *QgsGpsDetector::settingsGpsParity = new QgsSettingsEntryEnumFlag<QSerialPort::Parity>( QStringLiteral( "parity" ), QgsSettingsTree::sTreeGps, QSerialPort::NoParity );
42#endif
43
44QList< QPair<QString, QString> > QgsGpsDetector::availablePorts()
45{
46 QList< QPair<QString, QString> > devs;
47
48 // try local QtLocation first
49#if defined(QT_POSITIONING_LIB)
50 devs << QPair<QString, QString>( QStringLiteral( "internalGPS" ), tr( "internal GPS" ) );
51#endif
52
53 // try local gpsd first
54 devs << QPair<QString, QString>( QStringLiteral( "localhost:2947:" ), tr( "local gpsd" ) );
55
56 // try serial ports
57#if defined( HAVE_QTSERIALPORT )
58 for ( const QSerialPortInfo &p : QSerialPortInfo::availablePorts() )
59 {
60 devs << QPair<QString, QString>( p.portName(), tr( "%1: %2" ).arg( p.portName(), p.description() ) );
61 }
62#endif
63
64 return devs;
65}
66
67QgsGpsDetector::QgsGpsDetector( const QString &portName )
68{
69#if defined( HAVE_QTSERIALPORT )
70 mBaudList << QSerialPort::Baud4800 << QSerialPort::Baud9600 << QSerialPort::Baud38400 << QSerialPort::Baud57600 << QSerialPort::Baud115200; //add 57600 for SXBlueII GPS unit
71#endif
72
73 if ( portName.isEmpty() )
74 {
75 mPortList = availablePorts();
76 }
77 else
78 {
79 mPortList << QPair<QString, QString>( portName, portName );
80 }
81}
82
84
86{
87 mConn.reset();
88
89 while ( !mConn )
90 {
91 mBaudIndex++;
92 if ( mBaudIndex == mBaudList.size() )
93 {
94 mBaudIndex = 0;
95 mPortIndex++;
96 }
97
98 if ( mPortIndex == mPortList.size() )
99 {
100 emit detectionFailed();
101 deleteLater();
102 return;
103 }
104
105 if ( mPortList.at( mPortIndex ).first.contains( ':' ) )
106 {
107 mBaudIndex = mBaudList.size() - 1;
108
109 QStringList gpsParams = mPortList.at( mPortIndex ).first.split( ':' );
110
111 Q_ASSERT( gpsParams.size() >= 3 );
112
113 mConn = std::make_unique< QgsGpsdConnection >( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] );
114 }
115 else if ( mPortList.at( mPortIndex ).first.contains( QLatin1String( "internalGPS" ) ) )
116 {
117#if defined(QT_POSITIONING_LIB)
118 mConn = std::make_unique< QgsQtLocationConnection >();
119#else
120 qWarning( "QT_POSITIONING_LIB not found and mPortList matches internalGPS, this should never happen" );
121#endif
122 }
123 else
124 {
125#if defined( HAVE_QTSERIALPORT )
126 std::unique_ptr< QSerialPort > serial = std::make_unique< QSerialPort >( mPortList.at( mPortIndex ).first );
127
128 serial->setBaudRate( mBaudList[ mBaudIndex ] );
129
130 serial->setFlowControl( QgsGpsDetector::settingsGpsFlowControl->value() );
131 serial->setParity( QgsGpsDetector::settingsGpsParity->value() );
132 serial->setDataBits( QgsGpsDetector::settingsGpsDataBits->value() );
133 serial->setStopBits( QgsGpsDetector::settingsGpsStopBits->value() );
134
135 if ( serial->open( QIODevice::ReadOnly ) )
136 {
137 mConn = std::make_unique< QgsNmeaConnection >( serial.release() );
138 }
139#else
140 qWarning( "QT5SERIALPORT not found and mPortList matches serial port, this should never happen" );
141#endif
142 }
143 }
144
145 connect( mConn.get(), &QgsGpsConnection::stateChanged, this, static_cast < void ( QgsGpsDetector::* )( const QgsGpsInformation & ) >( &QgsGpsDetector::detected ) );
146 connect( mConn.get(), &QObject::destroyed, this, &QgsGpsDetector::connDestroyed );
147
148 // leave 2s to pickup a valid string
149 QTimer::singleShot( 2000, this, &QgsGpsDetector::advance );
150}
151
153{
154 Q_UNUSED( info )
155
156 if ( !mConn )
157 {
158 // advance if connection was destroyed
159 advance();
160 }
161 else if ( mConn->status() == QgsGpsConnection::GPSDataReceived )
162 {
163 // signal detected
164
165 // let's hope there's a single, unique connection to this signal... otherwise... boom
166 emit detected( mConn.release() );
167
168 deleteLater();
169 }
170}
171
173{
174 // WTF? This whole class needs re-writing...
175 if ( obj == mConn.get() )
176 {
177 mConn.release();
178 }
179}
void stateChanged(const QgsGpsInformation &info)
Emitted whenever the GPS state is changed.
Class to detect the GPS port.
~QgsGpsDetector() override
void connDestroyed(QObject *)
void detected(const QgsGpsInformation &)
static QList< QPair< QString, QString > > availablePorts()
QgsGpsDetector(const QString &portName)
void detectionFailed()
Encapsulates information relating to a GPS position fix.
A template class for enum and flag settings entry.
static QgsSettingsTreeNode * sTreeGps