1/**************************************************************************** 2** 3** Copyright (C) 2017 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the documentation of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:FDL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** GNU Free Documentation License Usage 18** Alternatively, this file may be used under the terms of the GNU Free 19** Documentation License version 1.3 as published by the Free Software 20** Foundation and appearing in the file included in the packaging of 21** this file. Please review the following information to ensure 22** the GNU Free Documentation License version 1.3 requirements 23** will be met: https://www.gnu.org/licenses/fdl-1.3.html. 24** $QT_END_LICENSE$ 25** 26****************************************************************************/ 27 28/*! 29 \example planespotter 30 \title Plane Spotter (QML) 31 \ingroup qtlocation-examples 32 33 \brief The \c {Plane Spotter} example demonstrates the tight integration of 34 location and positioning data types into QML. 35 36 \image planespotter.png 37 38 The \c {Plane Spotter} example demonstrates how to integrate location and positioning 39 related C++ data types into QML and vice versa. This is useful when it is desirable to 40 run CPU intensive position calculations in native environments 41 but the results are supposed to be displayed using QML. 42 43 The example shows a map of Europe and airplanes on two routes across Europe. 44 The first airplane commutes between Oslo and Berlin and the second airplane 45 commutes between London and Berlin. The position tracking of each airplane 46 is implemented in C++. The Oslo-Berlin plane is piloted in QML and the London-Berlin 47 plane is commanded by a C++ pilot. 48 49 \include examples-run.qdocinc 50 51 \section1 Overview 52 53 54 This example makes use of the \l Q_GADGET feature as part of its position controller 55 implementation. It permits \l {Cpp_value_integration_positioning}{direct integration} 56 of non-QObject based C++ value types into QML. 57 58 The main purpose of the \c PlaneController class is to track the current 59 coordinates of the plane at a given time. It exposes the position 60 via its position property. 61 62 \snippet planespotter/main.cpp PlaneController1 63 \snippet planespotter/main.cpp PlaneController2 64 65 The example's \c main() function is responsible for the binding of the 66 \c PlaneController class instances into the QML context: 67 68 \snippet planespotter/main.cpp PlaneControllerMain 69 70 Similar to QObject derived classes, \l QGeoCoordinate can be integrated without 71 an additional QML wrapper. 72 73 \section1 Steering the Planes 74 75 As mentioned above, the primary purpose of \c PlaneController class is to track the current 76 positions of the two planes (Oslo-Berlin and London-Berlin) and advertise them as a property 77 to the QML layer. Its secondary purpose is to set and progress a plane along a given 78 flight path. In a sense it can act as a pilot. This is very much like 79 \l CoordinateAnimation which can animate the transition from one geo coordinate to another. 80 This example demonstrates how the \c {PlaneController}'s position property is modified 81 by C++ code using the PlaneController's own piloting abilities and by QML code using 82 \l CoordinateAnimation as pilot. The Oslo-Berlin plane is animated using QML code 83 and the London-Berlin plane is animated using C++ code. 84 85 No matter which pilot is used, the results to the pilot's 86 actions are visible in C++ and QML and thus the example demonstrates unhindered and direct 87 exchange of position data through the C++/QML boundary. 88 89 The visual representation of each \c Plane is done using 90 the \l MapQuickItem type which permits the embedding of arbitrary QtQuick items 91 into a map: 92 93 \snippet planespotter/Plane.qml PlaneMapQuick1 94 \snippet planespotter/Plane.qml PlaneMapQuick2 95 96 \section2 The C++ Pilot 97 98 The C++ plane is steered by C++. The \c from and \c to property of the controller 99 class set the origin and destination which the pilot uses to calculate the 100 bearing for the plane: 101 102 \snippet planespotter/main.cpp C++Pilot1 103 104 The pilot employs a \l QBasicTimer and \l {QTimerEvent}{QTimerEvents} to 105 constantly update the position. During each timer iteration 106 \c PlaneController::updatePosition() is called and a new position calculated. 107 108 \snippet planespotter/main.cpp C++Pilot3 109 110 Once the new position is calculated, \c setPosition() is called and 111 the subsequent change notification of the property pushes the new position 112 to the QML layer. 113 114 The C++ plane is started by clicking on the plane: 115 116 \snippet planespotter/planespotter.qml CppPlane1 117 \snippet planespotter/planespotter.qml CppPlane2 118 119 \l {azimuthTo}() calculates the bearing in degrees from one coordinate to another. 120 Note that the above code utilizes a QML animation to tie the rotation 121 and the position change into a single animation flow: 122 123 \snippet planespotter/planespotter.qml CppPlane3 124 125 First, \l NumberAnimation rotates the plane into the correct direction 126 and once that is done the \c startFlight() function takes care of 127 starting the plane's position change. 128 129 \snippet planespotter/main.cpp C++Pilot2 130 131 \section2 The QML Pilot 132 133 The \l CoordinateAnimation type is used to control the flight from Oslo 134 to Berlin and vice versa. It replaces the above \l ScriptAction. 135 136 \snippet planespotter/planespotter.qml QmlPlane1 137 138 The \l MouseArea of the QML plane implements the logic for the course setting 139 and starts the animation when required. 140 141 \snippet planespotter/planespotter.qml QmlPlane2 142 143*/ 144