1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-01-18 19:52:09 +01:00

Scale the tile images in HiDPImode when they are scalable (vector tiles)

This commit is contained in:
Martin Tůma 2018-11-15 00:38:03 +01:00
parent ac5476868d
commit 4c88414677
9 changed files with 87 additions and 23 deletions

View File

@ -9,7 +9,7 @@
MapSource::Config::Config() : type(OSM), zooms(OSM::ZOOMS), bounds(OSM::BOUNDS),
format("image/png"), rest(false), tileRatio(1.0) {}
format("image/png"), rest(false), tileRatio(1.0), scalable(false) {}
static CoordinateSystem coordinateSystem(QXmlStreamReader &reader)
@ -178,6 +178,10 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
#else // ENABLE_HIDPI
reader.raiseError("HiDPI maps not supported");
#endif // ENABLE_HIDPI
} else if (reader.name() == "scalable") {
QString val = reader.readElementText().trimmed();
if (val == "true" || val == "1")
config.scalable = true;
} else
reader.skipCurrentElement();
}
@ -250,10 +254,12 @@ Map *MapSource::loadMap(const QString &path, QString &errorString)
config.dimensions, config.authorization));
case TMS:
return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, true);
config.bounds, config.tileRatio, config.authorization,
config.scalable, true);
case OSM:
return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, false);
config.bounds, config.tileRatio, config.authorization,
config.scalable, false);
default:
return 0;
}

View File

@ -40,6 +40,7 @@ private:
QList<KV> dimensions;
Authorization authorization;
qreal tileRatio;
bool scalable;
Config();
};

View File

@ -4,6 +4,8 @@
#include <QFileInfo>
#include <QPainter>
#include <QPixmapCache>
#include <QImageReader>
#include <QBuffer>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QtCore>
#else // QT_VERSION < 5
@ -18,8 +20,9 @@
class MBTile
{
public:
MBTile(int zoom, const QPoint &xy, const QByteArray &data,
const QString &key) : _zoom(zoom), _xy(xy), _data(data), _key(key) {}
MBTile(int zoom, int scaledSize, const QPoint &xy, const QByteArray &data,
const QString &key) : _zoom(zoom), _scaledSize(scaledSize), _xy(xy),
_data(data), _key(key) {}
const QPoint &xy() const {return _xy;}
const QString &key() const {return _key;}
@ -27,11 +30,17 @@ public:
void load() {
QByteArray z(QString::number(_zoom).toLatin1());
_image.loadFromData(_data, z);
QBuffer buffer(&_data);
QImageReader reader(&buffer, z);
if (_scaledSize)
reader.setScaledSize(QSize(_scaledSize, _scaledSize));
reader.read(&_image);
}
private:
int _zoom;
int _scaledSize;
QPoint _xy;
QByteArray _data;
QString _key;
@ -52,7 +61,7 @@ static double index2mercator(int index, int zoom)
MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
: Map(parent), _fileName(fileName), _deviceRatio(1.0), _tileRatio(1.0),
_valid(false)
_scalable(false), _scaledSize(0), _valid(false)
{
_db = QSqlDatabase::addDatabase("QSQLITE", fileName);
_db.setDatabaseName(fileName);
@ -118,12 +127,26 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
QString sql = QString("SELECT tile_data FROM tiles LIMIT 1");
QSqlQuery query(sql, _db);
query.first();
QImage tile = QImage::fromData(query.value(0).toByteArray());
if (tile.isNull() || tile.size().width() != tile.size().height()) {
QByteArray data = query.value(0).toByteArray();
QBuffer buffer(&data);
QImageReader reader(&buffer);
QSize tileSize(reader.size());
if (tileSize.isNull() || tileSize.width() != tileSize.height()) {
_errorString = "Unsupported/invalid tile images";
return;
}
_tileSize = tile.size().width();
_tileSize = tileSize.width();
}
{
QSqlQuery query("SELECT value FROM metadata WHERE name = 'format'", _db);
if (query.first()) {
if (query.value(0).toString() == "pbf")
_scalable = true;
} else
qWarning("%s: missing map name", qPrintable(_fileName));
}
{
@ -210,6 +233,16 @@ int MBTilesMap::zoomOut()
return _zoom;
}
void MBTilesMap::setDevicePixelRatio(qreal ratio)
{
_deviceRatio = ratio;
if (_scalable) {
_scaledSize = _tileSize * ratio;
_tileRatio = ratio;
}
}
qreal MBTilesMap::coordinatesRatio() const
{
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
@ -273,8 +306,10 @@ void MBTilesMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
* tileSize(), qMax(tl.y(), b.top()) + (t.y() - tile.y())
* tileSize());
drawTile(painter, pm, tp);
} else
tiles.append(MBTile(_zoom, t, tileData(_zoom, t), key));
} else {
tiles.append(MBTile(_zoom, _scaledSize, t, tileData(_zoom, t),
key));
}
}
}

View File

@ -29,7 +29,7 @@ public:
void load();
void unload();
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
void setDevicePixelRatio(qreal ratio);
bool isValid() const {return _valid;}
QString errorString() const {return _errorString;}
@ -50,6 +50,8 @@ private:
int _zoom;
int _tileSize;
qreal _deviceRatio, _tileRatio;
bool _scalable;
int _scaledSize;
bool _valid;
QString _errorString;

View File

@ -12,10 +12,11 @@
OnlineMap::OnlineMap(const QString &name, const QString &url,
const Range &zooms, const RectC &bounds, qreal tileRatio,
const Authorization &authorization, bool invertY, QObject *parent)
const Authorization &authorization, bool scalable, bool invertY,
QObject *parent)
: Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
_zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio),
_invertY(invertY)
_scalable(scalable), _scaledSize(0), _invertY(invertY)
{
_tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name),
this);
@ -70,6 +71,16 @@ int OnlineMap::zoomOut()
return _zoom;
}
void OnlineMap::setDevicePixelRatio(qreal ratio)
{
_deviceRatio = ratio;
if (_scalable) {
_scaledSize = TILE_SIZE * ratio;
_tileRatio = ratio;
}
}
qreal OnlineMap::coordinatesRatio() const
{
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
@ -103,7 +114,7 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
tiles.append(Tile(QPoint(tile.x() + i, _invertY ? (1<<_zoom)
- (tile.y() + j) - 1 : tile.y() + j), _zoom));
- (tile.y() + j) - 1 : tile.y() + j), _zoom, _scaledSize));
if (flags & Map::Block)
_tileLoader->loadTilesSync(tiles);

View File

@ -13,7 +13,7 @@ class OnlineMap : public Map
public:
OnlineMap(const QString &name, const QString &url, const Range &zooms,
const RectC &bounds, qreal tileRatio, const Authorization &authorization,
bool invertY, QObject *parent = 0);
bool scalable, bool invertY, QObject *parent = 0);
QString name() const {return _name;}
@ -31,7 +31,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
void setDevicePixelRatio(qreal ratio);
void clearCache() {_tileLoader->clearCache();}
private:
@ -46,6 +46,8 @@ private:
RectC _bounds;
int _zoom;
qreal _deviceRatio, _tileRatio;
bool _scalable;
int _scaledSize;
bool _invertY;
};

View File

@ -11,17 +11,20 @@ class Tile
{
public:
Tile() {}
Tile(const QPoint &xy, const QVariant &zoom, const RectD &bbox = RectD())
{_xy = xy; _zoom = zoom; _bbox = bbox;}
Tile(const QPoint &xy, const QVariant &zoom, int scaledSize = 0,
const RectD &bbox = RectD()) : _xy(xy), _zoom(zoom),
_scaledSize(scaledSize), _bbox(bbox) {}
const QVariant &zoom() const {return _zoom;}
const QPoint &xy() const {return _xy;}
const RectD &bbox() const {return _bbox;}
int scaledSize() const {return _scaledSize;}
QPixmap& pixmap() {return _pixmap;}
private:
QVariant _zoom;
QPoint _xy;
QVariant _zoom;
int _scaledSize;
RectD _bbox;
QPixmap _pixmap;
};

View File

@ -2,6 +2,7 @@
#include <QFileInfo>
#include <QEventLoop>
#include <QPixmapCache>
#include <QImageReader>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QtCore>
#else // QT_VERSION < 5
@ -24,7 +25,10 @@ public:
void load()
{
QByteArray z(_tile->zoom().toString().toLatin1());
_image.load(_file, z);
QImageReader reader(_file, z);
if (_tile->scaledSize())
reader.setScaledSize(QSize(_tile->scaledSize(), _tile->scaledSize()));
reader.read(&_image);
}
const QString &file() const {return _file;}

View File

@ -206,7 +206,7 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
? RectD(PointD(tbr.y(), tbr.x()), PointD(ttl.y(), ttl.x()))
: RectD(ttl, tbr);
tiles.append(Tile(QPoint(i, j), _zoom, bbox));
tiles.append(Tile(QPoint(i, j), _zoom, 0, bbox));
}
}