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 Connections {
119 target: QGroundControl.unitsConversion
120
121 function onUnitsChanged() { control.triggerRecalc() }
122 }
123
124 PropertyAnimation {
125 id: autoHideAnimation
126 target: control
127 property: "opacity"
128 from: 1
129 to: 0
130 duration: 500
131 }
132
133 Timer {
134 id: autoHideTimer
135 interval: 3000
136 onTriggered: autoHideAnimation.start()
137 }
138
139 QGCPalette { id: qgcPal }
140
141 QGCLabel {
142 id: scaleText
143 objectName: "scaleText"
144 anchors.left: parent.left
145 anchors.right: rightEnd.right
146 font.bold: true
147 horizontalAlignment: Text.AlignRight
148 text: "0 m"
149 }
150
151 Rectangle {
152 id: leftEnd
153 anchors.top: scaleText.bottom
154 anchors.left: parent.left
155 width: 2
156 height: ScreenTools.defaultFontPixelHeight
157 color: qgcPal.text
158 }
159
160 Rectangle {
161 id: centerLine
162 anchors.bottomMargin: 2
163 anchors.bottom: leftEnd.bottom
164 anchors.left: leftEnd.right
165 height: 2
166 color: qgcPal.text
167 }
168
169 Rectangle {
170 id: rightEnd
171 anchors.top: leftEnd.top
172 anchors.left: centerLine.right
173 width: 2
174 height: ScreenTools.defaultFontPixelHeight
175 color: qgcPal.text
176 }
177}