QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
Viewer3DScaleBar.qml
Go to the documentation of this file.
1import QtQuick
2
3import QGroundControl
4import QGroundControl.Controls
5import QGroundControl.Viewer3D
6
7/// Ground-scale indicator for the 3D viewer, patterned after MapScale.qml.
8/// Shows the ground distance covered on screen at the ground plane through the
9/// screen center (scale varies elsewhere in a perspective view).
10Item {
11 id: control
12 width: rightEnd.x + rightEnd.width
13 height: rightEnd.y + rightEnd.height
14
15 property Viewer3DCameraController controller
16 property bool autoHide: false ///< true: disappears after a timeout on scale change
17
18 // Scene units are meters x 10
19 readonly property real _sceneToMeters: 0.1
20 property var _scaleLengthsMeters: [5, 10, 25, 50, 100, 150, 250, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000]
21 property var _scaleLengthsFeet: [10, 25, 50, 100, 250, 500, 1000, 2000, 3000, 4000, 5280, 5280*2, 5280*5, 5280*10, 5280*25, 5280*50, 5280*100, 5280*250, 5280*500, 5280*1000]
22
23 function formatDistanceMeters(meters) {
24 var dist = Math.round(meters)
25 if (dist > 1000) {
26 if (dist > 100000) {
27 dist = Math.round(dist / 1000)
28 } else {
29 dist = Math.round(dist / 100)
30 dist = dist / 10
31 }
32 dist = dist + qsTr(" km")
33 } else {
34 dist = dist + qsTr(" m")
35 }
36 return dist
37 }
38
39 function formatDistanceFeet(feet) {
40 var dist = Math.round(feet)
41 if (dist >= 5280) {
42 dist = Math.round(dist / 5280)
43 if (dist === 1) {
44 dist += qsTr(" mile")
45 } else {
46 dist += qsTr(" miles")
47 }
48 } else {
49 dist = dist + qsTr(" ft")
50 }
51 return dist
52 }
53
54 function _applyNiceLength(scaleLineLength, scaleLinePixelLength, scaleLengths) {
55 var scaleLineRatio = 0
56 var i = 0
57
58 if (scaleLineLength === 0) {
59 return 0
60 }
61
62 for (i = 0; i < scaleLengths.length - 1; i++) {
63 if (scaleLineLength < ((scaleLengths[i] + scaleLengths[i + 1]) / 2)) {
64 scaleLineRatio = scaleLengths[i] / scaleLineLength
65 scaleLineLength = scaleLengths[i]
66 break
67 }
68 }
69 if (scaleLineRatio === 0) {
70 scaleLineRatio = scaleLengths[i] / scaleLineLength
71 scaleLineLength = scaleLengths[i]
72 }
73
74 centerLine.width = (scaleLinePixelLength * scaleLineRatio) - (2 * leftEnd.width)
75 return scaleLineLength
76 }
77
78 function calculateScale() {
79 if (!controller) {
80 return
81 }
82
83 var scaleLinePixelLength = 100
84 var scaleLineMeters = controller.sceneUnitsPerPixel() * scaleLinePixelLength * _sceneToMeters
85 if (scaleLineMeters <= 0) {
86 return
87 }
88
89 if (QGroundControl.settingsManager.unitsSettings.horizontalDistanceUnits.value === UnitsSettings.HorizontalDistanceUnitsFeet) {
90 var niceFeet = _applyNiceLength(scaleLineMeters * 3.2808399, scaleLinePixelLength, _scaleLengthsFeet)
91 scaleText.text = formatDistanceFeet(niceFeet)
92 } else {
93 var niceMeters = _applyNiceLength(scaleLineMeters, scaleLinePixelLength, _scaleLengthsMeters)
94 scaleText.text = formatDistanceMeters(niceMeters)
95 }
96 }
97
98 function triggerRecalc() {
99 calculateScale()
100 if (control.autoHide) {
101 autoHideTimer.restart()
102 autoHideAnimation.stop()
103 control.opacity = 1
104 }
105 }
106
107 Component.onCompleted: triggerRecalc()
108 onControllerChanged: triggerRecalc()
109
110 Connections {
111 target: control.controller
112
113 function onDistanceChanged() { control.triggerRecalc() }
114 function onViewportSizeChanged() { control.triggerRecalc() }
115 function onFieldOfViewChanged() { control.triggerRecalc() }
116 }
117
118 PropertyAnimation {
119 id: autoHideAnimation
120 target: control
121 property: "opacity"
122 from: 1
123 to: 0
124 duration: 500
125 }
126
127 Timer {
128 id: autoHideTimer
129 interval: 3000
130 onTriggered: autoHideAnimation.start()
131 }
132
133 QGCPalette { id: qgcPal }
134
135 QGCLabel {
136 id: scaleText
137 anchors.left: parent.left
138 anchors.right: rightEnd.right
139 font.bold: true
140 horizontalAlignment: Text.AlignRight
141 text: "0 m"
142 }
143
144 Rectangle {
145 id: leftEnd
146 anchors.top: scaleText.bottom
147 anchors.left: parent.left
148 width: 2
149 height: ScreenTools.defaultFontPixelHeight
150 color: qgcPal.text
151 }
152
153 Rectangle {
154 id: centerLine
155 anchors.bottomMargin: 2
156 anchors.bottom: leftEnd.bottom
157 anchors.left: leftEnd.right
158 height: 2
159 color: qgcPal.text
160 }
161
162 Rectangle {
163 id: rightEnd
164 anchors.top: leftEnd.top
165 anchors.left: centerLine.right
166 width: 2
167 height: ScreenTools.defaultFontPixelHeight
168 color: qgcPal.text
169 }
170}