TerrainQuery.h 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/****************************************************************************
 *
 *   (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

12 13
#include "TerrainTile.h"
#include "QGCMapEngineData.h"
14 15 16 17 18 19 20
#include "QGCLoggingCategory.h"

#include <QObject>
#include <QGeoCoordinate>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
21
#include <QtLocation/private/qgeotiledmapreply_p.h>
22 23

Q_DECLARE_LOGGING_CATEGORY(TerrainQueryLog)
DonLakeFlyer's avatar
DonLakeFlyer committed
24
Q_DECLARE_LOGGING_CATEGORY(TerrainQueryVerboseLog)
25 26 27

class TerrainAtCoordinateQuery;

28 29 30
/// Base class for offline/online terrain queries
class TerrainQueryInterface : public QObject
{
31 32 33
    Q_OBJECT

public:
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    TerrainQueryInterface(QObject* parent) : QObject(parent) { }

    /// Request terrain heights for specified coodinates.
    /// Signals: coordinateHeights when data is available
    virtual void requestCoordinateHeights(const QList<QGeoCoordinate>& coordinates) = 0;

    /// Requests terrain heights along the path specified by the two coordinates.
    /// Signals: pathHeights
    ///     @param coordinates to query
    virtual void requestPathHeights(const QGeoCoordinate& fromCoord, const QGeoCoordinate& toCoord) = 0;

    /// Request terrain heights for the rectangular area specified.
    /// Signals: carpetHeights when data is available
    ///     @param swCoord South-West bound of rectangular area to query
    ///     @param neCoord North-East bound of rectangular area to query
    ///     @param statsOnly true: Return only stats, no carpet data
    virtual void requestCarpetHeights(const QGeoCoordinate& swCoord, const QGeoCoordinate& neCoord, bool statsOnly) = 0;

signals:
DonLakeFlyer's avatar
DonLakeFlyer committed
53 54 55
    void coordinateHeightsReceived(bool success, QList<double> heights);
    void pathHeightsReceived(bool success, double latStep, double lonStep, const QList<double>& heights);
    void carpetHeightsReceived(bool success, double minHeight, double maxHeight, const QList<QList<double>>& carpet);
56
};
57

58 59 60 61 62
/// AirMap online implementation of terrain queries
class TerrainAirMapQuery : public TerrainQueryInterface {
    Q_OBJECT

public:
63
    TerrainAirMapQuery(QObject* parent = nullptr);
64

65
    // Overrides from TerrainQueryInterface
66 67 68
    void requestCoordinateHeights   (const QList<QGeoCoordinate>& coordinates) final;
    void requestPathHeights         (const QGeoCoordinate& fromCoord, const QGeoCoordinate& toCoord) final;
    void requestCarpetHeights       (const QGeoCoordinate& swCoord, const QGeoCoordinate& neCoord, bool statsOnly) final;
69 70

private slots:
71
    void _requestError              (QNetworkReply::NetworkError code);
72 73
    void _requestFinished           (void);
    void _sslErrors                 (const QList<QSslError> &errors);
74 75

private:
76 77 78 79 80
    void _sendQuery                 (const QString& path, const QUrlQuery& urlQuery);
    void _requestFailed             (void);
    void _parseCoordinateData       (const QJsonValue& coordinateJson);
    void _parsePathData             (const QJsonValue& pathJson);
    void _parseCarpetData           (const QJsonValue& carpetJson);
81 82 83 84 85 86 87 88 89 90

    enum QueryMode {
        QueryModeCoordinates,
        QueryModePath,
        QueryModeCarpet
    };

    QNetworkAccessManager   _networkManager;
    QueryMode               _queryMode;
    bool                    _carpetStatsOnly;
91 92
};

93
/// AirMap offline cachable implementation of terrain queries
94 95 96 97
class TerrainOfflineAirMapQuery : public TerrainQueryInterface {
    Q_OBJECT

public:
98
    TerrainOfflineAirMapQuery(QObject* parent = nullptr);
99 100 101 102 103 104

    // Overrides from TerrainQueryInterface
    void requestCoordinateHeights(const QList<QGeoCoordinate>& coordinates) final;
    void requestPathHeights(const QGeoCoordinate& fromCoord, const QGeoCoordinate& toCoord) final;
    void requestCarpetHeights(const QGeoCoordinate& swCoord, const QGeoCoordinate& neCoord, bool statsOnly) final;

105
    // Internal methods
106 107 108 109 110 111 112 113 114 115 116 117
    void _signalCoordinateHeights(bool success, QList<double> heights);
    void _signalPathHeights(bool success, double latStep, double lonStep, const QList<double>& heights);
    void _signalCarpetHeights(bool success, double minHeight, double maxHeight, const QList<QList<double>>& carpet);
};

/// Used internally by TerrainOfflineAirMapQuery to manage terrain tiles
class TerrainTileManager : public QObject {
    Q_OBJECT

public:
    TerrainTileManager(void);

118 119
    void addCoordinateQuery (TerrainOfflineAirMapQuery* terrainQueryInterface, const QList<QGeoCoordinate>& coordinates);
    void addPathQuery       (TerrainOfflineAirMapQuery* terrainQueryInterface, const QGeoCoordinate& startPoint, const QGeoCoordinate& endPoint);