ログファイルポジションソース (C++)

Logfile Position Sourceは、カスタム・ポジション・ソースの作成と操作方法を示します。GPSデータをシミュレートする場合や、データをカスタム・フォーマットで受信する場合に便利です。

例の実行

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

カスタムポジションソースの作成

この例では、データはテキストファイルsimplelog.txt から読み込まれます。このファイルは、単純なテキスト形式を使用して位置データを指定します:それは1行につき1つの位置更新を含み、各行は日付/時刻、緯度、経度をスペースで区切って含みます。日付/時刻はISO 8601フォーマットで、緯度と経度は10進法である。以下は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

QGeoPositionInfoSource から派生したカスタムクラスLogFilePositionSource を作成します。このクラスはファイルから位置データを読み込み、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(): クライアントアプリケーションから、指定されたタイムアウトで1回の更新を要求するために呼び出されます。

位置の更新が可能になると、サブクラスは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 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。