From 5a692c71a82d6fc3720133fecbeeba11d45dc8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Fri, 21 Sep 2018 23:18:05 +0200 Subject: [PATCH] Added support for tiles with a different size than 256px --- src/map/mbtilesmap.cpp | 41 ++++++++++++++++++++++++++++++++++------- src/map/mbtilesmap.h | 1 + src/map/onlinemap.cpp | 12 +++++++----- src/map/osm.cpp | 8 ++++---- src/map/osm.h | 6 ++---- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/map/mbtilesmap.cpp b/src/map/mbtilesmap.cpp index 251503d5..795b34b0 100644 --- a/src/map/mbtilesmap.cpp +++ b/src/map/mbtilesmap.cpp @@ -82,12 +82,39 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent) _bounds = RectC(tl, br); } + { + 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()) { + _errorString = "Unsupported/invalid tile images"; + return; + } + _tileSize = tile.size().width(); + } + { QSqlQuery query("SELECT value FROM metadata WHERE name = 'name'", _db); if (query.first()) _name = query.value(0).toString(); - else + else { + qWarning("%s: missing map name", qPrintable(_fileName)); _name = QFileInfo(_fileName).fileName(); + } + } + + { + QSqlQuery query( + "SELECT value FROM metadata WHERE name = 'tilepixelratio'", _db); + if (query.first()) { + bool ok; + _tileRatio = query.value(0).toString().toDouble(&ok); + if (!ok) { + _errorString = "Invalid tile pixel ratio"; + return; + } + } } _db.close(); @@ -128,7 +155,7 @@ int MBTilesMap::zoomFit(const QSize &size, const RectC &rect) QRectF tbr(osm::ll2m(rect.topLeft()), osm::ll2m(rect.bottomRight())); QPointF sc(tbr.width() / size.width(), tbr.height() / size.height()); _zoom = limitZoom(osm::scale2zoom(qMax(sc.x(), -sc.y()) - / coordinatesRatio())); + / coordinatesRatio(), _tileSize)); } return _zoom; @@ -136,7 +163,7 @@ int MBTilesMap::zoomFit(const QSize &size, const RectC &rect) qreal MBTilesMap::resolution(const QRectF &rect) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, _tileSize); return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0 * cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2)); @@ -166,7 +193,7 @@ qreal MBTilesMap::imageRatio() const qreal MBTilesMap::tileSize() const { - return (TILE_SIZE / coordinatesRatio()); + return (_tileSize / coordinatesRatio()); } QByteArray MBTilesMap::tileData(int zoom, const QPoint &tile) const @@ -188,7 +215,7 @@ QByteArray MBTilesMap::tileData(int zoom, const QPoint &tile) const void MBTilesMap::draw(QPainter *painter, const QRectF &rect, Flags flags) { Q_UNUSED(flags); - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, _tileSize); QRectF b(bounds()); @@ -224,14 +251,14 @@ void MBTilesMap::draw(QPainter *painter, const QRectF &rect, Flags flags) QPointF MBTilesMap::ll2xy(const Coordinates &c) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, _tileSize); QPointF m = osm::ll2m(c); return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio(); } Coordinates MBTilesMap::xy2ll(const QPointF &p) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, _tileSize); return osm::m2ll(QPointF(p.x() * scale, -p.y() * scale) * coordinatesRatio()); } diff --git a/src/map/mbtilesmap.h b/src/map/mbtilesmap.h index a3eb7755..3689990d 100644 --- a/src/map/mbtilesmap.h +++ b/src/map/mbtilesmap.h @@ -47,6 +47,7 @@ private: RectC _bounds; Range _zooms; int _zoom; + int _tileSize; qreal _deviceRatio, _tileRatio; bool _valid; diff --git a/src/map/onlinemap.cpp b/src/map/onlinemap.cpp index ff4f3280..fd0b3605 100644 --- a/src/map/onlinemap.cpp +++ b/src/map/onlinemap.cpp @@ -8,6 +8,8 @@ #include "onlinemap.h" +#define TILE_SIZE 256 + OnlineMap::OnlineMap(const QString &name, const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio, const Authorization &authorization, QObject *parent) @@ -53,7 +55,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect) QRectF tbr(osm::ll2m(rect.topLeft()), osm::ll2m(rect.bottomRight())); QPointF sc(tbr.width() / size.width(), tbr.height() / size.height()); _zoom = limitZoom(osm::scale2zoom(qMax(sc.x(), -sc.y()) - / coordinatesRatio())); + / coordinatesRatio(), TILE_SIZE)); } return _zoom; @@ -61,7 +63,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect) qreal OnlineMap::resolution(const QRectF &rect) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, TILE_SIZE); return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0 * cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2)); @@ -96,7 +98,7 @@ qreal OnlineMap::tileSize() const void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, TILE_SIZE); QRectF b(bounds()); QPoint tile = osm::mercator2tile(QPointF(rect.topLeft().x() * scale, @@ -131,14 +133,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags) QPointF OnlineMap::ll2xy(const Coordinates &c) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, TILE_SIZE); QPointF m = osm::ll2m(c); return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio(); } Coordinates OnlineMap::xy2ll(const QPointF &p) { - qreal scale = osm::zoom2scale(_zoom); + qreal scale = osm::zoom2scale(_zoom, TILE_SIZE); return osm::m2ll(QPointF(p.x() * scale, -p.y() * scale) * coordinatesRatio()); } diff --git a/src/map/osm.cpp b/src/map/osm.cpp index acd828a5..4fee38e6 100644 --- a/src/map/osm.cpp +++ b/src/map/osm.cpp @@ -18,12 +18,12 @@ QPoint osm::mercator2tile(const QPointF &m, int z) (int)(floor((1.0 - (m.y() / 180.0)) / 2.0 * (1< #include -#define TILE_SIZE 256 - namespace osm { QPointF ll2m(const Coordinates &c); Coordinates m2ll(const QPointF &p); QPoint mercator2tile(const QPointF &m, int z); - qreal zoom2scale(int zoom); - int scale2zoom(qreal scale); + qreal zoom2scale(int zoom, int tileSize); + int scale2zoom(qreal scale, int tileSize); } #endif // OSM_H