Log File Position Source (C++)

The Logfile Position Source shows how to create and work with a custom NMEA position source, for platforms without GPS.

The data is read from a file which has positional data in NMEA format. The resulting time and position information is then displayed to the screen as simple text in date/time and latitude/longitude format.

This example class reads position data from a text file, log.txt. The file specifies position data using a simple text format: it contains one position update per line, where each line contains a date/time, a latitude and a longitude, separated by spaces. The date/time is in ISO 8601 format and the latitude and longitude are in degrees decimal format. Here is an excerpt from log.txt:

2009-08-24T22:25:01 -27.576082 153.092415
2009-08-24T22:25:02 -27.576223 153.092530
2009-08-24T22:25:03 -27.576364 153.092648

The class reads this data and distributes it via the positionUpdated() signal.

Here is the definition of the LogFilePositionSource class:

class LogFilePositionSource : public QGeoPositionInfoSource
    LogFilePositionSource(QObject *parent = 0);

    QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;

    PositioningMethods supportedPositioningMethods() const;
    int minimumUpdateInterval() const;
    Error error() const;

public slots:
    virtual void startUpdates();
    virtual void stopUpdates();

    virtual void requestUpdate(int timeout = 5000);

private slots:
    void readNextPosition();

    QFile *logFile;
    QTimer *timer;
    QGeoPositionInfo lastPosition;

The main methods overrided by the subclass are:

  • startUpdates(): called by client applications to start regular position updates.
  • stopUpdates(): called by client applications to stop regular position updates.
  • requestUpdate(): called by client applications to request a single update, with a specified timeout.

When a position update is available, the subclass emits the positionUpdated() signal.

Here are the key methods in the class implementation:

LogFilePositionSource::LogFilePositionSource(QObject *parent)
    : QGeoPositionInfoSource(parent),
      logFile(new QFile(this)),
      timer(new QTimer(this))
    connect(timer, SIGNAL(timeout()), this, SLOT(readNextPosition()));

    if (!logFile->open(QIODevice::ReadOnly))
        qWarning() << "Error: cannot open source file" << logFile->fileName();

void LogFilePositionSource::startUpdates()
    int interval = updateInterval();
    if (interval < minimumUpdateInterval())
        interval = minimumUpdateInterval();


void LogFilePositionSource::stopUpdates()

void LogFilePositionSource::requestUpdate(int /*timeout*/)
    // For simplicity, ignore timeout - assume that if data is not available
    // now, no data will be added to the file later
    if (logFile->canReadLine())
        emit updateTimeout();

void LogFilePositionSource::readNextPosition()
    QByteArray line = logFile->readLine().trimmed();
    if (!line.isEmpty()) {
        QList<QByteArray> data = line.split(' ');
        double latitude;
        double longitude;
        bool hasLatitude = false;
        bool hasLongitude = false;
        QDateTime timestamp = QDateTime::fromString(QString(data.value(0)), Qt::ISODate);
        latitude = data.value(1).toDouble(&hasLatitude);
        longitude = data.value(2).toDouble(&hasLongitude);

        if (hasLatitude && hasLongitude && timestamp.isValid()) {
            QGeoCoordinate coordinate(latitude, longitude);
            QGeoPositionInfo info(coordinate, timestamp);
            if (info.isValid()) {
                lastPosition = info;
                emit positionUpdated(info);

Example project @ code.qt.io

© 2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.