衛星情報

Satellite Info の例では、Sky View、Table View、RSSI View を使って利用可能な衛星と、ユーザの現在位置を表示します。これはQt PositioningQt Quick で実装されています。

この例では、Qt Positioning QML API の使い方を説明します:

この例では、C++ のカスタムモデルを、QML のカスタムプロキシモデルと組み合わせて使用する方法も示しています。

UIの概要

この例では、3つの異なるタブで衛星情報を表示しています。データは、SatelliteSource::satellitesInView およびSatelliteSource::satellitesInUse プロパティから取得されています。

スカイ・ビュー」タブでは、Azimuth およびElevation attributes を使用して、衛星の相対位置を表示します。個々の衛星オブジェクトをクリックすると、satellite identifier 、方位と仰角のポップアップが開きます。

テーブル・ビュー(Table View)タブでは、検出されたすべての衛星のリストが表示され、 リストにソートとフィルタリングを適用できます。

RSSI表示タブでは、signalStrength プロパティを使用して、表示中の衛星の信号強度が表示されます。バーの下の数字は、個々のsatellite identifiers を表します。

スカイビューと RSSIビュータブには、現在の緯度と経度も表示されます。これらの情報は、PositionSource::position プロパティを使用して抽出されます。

タブの上部にあるステータスブロックは、現在のモードまたは最後のエラーを表示します。

設定メニューでは、アプリケーションのカラーモードを切り替えたり、ヘルプ情報を表示したりできます。

アプリケーションは3つの異なるモードで動作します:

アプリケーションモードアプリケーションモード
実行中アプリケーションは継続的に衛星と位置の更新をシステムに問い合わせます。新しいデータが利用可能になると表示されます。
停止中アプリケーションは衛星と位置情報の更新を停止します。
単一アプリケーションは衛星と位置の更新要求を 1 回だけ行います。

プラットフォームが衛星や位置情報を提供しない場合、アプリケーションは自動的にシミュレーションモードに切り替わります。シミュレーションモードでは、事前に記録されたNMEAデータを使用するNMEAプラグインを使用します。

注: Appleは衛星情報を取得するAPIを提供していないため、macOS およびiOS では、衛星情報は常に事前に記録されたデータから取得されます。これらのAPIの制限は測位情報には影響しないため、現在位置を正しく表示することができます。

例の実行

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

現在位置の取得

現在位置は、PositionSource QML オブジェクトから取得します。位置の更新を受け取るにはonPositionChanged ハンドラを使います。緯度と経度の文字列表現はcoordinate プロパティから抽出されます。

PositionSource {
    id: positionSource
    name: root.simulation ? "nmea" : ""
    onPositionChanged: {
        let posData = position.coordinate.toString().split(", ")
        positionBox.latitudeString = posData[0]
        positionBox.longitudeString = posData[1]
    }
}

衛星情報の取得

位置と同様に、現在の衛星情報はSatelliteSource QMLオブジェクトから取得されます。onSatellitesInViewChangedonSatellitesInUseChanged のハンドラを使って、それぞれ最新の衛星情報と使用中の衛星情報を取得します。この例では、このデータはC++ モデルに転送され、後にすべてのビューで使用されます。

SatelliteSource {
    id: satelliteSource
    name: root.simulation ? "nmea" : ""
    onSatellitesInViewChanged: root.satellitesModel.updateSatellitesInView(satellitesInView)
    onSatellitesInUseChanged: root.satellitesModel.updateSatellitesInUse(satellitesInUse)
}

注: この例では、QMLの測位APIとC++モデルのQMLへの統合の両方を示しています。そのため、衛星情報はまずQML で取得され、次にC++ に転送され、そしてQML に戻ってモデルで使用されます。実際には、アプリケーションが複雑なC++ モデルを使用することを想定している場合は、C++QGeoSatelliteInfoSource クラスを直接使用することを検討してください。

カスタムC++モデルの使用

この例では、SatelliteModelSortFilterModel の2つのカスタム・モデルを使用しています。

衛星モデル

SatelliteModel クラスは、QAbstractListModel から派生し、rowCount()、data()、roleNames() メソッドを再実装して衛星情報を表現しています。QAbstractListModel を基本クラスとして使用することで、QML ListView およびRepeater 型のモデルを簡単に使用することができます。カスタムsize プロパティは、タブバーの幅を動的に計算するために、RSSI ビュータブでのみ使用されます。

class SatelliteModel : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(int size READ rowCount NOTIFY sizeChanged)
    QML_ELEMENT
public:
    explicit SatelliteModel(QObject *parent = nullptr);

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

public slots:
    void updateSatellitesInView(const QList<QGeoSatelliteInfo> &inView);
    void updateSatellitesInUse(const QList<QGeoSatelliteInfo> &inUse);

signals:
    void sizeChanged();
};

roleNames() メソッドは、モデルのロールを、QML からモデル・データにアクセスするために使用できるプロパティ名にマッピングするために使用されます。例えば、id の名前は衛星識別子を抽出するために使用され、rssi の名前は信号強度を取得するために使用されます。

QHash<int, QByteArray> SatelliteModel::roleNames() const
{
    return {
        {Roles::IdRole, "id"},
        {Roles::RssiRole, "rssi"},
        {Roles::AzimuthRole, "azimuth"},
        {Roles::ElevationRole, "elevation"},
        {Roles::SystemRole, "system"},
        {Roles::SystemIdRole, "systemId"},
        {Roles::InUseRole, "inUse"},
        {Roles::VisibleNameRole, "name"}
    };
}

QML 側では、これらの名前を使用して実際の値を取得できる。例えば、RSSI Viewの実装では、rssiinUseid の役割名を使用して、個々の衛星を表すバーを描画しています:

Repeater {
    id: repeater
    model: root.satellitesModel
    delegate: Rectangle {
        required property var modelData
        height: rect.height
        width: view.singleWidth
        color: "transparent"
        SemiRoundedRectangle {
            anchors.bottom: satId.top
            width: parent.width
            height: (parent.height - satId.height)
                    * Math.min(parent.modelData.rssi, rect.maxVisibleLevel)
                    / rect.maxVisibleLevel
            color: parent.modelData.inUse ? root.inUseColor : root.inViewColor
        }
        Text {
            id: satId
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            text: parent.modelData.id
            color: Theme.textSecondaryColor
            font.pixelSize: Theme.smallFontSize
            font.weight: Theme.fontLightWeight
        }
    }
}
プロキシモデル

SortFilterModel クラスは、テーブル・ビュー・タブに表示される衛星オブジェクトのカスタム・ソートと フィルタリングを提供するために使用されます。

このモデルは、QSortFilterProxyModel から派生し、filterAcceptsRow() とlessThan() メソッドを再実装して、フィルタリングとソートを提供します。このモデルはまた、フィルタリングとソートの動作を調整するために、いくつかのslots

class SortFilterModel : public QSortFilterProxyModel
{
    Q_OBJECT
    QML_ELEMENT
public:
    explicit SortFilterModel(QObject *parent = nullptr);

public slots:
    void updateFilterString(const QString &str);
    void updateShowInView(bool show);
    void updateShowInUse(bool show);
    void updateSelectedSystems(int id, bool show);
    void updateSortRoles(int role, bool use);

protected:
    bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
    bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
};

これらのスロットは、C++QML の両方から呼び出すことができます。例えば、Satellite Identifierデリゲートは、updateSelectedSystems() スロットを使用して、特定の衛星システムに属する衛星に関する情報を表示または非表示にする。同様に、Satellite Statusデリゲートは、updateShowInView()updateShowInUse() のスロットを使って、特定のステータスの衛星をフィルタリングする。

Repeater {
    model: root.satelliteSystemModel
    delegate: CheckElement {
        required property var modelData
        text: modelData.name
        Layout.alignment: Qt.AlignRight
        onCheckedChanged: {
            root.sortFilterModel.updateSelectedSystems(modelData.id, checked)
        }
    }
}
    ...
CheckElement {
    text: qsTr("In View")
    Layout.alignment: Qt.AlignRight
    onCheckedChanged: root.sortFilterModel.updateShowInView(checked)
}
CheckElement {
    text: qsTr("In Use")
    Layout.alignment: Qt.AlignRight
    onCheckedChanged: root.sortFilterModel.updateShowInUse(checked)
}

QMLモジュールの登録

CMakeビルド

CMakeベースのビルドでは、CMakeLists.txt

qt_add_qml_module(satelliteinfo
    URI SatelliteInformation
    VERSION 1.0
    SOURCES
        roles.h
        satellitemodel.cpp satellitemodel.h
        sortfiltermodel.cpp sortfiltermodel.h
    QML_FILES
        ApplicationScreen.qml
        Button.qml
        Header.qml
        HelpPopup.qml
        LegendBox.qml
        Main.qml
        RssiView.qml
        PageButton.qml
        PermissionsScreen.qml
        PositionBox.qml
        SatelliteView.qml
        SettingsView.qml
        SkyView.qml
        Theme.qml
        ViewSwitch.qml
    RESOURCES
        icons/checkbox.svg
        icons/checkbox_blank.svg
        icons/darkmode.svg
        icons/filter.svg
        icons/help.svg
        icons/lightmode.svg
        icons/place.svg
        icons/qtlogo_green.png
        icons/qtlogo_white.png
        icons/rssiview.svg
        icons/satellite_small.png
        icons/satellite1.png
        icons/satellite2.png
        icons/search.svg
        icons/settings.svg
        icons/skyview.svg
        icons/sort.svg
        icons/tableview.svg
)
qmake ビルド

qmakeビルドの場合、satelliteinfo.pro

CONFIG += qmltypes
QML_IMPORT_NAME = SatelliteInformation
QML_IMPORT_MAJOR_VERSION = 1

qml_resources.files = \
    qmldir \
    ApplicationScreen.qml \
    Button.qml \
    Header.qml \
    HelpPopup.qml \
    LegendBox.qml \
    Main.qml \
    RssiView.qml \
    PageButton.qml \
    PermissionsScreen.qml \
    PositionBox.qml \
    SatelliteView.qml \
    SettingsView.qml \
    SkyView.qml \
    Theme.qml \
    ViewSwitch.qml

qml_resources.prefix = /qt/qml/SatelliteInformation

RESOURCES += qml_resources

icon_resources.files = \
    icons/checkbox.svg \
    icons/checkbox_blank.svg \
    icons/darkmode.svg \
    icons/filter.svg \
    icons/help.svg \
    icons/lightmode.svg \
    icons/place.svg \
    icons/qtlogo_green.png \
    icons/qtlogo_white.png \
    icons/rssiview.svg \
    icons/satellite_small.png \
    icons/satellite1.png \
    icons/satellite2.png \
    icons/search.svg \
    icons/settings.svg \
    icons/skyview.svg \
    icons/sort.svg \
    icons/tableview.svg

icon_resources.prefix = /qt/qml/SatelliteInformation

RESOURCES += icon_resources

サンプルプロジェクト @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。