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:
parent
946f30f696
commit
c4599e6c4c
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;}
|
||||
|
@ -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)));
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define MBTILESMAP_H
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QByteArray>
|
||||
#include "common/range.h"
|
||||
#include "map.h"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user