日志文件位置源(C++)

日志文件位置源示例演示了如何创建和使用自定义位置源。这可以用于模拟GPS数据,或在接收数据为某种自定义格式时很有用。

运行示例

要从Qt Creator运行示例,打开欢迎模式并从示例中选择示例。有关更多信息,请参阅构建和运行示例

创建自定义位置源

在此示例中,数据从文本文件simplelog.txt中读取。该文件使用简单的文本格式指定位置数据:每行包含一个日期/时间、纬度和经度,由空格分隔。日期/时间是ISO 8601格式,纬度和经度是十进制度格式。以下是simplelog.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

我们创建了一个自定义的LogFilePositionSource类,它从QGeoPositionInfoSource继承。它从文件中读取位置数据并通过positionUpdated()信号分发。

然后,将时间和位置信息以日期/时间和纬度/经度格式显示在屏幕上的简单文本中。

以下是LogFilePositionSource类的定义

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

    QGeoPositionInfo lastKnownPosition(bool satelliteMethodsOnly = false) const override;

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

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

    virtual void requestUpdate(int timeout = 5000) override;

private slots:
    void readNextPosition();

private:
    QFile *logFile;
    QTimer *timer;
    QGeoPositionInfo lastPosition;
    Error lastError = QGeoPositionInfoSource::NoError;
};

子类中重写的最主要方法是

  • startUpdates(): 由客户端应用程序调用以启动定期位置更新。
  • stopUpdates(): 由客户端应用程序调用以停止定期位置更新。
  • requestUpdate(): 由客户端应用程序调用以请求单个更新,具有指定的超时时间。

当可用位置更新时,子类会发出positionUpdated()信号。

以下是类实现中的关键方法

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

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

void LogFilePositionSource::startUpdates()
{
    lastError = QGeoPositionInfoSource::NoError;
    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
    lastError = QGeoPositionInfoSource::NoError;
    if (logFile->canReadLine()) {
        readNextPosition();
    } else {
        lastError = QGeoPositionInfoSource::UpdateTimeoutError;
        emit QGeoPositionInfoSource::errorOccurred(lastError);
    }
}

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);
            }
        }
    }
}

示例项目 @ code.qt.io

© 2024 Qt公司有限公司。此处包含的文档贡献者的版权所有。此处提供的文档根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款进行许可。Qt和相应的标志是芬兰的Qt公司及其在全世界其他国家的商标。所有其他商标的所有权均归其各自所有者。