FlightDisplayViewMap.qml 10.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

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 {
27 28 29 30 31
    id:                         flightMap
    anchors.fill:               parent
    mapName:                    _mapName
    allowGCSLocationCenter:     !userPanned
    allowVehicleLocationCenter: !_keepVehicleCentered
32
    planView:                   false
33

34 35
    property alias  scaleState: mapScale.state

36
    // The following properties must be set by the consumer
37
    property var    planMasterController
38
    property var    guidedActionsController
Don Gagne's avatar
Don Gagne committed
39
    property var    flightWidgets
40
    property var    rightPanelWidth
41
    property var    qgcView                             ///< QGCView control which contains this map
Don Gagne's avatar
Don Gagne committed
42

43 44
    property rect   centerViewport:             Qt.rect(0, 0, width, height)

45 46 47 48
    property var    _planMasterController:      planMasterController
    property var    _missionController:         _planMasterController.missionController
    property var    _geoFenceController:        _planMasterController.geoFenceController
    property var    _rallyPointController:      _planMasterController.rallyPointController
49 50 51 52
    property var    _activeVehicle:             QGroundControl.multiVehicleManager.activeVehicle
    property var    _activeVehicleCoordinate:   _activeVehicle ? _activeVehicle.coordinate : QtPositioning.coordinate()
    property var    _gotoHereCoordinate:        QtPositioning.coordinate()
    property real   _toolButtonTopMargin:       parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
53

54 55
    property bool   _disableVehicleTracking:    false
    property bool   _keepVehicleCentered:       _mainIsMap ? false : true
56

57
    // Track last known map position and zoom from Fly view in settings
58
    onZoomLevelChanged: QGroundControl.flightMapZoom = zoomLevel
59
    onCenterChanged:    QGroundControl.flightMapPosition = center
60

61
    // When the user pans the map we stop responding to vehicle coordinate updates until the panRecenterTimer fires
62 63 64
    onUserPannedChanged: {
        _disableVehicleTracking = true
        panRecenterTimer.start()
65 66
    }

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    function pointInRect(point, rect) {
        return point.x > rect.x &&
                point.x < rect.x + rect.width &&
                point.y > rect.y &&
                point.y < rect.y + rect.height;
    }

    property real _animatedLatitudeStart
    property real _animatedLatitudeStop
    property real _animatedLongitudeStart
    property real _animatedLongitudeStop
    property real animatedLatitude
    property real animatedLongitude

    onAnimatedLatitudeChanged: flightMap.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)
    onAnimatedLongitudeChanged: flightMap.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)

    NumberAnimation on animatedLatitude { id: animateLat; from: _animatedLatitudeStart; to: _animatedLatitudeStop; duration: 1000 }
    NumberAnimation on animatedLongitude { id: animateLong; from: _animatedLongitudeStart; to: _animatedLongitudeStop; duration: 1000 }

    function animatedMapRecenter(fromCoord, toCoord) {
        _animatedLatitudeStart = fromCoord.latitude
        _animatedLongitudeStart = fromCoord.longitude
        _animatedLatitudeStop = toCoord.latitude
        _animatedLongitudeStop = toCoord.longitude
        animateLat.start()
        animateLong.start()
    }

    function recenterNeeded() {
97
        var vehiclePoint = flightMap.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
98 99
        var centerViewport = Qt.rect(0, 0, width, height)
        return !pointInRect(vehiclePoint, centerViewport)
100 101 102
    }

    function updateMapToVehiclePosition() {
103 104
        // We let FlightMap handle first vehicle position
        if (firstVehiclePositionReceived && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
105
            if (_keepVehicleCentered) {
106
                flightMap.center = _activeVehicleCoordinate
107
            } else {
DonLakeFlyer's avatar
DonLakeFlyer committed
108
                if (firstVehiclePositionReceived && recenterNeeded()) {
109
                    animatedMapRecenter(flightMap.center, _activeVehicleCoordinate)
110 111
                }
            }
112 113 114 115
        }
    }

    Timer {
116 117 118
        id:         panRecenterTimer
        interval:   10000
        running:    false
119 120

        onTriggered: {
121
            _disableVehicleTracking = false
122
            updateMapToVehiclePosition()
123 124 125
        }
    }

126 127 128 129 130 131 132
    Timer {
        interval:       500
        running:        true
        repeat:         true
        onTriggered:    updateMapToVehiclePosition()
    }

Don Gagne's avatar
Don Gagne committed
133
    QGCPalette { id: qgcPal; colorGroupEnabled: true }
134
    QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
Don Gagne's avatar
Don Gagne committed
135

136
    Connections {
137
        target: _missionController
138 139

        onNewItemsFromVehicle: {
140
            var visualItems = _missionController.visualItems
141 142
            if (visualItems && visualItems.count != 1) {
                mapFitFunctions.fitMapViewportToMissionItems()
143
                firstVehiclePositionReceived = true
144 145
            }
        }
146 147
    }

148
    ExclusiveGroup {
Don Gagne's avatar
Don Gagne committed
149
        id: _mapTypeButtonsExclusiveGroup
150 151
    }

Don Gagne's avatar
Don Gagne committed
152 153 154 155
    MapFitFunctions {
        id:                         mapFitFunctions
        map:                        _flightMap
        usePlannedHomePosition:     false
156
        planMasterController:       _planMasterController
157

Don Gagne's avatar
Don Gagne committed
158 159
        property real leftToolWidth:    toolStrip.x + toolStrip.width
    }
160

161 162
    // Add trajectory points to the map
    MapItemView {
163
        model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints : 0 : 0
DonLakeFlyer's avatar
DonLakeFlyer committed
164 165

        delegate: MapPolyline {
Don Gagne's avatar
Don Gagne committed
166 167
            line.width: 3
            line.color: "red"
DonLakeFlyer's avatar
DonLakeFlyer committed
168
            z:          QGroundControl.zOrderTrajectoryLines
Don Gagne's avatar
Don Gagne committed
169
            path: [
170 171
                object.coordinate1,
                object.coordinate2,
Don Gagne's avatar
Don Gagne committed
172 173
            ]
        }
174 175 176 177
    }

    // Add the vehicles to the map
    MapItemView {
178
        model: QGroundControl.multiVehicleManager.vehicles
DonLakeFlyer's avatar
DonLakeFlyer committed
179 180

        delegate: VehicleMapItem {
Don Gagne's avatar
Don Gagne committed
181 182 183
            vehicle:        object
            coordinate:     object.coordinate
            isSatellite:    flightMap.isSatelliteMap
Gus Grubba's avatar
Gus Grubba committed
184
            size:           _mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight
DonLakeFlyer's avatar
DonLakeFlyer committed
185
            z:              QGroundControl.zOrderVehicles
Don Gagne's avatar
Don Gagne committed
186
        }
187 188
    }

189 190
    // Add the mission item visuals to the map
    Repeater {
191
        model: _mainIsMap ? _missionController.visualItems : 0
192 193

        delegate: MissionItemMapVisual {
194
            map:        flightMap
195
            onClicked:  guidedActionsController.confirmAction(guidedActionsController.actionSetWaypoint, Math.max(object.sequenceNumber, 1))
196
        }
197 198 199 200
    }

    // Add lines between waypoints
    MissionLineView {
201
        model:  _mainIsMap ? _missionController.waypointLines : 0
202 203
    }

204 205
    GeoFenceMapVisuals {
        map:                    flightMap
206
        myGeoFenceController:   _geoFenceController
207
        interactive:            false
208
        planView:               false
209
        homePosition:           _activeVehicle && _activeVehicle.homePosition.isValid ? _activeVehicle.homePosition : undefined
210 211
    }

212 213
    // Rally points on map
    MapItemView {
214
        model: _rallyPointController.points
215 216 217

        delegate: MapQuickItem {
            id:             itemIndicator
218 219
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
220 221 222 223 224 225 226 227 228 229
            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
230 231 232
    // GoTo here waypoint
    MapQuickItem {
        coordinate:     _gotoHereCoordinate
Don Gagne's avatar
Don Gagne committed
233
        visible:        _activeVehicle && _activeVehicle.guidedMode && _gotoHereCoordinate.isValid
Don Gagne's avatar
Don Gagne committed
234
        z:              QGroundControl.zOrderMapItems
235 236
        anchorPoint.x:  sourceItem.anchorPointX
        anchorPoint.y:  sourceItem.anchorPointY
Don Gagne's avatar
Don Gagne committed
237 238

        sourceItem: MissionItemIndexLabel {
239 240
            checked: true
            label:   qsTr("G", "Goto here waypoint") // second string is translator's hint.
Don Gagne's avatar
Don Gagne committed
241
        }
242 243
    }    

244 245
    // Camera points
    MapItemView {
246
        model: _missionController.cameraPoints
247 248 249 250 251 252 253

        delegate: CameraTriggerIndicator {
            coordinate:     object.coordinate
            z:              QGroundControl.zOrderTopMost
        }
    }

Don Gagne's avatar
Don Gagne committed
254
    // Handle guided mode clicks
255 256
    MouseArea {
        anchors.fill: parent
Don Gagne's avatar
Don Gagne committed
257 258

        onClicked: {
259 260 261
            if (guidedActionsController.showGotoLocation) {
                _gotoHereCoordinate = flightMap.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
                guidedActionsController.confirmAction(guidedActionsController.actionGoto, _gotoHereCoordinate)
Don Gagne's avatar
Don Gagne committed
262 263
            }
        }
264
    }
265 266

    MapScale {
267
        id:                     mapScale
268
        anchors.right:          parent.right
269 270 271
        anchors.margins:        ScreenTools.defaultFontPixelHeight * (0.33)
        anchors.topMargin:      ScreenTools.defaultFontPixelHeight * (0.33) + state === "bottomMode" ? 0 : ScreenTools.toolbarHeight
        anchors.bottomMargin:   ScreenTools.defaultFontPixelHeight * (0.33)
272 273
        mapControl:             flightMap
        visible:                !ScreenTools.isTinyScreen
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
        state:                  "bottomMode"
        states: [
            State {
                name:   "topMode"
                AnchorChanges {
                    target:                 mapScale
                    anchors.top:            parent.top
                    anchors.bottom:         undefined
                }
            },
            State {
                name:   "bottomMode"
                AnchorChanges {
                    target:                 mapScale
                    anchors.top:            undefined
                    anchors.bottom:         parent.bottom
                }
            }
        ]
293
    }
294
}