QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
SurfacePatchModel.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 <QtCore/QAbstractListModel>
13#include <QtCore/QElapsedTimer>
14#include <QtCore/QHash>
15#include <QtCore/QList>
16#include <QtCore/QSet>
17#include <QtCore/QString>
18#include <QtCore/QStringList>
19#include <QtGui/QImage>
20#include <QtQmlIntegration/QtQmlIntegration>
21
22#include "TileMath.h"
23
24class GeoScene;
25class GeoMapCamera;
26class HeightField;
27class HeightSource;
28class QNetworkAccessManager;
29class QTimer;
30class SurfaceModel;
31class TileImageSource;
32
33Q_MOC_INCLUDE("GeoScene.h")
34Q_MOC_INCLUDE("HeightField.h")
35
41class SurfacePatchModel : public QAbstractListModel
42{
43 Q_OBJECT
44 QML_ELEMENT
45 Q_PROPERTY(GeoScene* scene READ scene WRITE setScene NOTIFY sceneChanged)
46 Q_PROPERTY(bool terrain READ terrain WRITE setTerrain NOTIFY terrainChanged)
47 Q_PROPERTY(bool debugHills READ debugHills WRITE setDebugHills NOTIFY debugHillsChanged)
48 Q_PROPERTY(QString mapType READ mapType WRITE setMapType NOTIFY mapTypeChanged)
49 Q_PROPERTY(int gridSize READ gridSize CONSTANT)
50 Q_PROPERTY(double maxRangeMultiplier READ maxRangeMultiplier CONSTANT)
51 Q_PROPERTY(int patchCount READ patchCount NOTIFY statsChanged)
52 Q_PROPERTY(int pendingCount READ pendingCount NOTIFY statsChanged)
53 Q_PROPERTY(int maxZoomLevel READ maxZoomLevel NOTIFY statsChanged)
54 Q_PROPERTY(bool statsEnabled READ statsEnabled WRITE setStatsEnabled NOTIFY statsEnabledChanged)
55 Q_PROPERTY(QString statsText READ statsText NOTIFY statsTextChanged)
56 Q_PROPERTY(bool capturing READ capturing NOTIFY capturingChanged)
57
58public:
59 explicit SurfacePatchModel(QObject* parent = nullptr);
61
77
78 GeoScene* scene() const { return _scene; }
79
80 void setScene(GeoScene* scene);
81
82 bool terrain() const { return _terrain; }
83
86 void setTerrain(bool terrain);
87
88 bool debugHills() const { return _debugHills; }
89
90 void setDebugHills(bool debugHills);
91
92 QString mapType() const { return _mapType; }
93
96 void setMapType(const QString& mapType);
97
98 int gridSize() const;
99
102 HeightField* heightField() const { return _heightField; }
103
107 Q_INVOKABLE double terrainHeightAt(const QGeoCoordinate& coordinate) const;
108
111 double maxRangeMultiplier() const;
112
113 int patchCount() const { return _keys.count(); }
114
115 int pendingCount() const;
116 int maxZoomLevel() const;
117
119 int pendingImageCount() const { return _imageRequestKey.count(); }
120
123 void setTileImageNetworkManager(QNetworkAccessManager* networkManager)
124 {
125 _tileImageNetworkManager = networkManager;
126 }
127
128 bool statsEnabled() const { return _statsEnabled; }
129
132 void setStatsEnabled(bool enabled);
133
134 QString statsText() const { return _statsText; }
135
136 bool capturing() const { return _capturing; }
137
139 Q_INVOKABLE void startCapture();
140
143 Q_INVOKABLE QString stopCapture();
144
148 Q_INVOKABLE void analyzeSurface() const;
149
150#ifdef QGC_UNITTEST_BUILD
152 void drainUpdates();
153#endif
154
155 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
156 QVariant data(const QModelIndex& index, int role) const override;
157 QHash<int, QByteArray> roleNames() const override;
158
159signals:
170
171private slots:
172 void _patchAdded(const TileMath::TileKey& key);
173 void _patchReady(const TileMath::TileKey& key);
174 void _patchEdgeDeltasChanged(const TileMath::TileKey& key);
175 void _patchRemoved(const TileMath::TileKey& key);
176 void _sceneOriginChanged();
177 void _tileImageReady(int requestId, const QImage& image);
178 void _tileImageFailed(int requestId);
179 void _statsTick();
180
181private:
182 void _rebuildSurfaceModel();
183 void _resetImagery();
184 void _requestTileImage(const TileMath::TileKey& key);
185 void _retryFailedImages();
186 void _notifyTileImageChanged(const TileMath::TileKey& key);
187 void _invalidateFallbacks(const TileMath::TileKey& tile);
188 void _notifyCoveredMayHaveChanged(const TileMath::TileKey& changedKey);
189 void _scheduleStatsChanged();
190 void _startStatsSampling();
191 QImage _fallbackImage(const TileMath::TileKey& key) const;
192 bool _fallbackAvailable(const TileMath::TileKey& key) const;
193 GeoMapCamera* _camera() const;
194
195 static constexpr int kMaxRetiredImages = 128;
196 static constexpr int kMaxAncestorFallbackLevels = 8;
197 static constexpr int kImageRetryMs = 3000;
198
199 GeoScene* _scene = nullptr;
200 HeightSource* _heightSource = nullptr;
201 HeightField* _heightField = nullptr;
202 SurfaceModel* _surfaceModel = nullptr;
203 bool _terrain = false;
204 bool _debugHills = false;
205 QString _mapType;
206 TileImageSource* _tileSource = nullptr;
207 QNetworkAccessManager* _tileImageNetworkManager = nullptr;
208 QHash<TileMath::TileKey, QImage> _tileImages;
212 mutable QHash<TileMath::TileKey, QImage> _fallbackCache;
213 QList<TileMath::TileKey> _retiredOrder;
214 QHash<int, TileMath::TileKey> _imageRequestKey;
215 QHash<TileMath::TileKey, int> _imageRequestByKey;
216 QSet<TileMath::TileKey> _failedImageKeys;
217 QTimer* _imageRetryTimer = nullptr;
218 QList<TileMath::TileKey> _keys;
219
220 // Perf counters sampled by _statsTick (see setStatsEnabled)
221 QTimer* _statsTimer = nullptr;
222 bool _statsEnabled = false;
223 bool _statsNotifyPending = false;
224 QString _statsText;
225 int _statAdds = 0;
226 int _statRemoves = 0;
227 mutable int _statComposites = 0;
228
229 // Capture recording (see startCapture)
230 bool _capturing = false;
231 QStringList _captureRows;
232 QElapsedTimer _captureClock;
233 double _captureWorstMaxMs = 0.0;
234 double _captureWorstAvgMs = 0.0;
235};
void debugHillsChanged()
void statsEnabledChanged()
QString mapType() const
void terrainHeightsChanged()
terrainHeightAt answers changed somewhere: consumers re-query
HeightField * heightField() const
void setTileImageNetworkManager(QNetworkAccessManager *networkManager)
bool debugHills() const
@ SpanRole
patch edge length (m)
@ TileImageRole
drapable image: own tile, or ancestor/descendant fallback while loading
@ HasTileImageRole
QImage is opaque to QML; bool validity for bindings.
@ EdgeLodDeltasRole
{N,S,W,E} coarser-neighbor LOD deltas for edge stitching
@ ZoomRole
quadtree zoom level
@ TileYRole
slippy tile y of the patch key
@ CenterYRole
patch center y in scene meters
@ CoveredRole
pending but overlapped by a ready patch: delegate suppresses rendering
@ HeightsRole
vertex height grid (empty = flat)
@ TileXRole
slippy tile x of the patch key
int pendingImageCount() const
Tile image requests awaiting delivery or failure.
~SurfacePatchModel() override
GeoScene * scene() const
bool statsEnabled() const
QString statsText() const
int pendingCount() const
QString mapType() const