1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-02-07 12:05:14 +01:00
GPXSee/src/map/tileloader.cpp

164 lines
3.5 KiB
C++
Raw Normal View History

2018-02-20 23:37:19 +01:00
#include <QDir>
#include <QFileInfo>
#include <QEventLoop>
#include "tileloader.h"
#define SUBSTITUTE_CHAR '$'
2023-12-10 08:51:18 +01:00
#define IS_INT(zoom) \
((QMetaType::Type)((zoom).type()) == QMetaType::Int)
2018-02-20 23:37:19 +01:00
2018-11-10 13:18:54 +01:00
static QString fsSafeStr(const QString &str)
{
QString ret(str);
#ifdef Q_OS_WIN32
ret.replace('<', SUBSTITUTE_CHAR);
ret.replace('>', SUBSTITUTE_CHAR);
ret.replace(':', SUBSTITUTE_CHAR);
ret.replace('"', SUBSTITUTE_CHAR);
ret.replace('/', SUBSTITUTE_CHAR);
ret.replace('\\', SUBSTITUTE_CHAR);
ret.replace('|', SUBSTITUTE_CHAR);
ret.replace('?', SUBSTITUTE_CHAR);
ret.replace('*', SUBSTITUTE_CHAR);
#else // Q_OS_WIN32
ret.replace('/', SUBSTITUTE_CHAR);
#endif // Q_OS_WIN32
return ret;
}
2019-05-20 23:23:24 +02:00
static QString quadKey(const QPoint &xy, int zoom)
{
QString qk;
for (int i = zoom; i > 0; i--) {
char digit = '0';
unsigned mask = 1 << (i - 1);
if (xy.x() & mask)
digit++;
2019-05-21 17:59:46 +02:00
if (xy.y() & mask)
digit += 2;
2019-05-20 23:23:24 +02:00
qk.append(digit);
}
return qk;
}
2018-09-24 22:49:10 +02:00
TileLoader::TileLoader(const QString &dir, QObject *parent)
: QObject(parent), _urlType(XYZ), _dir(dir)
{
2018-09-24 22:49:10 +02:00
if (!QDir().mkpath(_dir))
2018-09-24 23:07:11 +02:00
qWarning("%s: %s", qPrintable(_dir), "Error creating tiles directory");
2018-09-24 22:49:10 +02:00
_downloader = new Downloader(this);
2021-04-28 00:01:07 +02:00
connect(_downloader, &Downloader::finished, this, &TileLoader::finished);
}
2018-02-20 23:37:19 +01:00
2023-05-06 16:14:49 +02:00
void TileLoader::loadTilesAsync(QVector<Tile> &list)
2018-02-20 23:37:19 +01:00
{
QList<Download> dl;
for (int i = 0; i < list.size(); i++) {
Tile &t = list[i];
2018-09-22 12:42:49 +02:00
QString file(tileFile(t));
2018-11-10 13:18:54 +01:00
if (QFileInfo::exists(file))
t.setFile(file);
2018-10-04 23:02:43 +02:00
else {
QUrl url(tileUrl(t));
if (url.isLocalFile())
t.setFile(url.toLocalFile());
2018-10-04 23:02:43 +02:00
else
dl.append(Download(url, file));
}
2018-02-20 23:37:19 +01:00
}
if (!dl.empty())
_downloader->get(dl, _headers);
2018-02-20 23:37:19 +01:00
}
void TileLoader::loadTilesSync(QVector<Tile> &list)
2018-02-20 23:37:19 +01:00
{
QList<Download> dl;
QList<Tile *> tl;
2018-02-20 23:37:19 +01:00
for (int i = 0; i < list.size(); i++) {
Tile &t = list[i];
2018-09-22 12:42:49 +02:00
QString file(tileFile(t));
2018-11-10 13:18:54 +01:00
if (QFileInfo::exists(file))
t.setFile(file);
2018-10-04 23:02:43 +02:00
else {
QUrl url(tileUrl(t));
if (url.isLocalFile())
t.setFile(url.toLocalFile());
2018-11-10 13:18:54 +01:00
else {
2018-10-04 23:02:43 +02:00
dl.append(Download(url, file));
2018-11-10 13:18:54 +01:00
tl.append(&t);
}
2018-10-04 23:02:43 +02:00
}
2018-02-20 23:37:19 +01:00
}
2018-11-10 13:18:54 +01:00
if (!dl.empty()) {
QEventLoop wait;
2021-04-28 00:01:07 +02:00
connect(_downloader, &Downloader::finished, &wait, &QEventLoop::quit);
if (_downloader->get(dl, _headers))
2018-11-10 13:18:54 +01:00
wait.exec();
2018-02-20 23:37:19 +01:00
2018-11-10 13:18:54 +01:00
for (int i = 0; i < tl.size(); i++) {
Tile *t = tl[i];
2023-12-26 14:14:08 +01:00
QString file(tileFile(*t));
if (QFileInfo::exists(file))
t->setFile(file);
2018-02-20 23:37:19 +01:00
}
}
}
void TileLoader::clearCache()
{
QDir dir = QDir(_dir);
QStringList list = dir.entryList();
for (int i = 0; i < list.count(); i++)
dir.remove(list.at(i));
_downloader->clearErrors();
2018-02-20 23:37:19 +01:00
}
QUrl TileLoader::tileUrl(const Tile &tile) const
2018-02-20 23:37:19 +01:00
{
QString url(_url);
2023-06-23 09:30:44 +02:00
switch (_urlType) {
case BoundingBox:
url.replace("$bbox", QString("%1,%2,%3,%4").arg(
QString::number(tile.bbox().left(), 'f', 6),
QString::number(tile.bbox().bottom(), 'f', 6),
QString::number(tile.bbox().right(), 'f', 6),
QString::number(tile.bbox().top(), 'f', 6)));
break;
case QuadTiles:
url.replace("$quadkey", quadKey(tile.xy(), tile.zoom().toInt()));
break;
default:
url.replace("$z", tile.zoom().toString());
url.replace("$x", QString::number(tile.xy().x()));
url.replace("$y", QString::number(tile.xy().y()));
}
2018-02-20 23:37:19 +01:00
2018-09-22 12:42:49 +02:00
return QUrl(url);
2018-02-20 23:37:19 +01:00
}
QString TileLoader::tileFile(const Tile &tile) const
2018-02-20 23:37:19 +01:00
{
2023-12-10 08:51:18 +01:00
QString zoom(IS_INT(tile.zoom())
? tile.zoom().toString() : fsSafeStr(tile.zoom().toString()));
return _dir + QLatin1Char('/') + zoom + QLatin1Char('-')
2018-10-04 23:02:43 +02:00
+ QString::number(tile.xy().x()) + QLatin1Char('-')
+ QString::number(tile.xy().y());
2018-02-20 23:37:19 +01:00
}