mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-06-25 18:49:16 +02:00
Added HiDPI displays/maps support
This commit is contained in:
@ -49,10 +49,7 @@ void Atlas::computeZooms()
|
||||
|
||||
void Atlas::computeBounds()
|
||||
{
|
||||
QList<QPointF> offsets;
|
||||
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
offsets.append(QPointF());
|
||||
QVector<QPointF> offsets(_maps.count());
|
||||
|
||||
for (int z = 0; z < _zooms.count(); z++) {
|
||||
QList<OfflineMap*> m;
|
||||
@ -62,21 +59,22 @@ void Atlas::computeBounds()
|
||||
qSort(m.begin(), m.end(), xCmp);
|
||||
offsets[_maps.indexOf(m.first())].setX(0);
|
||||
for (int i = 1; i < m.size(); i++) {
|
||||
qreal w = round(m.first()->pp2xy(TL(m.at(i))).x());
|
||||
qreal w = m.first()->pp2xy(TL(m.at(i))).x();
|
||||
offsets[_maps.indexOf(m.at(i))].setX(w);
|
||||
}
|
||||
|
||||
qSort(m.begin(), m.end(), yCmp);
|
||||
offsets[_maps.indexOf(m.first())].setY(0);
|
||||
for (int i = 1; i < m.size(); i++) {
|
||||
qreal h = round(m.first()->pp2xy(TL(m.at(i))).y());
|
||||
qreal h = m.first()->pp2xy(TL(m.at(i))).y();
|
||||
offsets[_maps.indexOf(m.at(i))].setY(h);
|
||||
}
|
||||
}
|
||||
|
||||
_bounds = QVector<Bounds>(_maps.count());
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
_bounds.append(Bounds(RectD(TL(_maps.at(i)), BR(_maps.at(i))),
|
||||
QRectF(offsets.at(i), _maps.at(i)->bounds().size())));
|
||||
_bounds[i] = Bounds(RectD(TL(_maps.at(i)), BR(_maps.at(i))),
|
||||
QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
|
||||
}
|
||||
|
||||
Atlas::Atlas(const QString &fileName, QObject *parent)
|
||||
@ -147,6 +145,14 @@ Atlas::Atlas(const QString &fileName, QObject *parent)
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
void Atlas::setDevicePixelRatio(qreal ratio)
|
||||
{
|
||||
for (int i = 0; i < _maps.size(); i++)
|
||||
_maps[i]->setDevicePixelRatio(ratio);
|
||||
|
||||
computeBounds();
|
||||
}
|
||||
|
||||
QRectF Atlas::bounds()
|
||||
{
|
||||
QSizeF s(0, 0);
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio);
|
||||
void unload();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "rectd.h"
|
||||
#include "gcs.h"
|
||||
#include "pcs.h"
|
||||
#include "config.h"
|
||||
#include "jnxmap.h"
|
||||
|
||||
|
||||
@ -19,8 +20,10 @@ struct Level {
|
||||
struct Ctx {
|
||||
QPainter *painter;
|
||||
QFile *file;
|
||||
qreal ratio;
|
||||
|
||||
Ctx(QPainter *painter, QFile *file) : painter(painter), file(file) {}
|
||||
Ctx(QPainter *painter, QFile *file, qreal ratio)
|
||||
: painter(painter), file(file), ratio(ratio) {}
|
||||
};
|
||||
|
||||
|
||||
@ -139,7 +142,7 @@ bool JNXMap::readTiles()
|
||||
}
|
||||
|
||||
JNXMap::JNXMap(const QString &fileName, QObject *parent)
|
||||
: Map(parent), _file(fileName), _zoom(0), _valid(false)
|
||||
: Map(parent), _file(fileName), _zoom(0), _ratio(1.0), _valid(false)
|
||||
{
|
||||
_name = QFileInfo(fileName).fileName();
|
||||
|
||||
@ -159,13 +162,13 @@ JNXMap::JNXMap(const QString &fileName, QObject *parent)
|
||||
QPointF JNXMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
const Zoom &z = _zooms.at(_zoom);
|
||||
return z.transform.proj2img(_projection.ll2xy(c));
|
||||
return z.transform.proj2img(_projection.ll2xy(c)) / _ratio;
|
||||
}
|
||||
|
||||
Coordinates JNXMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
const Zoom &z = _zooms.at(_zoom);
|
||||
return _projection.xy2ll(z.transform.img2proj(p));
|
||||
return _projection.xy2ll(z.transform.img2proj(p * _ratio));
|
||||
}
|
||||
|
||||
QRectF JNXMap::bounds()
|
||||
@ -233,7 +236,11 @@ QPixmap JNXMap::pixmap(const Tile *tile, QFile *file)
|
||||
bool JNXMap::cb(Tile *tile, void *context)
|
||||
{
|
||||
Ctx *ctx = static_cast<Ctx*>(context);
|
||||
ctx->painter->drawPixmap(tile->pos, pixmap(tile, ctx->file));
|
||||
QPixmap pm(pixmap(tile, ctx->file));
|
||||
#ifdef ENABLE_HIDPI
|
||||
pm.setDevicePixelRatio(ctx->ratio);
|
||||
#endif // ENABLE_HIDPI
|
||||
ctx->painter->drawPixmap(tile->pos / ctx->ratio, pm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -242,12 +249,13 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
{
|
||||
Q_UNUSED(block);
|
||||
const RTree<Tile*, qreal, 2> &tree = _zooms.at(_zoom).tree;
|
||||
Ctx ctx(painter, &_file);
|
||||
Ctx ctx(painter, &_file, _ratio);
|
||||
QRectF rr(rect.topLeft() * _ratio, rect.size() * _ratio);
|
||||
|
||||
qreal min[2], max[2];
|
||||
min[0] = rect.left();
|
||||
min[1] = rect.top();
|
||||
max[0] = rect.right();
|
||||
max[1] = rect.bottom();
|
||||
min[0] = rr.left();
|
||||
min[1] = rr.top();
|
||||
max[0] = rr.right();
|
||||
max[1] = rr.bottom();
|
||||
tree.Search(min, max, cb, &ctx);
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
@ -61,6 +63,7 @@ private:
|
||||
int _zoom;
|
||||
RectC _bounds;
|
||||
Projection _projection;
|
||||
qreal _ratio;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
virtual void clearCache() {}
|
||||
virtual void load() {}
|
||||
virtual void unload() {}
|
||||
virtual void setDevicePixelRatio(qreal ratio) {Q_UNUSED(ratio);}
|
||||
|
||||
virtual bool isValid() const {return true;}
|
||||
virtual QString errorString() const {return QString();}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
MapSource::Config::Config() : type(OSM), zooms(ZOOM_MIN, ZOOM_MAX),
|
||||
bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP), Coordinates(BOUNDS_RIGHT,
|
||||
BOUNDS_BOTTOM)), format("image/png"), rest(false) {}
|
||||
BOUNDS_BOTTOM)), format("image/png"), rest(false), tileRatio(1.0) {}
|
||||
|
||||
|
||||
static CoordinateSystem coordinateSystem(QXmlStreamReader &reader)
|
||||
@ -159,6 +159,13 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
|
||||
attr.value("username").toString(),
|
||||
attr.value("password").toString());
|
||||
reader.skipCurrentElement();
|
||||
} else if (reader.name() == "tilePixelRatio") {
|
||||
bool res;
|
||||
qreal val = reader.readElementText().toDouble(&res);
|
||||
if (!res)
|
||||
reader.raiseError("Invalid tilePixelRatio");
|
||||
else
|
||||
config.tileRatio = val;
|
||||
} else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
@ -222,12 +229,13 @@ Map *MapSource::loadMap(const QString &path, QString &errorString)
|
||||
if (config.type == WMTS)
|
||||
return new WMTSMap(config.name, WMTS::Setup(config.url, config.layer,
|
||||
config.set, config.style, config.format, config.rest,
|
||||
config.coordinateSystem, config.dimensions, config.authorization));
|
||||
config.coordinateSystem, config.dimensions, config.authorization),
|
||||
config.tileRatio);
|
||||
else if (config.type == WMS)
|
||||
return new WMSMap(config.name, WMS::Setup(config.url, config.layer,
|
||||
config.style, config.format, config.crs, config.coordinateSystem,
|
||||
config.dimensions, config.authorization));
|
||||
else
|
||||
return new OnlineMap(config.name, config.url, config.zooms,
|
||||
config.bounds, config.authorization);
|
||||
config.bounds, config.tileRatio, config.authorization);
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ private:
|
||||
bool rest;
|
||||
QList<QPair<QString, QString> > dimensions;
|
||||
Authorization authorization;
|
||||
qreal tileRatio;
|
||||
|
||||
Config();
|
||||
};
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "ozf.h"
|
||||
#include "mapfile.h"
|
||||
#include "geotiff.h"
|
||||
#include "config.h"
|
||||
#include "offlinemap.h"
|
||||
|
||||
|
||||
@ -94,7 +95,7 @@ bool OfflineMap::setTileInfo(const QStringList &tiles, const QString &path)
|
||||
}
|
||||
|
||||
OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
|
||||
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false)
|
||||
{
|
||||
QFileInfo fi(fileName);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
@ -172,7 +173,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
}
|
||||
|
||||
OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
|
||||
: Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false)
|
||||
{
|
||||
QFileInfo fi(fileName);
|
||||
QFileInfo map(fi.absolutePath());
|
||||
@ -224,8 +225,13 @@ void OfflineMap::load()
|
||||
|
||||
if (!_ozf && !_img && _map.isValid()) {
|
||||
_img = new QImage(_map.path);
|
||||
if (_img->isNull())
|
||||
if (!_img || _img->isNull()) {
|
||||
qWarning("%s: error loading map image", qPrintable(_map.path));
|
||||
return;
|
||||
}
|
||||
#ifdef ENABLE_HIDPI
|
||||
_img->setDevicePixelRatio(_ratio);
|
||||
#endif // ENABLE_HIDPI
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,15 +243,15 @@ void OfflineMap::unload()
|
||||
|
||||
void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const
|
||||
{
|
||||
QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tile.size.width())
|
||||
* _tile.size.width(), (int)floor(rect.top() / _tile.size.height())
|
||||
* _tile.size.height());
|
||||
QSizeF ts(_tile.size.width() / _ratio, _tile.size.height() / _ratio);
|
||||
QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
|
||||
floor(rect.top() / ts.height()) * ts.height());
|
||||
|
||||
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
|
||||
for (int i = 0; i < ceil(s.width() / _tile.size.width()); i++) {
|
||||
for (int j = 0; j < ceil(s.height() / _tile.size.height()); j++) {
|
||||
int x = tl.x() + i * _tile.size.width();
|
||||
int y = tl.y() + j * _tile.size.height();
|
||||
for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
|
||||
for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
|
||||
int x = round(tl.x() * _ratio + i * _tile.size.width());
|
||||
int y = round(tl.y() * _ratio + j * _tile.size.height());
|
||||
|
||||
QString tileName(_tile.path.arg(QString::number(x),
|
||||
QString::number(y)));
|
||||
@ -265,23 +271,29 @@ void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const
|
||||
if (pixmap.isNull())
|
||||
qWarning("%s: error loading tile image", qPrintable(
|
||||
_tile.path.arg(QString::number(x), QString::number(y))));
|
||||
else
|
||||
painter->drawPixmap(QPoint(x, y), pixmap);
|
||||
else {
|
||||
#ifdef ENABLE_HIDPI
|
||||
pixmap.setDevicePixelRatio(_ratio);
|
||||
#endif // ENABLE_HIDPI
|
||||
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
|
||||
painter->drawPixmap(tp, pixmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const
|
||||
{
|
||||
QPoint tl = QPoint((int)floor(rect.left() / _ozf->tileSize().width())
|
||||
* _ozf->tileSize().width(), (int)floor(rect.top()
|
||||
/ _ozf->tileSize().height()) * _ozf->tileSize().height());
|
||||
QSizeF ts(_ozf->tileSize().width() / _ratio, _ozf->tileSize().height()
|
||||
/ _ratio);
|
||||
QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
|
||||
floor(rect.top() / ts.height()) * ts.height());
|
||||
|
||||
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
|
||||
for (int i = 0; i < ceil(s.width() / _ozf->tileSize().width()); i++) {
|
||||
for (int j = 0; j < ceil(s.height() / _ozf->tileSize().height()); j++) {
|
||||
int x = tl.x() + i * _ozf->tileSize().width();
|
||||
int y = tl.y() + j * _ozf->tileSize().height();
|
||||
for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
|
||||
for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
|
||||
int x = round(tl.x() * _ratio + i * _ozf->tileSize().width());
|
||||
int y = round(tl.y() * _ratio + j * _ozf->tileSize().height());
|
||||
|
||||
QPixmap pixmap;
|
||||
QString key = _ozf->fileName() + "/" + QString::number(_zoom) + "_"
|
||||
@ -294,17 +306,21 @@ void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const
|
||||
|
||||
if (pixmap.isNull())
|
||||
qWarning("%s: error loading tile image", qPrintable(key));
|
||||
else
|
||||
painter->drawPixmap(QPoint(x, y), pixmap);
|
||||
else {
|
||||
#ifdef ENABLE_HIDPI
|
||||
pixmap.setDevicePixelRatio(_ratio);
|
||||
#endif // ENABLE_HIDPI
|
||||
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
|
||||
painter->drawPixmap(tp, pixmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OfflineMap::drawImage(QPainter *painter, const QRectF &rect) const
|
||||
{
|
||||
QRect r(rect.toRect());
|
||||
painter->drawImage(r.left(), r.top(), *_img, r.left(), r.top(),
|
||||
r.width(), r.height());
|
||||
painter->drawImage(rect.topLeft(), *_img, QRectF(rect.topLeft() * _ratio,
|
||||
rect.size() * _ratio));
|
||||
}
|
||||
|
||||
void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
@ -322,22 +338,24 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
QPointF p(_transform.proj2img(_projection.ll2xy(c)));
|
||||
return _ozf ? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) : p;
|
||||
return _ozf
|
||||
? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) / _ratio
|
||||
: p / _ratio;
|
||||
}
|
||||
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
return _ozf
|
||||
? _projection.xy2ll(_transform.img2proj(QPointF(p.x() / _scale.x(),
|
||||
p.y() / _scale.y())))
|
||||
: _projection.xy2ll(_transform.img2proj(p));
|
||||
p.y() / _scale.y()) * _ratio))
|
||||
: _projection.xy2ll(_transform.img2proj(p * _ratio));
|
||||
}
|
||||
|
||||
QRectF OfflineMap::bounds()
|
||||
{
|
||||
return _ozf
|
||||
? QRectF(QPointF(0, 0), _ozf->size(_zoom))
|
||||
: QRectF(QPointF(0, 0), _map.size);
|
||||
? QRectF(QPointF(0, 0), _ozf->size(_zoom) / _ratio)
|
||||
: QRectF(QPointF(0, 0), _map.size / _ratio);
|
||||
}
|
||||
|
||||
int OfflineMap::zoomFit(const QSize &size, const RectC &rect)
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
|
||||
void load();
|
||||
void unload();
|
||||
|
||||
@ -42,9 +43,9 @@ public:
|
||||
PointD ll2pp(const Coordinates &c) const
|
||||
{return _projection.ll2xy(c);}
|
||||
PointD xy2pp(const QPointF &p) const
|
||||
{return _transform.img2proj(p);}
|
||||
{return _transform.img2proj(p * _ratio);}
|
||||
QPointF pp2xy(const PointD &p) const
|
||||
{return _transform.proj2img(p);}
|
||||
{return _transform.proj2img(p) / _ratio;}
|
||||
|
||||
private:
|
||||
struct ImageInfo {
|
||||
@ -72,6 +73,7 @@ private:
|
||||
ImageInfo _map, _tile;
|
||||
int _zoom;
|
||||
QPointF _scale;
|
||||
qreal _ratio;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
@ -42,14 +42,13 @@ static int scale2zoom(qreal scale)
|
||||
|
||||
|
||||
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||
const Range &zooms, const RectC &bounds, const Authorization &authorization,
|
||||
QObject *parent) : Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
|
||||
_valid(false)
|
||||
const Range &zooms, const RectC &bounds, qreal tileRatio,
|
||||
const Authorization &authorization, QObject *parent)
|
||||
: Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
|
||||
_zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false)
|
||||
{
|
||||
QString dir(TILES_DIR + "/" + _name);
|
||||
|
||||
_zoom = _zooms.max();
|
||||
|
||||
_tileLoader = new TileLoader(this);
|
||||
_tileLoader->setUrl(url);
|
||||
_tileLoader->setDir(dir);
|
||||
@ -86,7 +85,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
|
||||
else {
|
||||
QRectF tbr(ll2m(rect.topLeft()), ll2m(rect.bottomRight()));
|
||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||
_zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y())));
|
||||
_zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y()) / coordinatesRatio()));
|
||||
}
|
||||
|
||||
return _zoom;
|
||||
@ -112,19 +111,34 @@ int OnlineMap::zoomOut()
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal OnlineMap::coordinatesRatio() const
|
||||
{
|
||||
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
|
||||
}
|
||||
|
||||
qreal OnlineMap::imageRatio() const
|
||||
{
|
||||
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio;
|
||||
}
|
||||
|
||||
qreal OnlineMap::tileSize() const
|
||||
{
|
||||
return (TILE_SIZE / coordinatesRatio());
|
||||
}
|
||||
|
||||
void OnlineMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
|
||||
QPoint tile = mercator2tile(QPointF(rect.topLeft().x() * scale,
|
||||
-rect.topLeft().y() * scale), _zoom);
|
||||
QPoint tl = QPoint((int)floor(rect.left() / (qreal)TILE_SIZE)
|
||||
* TILE_SIZE, (int)floor(rect.top() / TILE_SIZE) * TILE_SIZE);
|
||||
-rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
|
||||
QPointF tl(floor(rect.left() / tileSize())
|
||||
* tileSize(), floor(rect.top() / tileSize()) * tileSize());
|
||||
|
||||
QList<Tile> tiles;
|
||||
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
|
||||
for (int i = 0; i < ceil(s.width() / TILE_SIZE); i++)
|
||||
for (int j = 0; j < ceil(s.height() / TILE_SIZE); j++)
|
||||
for (int i = 0; i < ceil(s.width() / tileSize()); i++)
|
||||
for (int j = 0; j < ceil(s.height() / tileSize()); j++)
|
||||
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
|
||||
|
||||
if (block)
|
||||
@ -134,10 +148,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
|
||||
for (int i = 0; i < tiles.count(); i++) {
|
||||
Tile &t = tiles[i];
|
||||
QPoint tp(tl.x() + (t.xy().x() - tile.x()) * TILE_SIZE,
|
||||
tl.y() + (t.xy().y() - tile.y()) * TILE_SIZE);
|
||||
if (!t.pixmap().isNull())
|
||||
QPointF tp(tl.x() + (t.xy().x() - tile.x()) * tileSize(),
|
||||
tl.y() + (t.xy().y() - tile.y()) * tileSize());
|
||||
if (!t.pixmap().isNull()) {
|
||||
#ifdef ENABLE_HIDPI
|
||||
t.pixmap().setDevicePixelRatio(imageRatio());
|
||||
#endif // ENABLE_HIDPI
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,11 +163,11 @@ QPointF OnlineMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
QPointF m = ll2m(c);
|
||||
return QPointF(m.x() / scale, m.y() / -scale);
|
||||
return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio();
|
||||
}
|
||||
|
||||
Coordinates OnlineMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
qreal scale = zoom2scale(_zoom);
|
||||
return m2ll(QPointF(p.x() * scale, -p.y() * scale));
|
||||
return m2ll(QPointF(p.x() * scale, -p.y() * scale) * coordinatesRatio());
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class OnlineMap : public Map
|
||||
|
||||
public:
|
||||
OnlineMap(const QString &name, const QString &url, const Range &zooms,
|
||||
const RectC &bounds, const Authorization &authorization,
|
||||
const RectC &bounds, qreal tileRatio, const Authorization &authorization,
|
||||
QObject *parent = 0);
|
||||
|
||||
QString name() const {return _name;}
|
||||
@ -31,6 +31,7 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
|
||||
void clearCache() {_tileLoader->clearCache();}
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
@ -38,12 +39,16 @@ public:
|
||||
|
||||
private:
|
||||
int limitZoom(int zoom) const;
|
||||
qreal tileSize() const;
|
||||
qreal coordinatesRatio() const;
|
||||
qreal imageRatio() const;
|
||||
|
||||
TileLoader *_tileLoader;
|
||||
QString _name;
|
||||
Range _zooms;
|
||||
RectC _bounds;
|
||||
int _zoom;
|
||||
qreal _deviceRatio, _tileRatio;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
@ -103,7 +103,7 @@ bool WMSMap::loadWMS()
|
||||
|
||||
WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent)
|
||||
: Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0),
|
||||
_valid(false)
|
||||
_ratio(1.0), _valid(false)
|
||||
{
|
||||
if (!QDir().mkpath(tilesDir())) {
|
||||
_errorString = "Error creating tiles dir";
|
||||
@ -129,8 +129,8 @@ void WMSMap::clearCache()
|
||||
|
||||
QRectF WMSMap::bounds()
|
||||
{
|
||||
return QRectF(_transform.proj2img(_bbox.topLeft()),
|
||||
_transform.proj2img(_bbox.bottomRight()));
|
||||
return QRectF(_transform.proj2img(_bbox.topLeft()) / _ratio,
|
||||
_transform.proj2img(_bbox.bottomRight()) / _ratio);
|
||||
}
|
||||
|
||||
int WMSMap::zoomFit(const QSize &size, const RectC &rect)
|
||||
@ -146,7 +146,7 @@ int WMSMap::zoomFit(const QSize &size, const RectC &rect)
|
||||
|
||||
_zoom = 0;
|
||||
for (int i = 0; i < _zooms.size(); i++) {
|
||||
if (sd2res(_zooms.at(i)) < resolution)
|
||||
if (sd2res(_zooms.at(i)) < resolution / _ratio)
|
||||
break;
|
||||
_zoom = i;
|
||||
}
|
||||
@ -179,20 +179,25 @@ int WMSMap::zoomOut()
|
||||
|
||||
QPointF WMSMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
return _transform.proj2img(_projection.ll2xy(c));
|
||||
return _transform.proj2img(_projection.ll2xy(c)) / _ratio;
|
||||
}
|
||||
|
||||
Coordinates WMSMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
return _projection.xy2ll(_transform.img2proj(p));
|
||||
return _projection.xy2ll(_transform.img2proj(p * _ratio));
|
||||
}
|
||||
|
||||
qreal WMSMap::tileSize() const
|
||||
{
|
||||
return (TILE_SIZE / _ratio);
|
||||
}
|
||||
|
||||
void WMSMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
{
|
||||
QPoint tl = QPoint((int)floor(rect.left() / (qreal)TILE_SIZE),
|
||||
(int)floor(rect.top() / (qreal)TILE_SIZE));
|
||||
QPoint br = QPoint((int)ceil(rect.right() / (qreal)TILE_SIZE),
|
||||
(int)ceil(rect.bottom() / (qreal)TILE_SIZE));
|
||||
QPoint tl = QPoint((int)floor(rect.left() / tileSize()),
|
||||
(int)floor(rect.top() / tileSize()));
|
||||
QPoint br = QPoint((int)ceil(rect.right() / tileSize()),
|
||||
(int)ceil(rect.bottom() / tileSize()));
|
||||
|
||||
QList<Tile> tiles;
|
||||
for (int i = tl.x(); i < br.x(); i++) {
|
||||
@ -216,8 +221,12 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
|
||||
for (int i = 0; i < tiles.count(); i++) {
|
||||
Tile &t = tiles[i];
|
||||
QPoint tp(t.xy().x() * TILE_SIZE, t.xy().y() * TILE_SIZE);
|
||||
if (!t.pixmap().isNull())
|
||||
QPointF tp(t.xy().x() * tileSize(), t.xy().y() * tileSize());
|
||||
if (!t.pixmap().isNull()) {
|
||||
#ifdef ENABLE_HIDPI
|
||||
t.pixmap().setDevicePixelRatio(_ratio);
|
||||
#endif // ENABLE_HIDPI
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
|
||||
void clearCache();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
@ -43,6 +44,7 @@ private:
|
||||
void computeZooms(const RangeF &scaleDenominator);
|
||||
void updateTransform();
|
||||
bool loadWMS();
|
||||
qreal tileSize() const;
|
||||
|
||||
QString _name;
|
||||
|
||||
@ -54,6 +56,7 @@ private:
|
||||
QVector<double> _zooms;
|
||||
RectD _bbox;
|
||||
int _zoom;
|
||||
qreal _ratio;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
@ -35,9 +35,9 @@ bool WMTSMap::loadWMTS()
|
||||
return true;
|
||||
}
|
||||
|
||||
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent)
|
||||
: Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0),
|
||||
_valid(false)
|
||||
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio,
|
||||
QObject *parent) : Map(parent), _name(name), _setup(setup), _tileLoader(0),
|
||||
_zoom(0), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false)
|
||||
{
|
||||
if (!QDir().mkpath(tilesDir())) {
|
||||
_errorString = "Error creating tiles dir";
|
||||
@ -105,7 +105,6 @@ QRectF WMTSMap::bounds()
|
||||
|
||||
bounds = _bounds.isValid() ? QRectF(ll2xy(_bounds.topLeft()),
|
||||
ll2xy(_bounds.bottomRight())) : QRectF();
|
||||
|
||||
return _bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
|
||||
}
|
||||
|
||||
@ -122,7 +121,8 @@ int WMTSMap::zoomFit(const QSize &size, const RectC &rect)
|
||||
|
||||
_zoom = 0;
|
||||
for (int i = 0; i < _zooms.size(); i++) {
|
||||
if (sd2res(_zooms.at(i).scaleDenominator()) < resolution)
|
||||
if (sd2res(_zooms.at(i).scaleDenominator()) < resolution
|
||||
/ coordinatesRatio())
|
||||
break;
|
||||
_zoom = i;
|
||||
}
|
||||
@ -153,13 +153,31 @@ int WMTSMap::zoomOut()
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
qreal WMTSMap::coordinatesRatio() const
|
||||
{
|
||||
return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
|
||||
}
|
||||
|
||||
qreal WMTSMap::imageRatio() const
|
||||
{
|
||||
return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio;
|
||||
}
|
||||
|
||||
QSizeF WMTSMap::tileSize(const WMTS::Zoom &zoom) const
|
||||
{
|
||||
return QSizeF(zoom.tile().width() / coordinatesRatio(),
|
||||
zoom.tile().height() / coordinatesRatio());
|
||||
}
|
||||
|
||||
void WMTSMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
{
|
||||
const WMTS::Zoom &z = _zooms.at(_zoom);
|
||||
QPoint tl = QPoint((int)floor(rect.left() / (qreal)z.tile().width()),
|
||||
(int)floor(rect.top() / (qreal)z.tile().height()));
|
||||
QPoint br = QPoint((int)ceil(rect.right() / (qreal)z.tile().width()),
|
||||
(int)ceil(rect.bottom() / (qreal)z.tile().height()));
|
||||
QSizeF ts(tileSize(z));
|
||||
|
||||
QPoint tl = QPoint((int)floor(rect.left() / ts.width()),
|
||||
(int)floor(rect.top() / ts.height()));
|
||||
QPoint br = QPoint((int)ceil(rect.right() / ts.width()),
|
||||
(int)ceil(rect.bottom() / ts.height()));
|
||||
|
||||
QList<Tile> tiles;
|
||||
for (int i = tl.x(); i < br.x(); i++)
|
||||
@ -173,18 +191,22 @@ void WMTSMap::draw(QPainter *painter, const QRectF &rect, bool block)
|
||||
|
||||
for (int i = 0; i < tiles.count(); i++) {
|
||||
Tile &t = tiles[i];
|
||||
QPoint tp(t.xy().x() * z.tile().width(), t.xy().y() * z.tile().height());
|
||||
if (!t.pixmap().isNull())
|
||||
QPointF tp(t.xy().x() * ts.width(), t.xy().y() * ts.height());
|
||||
if (!t.pixmap().isNull()) {
|
||||
#ifdef ENABLE_HIDPI
|
||||
t.pixmap().setDevicePixelRatio(imageRatio());
|
||||
#endif // ENABLE_HIDPI
|
||||
painter->drawPixmap(tp, t.pixmap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPointF WMTSMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
return _transform.proj2img(_projection.ll2xy(c));
|
||||
return _transform.proj2img(_projection.ll2xy(c)) / coordinatesRatio();
|
||||
}
|
||||
|
||||
Coordinates WMTSMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
return _projection.xy2ll(_transform.img2proj(p));
|
||||
return _projection.xy2ll(_transform.img2proj(p * coordinatesRatio()));
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ class WMTSMap : public Map
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent = 0);
|
||||
WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio,
|
||||
QObject *parent = 0);
|
||||
|
||||
QString name() const {return _name;}
|
||||
|
||||
@ -30,6 +31,7 @@ public:
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, bool block);
|
||||
|
||||
void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
|
||||
void clearCache();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
@ -40,6 +42,9 @@ private:
|
||||
double sd2res(double scaleDenominator) const;
|
||||
QString tilesDir() const;
|
||||
void updateTransform();
|
||||
QSizeF tileSize(const WMTS::Zoom &zoom) const;
|
||||
qreal coordinatesRatio() const;
|
||||
qreal imageRatio() const;
|
||||
|
||||
QString _name;
|
||||
WMTS::Setup _setup;
|
||||
@ -50,6 +55,7 @@ private:
|
||||
Transform _transform;
|
||||
CoordinateSystem _cs;
|
||||
int _zoom;
|
||||
qreal _deviceRatio, _tileRatio;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
|
Reference in New Issue
Block a user