Log File Position Source (C++) | Qt Positioning 5.5

- Qt 5.5
- Qt Positioning
- Log File Position Source (C++)
- Qt 5.5.1 Reference Documentation

# Log File Position Source (C++)

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
    {
        Q_OBJECT
    public:
        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();

    private:
        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()));

        logFile->setFileName(":/simplelog.txt");
        if (!logFile->open(QIODevice::ReadOnly))
            qWarning() << "Error: cannot open source file" << logFile->fileName();
    }

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

        timer->start(interval);
    }

    void LogFilePositionSource::stopUpdates()
    {
        timer->stop();
    }

    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())
            readNextPosition();
        else
            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);
                }
            }
        }
    }

Files:

- logfilepositionsource/clientapplication.cpp
- logfilepositionsource/clientapplication.h
- logfilepositionsource/logfilepositionsource.cpp
- logfilepositionsource/logfilepositionsource.h
- logfilepositionsource/main.cpp
- logfilepositionsource/logfile.qrc
- logfilepositionsource/logfilepositionsource.pro