Skip to content

Commit

Permalink
3D View: Add support for Ardupilot, detect unavailable map tiles for …
Browse files Browse the repository at this point in the history
…the Bing provider
  • Loading branch information
omid-esrafilian committed Apr 6, 2024
1 parent 0e6b6ae commit 18585d8
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 24 deletions.
1 change: 0 additions & 1 deletion src/Viewer3D/OsmParser.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "OsmParser.h"
#include "earcut.hpp"
#include "Viewer3DUtils.h"
#include "QGCApplication.h"
#include "SettingsManager.h"

Expand Down
7 changes: 7 additions & 0 deletions src/Viewer3D/Viewer3DQml/Models3D/Viewer3DVehicleItems.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Node {
20, // Return To Launch
22, //Takeoff
195, // ROI
201, // ROI DEPRECATED
]; // based on MavCmdInfoCommon.json file
return acceptableCmdIds.includes(missionItem.command);
}
Expand All @@ -52,6 +53,10 @@ Node {
return qsTr("L");
}

if(missionItem.isTakeoffItem){
return qsTr("T"); //Takeoff
}

if(missionItem.specifiesCoordinate){
switch(missionItem.command){
case 16:
Expand All @@ -60,6 +65,8 @@ Node {
return qsTr("T"); //Takeoff
case 195:
return qsTr("R"); //ROI
case 201:
return qsTr("R"); //ROI DEPRECATED
}
}
return qsTr("null")
Expand Down
1 change: 1 addition & 0 deletions src/Viewer3D/Viewer3DQmlBackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void Viewer3DQmlBackend::_activeVehicleChangedEvent(Vehicle *vehicle)
_gpsRefSet = GPS_REF_NOT_SET;
}
}else{
_activeVehicleCoordinateChanged(_activeVehicle->coordinate());
connect(_activeVehicle, &Vehicle::coordinateChanged, this, &Viewer3DQmlBackend::_activeVehicleCoordinateChanged);
}
}
Expand Down
19 changes: 12 additions & 7 deletions src/Viewer3D/Viewer3DTerrainTexture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Viewer3DTerrainTexture::Viewer3DTerrainTexture()

setTextureGeometryDone(false);
setTextureLoaded(false);
setTextureDownloadProgress(0.0);
setTextureDownloadProgress(100.0);

// connect(_flightMapSettings->mapProvider(), &Fact::rawValueChanged, this, &Viewer3DTerrainTexture::mapTypeChangedEvent);
connect(_flightMapSettings->mapType(), &Fact::rawValueChanged, this, &Viewer3DTerrainTexture::mapTypeChangedEvent);
Expand All @@ -34,13 +34,11 @@ void Viewer3DTerrainTexture::loadTexture()
if(!_terrainTileLoader){
_terrainTileLoader = new MapTileQuery(this);
connect(_terrainTileLoader, &MapTileQuery::loadingMapCompleted, this, &Viewer3DTerrainTexture::updateTexture);
connect(_terrainTileLoader, &MapTileQuery::textureGeometryReady, this, &Viewer3DTerrainTexture::setTextureGeometry);
}
MapTileQuery::TileStatistics_t tileInfo = _terrainTileLoader->adaptiveMapTilesLoader(_mapType, _mapId,
_osmParser->getMapBoundingBoxCoordinate().first,
_osmParser->getMapBoundingBoxCoordinate().second);
setRoiMinCoordinate(tileInfo.coordinateMin);
setRoiMaxCoordinate(tileInfo.coordinateMax);
setTileCount(tileInfo.tileCounts);
_terrainTileLoader->adaptiveMapTilesLoader(_mapType, _mapId,
_osmParser->getMapBoundingBoxCoordinate().first,
_osmParser->getMapBoundingBoxCoordinate().second);
connect(_terrainTileLoader, &MapTileQuery::mapTileDownloaded, this, &Viewer3DTerrainTexture::setTextureDownloadProgress);
}
}
Expand Down Expand Up @@ -172,3 +170,10 @@ void Viewer3DTerrainTexture::setTextureDownloadProgress(float newTextureDownload
_textureDownloadProgress = newTextureDownloadProgress;
emit textureDownloadProgressChanged();
}

void Viewer3DTerrainTexture::setTextureGeometry(MapTileQuery::TileStatistics_t tileInfo)
{
setRoiMinCoordinate(tileInfo.coordinateMin);
setRoiMaxCoordinate(tileInfo.coordinateMax);
setTileCount(tileInfo.tileCounts);
}
1 change: 1 addition & 0 deletions src/Viewer3D/Viewer3DTerrainTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Viewer3DTerrainTexture : public QQuick3DTextureData

float textureDownloadProgress() const;
void setTextureDownloadProgress(float newTextureDownloadProgress);
void setTextureGeometry(MapTileQuery::TileStatistics_t tileInfo);

private:

Expand Down
29 changes: 23 additions & 6 deletions src/Viewer3D/Viewer3DTileQuery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define DEG_TO_RAD PI/180.0f
#define RAD_TO_DEG 180.0f/PI
#define MAX_TILE_COUNTS 200
#define MAX_ZOOM_LEVEL 20
#define MAX_ZOOM_LEVEL 23


enum RequestStat{
Expand Down Expand Up @@ -37,6 +37,7 @@ void MapTileQuery::loadMapTiles(int zoomLevel, QPoint tileMinIndex, QPoint tileM
Viewer3DTileReply* _reply = new Viewer3DTileReply(zoomLevel, x, y, _mapId, this);
connect(_reply, &Viewer3DTileReply::tileDone, this, &MapTileQuery::tileDone);
connect(_reply, &Viewer3DTileReply::tileGiveUp, this, &MapTileQuery::tileGiveUp);
connect(_reply, &Viewer3DTileReply::tileEmpty, this, &MapTileQuery::tileEmpty);
}
}
totalTilesCount = _mapToBeLoaded.tileList.size();
Expand Down Expand Up @@ -79,17 +80,19 @@ MapTileQuery::TileStatistics_t MapTileQuery::findAndLoadMapTiles(int zoomLevel,
return _output;
}

MapTileQuery::TileStatistics_t MapTileQuery::adaptiveMapTilesLoader(QString mapType, int mapId, QGeoCoordinate coordinate_1, QGeoCoordinate coordinate_2)
void MapTileQuery::adaptiveMapTilesLoader(QString mapType, int mapId, QGeoCoordinate coordinate_1, QGeoCoordinate coordinate_2)
{
int zoomLevel;
_mapId = mapId;
_mapType = mapType;
for(zoomLevel=MAX_ZOOM_LEVEL; zoomLevel>0; zoomLevel--){
if(maxTileCount(zoomLevel, coordinate_1, coordinate_2) < MAX_TILE_COUNTS){
for(_zoomLevel=MAX_ZOOM_LEVEL; _zoomLevel>0; _zoomLevel--){
if(maxTileCount(_zoomLevel, coordinate_1, coordinate_2) < MAX_TILE_COUNTS){
break;
}
}
return findAndLoadMapTiles(zoomLevel, coordinate_1, coordinate_2);

_textureCoordinateMin = coordinate_1;
_textureCoordinateMax = coordinate_2;
emit textureGeometryReady(findAndLoadMapTiles(_zoomLevel, coordinate_1, coordinate_2));
}

int MapTileQuery::maxTileCount(int zoomLevel, QGeoCoordinate coordinateMin, QGeoCoordinate coordinateMax)
Expand Down Expand Up @@ -191,6 +194,7 @@ void MapTileQuery::tileDone(Viewer3DTileReply::tileInfo_t _tileData)
}
disconnect(reply, &Viewer3DTileReply::tileDone, this, &MapTileQuery::tileDone);
disconnect(reply, &Viewer3DTileReply::tileGiveUp, this, &MapTileQuery::tileGiveUp);
disconnect(reply, &Viewer3DTileReply::tileEmpty, this, &MapTileQuery::tileEmpty);
reply->deleteLater();
}

Expand All @@ -199,7 +203,20 @@ void MapTileQuery::tileGiveUp(Viewer3DTileReply::tileInfo_t _tileData)
Viewer3DTileReply* reply = qobject_cast<Viewer3DTileReply*>(QObject::sender());
disconnect(reply, &Viewer3DTileReply::tileDone, this, &MapTileQuery::tileDone);
disconnect(reply, &Viewer3DTileReply::tileGiveUp, this, &MapTileQuery::tileGiveUp);
disconnect(reply, &Viewer3DTileReply::tileEmpty, this, &MapTileQuery::tileEmpty);
reply->deleteLater();
}

void MapTileQuery::tileEmpty(Viewer3DTileReply::tileInfo_t _tileData)
{
Viewer3DTileReply* reply = qobject_cast<Viewer3DTileReply*>(QObject::sender());
disconnect(reply, &Viewer3DTileReply::tileDone, this, &MapTileQuery::tileDone);
disconnect(reply, &Viewer3DTileReply::tileEmpty, this, &MapTileQuery::tileEmpty);
reply->deleteLater();
if(_tileData.zoomLevel > 0 && _tileData.zoomLevel == _zoomLevel){
_zoomLevel -= 1;
emit textureGeometryReady(findAndLoadMapTiles(_zoomLevel, _textureCoordinateMin, _textureCoordinateMax));
}
}

QString MapTileQuery::getTileKey(int mapId, int x, int y, int zoomLevel)
Expand Down
7 changes: 5 additions & 2 deletions src/Viewer3D/Viewer3DTileQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class MapTileQuery : public QObject
Q_OBJECT
public:
explicit MapTileQuery(QObject *parent = nullptr);
TileStatistics_t adaptiveMapTilesLoader(QString mapType, int mapId, QGeoCoordinate coordinate_1, QGeoCoordinate coordinate_2);
void adaptiveMapTilesLoader(QString mapType, int mapId, QGeoCoordinate coordinate_1, QGeoCoordinate coordinate_2);
int maxTileCount(int zoomLevel, QGeoCoordinate coordinateMin, QGeoCoordinate coordinateMax);
QByteArray getMapData(){ return _mapToBeLoaded.getMapData();}
QSize getMapSize(){ return QSize(_mapToBeLoaded.mapWidth, _mapToBeLoaded.mapHeight);}
Expand All @@ -114,8 +114,9 @@ class MapTileQuery : public QObject
MapTileContainer_t _mapToBeLoaded;
int totalTilesCount, downloadedTilesCount;
int _mapId;
int _zoomLevel;
QString _mapType;

QGeoCoordinate _textureCoordinateMin, _textureCoordinateMax;

void loadMapTiles(int zoomLevel, QPoint tileMinIndex, QPoint tileMaxIndex);
TileStatistics_t findAndLoadMapTiles(int zoomLevel, QGeoCoordinate coordinate_1, QGeoCoordinate coordinate_2);
Expand All @@ -126,12 +127,14 @@ class MapTileQuery : public QObject
QGeoCoordinate pixelXYToLatLong(QPoint pixel, int zoomLevel);
void tileDone(Viewer3DTileReply::tileInfo_t _tileData);
void tileGiveUp(Viewer3DTileReply::tileInfo_t _tileData);
void tileEmpty(Viewer3DTileReply::tileInfo_t _tileData);
void httpReadyRead();
QString getTileKey(int mapId, int x, int y, int zoomLevel);

signals:
void loadingMapCompleted();
void mapTileDownloaded(float progress);
void textureGeometryReady(TileStatistics_t tileInfo);
};

#endif // VIEWER3DTILEQUERY_H
38 changes: 30 additions & 8 deletions src/Viewer3D/Viewer3DTileReply.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
#include "Viewer3DTileReply.h"

#include "QGCMapEngine.h"
#include <QFile>

QByteArray Viewer3DTileReply::_bingNoTileImage;

Viewer3DTileReply::Viewer3DTileReply(int zoomLevel, int tileX, int tileY, int mapId, QObject *parent)
: QObject{parent}
{
if (_bingNoTileImage.length() == 0) {
QFile file(":/res/BingNoTileBytes.dat");
file.open(QFile::ReadOnly);
_bingNoTileImage = file.readAll();
file.close();
}

_timeoutCounter = 0;
_timeoutTimer = new QTimer(this);
_networkManager = new QNetworkAccessManager(this);
Expand Down Expand Up @@ -41,11 +50,24 @@ void Viewer3DTileReply::prepareDownload()
void Viewer3DTileReply::requestFinished()
{
_tile.data = _reply->readAll();
UrlFactory* urlFactory = getQGCMapEngine()->urlFactory();
MapProvider* mapProvider = urlFactory->getMapProviderFromQtMapId(_tile.mapId);
// disconnect(_networkManager, &QNetworkAccessManager::finished, this, &Viewer3DTileReply::requestFinished);
_timeoutTimer->stop();
disconnect(_reply, &QNetworkReply::finished, this, &Viewer3DTileReply::requestFinished);
disconnect(_reply, &QNetworkReply::errorOccurred, this, &Viewer3DTileReply::requestError);
disconnect(_timeoutTimer, &QTimer::timeout, this, &Viewer3DTileReply::timeoutTimerEvent);

if(mapProvider && mapProvider->_isBingProvider() && _tile.data.size() && _tile.data == _bingNoTileImage){
// Bing doesn't return an error if you request a tile above supported zoom level
// It instead returns an image of a missing tile graphic. We need to detect that
// and error out so 3D View will deal with zooming correctly even if it doesn't have the tile.
// This allows us to zoom up to level 23 even though the tiles don't actually exist
// so we clear the data to imdicate it is not a valid tile
_tile.data.clear();
emit tileEmpty(_tile);
return;
}
emit tileDone(_tile);
}

Expand All @@ -59,15 +81,15 @@ void Viewer3DTileReply::requestError()
void Viewer3DTileReply::timeoutTimerEvent()
{
if(_timeoutCounter > 5){
_timeoutCounter = 0;
_networkManager->setTransferTimeout(14000);
_timeoutTimer->stop();
_timeoutTimer->start(15000);
// disconnect(_reply, &QNetworkReply::finished, this, &Viewer3DTileReply::requestFinished);
// disconnect(_reply, &QNetworkReply::errorOccurred, this, &Viewer3DTileReply::requestError);
// disconnect(_timeoutTimer, &QTimer::timeout, this, &Viewer3DTileReply::timeoutTimerEvent);
// emit tileGiveUp(_tile);
// _timeoutCounter = 0;
// _networkManager->setTransferTimeout(14000);
// _timeoutTimer->stop();
// _timeoutTimer->start(15000);
disconnect(_reply, &QNetworkReply::finished, this, &Viewer3DTileReply::requestFinished);
disconnect(_reply, &QNetworkReply::errorOccurred, this, &Viewer3DTileReply::requestError);
disconnect(_timeoutTimer, &QTimer::timeout, this, &Viewer3DTileReply::timeoutTimerEvent);
emit tileGiveUp(_tile);
_timeoutTimer->stop();
}else if(_tile.data.isEmpty()){
emit tileError(_tile);
prepareDownload();
Expand Down
2 changes: 2 additions & 0 deletions src/Viewer3D/Viewer3DTileReply.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Viewer3DTileReply : public QObject
QTimer* _timeoutTimer;
int _mapId;
int _timeoutCounter;
static QByteArray _bingNoTileImage;

void prepareDownload();
void requestFinished();
Expand All @@ -40,6 +41,7 @@ class Viewer3DTileReply : public QObject

signals:
void tileDone(tileInfo_t);
void tileEmpty(tileInfo_t);
void tileError(tileInfo_t);
void tileGiveUp(tileInfo_t);
};
Expand Down

0 comments on commit 18585d8

Please sign in to comment.