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 += \ ...@@ -22,6 +22,8 @@ HEADERS += \
$$PWD/QGeoServiceProviderPluginQGC.h \ $$PWD/QGeoServiceProviderPluginQGC.h \
$$PWD/QGeoTileFetcherQGC.h \ $$PWD/QGeoTileFetcherQGC.h \
$$PWD/QGeoTiledMappingManagerEngineQGC.h \ $$PWD/QGeoTiledMappingManagerEngineQGC.h \
$$PWD/MapProvider.h \
$$PWD/GoogleMapProvider.h \
SOURCES += \ SOURCES += \
$$PWD/QGCMapEngine.cpp \ $$PWD/QGCMapEngine.cpp \
...@@ -34,6 +36,8 @@ SOURCES += \ ...@@ -34,6 +36,8 @@ SOURCES += \
$$PWD/QGeoServiceProviderPluginQGC.cpp \ $$PWD/QGeoServiceProviderPluginQGC.cpp \
$$PWD/QGeoTileFetcherQGC.cpp \ $$PWD/QGeoTileFetcherQGC.cpp \
$$PWD/QGeoTiledMappingManagerEngineQGC.cpp \ $$PWD/QGeoTiledMappingManagerEngineQGC.cpp \
$$PWD/MapProvider.cpp \
$$PWD/GoogleMapProvider.cpp \
OTHER_FILES += \ OTHER_FILES += \
$$PWD/qgc_maps_plugin.json $$PWD/qgc_maps_plugin.json
...@@ -28,47 +28,32 @@ ...@@ -28,47 +28,32 @@
#include <QString> #include <QString>
#include <QByteArray> #include <QByteArray>
#if defined(DEBUG_GOOGLE_MAPS)
#include <QFile>
#include <QStandardPaths>
#endif
static const unsigned char pngSignature[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00}; #define AVERAGE_GOOGLE_TERRAIN_MAP 19391
static const unsigned char jpegSignature[] = {0xFF, 0xD8, 0xFF, 0x00}; #define AVERAGE_BING_STREET_MAP 1297
static const unsigned char gifSignature[] = {0x47, 0x49, 0x46, 0x38, 0x00}; #define AVERAGE_BING_SAT_MAP 19597
#define AVERAGE_GOOGLE_SAT_MAP 56887
#define AVERAGE_MAPBOX_SAT_MAP 15739
#define AVERAGE_MAPBOX_STREET_MAP 5648
#define AVERAGE_TILE_SIZE 13652
#define AVERAGE_AIRMAP_ELEV_SIZE 2786
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
UrlFactory::UrlFactory() UrlFactory::UrlFactory()
: _timeout(5 * 1000) : _timeout(5 * 1000)
#ifndef QGC_NO_GOOGLE_MAPS
, _googleVersionRetrieved(false)
, _googleReply(nullptr)
#endif
{ {
QStringList langs = QLocale::system().uiLanguages();
if (langs.length() > 0) { // BingMaps
_language = langs[0]; //_versionBingMaps = "563";
}
#ifndef QGC_NO_GOOGLE_MAPS #ifndef QGC_NO_GOOGLE_MAPS
// Google version strings _googleMapProvider = new GoogleMapProvider(this);
_versionGoogleMap = "m@354000000";
_versionGoogleSatellite = "692";
_versionGoogleLabels = "h@336";
_versionGoogleTerrain = "t@354,r@354000000";
_secGoogleWord = "Galileo";
#endif #endif
// BingMaps
_versionBingMaps = "563";
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
UrlFactory::~UrlFactory() UrlFactory::~UrlFactory()
{ {
#ifndef QGC_NO_GOOGLE_MAPS
if(_googleReply)
_googleReply->deleteLater();
#endif
} }
...@@ -76,157 +61,143 @@ UrlFactory::~UrlFactory() ...@@ -76,157 +61,143 @@ UrlFactory::~UrlFactory()
QString QString
UrlFactory::getImageFormat(MapType type, const QByteArray& image) UrlFactory::getImageFormat(MapType type, const QByteArray& image)
{ {
QString format; Q_UNUSED(type);
if(image.size() > 2) return _googleMapProvider->getImageFormat(image);
{ //QString format;
if (image.startsWith(reinterpret_cast<const char*>(pngSignature))) //if(image.size() > 2)
format = "png"; //{
else if (image.startsWith(reinterpret_cast<const char*>(jpegSignature))) // if (image.startsWith(reinterpret_cast<const char*>(pngSignature)))
format = "jpg"; // format = "png";
else if (image.startsWith(reinterpret_cast<const char*>(gifSignature))) // else if (image.startsWith(reinterpret_cast<const char*>(jpegSignature)))
format = "gif"; // format = "jpg";
else { // else if (image.startsWith(reinterpret_cast<const char*>(gifSignature)))
switch (type) { // format = "gif";
case GoogleMap: // else {
case GoogleLabels: // switch (type) {
case GoogleTerrain: // case GoogleMap:
case GoogleHybrid: // case GoogleLabels:
case BingMap: // case GoogleTerrain:
case StatkartTopo: // case GoogleHybrid:
format = "png"; // case BingMap:
break; // case StatkartTopo:
case EniroTopo: // format = "png";
format = "png"; // break;
break; // case EniroTopo:
/* // format = "png";
case MapQuestMap: // break;
case MapQuestSat: // /*
case OpenStreetMap: // case MapQuestMap:
*/ // case MapQuestSat:
case MapboxStreets: // case OpenStreetMap:
case MapboxLight: // */
case MapboxDark: // case MapboxStreets:
case MapboxSatellite: // case MapboxLight:
case MapboxHybrid: // case MapboxDark:
case MapboxWheatPaste: // case MapboxSatellite:
case MapboxStreetsBasic: // case MapboxHybrid:
case MapboxComic: // case MapboxWheatPaste:
case MapboxOutdoors: // case MapboxStreetsBasic:
case MapboxRunBikeHike: // case MapboxComic:
case MapboxPencil: // case MapboxOutdoors:
case MapboxPirates: // case MapboxRunBikeHike:
case MapboxEmerald: // case MapboxPencil:
case MapboxHighContrast: // case MapboxPirates:
case GoogleSatellite: // case MapboxEmerald:
case BingSatellite: // case MapboxHighContrast:
case BingHybrid: // case GoogleSatellite:
format = "jpg"; // case BingSatellite:
break; // case BingHybrid:
case AirmapElevation: // format = "jpg";
format = "bin"; // break;
break; // case AirmapElevation:
case VWorldStreet : // format = "bin";
format = "png"; // break;
break; // case VWorldStreet :
case VWorldSatellite : // format = "png";
format = "jpg"; // break;
break; // case VWorldSatellite :
default: // format = "jpg";
qWarning("UrlFactory::getImageFormat() Unknown map id %d", type); // break;
break; // default:
} // qWarning("UrlFactory::getImageFormat() Unknown map id %d", type);
} // break;
} // }
return format; // }
//}
//return format;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QNetworkRequest QNetworkRequest
UrlFactory::getTileURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager) UrlFactory::getTileURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager)
{ {
//-- Build URL Q_UNUSED(type);
QNetworkRequest request; return _googleMapProvider->getTileURL(x,y,zoom,networkManager);
QString url = _getURL(type, x, y, zoom, networkManager); ////-- Build URL
if(url.isEmpty()) { //QNetworkRequest request;
return request; //QString url = _getURL(type, x, y, zoom, networkManager);
} //if(url.isEmpty()) {
request.setUrl(QUrl(url)); // return request;
request.setRawHeader("Accept", "*/*"); //}
switch (type) { //request.setUrl(QUrl(url));
#ifndef QGC_NO_GOOGLE_MAPS //request.setRawHeader("Accept", "*/*");
case GoogleMap: //switch (type) {
case GoogleSatellite: // // case GoogleMap:
case GoogleLabels: // // case GoogleSatellite:
case GoogleTerrain: // // case GoogleLabels:
case GoogleHybrid: // // case GoogleTerrain:
request.setRawHeader("Referrer", "https://www.google.com/maps/preview"); // // case GoogleHybrid:
break; // // request.setRawHeader("Referrer", "https://www.google.com/maps/preview");
#endif // // break;
case BingHybrid: // case BingHybrid:
case BingMap: // case BingMap:
case BingSatellite: // case BingSatellite:
request.setRawHeader("Referrer", "https://www.bing.com/maps/"); // request.setRawHeader("Referrer", "https://www.bing.com/maps/");
break; // break;
case StatkartTopo: // case StatkartTopo:
request.setRawHeader("Referrer", "https://www.norgeskart.no/"); // request.setRawHeader("Referrer", "https://www.norgeskart.no/");
break; // break;
case EniroTopo: // case EniroTopo:
request.setRawHeader("Referrer", "https://www.eniro.se/"); // request.setRawHeader("Referrer", "https://www.eniro.se/");
break; // break;
/* // /*
case OpenStreetMapSurfer: // case OpenStreetMapSurfer:
case OpenStreetMapSurferTerrain: // case OpenStreetMapSurferTerrain:
request.setRawHeader("Referrer", "http://www.mapsurfer.net/"); // request.setRawHeader("Referrer", "http://www.mapsurfer.net/");
break; // break;
case OpenStreetMap: // case OpenStreetMap:
case OpenStreetOsm: // case OpenStreetOsm:
request.setRawHeader("Referrer", "https://www.openstreetmap.org/"); // request.setRawHeader("Referrer", "https://www.openstreetmap.org/");
break; // break;
*/ // */
case EsriWorldStreet: // case EsriWorldStreet:
case EsriWorldSatellite: // case EsriWorldSatellite:
case EsriTerrain: { // case EsriTerrain: {
QByteArray token = qgcApp()->toolbox()->settingsManager()->appSettings()->esriToken()->rawValue().toString().toLatin1(); // QByteArray token = qgcApp()->toolbox()->settingsManager()->appSettings()->esriToken()->rawValue().toString().toLatin1();
request.setRawHeader("User-Agent", QByteArrayLiteral("Qt Location based application")); // request.setRawHeader("User-Agent", QByteArrayLiteral("Qt Location based application"));
request.setRawHeader("User-Token", token); // request.setRawHeader("User-Token", token);
} // }
return request; // return request;
case AirmapElevation: // case AirmapElevation:
request.setRawHeader("Referrer", "https://api.airmap.com/"); // request.setRawHeader("Referrer", "https://api.airmap.com/");
break; // break;
default: // default:
break; // break;
} //}
request.setRawHeader("User-Agent", _userAgent); //request.setRawHeader("User-Agent", _userAgent);
return request; //return request;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef QGC_NO_GOOGLE_MAPS #if 0
void
UrlFactory::_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=";
}
}
#endif
//-----------------------------------------------------------------------------
QString QString
UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager) UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager)
{ {
switch (type) { switch (type) {
#ifdef QGC_NO_GOOGLE_MAPS
Q_UNUSED(networkManager); Q_UNUSED(networkManager);
#else
case GoogleMap: case GoogleMap:
{ {
// http://mt1.google.com/vt/lyrs=m // http://mt1.google.com/vt/lyrs=m
...@@ -273,7 +244,6 @@ UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* ...@@ -273,7 +244,6 @@ UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager*
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); 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; break;
#endif
case StatkartTopo: case StatkartTopo:
{ {
return QString("http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom=%1&x=%2&y=%3").arg(zoom).arg(x).arg(y); return QString("http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom=%1&x=%2&y=%3").arg(zoom).arg(x).arg(y);
...@@ -476,181 +446,54 @@ UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager* ...@@ -476,181 +446,54 @@ UrlFactory::_getURL(MapType type, int x, int y, int zoom, QNetworkAccessManager*
return {}; return {};
} }
//-----------------------------------------------------------------------------
QString
UrlFactory::_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
UrlFactory::_getServerNum(int x, int y, int max)
{
return (x + 2 * y) % max;
}
//-----------------------------------------------------------------------------
#ifndef QGC_NO_GOOGLE_MAPS
void
UrlFactory::_networkReplyError(QNetworkReply::NetworkError error)
{
qWarning() << "Could not connect to google maps. Error:" << error;
if(_googleReply)
{
_googleReply->deleteLater();
_googleReply = nullptr;
}
}
#endif
//-----------------------------------------------------------------------------
#ifndef QGC_NO_GOOGLE_MAPS
void
UrlFactory::_replyDestroyed()
{
_googleReply = nullptr;
}
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef QGC_NO_GOOGLE_MAPS
void
UrlFactory::_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;
}
#endif
//-----------------------------------------------------------------------------
#ifndef QGC_NO_GOOGLE_MAPS
void
UrlFactory::_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, &UrlFactory::_googleVersionCompleted);
connect(_googleReply, &QNetworkReply::destroyed, this, &UrlFactory::_replyDestroyed);
connect(_googleReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
this, &UrlFactory::_networkReplyError);
networkManager->setProxy(proxy);
}
}
#endif #endif
#define AVERAGE_GOOGLE_STREET_MAP 4913
#define AVERAGE_GOOGLE_TERRAIN_MAP 19391
#define AVERAGE_BING_STREET_MAP 1297
#define AVERAGE_BING_SAT_MAP 19597
#define AVERAGE_GOOGLE_SAT_MAP 56887
#define AVERAGE_MAPBOX_SAT_MAP 15739
#define AVERAGE_MAPBOX_STREET_MAP 5648
#define AVERAGE_TILE_SIZE 13652
#define AVERAGE_AIRMAP_ELEV_SIZE 2786
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
quint32 quint32
UrlFactory::averageSizeForType(MapType type) UrlFactory::averageSizeForType(MapType type)
{ {
switch (type) { Q_UNUSED(type);
case GoogleMap: return GoogleMapProvider::getAverageSize();
return AVERAGE_GOOGLE_STREET_MAP;
case BingMap: // switch (type) {
return AVERAGE_BING_STREET_MAP; // case GoogleMap:
case GoogleSatellite: // return AVERAGE_GOOGLE_STREET_MAP;
return AVERAGE_GOOGLE_SAT_MAP; // case BingMap:
case MapboxSatellite: // return AVERAGE_BING_STREET_MAP;
return AVERAGE_MAPBOX_SAT_MAP; // case GoogleSatellite:
case BingHybrid: // return AVERAGE_GOOGLE_SAT_MAP;
case BingSatellite: // case MapboxSatellite:
return AVERAGE_BING_SAT_MAP; // return AVERAGE_MAPBOX_SAT_MAP;
case GoogleTerrain: // case BingHybrid:
return AVERAGE_GOOGLE_TERRAIN_MAP; // case BingSatellite:
case MapboxStreets: // return AVERAGE_BING_SAT_MAP;
case MapboxStreetsBasic: // case GoogleTerrain:
case MapboxRunBikeHike: // return AVERAGE_GOOGLE_TERRAIN_MAP;
return AVERAGE_MAPBOX_STREET_MAP; // case MapboxStreets:
case AirmapElevation: // case MapboxStreetsBasic:
return AVERAGE_AIRMAP_ELEV_SIZE; // case MapboxRunBikeHike:
case GoogleLabels: // return AVERAGE_MAPBOX_STREET_MAP;
case MapboxDark: // case AirmapElevation:
case MapboxLight: // return AVERAGE_AIRMAP_ELEV_SIZE;
case MapboxOutdoors: // case GoogleLabels:
case MapboxPencil: // case MapboxDark:
case OpenStreetMap: // case MapboxLight:
case GoogleHybrid: // case MapboxOutdoors:
case MapboxComic: // case MapboxPencil:
case MapboxEmerald: // case OpenStreetMap:
case MapboxHighContrast: // case GoogleHybrid:
case MapboxHybrid: // case MapboxComic:
case MapboxPirates: // case MapboxEmerald:
case MapboxWheatPaste: // case MapboxHighContrast:
default: // case MapboxHybrid:
break; // case MapboxPirates:
} // case MapboxWheatPaste:
return AVERAGE_TILE_SIZE; // default:
// break;
// }
// return AVERAGE_TILE_SIZE;
} }
...@@ -16,12 +16,7 @@ ...@@ -16,12 +16,7 @@
#ifndef QGC_MAP_URL_ENGINE_H #ifndef QGC_MAP_URL_ENGINE_H
#define QGC_MAP_URL_ENGINE_H #define QGC_MAP_URL_ENGINE_H
#include <QString> #include "GoogleMapProvider.h"
#include <QPoint>
#include <QByteArray>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QMutex>
#define MAX_MAP_ZOOM (20.0) #define MAX_MAP_ZOOM (20.0)
...@@ -90,41 +85,16 @@ public: ...@@ -90,41 +85,16 @@ public:
static quint32 averageSizeForType (MapType type); static quint32 averageSizeForType (MapType type);
private slots:
#ifndef QGC_NO_GOOGLE_MAPS
void _networkReplyError (QNetworkReply::NetworkError error);
void _googleVersionCompleted ();
void _replyDestroyed ();
#endif
private: //private:
QString _getURL (MapType type, int x, int y, int zoom, QNetworkAccessManager* networkManager); // 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: private:
int _timeout; 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 // 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