QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
CenterMapDropButton.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Layouts
4import QtPositioning
5
6import QGroundControl
7import QGroundControl.Controls
8
9DropButton {
10 id: dropButton
11 dropDirection: dropRight
12 buttonImage: "/qmlimages/MapCenter.svg"
13 viewportMargins: ScreenTools.defaultFontPixelWidth / 2
14 lightBorders: map.isSatelliteMap
15
16 property var map
17 property rect mapFitViewport
18 property bool usePlannedHomePosition ///< true: planned home position used for calculations, false: vehicle home position use for calculations
19 property var geoFenceController
20 property var missionController
21 property var rallyPointController
22 property bool showMission: true
23 property bool showAllItems: true
24 property bool showFollowVehicle: false
25 property bool followVehicle: false
26
27 function fitHomePosition() {
28 var homePosition = QtPositioning.coordinate()
29 var activeVehicle = QGroundControl.multiVehicleManager.activeVehicle
30 if (usePlannedHomePosition) {
31 homePosition = missionController.visualItems.get(0).coordinate
32 } else if (activeVehicle) {
33 homePosition = activeVehicle.homePosition
34 }
35 return homePosition
36 }
37
38 /// Normalize latitude to range: 0 to 180, S to N
39 function normalizeLat(lat) {
40 return lat + 90.0
41 }
42
43 /// Normalize longitude to range: 0 to 360, W to E
44 function normalizeLon(lon) {
45 return lon + 180.0
46 }
47
48 /// Fits the visible region of the map to inclues all of the specified coordinates. If no coordinates
49 /// are specified the map will center to fitHomePosition()
50 function fitMapViewportToAllCoordinates(coordList) {
51 if (coordList.length === 0) {
52 map.center = fitHomePosition()
53 return
54 }
55
56 // Create the normalized lat/lon corners for the coordinate bounding rect from the list of coordinates
57 var north = normalizeLat(coordList[0].latitude)
58 var south = north
59 var east = normalizeLon(coordList[0].longitude)
60 var west = east
61 for (var i=1; i<coordList.length; i++) {
62 var lat = normalizeLat(coordList[i].latitude)
63 var lon = normalizeLon(coordList[i].longitude)
64
65 north = Math.max(north, lat)
66 south = Math.min(south, lat)
67 east = Math.max(east, lon)
68 west = Math.min(west, lon)
69 }
70
71 // Expand the coordinate bounding rect to make room for the tools around the edge of the map
72 var latDegreesPerPixel = (north - south) / mapFitViewport.width
73 var lonDegreesPerPixel = (east - west) / mapFitViewport.height
74 north = Math.min(north + (mapFitViewport.y * latDegreesPerPixel), 180)
75 south = Math.max(south - ((map.height - mapFitViewport.bottom) * latDegreesPerPixel), 0)
76 west = Math.max(west - (mapFitViewport.x * lonDegreesPerPixel), 0)
77 east = Math.min(east + ((map.width - mapFitViewport.right) * lonDegreesPerPixel), 360)
78
79 // Fix the map region to the new bounding rect
80 var topLeftCoord = QtPositioning.coordinate(north - 90.0, west - 180.0)
81 var bottomRightCoord = QtPositioning.coordinate(south - 90.0, east - 180.0)
82 map.setVisibleRegion(QtPositioning.rectangle(topLeftCoord, bottomRightCoord))
83 }
84
85 function addMissionItemCoordsForFit(coordList) {
86 var homePosition = fitHomePosition()
87 if (homePosition.isValid) {
88 coordList.push(homePosition)
89 }
90 for (var i=1; i<missionController.visualItems.count; i++) {
91 var missionItem = missionController.visualItems.get(i)
92 if (missionItem.specifiesCoordinate && !missionItem.isStandaloneCoordinate) {
93 coordList.push(missionItem.coordinate)
94 }
95 }
96 }
97
98 function fitMapViewportToMissionItems() {
99 var coordList = [ ]
100 addMissionItemCoordsForFit(coordList)
101 fitMapViewportToAllCoordinates(coordList)
102 }
103
104 function addFenceItemCoordsForFit(coordList) {
105 var i
106 var homePosition = fitHomePosition()
107 if (homePosition.isValid && geoFenceController.circleEnabled) {
108 var azimuthList = [ 0, 180, 90, 270 ]
109 for (i = 0; i < azimuthList.length; i++) {
110 var edgeCoordinate = homePosition.atDistanceAndAzimuth(geoFenceController.circleRadius, azimuthList[i])
111 coordList.push(edgeCoordinate)
112 }
113 }
114 if (geoFenceController.polygonEnabled && geoFenceController.polygon.count() > 2) {
115 for (i = 0; i < geoFenceController.polygon.count(); i++) {
116 coordList.push(geoFenceController.polygon.path[i])
117 }
118 }
119 }
120
121 function fitMapViewportToFenceItems() {
122 var coordList = [ ]
123 addFenceItemCoordsForFit(coordList)
124 fitMapViewportToAllCoordinates(coordList)
125 }
126
127 function addRallyItemCoordsForFit(coordList) {
128 for (var i=0; i<rallyPointController.points.count; i++) {
129 coordList.push(rallyPointController.points.get(i).coordinate)
130 }
131 }
132
133 function fitMapViewportToRallyItems() {
134 var coordList = [ ]
135 addRallyItemCoordsForFit(coordList)
136 fitMapViewportToAllCoordinates(coordList)
137 }
138
139 function fitMapViewportToAllItems() {
140 var coordList = [ ]
141 addMissionItemCoordsForFit(coordList)
142 addFenceItemCoordsForFit(coordList)
143 addRallyItemCoordsForFit(coordList)
144 fitMapViewportToAllCoordinates(coordList)
145 }
146
147 dropDownComponent: Component {
148 ColumnLayout {
149 spacing: ScreenTools.defaultFontPixelWidth * 0.5
150
151 QGCLabel { text: qsTr("Center map on:") }
152
153 QGCButton {
154 text: qsTr("Mission")
155 Layout.fillWidth: true
156 visible: showMission
157 enabled: !followVehicleCheckBox.checked
158
159 onClicked: {
160 dropButton.hideDropDown()
161 fitMapViewportToMissionItems()
162 }
163 }
164
165 QGCButton {
166 text: qsTr("All items")
167 Layout.fillWidth: true
168 visible: showAllItems
169 enabled: !followVehicleCheckBox.checked
170
171 onClicked: {
172 dropButton.hideDropDown()
173 fitMapViewportToAllItems()
174 }
175 }
176
177 QGCButton {
178 text: qsTr("Launch")
179 Layout.fillWidth: true
180 enabled: !followVehicleCheckBox.checked
181
182 onClicked: {
183 dropButton.hideDropDown()
184 map.center = fitHomePosition()
185 }
186 }
187
188 QGCButton {
189 text: qsTr("Current Location")
190 Layout.fillWidth: true
191 enabled: map.gcsPosition ? map.gcsPosition.isValid && !followVehicleCheckBox.checked : false
192
193 onClicked: {
194 dropButton.hideDropDown()
195 map.center = map.gcsPosition
196 }
197 }
198
199
200 QGCButton {
201 text: qsTr("Specified Location")
202 Layout.fillWidth: true
203
204 onClicked: {
205 dropButton.hideDropDown()
206 map.centerToSpecifiedLocation()
207 }
208 }
209
210 QGCButton {
211 text: qsTr("Vehicle")
212 Layout.fillWidth: true
213 enabled: globals.activeVehicle && globals.activeVehicle.latitude != 0 && globals.activeVehicle.longitude != 0 && !followVehicleCheckBox.checked
214
215 onClicked: {
216 dropButton.hideDropDown()
217 map.center = globals.activeVehicle.coordinate
218 }
219 }
220
221 QGCCheckBox {
222 id: followVehicleCheckBox
223 text: qsTr("Follow Vehicle")
224 checked: followVehicle
225 visible: showFollowVehicle
226
227 onClicked: {
228 dropButton.hideDropDown()
229 dropButton.followVehicle = checked
230 }
231 }
232 } // Column
233 } // Component - dropDownComponent
234} // DropButton