1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34: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)) if (!parseLevel(data, zoom, tileSize, bounds))
return false; return false;
_bounds = RectC(OSM::tile2ll(bounds.topLeft(), zoom), if (_bounds.isNull()) {
OSM::tile2ll(bounds.bottomRight(), zoom)); 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)); _zooms.append(Zoom(zoom, tileSize));
} else if (files.at(i).name == "@LEVEL") { } else if (files.at(i).name == "@LEVEL") {
li = i; li = i;
@ -353,16 +368,20 @@ void AQMMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
Q_UNUSED(flags); Q_UNUSED(flags);
const Zoom &z = _zooms.at(_zoom); const Zoom &z = _zooms.at(_zoom);
qreal scale = OSM::zoom2scale(z.zoom, z.tileSize); qreal scale = OSM::zoom2scale(z.zoom, z.tileSize);
QRectF b(bounds());
QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale, QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * _mapRatio, z.zoom); -rect.topLeft().y() * scale) * _mapRatio, z.zoom);
QPointF tl(floor(rect.left() / tileSize()) QPointF tl(floor(rect.left() / tileSize())
* tileSize(), floor(rect.top() / tileSize()) * 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 width = ceil(s.width() / tileSize());
int height = ceil(s.height() / tileSize()); int height = ceil(s.height() / tileSize());
QList<AQTile> tiles; QList<AQTile> tiles;
for (int i = 0; i < width; i++) { 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()); + QString::number(t.x()) + "_" + QString::number(t.y());
if (QPixmapCache::find(key, &pm)) { if (QPixmapCache::find(key, &pm)) {
QPointF tp(tl.x() + (t.x() - tile.x()) * tileSize(), QPointF tp(qMax(tl.x(), b.left()) + (t.x() - tile.x())
tl.y() + (t.y() - tile.y()) * tileSize()); * tileSize(), qMax(tl.y(), b.top()) + (t.y() - tile.y())
* tileSize());
drawTile(painter, pm, tp); drawTile(painter, pm, tp);
} else } else {
tiles.append(AQTile(t, tileData(t), key)); tiles.append(AQTile(t, tileData(t), key));
} }
} }
}
QFuture<void> future = QtConcurrent::map(tiles, &AQTile::load); QFuture<void> future = QtConcurrent::map(tiles, &AQTile::load);
future.waitForFinished(); future.waitForFinished();
@ -389,10 +410,12 @@ void AQMMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QPixmap pm(mt.pixmap()); QPixmap pm(mt.pixmap());
if (pm.isNull()) if (pm.isNull())
continue; continue;
QPixmapCache::insert(mt.key(), pm); QPixmapCache::insert(mt.key(), pm);
QPointF tp(tl.x() + (mt.xy().x() - tile.x()) * tileSize(), QPointF tp(qMax(tl.x(), b.left()) + (mt.xy().x() - tile.x())
tl.y() + (mt.xy().y() - tile.y()) * tileSize()); * tileSize(), qMax(tl.y(), b.top()) + (mt.xy().y() - tile.y())
* tileSize());
drawTile(painter, pm, tp); drawTile(painter, pm, tp);
} }
} }

View File

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

View File

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

View File

@ -2,7 +2,6 @@
#define MBTILESMAP_H #define MBTILESMAP_H
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QByteArray>
#include "common/range.h" #include "common/range.h"
#include "map.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))); 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 rad2deg(-M_PI + 2 * M_PI * ((double)index / (1<<zoom)));
return Coordinates(p.x() / (double)(1 << z) * 360.0 - 180,
180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))));
} }
qreal OSM::zoom2scale(int zoom, int tileSize) qreal OSM::zoom2scale(int zoom, int tileSize)

View File

@ -15,7 +15,7 @@ namespace OSM
QPointF ll2m(const Coordinates &c); QPointF ll2m(const Coordinates &c);
Coordinates m2ll(const QPointF &p); Coordinates m2ll(const QPointF &p);
QPoint mercator2tile(const QPointF &m, int zoom); 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); qreal zoom2scale(int zoom, int tileSize);
int scale2zoom(qreal scale, int tileSize); int scale2zoom(qreal scale, int tileSize);
qreal resolution(const QPointF &p, int zoom, int tileSize); qreal resolution(const QPointF &p, int zoom, int tileSize);