Revision control
Copy as Markdown
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example satelliteinfo
\title Satellite Info
\examplecategory {Application Examples}
\examplecategory {Positioning & Location}
\meta tags {c++, qml, quick}
\ingroup qtpositioning-examples
\brief The Satellite Info example shows the available satellites
using Sky View, Table View, or RSSI View and the user's current position.
It is implemented with \l{Qt Positioning} and \l{Qt Quick}.
This example demonstrates the usage of \l {Qt Positioning QML Types}
{Qt Positioning QML API}:
\list
\li \l {PositionSource}
\li \l {SatelliteSource}
\endlist
The example also shows how to use a custom \c {C++} model together with a
custom proxy model from \c {QML}.
\include examples-run.qdocinc
\section1 UI walkthrough
The example shows satellite information in three different tabs.
The data is taken from the \l {SatelliteSource::satellitesInView} and
\l {SatelliteSource::satellitesInUse} properties.
\image ../images/skyview_tableview.webp {Satellite view and table UI}
The \e {Sky View} tab shows the relative satellite positions using the
\c {Azimuth} and \c {Elevation} \l {geoSatelliteInfo::attribute}
{attributes}. Clicking on an individual satellite object opens a popup
with the \l {geoSatelliteInfo::satelliteIdentifier} {satellite identifier},
its azimuth, and elevation.
The \e {Table View} tab shows the list of all detected satellites, and
allows to apply sorting and filtering to the list.
\image ../images/rssiview_settings.webp {RSSI view with satellite signal bars}
The \e {RSSI View} tab shows the signal strength of satellites in view using
the \l {geoSatelliteInfo::}{signalStrength} property. The numbers below the
bars represent the individual \l {geoSatelliteInfo::satelliteIdentifier}
{satellite identifiers}.
The \e {Sky View} and \e {RSSI View} tabs also show the current latitude and
longitude. They use \l {PositionSource::position} property to extract this
information.
The \e {Status} block on top of the tabs shows the current mode or the last
error.
The \e {Settings} menu allows you to switch the application color mode and
show the help information.
The application operates in three different modes:
\table
\header
\li Application mode
\li Description
\row
\li Running
\li The application continuously queries the system for satellite
and position updates. When new data is available, it will be
displayed.
\row
\li Stopped
\li The application stops updating the satellite and position
information.
\row
\li Single
\li The application makes a single satellite and position update
request.
\endtable
The application automatically switches into a simulation mode if the
platform does not provide satellite or position information. The simulation
mode uses an \l {Qt Positioning NMEA plugin}{NMEA plugin} with pre-recorded
NMEA data.
\note Apple does not provide any APIs to retrieve satellite information, so
on \c macOS and \c iOS the satellite information will always be taken from
pre-recorded data. These API limitations do not affect positioning
information, so current position can be displayed correctly.
\section1 Retrieving Current Position
The current position is retrieved from the \l PositionSource QML object. The
\c {onPositionChanged} handler is used to receive position updates. The
string representations of latitude and longitude are extracted from the
\l {Position::}{coordinate} property.
\snippet satelliteinfo/ApplicationScreen.qml 3
\snippet satelliteinfo/ApplicationScreen.qml 4
\snippet satelliteinfo/ApplicationScreen.qml 5
\section1 Retrieving Satellite Information
Similarly to the position, the current satellite information is retrieved
from the \l SatelliteSource QML object. The \c {onSatellitesInViewChanged}
and \c {onSatellitesInUseChanged} handlers are used to get the updated
satellites in view and satellites in use respectively. In this example, the
data is then forwarded to the \c {C++} model, which is later used in all
views.
\snippet satelliteinfo/ApplicationScreen.qml 0
\snippet satelliteinfo/ApplicationScreen.qml 1
\snippet satelliteinfo/ApplicationScreen.qml 2
\note The example shows both the QML Positioning API, and the integration
of C++ model to QML. That is the reason why the satellite information is
first retrieved in \c {QML}, then forwarded to \c {C++}, and then back to
\c {QML} to be used in the model. In practice, if the application is
supposed to use complex \c {C++} models, consider directly using the
\l QGeoSatelliteInfoSource class from \c {C++}.
\section1 Using Custom C++ Models
The example uses two custom models - \c {SatelliteModel} and
\c {SortFilterModel}.
\section2 Satellite Model
The \c {SatelliteModel} class is derived from \l QAbstractListModel and
reimplements the \l {QAbstractListModel::}{rowCount()},
\l {QAbstractListModel::}{data()}, and
\l {QAbstractListModel::}{roleNames()} methods to represent the
satellite information. Using \l QAbstractListModel as a base class allows
to easily use the model with the \c {QML} \l ListView and \l Repeater types.
A custom \c {size} property is used only in the \e {RSSI View} tab to
dynamically calculate the width of the tab bars.
\snippet satelliteinfo/satellitemodel.h 0
\snippet satelliteinfo/satellitemodel.h 1
The \c {roleNames()} method is used to map the model's roles to the
property names which can be used to access the model data from \c {QML}.
For example, the \c {id} name is used to extract the satellite identifier,
and the \c {rssi} name is used to get the signal strength.
\snippet satelliteinfo/satellitemodel.cpp 0
On the \c {QML} side, we can use these names to get the actual values.
For example, the implementation of \e {RSSI View} uses the \c {rssi},
\c {inUse}, and \c {id} role names to draw the bars that represent
individual satellites:
\snippet satelliteinfo/RssiView.qml 0
\section2 Proxy Model
The \c {SortFilterModel} class is used to provide custom sorting and
filtering of the satellite objects shown in the \e {Table View} tab.
The model is derived from \l QSortFilterProxyModel and reimplements the
\l {QSortFilterProxyModel::}{filterAcceptsRow()} and
\l {QSortFilterProxyModel::}{lessThan()} methods to provide filtering and
sorting. The model also exposes several \c {slots} to tune the filtering
and sorting behavior.
\snippet satelliteinfo/sortfiltermodel.h 0
\snippet satelliteinfo/sortfiltermodel.h 1
These slots can be called from both \c {C++} and \c {QML}. For example, the
\e {Satellite Identifier} delegate uses the \c {updateSelectedSystems()}
slot to show or hide the information about satellites belonging to certain
satellite systems. Likewise, the \e {Satellite Status} delegates use the
\c {updateShowInView()} and \c {updateShowInUse()} slots to filter the
satellites with a specific status.
\snippet satelliteinfo/SatelliteView.qml 0
\dots
\snippet satelliteinfo/SatelliteView.qml 1
\section1 QML Module Registration
\section2 CMake Build
For a CMake-based build, we need to add the following to the
\c {CMakeLists.txt}:
\quotefromfile satelliteinfo/CMakeLists.txt
\skipto qt_add_qml_module(satelliteinfo
\printuntil )
\section2 qmake Build
For a qmake build, we need to modify the \c {satelliteinfo.pro} file in the
following way:
\quotefromfile satelliteinfo/satelliteinfo.pro
\skipto CONFIG += qmltypes
\printuntil QML_IMPORT_MAJOR_VERSION = 1
\skipto qml_resources.files
\printuntil RESOURCES += icon_resources
\section1 Source files
\sa {All Qt Examples}, {Qt Positioning Examples},
{Qt Quick Examples and Tutorials}
*/