FlightDisplayViewMap.qml 11.5 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (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.
 *
 ****************************************************************************/
9 10


11 12 13 14 15
import QtQuick          2.3
import QtQuick.Controls 1.2
import QtLocation       5.3
import QtPositioning    5.3
import QtQuick.Dialogs  1.2
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

import QGroundControl               1.0
import QGroundControl.FlightDisplay 1.0
import QGroundControl.FlightMap     1.0
import QGroundControl.ScreenTools   1.0
import QGroundControl.Controls      1.0
import QGroundControl.Palette       1.0
import QGroundControl.Vehicle       1.0
import QGroundControl.Controllers   1.0

FlightMap {
    id:             flightMap
    anchors.fill:   parent
    mapName:        _mapName

31
    property alias  missionController: missionController
Don Gagne's avatar
Don Gagne committed
32
    property var    flightWidgets
33
    property var    rightPanelWidth
34
    property var    qgcView             ///< QGCView control which contains this map
Don Gagne's avatar
Don Gagne committed
35

36 37
    property bool   _followVehicleSetting:          true                                                    ///< User facing setting for follow vehicle
    property bool   _followVehicle:                 _followVehicleSetting && _activeVehicleCoordinateValid  ///< Control map follow vehicle functionality
Don Gagne's avatar
Don Gagne committed
38 39 40 41
    property var    _activeVehicle:                 QGroundControl.multiVehicleManager.activeVehicle
    property bool   _activeVehicleCoordinateValid:  _activeVehicle ? _activeVehicle.coordinateValid : false
    property var    activeVehicleCoordinate:        _activeVehicle ? _activeVehicle.coordinate : QtPositioning.coordinate()
    property var    _gotoHereCoordinate:            QtPositioning.coordinate()
42
    property int    _retaskSequence:                0
43
    property real   _toolButtonTopMargin:           parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
44 45
    property bool   _firstVehicleCoordinate:        false
    property bool   _centerUpdateFromTimer:         true
46

47 48 49 50
    Component.onCompleted: {
        QGroundControl.flightMapPosition = center
        QGroundControl.flightMapZoom = zoomLevel
    }
51

52
    onZoomLevelChanged: QGroundControl.flightMapZoom = zoomLevel
53

54 55 56 57 58 59 60 61 62 63
    onCenterChanged: {
        if (_centerUpdateFromTimer) {
            _centerUpdateFromTimer = false
        } else {
            vehicleCenterTimer.restart()
        }

        QGroundControl.flightMapPosition = center
    }

64
    onActiveVehicleCoordinateChanged: {
65 66 67 68 69 70 71 72
        if (!_firstVehicleCoordinate && _activeVehicleCoordinateValid) {
            _firstVehicleCoordinate = true
            updateMapToVehiclePosition()
        }
    }

    function updateMapToVehiclePosition() {
        if (_followVehicle) {
73
            _initialMapPositionSet = true
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
            _firstVehicleCoordinate = true
            _centerUpdateFromTimer = true
            flightMap.center = activeVehicleCoordinate
        }
    }

    Timer {
        id:                 vehicleCenterTimer
        interval:           5000
        running:            true
        triggeredOnStart:   true
        repeat:             true

        onTriggered: {
            triggeredOnStart = false
            updateMapToVehiclePosition()
90 91 92
        }
    }

Don Gagne's avatar
Don Gagne committed
93
    QGCPalette { id: qgcPal; colorGroupEnabled: true }
94
    QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
Don Gagne's avatar
Don Gagne committed
95

96
    MissionController {
97
        id: missionController
98 99 100
        Component.onCompleted: start(false /* editMode */)
    }

101
    GeoFenceController {
102
        id: geoFenceController
103 104 105
        Component.onCompleted: start(false /* editMode */)
    }

106 107 108 109 110
    RallyPointController {
        id: rallyPointController
        Component.onCompleted: start(false /* editMode */)
    }

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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
    // The following code is used to track vehicle states such that we prompt to remove mission from vehicle when mission completes

    property bool vehicleArmed:                 _activeVehicle ? _activeVehicle.armed : false
    property bool vehicleWasArmed:              false
    property bool vehicleInMissionFlightMode:   _activeVehicle ? (_activeVehicle.flightMode === _activeVehicle.missionFlightMode) : false
    property bool promptForMissionRemove:       false

    onVehicleArmedChanged: {
        if (vehicleArmed) {
            if (!promptForMissionRemove) {
                promptForMissionRemove = vehicleInMissionFlightMode
                vehicleWasArmed = true
            }
        } else {
            if (promptForMissionRemove && (missionController.containsItems || geoFenceController.containsItems || rallyPointController.containsItems)) {
                qgcView.showDialog(removeMissionDialogComponent, qsTr("Flight complete"), showDialogDefaultWidth, StandardButton.No | StandardButton.Yes)
            }
            promptForMissionRemove = false
        }
    }

    onVehicleInMissionFlightModeChanged: {
        if (!promptForMissionRemove && vehicleArmed) {
            promptForMissionRemove = true
        }
    }

    Component {
        id: removeMissionDialogComponent

        QGCViewMessage {
            message: qsTr("Do you want to remove the mission from the vehicle?")

            function accept() {
                missionController.removeAllFromVehicle()
                geoFenceController.removeAllFromVehicle()
                rallyPointController.removeAllFromVehicle()
                hideDialog()

            }
        }
    }

154
    ExclusiveGroup {
Don Gagne's avatar
Don Gagne committed
155
        id: _mapTypeButtonsExclusiveGroup
156 157
    }

Don Gagne's avatar
Don Gagne committed
158 159 160 161 162 163 164 165 166
    ToolStrip {
        id:                 toolStrip
        anchors.leftMargin: ScreenTools.defaultFontPixelWidth
        anchors.left:       parent.left
        anchors.topMargin:  _toolButtonTopMargin
        anchors.top:        parent.top
        color:              qgcPal.window
        title:              qsTr("Fly")
        z:                  QGroundControl.zOrderWidgets
167
        buttonVisible:      [ true, _showZoom, _showZoom ]
168
        maxHeight:          (_flightVideo.visible ? _flightVideo.y : parent.height) - toolStrip.y   // Massive reach across hack
Don Gagne's avatar
Don Gagne committed
169

Don Gagne's avatar
Don Gagne committed
170
        property bool _showZoom: !ScreenTools.isMobile
Don Gagne's avatar
Don Gagne committed
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

        model: [
            {
                name:               "Center",
                iconSource:         "/qmlimages/MapCenter.svg",
                dropPanelComponent: centerMapDropPanel
            },
            {
                name:               "In",
                iconSource:         "/qmlimages/ZoomPlus.svg"
            },
            {
                name:               "Out",
                iconSource:         "/qmlimages/ZoomMinus.svg"
            }
        ]
187 188

        onClicked: {
Don Gagne's avatar
Don Gagne committed
189 190 191 192 193 194 195
            switch (index) {
            case 2:
                _flightMap.zoomLevel += 0.5
                break
            case 3:
                _flightMap.zoomLevel -= 0.5
                break
196 197 198 199
            }
        }
    }

Don Gagne's avatar
Don Gagne committed
200
    // Toolstrip drop panel compomnents
Don Gagne's avatar
Don Gagne committed
201

Don Gagne's avatar
Don Gagne committed
202 203 204 205 206 207 208 209
    MapFitFunctions {
        id:                         mapFitFunctions
        map:                        _flightMap
        mapFitViewport:             Qt.rect(leftToolWidth, _toolButtonTopMargin, flightMap.width - leftToolWidth - rightPanelWidth, flightMap.height - _toolButtonTopMargin)
        usePlannedHomePosition:     false
        mapMissionController:      missionController
        mapGeoFenceController:     geoFenceController
        mapRallyPointController:   rallyPointController
210

Don Gagne's avatar
Don Gagne committed
211 212
        property real leftToolWidth:    toolStrip.x + toolStrip.width
    }
213

Don Gagne's avatar
Don Gagne committed
214 215
    Component {
        id: centerMapDropPanel
216

Don Gagne's avatar
Don Gagne committed
217
        CenterMapDropPanel {
218 219 220
            map:                _flightMap
            fitFunctions:       mapFitFunctions
            showFollowVehicle:  true
221
            followVehicle:      _followVehicleSetting
222

223
            onFollowVehicleChanged: _followVehicleSetting = followVehicle
Don Gagne's avatar
Don Gagne committed
224 225
        }
    }
226

227 228
    // Add trajectory points to the map
    MapItemView {
229
        model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints : 0 : 0
230 231
        delegate:
            MapPolyline {
Don Gagne's avatar
Don Gagne committed
232 233 234 235
            line.width: 3
            line.color: "red"
            z:          QGroundControl.zOrderMapItems - 1
            path: [
236 237
                object.coordinate1,
                object.coordinate2,
Don Gagne's avatar
Don Gagne committed
238 239
            ]
        }
240 241 242 243
    }

    // Add the vehicles to the map
    MapItemView {
244
        model: QGroundControl.multiVehicleManager.vehicles
245 246
        delegate:
            VehicleMapItem {
Don Gagne's avatar
Don Gagne committed
247 248 249
            vehicle:        object
            coordinate:     object.coordinate
            isSatellite:    flightMap.isSatelliteMap
Gus Grubba's avatar
Gus Grubba committed
250
            size:           _mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight
251
            z:              QGroundControl.zOrderMapItems - 1
Don Gagne's avatar
Don Gagne committed
252
        }
253 254
    }

255 256
    // Add the mission item visuals to the map
    Repeater {
257
        model: _mainIsMap ? missionController.visualItems : 0
258 259

        delegate: MissionItemMapVisual {
260 261 262 263 264 265
            map:        flightMap

            onClicked: {
                _retaskSequence = object.sequenceNumber
                flightWidgets.guidedModeBar.confirmAction(parent.flightWidgets.guidedModeBar.confirmRetask)
            }
266
        }
267 268 269 270
    }

    // Add lines between waypoints
    MissionLineView {
271
        model: _mainIsMap ? missionController.waypointLines : 0
272 273
    }

274 275 276 277 278
    GeoFenceMapVisuals {
        map:                    flightMap
        myGeoFenceController:   geoFenceController
        interactive:            false
        homePosition:           _activeVehicle && _activeVehicle.homePositionAvailable ? _activeVehicle.homePosition : undefined
279 280
    }

281 282 283 284 285 286
    // Rally points on map
    MapItemView {
        model: rallyPointController.points

        delegate: MapQuickItem {
            id:             itemIndicator
287 288
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
289 290 291 292 293 294 295 296 297 298
            coordinate:     object.coordinate
            z:              QGroundControl.zOrderMapItems

            sourceItem: MissionItemIndexLabel {
                id:         itemIndexLabel
                label:      qsTr("R", "rally point map item label")
            }
        }
    }

Don Gagne's avatar
Don Gagne committed
299 300 301
    // GoTo here waypoint
    MapQuickItem {
        coordinate:     _gotoHereCoordinate
Don Gagne's avatar
Don Gagne committed
302
        visible:        _activeVehicle && _activeVehicle.guidedMode && _gotoHereCoordinate.isValid
Don Gagne's avatar
Don Gagne committed
303
        z:              QGroundControl.zOrderMapItems
304 305
        anchorPoint.x:  sourceItem.anchorPointX
        anchorPoint.y:  sourceItem.anchorPointY
Don Gagne's avatar
Don Gagne committed
306 307

        sourceItem: MissionItemIndexLabel {
308 309
            checked: true
            label:   qsTr("G", "Goto here waypoint") // second string is translator's hint.
Don Gagne's avatar
Don Gagne committed
310
        }
311 312 313 314 315 316 317 318 319
    }    

    MapScale {
        anchors.bottomMargin:   ScreenTools.defaultFontPixelHeight * (0.66)
        anchors.rightMargin:    ScreenTools.defaultFontPixelHeight * (0.33)
        anchors.bottom:         parent.bottom
        anchors.right:          parent.right
        mapControl:             flightMap
        visible:                !ScreenTools.isTinyScreen
Don Gagne's avatar
Don Gagne committed
320 321 322
    }

    // Handle guided mode clicks
323 324
    MouseArea {
        anchors.fill: parent
Don Gagne's avatar
Don Gagne committed
325 326

        onClicked: {
Don Gagne's avatar
Don Gagne committed
327
            if (_activeVehicle) {
328
                if (flightWidgets.guidedModeBar.state != "Shown") {
Don Gagne's avatar
Don Gagne committed
329
                    flightWidgets.guidedModeBar.state = "Shown"
330 331
                } else {
                    if (flightWidgets.gotoEnabled) {
DonLakeFlyer's avatar
DonLakeFlyer committed
332
                        _gotoHereCoordinate = flightMap.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
333 334
                        flightWidgets.guidedModeBar.confirmAction(flightWidgets.guidedModeBar.confirmGoTo)
                    }
Don Gagne's avatar
Don Gagne committed
335
                }
Don Gagne's avatar
Don Gagne committed
336 337
            }
        }
338 339
    }
}