FWLandingPatternMapVisual.qml 7.65 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10 11 12 13
import QtQuick          2.3
import QtQuick.Controls 1.2
import QtLocation       5.3
import QtPositioning    5.3
14

15
import QGroundControl               1.0
16 17 18
import QGroundControl.ScreenTools   1.0
import QGroundControl.Palette       1.0
import QGroundControl.Controls      1.0
19
import QGroundControl.FlightMap     1.0
20 21 22

/// Fixed Wing Landing Pattern map visuals
Item {
23 24
    id: _root

DonLakeFlyer's avatar
DonLakeFlyer committed
25 26
    property var map        ///< Map control to place item in
    property var qgcView    ///< QGCView to use for popping dialogs
27

28 29
    signal clicked(int sequenceNumber)

30
    property var _missionItem:  object
Don Gagne's avatar
Don Gagne committed
31
    property var _itemVisuals: [ ]
32
    property var _mouseArea
Don Gagne's avatar
Don Gagne committed
33
    property var _dragAreas: [ ]
34
    property var _flightPath
Don Gagne's avatar
Don Gagne committed
35 36 37 38 39

    readonly property int _flightPathIndex:     0
    readonly property int _loiterPointIndex:    1
    readonly property int _loiterRadiusIndex:   2
    readonly property int _landPointIndex:      3
40

41
    function hideItemVisuals() {
Don Gagne's avatar
Don Gagne committed
42 43
        for (var i=0; i<_itemVisuals.length; i++) {
            _itemVisuals[i].destroy()
44
        }
Don Gagne's avatar
Don Gagne committed
45
        _itemVisuals = [ ]
46 47 48
    }

    function showItemVisuals() {
Don Gagne's avatar
Don Gagne committed
49 50 51 52 53 54 55 56 57 58 59 60 61
        if (_itemVisuals.length === 0) {
            var itemVisual = flightPathComponent.createObject(map)
            map.addMapItem(itemVisual)
            _itemVisuals[_flightPathIndex] =itemVisual
            itemVisual = loiterPointComponent.createObject(map)
            map.addMapItem(itemVisual)
            _itemVisuals[_loiterPointIndex] = itemVisual
            itemVisual = loiterRadiusComponent.createObject(map)
            map.addMapItem(itemVisual)
            _itemVisuals[_loiterRadiusIndex] = itemVisual
            itemVisual = landPointComponent.createObject(map)
            map.addMapItem(itemVisual)
            _itemVisuals[_landPointIndex] = itemVisual
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        }
    }

    function hideMouseArea() {
        if (_mouseArea) {
            _mouseArea.destroy()
            _mouseArea = undefined
        }
    }

    function showMouseArea() {
        if (!_mouseArea) {
            _mouseArea = mouseAreaComponent.createObject(map)
            map.addMapItem(_mouseArea)
        }
    }

    function hideDragAreas() {
Don Gagne's avatar
Don Gagne committed
80 81
        for (var i=0; i<_dragAreas.length; i++) {
            _dragAreas[i].destroy()
82
        }
Don Gagne's avatar
Don Gagne committed
83
        _dragAreas = [ ]
84 85 86
    }

    function showDragAreas() {
Don Gagne's avatar
Don Gagne committed
87
        if (_dragAreas.length === 0) {
88 89
            _dragAreas.push(loiterDragAreaComponent.createObject(map))
            _dragAreas.push(landDragAreaComponent.createObject(map))
90 91 92
        }
    }

93 94
    function _setFlightPath() {
        _flightPath = [ _missionItem.loiterTangentCoordinate, _missionItem.landingCoordinate ]
95 96
    }

97
    Component.onCompleted: {
98 99
        if (_missionItem.landingCoordSet) {
            showItemVisuals()
100
            if (!_missionItem.flyView && _missionItem.isCurrentItem) {
101 102
                showDragAreas()
            }
103
            _setFlightPath()
104
        } else if (!_missionItem.flyView && _missionItem.isCurrentItem) {
105 106
            showMouseArea()
        }
107 108 109
    }

    Component.onDestruction: {
110 111 112 113 114 115 116 117 118
        hideDragAreas()
        hideMouseArea()
        hideItemVisuals()
    }

    Connections {
        target: _missionItem

        onIsCurrentItemChanged: {
119 120 121
            if (_missionItem.flyView) {
                return
            }
122 123 124 125 126 127 128 129 130 131 132 133 134
            if (_missionItem.isCurrentItem) {
                if (_missionItem.landingCoordSet) {
                    showDragAreas()
                } else {
                    showMouseArea()
                }
            } else {
                hideMouseArea()
                hideDragAreas()
            }
        }

        onLandingCoordSetChanged: {
135 136 137
            if (_missionItem.flyView) {
                return
            }
138 139 140 141
            if (_missionItem.landingCoordSet) {
                hideMouseArea()
                showItemVisuals()
                showDragAreas()
142
                _setFlightPath()
143 144 145 146 147
            } else if (_missionItem.isCurrentItem) {
                hideDragAreas()
                showMouseArea()
            }
        }
148

149 150
        onLandingCoordinateChanged:         _setFlightPath()
        onLoiterTangentCoordinateChanged:   _setFlightPath()
151 152 153 154 155 156 157 158 159 160
    }

    // Mouse area to capture landing point coordindate
    Component {
        id:  mouseAreaComponent

        MouseArea {
            anchors.fill: map

            onClicked: {
DonLakeFlyer's avatar
DonLakeFlyer committed
161
                var coordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
162 163 164 165 166 167 168 169
                coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
                coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
                coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
                _missionItem.landingCoordinate = coordinate
            }
        }
    }

170
    // Control which is used to drag the loiter point
171
    Component {
172
        id: loiterDragAreaComponent
173

174
        MissionItemIndicatorDrag {
175 176
            itemIndicator:  _itemVisuals[_loiterPointIndex]
            itemCoordinate: _missionItem.loiterCoordinate
177

178
            onItemCoordinateChanged: _missionItem.loiterCoordinate = itemCoordinate
179 180 181 182 183 184 185 186
        }
    }

    // Control which is used to drag the loiter point
    Component {
        id: landDragAreaComponent

        MissionItemIndicatorDrag {
187 188
            itemIndicator:  _itemVisuals[_landPointIndex]
            itemCoordinate: _missionItem.landingCoordinate
189

190
            onItemCoordinateChanged: _missionItem.landingCoordinate = itemCoordinate
191
        }
192 193 194 195 196 197 198
    }

    // Flight path
    Component {
        id: flightPathComponent

        MapPolyline {
199
            z:          QGroundControl.zOrderMapItems - 1   // Under item indicators
Don Gagne's avatar
Don Gagne committed
200
            line.color: "#be781c"
201
            line.width: 2
202
            path:       _flightPath
203 204 205 206 207
        }
    }

    // Loiter point
    Component {
208
        id: loiterPointComponent
209 210

        MapQuickItem {
211 212
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
213 214
            z:              QGroundControl.zOrderMapItems
            coordinate:     _missionItem.loiterCoordinate
215 216 217

            sourceItem:
                MissionItemIndexLabel {
218
                index:      _missionItem.sequenceNumber
219 220 221
                label:      "Loiter"
                checked:    _missionItem.isCurrentItem

222
                onClicked: _root.clicked(_missionItem.sequenceNumber)
223 224 225 226
            }
        }
    }

Don Gagne's avatar
Don Gagne committed
227 228 229 230 231 232 233
    // Loiter radius visual
    Component {
        id: loiterRadiusComponent

        MapCircle {
            z:              QGroundControl.zOrderMapItems
            center:         _missionItem.loiterCoordinate
234
            radius:         _missionItem.loiterRadius.rawValue
Don Gagne's avatar
Don Gagne committed
235 236 237 238 239 240
            border.width:   2
            border.color:   "green"
            color:          "transparent"
        }
    }

241 242 243 244 245
    // Land point
    Component {
        id: landPointComponent

        MapQuickItem {
246 247
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
248 249 250 251 252
            z:              QGroundControl.zOrderMapItems
            coordinate:     _missionItem.landingCoordinate

            sourceItem:
                MissionItemIndexLabel {
253
                index:      _missionItem.lastSequenceNumber
254
                label:      "Land"
Don Gagne's avatar
Don Gagne committed
255
                checked:    _missionItem.isCurrentItem
256

257
                onClicked: _root.clicked(_missionItem.sequenceNumber)
258
            }
259 260 261
        }
    }
}