1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Propper handling of vector tiles scaling in all map display modes

This commit is contained in:
Martin Tůma 2018-11-17 10:10:35 +01:00
parent 4c88414677
commit 3c6ce2dde2
22 changed files with 153 additions and 107 deletions

View File

@ -924,8 +924,8 @@ void GUI::openOptions()
#endif // ENABLE_HTTP2 #endif // ENABLE_HTTP2
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
if (options.hidpiMap != _options.hidpiMap) if (options.hidpiMap != _options.hidpiMap)
_mapView->setDevicePixelRatio(options.hidpiMap ? devicePixelRatioF() _mapView->setDevicePixelRatio(devicePixelRatioF(),
: 1.0); options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
if (reload) if (reload)
@ -2047,7 +2047,8 @@ void GUI::readSettings()
if (_options.useOpenGL) if (_options.useOpenGL)
_mapView->useOpenGL(true); _mapView->useOpenGL(true);
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(_options.hidpiMap ? devicePixelRatioF() : 1.0); _mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
for (int i = 0; i < _tabs.count(); i++) { for (int i = 0; i < _tabs.count(); i++) {
@ -2130,7 +2131,8 @@ void GUI::show()
void GUI::screenChanged(QScreen *screen) void GUI::screenChanged(QScreen *screen)
{ {
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(_options.hidpiMap ? devicePixelRatioF() : 1.0); _mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
disconnect(SIGNAL(logicalDotsPerInchChanged(qreal)), this, disconnect(SIGNAL(logicalDotsPerInchChanged(qreal)), this,
SLOT(logicalDotsPerInchChanged(qreal))); SLOT(logicalDotsPerInchChanged(qreal)));
@ -2146,6 +2148,7 @@ void GUI::logicalDotsPerInchChanged(qreal dpi)
Q_UNUSED(dpi) Q_UNUSED(dpi)
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_mapView->setDevicePixelRatio(_options.hidpiMap ? devicePixelRatioF() : 1.0); _mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0);
#endif // ENBLE_HIDPI #endif // ENBLE_HIDPI
} }

View File

@ -73,7 +73,8 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_poiColor = Qt::black; _poiColor = Qt::black;
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_ratio = 1.0; _deviceRatio = 1.0;
_mapRatio = 1.0;
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
_opengl = false; _opengl = false;
_plot = false; _plot = false;
@ -271,7 +272,7 @@ void MapView::setMap(Map *map)
_map = map; _map = map;
_map->load(); _map->load();
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(_ratio); _map->setDevicePixelRatio(_deviceRatio, _mapRatio);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap())); connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
@ -506,7 +507,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
setUpdatesEnabled(false); setUpdatesEnabled(false);
_plot = true; _plot = true;
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(1.0); _map->setDevicePixelRatio(_deviceRatio, 1.0);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
// Compute sizes & ratios // Compute sizes & ratios
@ -567,7 +568,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
// Exit plot mode // Exit plot mode
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
_map->setDevicePixelRatio(_ratio); _map->setDevicePixelRatio(_deviceRatio, _mapRatio);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
_plot = false; _plot = false;
setUpdatesEnabled(true); setUpdatesEnabled(true);
@ -845,19 +846,21 @@ void MapView::reloadMap()
_scene->invalidate(); _scene->invalidate();
} }
void MapView::setDevicePixelRatio(qreal ratio) void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
if (_ratio == ratio) if (_deviceRatio == deviceRatio && _mapRatio == mapRatio)
return; return;
_ratio = ratio; _deviceRatio = deviceRatio;
_mapRatio = mapRatio;
QPixmapCache::clear();
QRectF vr(mapToScene(viewport()->rect()).boundingRect() QRectF vr(mapToScene(viewport()->rect()).boundingRect()
.intersected(_map->bounds())); .intersected(_map->bounds()));
RectC cr(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight())); RectC cr(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight()));
_map->setDevicePixelRatio(_ratio); _map->setDevicePixelRatio(_deviceRatio, _mapRatio);
_scene->setSceneRect(_map->bounds()); _scene->setSceneRect(_map->bounds());
for (int i = 0; i < _tracks.size(); i++) for (int i = 0; i < _tracks.size(); i++)

View File

@ -69,7 +69,7 @@ public slots:
void showRouteWaypoints(bool show); void showRouteWaypoints(bool show);
void clearMapCache(); void clearMapCache();
void setCoordinatesFormat(CoordinatesFormat format); void setCoordinatesFormat(CoordinatesFormat format);
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
private slots: private slots:
void updatePOI(); void updatePOI();
@ -140,7 +140,8 @@ private:
bool _plot; bool _plot;
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
qreal _ratio; qreal _deviceRatio;
qreal _mapRatio;
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
bool _opengl; bool _opengl;
}; };

View File

@ -145,10 +145,10 @@ Atlas::Atlas(const QString &fileName, QObject *parent)
_valid = true; _valid = true;
} }
void Atlas::setDevicePixelRatio(qreal ratio) void Atlas::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
for (int i = 0; i < _maps.size(); i++) for (int i = 0; i < _maps.size(); i++)
_maps[i]->setDevicePixelRatio(ratio); _maps[i]->setDevicePixelRatio(deviceRatio, mapRatio);
computeBounds(); computeBounds();
} }

View File

@ -28,7 +28,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void unload(); void unload();
bool isValid() const {return _valid;} bool isValid() const {return _valid;}

View File

@ -61,9 +61,11 @@ void GeoTIFFMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
_img->draw(painter, rect, flags); _img->draw(painter, rect, flags);
} }
void GeoTIFFMap::setDevicePixelRatio(qreal ratio) void GeoTIFFMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
_ratio = ratio; Q_UNUSED(deviceRatio);
_ratio = mapRatio;
if (_img) if (_img)
_img->setDevicePixelRatio(_ratio); _img->setDevicePixelRatio(_ratio);
} }

View File

@ -25,7 +25,7 @@ public:
void load(); void load();
void unload(); void unload();
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}

View File

@ -142,7 +142,7 @@ bool JNXMap::readTiles()
} }
JNXMap::JNXMap(const QString &fileName, QObject *parent) JNXMap::JNXMap(const QString &fileName, QObject *parent)
: Map(parent), _file(fileName), _zoom(0), _ratio(1.0), _valid(false) : Map(parent), _file(fileName), _zoom(0), _mapRatio(1.0), _valid(false)
{ {
_name = QFileInfo(fileName).fileName(); _name = QFileInfo(fileName).fileName();
@ -162,13 +162,13 @@ JNXMap::JNXMap(const QString &fileName, QObject *parent)
QPointF JNXMap::ll2xy(const Coordinates &c) QPointF JNXMap::ll2xy(const Coordinates &c)
{ {
const Zoom &z = _zooms.at(_zoom); const Zoom &z = _zooms.at(_zoom);
return z.transform.proj2img(_projection.ll2xy(c)) / _ratio; return z.transform.proj2img(_projection.ll2xy(c)) / _mapRatio;
} }
Coordinates JNXMap::xy2ll(const QPointF &p) Coordinates JNXMap::xy2ll(const QPointF &p)
{ {
const Zoom &z = _zooms.at(_zoom); const Zoom &z = _zooms.at(_zoom);
return _projection.xy2ll(z.transform.img2proj(p * _ratio)); return _projection.xy2ll(z.transform.img2proj(p * _mapRatio));
} }
QRectF JNXMap::bounds() QRectF JNXMap::bounds()
@ -249,8 +249,8 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{ {
Q_UNUSED(flags); Q_UNUSED(flags);
const RTree<Tile*, qreal, 2> &tree = _zooms.at(_zoom).tree; const RTree<Tile*, qreal, 2> &tree = _zooms.at(_zoom).tree;
Ctx ctx(painter, &_file, _ratio); Ctx ctx(painter, &_file, _mapRatio);
QRectF rr(rect.topLeft() * _ratio, rect.size() * _ratio); QRectF rr(rect.topLeft() * _mapRatio, rect.size() * _mapRatio);
qreal min[2], max[2]; qreal min[2], max[2];
min[0] = rr.left(); min[0] = rr.left();

View File

@ -32,7 +32,8 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio) {_ratio = ratio;} void setDevicePixelRatio(qreal /*deviceRatio*/, qreal mapRatio)
{_mapRatio = mapRatio;}
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
@ -63,7 +64,7 @@ private:
int _zoom; int _zoom;
RectC _bounds; RectC _bounds;
Projection _projection; Projection _projection;
qreal _ratio; qreal _mapRatio;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -44,7 +44,7 @@ public:
virtual void clearCache() {} virtual void clearCache() {}
virtual void load() {} virtual void load() {}
virtual void unload() {} virtual void unload() {}
virtual void setDevicePixelRatio(qreal) {} virtual void setDevicePixelRatio(qreal, qreal) {}
virtual bool isValid() const {return true;} virtual bool isValid() const {return true;}
virtual QString errorString() const {return QString();} virtual QString errorString() const {return QString();}

View File

@ -9,7 +9,8 @@
MapSource::Config::Config() : type(OSM), zooms(OSM::ZOOMS), bounds(OSM::BOUNDS), MapSource::Config::Config() : type(OSM), zooms(OSM::ZOOMS), bounds(OSM::BOUNDS),
format("image/png"), rest(false), tileRatio(1.0), scalable(false) {} format("image/png"), rest(false), tileRatio(1.0), tileSize(256),
scalable(false) {}
static CoordinateSystem coordinateSystem(QXmlStreamReader &reader) static CoordinateSystem coordinateSystem(QXmlStreamReader &reader)
@ -115,6 +116,7 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
{ {
const QXmlStreamAttributes &attr = reader.attributes(); const QXmlStreamAttributes &attr = reader.attributes();
QStringRef type = attr.value("type"); QStringRef type = attr.value("type");
bool res;
if (type == "WMTS") if (type == "WMTS")
config.type = WMTS; config.type = WMTS;
@ -168,8 +170,8 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
attr.value("password").toString()); attr.value("password").toString());
reader.skipCurrentElement(); reader.skipCurrentElement();
} else if (reader.name() == "tilePixelRatio") { } else if (reader.name() == "tilePixelRatio") {
// Legacy tilePixelRatio tag support
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
bool res;
qreal val = reader.readElementText().toDouble(&res); qreal val = reader.readElementText().toDouble(&res);
if (!res) if (!res)
reader.raiseError("Invalid tilePixelRatio"); reader.raiseError("Invalid tilePixelRatio");
@ -178,10 +180,40 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
#else // ENABLE_HIDPI #else // ENABLE_HIDPI
reader.raiseError("HiDPI maps not supported"); reader.raiseError("HiDPI maps not supported");
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
} else if (reader.name() == "scalable") { } else if (reader.name() == "tile") {
QString val = reader.readElementText().trimmed(); QXmlStreamAttributes attr = reader.attributes();
if (val == "true" || val == "1")
if (attr.hasAttribute("size")) {
int size = attr.value("size").toString().toInt(&res);
if (!res || size < 0) {
reader.raiseError("Invalid tile size");
return;
} else
config.tileSize = size;
}
if (attr.hasAttribute("type")) {
if (attr.value("type") == "raster")
config.scalable = false;
else if (attr.value("type") == "vector")
config.scalable = true; config.scalable = true;
else {
reader.raiseError("Invalid tile type");
return;
}
}
if (attr.hasAttribute("pixelRatio")) {
#ifdef ENABLE_HIDPI
qreal ratio = attr.value("pixelRatio").toString().toDouble(&res);
if (!res || ratio < 0) {
reader.raiseError("Invalid tile pixelRatio");
return;
} else
config.tileRatio = ratio;
#else // ENABLE_HIDPI
reader.raiseError("HiDPI maps not supported");
#endif // ENABLE_HIDPI
}
} else } else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
@ -255,11 +287,11 @@ Map *MapSource::loadMap(const QString &path, QString &errorString)
case TMS: case TMS:
return new OnlineMap(config.name, config.url, config.zooms, return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, config.bounds, config.tileRatio, config.authorization,
config.scalable, true); config.tileSize, config.scalable, true);
case OSM: case OSM:
return new OnlineMap(config.name, config.url, config.zooms, return new OnlineMap(config.name, config.url, config.zooms,
config.bounds, config.tileRatio, config.authorization, config.bounds, config.tileRatio, config.authorization,
config.scalable, false); config.tileSize, config.scalable, false);
default: default:
return 0; return 0;
} }

View File

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

View File

@ -60,7 +60,7 @@ static double index2mercator(int index, int zoom)
} }
MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent) MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
: Map(parent), _fileName(fileName), _deviceRatio(1.0), _tileRatio(1.0), : Map(parent), _fileName(fileName), _mapRatio(1.0), _tileRatio(1.0),
_scalable(false), _scaledSize(0), _valid(false) _scalable(false), _scaledSize(0), _valid(false)
{ {
_db = QSqlDatabase::addDatabase("QSQLITE", fileName); _db = QSqlDatabase::addDatabase("QSQLITE", fileName);
@ -133,7 +133,7 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
QImageReader reader(&buffer); QImageReader reader(&buffer);
QSize tileSize(reader.size()); QSize tileSize(reader.size());
if (tileSize.isNull() || tileSize.width() != tileSize.height()) { if (!tileSize.isValid() || tileSize.width() != tileSize.height()) {
_errorString = "Unsupported/invalid tile images"; _errorString = "Unsupported/invalid tile images";
return; return;
} }
@ -233,24 +233,24 @@ int MBTilesMap::zoomOut()
return _zoom; return _zoom;
} }
void MBTilesMap::setDevicePixelRatio(qreal ratio) void MBTilesMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
_deviceRatio = ratio; _mapRatio = mapRatio;
if (_scalable) { if (_scalable) {
_scaledSize = _tileSize * ratio; _scaledSize = _tileSize * deviceRatio;
_tileRatio = ratio; _tileRatio = deviceRatio;
} }
} }
qreal MBTilesMap::coordinatesRatio() const qreal MBTilesMap::coordinatesRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0; return _mapRatio > 1.0 ? _mapRatio / _tileRatio : 1.0;
} }
qreal MBTilesMap::imageRatio() const qreal MBTilesMap::imageRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio; return _mapRatio > 1.0 ? _mapRatio : _tileRatio;
} }
qreal MBTilesMap::tileSize() const qreal MBTilesMap::tileSize() const

View File

@ -29,7 +29,7 @@ public:
void load(); void load();
void unload(); void unload();
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
@ -49,7 +49,7 @@ private:
Range _zooms; Range _zooms;
int _zoom; int _zoom;
int _tileSize; int _tileSize;
qreal _deviceRatio, _tileRatio; qreal _mapRatio, _tileRatio;
bool _scalable; bool _scalable;
int _scaledSize; int _scaledSize;

View File

@ -8,15 +8,13 @@
#include "onlinemap.h" #include "onlinemap.h"
#define TILE_SIZE 256
OnlineMap::OnlineMap(const QString &name, const QString &url, OnlineMap::OnlineMap(const QString &name, const QString &url,
const Range &zooms, const RectC &bounds, qreal tileRatio, const Range &zooms, const RectC &bounds, qreal tileRatio,
const Authorization &authorization, bool scalable, bool invertY, const Authorization &authorization, int tileSize, bool scalable, bool invertY,
QObject *parent) QObject *parent)
: Map(parent), _name(name), _zooms(zooms), _bounds(bounds), : Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
_zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio), _zoom(_zooms.max()), _mapRatio(1.0), _tileRatio(tileRatio),
_scalable(scalable), _scaledSize(0), _invertY(invertY) _tileSize(tileSize), _scalable(scalable), _invertY(invertY), _scaledSize(0)
{ {
_tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name), _tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name),
this); this);
@ -48,7 +46,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
QRectF tbr(OSM::ll2m(rect.topLeft()), OSM::ll2m(rect.bottomRight())); QRectF tbr(OSM::ll2m(rect.topLeft()), OSM::ll2m(rect.bottomRight()));
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height()); QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
_zoom = limitZoom(OSM::scale2zoom(qMax(sc.x(), -sc.y()) _zoom = limitZoom(OSM::scale2zoom(qMax(sc.x(), -sc.y())
/ coordinatesRatio(), TILE_SIZE)); / coordinatesRatio(), _tileSize));
} }
return _zoom; return _zoom;
@ -56,7 +54,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
qreal OnlineMap::resolution(const QRectF &rect) qreal OnlineMap::resolution(const QRectF &rect)
{ {
return OSM::resolution(rect.center(), _zoom, TILE_SIZE); return OSM::resolution(rect.center(), _zoom, _tileSize);
} }
int OnlineMap::zoomIn() int OnlineMap::zoomIn()
@ -71,34 +69,34 @@ int OnlineMap::zoomOut()
return _zoom; return _zoom;
} }
void OnlineMap::setDevicePixelRatio(qreal ratio) void OnlineMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
_deviceRatio = ratio; _mapRatio = mapRatio;
if (_scalable) { if (_scalable) {
_scaledSize = TILE_SIZE * ratio; _scaledSize = _tileSize * deviceRatio;
_tileRatio = ratio; _tileRatio = deviceRatio;
} }
} }
qreal OnlineMap::coordinatesRatio() const qreal OnlineMap::coordinatesRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0; return _mapRatio > 1.0 ? _mapRatio / _tileRatio : 1.0;
} }
qreal OnlineMap::imageRatio() const qreal OnlineMap::imageRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio; return _mapRatio > 1.0 ? _mapRatio : _tileRatio;
} }
qreal OnlineMap::tileSize() const qreal OnlineMap::tileSize() const
{ {
return (TILE_SIZE / coordinatesRatio()); return (_tileSize / coordinatesRatio());
} }
void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags) void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{ {
qreal scale = OSM::zoom2scale(_zoom, TILE_SIZE); qreal scale = OSM::zoom2scale(_zoom, _tileSize);
QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale, QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * coordinatesRatio(), _zoom); -rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
@ -138,14 +136,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QPointF OnlineMap::ll2xy(const Coordinates &c) QPointF OnlineMap::ll2xy(const Coordinates &c)
{ {
qreal scale = OSM::zoom2scale(_zoom, TILE_SIZE); qreal scale = OSM::zoom2scale(_zoom, _tileSize);
QPointF m = OSM::ll2m(c); QPointF m = OSM::ll2m(c);
return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio(); return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio();
} }
Coordinates OnlineMap::xy2ll(const QPointF &p) Coordinates OnlineMap::xy2ll(const QPointF &p)
{ {
qreal scale = OSM::zoom2scale(_zoom, TILE_SIZE); qreal scale = OSM::zoom2scale(_zoom, _tileSize);
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale)
* coordinatesRatio()); * coordinatesRatio());
} }

View File

@ -13,7 +13,7 @@ class OnlineMap : public Map
public: public:
OnlineMap(const QString &name, const QString &url, const Range &zooms, OnlineMap(const QString &name, const QString &url, const Range &zooms,
const RectC &bounds, qreal tileRatio, const Authorization &authorization, const RectC &bounds, qreal tileRatio, const Authorization &authorization,
bool scalable, bool invertY, QObject *parent = 0); int tileSize, bool scalable, bool invertY, QObject *parent = 0);
QString name() const {return _name;} QString name() const {return _name;}
@ -31,7 +31,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void clearCache() {_tileLoader->clearCache();} void clearCache() {_tileLoader->clearCache();}
private: private:
@ -45,10 +45,11 @@ private:
Range _zooms; Range _zooms;
RectC _bounds; RectC _bounds;
int _zoom; int _zoom;
qreal _deviceRatio, _tileRatio; qreal _mapRatio, _tileRatio;
int _tileSize;
bool _scalable; bool _scalable;
int _scaledSize;
bool _invertY; bool _invertY;
int _scaledSize;
}; };
#endif // ONLINEMAP_H #endif // ONLINEMAP_H

View File

@ -16,7 +16,7 @@
OziMap::OziMap(const QString &fileName, QObject *parent) OziMap::OziMap(const QString &fileName, QObject *parent)
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false) : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0), _valid(false)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
QString suffix = fi.suffix().toLower(); QString suffix = fi.suffix().toLower();
@ -78,7 +78,7 @@ OziMap::OziMap(const QString &fileName, QObject *parent)
} }
OziMap::OziMap(const QString &fileName, Tar &tar, QObject *parent) OziMap::OziMap(const QString &fileName, Tar &tar, QObject *parent)
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false) : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0), _valid(false)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
QFileInfo map(fi.absolutePath()); QFileInfo map(fi.absolutePath());
@ -217,15 +217,15 @@ void OziMap::unload()
void OziMap::drawTiled(QPainter *painter, const QRectF &rect) const void OziMap::drawTiled(QPainter *painter, const QRectF &rect) const
{ {
QSizeF ts(_tile.size.width() / _ratio, _tile.size.height() / _ratio); QSizeF ts(_tile.size.width() / _mapRatio, _tile.size.height() / _mapRatio);
QPointF tl(floor(rect.left() / ts.width()) * ts.width(), QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
floor(rect.top() / ts.height()) * ts.height()); floor(rect.top() / ts.height()) * ts.height());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y()); QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
for (int i = 0; i < ceil(s.width() / ts.width()); i++) { for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
for (int j = 0; j < ceil(s.height() / ts.height()); j++) { for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
int x = round(tl.x() * _ratio + i * _tile.size.width()); int x = round(tl.x() * _mapRatio + i * _tile.size.width());
int y = round(tl.y() * _ratio + j * _tile.size.height()); int y = round(tl.y() * _mapRatio + j * _tile.size.height());
QString tileName(_tile.path.arg(QString::number(x), QString tileName(_tile.path.arg(QString::number(x),
QString::number(y))); QString::number(y)));
@ -247,7 +247,7 @@ void OziMap::drawTiled(QPainter *painter, const QRectF &rect) const
_tile.path.arg(QString::number(x), QString::number(y)))); _tile.path.arg(QString::number(x), QString::number(y))));
else { else {
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
pixmap.setDevicePixelRatio(_ratio); pixmap.setDevicePixelRatio(_mapRatio);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height()); QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
painter->drawPixmap(tp, pixmap); painter->drawPixmap(tp, pixmap);
@ -258,16 +258,16 @@ void OziMap::drawTiled(QPainter *painter, const QRectF &rect) const
void OziMap::drawOZF(QPainter *painter, const QRectF &rect) const void OziMap::drawOZF(QPainter *painter, const QRectF &rect) const
{ {
QSizeF ts(_ozf->tileSize().width() / _ratio, _ozf->tileSize().height() QSizeF ts(_ozf->tileSize().width() / _mapRatio, _ozf->tileSize().height()
/ _ratio); / _mapRatio);
QPointF tl(floor(rect.left() / ts.width()) * ts.width(), QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
floor(rect.top() / ts.height()) * ts.height()); floor(rect.top() / ts.height()) * ts.height());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y()); QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
for (int i = 0; i < ceil(s.width() / ts.width()); i++) { for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
for (int j = 0; j < ceil(s.height() / ts.height()); j++) { for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
int x = round(tl.x() * _ratio + i * _ozf->tileSize().width()); int x = round(tl.x() * _mapRatio + i * _ozf->tileSize().width());
int y = round(tl.y() * _ratio + j * _ozf->tileSize().height()); int y = round(tl.y() * _mapRatio + j * _ozf->tileSize().height());
QPixmap pixmap; QPixmap pixmap;
QString key = _ozf->fileName() + "/" + QString::number(_zoom) + "_" QString key = _ozf->fileName() + "/" + QString::number(_zoom) + "_"
@ -282,7 +282,7 @@ void OziMap::drawOZF(QPainter *painter, const QRectF &rect) const
qWarning("%s: error loading tile image", qPrintable(key)); qWarning("%s: error loading tile image", qPrintable(key));
else { else {
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
pixmap.setDevicePixelRatio(_ratio); pixmap.setDevicePixelRatio(_mapRatio);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height()); QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
painter->drawPixmap(tp, pixmap); painter->drawPixmap(tp, pixmap);
@ -307,23 +307,23 @@ QPointF OziMap::ll2xy(const Coordinates &c)
{ {
QPointF p(_transform.proj2img(_projection.ll2xy(c))); QPointF p(_transform.proj2img(_projection.ll2xy(c)));
return _ozf return _ozf
? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) / _ratio ? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) / _mapRatio
: p / _ratio; : p / _mapRatio;
} }
Coordinates OziMap::xy2ll(const QPointF &p) Coordinates OziMap::xy2ll(const QPointF &p)
{ {
return _ozf return _ozf
? _projection.xy2ll(_transform.img2proj(QPointF(p.x() / _scale.x(), ? _projection.xy2ll(_transform.img2proj(QPointF(p.x() / _scale.x(),
p.y() / _scale.y()) * _ratio)) p.y() / _scale.y()) * _mapRatio))
: _projection.xy2ll(_transform.img2proj(p * _ratio)); : _projection.xy2ll(_transform.img2proj(p * _mapRatio));
} }
QRectF OziMap::bounds() QRectF OziMap::bounds()
{ {
return _ozf return _ozf
? QRectF(QPointF(0, 0), _ozf->size(_zoom) / _ratio) ? QRectF(QPointF(0, 0), _ozf->size(_zoom) / _mapRatio)
: QRectF(QPointF(0, 0), _map.size / _ratio); : QRectF(QPointF(0, 0), _map.size / _mapRatio);
} }
int OziMap::zoomFit(const QSize &size, const RectC &rect) int OziMap::zoomFit(const QSize &size, const RectC &rect)
@ -371,9 +371,11 @@ void OziMap::rescale(int zoom)
_scale = _ozf->scale(zoom); _scale = _ozf->scale(zoom);
} }
void OziMap::setDevicePixelRatio(qreal ratio) void OziMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
{ {
_ratio = ratio; Q_UNUSED(deviceRatio);
_mapRatio = mapRatio;
if (_img) if (_img)
_img->setDevicePixelRatio(_ratio); _img->setDevicePixelRatio(_mapRatio);
} }

View File

@ -33,7 +33,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void load(); void load();
void unload(); void unload();
@ -43,9 +43,9 @@ public:
PointD ll2pp(const Coordinates &c) const PointD ll2pp(const Coordinates &c) const
{return _projection.ll2xy(c);} {return _projection.ll2xy(c);}
PointD xy2pp(const QPointF &p) const PointD xy2pp(const QPointF &p) const
{return _transform.img2proj(p * _ratio);} {return _transform.img2proj(p * _mapRatio);}
QPointF pp2xy(const PointD &p) const QPointF pp2xy(const PointD &p) const
{return _transform.proj2img(p) / _ratio;} {return _transform.proj2img(p) / _mapRatio;}
private: private:
struct ImageInfo { struct ImageInfo {
@ -73,7 +73,7 @@ private:
ImageInfo _map, _tile; ImageInfo _map, _tile;
int _zoom; int _zoom;
QPointF _scale; QPointF _scale;
qreal _ratio; qreal _mapRatio;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -104,7 +104,7 @@ bool WMSMap::loadWMS()
WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent) WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent)
: Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0), : Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0),
_ratio(1.0), _valid(false) _mapRatio(1.0), _valid(false)
{ {
_tileLoader = new TileLoader(tilesDir(), this); _tileLoader = new TileLoader(tilesDir(), this);
_tileLoader->setAuthorization(_setup.authorization()); _tileLoader->setAuthorization(_setup.authorization());
@ -124,8 +124,8 @@ void WMSMap::clearCache()
QRectF WMSMap::bounds() QRectF WMSMap::bounds()
{ {
return QRectF(_transform.proj2img(_bbox.topLeft()) / _ratio, return QRectF(_transform.proj2img(_bbox.topLeft()) / _mapRatio,
_transform.proj2img(_bbox.bottomRight()) / _ratio); _transform.proj2img(_bbox.bottomRight()) / _mapRatio);
} }
int WMSMap::zoomFit(const QSize &size, const RectC &rect) int WMSMap::zoomFit(const QSize &size, const RectC &rect)
@ -141,7 +141,7 @@ int WMSMap::zoomFit(const QSize &size, const RectC &rect)
_zoom = 0; _zoom = 0;
for (int i = 0; i < _zooms.size(); i++) { for (int i = 0; i < _zooms.size(); i++) {
if (sd2res(_zooms.at(i)) < resolution / _ratio) if (sd2res(_zooms.at(i)) < resolution / _mapRatio)
break; break;
_zoom = i; _zoom = i;
} }
@ -174,17 +174,17 @@ int WMSMap::zoomOut()
QPointF WMSMap::ll2xy(const Coordinates &c) QPointF WMSMap::ll2xy(const Coordinates &c)
{ {
return _transform.proj2img(_projection.ll2xy(c)) / _ratio; return _transform.proj2img(_projection.ll2xy(c)) / _mapRatio;
} }
Coordinates WMSMap::xy2ll(const QPointF &p) Coordinates WMSMap::xy2ll(const QPointF &p)
{ {
return _projection.xy2ll(_transform.img2proj(p * _ratio)); return _projection.xy2ll(_transform.img2proj(p * _mapRatio));
} }
qreal WMSMap::tileSize() const qreal WMSMap::tileSize() const
{ {
return (TILE_SIZE / _ratio); return (TILE_SIZE / _mapRatio);
} }
void WMSMap::draw(QPainter *painter, const QRectF &rect, Flags flags) void WMSMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
@ -220,7 +220,7 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QPointF tp(t.xy().x() * tileSize(), t.xy().y() * tileSize()); QPointF tp(t.xy().x() * tileSize(), t.xy().y() * tileSize());
if (!t.pixmap().isNull()) { if (!t.pixmap().isNull()) {
#ifdef ENABLE_HIDPI #ifdef ENABLE_HIDPI
t.pixmap().setDevicePixelRatio(_ratio); t.pixmap().setDevicePixelRatio(_mapRatio);
#endif // ENABLE_HIDPI #endif // ENABLE_HIDPI
painter->drawPixmap(tp, t.pixmap()); painter->drawPixmap(tp, t.pixmap());
} }

View File

@ -31,7 +31,8 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio) {_ratio = ratio;} void setDevicePixelRatio(qreal /*deviceRatio*/, qreal mapRatio)
{_mapRatio = mapRatio;}
void clearCache(); void clearCache();
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
@ -56,7 +57,7 @@ private:
QVector<double> _zooms; QVector<double> _zooms;
RectD _bbox; RectD _bbox;
int _zoom; int _zoom;
qreal _ratio; qreal _mapRatio;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -39,7 +39,7 @@ bool WMTSMap::loadWMTS()
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio, WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio,
QObject *parent) : Map(parent), _name(name), _setup(setup), _tileLoader(0), QObject *parent) : Map(parent), _name(name), _setup(setup), _tileLoader(0),
_zoom(0), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false) _zoom(0), _mapRatio(1.0), _tileRatio(tileRatio), _valid(false)
{ {
_tileLoader = new TileLoader(tilesDir(), this); _tileLoader = new TileLoader(tilesDir(), this);
_tileLoader->setAuthorization(_setup.authorization()); _tileLoader->setAuthorization(_setup.authorization());
@ -151,12 +151,12 @@ int WMTSMap::zoomOut()
qreal WMTSMap::coordinatesRatio() const qreal WMTSMap::coordinatesRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0; return _mapRatio > 1.0 ? _mapRatio / _tileRatio : 1.0;
} }
qreal WMTSMap::imageRatio() const qreal WMTSMap::imageRatio() const
{ {
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio; return _mapRatio > 1.0 ? _mapRatio : _tileRatio;
} }
QSizeF WMTSMap::tileSize(const WMTS::Zoom &zoom) const QSizeF WMTSMap::tileSize(const WMTS::Zoom &zoom) const

View File

@ -31,7 +31,8 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;} void setDevicePixelRatio(qreal /*deviceRatio*/, qreal mapRatio)
{_mapRatio = mapRatio;}
void clearCache(); void clearCache();
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
@ -55,7 +56,7 @@ private:
Transform _transform; Transform _transform;
CoordinateSystem _cs; CoordinateSystem _cs;
int _zoom; int _zoom;
qreal _deviceRatio, _tileRatio; qreal _mapRatio, _tileRatio;
bool _valid; bool _valid;
QString _errorString; QString _errorString;