MapProvider.cpp 3.8 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9 10 11 12
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include <QNetworkAccessManager>
#include <QNetworkRequest>

13 14
#include "MapProvider.h"

15 16 17 18 19 20 21 22 23
MapProvider::MapProvider(const QString &referrer, const QString &imageFormat,
                         const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject* parent)
    : QObject(parent)
    , _referrer(referrer)
    , _imageFormat(imageFormat)
    , _averageSize(averageSize)
    , _mapType(mapType)
{
    const QStringList langs = QLocale::system().uiLanguages();
24 25 26 27 28
    if (langs.length() > 0) {
        _language = langs[0];
    }
}

29
QNetworkRequest MapProvider::getTileURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) {
30 31
    //-- Build URL
    QNetworkRequest request;
32
    const QString url = _getURL(x, y, zoom, networkManager);
33 34 35 36
    if (url.isEmpty()) {
        return request;
    }
    request.setUrl(QUrl(url));
Cosmin Marc's avatar
Cosmin Marc committed
37 38 39
    request.setRawHeader(QByteArrayLiteral("Accept"), QByteArrayLiteral("*/*"));
    request.setRawHeader(QByteArrayLiteral("Referrer"), _referrer.toUtf8());
    request.setRawHeader(QByteArrayLiteral("User-Agent"), _userAgent);
40 41 42
    return request;
}

43
QString MapProvider::getImageFormat(const QByteArray& image) const {
44 45 46
    QString format;
    if (image.size() > 2) {
        if (image.startsWith(reinterpret_cast<const char*>(pngSignature)))
47
            format = QStringLiteral("png");
48
        else if (image.startsWith(reinterpret_cast<const char*>(jpegSignature)))
49
            format = QStringLiteral("jpg");
50
        else if (image.startsWith(reinterpret_cast<const char*>(gifSignature)))
51
            format = QStringLiteral("gif");
52 53 54 55 56 57 58
        else {
            return _imageFormat;
        }
    }
    return format;
}

Cosmin Marc's avatar
Cosmin Marc committed
59
QString MapProvider::_tileXYToQuadKey(const int tileX, const int tileY, const int levelOfDetail) const {
60 61 62
    QString quadKey;
    for (int i = levelOfDetail; i > 0; i--) {
        char digit = '0';
63
        const int  mask  = 1 << (i - 1);
64 65 66 67 68 69 70 71 72 73 74 75
        if ((tileX & mask) != 0) {
            digit++;
        }
        if ((tileY & mask) != 0) {
            digit++;
            digit++;
        }
        quadKey.append(digit);
    }
    return quadKey;
}

Cosmin Marc's avatar
Cosmin Marc committed
76
int MapProvider::_getServerNum(const int x, const int y, const int max) const {
77 78
    return (x + 2 * y) % max;
}
79

80
int MapProvider::long2tileX(const double lon, const int z) const {
81 82 83 84
    return static_cast<int>(floor((lon + 180.0) / 360.0 * pow(2.0, z)));
}

//-----------------------------------------------------------------------------
85
int MapProvider::lat2tileY(const double lat, const int z) const {
86 87 88 89 90
    return static_cast<int>(floor(
        (1.0 -
         log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) /
        2.0 * pow(2.0, z)));
}
91

Cosmin Marc's avatar
Cosmin Marc committed
92 93 94
bool MapProvider::_isElevationProvider() const {
    return false;
}
95

96 97 98
QGCTileSet MapProvider::getTileCount(const int zoom, const double topleftLon,
                                     const double topleftLat, const double bottomRightLon,
                                     const double bottomRightLat) const {
99 100 101 102 103 104 105 106 107 108 109 110 111 112
    QGCTileSet set;
    set.tileX0 = long2tileX(topleftLon, zoom);
    set.tileY0 = lat2tileY(topleftLat, zoom);
    set.tileX1 = long2tileX(bottomRightLon, zoom);
    set.tileY1 = lat2tileY(bottomRightLat, 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;
}