QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
Viewer3DTerrainTexture.cc
Go to the documentation of this file.
2
3#include <tuple>
4
5#include "Fact.h"
6#include "FlightMapSettings.h"
8#include "QGCMapEngine.h"
9#include "QGCMapUrlEngine.h"
10#include "SettingsManager.h"
11#include "Viewer3DMapProvider.h"
12#include "Viewer3DTileQuery.h"
14
15QGC_LOGGING_CATEGORY(Viewer3DTerrainTextureLog, "Viewer3d.Viewer3DTerrainTexture")
16
18 : _flightMapSettings(SettingsManager::instance()->flightMapSettings())
19{
20 _onMapTypeChanged();
21
22 connect(_flightMapSettings->mapType(), &Fact::rawValueChanged, this, &Viewer3DTerrainTexture::_onMapTypeChanged);
23}
24
26{
27 _setTextureLoaded(false);
29
30 QGeoCoordinate bbMin;
31 QGeoCoordinate bbMax;
32
33 if (_mapProvider && _mapProvider->mapLoaded()) {
34 std::tie(bbMin, bbMax) = _mapProvider->mapBoundingBox();
35 } else if (_fallbackCenter.isValid()) {
36 // No OSM map loaded: load a small default tile area around the
37 // fallback center (vehicle home position).
38 std::tie(bbMin, bbMax) = _fallbackBoundingBox(_fallbackCenter);
39 } else {
40 qCDebug(Viewer3DTerrainTextureLog) << "loadTexture: no map loaded and no fallback center";
41 return;
42 }
43
44 if (!_terrainTileLoader) {
45 _terrainTileLoader = new Viewer3DTileQuery(this);
46 }
47
48 connect(_terrainTileLoader, &Viewer3DTileQuery::loadingMapCompleted, this, &Viewer3DTerrainTexture::_updateTexture, Qt::UniqueConnection);
49 connect(_terrainTileLoader, &Viewer3DTileQuery::textureGeometryReady, this, &Viewer3DTerrainTexture::setTextureGeometry, Qt::UniqueConnection);
50
51 _terrainTileLoader->adaptiveMapTilesLoader(_mapType, _mapId, bbMin, bbMax);
52}
53
54std::pair<QGeoCoordinate, QGeoCoordinate> Viewer3DTerrainTexture::_fallbackBoundingBox(const QGeoCoordinate &center)
55{
56 constexpr double fallbackRadiusMeters = 500.0;
57 const QGeoCoordinate south = center.atDistanceAndAzimuth(fallbackRadiusMeters, 180);
58 const QGeoCoordinate west = center.atDistanceAndAzimuth(fallbackRadiusMeters, 270);
59 const QGeoCoordinate north = center.atDistanceAndAzimuth(fallbackRadiusMeters, 0);
60 const QGeoCoordinate east = center.atDistanceAndAzimuth(fallbackRadiusMeters, 90);
61 return {QGeoCoordinate(south.latitude(), west.longitude(), 0),
62 QGeoCoordinate(north.latitude(), east.longitude(), 0)};
63}
64
65void Viewer3DTerrainTexture::setFallbackCenter(const QGeoCoordinate &newFallbackCenter)
66{
67 if (_fallbackCenter == newFallbackCenter) {
68 return;
69 }
70 _fallbackCenter = newFallbackCenter;
72
73 // The fallback region only drives the texture when no map is loaded.
74 if (!_mapProvider || !_mapProvider->mapLoaded()) {
75 if (!_fallbackCenter.isValid() && _terrainTileLoader) {
76 // Fallback center went invalid: drop any in-flight tile query so
77 // stale results can't resurrect texture state for a region that
78 // no longer has meaning. Disconnect first: the loader stays alive
79 // until the deferred delete runs and could still emit.
80 disconnect(_terrainTileLoader, nullptr, this, nullptr);
81 _terrainTileLoader->deleteLater();
82 _terrainTileLoader = nullptr;
83 _setTextureLoaded(false);
85 } else {
87 }
88 }
89}
90
91void Viewer3DTerrainTexture::_updateTexture()
92{
93 if (!_terrainTileLoader) {
94 return;
95 }
96
97 qCDebug(Viewer3DTerrainTextureLog) << "Texture loaded:" << _terrainTileLoader->mapSize();
98 setSize(_terrainTileLoader->mapSize());
99 setFormat(QQuick3DTextureData::RGBA32F);
100 setHasTransparency(false);
101
102 setTextureData(_terrainTileLoader->mapData());
103 _setTextureLoaded(true);
105 disconnect(_terrainTileLoader, &Viewer3DTileQuery::loadingMapCompleted, this, &Viewer3DTerrainTexture::_updateTexture);
106
107 _terrainTileLoader->deleteLater();
108 _terrainTileLoader = nullptr;
109}
110
111void Viewer3DTerrainTexture::_onMapTypeChanged()
112{
113 _mapType = _flightMapSettings->mapProvider()->rawValue().toString()
114 + QStringLiteral(" ")
115 + _flightMapSettings->mapType()->rawValue().toString();
116
117 const int mapId = UrlFactory::getQtMapIdFromProviderType(_mapType);
118
119 if (mapId == _mapId) {
120 return;
121 }
122
123 qCDebug(Viewer3DTerrainTextureLog) << "Map type changed:" << _mapType << "mapId:" << mapId;
124 _mapId = mapId;
125 loadTexture();
126}
127
128void Viewer3DTerrainTexture::setRoiMinCoordinate(const QGeoCoordinate &newRoiMinCoordinate)
129{
130 if (_roiMinCoordinate == newRoiMinCoordinate) {
131 return;
132 }
133 _roiMinCoordinate = newRoiMinCoordinate;
135}
136
137void Viewer3DTerrainTexture::setRoiMaxCoordinate(const QGeoCoordinate &newRoiMaxCoordinate)
138{
139 if (_roiMaxCoordinate == newRoiMaxCoordinate) {
140 return;
141 }
142 _roiMaxCoordinate = newRoiMaxCoordinate;
144}
145
147{
148 if (_mapProvider == newMapProvider) {
149 return;
150 }
151
152 if (_mapProvider) {
154 }
155
156 _mapProvider = newMapProvider;
157
158 if (_mapProvider) {
160 // Handle late binding: provider may already have a loaded map before this object is wired.
161 loadTexture();
162 }
163
164 emit mapProviderChanged();
165}
166
167void Viewer3DTerrainTexture::setTileCount(const QSize &newTileCount)
168{
169 if (_tileCount == newTileCount) {
170 return;
171 }
172 _tileCount = newTileCount;
173 emit tileCountChanged();
174}
175
176void Viewer3DTerrainTexture::setTextureGeometryDone(bool newTextureGeometryDone)
177{
178 if (_textureGeometryDone == newTextureGeometryDone) {
179 return;
180 }
181 _textureGeometryDone = newTextureGeometryDone;
183}
184
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void rawValueChanged(const QVariant &value)
Provides access to all app settings.
static int getQtMapIdFromProviderType(QStringView type)
virtual std::pair< QGeoCoordinate, QGeoCoordinate > mapBoundingBox() const =0
virtual bool mapLoaded() const =0
void setRoiMinCoordinate(const QGeoCoordinate &newRoiMinCoordinate)
void setTextureGeometryDone(bool newTextureGeometryDone)
void setRoiMaxCoordinate(const QGeoCoordinate &newRoiMaxCoordinate)
void setTextureGeometry(const Viewer3DTileStatistics &tileInfo)
void setFallbackCenter(const QGeoCoordinate &newFallbackCenter)
void setTileCount(const QSize &newTileCount)
void setMapProvider(Viewer3DMapProvider *newMapProvider)
void textureGeometryReady(TileStatistics_t tileInfo)
void adaptiveMapTilesLoader(const QString &mapType, int mapId, const QGeoCoordinate &coordinateMin, const QGeoCoordinate &coordinateMax)
QByteArray mapData() const
QSize mapSize() const
void loadingMapCompleted()