22#include <QApplication> 
   34#define KNOTS_TO_KMH 1.852 
   50  if ( ! 
mSource->isSequential() ) 
 
   56    numBytes = 
mSource->bytesAvailable();
 
 
   77  int endSentenceIndex = 0;
 
   80  while ( ( endSentenceIndex = 
mStringBuffer.indexOf( QLatin1String( 
"\r\n" ) ) ) && endSentenceIndex != -1 )
 
   82    endSentenceIndex = 
mStringBuffer.indexOf( QLatin1String( 
"\r\n" ) );
 
   85    if ( endSentenceIndex == -1 )
 
   90    if ( endSentenceIndex >= dollarIndex )
 
   92      if ( dollarIndex != -1 )
 
   94        const QString substring = 
mStringBuffer.mid( dollarIndex, endSentenceIndex );
 
   95        QByteArray ba = substring.toLocal8Bit();
 
   96        if ( substring.startsWith( QLatin1String( 
"$GPGGA" ) ) || substring.startsWith( QLatin1String( 
"$GNGGA" ) ) )
 
  102          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  104        else if ( substring.startsWith( QLatin1String( 
"$GPRMC" ) ) || substring.startsWith( QLatin1String( 
"$GNRMC" ) ) )
 
  110          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  113        else if ( substring.startsWith( QLatin1String( 
"$GPGSV" ) ) || substring.startsWith( QLatin1String( 
"$GNGSV" ) ) || substring.startsWith( QLatin1String( 
"$GLGSV" ) ) || substring.startsWith( QLatin1String( 
"$GAGSV" ) ) || substring.startsWith( QLatin1String( 
"$GBGSV" ) ) || substring.startsWith( QLatin1String( 
"$GQGSV" ) ) )
 
  119          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  121        else if ( substring.startsWith( QLatin1String( 
"$GPVTG" ) ) || substring.startsWith( QLatin1String( 
"$GNVTG" ) ) )
 
  127          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  129        else if ( substring.startsWith( QLatin1String( 
"$GPGSA" ) ) || substring.startsWith( QLatin1String( 
"$GNGSA" ) ) || substring.startsWith( QLatin1String( 
"$GLGSA" ) ) )
 
  134          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  136        else if ( substring.startsWith( QLatin1String( 
"$GPGST" ) ) || substring.startsWith( QLatin1String( 
"$GNGST" ) ) )
 
  142          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  144        else if ( substring.startsWith( QLatin1String( 
"$GPHDT" ) ) || substring.startsWith( QLatin1String( 
"$GNHDT" ) ) )
 
  150          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  152        else if ( substring.startsWith( QLatin1String( 
"$HCHDG" ) ) )
 
  158          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  160        else if ( substring.startsWith( QLatin1String( 
"$HCHDT" ) ) )
 
  166          QgsDebugMsgLevel( QStringLiteral( 
"*******************GPS data received****************" ), 2 );
 
  171          QgsDebugMsgLevel( QStringLiteral( 
"unknown nmea sentence: %1" ).arg( substring ), 2 );
 
 
  183  if ( nmea_parse_GPGGA( data, len, &result ) )
 
  186    double longitude = result.lon;
 
  187    if ( result.ew == 
'W' )
 
  189      longitude = -longitude;
 
  191    double latitude = result.lat;
 
  192    if ( result.ns == 
'S' )
 
  194      latitude = -latitude;
 
  202    const QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec );
 
  203    if ( time.isValid() )
 
  216    if ( result.sig >= 0 && result.sig <= 8 )
 
 
  232  if ( nmea_parse_GPGST( data, len, &result ) )
 
  235    const double sig_lat = result.sig_lat;
 
  236    const double sig_lon = result.sig_lon;
 
  237    const double sig_alt = result.sig_alt;
 
 
  251  if ( nmea_parse_GPHDT( data, len, &result ) )
 
 
  260  if ( nmea_parse_HCHDG( data, len, &result ) )
 
  263    if ( result.ew_variation == 
'E' )
 
 
  273  if ( nmea_parse_HCHDT( data, len, &result ) )
 
 
  282  if ( nmea_parse_GPRMC( data, len, &result ) )
 
  284    double longitude = result.lon;
 
  285    if ( result.ew == 
'W' )
 
  287      longitude = -longitude;
 
  289    double latitude = result.lat;
 
  290    if ( result.ns == 
'S' )
 
  292      latitude = -latitude;
 
  297    if ( !std::isnan( result.direction ) )
 
  301    const QDate date( result.utc.year + 1900, result.utc.mon + 1, result.utc.day );
 
  302    const QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec );
 
  303    if ( date.isValid() && time.isValid() )
 
  317    if ( result.status == 
'A' )
 
  319      if ( result.mode == 
'A' )
 
  324      else if ( result.mode == 
'D' )
 
  329      else if ( result.mode == 
'P' )
 
  334      else if ( result.mode == 
'R' )
 
  339      else if ( result.mode == 
'F' )
 
  344      else if ( result.mode == 
'E' )
 
  349      else if ( result.mode == 
'M' )
 
  354      else if ( result.mode == 
'S' )
 
 
  376  if ( nmea_parse_GPGSV( data, len, &result ) )
 
  379    for ( 
int i = 0; i < NMEA_SATINPACK; ++i )
 
  381      const nmeaSATELLITE currentSatellite = result.sat_data[i];
 
  383      satelliteInfo.
azimuth = currentSatellite.azimuth;
 
  384      satelliteInfo.
elevation = currentSatellite.elv;
 
  385      satelliteInfo.
id = currentSatellite.id;
 
  386      satelliteInfo.
inUse = 
false;
 
  391          satelliteInfo.
inUse = 
true;
 
  394      satelliteInfo.
signal = currentSatellite.sig;
 
  395      satelliteInfo.
satType = result.pack_type;
 
  397      if ( result.pack_type == 
'P' )
 
  401      else if ( result.pack_type == 
'L' )
 
  405      else if ( result.pack_type == 
'A' )
 
  409      else if ( result.pack_type == 
'B' )
 
  413      else if ( result.pack_type == 
'Q' )
 
  418      if ( satelliteInfo.
satType == 
'P' && satelliteInfo.
id > 32 )
 
  422        satelliteInfo.
id = currentSatellite.id + 87;
 
  425      bool idAlreadyPresent = 
false;
 
  430          if ( existingSatInView.id == currentSatellite.id )
 
  432            idAlreadyPresent = 
true;
 
  438      if ( !idAlreadyPresent && currentSatellite.azimuth > 0 && currentSatellite.elv > 0 )
 
 
  450  if ( nmea_parse_GPVTG( data, len, &result ) )
 
  453    if ( !std::isnan( result.dir ) )
 
 
  469  if ( nmea_parse_GPGSA( data, len, &result ) )
 
  479    bool mixedConstellation = 
false;
 
  480    for ( 
int i = 0; i < NMEA_MAXSAT; i++ )
 
  482      if ( result.sat_prn[ i ] > 0 )
 
  488        if ( result.pack_type == 
'L' || result.sat_prn[i] > 64 )
 
  490        else if ( result.sat_prn[i] >= 1 && result.sat_prn[i] <= 32 )
 
  492        else if ( result.sat_prn[i] > 32 && result.sat_prn[i] <= 64 )
 
  496        if ( result.sat_prn[i] > 0 )
 
  498          if ( mixedConstellation
 
  500                    && commonConstellation != constellation ) )
 
  502            mixedConstellation = 
true;
 
  506            commonConstellation = constellation;
 
  511    if ( mixedConstellation )
 
  514    switch ( result.fix_type )
 
 
GnssConstellation
GNSS constellation.
@ Gps
Global Positioning System (GPS)
@ Glonass
Global Navigation Satellite System (GLONASS)
@ Unknown
Unknown/other system.
@ Qzss
Quasi Zenith Satellite System (QZSS)
GpsQualityIndicator
GPS signal quality indicator.
@ RTK
Real-time-kynematic.
@ Simulation
Simulation mode.
@ FloatRTK
Float real-time-kynematic.
@ Manual
Manual input mode.
Abstract base class for connection to a GPS device.
QgsGpsInformation mLastGPSInformation
Last state of the gps related variables (e.g. position, time, ...)
void nmeaSentenceReceived(const QString &substring)
Emitted whenever the GPS device receives a raw NMEA sentence.
std::unique_ptr< QIODevice > mSource
Data source (e.g. serial device, socket, file,...)
Status mStatus
Connection status.
void stateChanged(const QgsGpsInformation &info)
Emitted whenever the GPS state is changed.
void processVtgSentence(const char *data, int len)
process VTG sentence
void processRmcSentence(const char *data, int len)
process RMC sentence
void processHchdtSentence(const char *data, int len)
process HCHDT sentence
void parseData() override
Parse available data source content.
void processHchdgSentence(const char *data, int len)
process HCHDG sentence
void processGgaSentence(const char *data, int len)
process GGA sentence
void processGsvSentence(const char *data, int len)
process GSV sentence
void processGstSentence(const char *data, int len)
process GST sentence
void processHdtSentence(const char *data, int len)
process HDT sentence
void processGsaSentence(const char *data, int len)
process GSA sentence
QString mStringBuffer
Store data from the device before it is processed.
QgsNmeaConnection(QIODevice *device)
Constructs a QgsNmeaConnection with given device.
void processStringBuffer()
Splits mStringBuffer into sentences and calls libnmea.
Encapsulates information relating to a GPS satellite.
double elevation
Elevation of the satellite, in degrees.
bool inUse
true if satellite was used in obtaining the position fix.
int signal
Signal strength (0-99dB), or -1 if not available.
int id
Contains the satellite identifier number.
double azimuth
The azimuth of the satellite to true north, in degrees.
QChar satType
satType value from NMEA message $GxGSV, where x: P = GPS; S = SBAS (GPSid> 32 then SBasid = GPSid + 8...
#define QgsDebugMsgLevel(str, level)