FWLandingPatternMapVisual.qml 7.45 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 100 101 102
        if (_missionItem.landingCoordSet) {
            showItemVisuals()
            if (_missionItem.isCurrentItem) {
                showDragAreas()
            }
103
            _setFlightPath()
104 105 106
        } else if (_missionItem.isCurrentItem) {
            showMouseArea()
        }
107 108 109
    }

    Component.onDestruction: {
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
        hideDragAreas()
        hideMouseArea()
        hideItemVisuals()
    }

    Connections {
        target: _missionItem

        onIsCurrentItemChanged: {
            if (_missionItem.isCurrentItem) {
                if (_missionItem.landingCoordSet) {
                    showDragAreas()
                } else {
                    showMouseArea()
                }
            } else {
                hideMouseArea()
                hideDragAreas()
            }
        }

        onLandingCoordSetChanged: {
            if (_missionItem.landingCoordSet) {
                hideMouseArea()
                showItemVisuals()
                showDragAreas()
136
                _setFlightPath()
137 138 139 140 141
            } else if (_missionItem.isCurrentItem) {
                hideDragAreas()
                showMouseArea()
            }
        }
142

143 144
        onLandingCoordinateChanged:         _setFlightPath()
        onLoiterTangentCoordinateChanged:   _setFlightPath()
145 146 147 148 149 150 151 152 153 154
    }

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

        MouseArea {
            anchors.fill: map

            onClicked: {
DonLakeFlyer's avatar
DonLakeFlyer committed
155
                var coordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
156 157 158 159 160 161 162 163
                coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
                coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
                coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
                _missionItem.landingCoordinate = coordinate
            }
        }
    }

164
    // Control which is used to drag the loiter point
165
    Component {
166
        id: loiterDragAreaComponent
167

168
        MissionItemIndicatorDrag {
169 170
            itemIndicator:  _itemVisuals[_loiterPointIndex]
            itemCoordinate: _missionItem.loiterCoordinate
171

172
            onItemCoordinateChanged: _missionItem.loiterCoordinate = itemCoordinate
173 174 175 176 177 178 179 180
        }
    }

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

        MissionItemIndicatorDrag {
181 182
            itemIndicator:  _itemVisuals[_landPointIndex]
            itemCoordinate: _missionItem.landingCoordinate
183

184
            onItemCoordinateChanged: _missionItem.landingCoordinate = itemCoordinate
185
        }
186 187 188 189 190 191 192
    }

    // Flight path
    Component {
        id: flightPathComponent

        MapPolyline {
193
            z:          QGroundControl.zOrderMapItems - 1   // Under item indicators
Don Gagne's avatar
Don Gagne committed
194
            line.color: "#be781c"
195
            line.width: 2
196
            path:       _flightPath
197 198 199 200 201
        }
    }

    // Loiter point
    Component {
202
        id: loiterPointComponent
203 204

        MapQuickItem {
205 206
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
207 208
            z:              QGroundControl.zOrderMapItems
            coordinate:     _missionItem.loiterCoordinate
209 210 211

            sourceItem:
                MissionItemIndexLabel {
212
                index:      _missionItem.sequenceNumber
213 214 215
                label:      "Loiter"
                checked:    _missionItem.isCurrentItem

216
                onClicked: _root.clicked(_missionItem.sequenceNumber)
217 218 219 220
            }
        }
    }

Don Gagne's avatar
Don Gagne committed
221 222 223 224 225 226 227
    // Loiter radius visual
    Component {
        id: loiterRadiusComponent

        MapCircle {
            z:              QGroundControl.zOrderMapItems
            center:         _missionItem.loiterCoordinate
228
            radius:         _missionItem.loiterRadius.rawValue
Don Gagne's avatar
Don Gagne committed
229 230 231 232 233 234
            border.width:   2
            border.color:   "green"
            color:          "transparent"
        }
    }

235 236 237 238 239
    // Land point
    Component {
        id: landPointComponent

        MapQuickItem {
240 241
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
242 243 244 245 246
            z:              QGroundControl.zOrderMapItems
            coordinate:     _missionItem.landingCoordinate

            sourceItem:
                MissionItemIndexLabel {
247
                index:      _missionItem.lastSequenceNumber
248
                label:      "Land"
Don Gagne's avatar
Don Gagne committed
249
                checked:    _missionItem.isCurrentItem
250

251
                onClicked: _root.clicked(_missionItem.sequenceNumber)
252
            }
253 254 255
        }
    }
}