QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GeoMapDropShadow.qml
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * (c) 2009-2024 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 *
5 * QGroundControl is licensed according to the terms in the file
6 * COPYING.md in the root of the source code directory.
7 *
8 ****************************************************************************/
9
10import QtQuick
11import QtPositioning
12
13import QGroundControl
14import QGroundControl.Controls
15import QGroundControl.GeoMap
16
17/// Draped ground shadow under a floating marker's drop line: GeoMapCircle
18/// clamps each rim point to the terrain mesh, so the shadow follows slopes
19/// instead of half-burying like a flat disc. Instantiate as a direct child
20/// of the marker's GeoMapItem — the item repositions itself in viewport
21/// coordinates and this undoes that offset (screen-space geometry).
22/// Also owns the marker-to-ground drop computation (dropLength /
23/// dropLineScale) shared with the delegate3D's GeoMapDropLine, since the
24/// shadow already samples the terrain under the marker.
25GeoMapCircle {
26 id: root
27
28 property var geoItem ///< Owning GeoMapItem (the marker)
29 property real indicatorSize: 0 ///< Marker diameter in pixels; sets the shadow radius
30
31 /// Scene-space length of the drop line from marker to the rendered
32 /// terrain (tracks terrainScale, so it flattens in lockstep with the
33 /// anchor z); 0 for clamped markers, so they show no line
34 readonly property real dropLength: {
35 if (!scene || !geoItem || geoItem.altitudeMode !== GeoMapItem.Absolute || isNaN(geoItem.coordinate.altitude)) {
36 return 0
37 }
38 const drop = (geoItem.coordinate.altitude - _groundHeight) * scene.verticalScale * scene.terrainScale
39 return isFinite(drop) ? Math.max(0, drop) : 0
40 }
41
42 /// Drop line diameter: constant apparent width, like the marker
43 /// (built-in QtQuick3D meshes are 100 units across)
44 readonly property real dropLineScale: _camera
45 ? (ScreenTools.defaultFontPixelHeight / 8) * _camera.distance * _camera.unitsPerPixelAtUnitDistance / 100
46 : 0
47
48 readonly property var _camera: scene ? scene.camera : null
49
50 // Rendered-terrain height (true meters) under the marker; terrainHeightAt
51 // is not a binding dependency, so re-sampled explicitly as terrain tiles
52 // arrive and when the marker moves. Keyed on lat/lon so altitude-only
53 // coordinate changes (e.g. terrain-bias updates) skip the resample.
54 property real _groundHeight: 0
55 readonly property real _latitude: geoItem ? geoItem.coordinate.latitude : NaN
56 readonly property real _longitude: geoItem ? geoItem.coordinate.longitude : NaN
57
58 function _updateGroundHeight() {
59 _groundHeight = (surfaceModel && geoItem && geoItem.coordinate.isValid)
60 ? surfaceModel.terrainHeightAt(geoItem.coordinate) : 0
61 }
62
63 Component.onCompleted: _updateGroundHeight()
64 onSurfaceModelChanged: _updateGroundHeight()
65 on_LatitudeChanged: _updateGroundHeight()
66 on_LongitudeChanged: _updateGroundHeight()
67
68 Connections {
69 target: root.surfaceModel
70 function onTerrainHeightsChanged() { root._updateGroundHeight() }
71 }
72
73 x: geoItem ? -geoItem.x : 0
74 y: geoItem ? -geoItem.y : 0
75 visible: dropLength > 0
76 opacity: scene ? scene.terrainScale : 0
77 scene: geoItem ? geoItem.scene : null
78 surfaceModel: geoItem ? geoItem.surfaceModel : null
79 center: geoItem ? geoItem.coordinate : QtPositioning.coordinate()
80 radiusMeters: _camera
81 ? (indicatorSize / 2) * _camera.distance * _camera.unitsPerPixelAtUnitDistance
82 : 1
83 strokeColor: "transparent"
84 strokeWidth: 0
85 // Translucent black (ADS-B shadow convention) so the colored drop line
86 // stays visible where it meets the shadow
87 fillColor: Qt.alpha("black", 0.35)
88}