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

Fixed AQM maps display with "world-level" tiles

+ code cleanup
This commit is contained in:
Martin Tůma 2021-02-09 20:09:14 +01:00
parent 946f30f696
commit c4599e6c4c
6 changed files with 42 additions and 27 deletions

View File

@ -191,8 +191,23 @@ bool AQMMap::readHeader()
if (!parseLevel(data, zoom, tileSize, bounds))
return false;
_bounds = RectC(OSM::tile2ll(bounds.topLeft(), zoom),
OSM::tile2ll(bounds.bottomRight(), zoom));
if (_bounds.isNull()) {
double minX = OSM::index2mercator(qMin((1<<zoom) - 1,
qMax(0, bounds.left())), zoom);
double minY = OSM::index2mercator(qMin((1<<zoom) - 1,
qMax(0, bounds.top())), zoom);
double maxX = OSM::index2mercator(qMin((1<<zoom) - 1,
qMax(0, bounds.right())) + 1, zoom);
double maxY = OSM::index2mercator(qMin((1<<zoom) - 1,
qMax(0, bounds.bottom())) + 1, zoom);
Coordinates tl(OSM::m2ll(QPointF(minX, -minY)));
Coordinates br(OSM::m2ll(QPointF(maxX, -maxY)));
// Workaround of broken zoom levels 0 and 1 due to numerical
// instability
tl.rlat() = qMin(tl.lat(), OSM::BOUNDS.top());
br.rlat() = qMax(br.lat(), OSM::BOUNDS.bottom());
_bounds = RectC(tl, br);
}
_zooms.append(Zoom(zoom, tileSize));
} else if (files.at(i).name == "@LEVEL") {
li = i;
@ -353,16 +368,20 @@ void AQMMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
Q_UNUSED(flags);
const Zoom &z = _zooms.at(_zoom);
qreal scale = OSM::zoom2scale(z.zoom, z.tileSize);
QRectF b(bounds());
QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * _mapRatio, z.zoom);
QPointF tl(floor(rect.left() / tileSize())
* tileSize(), floor(rect.top() / tileSize()) * tileSize());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
QSizeF s(qMin(rect.right() - tl.x(), b.width()),
qMin(rect.bottom() - tl.y(), b.height()));
int width = ceil(s.width() / tileSize());
int height = ceil(s.height() / tileSize());
QList<AQTile> tiles;
for (int i = 0; i < width; i++) {
@ -373,13 +392,15 @@ void AQMMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
+ QString::number(t.x()) + "_" + QString::number(t.y());
if (QPixmapCache::find(key, &pm)) {
QPointF tp(tl.x() + (t.x() - tile.x()) * tileSize(),
tl.y() + (t.y() - tile.y()) * tileSize());
QPointF tp(qMax(tl.x(), b.left()) + (t.x() - tile.x())
* tileSize(), qMax(tl.y(), b.top()) + (t.y() - tile.y())
* tileSize());
drawTile(painter, pm, tp);
} else
} else {
tiles.append(AQTile(t, tileData(t), key));
}
}
}
QFuture<void> future = QtConcurrent::map(tiles, &AQTile::load);
future.waitForFinished();
@ -389,10 +410,12 @@ void AQMMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QPixmap pm(mt.pixmap());
if (pm.isNull())
continue;
QPixmapCache::insert(mt.key(), pm);
QPointF tp(tl.x() + (mt.xy().x() - tile.x()) * tileSize(),
tl.y() + (mt.xy().y() - tile.y()) * tileSize());
QPointF tp(qMax(tl.x(), b.left()) + (mt.xy().x() - tile.x())
* tileSize(), qMax(tl.y(), b.top()) + (mt.xy().y() - tile.y())
* tileSize());
drawTile(painter, pm, tp);
}
}

View File

@ -18,6 +18,7 @@ public:
QString name() const {return _name;}
QRectF bounds();
RectC llBounds() {return _bounds;}
qreal resolution(const QRectF &rect);
int zoom() const {return _zoom;}

View File

@ -1,18 +1,18 @@
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlField>
#include <QFileInfo>
#include <QPainter>
#include <QPixmapCache>
#include <QImageReader>
#include <QBuffer>
#include <QtConcurrent>
#include "common/rectc.h"
#include "common/util.h"
#include "osm.h"
#include "mbtilesmap.h"
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
class MBTile
{
public:
@ -43,12 +43,6 @@ private:
QImage _image;
};
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
static double index2mercator(int index, int zoom)
{
return rad2deg(-M_PI + 2 * M_PI * ((double)index / (1<<zoom)));
}
MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
: Map(fileName, parent), _mapRatio(1.0), _tileRatio(1.0), _scalable(false),
@ -59,7 +53,7 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
_db.setConnectOptions("QSQLITE_OPEN_READONLY");
if (!_db.open()) {
_errorString = fileName + ": Error opening database file";
_errorString = "Error opening database file";
return;
}
@ -99,13 +93,13 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
QSqlQuery query(sql, _db);
query.first();
double minX = index2mercator(qMin((1<<_zooms.min()) - 1,
double minX = OSM::index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(0).toInt())), _zooms.min());
double minY = index2mercator(qMin((1<<_zooms.min()) - 1,
double minY = OSM::index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(1).toInt())), _zooms.min());
double maxX = index2mercator(qMin((1<<_zooms.min()) - 1,
double maxX = OSM::index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(2).toInt())) + 1, _zooms.min());
double maxY = index2mercator(qMin((1<<_zooms.min()) - 1,
double maxY = OSM::index2mercator(qMin((1<<_zooms.min()) - 1,
qMax(0, query.value(3).toInt())) + 1, _zooms.min());
Coordinates tl(OSM::m2ll(QPointF(minX, maxY)));
Coordinates br(OSM::m2ll(QPointF(maxX, minY)));

View File

@ -2,7 +2,6 @@
#define MBTILESMAP_H
#include <QSqlDatabase>
#include <QByteArray>
#include "common/range.h"
#include "map.h"

View File

@ -21,11 +21,9 @@ QPoint OSM::mercator2tile(const QPointF &m, int zoom)
qFloor((1.0 - (m.y() / 180.0)) / 2.0 * (1<<zoom)));
}
Coordinates OSM::tile2ll(const QPoint &p, int z)
double OSM::index2mercator(int index, int zoom)
{
double n = M_PI - 2.0 * M_PI * p.y() / (double)(1 << z);
return Coordinates(p.x() / (double)(1 << z) * 360.0 - 180,
180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))));
return rad2deg(-M_PI + 2 * M_PI * ((double)index / (1<<zoom)));
}
qreal OSM::zoom2scale(int zoom, int tileSize)

View File

@ -15,7 +15,7 @@ namespace OSM
QPointF ll2m(const Coordinates &c);
Coordinates m2ll(const QPointF &p);
QPoint mercator2tile(const QPointF &m, int zoom);
Coordinates tile2ll(const QPoint &p, int z);
double index2mercator(int index, int zoom);
qreal zoom2scale(int zoom, int tileSize);
int scale2zoom(qreal scale, int tileSize);
qreal resolution(const QPointF &p, int zoom, int tileSize);