10 changed files with 293 additions and 34 deletions
@ -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 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* |
||||||
|
* (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