From 566f3185f90c970a24e683504cebba906a38f709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Fri, 27 Apr 2018 19:31:27 +0200 Subject: [PATCH] Separated map downloaders, added configurable connection timeouts --- src/GUI/app.cpp | 9 ++------- src/GUI/gui.cpp | 8 ++++++++ src/GUI/optionsdialog.cpp | 20 ++++++++++++++------ src/GUI/optionsdialog.h | 2 ++ src/GUI/settings.h | 2 ++ src/map/downloader.cpp | 21 ++++++++++++--------- src/map/downloader.h | 13 ++++++++++--- src/map/onlinemap.cpp | 27 +++++++-------------------- src/map/onlinemap.h | 10 ++-------- src/map/tileloader.cpp | 6 +++++- src/map/tileloader.h | 23 +++++++++++++---------- src/map/wms.cpp | 7 +++---- src/map/wms.h | 3 --- src/map/wmsmap.cpp | 31 +++++++++---------------------- src/map/wmsmap.h | 8 +------- src/map/wmts.cpp | 7 +++---- src/map/wmts.h | 5 ----- src/map/wmtsmap.cpp | 31 +++++++++---------------------- src/map/wmtsmap.h | 8 +------- 19 files changed, 103 insertions(+), 138 deletions(-) diff --git a/src/GUI/app.cpp b/src/GUI/app.cpp index 89347273..66d03e1a 100644 --- a/src/GUI/app.cpp +++ b/src/GUI/app.cpp @@ -3,10 +3,8 @@ #include #include #include +#include #include -#include "map/wmts.h" -#include "map/wms.h" -#include "map/tileloader.h" #include "map/downloader.h" #include "map/ellipsoid.h" #include "map/gcs.h" @@ -38,10 +36,7 @@ App::App(int &argc, char **argv) : QApplication(argc, argv), #endif // Q_OS_MAC QNetworkProxyFactory::setUseSystemConfiguration(true); - Downloader *dl = new Downloader(this); - TileLoader::setDownloader(dl); - WMTS::setDownloader(dl); - WMS::setDownloader(dl); + Downloader::setNetworkAccessManager(new QNetworkAccessManager(this)); OPENGL_SET_SAMPLES(4); loadDatums(); loadPCSs(); diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 6228de6b..9c951e2a 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -25,6 +25,7 @@ #include "data/data.h" #include "map/maplist.h" #include "map/emptymap.h" +#include "map/downloader.h" #include "config.h" #include "icons.h" #include "keys.h" @@ -855,6 +856,8 @@ void GUI::openOptions() _poi->setRadius(options.poiRadius); if (options.pixmapCache != _options.pixmapCache) QPixmapCache::setCacheLimit(options.pixmapCache * 1024); + if (options.connectionTimeout != _options.connectionTimeout) + Downloader::setTimeout(options.connectionTimeout); if (reload) reloadFile(); @@ -1620,6 +1623,8 @@ void GUI::writeSettings() settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL); if (_options.pixmapCache != PIXMAP_CACHE_DEFAULT) settings.setValue(PIXMAP_CACHE_SETTING, _options.pixmapCache); + if (_options.connectionTimeout != CONNECTION_TIMEOUT_DEFAULT) + settings.setValue(CONNECTION_TIMEOUT_SETTING, _options.connectionTimeout); if (_options.hiresPrint != HIRES_PRINT_DEFAULT) settings.setValue(HIRES_PRINT_SETTING, _options.hiresPrint); if (_options.printName != PRINT_NAME_DEFAULT) @@ -1848,6 +1853,8 @@ void GUI::readSettings() .toBool(); _options.pixmapCache = settings.value(PIXMAP_CACHE_SETTING, PIXMAP_CACHE_DEFAULT).toInt(); + _options.connectionTimeout = settings.value(CONNECTION_TIMEOUT_SETTING, + CONNECTION_TIMEOUT_DEFAULT).toInt(); _options.hiresPrint = settings.value(HIRES_PRINT_SETTING, HIRES_PRINT_DEFAULT).toBool(); _options.printName = settings.value(PRINT_NAME_SETTING, PRINT_NAME_DEFAULT) @@ -1907,6 +1914,7 @@ void GUI::readSettings() _poi->setRadius(_options.poiRadius); QPixmapCache::setCacheLimit(_options.pixmapCache * 1024); + Downloader::setTimeout(_options.connectionTimeout); settings.endGroup(); } diff --git a/src/GUI/optionsdialog.cpp b/src/GUI/optionsdialog.cpp index 2ea87dc8..f233d8bf 100644 --- a/src/GUI/optionsdialog.cpp +++ b/src/GUI/optionsdialog.cpp @@ -431,16 +431,23 @@ QWidget *OptionsDialog::createSystemPage() _pixmapCache->setSuffix(UNIT_SPACE + tr("MB")); _pixmapCache->setValue(_options->pixmapCache); - QFormLayout *cacheLayout = new QFormLayout(); - cacheLayout->addRow(tr("Image cache size:"), _pixmapCache); + _connectionTimeout = new QSpinBox(); + _connectionTimeout->setMinimum(30); + _connectionTimeout->setMaximum(120); + _connectionTimeout->setSuffix(UNIT_SPACE + tr("s")); + _connectionTimeout->setValue(_options->connectionTimeout); - QFormLayout *openGLLayout = new QFormLayout(); - openGLLayout->addWidget(_useOpenGL); + QFormLayout *formLayout = new QFormLayout(); + formLayout->addRow(tr("Image cache size:"), _pixmapCache); + formLayout->addRow(tr("Connection timeout:"), _connectionTimeout); + + QFormLayout *checkboxLayout = new QFormLayout(); + checkboxLayout->addWidget(_useOpenGL); QWidget *systemTab = new QWidget(); QVBoxLayout *systemTabLayout = new QVBoxLayout(); - systemTabLayout->addLayout(cacheLayout); - systemTabLayout->addLayout(openGLLayout); + systemTabLayout->addLayout(formLayout); + systemTabLayout->addLayout(checkboxLayout); systemTabLayout->addStretch(); systemTab->setLayout(systemTabLayout); @@ -545,6 +552,7 @@ void OptionsDialog::accept() _options->useOpenGL = _useOpenGL->isChecked(); _options->pixmapCache = _pixmapCache->value(); + _options->connectionTimeout = _connectionTimeout->value(); _options->hiresPrint = _hires->isChecked(); _options->printName = _name->isChecked(); diff --git a/src/GUI/optionsdialog.h b/src/GUI/optionsdialog.h index 07f451a7..003e9e8a 100644 --- a/src/GUI/optionsdialog.h +++ b/src/GUI/optionsdialog.h @@ -48,6 +48,7 @@ struct Options { // System bool useOpenGL; int pixmapCache; + int connectionTimeout; // Print/Export bool hiresPrint; bool printName; @@ -113,6 +114,7 @@ private: QDoubleSpinBox *_poiRadius; // System QSpinBox *_pixmapCache; + QSpinBox *_connectionTimeout; QCheckBox *_useOpenGL; // Print/Export QRadioButton *_wysiwyg; diff --git a/src/GUI/settings.h b/src/GUI/settings.h index a73bfaa3..4da33de4 100644 --- a/src/GUI/settings.h +++ b/src/GUI/settings.h @@ -130,6 +130,8 @@ #define USE_OPENGL_DEFAULT false #define PIXMAP_CACHE_SETTING "pixmapCache" #define PIXMAP_CACHE_DEFAULT 64 /* MB */ +#define CONNECTION_TIMEOUT_SETTING "connectionTimeout" +#define CONNECTION_TIMEOUT_DEFAULT 30 /* s */ #define HIRES_PRINT_SETTING "hiresPrint" #define HIRES_PRINT_DEFAULT false #define PRINT_NAME_SETTING "printName" diff --git a/src/map/downloader.cpp b/src/map/downloader.cpp index df05436c..23538baa 100644 --- a/src/map/downloader.cpp +++ b/src/map/downloader.cpp @@ -26,7 +26,6 @@ #define ATTR_LEVEL (QNetworkRequest::Attribute)(QNetworkRequest::User + 2) #define MAX_REDIRECT_LEVEL 5 -#define TIMEOUT 30 /* s */ Authorization::Authorization(const QString &username, const QString &password) @@ -80,11 +79,8 @@ private: }; -Downloader::Downloader(QObject *parent) : QObject(parent) -{ - connect(&_manager, SIGNAL(finished(QNetworkReply*)), - SLOT(downloadFinished(QNetworkReply*))); -} +QNetworkAccessManager *Downloader::_manager = 0; +int Downloader::_timeout = 30; bool Downloader::doDownload(const Download &dl, const QByteArray &authorization, const Redirect *redirect) @@ -111,10 +107,11 @@ bool Downloader::doDownload(const Download &dl, if (!authorization.isNull()) request.setRawHeader("Authorization", authorization); - QNetworkReply *reply = _manager.get(request); + QNetworkReply *reply = _manager->get(request); if (reply && reply->isRunning()) { _currentDownloads.insert(url); - ReplyTimeout::setTimeout(reply, TIMEOUT); + ReplyTimeout::setTimeout(reply, _timeout); + connect(reply, SIGNAL(finished()), this, SLOT(emitFinished())); } else if (reply) downloadFinished(reply); else @@ -123,6 +120,11 @@ bool Downloader::doDownload(const Download &dl, return true; } +void Downloader::emitFinished() +{ + downloadFinished(static_cast(sender())); +} + bool Downloader::saveToDisk(const QString &filename, QIODevice *data) { QFile file(filename); @@ -184,9 +186,10 @@ void Downloader::downloadFinished(QNetworkReply *reply) &redirect)) _errorDownloads.insert(origin.isEmpty() ? url : origin); } - } else + } else { if (!saveToDisk(filename, reply)) _errorDownloads.insert(url); + } } _currentDownloads.remove(url); diff --git a/src/map/downloader.h b/src/map/downloader.h index 3adb6eb9..a6b1048e 100644 --- a/src/map/downloader.h +++ b/src/map/downloader.h @@ -1,4 +1,4 @@ -#ifndef DOWNLOADER_H +#ifndef DOWNLOADER_H #define DOWNLOADER_H #include @@ -38,16 +38,21 @@ class Downloader : public QObject Q_OBJECT public: - Downloader(QObject *parent = 0); + Downloader(QObject *parent = 0) : QObject(parent) {} bool get(const QList &list, const Authorization &authorization = Authorization()); void clearErrors() {_errorDownloads.clear();} + static void setTimeout(int timeout) {_timeout = timeout;} + static void setNetworkAccessManager(QNetworkAccessManager *manager) + {_manager = manager;} + signals: void finished(); private slots: + void emitFinished(); void downloadFinished(QNetworkReply *reply); private: @@ -58,9 +63,11 @@ private: const Redirect *redirect = 0); bool saveToDisk(const QString &filename, QIODevice *data); - QNetworkAccessManager _manager; QSet _currentDownloads; QSet _errorDownloads; + + static int _timeout; + static QNetworkAccessManager *_manager; }; #endif // DOWNLOADER_H diff --git a/src/map/onlinemap.cpp b/src/map/onlinemap.cpp index 5aeaa268..8460c7c7 100644 --- a/src/map/onlinemap.cpp +++ b/src/map/onlinemap.cpp @@ -49,7 +49,11 @@ OnlineMap::OnlineMap(const QString &name, const QString &url, QString dir(TILES_DIR + "/" + _name); _zoom = _zooms.max(); - _tileLoader = TileLoader(url, dir); + + _tileLoader = new TileLoader(this); + _tileLoader->setUrl(url); + _tileLoader->setDir(dir); + connect(_tileLoader, SIGNAL(finished()), this, SIGNAL(loaded())); if (!QDir().mkpath(dir)) { _errorString = "Error creating tiles dir"; @@ -59,23 +63,6 @@ OnlineMap::OnlineMap(const QString &name, const QString &url, _valid = true; } -void OnlineMap::load() -{ - connect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void OnlineMap::unload() -{ - disconnect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void OnlineMap::emitLoaded() -{ - emit loaded(); -} - QRectF OnlineMap::bounds() const { return QRectF(ll2xy(_bounds.topLeft()), ll2xy(_bounds.bottomRight())); @@ -140,9 +127,9 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect) tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom)); if (_block) - _tileLoader.loadTilesSync(tiles); + _tileLoader->loadTilesSync(tiles); else - _tileLoader.loadTilesAsync(tiles); + _tileLoader->loadTilesAsync(tiles); for (int i = 0; i < tiles.count(); i++) { Tile &t = tiles[i]; diff --git a/src/map/onlinemap.h b/src/map/onlinemap.h index fdada059..20a40e7e 100644 --- a/src/map/onlinemap.h +++ b/src/map/onlinemap.h @@ -32,23 +32,17 @@ public: void draw(QPainter *painter, const QRectF &rect); void setBlockingMode(bool block) {_block = block;} - void clearCache() {_tileLoader.clearCache();} - - void load(); - void unload(); + void clearCache() {_tileLoader->clearCache();} bool isValid() const {return _valid;} QString errorString() const {return _errorString;} -private slots: - void emitLoaded(); - private: QPointF ll2xy(const Coordinates &c) const; Coordinates xy2ll(const QPointF &p) const; int limitZoom(int zoom) const; - TileLoader _tileLoader; + TileLoader *_tileLoader; QString _name; Range _zooms; RectC _bounds; diff --git a/src/map/tileloader.cpp b/src/map/tileloader.cpp index a768b2d9..a4420ea7 100644 --- a/src/map/tileloader.cpp +++ b/src/map/tileloader.cpp @@ -15,7 +15,11 @@ static bool loadTileFile(Tile &tile, const QString &file) return true; } -Downloader *TileLoader::_downloader = 0; +TileLoader::TileLoader(QObject *parent) : QObject(parent) +{ + _downloader = new Downloader(this); + connect(_downloader, SIGNAL(finished()), this, SIGNAL(finished())); +} void TileLoader::loadTilesAsync(QList &list) { diff --git a/src/map/tileloader.h b/src/map/tileloader.h index 30571348..2cad88f2 100644 --- a/src/map/tileloader.h +++ b/src/map/tileloader.h @@ -1,35 +1,38 @@ #ifndef TILELOADER_H #define TILELOADER_H +#include #include #include "tile.h" #include "downloader.h" -class TileLoader +class TileLoader : public QObject { + Q_OBJECT + public: - TileLoader() {} - TileLoader(const QString &url, const QString &dir, - const Authorization &authorization = Authorization()) - : _url(url), _dir(dir), _authorization(authorization) {} + TileLoader(QObject *parent = 0); + + void setUrl(const QString &url) {_url = url;} + void setDir(const QString &dir) {_dir = dir;} + void setAuthorization(const Authorization &authorization) + {_authorization = authorization;} void loadTilesAsync(QList &list); void loadTilesSync(QList &list); void clearCache(); - static Downloader *downloader() {return _downloader;} - static void setDownloader(Downloader *downloader) - {_downloader = downloader;} +signals: + void finished(); private: QString tileUrl(const Tile &tile) const; QString tileFile(const Tile &tile) const; + Downloader *_downloader; QString _url; QString _dir; Authorization _authorization; - - static Downloader *_downloader; }; #endif // TILELOADER_Honlinemap diff --git a/src/map/wms.cpp b/src/map/wms.cpp index 0f94af56..9b308e63 100644 --- a/src/map/wms.cpp +++ b/src/map/wms.cpp @@ -7,8 +7,6 @@ #include "wms.h" -Downloader *WMS::_downloader = 0; - WMS::CTX::CTX(const Setup &setup) : setup(setup), formatSupported(false) { QStringList ll = setup.layer().split(','); @@ -256,13 +254,14 @@ bool WMS::parseCapabilities(const QString &path, const Setup &setup) bool WMS::getCapabilities(const QString &url, const QString &file, const Authorization &authorization) { + Downloader d; QList dl; dl.append(Download(url, file)); QEventLoop wait; - QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit())); - if (_downloader->get(dl, authorization)) + QObject::connect(&d, SIGNAL(finished()), &wait, SLOT(quit())); + if (d.get(dl, authorization)) wait.exec(); if (QFileInfo(file).exists()) diff --git a/src/map/wms.h b/src/map/wms.h index 77c1952f..dc26a074 100644 --- a/src/map/wms.h +++ b/src/map/wms.h @@ -58,9 +58,6 @@ public: bool isValid() const {return _valid;} const QString &errorString() const {return _errorString;} - static void setDownloader(Downloader *downloader) - {_downloader = downloader;} - private: struct Layer { QString name; diff --git a/src/map/wmsmap.cpp b/src/map/wmsmap.cpp index 3ace1ce9..0e2d3a82 100644 --- a/src/map/wmsmap.cpp +++ b/src/map/wmsmap.cpp @@ -86,8 +86,8 @@ bool WMSMap::loadWMS() _projection = wms.projection(); _tl = _projection.ll2xy(wms.boundingBox().topLeft()); _br = _projection.ll2xy(wms.boundingBox().bottomRight()); - _tileLoader = TileLoader(tileUrl(wms.version()), tilesDir(), - _setup.authorization()); + _tileLoader->setUrl(tileUrl(wms.version())); + _tileLoader->setAuthorization(_setup.authorization()); if (wms.version() >= "1.3.0") { if (_setup.coordinateSystem().axisOrder() == CoordinateSystem::Unknown) @@ -112,35 +112,22 @@ WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent) return; } + _tileLoader = new TileLoader(this); + _tileLoader->setDir(tilesDir()); + connect(_tileLoader, SIGNAL(finished()), this, SIGNAL(loaded())); + _valid = loadWMS(); } void WMSMap::clearCache() { - _tileLoader.clearCache(); + _tileLoader->clearCache(); _zoom = 0; if (!loadWMS()) qWarning("%s: %s\n", qPrintable(_name), qPrintable(_errorString)); } -void WMSMap::load() -{ - connect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void WMSMap::unload() -{ - disconnect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void WMSMap::emitLoaded() -{ - emit loaded(); -} - qreal WMSMap::resolution(const QRectF &rect) const { Coordinates tl = xy2ll((rect.topLeft())); @@ -223,9 +210,9 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect) } if (_block) - _tileLoader.loadTilesSync(tiles); + _tileLoader->loadTilesSync(tiles); else - _tileLoader.loadTilesAsync(tiles); + _tileLoader->loadTilesAsync(tiles); for (int i = 0; i < tiles.count(); i++) { Tile &t = tiles[i]; diff --git a/src/map/wmsmap.h b/src/map/wmsmap.h index 970327c2..099123f3 100644 --- a/src/map/wmsmap.h +++ b/src/map/wmsmap.h @@ -35,15 +35,9 @@ public: void setBlockingMode(bool block) {_block = block;} void clearCache(); - void load(); - void unload(); - bool isValid() const {return _valid;} QString errorString() const {return _errorString;} -private slots: - void emitLoaded(); - private: QString tileUrl(const QString &version) const; double sd2res(double scaleDenominator) const; @@ -58,7 +52,7 @@ private: QString _name; WMS::Setup _setup; - TileLoader _tileLoader; + TileLoader *_tileLoader; Projection _projection; Transform _transform; CoordinateSystem _cs; diff --git a/src/map/wmts.cpp b/src/map/wmts.cpp index b237255a..1f09a8c4 100644 --- a/src/map/wmts.cpp +++ b/src/map/wmts.cpp @@ -12,8 +12,6 @@ #include "wmts.h" -Downloader *WMTS::_downloader = 0; - WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader) { TileMatrix matrix; @@ -282,13 +280,14 @@ bool WMTS::parseCapabilities(const QString &path, const Setup &setup) bool WMTS::getCapabilities(const QString &url, const QString &file, const Authorization &authorization) { + Downloader d; QList dl; dl.append(Download(url, file)); QEventLoop wait; - QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit())); - if (_downloader->get(dl, authorization)) + QObject::connect(&d, SIGNAL(finished()), &wait, SLOT(quit())); + if (d.get(dl, authorization)) wait.exec(); if (QFileInfo(file).exists()) diff --git a/src/map/wmts.h b/src/map/wmts.h index 9268c3d6..d7d8d673 100644 --- a/src/map/wmts.h +++ b/src/map/wmts.h @@ -88,9 +88,6 @@ public: bool isValid() const {return _valid;} const QString &errorString() const {return _errorString;} - static void setDownloader(Downloader *downloader) - {_downloader = downloader;} - private: struct TileMatrix { QString id; @@ -154,8 +151,6 @@ private: bool _valid; QString _errorString; - static Downloader *_downloader; - friend uint qHash(const WMTS::TileMatrix &key); friend uint qHash(const WMTS::MatrixLimits &key); }; diff --git a/src/map/wmtsmap.cpp b/src/map/wmtsmap.cpp index 0f34291f..4f709383 100644 --- a/src/map/wmtsmap.cpp +++ b/src/map/wmtsmap.cpp @@ -23,8 +23,8 @@ bool WMTSMap::loadWMTS() _bounds = wmts.bounds(); _zooms = wmts.zooms(); _projection = wmts.projection(); - _tileLoader = TileLoader(wmts.tileUrl(), tilesDir(), - _setup.authorization()); + _tileLoader->setUrl(wmts.tileUrl()); + _tileLoader->setAuthorization(_setup.authorization()); if (_setup.coordinateSystem().axisOrder() == CoordinateSystem::Unknown) _cs = _projection.coordinateSystem(); @@ -45,12 +45,16 @@ WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent) return; } + _tileLoader = new TileLoader(this); + _tileLoader->setDir(tilesDir()); + connect(_tileLoader, SIGNAL(finished()), this, SIGNAL(loaded())); + _valid = loadWMTS(); } void WMTSMap::clearCache() { - _tileLoader.clearCache(); + _tileLoader->clearCache(); _zoom = 0; if (!loadWMTS()) @@ -87,23 +91,6 @@ void WMTSMap::updateTransform() _transform = Transform(tl, br); } -void WMTSMap::load() -{ - connect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void WMTSMap::unload() -{ - disconnect(TileLoader::downloader(), SIGNAL(finished()), this, - SLOT(emitLoaded())); -} - -void WMTSMap::emitLoaded() -{ - emit loaded(); -} - QRectF WMTSMap::bounds() const { const WMTS::Zoom &z = _zooms.at(_zoom); @@ -185,9 +172,9 @@ void WMTSMap::draw(QPainter *painter, const QRectF &rect) tiles.append(Tile(QPoint(i, j), z.id())); if (_block) - _tileLoader.loadTilesSync(tiles); + _tileLoader->loadTilesSync(tiles); else - _tileLoader.loadTilesAsync(tiles); + _tileLoader->loadTilesAsync(tiles); for (int i = 0; i < tiles.count(); i++) { Tile &t = tiles[i]; diff --git a/src/map/wmtsmap.h b/src/map/wmtsmap.h index 80ba295a..4fdb734c 100644 --- a/src/map/wmtsmap.h +++ b/src/map/wmtsmap.h @@ -35,15 +35,9 @@ public: void setBlockingMode(bool block) {_block = block;} void clearCache(); - void load(); - void unload(); - bool isValid() const {return _valid;} QString errorString() const {return _errorString;} -private slots: - void emitLoaded(); - private: bool loadWMTS(); double sd2res(double scaleDenominator) const; @@ -55,7 +49,7 @@ private: QString _name; WMTS::Setup _setup; - TileLoader _tileLoader; + TileLoader *_tileLoader; RectC _bounds; QList _zooms; Projection _projection;