Skip to content

Commit

Permalink
QtLocationPlugin: Add Elevation Provider Selection
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Sep 21, 2024
1 parent 4a29f1e commit 3f80685
Show file tree
Hide file tree
Showing 31 changed files with 922 additions and 499 deletions.
7 changes: 4 additions & 3 deletions src/QmlControls/QGroundControlQmlGlobal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
#include "QGCApplication.h"
#include "LinkManager.h"
#include "MAVLinkProtocol.h"
#include "ElevationMapProvider.h"
#include "FirmwarePluginManager.h"
#include "AppSettings.h"
#include "FlightMapSettings.h"
#include "SettingsManager.h"
#include "PositionManager.h"
#include "QGCMapEngineManager.h"
#include "ADSBVehicleManager.h"
Expand Down Expand Up @@ -335,12 +336,12 @@ int QGroundControlQmlGlobal::mavlinkSystemID()

QString QGroundControlQmlGlobal::elevationProviderName()
{
return CopernicusElevationProvider::kProviderKey;
return _settingsManager->flightMapSettings()->elevationMapProvider()->rawValue().toString();
}

QString QGroundControlQmlGlobal::elevationProviderNotice()
{
return CopernicusElevationProvider::kProviderNotice;
return _settingsManager->flightMapSettings()->elevationMapProvider()->rawValue().toString();
}

QString QGroundControlQmlGlobal::parameterFileExtension() const
Expand Down
4 changes: 2 additions & 2 deletions src/QmlControls/QGroundControlQmlGlobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ class QGroundControlQmlGlobal : public QGCTool
bool hasMAVLinkInspector () { return true; }
#endif

static QString elevationProviderName ();
static QString elevationProviderNotice ();
QString elevationProviderName ();
QString elevationProviderNotice ();

bool singleFirmwareSupport ();
bool singleVehicleSupport ();
Expand Down
71 changes: 64 additions & 7 deletions src/QtLocationPlugin/Providers/ElevationMapProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,28 @@

#include "ElevationMapProvider.h"
#include "TerrainTileCopernicus.h"
#include "TerrainTileArduPilot.h"

int CopernicusElevationProvider::long2tileX(double lon, int z) const
{
Q_UNUSED(z)
return static_cast<int>(floor((lon + 180.0) / TerrainTileCopernicus::tileSizeDegrees));
return static_cast<int>(floor((lon + 180.0) / TerrainTileCopernicus::kTileSizeDegrees));
}

int CopernicusElevationProvider::lat2tileY(double lat, int z) const
{
Q_UNUSED(z)
return static_cast<int>(floor((lat + 90.0) / TerrainTileCopernicus::tileSizeDegrees));
return static_cast<int>(floor((lat + 90.0) / TerrainTileCopernicus::kTileSizeDegrees));
}

QString CopernicusElevationProvider::_getURL(int x, int y, int zoom) const
{
Q_UNUSED(zoom)
return _mapUrl
.arg((static_cast<double>(y) * TerrainTileCopernicus::tileSizeDegrees) - 90.0)
.arg((static_cast<double>(x) * TerrainTileCopernicus::tileSizeDegrees) - 180.0)
.arg((static_cast<double>(y + 1) * TerrainTileCopernicus::tileSizeDegrees) - 90.0)
.arg((static_cast<double>(x + 1) * TerrainTileCopernicus::tileSizeDegrees) - 180.0);
.arg((static_cast<double>(y) * TerrainTileCopernicus::kTileSizeDegrees) - 90.0)
.arg((static_cast<double>(x) * TerrainTileCopernicus::kTileSizeDegrees) - 180.0)
.arg((static_cast<double>(y + 1) * TerrainTileCopernicus::kTileSizeDegrees) - 90.0)
.arg((static_cast<double>(x + 1) * TerrainTileCopernicus::kTileSizeDegrees) - 180.0);
}

QGCTileSet CopernicusElevationProvider::getTileCount(int zoom, double topleftLon,
Expand All @@ -59,5 +60,61 @@ QGCTileSet CopernicusElevationProvider::getTileCount(int zoom, double topleftLon

QByteArray CopernicusElevationProvider::serialize(const QByteArray &image) const
{
return TerrainTileCopernicus::serializeFromJson(image);
return TerrainTileCopernicus::serializeFromData(image);
}

/*===========================================================================*/

int ArduPilotTerrainElevationProvider::long2tileX(double lon, int z) const
{
Q_UNUSED(z)
return static_cast<int>(floor((lon + 180.0)));
}

int ArduPilotTerrainElevationProvider::lat2tileY(double lat, int z) const
{
Q_UNUSED(z)
return static_cast<int>(floor((lat + 90.0)));
}

QString ArduPilotTerrainElevationProvider::_getURL(int x, int y, int zoom) const
{
Q_UNUSED(zoom)

// For saving them internally we do 0-360 and 0-180 to avoid signs. Need to redo that to obtain proper format for call
int xForUrl = x - 180;
int yForUrl = y - 90;

const QString formattedStringYLat = (yForUrl > 0) ? QStringLiteral("N%1").arg(QString::number(yForUrl).rightJustified(2, '0')) :
QStringLiteral("S%1").arg(QString::number(-yForUrl).rightJustified(2, '0'));

const QString formattedStringXLong = (xForUrl > 0) ? QStringLiteral("E%1").arg(QString::number(xForUrl).rightJustified(3, '0')) :
QStringLiteral("W%1").arg(QString::number(-xForUrl).rightJustified(3, '0'));

return _mapUrl.arg(formattedStringYLat, formattedStringXLong);
}

QGCTileSet ArduPilotTerrainElevationProvider::getTileCount(int zoom, double topleftLon,
double topleftLat, double bottomRightLon,
double bottomRightLat) const
{
QGCTileSet set;
set.tileX0 = long2tileX(topleftLon, zoom);
set.tileY0 = lat2tileY(bottomRightLat, zoom);
set.tileX1 = long2tileX(bottomRightLon, zoom);
set.tileY1 = lat2tileY(topleftLat, zoom);

set.tileCount = (static_cast<quint64>(set.tileX1) -
static_cast<quint64>(set.tileX0) + 1) *
(static_cast<quint64>(set.tileY1) -
static_cast<quint64>(set.tileY0) + 1);

set.tileSize = getAverageSize() * set.tileCount;

return set;
}

QByteArray ArduPilotTerrainElevationProvider::serialize(const QByteArray &image) const
{
return TerrainTileArduPilot::serializeFromData(image);
}
42 changes: 37 additions & 5 deletions src/QtLocationPlugin/Providers/ElevationMapProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include "MapProvider.h"

static constexpr const quint32 AVERAGE_COPERNICUS_ELEV_SIZE = 2786;

class ElevationProvider : public MapProvider
{
protected:
Expand All @@ -21,13 +19,14 @@ class ElevationProvider : public MapProvider
virtual QByteArray serialize(const QByteArray &image) const = 0;
};

/// https://spacedata.copernicus.eu/collections/copernicus-digital-elevation-model
class CopernicusElevationProvider : public ElevationProvider
{
public:
CopernicusElevationProvider()
: ElevationProvider(
QStringLiteral("Copernicus Elevation"),
QStringLiteral("https://terrain-ce.suite.auterion.com/"),
kProviderKey,
kProviderURL,
QStringLiteral("bin"),
AVERAGE_COPERNICUS_ELEV_SIZE,
QGeoMapType::StreetMap) {}
Expand All @@ -43,9 +42,42 @@ class CopernicusElevationProvider : public ElevationProvider

static constexpr const char *kProviderKey = "Copernicus Elevation";
static constexpr const char *kProviderNotice = "© Airbus Defence and Space GmbH";
static constexpr const char *kProviderURL = "https://terrain-ce.suite.auterion.com";
static constexpr quint32 AVERAGE_COPERNICUS_ELEV_SIZE = 2786;

private:
QString _getURL(int x, int y, int zoom) const final;

const QString _mapUrl = QString(kProviderURL) + QStringLiteral("/api/v1/carpet?points=%1,%2,%3,%4");
};

class ArduPilotTerrainElevationProvider : public ElevationProvider
{
public:
ArduPilotTerrainElevationProvider()
: ElevationProvider(
kProviderKey,
kProviderURL,
QStringLiteral("hgt"),
AVERAGE_ARDUPILOT_ELEV_SIZE,
QGeoMapType::StreetMap) {}

int long2tileX(double lon, int z) const final;
int lat2tileY(double lat, int z) const final;

QGCTileSet getTileCount(int zoom, double topleftLon,
double topleftLat, double bottomRightLon,
double bottomRightLat) const final;

QByteArray serialize(const QByteArray &image) const final;

static constexpr const char *kProviderKey = "ArduPilot Terrain Elevation";
static constexpr const char *kProviderNotice = "© ArduPilot.org";
static constexpr const char *kProviderURL = "https://terrain.ardupilot.org/SRTM1";
static constexpr quint32 AVERAGE_ARDUPILOT_ELEV_SIZE = 100000;

private:
QString _getURL(int x, int y, int zoom) const final;

const QString _mapUrl = QStringLiteral("https://terrain-ce.suite.auterion.com/api/v1/carpet?points=%1,%2,%3,%4");
const QString _mapUrl = QString(kProviderURL) + QStringLiteral("/%1%2.hgt.zip");
};
1 change: 0 additions & 1 deletion src/QtLocationPlugin/QGCCachedTileSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <QGCApplication.h>
#include <QGCFileDownload.h>
#include <QGCLoggingCategory.h>
#include <TerrainTile.h>

#include <QtNetwork/QNetworkProxy>

Expand Down
13 changes: 13 additions & 0 deletions src/QtLocationPlugin/QGCMapUrlEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const QList<SharedMapProvider> UrlFactory::_providers = {
std::make_shared<VWorldSatMapProvider>(),

std::make_shared<CopernicusElevationProvider>(),
std::make_shared<ArduPilotTerrainElevationProvider>(),

std::make_shared<JapanStdMapProvider>(),
std::make_shared<JapanSeamlessMapProvider>(),
Expand Down Expand Up @@ -229,6 +230,18 @@ int UrlFactory::getQtMapIdFromProviderType(QStringView type)
return -1;
}

QStringList UrlFactory::getElevationProviderTypes()
{
QStringList types;
for (const SharedMapProvider &provider : _providers) {
if (provider->isElevationProvider()) {
(void) types.append(provider->getMapName());
}
}

return types;
}

QStringList UrlFactory::getProviderTypes()
{
QStringList types;
Expand Down
1 change: 1 addition & 0 deletions src/QtLocationPlugin/QGCMapUrlEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class UrlFactory
QStringView mapType);

static const QList<std::shared_ptr<const MapProvider>>& getProviders() { return _providers; }
static QStringList getElevationProviderTypes();
static QStringList getProviderTypes();
static int getQtMapIdFromProviderType(QStringView type);
static QString getProviderTypeFromQtMapId(int qtMapId);
Expand Down
26 changes: 18 additions & 8 deletions src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "ElevationMapProvider.h"
#include "QmlObjectListModel.h"
#include "QGCApplication.h"
#include "QGCToolbox.h"
#include "SettingsManager.h"
#include "QGCLoggingCategory.h"

#include <QtCore/qapplicationstatic.h>
Expand All @@ -28,9 +30,6 @@

QGC_LOGGING_CATEGORY(QGCMapEngineManagerLog, "qgc.qtlocation.qmlcontrol.qgcmapenginemanagerlog")

static const QString kQmlOfflineMapKeyName = QStringLiteral("QGCOfflineMap");
static const QString kElevationMapType = QString(CopernicusElevationProvider::kProviderKey); // TODO: Variable Elevation Provider Type

Q_APPLICATION_STATIC(QGCMapEngineManager, _mapEngineManager);

QGCMapEngineManager *QGCMapEngineManager::instance()
Expand Down Expand Up @@ -76,7 +75,8 @@ void QGCMapEngineManager::updateForCurrentView(double lon0, double lat0, double
}

if (_fetchElevation) {
const QGCTileSet set = UrlFactory::getTileCount(1, lon0, lat0, lon1, lat1, kElevationMapType);
const QString elevationProviderName = qgcApp()->toolbox()->settingsManager()->flightMapSettings()->elevationMapProvider()->rawValue().toString();
const QGCTileSet set = UrlFactory::getTileCount(1, lon0, lat0, lon1, lat1, elevationProviderName);
_elevationSet += set;
}

Expand Down Expand Up @@ -143,9 +143,11 @@ void QGCMapEngineManager::startDownload(const QString &name, const QString &mapT
qCWarning(QGCMapEngineManagerLog) << Q_FUNC_INFO << "No Tiles to save";
}

if ((mapType != kElevationMapType) && _fetchElevation) {
const int mapid = UrlFactory::getQtMapIdFromProviderType(mapType);
if (_fetchElevation && !UrlFactory::isElevation(mapid)) {
QGCCachedTileSet* const set = new QGCCachedTileSet(name + QStringLiteral(" Elevation"));
set->setMapTypeStr(kElevationMapType);
const QString elevationProviderName = qgcApp()->toolbox()->settingsManager()->flightMapSettings()->elevationMapProvider()->rawValue().toString();
set->setMapTypeStr(elevationProviderName);
set->setTopleftLat(_topleftLat);
set->setTopleftLon(_topleftLon);
set->setBottomRightLat(_bottomRightLat);
Expand All @@ -154,7 +156,7 @@ void QGCMapEngineManager::startDownload(const QString &name, const QString &mapT
set->setMaxZoom(1);
set->setTotalTileSize(_elevationSet.tileSize);
set->setTotalTileCount(static_cast<quint32>(_elevationSet.tileCount));
set->setType(kElevationMapType);
set->setType(elevationProviderName);

QGCCreateTileSetTask* const task = new QGCCreateTileSetTask(set);
(void) connect(task, &QGCCreateTileSetTask::tileSetSaved, this, &QGCMapEngineManager::_tileSetSaved);
Expand Down Expand Up @@ -458,11 +460,19 @@ QStringList QGCMapEngineManager::mapList()
QStringList QGCMapEngineManager::mapProviderList()
{
QStringList mapStringList = mapList();
(void) mapStringList.removeAll(CopernicusElevationProvider::kProviderKey);
const QStringList elevationStringList = elevationProviderList();
for (const QString &elevationProviderName : elevationStringList) {
(void) mapStringList.removeAll(elevationProviderName);
}

static const QRegularExpression providerType = QRegularExpression(QStringLiteral("^([^\\ ]*) (.*)$"));
(void) mapStringList.replaceInStrings(providerType,"\\1");
(void) mapStringList.removeDuplicates();

return mapStringList;
}

QStringList QGCMapEngineManager::elevationProviderList()
{
return UrlFactory::getElevationProviderTypes();
}
36 changes: 20 additions & 16 deletions src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,22 @@ class QGCMapEngineManager : public QObject
Q_MOC_INCLUDE("QmlObjectListModel.h")
Q_MOC_INCLUDE("QGCCachedTileSet.h")

Q_PROPERTY(bool fetchElevation MEMBER _fetchElevation NOTIFY fetchElevationChanged)
Q_PROPERTY(bool importReplace MEMBER _importReplace NOTIFY importReplaceChanged)
Q_PROPERTY(ImportAction importAction READ importAction WRITE setImportAction NOTIFY importActionChanged)
Q_PROPERTY(int actionProgress READ actionProgress NOTIFY actionProgressChanged)
Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged)
Q_PROPERTY(QmlObjectListModel *tileSets READ tileSets NOTIFY tileSetsChanged)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
Q_PROPERTY(QString tileCountStr READ tileCountStr NOTIFY tileCountChanged)
Q_PROPERTY(QString tileSizeStr READ tileSizeStr NOTIFY tileSizeChanged)
Q_PROPERTY(QStringList mapList READ mapList CONSTANT)
Q_PROPERTY(QStringList mapProviderList READ mapProviderList CONSTANT)
Q_PROPERTY(quint32 diskSpace READ diskSpace)
Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged)
Q_PROPERTY(quint64 tileCount READ tileCount NOTIFY tileCountChanged)
Q_PROPERTY(quint64 tileSize READ tileSize NOTIFY tileSizeChanged)
Q_PROPERTY(bool fetchElevation MEMBER _fetchElevation NOTIFY fetchElevationChanged)
Q_PROPERTY(bool importReplace MEMBER _importReplace NOTIFY importReplaceChanged)
Q_PROPERTY(ImportAction importAction READ importAction WRITE setImportAction NOTIFY importActionChanged)
Q_PROPERTY(int actionProgress READ actionProgress NOTIFY actionProgressChanged)
Q_PROPERTY(int selectedCount READ selectedCount NOTIFY selectedCountChanged)
Q_PROPERTY(QmlObjectListModel *tileSets READ tileSets NOTIFY tileSetsChanged)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
Q_PROPERTY(QString tileCountStr READ tileCountStr NOTIFY tileCountChanged)
Q_PROPERTY(QString tileSizeStr READ tileSizeStr NOTIFY tileSizeChanged)
Q_PROPERTY(QStringList mapList READ mapList CONSTANT)
Q_PROPERTY(QStringList mapProviderList READ mapProviderList CONSTANT)
Q_PROPERTY(QStringList elevationProviderList READ elevationProviderList CONSTANT)
Q_PROPERTY(quint32 diskSpace READ diskSpace)
Q_PROPERTY(quint32 freeDiskSpace READ freeDiskSpace NOTIFY freeDiskSpaceChanged)
Q_PROPERTY(quint64 tileCount READ tileCount NOTIFY tileCountChanged)
Q_PROPERTY(quint64 tileSize READ tileSize NOTIFY tileSizeChanged)

public:
QGCMapEngineManager(QObject *parent = nullptr);
Expand Down Expand Up @@ -97,6 +98,7 @@ class QGCMapEngineManager : public QObject

static QStringList mapList();
static QStringList mapProviderList();
static QStringList elevationProviderList();

signals:
void actionProgressChanged();
Expand All @@ -123,7 +125,7 @@ private slots:
void _updateTotals(quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize);

private:
void _updateDiskFreeSpace();
void _updateDiskFreeSpace();

QmlObjectListModel *_tileSets = nullptr;
QGCTileSet _imageSet;
Expand All @@ -142,4 +144,6 @@ private slots:
QString _errorMessage;
bool _fetchElevation = true;
bool _importReplace = false;

static constexpr const char *kQmlOfflineMapKeyName = "QGCOfflineMap";
};
6 changes: 6 additions & 0 deletions src/Settings/FlightMap.SettingsGroup.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"shortDesc": "Currently selected map type for flight maps",
"type": "string",
"default": "Hybrid"
},
{
"name": "elevationMapProvider",
"shortDesc": "Currently selected elevation map provider",
"type": "string",
"default": "Copernicus Elevation"
}
]
}
Loading

0 comments on commit 3f80685

Please sign in to comment.