QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCMapCircleVisuals.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Shapes
4import QtLocation
5import QtPositioning
6
7import QGroundControl
8import QGroundControl.Controls
9import QGroundControl.FlightMap
10
11/// QGCMapCircle map visuals
12Item {
13 id: _root
14
15 property var mapControl ///< Map control to place item in
16 property var mapCircle ///< QGCMapCircle object
17 property bool interactive: mapCircle ? mapCircle.interactive : 0 /// true: user can manipulate polygon
18 property color interiorColor: "transparent"
19 property real interiorOpacity: 0.95
20 property int borderWidth: 3
21 property color borderColor: QGroundControl.globalPalette.mapMissionTrajectory
22 property bool centerDragHandleVisible: true
23 property bool radiusLabelVisible: false
24 property real _radius: mapCircle ? mapCircle.radius.rawValue : 0
25
26 property var _circleComponent
27 property var _topRotationIndicatorComponent
28 property var _bottomRotationIndicatorComponent
29 property var _dragHandlesComponent
30
31 function addVisuals() {
32 if (!_circleComponent) {
33 _circleComponent = circleComponent.createObject(mapControl)
34 mapControl.addMapItem(_circleComponent)
35 }
36 if (!_topRotationIndicatorComponent) {
37 _topRotationIndicatorComponent = rotationIndicatorComponent.createObject(mapControl, { "topIndicator": true })
38 _bottomRotationIndicatorComponent = rotationIndicatorComponent.createObject(mapControl, { "topIndicator": false })
39 mapControl.addMapItem(_topRotationIndicatorComponent)
40 mapControl.addMapItem(_bottomRotationIndicatorComponent)
41 }
42 }
43
44 function removeVisuals() {
45 if (_circleComponent) {
46 _circleComponent.destroy()
47 _circleComponent = undefined
48 }
49 if (_topRotationIndicatorComponent) {
50 _topRotationIndicatorComponent.destroy()
51 _bottomRotationIndicatorComponent.destroy()
52 _topRotationIndicatorComponent = undefined
53 _bottomRotationIndicatorComponent = undefined
54 }
55 }
56
57 function addDragHandles() {
58 if (!_dragHandlesComponent) {
59 _dragHandlesComponent = dragHandlesComponent.createObject(mapControl)
60 }
61 }
62
63 function removeDragHandles() {
64 if (_dragHandlesComponent) {
65 _dragHandlesComponent.destroy()
66 _dragHandlesComponent = undefined
67 }
68 }
69
70 function updateInternalComponents() {
71 if (visible) {
72 addVisuals()
73 if (interactive) {
74 addDragHandles()
75 } else {
76 removeDragHandles()
77 }
78 } else {
79 removeVisuals()
80 removeDragHandles()
81 }
82 }
83
84 Component.onCompleted: {
85 updateInternalComponents()
86 }
87
88 Component.onDestruction: {
89 removeVisuals()
90 removeDragHandles()
91 }
92
93 onInteractiveChanged: updateInternalComponents()
94 onVisibleChanged: updateInternalComponents()
95
96 Component {
97 id: rotationIndicatorComponent
98
99 MapQuickItem {
100 visible: mapCircle.showRotation
101 property bool topIndicator: true
102
103 property real _rotationRadius: _radius
104
105 function updateCoordinate() {
106 coordinate = mapCircle.center.atDistanceAndAzimuth(_radius, topIndicator ? 0 : 180)
107 }
108
109 Component.onCompleted: updateCoordinate()
110
111 on_RotationRadiusChanged: updateCoordinate()
112
113 Connections {
114 target: mapCircle
115 function onCenterChanged() { updateCoordinate() }
116 }
117
118 sourceItem: Shape {
119 width: ScreenTools.defaultFontPixelHeight
120 height: ScreenTools.defaultFontPixelHeight
121 anchors.centerIn: parent
122
123 transform: Rotation {
124 origin.x: width / 2
125 origin.y: height / 2
126 angle: (mapCircle.clockwiseRotation ? 0 : 180) + (topIndicator ? 180 : 0)
127 }
128
129 ShapePath {
130 strokeWidth: 2
131 strokeColor: borderColor
132 fillColor: borderColor
133 startX: 0
134 startY: width / 2
135 PathLine { x: width; y: width }
136 PathLine { x: width; y: 0 }
137 PathLine { x: 0; y: width / 2 }
138 }
139
140 QGCMouseArea {
141 fillItem: parent
142 onClicked: mapCircle.clockwiseRotation = !mapCircle.clockwiseRotation
143 visible: mapCircle.interactive
144 }
145 }
146 }
147 }
148
149 Component {
150 id: circleComponent
151
152 MapCircle {
153 color: interiorColor
154 opacity: interiorOpacity
155 border.color: borderColor
156 border.width: borderWidth
157 center: mapCircle.center
158 radius: _radius
159 }
160 }
161
162 Component {
163 id: dragHandleComponent
164
165 MapQuickItem {
166 id: mapQuickItem
167 anchorPoint.x: dragHandle.width / 2
168 anchorPoint.y: dragHandle.height / 2
169 z: QGroundControl.zOrderMapItems + 2
170
171 sourceItem: Item {
172 id: handleContainer
173 width: dragHandle.width + labelControl.width
174 height: dragHandle.height
175
176 Rectangle {
177 id: dragHandle
178 width: ScreenTools.defaultFontPixelHeight * 1.5
179 height: width
180 radius: width / 2
181 color: "white"
182 opacity: .90
183 }
184
185 Rectangle {
186 id: labelControl
187
188 anchors {
189 bottom: dragHandle.top
190 bottomMargin: ScreenTools.defaultFontPixelHeight * 0.25
191 horizontalCenter: dragHandle.horizontalCenter
192 }
193 height: dragHandle.height
194 width: labelText.width + (ScreenTools.defaultFontPixelHeight * 0.25 * 2)
195 radius: height / 2
196
197 color: "white"
198 opacity: 0.5
199 visible: _root.radiusLabelVisible
200 }
201
202 QGCLabel {
203 id: labelText
204
205 anchors.centerIn: labelControl
206
207 color: "black"
208 text: QGroundControl.unitsConversion.metersToAppSettingsHorizontalDistanceUnits(_radius).toFixed(0) +
209 " " + QGroundControl.unitsConversion.appSettingsHorizontalDistanceUnitsString
210 verticalAlignment: Text.AlignVCenter
211 visible: labelControl.visible
212 }
213 }
214 }
215 }
216
217 Component {
218 id: centerDragAreaComponent
219
220 MissionItemIndicatorDrag {
221 mapControl: _root.mapControl
222
223 onItemCoordinateChanged: mapCircle.center = itemCoordinate
224 }
225 }
226
227 Component {
228 id: radiusDragAreaComponent
229
230 MissionItemIndicatorDrag {
231 mapControl: _root.mapControl
232
233 onItemCoordinateChanged: mapCircle.radius.rawValue = mapCircle.center.distanceTo(itemCoordinate)
234 }
235 }
236
237 Component {
238 id: dragHandlesComponent
239
240 Item {
241 property var centerDragHandle
242 property var centerDragArea
243 property var radiusDragHandle
244 property var radiusDragArea
245 property var radiusDragCoord: QtPositioning.coordinate()
246 property var circleCenterCoord: mapCircle.center
247 property real circleRadius: _radius
248
249 function calcRadiusDragCoord() {
250 radiusDragCoord = mapCircle.center.atDistanceAndAzimuth(circleRadius, 90)
251 }
252
253 onCircleCenterCoordChanged: calcRadiusDragCoord()
254 onCircleRadiusChanged: calcRadiusDragCoord()
255
256 Component.onCompleted: {
257 calcRadiusDragCoord()
258 radiusDragHandle = dragHandleComponent.createObject(mapControl)
259 radiusDragHandle.coordinate = Qt.binding(function() { return radiusDragCoord })
260 mapControl.addMapItem(radiusDragHandle)
261 radiusDragArea = radiusDragAreaComponent.createObject(mapControl, { "itemIndicator": radiusDragHandle, "itemCoordinate": radiusDragCoord } )
262 centerDragHandle = dragHandleComponent.createObject(mapControl, { "visible": _root.centerDragHandleVisible })
263 centerDragHandle.coordinate = Qt.binding(function() { return circleCenterCoord })
264 mapControl.addMapItem(centerDragHandle)
265 centerDragArea = centerDragAreaComponent.createObject(mapControl, { "itemIndicator": centerDragHandle, "itemCoordinate": circleCenterCoord, "visible": _root.centerDragHandleVisible })
266 }
267
268 Component.onDestruction: {
269 centerDragHandle.destroy()
270 centerDragArea.destroy()
271 radiusDragHandle.destroy()
272 radiusDragArea.destroy()
273 }
274 }
275 }
276}