7#include <QtGui/QPainter>
8#include <QtGui/QPixmap>
9#include <QtNetwork/QNetworkAccessManager>
23void Viewer3DTileQuery::MapTileContainer_t::init()
25 mapWidth = (tileMaxIndex.x() - tileMinIndex.x() + 1) * tileSize;
26 mapHeight = (tileMaxIndex.y() - tileMinIndex.y() + 1) * tileSize;
27 mapTextureImage = QImage(mapWidth, mapHeight, QImage::Format_RGBA32FPx4);
28 mapTextureImage.fill(Qt::gray);
31void Viewer3DTileQuery::MapTileContainer_t::setMapTile()
34 tmpPixmap.loadFromData(currentTileData);
35 QImage tmpImage = tmpPixmap.toImage().convertToFormat(QImage::Format_RGBA32FPx4);
37 QPainter painter(&mapTextureImage);
38 int idxX = (currentTileIndex.x() - tileMinIndex.x()) * tileSize;
39 int idxY = (currentTileIndex.y() - tileMinIndex.y()) * tileSize;
40 painter.drawImage(idxX, idxY, tmpImage);
43QByteArray Viewer3DTileQuery::MapTileContainer_t::mapData()
const
45 return QByteArray(
reinterpret_cast<const char *
>(mapTextureImage.constBits()), mapTextureImage.sizeInBytes());
48void Viewer3DTileQuery::MapTileContainer_t::clear()
53void Viewer3DTileQuery::_loadMapTiles(
int zoomLevel, QPoint tileMinIndex, QPoint tileMaxIndex)
55 _mapToBeLoaded.clear();
56 _mapToBeLoaded.zoomLevel = zoomLevel;
57 _mapToBeLoaded.tileMinIndex = tileMinIndex;
58 _mapToBeLoaded.tileMaxIndex = tileMaxIndex;
59 _mapToBeLoaded.init();
61 if (!_networkManager) {
62 _networkManager =
new QNetworkAccessManager(
this);
63 _networkManager->setTransferTimeout(9000);
66 for (
int x = tileMinIndex.x(); x <= tileMaxIndex.x(); x++) {
67 for (
int y = tileMinIndex.y(); y <= tileMaxIndex.y(); y++) {
68 _mapToBeLoaded.tileList.append(_tileKey(_mapId, x, y, zoomLevel));
70 auto *reply =
new Viewer3DTileReply(zoomLevel, x, y, _mapId, _mapType, _networkManager,
this);
77 _totalTilesCount = _mapToBeLoaded.tileList.size();
78 _downloadedTilesCount = 0;
79 qCDebug(Viewer3DTileQueryLog) <<
"Requesting" << _totalTilesCount <<
"tiles at zoom" << zoomLevel
80 <<
"x:[" << tileMinIndex.x() <<
".." << tileMaxIndex.x() <<
"]"
81 <<
"y:[" << tileMinIndex.y() <<
".." << tileMaxIndex.y() <<
"]";
91 const double lat1 = coordinateMin.latitude();
92 const double lon1 = coordinateMin.longitude();
93 const double lat2 = coordinateMax.latitude();
94 const double lon2 = coordinateMax.longitude();
96 const int minTileX = provider->long2tileX(std::fmin(lon1, lon2), zoomLevel);
97 const int maxTileX = provider->long2tileX(std::fmax(lon1, lon2), zoomLevel);
98 const int minTileY = provider->lat2tileY(std::fmax(lat1, lat2), zoomLevel);
99 const int maxTileY = provider->lat2tileY(std::fmin(lat1, lat2), zoomLevel);
101 const QPoint minTile(minTileX, minTileY);
102 const QPoint maxTile(maxTileX, maxTileY);
104 const QGeoCoordinate nwCoord(provider->tileY2lat(minTileY, zoomLevel),
105 provider->tileX2long(minTileX, zoomLevel), 0);
106 const QGeoCoordinate seCoord(provider->tileY2lat(maxTileY + 1, zoomLevel),
107 provider->tileX2long(maxTileX + 1, zoomLevel), 0);
109 const QGeoCoordinate finalMin = QGeoCoordinate(seCoord.latitude(), nwCoord.longitude(), 0);
110 const QGeoCoordinate finalMax = QGeoCoordinate(nwCoord.latitude(), seCoord.longitude(), 0);
112 _loadMapTiles(zoomLevel, minTile, maxTile);
114 TileStatistics_t output;
115 output.coordinateMin = finalMin;
116 output.coordinateMax = finalMax;
117 output.tileCounts = QSize(maxTile.x() - minTile.x() + 1, maxTile.y() - minTile.y() + 1);
118 output.zoomLevel = zoomLevel;
128 for (_zoomLevel =
kMaxZoomLevel; _zoomLevel > 0; _zoomLevel--) {
134 _textureCoordinateMin = coordinateMin;
135 _textureCoordinateMax = coordinateMax;
146 const double minLon = std::fmin(coordinateMin.longitude(), coordinateMax.longitude());
147 const double maxLon = std::fmax(coordinateMin.longitude(), coordinateMax.longitude());
148 const double minLat = std::fmin(coordinateMin.latitude(), coordinateMax.latitude());
149 const double maxLat = std::fmax(coordinateMin.latitude(), coordinateMax.latitude());
151 const int minTileX = provider->long2tileX(minLon, zoomLevel);
152 const int maxTileX = provider->long2tileX(maxLon, zoomLevel);
153 const int minTileY = provider->lat2tileY(maxLat, zoomLevel);
154 const int maxTileY = provider->lat2tileY(minLat, zoomLevel);
156 return (maxTileX - minTileX + 1) * (maxTileY - minTileY + 1);
164 reply->deleteLater();
169 auto *reply = qobject_cast<Viewer3DTileReply *>(QObject::sender());
171 const QString key = _tileKey(tileData.
mapId, tileData.
x, tileData.
y, tileData.
zoomLevel);
172 const qsizetype itemRemoved = _mapToBeLoaded.tileList.removeAll(key);
174 if (itemRemoved > 0) {
175 _mapToBeLoaded.currentTileIndex = QPoint(tileData.
x, tileData.
y);
176 _mapToBeLoaded.currentTileData = tileData.
data;
177 _mapToBeLoaded.setMapTile();
178 _downloadedTilesCount++;
179 emit
mapTileDownloaded(100.0f * (
static_cast<float>(_downloadedTilesCount) /
static_cast<float>(_totalTilesCount)));
181 if (_mapToBeLoaded.tileList.isEmpty()) {
182 qCDebug(Viewer3DTileQueryLog) <<
"All tiles downloaded";
183 _downloadedTilesCount = _totalTilesCount;
188 _cleanupReply(reply);
193 auto *reply = qobject_cast<Viewer3DTileReply *>(QObject::sender());
194 _cleanupReply(reply);
196 const QString key = _tileKey(tileData.
mapId, tileData.
x, tileData.
y, tileData.
zoomLevel);
197 _mapToBeLoaded.tileList.removeAll(key);
198 _downloadedTilesCount++;
199 emit
mapTileDownloaded(100.0f * (
static_cast<float>(_downloadedTilesCount) /
static_cast<float>(_totalTilesCount)));
201 if (_mapToBeLoaded.tileList.isEmpty()) {
202 _downloadedTilesCount = _totalTilesCount;
209 auto *reply = qobject_cast<Viewer3DTileReply *>(QObject::sender());
210 _cleanupReply(reply);
214 emit
textureGeometryReady(_findAndLoadMapTiles(_zoomLevel, _textureCoordinateMin, _textureCoordinateMax));
218QString Viewer3DTileQuery::_tileKey(
int mapId,
int x,
int y,
int zoomLevel)
220 return QString::asprintf(
"%010d%08d%08d%03d", mapId, x, y, zoomLevel);
#define QGC_LOGGING_CATEGORY(name, categoryStr)
std::shared_ptr< const MapProvider > SharedMapProvider
static constexpr int kMaxZoomLevel
static constexpr int kMaxTileCounts
static std::shared_ptr< const MapProvider > getMapProviderFromQtMapId(int qtMapId)
void textureGeometryReady(TileStatistics_t tileInfo)
void mapTileDownloaded(float progress)
void adaptiveMapTilesLoader(const QString &mapType, int mapId, const QGeoCoordinate &coordinateMin, const QGeoCoordinate &coordinateMax)
int maxTileCount(int zoomLevel, const QGeoCoordinate &coordinateMin, const QGeoCoordinate &coordinateMax)
void loadingMapCompleted()
void tileDone(TileInfo_t)
void tileEmpty(TileInfo_t)
void tileGiveUp(TileInfo_t)