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

33 34
    property alias  scaleState: mapScale.state

35
    property var    missionController
36 37
    property var    geoFenceController
    property var    rallyPointController
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 45 46
    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)
47

48 49
    property bool   _disableVehicleTracking:    false
    property bool   _keepVehicleCentered:       _mainIsMap ? false : true
50

51
    // Track last known map position and zoom from Fly view in settings
52
    onZoomLevelChanged: QGroundControl.flightMapZoom = zoomLevel
53
    onCenterChanged:    QGroundControl.flightMapPosition = center
54

55
    // When the user pans the map we stop responding to vehicle coordinate updates until the panRecenterTimer fires
56 57 58
    onUserPannedChanged: {
        _disableVehicleTracking = true
        panRecenterTimer.start()
59 60
    }

61 62 63 64 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
    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() {
91
        var vehiclePoint = flightMap.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
92 93
        var centerViewport = Qt.rect(0, 0, width, height)
        return !pointInRect(vehiclePoint, centerViewport)
94 95 96
    }

    function updateMapToVehiclePosition() {
97 98
        // We let FlightMap handle first vehicle position
        if (firstVehiclePositionReceived && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
99
            if (_keepVehicleCentered) {
100
                flightMap.center = _activeVehicleCoordinate
101
            } else {
DonLakeFlyer's avatar
DonLakeFlyer committed
102
                if (firstVehiclePositionReceived && recenterNeeded()) {
103
                    animatedMapRecenter(flightMap.center, _activeVehicleCoordinate)
104 105
                }
            }
106 107 108 109
        }
    }

    Timer {
110 111 112
        id:         panRecenterTimer
        interval:   10000
        running:    false
113 114

        onTriggered: {
115
            _disableVehicleTracking = false
116
            updateMapToVehiclePosition()
117 118 119
        }
    }

120 121 122 123 124 125 126
    Timer {
        interval:       500
        running:        true
        repeat:         true
        onTriggered:    updateMapToVehiclePosition()
    }

Don Gagne's avatar
Don Gagne committed
127
    QGCPalette { id: qgcPal; colorGroupEnabled: true }
128
    QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
Don Gagne's avatar
Don Gagne committed
129

130 131
    Connections {
        target: missionController
132 133

        onNewItemsFromVehicle: {
134
            var visualItems = missionController.visualItems
135 136
            if (visualItems && visualItems.count != 1) {
                mapFitFunctions.fitMapViewportToMissionItems()
137
                firstVehiclePositionReceived = true
138 139
            }
        }
140 141
    }

142
    ExclusiveGroup {
Don Gagne's avatar
Don Gagne committed
143
        id: _mapTypeButtonsExclusiveGroup
144 145
    }

Don Gagne's avatar
Don Gagne committed
146 147 148 149 150 151 152
    MapFitFunctions {
        id:                         mapFitFunctions
        map:                        _flightMap
        usePlannedHomePosition:     false
        mapMissionController:      missionController
        mapGeoFenceController:     geoFenceController
        mapRallyPointController:   rallyPointController
153

Don Gagne's avatar
Don Gagne committed
154 155
        property real leftToolWidth:    toolStrip.x + toolStrip.width
    }
156

157 158
    // Add trajectory points to the map
    MapItemView {
159
        model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints : 0 : 0
DonLakeFlyer's avatar
DonLakeFlyer committed
160 161

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

    // Add the vehicles to the map
    MapItemView {
174
        model: QGroundControl.multiVehicleManager.vehicles
DonLakeFlyer's avatar
DonLakeFlyer committed
175 176

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

185 186
    // Add the mission item visuals to the map
    Repeater {
187
        model: _mainIsMap ? missionController.visualItems : 0
188 189

        delegate: MissionItemMapVisual {
190
            map:        flightMap
191
            onClicked:  guidedActionsController.confirmAction(guidedActionsController.actionSetWaypoint, Math.max(object.sequenceNumber, 1))
192
        }
193 194 195 196
    }

    // Add lines between waypoints
    MissionLineView {
DonLakeFlyer's avatar
DonLakeFlyer committed
197
        model:  _mainIsMap ? missionController.waypointLines : 0
198 199
    }

200 201 202 203
    GeoFenceMapVisuals {
        map:                    flightMap
        myGeoFenceController:   geoFenceController
        interactive:            false
204
        homePosition:           _activeVehicle && _activeVehicle.homePosition.isValid ? _activeVehicle.homePosition : undefined
205 206
    }

207 208 209 210 211 212
    // Rally points on map
    MapItemView {
        model: rallyPointController.points

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

        sourceItem: MissionItemIndexLabel {
234 235
            checked: true
            label:   qsTr("G", "Goto here waypoint") // second string is translator's hint.
Don Gagne's avatar
Don Gagne committed
236
        }
237 238
    }    

Don Gagne's avatar
Don Gagne committed
239
    // Handle guided mode clicks
240 241
    MouseArea {
        anchors.fill: parent
Don Gagne's avatar
Don Gagne committed
242 243

        onClicked: {
244 245 246
            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
247 248
            }
        }
249
    }
250 251

    MapScale {
252
        id:                     mapScale
253
        anchors.right:          parent.right
254 255 256
        anchors.margins:        ScreenTools.defaultFontPixelHeight * (0.33)
        anchors.topMargin:      ScreenTools.defaultFontPixelHeight * (0.33) + state === "bottomMode" ? 0 : ScreenTools.toolbarHeight
        anchors.bottomMargin:   ScreenTools.defaultFontPixelHeight * (0.33)
257 258
        mapControl:             flightMap
        visible:                !ScreenTools.isTinyScreen
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
        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
                }
            }
        ]
278
    }
279
}