// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page location-positioning-cpp.html

\title Positioning (C++)

\brief The Location Positioning API enables location positioning by means of
GPS or an NMEA data source.

\section1 Positioning

The Positioning component of the Qt Location API is about the geographical
position, size, and address of some place. Positioning contains a
\l QGeoCoordinate class, containing latitude, longitude and altitude in meters.
\l QGeoLocation contains a \l QGeoCoordinate plus address and size information
(a bounding box) so that positions can be more than mathematical points.
Movement into or out of the defined bounding box areas can be monitored. The API
also allows the developer to control the source of the positional information
as well.

Location data involves a precisely specified position on the Earth's
surface \unicode {0x2014} as provided by a latitude-longitude coordinate
\unicode {0x2014} along with associated data, such as:

    \list
    \li The date and time at which the position was reported
    \li The velocity of the device that reported the position
    \li The altitude of the reported position (height above sea level)
    \li The bearing of the device in degrees, relative to true north
    \endlist

This data can be extracted through a variety of methods. One of the most
well known methods of positioning is GPS (Global Positioning System), a
publicly available system that uses radiowave signals received from
Earth-orbiting satellites to calculate the precise position and time of
the receiver. Another popular method is 'Cell Identifier Positioning', which uses
the cell identifier of the cell site that is currently serving the receiving
device to calculate its approximate location. These and other positioning
methods can all be used with the Location API; the only requirement for a
location data source within the API is that it provides a
latitude-longitude coordinate with a date/time value, with the option of
providing the other attributes listed above.


Location data sources are created by subclassing \l QGeoPositionInfoSource and
providing \l QGeoPositionInfo objects through the
\l {QGeoPositionInfoSource::positionUpdated()} signal. Clients that require
location data can connect to the
\l{QGeoPositionInfoSource::positionUpdated()}{positionUpdated()} signal and
call \l{QGeoPositionInfoSource::startUpdates()}{startUpdates()} or
\l{QGeoPositionInfoSource::requestUpdate()}{requestUpdate()} to trigger the
distribution of location data. The location data distribution can be stopped by
calling the \l {QGeoPositionInfoSource::stopUpdates()}{stopUpdates()} function.

A default position source may be available on some platforms. Call
\l {QGeoPositionInfoSource::createDefaultSource()} to create an instance of the
default position source. The method returns \c nullptr if no default source is
available for the platform.

If a problem occurs with access to the information source then an
\l {QGeoPositionInfoSource::errorOccurred()}{errorOccurred()} signal is emitted.

The \l QGeoAreaMonitorSource class enables client applications to be notified
when the receiving device has moved into or out of a particular area, as
specified by a coordinate and radius. If the platform provides built-in support
for area monitoring, the \l {QGeoAreaMonitorSource::createDefaultSource()}
method returns an instance of the default area monitor.

Satellite information can also be distributed through the
\l QGeoSatelliteInfoSource class. Call
\l {QGeoSatelliteInfoSource::createDefaultSource()} to create an instance of the
default satellite data source for the platform if one is available.
Alternatively, clients can subclass it to provide a custom satellite data
source.



\section2 Requesting Location Data from Data Sources

To receive data from a source, connect to its
\l{QGeoPositionInfoSource::positionUpdated()}{positionUpdated()} signal,
then call either \l{QGeoPositionInfoSource::startUpdates()}{startUpdates()}
or \l{QGeoPositionInfoSource::requestUpdate()}{requestUpdate()} to begin.

Here is an example of a client that receives data from the default location
data source, as returned by \l {QGeoPositionInfoSource::createDefaultSource()}:

\code
class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass(QObject *parent = 0)
        : QObject(parent)
    {
        QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
        if (source) {
            connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
                    this, SLOT(positionUpdated(QGeoPositionInfo)));
            source->startUpdates();
        }
    }

private slots:
    void positionUpdated(const QGeoPositionInfo &info)
    {
        qDebug() << "Position updated:" << info;
    }
};

\endcode

\section2 Controlling Aspects of Data Sources

The \l {QGeoPositionInfoSource::setUpdateInterval()} method can be used to
control the rate at which position updates are received. For example, if
the client application only requires updates once every 30 seconds, it can
call \c setUpdateInterval(30000). If no update interval is set, or
\l {QGeoPositionInfoSource::}{setUpdateInterval()} is called with a value of 0,
the source uses a default interval or some other internal logic to determine
when updates should be provided.

\l {QGeoPositionInfoSource::setPreferredPositioningMethods()} enables client
applications to request that a certain type of positioning method be used.
For example, if the application prefers to use only satellite positioning,
which offers fairly precise outdoor positioning but can be a heavy user of
power resources, it can call this method with the
\l {QGeoPositionInfoSource::SatellitePositioningMethods} value. However, this
method should only be used in specialized client applications; in most
cases, the default positioning methods should not be changed, as a source
may internally use a variety of positioning methods that can be useful to
the application.

\section2 NMEA Data

\l {http://en.wikipedia.org/wiki/NMEA_0183}{NMEA} is a common text-based
protocol for specifying navigational data. For convenience, the
\l QNmeaPositionInfoSource is provided to enable client applications to read
and distribute NMEA data in either real-time mode (for example, when
streaming from a GPS device) or simulation mode (for example, when reading
from a NMEA log file). In simulation mode, the source will emit updates
according to the time stamp of each NMEA sentence to produce a "replay"
of the recorded data.

Generally, the capabilities provided by the default position source as
returned by \l {QGeoPositionInfoSource::createDefaultSource()}, along with the
\l QNmeaPositionInfoSource class, are sufficient for retrieving location
data. However, in some cases developers may wish to write their own custom
location data source.

The \l {Log File Position Source (C++)} example demonstrates how to subclass
\l QGeoPositionInfoSource to create a custom positioning source.

\section1 Examples

\section3 \b{Log File Position Source Example}

The \l{Log File Position Source (C++)}{Log File Position Source} Example demonstrates
how to subclass \l QGeoPositionInfoSource to create a custom positioning source.

\section3 \b{Weather Info Example}

The \l{Weather Info} example shows how to use the user's current
position to retrieve local content from a web service in a C++ plugin for QML.

\section1 Positioning Classes

\annotatedlist QtPositioning-positioning

*/
