QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
FlyViewMap.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtLocation
4import QtPositioning
5import QtQuick.Dialogs
6import QtQuick.Layouts
7
8import QGroundControl
9import QGroundControl.Controls
10import QGroundControl.FlyView
11import QGroundControl.FlightMap
12import QGroundControl.PlanView
13
14FlightMap {
15 id: _root
16 allowGCSLocationCenter: true
17 allowVehicleLocationCenter: !_keepVehicleCentered
18 planView: false
19 zoomLevel: QGroundControl.flightMapZoom
20 center: QGroundControl.flightMapPosition
21
22 property Item pipView
23 property Item pipState: _pipState
24 property var rightPanelWidth
25 property var planMasterController
26 property bool pipMode: false // true: map is shown in a small pip mode
27 property var toolInsets // Insets for the center viewport area
28
29 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
30 property var _planMasterController: planMasterController
31 property var _geoFenceController: planMasterController.geoFenceController
32 property var _rallyPointController: planMasterController.rallyPointController
33 property var _activeVehicleCoordinate: _activeVehicle ? _activeVehicle.coordinate : QtPositioning.coordinate()
34 property real _toolButtonTopMargin: parent.height - mainWindow.height + (ScreenTools.defaultFontPixelHeight / 2)
35 property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75
36 property var _flyViewSettings: QGroundControl.settingsManager.flyViewSettings
37 property bool _keepMapCenteredOnVehicle: _flyViewSettings.keepMapCenteredOnVehicle.rawValue
38
39 property bool _disableVehicleTracking: false
40 property bool _keepVehicleCentered: pipMode ? true : false
41 property bool _saveZoomLevelSetting: true
42
43 function _adjustMapZoomForPipMode() {
44 _saveZoomLevelSetting = false
45 if (pipMode) {
46 if (QGroundControl.flightMapZoom > 3) {
47 zoomLevel = QGroundControl.flightMapZoom - 3
48 }
49 } else {
50 zoomLevel = QGroundControl.flightMapZoom
51 }
52 _saveZoomLevelSetting = true
53 }
54
55 onPipModeChanged: _adjustMapZoomForPipMode()
56
57 onVisibleChanged: {
58 if (visible) {
59 // Synchronize center position with Plan View
60 center = QGroundControl.flightMapPosition
61 }
62 }
63
64 onZoomLevelChanged: {
65 if (_saveZoomLevelSetting) {
66 QGroundControl.flightMapZoom = _root.zoomLevel
67 }
68 }
69 onCenterChanged: {
70 QGroundControl.flightMapPosition = _root.center
71 }
72
73 // We track whether the user has panned or not to correctly handle automatic map positioning
74 onMapPanStart: _disableVehicleTracking = true
75 onMapPanStop: panRecenterTimer.restart()
76
77 function pointInRect(point, rect) {
78 return point.x > rect.x &&
79 point.x < rect.x + rect.width &&
80 point.y > rect.y &&
81 point.y < rect.y + rect.height;
82 }
83
84 property real _animatedLatitudeStart
85 property real _animatedLatitudeStop
86 property real _animatedLongitudeStart
87 property real _animatedLongitudeStop
88 property real animatedLatitude
89 property real animatedLongitude
90
91 onAnimatedLatitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)
92 onAnimatedLongitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)
93
94 NumberAnimation on animatedLatitude { id: animateLat; from: _animatedLatitudeStart; to: _animatedLatitudeStop; duration: 1000 }
95 NumberAnimation on animatedLongitude { id: animateLong; from: _animatedLongitudeStart; to: _animatedLongitudeStop; duration: 1000 }
96
97 function animatedMapRecenter(fromCoord, toCoord) {
98 _animatedLatitudeStart = fromCoord.latitude
99 _animatedLongitudeStart = fromCoord.longitude
100 _animatedLatitudeStop = toCoord.latitude
101 _animatedLongitudeStop = toCoord.longitude
102 animateLat.start()
103 animateLong.start()
104 }
105
106 // returns the rectangle formed by the four center insets
107 // used for checking if vehicle is under ui, and as a target for recentering the view
108 function _insetCenterRect() {
109 return Qt.rect(toolInsets.leftEdgeCenterInset,
110 toolInsets.topEdgeCenterInset,
111 _root.width - toolInsets.leftEdgeCenterInset - toolInsets.rightEdgeCenterInset,
112 _root.height - toolInsets.topEdgeCenterInset - toolInsets.bottomEdgeCenterInset)
113 }
114
115 // returns the four rectangles formed by the 8 corner insets
116 // used for detecting if the vehicle has flown under the instrument panel, virtual joystick etc
117 function _insetCornerRects() {
118 var rects = {
119 "topleft": Qt.rect(0,0,
120 toolInsets.leftEdgeTopInset,
121 toolInsets.topEdgeLeftInset),
122 "topright": Qt.rect(_root.width-toolInsets.rightEdgeTopInset,0,
123 toolInsets.rightEdgeTopInset,
124 toolInsets.topEdgeRightInset),
125 "bottomleft": Qt.rect(0,_root.height-toolInsets.bottomEdgeLeftInset,
126 toolInsets.leftEdgeBottomInset,
127 toolInsets.bottomEdgeLeftInset),
128 "bottomright": Qt.rect(_root.width-toolInsets.rightEdgeBottomInset,_root.height-toolInsets.bottomEdgeRightInset,
129 toolInsets.rightEdgeBottomInset,
130 toolInsets.bottomEdgeRightInset)}
131 return rects
132 }
133
134 function recenterNeeded() {
135 var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
136 var centerRect = _insetCenterRect()
137 //return !pointInRect(vehiclePoint,insetRect)
138
139 // If we are outside the center inset rectangle, recenter
140 if(!pointInRect(vehiclePoint, centerRect)){
141 return true
142 }
143
144 // if we are inside the center inset rectangle
145 // then additionally check if we are underneath one of the corner inset rectangles
146 var cornerRects = _insetCornerRects()
147 if(pointInRect(vehiclePoint, cornerRects["topleft"])){
148 return true
149 } else if(pointInRect(vehiclePoint, cornerRects["topright"])){
150 return true
151 } else if(pointInRect(vehiclePoint, cornerRects["bottomleft"])){
152 return true
153 } else if(pointInRect(vehiclePoint, cornerRects["bottomright"])){
154 return true
155 }
156
157 // if we are inside the center inset rectangle, and not under any corner elements
158 return false
159 }
160
161 function updateMapToVehiclePosition() {
162 if (animateLat.running || animateLong.running) {
163 return
164 }
165 // We let FlightMap handle first vehicle position
166 if (!_keepMapCenteredOnVehicle && firstVehiclePositionReceived && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
167 if (_keepVehicleCentered) {
168 _root.center = _activeVehicleCoordinate
169 } else {
170 if (firstVehiclePositionReceived && recenterNeeded()) {
171 // Move the map such that the vehicle is centered within the inset area
172 var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
173 var centerInsetRect = _insetCenterRect()
174 var centerInsetPoint = Qt.point(centerInsetRect.x + centerInsetRect.width / 2, centerInsetRect.y + centerInsetRect.height / 2)
175 var centerOffset = Qt.point((_root.width / 2) - centerInsetPoint.x, (_root.height / 2) - centerInsetPoint.y)
176 var vehicleOffsetPoint = Qt.point(vehiclePoint.x + centerOffset.x, vehiclePoint.y + centerOffset.y)
177 var vehicleOffsetCoord = _root.toCoordinate(vehicleOffsetPoint, false /* clipToViewport */)
178 animatedMapRecenter(_root.center, vehicleOffsetCoord)
179 }
180 }
181 }
182 }
183
184 on_ActiveVehicleCoordinateChanged: {
185 if (_keepMapCenteredOnVehicle && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
186 _root.center = _activeVehicleCoordinate
187 }
188 }
189
190 PipState {
191 id: _pipState
192 pipView: _root.pipView
193 isDark: _isFullWindowItemDark
194 }
195
196 Timer {
197 id: panRecenterTimer
198 interval: 10000
199 running: false
200 onTriggered: {
201 _disableVehicleTracking = false
202 updateMapToVehiclePosition()
203 }
204 }
205
206 Timer {
207 interval: 500
208 running: true
209 repeat: true
210 onTriggered: updateMapToVehiclePosition()
211 }
212
213 QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
214
215 Connections {
216 target: _missionController
217 ignoreUnknownSignals: true
218 function onNewItemsFromVehicle() {
219 var visualItems = _missionController.visualItems
220 if (visualItems && visualItems.count !== 1) {
221 mapFitFunctions.fitMapViewportToMissionItems()
222 firstVehiclePositionReceived = true
223 }
224 }
225 }
226
227 MapFitFunctions {
228 id: mapFitFunctions // The name for this id cannot be changed without breaking references outside of this code. Beware!
229 map: _root
230 usePlannedHomePosition: false
231 planMasterController: _planMasterController
232 }
233
234 ObstacleDistanceOverlayMap {
235 id: obstacleDistance
236 showText: !pipMode
237 }
238
239 // Add trajectory lines to the map
240 MapPolyline {
241 id: trajectoryPolyline
242 line.width: 3
243 line.color: "red"
244 z: QGroundControl.zOrderTrajectoryLines
245 visible: !pipMode
246
247 Connections {
248 target: QGroundControl.multiVehicleManager
249 function onActiveVehicleChanged(activeVehicle) {
250 trajectoryPolyline.path = _activeVehicle ? _activeVehicle.trajectoryPoints.list() : []
251 }
252 }
253
254 Connections {
255 target: _activeVehicle ? _activeVehicle.trajectoryPoints : null
256 function onPointAdded(coordinate) { trajectoryPolyline.addCoordinate(coordinate) }
257 function onUpdateLastPoint(coordinate) { trajectoryPolyline.replaceCoordinate(trajectoryPolyline.pathLength() - 1, coordinate) }
258 function onPointsCleared() { trajectoryPolyline.path = [] }
259 }
260 }
261
262 // Add the vehicles to the map
263 MapItemView {
264 model: QGroundControl.multiVehicleManager.vehicles
265 delegate: VehicleMapItem {
266 vehicle: object
267 coordinate: object.coordinate
268 map: _root
269 size: pipMode ? ScreenTools.defaultFontPixelHeight : ScreenTools.defaultFontPixelHeight * 3
270 z: QGroundControl.zOrderVehicles
271 }
272 }
273 // Add distance sensor view
274 MapItemView{
275 model: QGroundControl.multiVehicleManager.vehicles
276 delegate: ProximityRadarMapView {
277 vehicle: object
278 coordinate: object.coordinate
279 map: _root
280 z: QGroundControl.zOrderVehicles
281 }
282 }
283 // Add ADSB vehicles to the map
284 MapItemView {
285 model: QGroundControl.adsbVehicleManager.adsbVehicles
286 delegate: VehicleMapItem {
287 coordinate: object.coordinate
288 altitude: object.altitude
289 callsign: object.callsign
290 heading: object.heading
291 alert: object.alert
292 map: _root
293 size: pipMode ? ScreenTools.defaultFontPixelHeight : ScreenTools.defaultFontPixelHeight * 2.5
294 z: QGroundControl.zOrderVehicles
295 }
296 }
297
298 // Add the items associated with each vehicles flight plan to the map
299 Repeater {
300 model: QGroundControl.multiVehicleManager.vehicles
301
302 PlanMapItems {
303 map: _root
304 largeMapView: !pipMode
305 planMasterController: masterController
306 vehicle: _vehicle
307
308 property var _vehicle: object
309
310 PlanMasterController {
311 id: masterController
312 Component.onCompleted: startStaticActiveVehicle(object)
313 }
314 }
315 }
316
317 // Allow custom builds to add map items
318 CustomMapItems {
319 map: _root
320 largeMapView: !pipMode
321 }
322
323 GeoFenceMapVisuals {
324 map: _root
325 myGeoFenceController: _geoFenceController
326 interactive: false
327 planView: false
328 homePosition: _activeVehicle && _activeVehicle.homePosition.isValid ? _activeVehicle.homePosition : QtPositioning.coordinate()
329 }
330
331 // Rally points on map
332 MapItemView {
333 model: _rallyPointController.points
334
335 delegate: MapQuickItem {
336 id: itemIndicator
337 anchorPoint.x: sourceItem.anchorPointX
338 anchorPoint.y: sourceItem.anchorPointY
339 coordinate: object.coordinate
340 z: QGroundControl.zOrderMapItems
341
342 sourceItem: MissionItemIndexLabel {
343 id: itemIndexLabel
344 label: qsTr("R", "rally point map item label")
345 }
346 }
347 }
348
349 // Camera trigger points
350 MapItemView {
351 model: _activeVehicle ? _activeVehicle.cameraTriggerPoints : 0
352
353 delegate: CameraTriggerIndicator {
354 coordinate: object.coordinate
355 z: QGroundControl.zOrderTopMost
356 }
357 }
358
359 // GoTo Location forward flight circle visuals
360 QGCMapCircleVisuals {
361 id: fwdFlightGotoMapCircle
362 mapControl: parent
363 mapCircle: _fwdFlightGotoMapCircle
364 radiusLabelVisible: true
365 visible: gotoLocationItem.visible && _activeVehicle &&
366 _activeVehicle.inFwdFlight &&
367 !_activeVehicle.orbitActive
368
369 property alias coordinate: _fwdFlightGotoMapCircle.center
370 property alias radius: _fwdFlightGotoMapCircle.radius
371 property alias clockwiseRotation: _fwdFlightGotoMapCircle.clockwiseRotation
372
373 Component.onCompleted: {
374 // Only allow editing the radius, not the position
375 centerDragHandleVisible = false
376
377 globals.guidedControllerFlyView.fwdFlightGotoMapCircle = this
378 }
379
380 Binding {
381 target: _fwdFlightGotoMapCircle
382 property: "center"
383 value: gotoLocationItem.coordinate
384 }
385
386 function startLoiterRadiusEdit() {
387 _fwdFlightGotoMapCircle.interactive = true
388 }
389
390 // Called when loiter edit is confirmed
391 function actionConfirmed() {
392 _fwdFlightGotoMapCircle.interactive = false
393 _fwdFlightGotoMapCircle._commitRadius()
394 }
395
396 // Called when loiter edit is cancelled
397 function actionCancelled() {
398 _fwdFlightGotoMapCircle.interactive = false
399 _fwdFlightGotoMapCircle._restoreRadius()
400 }
401
402 QGCMapCircle {
403 id: _fwdFlightGotoMapCircle
404 interactive: false
405 showRotation: true
406 clockwiseRotation: true
407
408 property real _defaultLoiterRadius: _flyViewSettings.forwardFlightGoToLocationLoiterRad.value
409 property real _committedRadius;
410
411 onCenterChanged: {
412 radius.rawValue = _defaultLoiterRadius
413 // Don't commit the radius in case this operation is undone
414 }
415
416 Component.onCompleted: {
417 radius.rawValue = _defaultLoiterRadius
418 _commitRadius()
419 }
420
421 function _commitRadius() {
422 _committedRadius = radius.rawValue
423 }
424
425 function _restoreRadius() {
426 radius.rawValue = _committedRadius
427 }
428 }
429 }
430
431 // GoTo Location visuals
432 MapQuickItem {
433 id: gotoLocationItem
434 visible: false
435 z: QGroundControl.zOrderMapItems
436 anchorPoint.x: sourceItem.anchorPointX
437 anchorPoint.y: sourceItem.anchorPointY
438 sourceItem: MissionItemIndexLabel {
439 checked: true
440 index: -1
441 label: qsTr("Go here", "Go to location waypoint")
442 }
443
444 property bool inGotoFlightMode: _activeVehicle ? _activeVehicle.flightMode === _activeVehicle.gotoFlightMode : false
445
446 property var _committedCoordinate: null
447
448 onInGotoFlightModeChanged: {
449 if (!inGotoFlightMode && gotoLocationItem.visible) {
450 // Hide goto indicator when vehicle falls out of guided mode
451 hide()
452 }
453 }
454
455 function show(coord) {
456 gotoLocationItem.coordinate = coord
457 gotoLocationItem.visible = true
458 }
459
460 function hide() {
461 gotoLocationItem.visible = false
462 }
463
464 function actionConfirmed() {
465 _commitCoordinate()
466
467 // Commit the new radius which possibly changed
468 fwdFlightGotoMapCircle.actionConfirmed()
469
470 // We leave the indicator visible. The handling for onInGuidedModeChanged will hide it.
471 }
472
473 function actionCancelled() {
474 _restoreCoordinate()
475
476 // Also restore the loiter radius
477 fwdFlightGotoMapCircle.actionCancelled()
478 }
479
480 function _commitCoordinate() {
481 // Must deep copy
482 _committedCoordinate = QtPositioning.coordinate(
483 coordinate.latitude,
484 coordinate.longitude
485 );
486 }
487
488 function _restoreCoordinate() {
489 if (_committedCoordinate) {
490 coordinate = _committedCoordinate
491 } else {
492 hide()
493 }
494 }
495 }
496
497 // Orbit editing visuals
498 QGCMapCircleVisuals {
499 id: orbitMapCircle
500 mapControl: parent
501 mapCircle: _mapCircle
502 visible: false
503
504 property alias center: _mapCircle.center
505 property alias clockwiseRotation: _mapCircle.clockwiseRotation
506 readonly property real defaultRadius: 30
507
508 Connections {
509 target: QGroundControl.multiVehicleManager
510 function onActiveVehicleChanged(activeVehicle) {
511 if (!activeVehicle) {
512 orbitMapCircle.visible = false
513 }
514 }
515 }
516
517 function show(coord) {
518 _mapCircle.radius.rawValue = defaultRadius
519 orbitMapCircle.center = coord
520 orbitMapCircle.visible = true
521 }
522
523 function hide() {
524 orbitMapCircle.visible = false
525 }
526
527 function actionConfirmed() {
528 // Live orbit status is handled by telemetry so we hide here and telemetry will show again.
529 hide()
530 }
531
532 function actionCancelled() {
533 hide()
534 }
535
536 function radius() {
537 return _mapCircle.radius.rawValue
538 }
539
540 Component.onCompleted: globals.guidedControllerFlyView.orbitMapCircle = orbitMapCircle
541
542 QGCMapCircle {
543 id: _mapCircle
544 interactive: true
545 radius.rawValue: 30
546 showRotation: true
547 clockwiseRotation: true
548 }
549 }
550
551 // ROI Location visuals
552 MapQuickItem {
553 id: roiLocationItem
554 visible: _activeVehicle && _activeVehicle.isROIEnabled
555 z: QGroundControl.zOrderMapItems
556 anchorPoint.x: sourceItem.anchorPointX
557 anchorPoint.y: sourceItem.anchorPointY
558
559 Connections {
560 target: _activeVehicle
561 function onRoiCoordChanged(centerCoord) {
562 roiLocationItem.show(centerCoord)
563 }
564 }
565
566 MouseArea {
567 anchors.fill: parent
568 onClicked: (position) => {
569 position = Qt.point(position.x, position.y)
570 var clickCoord = _root.toCoordinate(position, false /* clipToViewPort */)
571 // For some strange reason using mainWindow in mapToItem doesn't work, so we use globals.parent instead which also gets us mainWindow
572 position = mapToItem(globals.parent, position)
573 var dropPanel = roiEditDropPanelComponent.createObject(mainWindow, { clickRect: Qt.rect(position.x, position.y, 0, 0) })
574 dropPanel.open()
575 }
576 }
577
578 sourceItem: MissionItemIndexLabel {
579 checked: true
580 index: -1
581 label: qsTr("ROI here", "Make this a Region Of Interest")
582 }
583
584 //-- Visibilty controlled by actual state
585 function show(coord) {
586 roiLocationItem.coordinate = coord
587 }
588 }
589
590 // Orbit telemetry visuals
591 QGCMapCircleVisuals {
592 id: orbitTelemetryCircle
593 mapControl: parent
594 mapCircle: _activeVehicle ? _activeVehicle.orbitMapCircle : null
595 visible: _activeVehicle ? _activeVehicle.orbitActive : false
596 }
597
598 MapQuickItem {
599 id: orbitCenterIndicator
600 anchorPoint.x: sourceItem.anchorPointX
601 anchorPoint.y: sourceItem.anchorPointY
602 coordinate: _activeVehicle ? _activeVehicle.orbitMapCircle.center : QtPositioning.coordinate()
603 visible: orbitTelemetryCircle.visible && !gotoLocationItem.visible
604
605 sourceItem: MissionItemIndexLabel {
606 checked: true
607 index: -1
608 label: qsTr("Orbit", "Orbit waypoint")
609 }
610 }
611
612 QGCPopupDialogFactory {
613 id: roiEditPositionDialogFactory
614
615 dialogComponent: roiEditPositionDialogComponent
616 }
617
618 Component {
619 id: roiEditPositionDialogComponent
620
621 EditPositionDialog {
622 title: qsTr("Edit ROI Position")
623 coordinate: roiLocationItem.coordinate
624 onCoordinateChanged: {
625 roiLocationItem.coordinate = coordinate
626 _activeVehicle.guidedModeROI(coordinate)
627 }
628 }
629 }
630
631 Component {
632 id: roiEditDropPanelComponent
633
634 DropPanel {
635 id: roiEditDropPanel
636
637 sourceComponent: Component {
638 ColumnLayout {
639 spacing: ScreenTools.defaultFontPixelWidth / 2
640
641 QGCButton {
642 Layout.fillWidth: true
643 text: qsTr("Cancel ROI")
644 onClicked: {
645 _activeVehicle.stopGuidedModeROI()
646 roiEditDropPanel.close()
647 }
648 }
649
650 QGCButton {
651 Layout.fillWidth: true
652 text: qsTr("Edit Position")
653 onClicked: {
654 roiEditPositionDialogFactory.open()
655 roiEditDropPanel.close()
656 }
657 }
658 }
659 }
660 }
661 }
662
663 Component {
664 id: mapClickDropPanelComponent
665
666 DropPanel {
667 id: mapClickDropPanel
668
669 property var mapClickCoord
670
671 sourceComponent: Component {
672 ColumnLayout {
673 spacing: ScreenTools.defaultFontPixelWidth / 2
674
675 QGCButton {
676 Layout.fillWidth: true
677 text: qsTr("Go to location")
678 visible: globals.guidedControllerFlyView.showGotoLocation
679 onClicked: {
680 mapClickDropPanel.close()
681 gotoLocationItem.show(mapClickCoord)
682
683 if ((_activeVehicle.flightMode == _activeVehicle.gotoFlightMode) && !_flyViewSettings.goToLocationRequiresConfirmInGuided.value) {
684 if (globals.guidedControllerFlyView.executeAction(globals.guidedControllerFlyView.actionGoto, mapClickCoord)) {
685 gotoLocationItem.actionConfirmed() // Still need to call this to commit the new coordinate and radius
686 } else {
687 gotoLocationItem.actionCancelled()
688 }
689 } else {
690 globals.guidedControllerFlyView.confirmAction(globals.guidedControllerFlyView.actionGoto, mapClickCoord, gotoLocationItem)
691 }
692 }
693 }
694
695 QGCButton {
696 Layout.fillWidth: true
697 text: qsTr("Orbit at location")
698 visible: globals.guidedControllerFlyView.showOrbit
699 onClicked: {
700 mapClickDropPanel.close()
701 orbitMapCircle.show(mapClickCoord)
702 globals.guidedControllerFlyView.confirmAction(globals.guidedControllerFlyView.actionOrbit, mapClickCoord, orbitMapCircle)
703 }
704 }
705
706 QGCButton {
707 Layout.fillWidth: true
708 text: qsTr("ROI at location")
709 visible: globals.guidedControllerFlyView.showROI
710 onClicked: {
711 mapClickDropPanel.close()
712 globals.guidedControllerFlyView.executeAction(globals.guidedControllerFlyView.actionROI, mapClickCoord, 0, false)
713 }
714 }
715
716 QGCButton {
717 Layout.fillWidth: true
718 text: qsTr("Set home here")
719 visible: globals.guidedControllerFlyView.showSetHome
720 onClicked: {
721 mapClickDropPanel.close()
722 globals.guidedControllerFlyView.confirmAction(globals.guidedControllerFlyView.actionSetHome, mapClickCoord)
723 }
724 }
725
726 QGCButton {
727 Layout.fillWidth: true
728 text: qsTr("Set Estimator Origin")
729 visible: globals.guidedControllerFlyView.showSetEstimatorOrigin
730 onClicked: {
731 mapClickDropPanel.close()
732 globals.guidedControllerFlyView.confirmAction(globals.guidedControllerFlyView.actionSetEstimatorOrigin, mapClickCoord)
733 }
734 }
735
736 QGCButton {
737 Layout.fillWidth: true
738 text: qsTr("Set Heading")
739 visible: globals.guidedControllerFlyView.showChangeHeading
740 onClicked: {
741 mapClickDropPanel.close()
742 globals.guidedControllerFlyView.confirmAction(globals.guidedControllerFlyView.actionChangeHeading, mapClickCoord)
743 }
744 }
745
746 ColumnLayout {
747 spacing: 0
748 QGCLabel { text: qsTr("Lat: %1").arg(mapClickCoord.latitude.toFixed(6)) }
749 QGCLabel { text: qsTr("Lon: %1").arg(mapClickCoord.longitude.toFixed(6)) }
750 }
751 }
752 }
753 }
754 }
755
756 onMapClicked: (position) => {
757 if (!globals.guidedControllerFlyView.guidedUIVisible &&
758 (globals.guidedControllerFlyView.showGotoLocation || globals.guidedControllerFlyView.showOrbit ||
759 globals.guidedControllerFlyView.showROI || globals.guidedControllerFlyView.showSetHome ||
760 globals.guidedControllerFlyView.showSetEstimatorOrigin)) {
761
762 position = Qt.point(position.x, position.y)
763 var clickCoord = _root.toCoordinate(position, false /* clipToViewPort */)
764 // For some strange reason using mainWindow in mapToItem doesn't work, so we use globals.parent instead which also gets us mainWindow
765 position = _root.mapToItem(globals.parent, position)
766 var dropPanel = mapClickDropPanelComponent.createObject(mainWindow, { mapClickCoord: clickCoord, clickRect: Qt.rect(position.x, position.y, 0, 0) })
767 dropPanel.open()
768 }
769 }
770
771 MapScale {
772 id: mapScale
773 anchors.margins: _toolsMargin
774 anchors.left: parent.left
775 anchors.top: parent.top
776 mapControl: _root
777 visible: !ScreenTools.isTinyScreen && QGroundControl.corePlugin.options.flyView.showMapScale && mapControl.pipState.state === mapControl.pipState.windowState
778 }
779}