FWLandingPatternMapVisual.qml 7.38 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

25 26
    property var map    ///< Map control to place item in

27 28
    signal clicked(int sequenceNumber)

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

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

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

    function showItemVisuals() {
Don Gagne's avatar
Don Gagne committed
48 49 50 51 52 53 54 55 56 57 58 59 60
        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
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
        }
    }

    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
79 80
        for (var i=0; i<_dragAreas.length; i++) {
            _dragAreas[i].destroy()
81
        }
Don Gagne's avatar
Don Gagne committed
82
        _dragAreas = [ ]
83 84 85
    }

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

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

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

    Component.onDestruction: {
109 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
        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()
135
                _setFlightPath()
136 137 138 139 140
            } else if (_missionItem.isCurrentItem) {
                hideDragAreas()
                showMouseArea()
            }
        }
141

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

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

        MouseArea {
            anchors.fill: map

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

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

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

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

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

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

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

    // Flight path
    Component {
        id: flightPathComponent

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

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

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

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

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

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

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

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

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

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

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