diff --git a/src/QtLocationPlugin/OpenPilotMaps.cc b/src/QtLocationPlugin/OpenPilotMaps.cc index e38d56414c579696149cc4b197b9adf7ecf9f90e..79ba92b603a3e978a833559c8f991f7f5373853e 100644 --- a/src/QtLocationPlugin/OpenPilotMaps.cc +++ b/src/QtLocationPlugin/OpenPilotMaps.cc @@ -37,7 +37,7 @@ This file is part of the QGROUNDCONTROL project namespace OpenPilot { -const QString ProviderStrings::levelsForSigPacSpainMap[] = +const QString ProviderStrings::kLevelsForSigPacSpainMap[] = { "0", "1", "2", "3", "4", "MTNSIGPAC", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", @@ -45,15 +45,13 @@ const QString ProviderStrings::levelsForSigPacSpainMap[] = "MTN25", "MTN25", "ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS" }; -const double UrlFactory::EarthRadiusKm = 6378.137; // WGS-84 - ProviderStrings::ProviderStrings() { // Google version strings - VersionGoogleMap = "m@113"; - VersionGoogleSatellite = "s"; - VersionGoogleLabels = "h@221000000"; - VersionGoogleTerrain = "t@132,r@249000000"; + VersionGoogleMap = "m@296306248"; + VersionGoogleSatellite = "s@168"; + VersionGoogleLabels = "h@296000000"; + VersionGoogleTerrain = "t@132,r@296000000"; SecGoogleWord = "Galileo"; // Google (China) version strings @@ -91,18 +89,18 @@ ProviderStrings::ProviderStrings() BingMapsClientToken = ""; } -UrlFactory::UrlFactory() - : _isCorrectedGoogleVersions(false) - , _correctGoogleVersions(true) - , _timeout(5 * 1000) +UrlFactory::UrlFactory(QNetworkAccessManager *network) + : _timeout(5 * 1000) + , _googleVersionRetrieved(false) + , _network(network) + , _googleReply(NULL) { - Proxy.setType(QNetworkProxy::NoProxy); - UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7"; } UrlFactory::~UrlFactory() { - + if(_googleReply) + _googleReply->deleteLater(); } QString UrlFactory::_tileXYToQuadKey(const int& tileX, const int& tileY, const int& levelOfDetail) const @@ -128,68 +126,83 @@ int UrlFactory::_getServerNum(const QPoint &pos, const int &max) const return (pos.x() + 2 * pos.y()) % max; } +void UrlFactory::_networkReplyError(QNetworkReply::NetworkError error) +{ + qWarning() << "Could not connect to google maps. Error:" << error; + if(_googleReply) + { + _googleReply->deleteLater(); + _googleReply = NULL; + } +} + +void UrlFactory::_replyDestroyed() +{ + _googleReply = NULL; +} + +void UrlFactory::_googleVersionCompleted() +{ + if (!_googleReply || (_googleReply->error() != QNetworkReply::NoError)) { + qDebug() << "Error collecting Google maps version info"; + return; + } + QString html = QString(_googleReply->readAll()); + QRegExp reg("\"*https://mts0.google.com/vt/lyrs=m@(\\d*)", Qt::CaseInsensitive); + if (reg.indexIn(html) != -1) { + QStringList gc = reg.capturedTexts(); + VersionGoogleMap = QString("m@%1").arg(gc[1]); + VersionGoogleMapChina = VersionGoogleMap; + VersionGoogleMapKorea = VersionGoogleMap; + } + reg = QRegExp("\"*https://mts0.google.com/vt/lyrs=h@(\\d*)", Qt::CaseInsensitive); + if (reg.indexIn(html) != -1) { + QStringList gc = reg.capturedTexts(); + VersionGoogleLabels = QString("h@%1").arg(gc[1]); + VersionGoogleLabelsChina = VersionGoogleLabels; + VersionGoogleLabelsKorea = VersionGoogleLabels; + } + reg = QRegExp("\"*https://khms0.google.com/kh/v=(\\d*)", Qt::CaseInsensitive); + if (reg.indexIn(html) != -1) { + QStringList gc = reg.capturedTexts(); + VersionGoogleSatellite = "s@" + gc[1]; + VersionGoogleSatelliteKorea = VersionGoogleSatellite; + VersionGoogleSatelliteChina = VersionGoogleSatellite; + } + reg = QRegExp("\"*https://mts0.google.com/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]); + VersionGoogleTerrainChina = VersionGoogleTerrain; + VersionGoogleTerrainChina = VersionGoogleTerrain; + } + _googleReply->deleteLater(); + _googleReply = NULL; +} + void UrlFactory::_tryCorrectGoogleVersions() { - static bool _kVersionRetrieved = false; - if (_kVersionRetrieved) { + QMutexLocker locker(&_googleVersionMutex); + if (_googleVersionRetrieved) { return; } - QMutexLocker locker(&mutex); - if (_correctGoogleVersions && !_isCorrectedGoogleVersions) { - QNetworkReply* reply; + _googleVersionRetrieved = true; + if(_network) + { QNetworkRequest qheader; - QNetworkAccessManager network; - QEventLoop q; - QTimer tT; - tT.setSingleShot(true); - connect(&network, SIGNAL(finished(QNetworkReply *)), &q, SLOT(quit())); - connect(&tT, SIGNAL(timeout()), &q, SLOT(quit())); - network.setProxy(Proxy); - _isCorrectedGoogleVersions = true; + QNetworkProxy proxy = _network->proxy(); + QNetworkProxy tProxy; + tProxy.setType(QNetworkProxy::NoProxy); + _network->setProxy(tProxy); QString url = "https://maps.google.com/maps?output=classic"; qheader.setUrl(QUrl(url)); - qheader.setRawHeader("User-Agent", UserAgent); - reply = network.get(qheader); - tT.start(_timeout); - q.exec(); - if (!tT.isActive()) { - return; - } - tT.stop(); - if ((reply->error() != QNetworkReply::NoError)) { - return; - } - QString html = QString(reply->readAll()); - QRegExp reg("\"*https://mts0.google.com/vt/lyrs=m@(\\d*)", Qt::CaseInsensitive); - if (reg.indexIn(html) != -1) { - QStringList gc = reg.capturedTexts(); - VersionGoogleMap = QString("m@%1").arg(gc[1]); - VersionGoogleMapChina = VersionGoogleMap; - VersionGoogleMapKorea = VersionGoogleMap; - } - reg = QRegExp("\"*https://mts0.google.com/vt/lyrs=h@(\\d*)", Qt::CaseInsensitive); - if (reg.indexIn(html) != -1) { - QStringList gc = reg.capturedTexts(); - VersionGoogleLabels = QString("h@%1").arg(gc[1]); - VersionGoogleLabelsChina = VersionGoogleLabels; - VersionGoogleLabelsKorea = VersionGoogleLabels; - } - reg = QRegExp("\"*https://khms0.google.com/kh/v=(\\d*)", Qt::CaseInsensitive); - if (reg.indexIn(html) != -1) { - QStringList gc = reg.capturedTexts(); - VersionGoogleSatellite = "s@" + gc[1]; - VersionGoogleSatelliteKorea = VersionGoogleSatellite; - VersionGoogleSatelliteChina = VersionGoogleSatellite; - } - reg = QRegExp("\"*https://mts0.google.com/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]); - VersionGoogleTerrainChina = VersionGoogleTerrain; - VersionGoogleTerrainChina = VersionGoogleTerrain; - } - reply->deleteLater(); - _kVersionRetrieved = true; + QByteArray userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7"; + qheader.setRawHeader("User-Agent", userAgent); + _googleReply = _network->get(qheader); + connect(_googleReply, SIGNAL(finished()), this, SLOT(_googleVersionCompleted())); + connect(_googleReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(_networkReplyError(QNetworkReply::NetworkError))); + connect(_googleReply, SIGNAL(destroyed()), this, SLOT(_replyDestroyed())); + _network->setProxy(proxy); } } @@ -459,7 +472,7 @@ QString UrlFactory::makeImageUrl(const MapType &type, const QPoint& pos, const i break; case SigPacSpainMap: { - return QString("http://sigpac.mapa.es/kmlserver/raster/%1@3785/%2.%3.%4.img").arg(levelsForSigPacSpainMap[zoom]).arg(zoom).arg(pos.x()).arg((2 << (zoom - 1)) - pos.y() - 1); + return QString("http://sigpac.mapa.es/kmlserver/raster/%1@3785/%2.%3.%4.img").arg(kLevelsForSigPacSpainMap[zoom]).arg(zoom).arg(pos.x()).arg((2 << (zoom - 1)) - pos.y() - 1); } break; case YandexMapRu: diff --git a/src/QtLocationPlugin/OpenPilotMaps.h b/src/QtLocationPlugin/OpenPilotMaps.h index 5d88d6ad0cb7ba3098ab3a04e81bbe69d8e811f4..ba8e8d4ae12176e254bb892593d80351c9873f94 100644 --- a/src/QtLocationPlugin/OpenPilotMaps.h +++ b/src/QtLocationPlugin/OpenPilotMaps.h @@ -35,6 +35,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #include namespace OpenPilot { @@ -88,10 +89,11 @@ enum MapType YandexMapRu = 5000 }; -class ProviderStrings { +class ProviderStrings : public QObject { + Q_OBJECT public: ProviderStrings(); - static const QString levelsForSigPacSpainMap[]; + static const QString kLevelsForSigPacSpainMap[]; QString GoogleMapsAPIKey; // Google version strings QString VersionGoogleMap; @@ -127,29 +129,32 @@ public: QString BingMapsClientToken; }; -class UrlFactory : public QObject, public ProviderStrings { +class UrlFactory : public ProviderStrings { Q_OBJECT public: - QByteArray UserAgent; - QNetworkProxy Proxy; - UrlFactory(); + UrlFactory(QNetworkAccessManager* network); ~UrlFactory(); QString makeImageUrl (const MapType &type, const QPoint &pos, const int &zoom, const QString &language); +private slots: + void _networkReplyError (QNetworkReply::NetworkError error); + void _googleVersionCompleted (); + void _replyDestroyed (); + private: void _getSecGoogleWords (const QPoint &pos, QString &sec1, QString &sec2); int _getServerNum (const QPoint& pos, const int &max) const; void _tryCorrectGoogleVersions (); QString _tileXYToQuadKey (const int &tileX, const int &tileY, const int &levelOfDetail) const; - bool _isCorrectedGoogleVersions; - bool _correctGoogleVersions; - int _timeout; - - QMutex mutex; - static const double EarthRadiusKm; + int _timeout; + bool _googleVersionRetrieved; + QNetworkAccessManager* _network; + QNetworkReply* _googleReply; + QMutex _googleVersionMutex; + QByteArray _userAgent; }; } diff --git a/src/QtLocationPlugin/qgeotilefetcherqgc.cpp b/src/QtLocationPlugin/qgeotilefetcherqgc.cpp index 2aaa3a11700adada5f4b2a2e5a78e4bf0e1342e8..5d69be6624f3451f62c1c6001b5037a921251daa 100644 --- a/src/QtLocationPlugin/qgeotilefetcherqgc.cpp +++ b/src/QtLocationPlugin/qgeotilefetcherqgc.cpp @@ -56,11 +56,19 @@ QGeoTileFetcherQGC::QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent) : QGeoTileFetcher(parent) , m_networkManager(new QNetworkAccessManager(this)) , m_userAgent("Qt Application") + , m_UrlFactory(NULL) { QStringList langs = QLocale::system().uiLanguages(); if (langs.length() > 0) { m_Language = langs[0]; } + m_UrlFactory = new OpenPilot::UrlFactory(m_networkManager); +} + +QGeoTileFetcherQGC::~QGeoTileFetcherQGC() +{ + if(m_UrlFactory) + delete m_UrlFactory; } void QGeoTileFetcherQGC::setUserAgent(const QByteArray &userAgent) @@ -71,7 +79,7 @@ void QGeoTileFetcherQGC::setUserAgent(const QByteArray &userAgent) QGeoTiledMapReply *QGeoTileFetcherQGC::getTileImage(const QGeoTileSpec &spec) { QNetworkRequest request; - QString url = m_UrlFactory.makeImageUrl((OpenPilot::MapType)spec.mapId(), QPoint(spec.x(), spec.y()), spec.zoom(), m_Language); + QString url = m_UrlFactory->makeImageUrl((OpenPilot::MapType)spec.mapId(), QPoint(spec.x(), spec.y()), spec.zoom(), m_Language); request.setUrl(QUrl(url)); request.setRawHeader("User-Agent", m_userAgent); diff --git a/src/QtLocationPlugin/qgeotilefetcherqgc.h b/src/QtLocationPlugin/qgeotilefetcherqgc.h index be6d6829a11ee3feedcb5bbe6d854c590f9d6b74..5f3dfab8df9ab1ff0a5ad681dfb5c39837e86b9a 100644 --- a/src/QtLocationPlugin/qgeotilefetcherqgc.h +++ b/src/QtLocationPlugin/qgeotilefetcherqgc.h @@ -60,6 +60,7 @@ class QGeoTileFetcherQGC : public QGeoTileFetcher public: explicit QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent = 0); + ~QGeoTileFetcherQGC(); void setUserAgent(const QByteArray &userAgent); @@ -67,7 +68,7 @@ private: QGeoTiledMapReply* getTileImage(const QGeoTileSpec &spec); QNetworkAccessManager* m_networkManager; QByteArray m_userAgent; - OpenPilot::UrlFactory m_UrlFactory; + OpenPilot::UrlFactory* m_UrlFactory; QString m_Language; };