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
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:
......
......@@ -35,6 +35,7 @@ This file is part of the QGROUNDCONTROL project
#include <QPoint>
#include <QByteArray>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QMutex>
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;
};
}
......
......@@ -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);
......
......@@ -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;
};
......
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