10 changed files with 293 additions and 34 deletions
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#include "Terrain.h" |
||||
|
||||
#include <QUrl> |
||||
#include <QUrlQuery> |
||||
#include <QNetworkRequest> |
||||
#include <QNetworkProxy> |
||||
#include <QNetworkReply> |
||||
#include <QJsonDocument> |
||||
#include <QJsonObject> |
||||
#include <QJsonArray> |
||||
|
||||
ElevationProvider::ElevationProvider(QObject* parent) |
||||
: QObject(parent) |
||||
{ |
||||
|
||||
} |
||||
|
||||
bool ElevationProvider::queryTerrainData(const QList<QGeoCoordinate>& coordinates) |
||||
{ |
||||
if (_state != State::Idle || coordinates.length() == 0) { |
||||
return false; |
||||
} |
||||
|
||||
QUrlQuery query; |
||||
QString points = ""; |
||||
for (const auto& coordinate : coordinates) { |
||||
points += QString::number(coordinate.latitude(), 'f', 10) + "," |
||||
+ QString::number(coordinate.longitude(), 'f', 10) + ","; |
||||
} |
||||
points = points.mid(0, points.length() - 1); // remove the last ','
|
||||
|
||||
query.addQueryItem(QStringLiteral("points"), points); |
||||
QUrl url(QStringLiteral("https://api.airmap.com/elevation/stage/srtm1/ele")); |
||||
url.setQuery(query); |
||||
|
||||
QNetworkRequest request(url); |
||||
|
||||
QNetworkProxy tProxy; |
||||
tProxy.setType(QNetworkProxy::DefaultProxy); |
||||
_networkManager.setProxy(tProxy); |
||||
|
||||
QNetworkReply* networkReply = _networkManager.get(request); |
||||
if (!networkReply) { |
||||
return false; |
||||
} |
||||
|
||||
connect(networkReply, &QNetworkReply::finished, this, &ElevationProvider::_requestFinished); |
||||
|
||||
_state = State::Downloading; |
||||
return true; |
||||
} |
||||
|
||||
void ElevationProvider::_requestFinished() |
||||
{ |
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender()); |
||||
QList<float> altitudes; |
||||
_state = State::Idle; |
||||
|
||||
// When an error occurs we still end up here
|
||||
if (reply->error() != QNetworkReply::NoError) { |
||||
QByteArray responseBytes = reply->readAll(); |
||||
|
||||
QJsonParseError parseError; |
||||
QJsonDocument responseJson = QJsonDocument::fromJson(responseBytes, &parseError); |
||||
qDebug() << responseJson; |
||||
emit terrainData(false, altitudes); |
||||
return; |
||||
} |
||||
|
||||
QByteArray responseBytes = reply->readAll(); |
||||
|
||||
QJsonParseError parseError; |
||||
QJsonDocument responseJson = QJsonDocument::fromJson(responseBytes, &parseError); |
||||
if (parseError.error != QJsonParseError::NoError) { |
||||
emit terrainData(false, altitudes); |
||||
return; |
||||
} |
||||
QJsonObject rootObject = responseJson.object(); |
||||
QString status = rootObject["status"].toString(); |
||||
if (status == "success") { |
||||
const QJsonArray& dataArray = rootObject["data"].toArray(); |
||||
for (int i = 0; i < dataArray.count(); i++) { |
||||
altitudes.push_back(dataArray[i].toDouble()); |
||||
} |
||||
|
||||
emit terrainData(true, altitudes); |
||||
} |
||||
emit terrainData(false, altitudes); |
||||
} |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2017 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <QObject> |
||||
#include <QGeoCoordinate> |
||||
#include <QNetworkAccessManager> |
||||
|
||||
/* usage example:
|
||||
ElevationProvider *p = new ElevationProvider(); |
||||
QList<QGeoCoordinate> coordinates; |
||||
QGeoCoordinate c(47.379243, 8.548265); |
||||
coordinates.push_back(c); |
||||
c.setLatitude(c.latitude()+0.01); |
||||
coordinates.push_back(c); |
||||
p->queryTerrainData(coordinates); |
||||
*/ |
||||
|
||||
|
||||
class ElevationProvider : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
ElevationProvider(QObject* parent = NULL); |
||||
|
||||
/**
|
||||
* Async elevation query for a list of lon,lat coordinates. When the query is done, the terrainData() signal |
||||
* is emitted. |
||||
* @param coordinates |
||||
* @return true on success |
||||
*/ |
||||
bool queryTerrainData(const QList<QGeoCoordinate>& coordinates); |
||||
|
||||
signals: |
||||
void terrainData(bool success, QList<float> altitudes); |
||||
|
||||
private slots: |
||||
void _requestFinished(); |
||||
private: |
||||
|
||||
enum class State { |
||||
Idle, |
||||
Downloading, |
||||
}; |
||||
|
||||
State _state = State::Idle; |
||||
QNetworkAccessManager _networkManager; |
||||
}; |
Loading…
Reference in new issue