QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GeoMapCamera.h
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
10#pragma once
11
12#include <optional>
13
14#include <QtCore/QObject>
15#include <QtCore/QPointF>
16#include <QtCore/QSizeF>
17#include <QtCore/qnumeric.h>
18#include <QtGui/QQuaternion>
19#include <QtGui/QVector3D>
20#include <QtPositioning/QGeoCoordinate>
21#include <QtPositioning/QGeoRectangle>
22#include <QtQmlIntegration/QtQmlIntegration>
23
35class GeoMapCamera : public QObject
36{
37 Q_OBJECT
38 QML_ELEMENT
39 Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
40 Q_PROPERTY(qreal heading READ heading WRITE setHeading NOTIFY headingChanged)
41 Q_PROPERTY(qreal tilt READ tilt WRITE setTilt NOTIFY tiltChanged)
42 Q_PROPERTY(qreal distance READ distance WRITE setDistance NOTIFY distanceChanged)
44 Q_PROPERTY(QSizeF viewportSize READ viewportSize WRITE setViewportSize NOTIFY viewportSizeChanged)
45 Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged)
48 Q_PROPERTY(bool isTopDown READ isTopDown NOTIFY tiltChanged)
49 Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged)
50 Q_PROPERTY(qreal default3DTilt READ default3DTilt CONSTANT)
51 Q_PROPERTY(QPointF sceneOrigin READ sceneOrigin WRITE setSceneOrigin NOTIFY scenePoseChanged)
52 Q_PROPERTY(QVector3D scenePosition READ scenePosition NOTIFY scenePoseChanged)
53 Q_PROPERTY(QQuaternion sceneRotation READ sceneRotation NOTIFY scenePoseChanged)
54
55public:
56 explicit GeoMapCamera(QObject* parent = nullptr);
57
61 enum class Mode
62 {
63 Mode2D,
64 Mode3D
65 };
66 Q_ENUM(Mode)
67
68 static constexpr qreal kMinDistance = 10.0;
69 static constexpr qreal kMaxDistance = 40000000.0;
70 static constexpr qreal kMinTilt = 0.0;
71 static constexpr qreal kMaxTilt = 85.0;
72 static constexpr qreal kDefaultDistance = 1500.0;
73 // Applied to the larger viewport axis (see verticalFieldOfView). Moderate
74 // angle: wide-angle values skew level circles into tilted ellipses at the
75 // screen edges (off-axis rectilinear distortion)
76 static constexpr qreal kDefaultFieldOfView = 45.0;
77 static constexpr qreal kDefault3DTilt = 55.0;
78
79 QGeoCoordinate center() const;
80 void setCenter(const QGeoCoordinate& center);
81
85 bool isPositioned() const { return _positioned; }
86
87 qreal heading() const { return _heading; }
88
89 void setHeading(qreal heading);
90
91 qreal tilt() const { return _tilt; }
92
93 void setTilt(qreal tilt);
94
95 qreal distance() const { return _distance; }
96
97 void setDistance(qreal distance);
98
104 qreal centerElevation() const { return _centerElevation; }
105
106 void setCenterElevation(qreal elevation);
107
108 QSizeF viewportSize() const { return _viewportSize; }
109
110 void setViewportSize(const QSizeF& size);
111
112 qreal fieldOfView() const { return _fieldOfView; }
113
114 void setFieldOfView(qreal fov);
115
119 qreal verticalFieldOfView() const;
120
124 qreal unitsPerPixelAtUnitDistance() const;
125
129 bool isTopDown() const { return qFuzzyIsNull(_tilt); }
130
131 Mode mode() const { return _mode; }
132
133 void setMode(Mode mode);
134
135 qreal default3DTilt() const { return kDefault3DTilt; }
136
138 Q_INVOKABLE void reset();
139
141 Q_INVOKABLE void lookAt(const QGeoCoordinate& center, qreal heading, qreal tilt, qreal distance);
142
145 Q_INVOKABLE void goTo2D()
146 {
149 }
150
151 Q_INVOKABLE void goTo3D()
152 {
155 }
156
161 Q_INVOKABLE void beginPan(const QPointF& screenPos, double anchorZ = 0.0);
163 Q_INVOKABLE void panTo(const QPointF& screenPos);
164
166 Q_INVOKABLE void beginOrbit(const QPointF& screenPos, double anchorZ = 0.0);
170 Q_INVOKABLE void orbitTo(const QPointF& screenPos);
171
173 Q_INVOKABLE void beginLook(const QPointF& screenPos);
178 Q_INVOKABLE void lookTo(const QPointF& screenPos);
179
182 Q_INVOKABLE void rotateBy(qreal degrees, const QPointF& screenPos);
183
186 Q_INVOKABLE void tiltBy(qreal degrees, const QPointF& screenPos);
187
190 Q_INVOKABLE void zoom(qreal amount, const QPointF& screenPos);
191
194 Q_INVOKABLE void zoomBy(qreal factor, const QPointF& screenPos);
195
198 Q_INVOKABLE qreal sceneUnitsPerPixel() const;
199
204 Q_INVOKABLE qreal distanceForZoomLevel(qreal zoomLevel) const;
205
209 Q_INVOKABLE qreal zoomLevelForDistance(qreal distance) const;
210
218 Q_INVOKABLE QGeoCoordinate centerForCoordinateAtScreenPoint(const QGeoCoordinate& coordinate,
219 const QPointF& screenPos, double worldZ = 0.0,
220 double centerElevation = qQNaN()) const;
221
226 Q_INVOKABLE void fitToRegion(const QGeoRectangle& region);
227
230 QVector3D cameraPosition() const;
231
235 QPointF cameraGroundPosition() const;
236
239 QPointF sceneOrigin() const { return _sceneOrigin; }
240
241 void setSceneOrigin(const QPointF& origin);
242
245 QVector3D scenePosition() const;
246
249 QQuaternion sceneRotation() const;
250
254 struct PickRay
255 {
256 double originX = 0.0;
257 double originY = 0.0;
258 double originZ = 0.0;
259 double dirX = 0.0;
260 double dirY = 0.0;
261 double dirZ = 0.0;
262 };
263
267 std::optional<PickRay> pickRayAt(const QPointF& screenPos) const;
268
273 std::optional<QPointF> screenToGround(const QPointF& screenPos, double planeZ = 0.0) const;
274
278 Q_INVOKABLE QGeoCoordinate coordinateAtScreenPoint(const QPointF& screenPos, double worldZ = 0.0) const;
279
284 std::optional<QPointF> groundPointCapped(const QPointF& screenPos, double maxRange) const;
285
289 std::optional<QPointF> worldToScreen(const QPointF& worldGround, double worldZ = 0.0) const;
290
291signals:
305
306private:
307 void _setCenterWorld(const QPointF& world);
309 void _anchorToScreen(const QPointF& anchorWorld, const QPointF& screenPos, double anchorZ = 0.0);
310 static qreal _normalizedHeading(qreal heading);
311
312 QPointF _centerWorld; // mercator meters
313 bool _positioned = false;
314 QPointF _sceneOrigin; // mercator meters
315 Mode _mode = Mode::Mode2D;
316 qreal _heading = 0.0;
317 qreal _tilt = 0.0;
318 qreal _distance = kDefaultDistance;
319 qreal _centerElevation = 0.0;
320 QSizeF _viewportSize;
321 qreal _fieldOfView = kDefaultFieldOfView;
322
323 // Gesture state
324 std::optional<QPointF> _panAnchorWorld;
325 double _panAnchorZ = 0.0;
326 std::optional<QPointF> _orbitAnchorWorld;
327 double _orbitAnchorZ = 0.0;
328 QPointF _orbitAnchorScreen;
329 QPointF _orbitStartScreen;
330 qreal _orbitStartHeading = 0.0;
331 qreal _orbitStartTilt = 0.0;
332 std::optional<QPointF> _lookCameraGround; // fixed camera ground position (world meters)
333 qreal _lookCameraZ = 0.0;
334 QPointF _lookStartScreen;
335 qreal _lookStartHeading = 0.0;
336 qreal _lookStartTilt = 0.0;
337};
qreal default3DTilt() const
Q_INVOKABLE void panTo(const QPointF &screenPos)
Continue a pan gesture: the surface point picked at beginPan stays under the cursor.
void unitsPerPixelAtUnitDistanceChanged()
Q_INVOKABLE QGeoCoordinate coordinateAtScreenPoint(const QPointF &screenPos, double worldZ=0.0) const
QSizeF viewportSize() const
void distanceChanged()
void centerElevationChanged()
qreal unitsPerPixelAtUnitDistance() const
void setCenterElevation(qreal elevation)
void setMode(Mode mode)
qreal distance() const
Q_INVOKABLE void beginPan(const QPointF &screenPos, double anchorZ=0.0)
Q_INVOKABLE qreal zoomLevelForDistance(qreal distance) const
Q_INVOKABLE void lookTo(const QPointF &screenPos)
void setFieldOfView(qreal fov)
std::optional< QPointF > worldToScreen(const QPointF &worldGround, double worldZ=0.0) const
Q_INVOKABLE void goTo2D()
qreal fieldOfView() const
void tiltChanged()
static constexpr qreal kMinTilt
void verticalFieldOfViewChanged()
QPointF cameraGroundPosition() const
Q_INVOKABLE void fitToRegion(const QGeoRectangle &region)
Q_INVOKABLE qreal sceneUnitsPerPixel() const
Q_INVOKABLE void zoom(qreal amount, const QPointF &screenPos)
void setCenter(const QGeoCoordinate &center)
void headingChanged()
static constexpr qreal kDefault3DTilt
qreal centerElevation() const
static constexpr qreal kMinDistance
void setSceneOrigin(const QPointF &origin)
void scenePoseChanged()
Q_INVOKABLE void beginLook(const QPointF &screenPos)
Start a first-person look gesture at the given screen position (pixels)
void fieldOfViewChanged()
Q_INVOKABLE void zoomBy(qreal factor, const QPointF &screenPos)
Q_INVOKABLE void beginOrbit(const QPointF &screenPos, double anchorZ=0.0)
Start an orbit gesture at the given screen position (pixels); anchorZ as in beginPan.
Q_INVOKABLE void orbitTo(const QPointF &screenPos)
qreal verticalFieldOfView() const
void setDistance(qreal distance)
Q_INVOKABLE void lookAt(const QGeoCoordinate &center, qreal heading, qreal tilt, qreal distance)
Set the full pose in one call. tilt/distance are clamped.
bool isPositioned() const
std::optional< QPointF > screenToGround(const QPointF &screenPos, double planeZ=0.0) const
QVector3D cameraPosition() const
Q_INVOKABLE void goTo3D()
void setHeading(qreal heading)
QVector3D scenePosition() const
void setViewportSize(const QSizeF &size)
void viewportSizeChanged()
static constexpr qreal kDefaultDistance
Q_INVOKABLE void reset()
Restore the default pose at the current center (heading 0, tilt 0, default distance)
QPointF sceneOrigin() const
static constexpr qreal kMaxTilt
qreal heading() const
Q_INVOKABLE void tiltBy(qreal degrees, const QPointF &screenPos)
Mode mode() const
static constexpr qreal kDefaultFieldOfView
std::optional< QPointF > groundPointCapped(const QPointF &screenPos, double maxRange) const
Q_INVOKABLE void rotateBy(qreal degrees, const QPointF &screenPos)
std::optional< PickRay > pickRayAt(const QPointF &screenPos) const
Q_INVOKABLE qreal distanceForZoomLevel(qreal zoomLevel) const
void centerChanged()
qreal tilt() const
Q_INVOKABLE QGeoCoordinate centerForCoordinateAtScreenPoint(const QGeoCoordinate &coordinate, const QPointF &screenPos, double worldZ=0.0, double centerElevation=qQNaN()) const
QGeoCoordinate center() const
void modeChanged()
void setTilt(qreal tilt)
bool isTopDown() const
static constexpr qreal kMaxDistance
QQuaternion sceneRotation() const