Commit f538e059 authored by Pierre TILAK's avatar Pierre TILAK

Start reorganize QGCMapUrlEngine

parent 425263e7
#include "GoogleMapProvider.h"
#if defined(DEBUG_GOOGLE_MAPS)
#include <QFile>
#include <QStandardPaths>
#endif
#include "QGCMapEngine.h"
#define AVERAGE_GOOGLE_STREET_MAP 4913
GoogleMapProvider::GoogleMapProvider(QObject* parent)
: MapProvider(QString("https://www.google.com/maps/preview"),
QString("png"), quint32(AVERAGE_GOOGLE_STREET_MAP), parent),
_googleVersionRetrieved(false), _googleReply(nullptr) {
// Google version strings
_versionGoogleMap = "m@354000000";
_versionGoogleSatellite = "692";
_versionGoogleLabels = "h@336";
_versionGoogleTerrain = "t@354,r@354000000";
_secGoogleWord = "Galileo";
}
quint32 GoogleMapProvider::getAverageSize(){
return quint32(AVERAGE_GOOGLE_STREET_MAP);
}
GoogleMapProvider::~GoogleMapProvider() {
if (_googleReply)
_googleReply->deleteLater();
}
//-----------------------------------------------------------------------------
void GoogleMapProvider::_getSecGoogleWords(int x, int y, QString& sec1,
QString& sec2) {
sec1 = ""; // after &x=...
sec2 = ""; // after &zoom=...
int seclen = ((x * 3) + y) % 8;
sec2 = _secGoogleWord.left(seclen);
if (y >= 10000 && y < 100000) {
sec1 = "&s=";
}
}
//-----------------------------------------------------------------------------
void GoogleMapProvider::_networkReplyError(QNetworkReply::NetworkError error) {
qWarning() << "Could not connect to google maps. Error:" << error;
if (_googleReply) {
_googleReply->deleteLater();
_googleReply = nullptr;
}
}
//-----------------------------------------------------------------------------
void GoogleMapProvider::_replyDestroyed() { _googleReply = nullptr; }
void GoogleMapProvider::_googleVersionCompleted() {
if (!_googleReply || (_googleReply->error() != QNetworkReply::NoError)) {
qDebug() << "Error collecting Google maps version info";
return;
}
QString html = QString(_googleReply->readAll());
#if defined(DEBUG_GOOGLE_MAPS)
QString filename =
QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
filename += "/google.output";
QFile file(filename);
if (file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
stream << html << endl;
}
#endif
QRegExp reg("\"*https?://mt\\D?\\d..*/vt\\?lyrs=m@(\\d*)",
Qt::CaseInsensitive);
if (reg.indexIn(html) != -1) {
QStringList gc = reg.capturedTexts();
_versionGoogleMap = QString("m@%1").arg(gc[1]);
}
reg = QRegExp("\"*https?://khm\\D?\\d.googleapis.com/kh\\?v=(\\d*)",
Qt::CaseInsensitive);
if (reg.indexIn(html) != -1) {
QStringList gc = reg.capturedTexts();
_versionGoogleSatellite = gc[1];
}
reg = QRegExp("\"*https?://mt\\D?\\d..*/vt\\?lyrs=t@(\\d*),r@(\\d*)",
Qt::CaseInsensitive);
if (reg.indexIn(html) != -1) {
QStringList gc = reg.capturedTexts();
_versionGoogleTerrain = QString("t@%1,r@%2").arg(gc[1]).arg(gc[2]);
}
_googleReply->deleteLater();
_googleReply = nullptr;
}
//-----------------------------------------------------------------------------
void GoogleMapProvider::_tryCorrectGoogleVersions(
QNetworkAccessManager* networkManager) {
QMutexLocker locker(&_googleVersionMutex);
if (_googleVersionRetrieved) {
return;
}
_googleVersionRetrieved = true;
if (networkManager) {
QNetworkRequest qheader;
QNetworkProxy proxy = networkManager->proxy();
QNetworkProxy tProxy;
tProxy.setType(QNetworkProxy::DefaultProxy);
networkManager->setProxy(tProxy);
QSslConfiguration conf = qheader.sslConfiguration();
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
qheader.setSslConfiguration(conf);
QString url = "http://maps.google.com/maps/api/js?v=3.2&sensor=false";
qheader.setUrl(QUrl(url));
QByteArray ua;
ua.append(getQGCMapEngine()->userAgent());
qheader.setRawHeader("User-Agent", ua);
_googleReply = networkManager->get(qheader);
connect(_googleReply, &QNetworkReply::finished, this,
&GoogleMapProvider::_googleVersionCompleted);
connect(_googleReply, &QNetworkReply::destroyed, this,
&GoogleMapProvider::_replyDestroyed);
connect(
_googleReply,
static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(
&QNetworkReply::error),
this, &GoogleMapProvider::_networkReplyError);
networkManager->setProxy(proxy);
}
}
//
//-----------------------------------------------------------------------------
QString GoogleMapProvider::_getURL(int x, int y, int zoom,
QNetworkAccessManager* networkManager) {
// http://mt1.google.com/vt/lyrs=m
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
_getSecGoogleWords(x, y, sec1, sec2);
_tryCorrectGoogleVersions(networkManager);
return QString(
"http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")
.arg(server)
.arg(_getServerNum(x, y, 4))
.arg(request)
.arg(_versionGoogleMap)
.arg(_language)
.arg(x)
.arg(sec1)
.arg(y)
.arg(zoom)
.arg(sec2);
//} break;
//case GoogleSatellite: {
// // http://mt1.google.com/vt/lyrs=s
// QString server = "khm";
// QString request = "kh";
// QString sec1 = ""; // after &x=...
// QString sec2 = ""; // after &zoom=...
// _getSecGoogleWords(x, y, sec1, sec2);
// _tryCorrectGoogleVersions(networkManager);
// return QString(
// "http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")
// .arg(server)
// .arg(_getServerNum(x, y, 4))
// .arg(request)
// .arg(_versionGoogleSatellite)
// .arg(_language)
// .arg(x)
// .arg(sec1)
// .arg(y)
// .arg(zoom)
// .arg(sec2);
//} break;
//case GoogleLabels: {
// QString server = "mts";
// QString request = "vt";
// QString sec1 = ""; // after &x=...
// QString sec2 = ""; // after &zoom=...
// _getSecGoogleWords(x, y, sec1, sec2);
// _tryCorrectGoogleVersions(networkManager);
// return QString(
// "http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")
// .arg(server)
// .arg(_getServerNum(x, y, 4))
// .arg(request)
// .arg(_versionGoogleLabels)
// .arg(_language)
// .arg(x)
// .arg(sec1)
// .arg(y)
// .arg(zoom)
// .arg(sec2);
//} break;
//case GoogleTerrain: {
// QString server = "mt";
// QString request = "vt";
// QString sec1 = ""; // after &x=...
// QString sec2 = ""; // after &zoom=...
// _getSecGoogleWords(x, y, sec1, sec2);
// _tryCorrectGoogleVersions(networkManager);
// return QString(
// "http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")
// .arg(server)
// .arg(_getServerNum(x, y, 4))
// .arg(request)
// .arg(_versionGoogleTerrain)
// .arg(_language)
// .arg(x)
// .arg(sec1)
// .arg(y)
// .arg(zoom)
// .arg(sec2);
//} break;
//default:
// qWarning("Unknown map id %d\n", type);
// break;
//}
//return {};
}
#pragma once
#include "MapProvider.h"
#include <QByteArray>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QString>
#include <QPoint>
#include <QMutex>
class GoogleMapProvider : public MapProvider {
Q_OBJECT
public:
GoogleMapProvider(QObject* parent);
~GoogleMapProvider();
static quint32 getAverageSize();
// Google Specific private slots
private slots:
void _networkReplyError(QNetworkReply::NetworkError error);
void _googleVersionCompleted();
void _replyDestroyed();
private:
// Define the url to Request
QString _getURL(int x, int y, int zoom,
QNetworkAccessManager* networkManager) ;
// Google Specific private methods
void _getSecGoogleWords(int x, int y, QString& sec1, QString& sec2);
void _tryCorrectGoogleVersions(QNetworkAccessManager* networkManager);
// Google Specific attributes
bool _googleVersionRetrieved;
QNetworkReply* _googleReply;
QMutex _googleVersionMutex;
QString _versionGoogleMap;
QString _versionGoogleSatellite;
QString _versionGoogleLabels;
QString _versionGoogleTerrain;
QString _secGoogleWord;
};
#include "MapProvider.h"
MapProvider::MapProvider(QString referrer, QString imageFormat,
quint32 averageSize, QObject* parent)
: QObject(parent), _referrer(referrer), _imageFormat(imageFormat),
_averageSize(averageSize) {
QStringList langs = QLocale::system().uiLanguages();
if (langs.length() > 0) {
_language = langs[0];
}
}
QNetworkRequest MapProvider::getTileURL(int x, int y, int zoom,
QNetworkAccessManager* networkManager) {
//-- Build URL
QNetworkRequest request;
QString url = _getURL(x, y, zoom, networkManager);
if (url.isEmpty()) {
return request;
}
request.setUrl(QUrl(url));
request.setRawHeader("Accept", "*/*");
request.setRawHeader("Referrer", _referrer.toUtf8());
request.setRawHeader("User-Agent", _userAgent);
return request;
}
QString MapProvider::getImageFormat(const QByteArray& image) {
QString format;
if (image.size() > 2) {
if (image.startsWith(reinterpret_cast<const char*>(pngSignature)))
format = "png";
else if (image.startsWith(reinterpret_cast<const char*>(jpegSignature)))
format = "jpg";
else if (image.startsWith(reinterpret_cast<const char*>(gifSignature)))
format = "gif";
else {
return _imageFormat;
}
}
return format;
}
QString MapProvider::_tileXYToQuadKey(int tileX, int tileY, int levelOfDetail) {
QString quadKey;
for (int i = levelOfDetail; i > 0; i--) {
char digit = '0';
int mask = 1 << (i - 1);
if ((tileX & mask) != 0) {
digit++;
}
if ((tileY & mask) != 0) {
digit++;
digit++;
}
quadKey.append(digit);
}
return quadKey;
}
int MapProvider::_getServerNum(int x, int y, int max) {
return (x + 2 * y) % max;
}
#pragma once
#include <QByteArray>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QString>
static const unsigned char pngSignature[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00};
static const unsigned char jpegSignature[] = {0xFF, 0xD8, 0xFF, 0x00};
static const unsigned char gifSignature[] = {0x47, 0x49, 0x46, 0x38, 0x00};
class MapProvider : public QObject {
Q_OBJECT
public:
MapProvider(QString referrer, QString imageFormat, quint32 averageSize,
QObject* parent = nullptr);
QNetworkRequest getTileURL(int x, int y, int zoom,
QNetworkAccessManager* networkManager);
QString getImageFormat(const QByteArray& image);
protected:
QString _tileXYToQuadKey (int tileX, int tileY, int levelOfDetail);
int _getServerNum (int x, int y, int max);
// Define Referrer for Request RawHeader
QString _referrer;
QString _imageFormat;
quint32 _averageSize;
QByteArray _userAgent;
QString _language;
// Define the url to Request
virtual QString _getURL(int x, int y, int zoom,
QNetworkAccessManager* networkManager) = 0;
};
......@@ -22,6 +22,8 @@ HEADERS += \
$$PWD/QGeoServiceProviderPluginQGC.h \
$$PWD/QGeoTileFetcherQGC.h \
$$PWD/QGeoTiledMappingManagerEngineQGC.h \
$$PWD/MapProvider.h \
$$PWD/GoogleMapProvider.h \
SOURCES += \
$$PWD/QGCMapEngine.cpp \
......@@ -34,6 +36,8 @@ SOURCES += \
$$PWD/QGeoServiceProviderPluginQGC.cpp \
$$PWD/QGeoTileFetcherQGC.cpp \
$$PWD/QGeoTiledMappingManagerEngineQGC.cpp \
$$PWD/MapProvider.cpp \
$$PWD/GoogleMapProvider.cpp \
OTHER_FILES += \
$$PWD/qgc_maps_plugin.json
This diff is collapsed.
......@@ -16,12 +16,7 @@
#ifndef QGC_MAP_URL_ENGINE_H
#define QGC_MAP_URL_ENGINE_H
#include <QString>
#include <QPoint>
#include <QByteArray>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QMutex>
#include "GoogleMapProvider.h"
#define MAX_MAP_ZOOM (20.0)
......@@ -90,41 +85,16 @@ public:
static quint32 averageSizeForType (MapType type);
private slots:
#ifndef QGC_NO_GOOGLE_MAPS
void _networkReplyError (QNetworkReply::NetworkError error);
void _googleVersionCompleted ();
void _replyDestroyed ();
#endif
private:
QString _getURL (MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager);
QString _tileXYToQuadKey (int tileX, int tileY, int levelOfDetail);
int _getServerNum (int x, int y, int max);
#ifndef QGC_NO_GOOGLE_MAPS
void _getSecGoogleWords (int x, int y, QString& sec1, QString& sec2);
void _tryCorrectGoogleVersions (QNetworkAccessManager* networkManager);
#endif
//private:
// QString _getURL (MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager);
private:
int _timeout;
QByteArray _userAgent;
QString _language;
// Google version strings
#ifndef QGC_NO_GOOGLE_MAPS
bool _googleVersionRetrieved;
QNetworkReply* _googleReply;
QMutex _googleVersionMutex;
QString _versionGoogleMap;
QString _versionGoogleSatellite;
QString _versionGoogleLabels;
QString _versionGoogleTerrain;
QString _secGoogleWord;
#endif
// BingMaps
QString _versionBingMaps;
//QString _versionBingMaps;
GoogleMapProvider* _googleMapProvider;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment