1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Separated map downloaders, added configurable connection timeouts

This commit is contained in:
Martin Tůma 2018-04-27 19:31:27 +02:00
parent 62962b5de2
commit 566f3185f9
19 changed files with 103 additions and 138 deletions

View File

@ -3,10 +3,8 @@
#include <QLocale>
#include <QFileOpenEvent>
#include <QNetworkProxyFactory>
#include <QNetworkAccessManager>
#include <QLibraryInfo>
#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();

View File

@ -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();
}

View File

@ -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();

View File

@ -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;

View File

@ -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"

View File

@ -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<QNetworkReply*>(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);

View File

@ -1,4 +1,4 @@
#ifndef DOWNLOADER_H
#ifndef DOWNLOADER_H
#define DOWNLOADER_H
#include <QNetworkAccessManager>
@ -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<Download> &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<QUrl> _currentDownloads;
QSet<QUrl> _errorDownloads;
static int _timeout;
static QNetworkAccessManager *_manager;
};
#endif // DOWNLOADER_H

View File

@ -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];

View File

@ -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;

View File

@ -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<Tile> &list)
{

View File

@ -1,35 +1,38 @@
#ifndef TILELOADER_H
#define TILELOADER_H
#include <QObject>
#include <QString>
#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<Tile> &list);
void loadTilesSync(QList<Tile> &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

View File

@ -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<Download> 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())

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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<Download> 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())

View File

@ -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);
};

View File

@ -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];

View File

@ -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<WMTS::Zoom> _zooms;
Projection _projection;