Commit 8d95ffff authored by dogmaphobic's avatar dogmaphobic

Fixed thread race condition.

It was introduced by the Open Pilot URL Factory code.
parent 999a4a87
...@@ -37,7 +37,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -37,7 +37,7 @@ This file is part of the QGROUNDCONTROL project
namespace OpenPilot { namespace OpenPilot {
const QString ProviderStrings::levelsForSigPacSpainMap[] = const QString ProviderStrings::kLevelsForSigPacSpainMap[] =
{ "0", "1", "2", "3", "4", { "0", "1", "2", "3", "4",
"MTNSIGPAC", "MTNSIGPAC",
"MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000",
...@@ -45,15 +45,13 @@ const QString ProviderStrings::levelsForSigPacSpainMap[] = ...@@ -45,15 +45,13 @@ const QString ProviderStrings::levelsForSigPacSpainMap[] =
"MTN25", "MTN25", "MTN25", "MTN25",
"ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS" }; "ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS", "ORTOFOTOS" };
const double UrlFactory::EarthRadiusKm = 6378.137; // WGS-84
ProviderStrings::ProviderStrings() ProviderStrings::ProviderStrings()
{ {
// Google version strings // Google version strings
VersionGoogleMap = "m@113"; VersionGoogleMap = "m@296306248";
VersionGoogleSatellite = "s"; VersionGoogleSatellite = "s@168";
VersionGoogleLabels = "h@221000000"; VersionGoogleLabels = "h@296000000";
VersionGoogleTerrain = "t@132,r@249000000"; VersionGoogleTerrain = "t@132,r@296000000";
SecGoogleWord = "Galileo"; SecGoogleWord = "Galileo";
// Google (China) version strings // Google (China) version strings
...@@ -91,18 +89,18 @@ ProviderStrings::ProviderStrings() ...@@ -91,18 +89,18 @@ ProviderStrings::ProviderStrings()
BingMapsClientToken = ""; BingMapsClientToken = "";
} }
UrlFactory::UrlFactory() UrlFactory::UrlFactory(QNetworkAccessManager *network)
: _isCorrectedGoogleVersions(false) : _timeout(5 * 1000)
, _correctGoogleVersions(true) , _googleVersionRetrieved(false)
, _timeout(5 * 1000) , _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() UrlFactory::~UrlFactory()
{ {
if(_googleReply)
_googleReply->deleteLater();
} }
QString UrlFactory::_tileXYToQuadKey(const int& tileX, const int& tileY, const int& levelOfDetail) const 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 ...@@ -128,68 +126,83 @@ int UrlFactory::_getServerNum(const QPoint &pos, const int &max) const
return (pos.x() + 2 * pos.y()) % max; 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() void UrlFactory::_tryCorrectGoogleVersions()
{ {
static bool _kVersionRetrieved = false; QMutexLocker locker(&_googleVersionMutex);
if (_kVersionRetrieved) { if (_googleVersionRetrieved) {
return; return;
} }
QMutexLocker locker(&mutex); _googleVersionRetrieved = true;
if (_correctGoogleVersions && !_isCorrectedGoogleVersions) { if(_network)
QNetworkReply* reply; {
QNetworkRequest qheader; QNetworkRequest qheader;
QNetworkAccessManager network; QNetworkProxy proxy = _network->proxy();
QEventLoop q; QNetworkProxy tProxy;
QTimer tT; tProxy.setType(QNetworkProxy::NoProxy);
tT.setSingleShot(true); _network->setProxy(tProxy);
connect(&network, SIGNAL(finished(QNetworkReply *)), &q, SLOT(quit()));
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
network.setProxy(Proxy);
_isCorrectedGoogleVersions = true;
QString url = "https://maps.google.com/maps?output=classic"; QString url = "https://maps.google.com/maps?output=classic";
qheader.setUrl(QUrl(url)); qheader.setUrl(QUrl(url));
qheader.setRawHeader("User-Agent", UserAgent); QByteArray userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7";
reply = network.get(qheader); qheader.setRawHeader("User-Agent", userAgent);
tT.start(_timeout); _googleReply = _network->get(qheader);
q.exec(); connect(_googleReply, SIGNAL(finished()), this, SLOT(_googleVersionCompleted()));
if (!tT.isActive()) { connect(_googleReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(_networkReplyError(QNetworkReply::NetworkError)));
return; connect(_googleReply, SIGNAL(destroyed()), this, SLOT(_replyDestroyed()));
} _network->setProxy(proxy);
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;
} }
} }
...@@ -459,7 +472,7 @@ QString UrlFactory::makeImageUrl(const MapType &type, const QPoint& pos, const i ...@@ -459,7 +472,7 @@ QString UrlFactory::makeImageUrl(const MapType &type, const QPoint& pos, const i
break; break;
case SigPacSpainMap: 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; break;
case YandexMapRu: case YandexMapRu:
......
...@@ -35,6 +35,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -35,6 +35,7 @@ This file is part of the QGROUNDCONTROL project
#include <QPoint> #include <QPoint>
#include <QByteArray> #include <QByteArray>
#include <QNetworkProxy> #include <QNetworkProxy>
#include <QNetworkReply>
#include <QMutex> #include <QMutex>
namespace OpenPilot { namespace OpenPilot {
...@@ -88,10 +89,11 @@ enum MapType ...@@ -88,10 +89,11 @@ enum MapType
YandexMapRu = 5000 YandexMapRu = 5000
}; };
class ProviderStrings { class ProviderStrings : public QObject {
Q_OBJECT
public: public:
ProviderStrings(); ProviderStrings();
static const QString levelsForSigPacSpainMap[]; static const QString kLevelsForSigPacSpainMap[];
QString GoogleMapsAPIKey; QString GoogleMapsAPIKey;
// Google version strings // Google version strings
QString VersionGoogleMap; QString VersionGoogleMap;
...@@ -127,29 +129,32 @@ public: ...@@ -127,29 +129,32 @@ public:
QString BingMapsClientToken; QString BingMapsClientToken;
}; };
class UrlFactory : public QObject, public ProviderStrings { class UrlFactory : public ProviderStrings {
Q_OBJECT Q_OBJECT
public: public:
QByteArray UserAgent;
QNetworkProxy Proxy;
UrlFactory(); UrlFactory(QNetworkAccessManager* network);
~UrlFactory(); ~UrlFactory();
QString makeImageUrl (const MapType &type, const QPoint &pos, const int &zoom, const QString &language); 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: private:
void _getSecGoogleWords (const QPoint &pos, QString &sec1, QString &sec2); void _getSecGoogleWords (const QPoint &pos, QString &sec1, QString &sec2);
int _getServerNum (const QPoint& pos, const int &max) const; int _getServerNum (const QPoint& pos, const int &max) const;
void _tryCorrectGoogleVersions (); void _tryCorrectGoogleVersions ();
QString _tileXYToQuadKey (const int &tileX, const int &tileY, const int &levelOfDetail) const; QString _tileXYToQuadKey (const int &tileX, const int &tileY, const int &levelOfDetail) const;
bool _isCorrectedGoogleVersions; int _timeout;
bool _correctGoogleVersions; bool _googleVersionRetrieved;
int _timeout; QNetworkAccessManager* _network;
QNetworkReply* _googleReply;
QMutex mutex; QMutex _googleVersionMutex;
static const double EarthRadiusKm; QByteArray _userAgent;
}; };
} }
......
...@@ -56,11 +56,19 @@ QGeoTileFetcherQGC::QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent) ...@@ -56,11 +56,19 @@ QGeoTileFetcherQGC::QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent)
: QGeoTileFetcher(parent) : QGeoTileFetcher(parent)
, m_networkManager(new QNetworkAccessManager(this)) , m_networkManager(new QNetworkAccessManager(this))
, m_userAgent("Qt Application") , m_userAgent("Qt Application")
, m_UrlFactory(NULL)
{ {
QStringList langs = QLocale::system().uiLanguages(); QStringList langs = QLocale::system().uiLanguages();
if (langs.length() > 0) { if (langs.length() > 0) {
m_Language = langs[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) void QGeoTileFetcherQGC::setUserAgent(const QByteArray &userAgent)
...@@ -71,7 +79,7 @@ void QGeoTileFetcherQGC::setUserAgent(const QByteArray &userAgent) ...@@ -71,7 +79,7 @@ void QGeoTileFetcherQGC::setUserAgent(const QByteArray &userAgent)
QGeoTiledMapReply *QGeoTileFetcherQGC::getTileImage(const QGeoTileSpec &spec) QGeoTiledMapReply *QGeoTileFetcherQGC::getTileImage(const QGeoTileSpec &spec)
{ {
QNetworkRequest request; 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.setUrl(QUrl(url));
request.setRawHeader("User-Agent", m_userAgent); request.setRawHeader("User-Agent", m_userAgent);
......
...@@ -60,6 +60,7 @@ class QGeoTileFetcherQGC : public QGeoTileFetcher ...@@ -60,6 +60,7 @@ class QGeoTileFetcherQGC : public QGeoTileFetcher
public: public:
explicit QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent = 0); explicit QGeoTileFetcherQGC(QGeoTiledMappingManagerEngine *parent = 0);
~QGeoTileFetcherQGC();
void setUserAgent(const QByteArray &userAgent); void setUserAgent(const QByteArray &userAgent);
...@@ -67,7 +68,7 @@ private: ...@@ -67,7 +68,7 @@ private:
QGeoTiledMapReply* getTileImage(const QGeoTileSpec &spec); QGeoTiledMapReply* getTileImage(const QGeoTileSpec &spec);
QNetworkAccessManager* m_networkManager; QNetworkAccessManager* m_networkManager;
QByteArray m_userAgent; QByteArray m_userAgent;
OpenPilot::UrlFactory m_UrlFactory; OpenPilot::UrlFactory* m_UrlFactory;
QString m_Language; QString m_Language;
}; };
......
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