diff --git a/src/map/mapsource.cpp b/src/map/mapsource.cpp index 050f5f6b..d451cfef 100644 --- a/src/map/mapsource.cpp +++ b/src/map/mapsource.cpp @@ -160,6 +160,8 @@ void MapSource::map(QXmlStreamReader &reader, Config &config) config.type = WMS; else if (type == "TMS") config.type = TMS; + else if (type == "QuadTiles") + config.type = QuadTiles; else if (type == "OSM" || type.isEmpty()) config.type = OSM; else { @@ -293,11 +295,15 @@ Map *MapSource::loadMap(const QString &path, QString &errorString) case TMS: return new OnlineMap(config.name, config.url, config.zooms, config.bounds, config.tileRatio, config.authorization, - config.tileSize, config.scalable, true); + config.tileSize, config.scalable, true, false); case OSM: return new OnlineMap(config.name, config.url, config.zooms, config.bounds, config.tileRatio, config.authorization, - config.tileSize, config.scalable, false); + config.tileSize, config.scalable, false, false); + case QuadTiles: + return new OnlineMap(config.name, config.url, config.zooms, + config.bounds, config.tileRatio, config.authorization, + config.tileSize, config.scalable, false, true); default: return 0; } diff --git a/src/map/mapsource.h b/src/map/mapsource.h index dad06412..5a0b9d25 100644 --- a/src/map/mapsource.h +++ b/src/map/mapsource.h @@ -21,7 +21,8 @@ private: OSM, WMTS, WMS, - TMS + TMS, + QuadTiles }; struct Config { diff --git a/src/map/onlinemap.cpp b/src/map/onlinemap.cpp index 968d890b..138d8c86 100644 --- a/src/map/onlinemap.cpp +++ b/src/map/onlinemap.cpp @@ -11,15 +11,16 @@ OnlineMap::OnlineMap(const QString &name, const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio, const Authorization &authorization, int tileSize, bool scalable, bool invertY, - QObject *parent) + bool quadTiles, QObject *parent) : Map(parent), _name(name), _zooms(zooms), _bounds(bounds), _zoom(_zooms.max()), _mapRatio(1.0), _tileRatio(tileRatio), - _tileSize(tileSize), _scalable(scalable), _invertY(invertY), _scaledSize(0) + _tileSize(tileSize), _scalable(scalable), _invertY(invertY) { _tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name), this); _tileLoader->setUrl(url); _tileLoader->setAuthorization(authorization); + _tileLoader->setQuadTiles(quadTiles); connect(_tileLoader, SIGNAL(finished()), this, SIGNAL(loaded())); } @@ -74,7 +75,7 @@ void OnlineMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio) _mapRatio = mapRatio; if (_scalable) { - _scaledSize = _tileSize * deviceRatio; + _tileLoader->setScaledSize(_tileSize * deviceRatio); _tileRatio = deviceRatio; } } @@ -112,7 +113,7 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags) for (int i = 0; i < width; i++) for (int j = 0; j < height; j++) tiles.append(Tile(QPoint(tile.x() + i, _invertY ? (1<<_zoom) - - (tile.y() + j) - 1 : tile.y() + j), _zoom, _scaledSize)); + - (tile.y() + j) - 1 : tile.y() + j), _zoom)); if (flags & Map::Block) _tileLoader->loadTilesSync(tiles); diff --git a/src/map/onlinemap.h b/src/map/onlinemap.h index 01df9aca..b4c947db 100644 --- a/src/map/onlinemap.h +++ b/src/map/onlinemap.h @@ -13,7 +13,8 @@ class OnlineMap : public Map public: OnlineMap(const QString &name, const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio, const Authorization &authorization, - int tileSize, bool scalable, bool invertY, QObject *parent = 0); + int tileSize, bool scalable, bool invertY, bool quadTiles, + QObject *parent = 0); QString name() const {return _name;} @@ -49,7 +50,6 @@ private: int _tileSize; bool _scalable; bool _invertY; - int _scaledSize; }; #endif // ONLINEMAP_H diff --git a/src/map/tile.h b/src/map/tile.h index ce365b44..39b484cd 100644 --- a/src/map/tile.h +++ b/src/map/tile.h @@ -10,21 +10,18 @@ class Tile { public: - Tile() : _scaledSize(0) {} - Tile(const QPoint &xy, const QVariant &zoom, int scaledSize = 0, - const RectD &bbox = RectD()) : _xy(xy), _zoom(zoom), - _scaledSize(scaledSize), _bbox(bbox) {} + Tile() {} + Tile(const QPoint &xy, const QVariant &zoom, const RectD &bbox = RectD()) + : _xy(xy), _zoom(zoom), _bbox(bbox) {} const QVariant &zoom() const {return _zoom;} const QPoint &xy() const {return _xy;} const RectD &bbox() const {return _bbox;} - int scaledSize() const {return _scaledSize;} QPixmap& pixmap() {return _pixmap;} private: QPoint _xy; QVariant _zoom; - int _scaledSize; RectD _bbox; QPixmap _pixmap; }; diff --git a/src/map/tileloader.cpp b/src/map/tileloader.cpp index ec727080..981910ad 100644 --- a/src/map/tileloader.cpp +++ b/src/map/tileloader.cpp @@ -14,9 +14,9 @@ class TileImage { public: - TileImage() : _tile(0) {} - TileImage(const QString &file, Tile *tile) - : _file(file), _tile(tile) {} + TileImage() : _tile(0), _scaledSize(0) {} + TileImage(const QString &file, Tile *tile, int scaledSize) + : _file(file), _tile(tile), _scaledSize(scaledSize) {} void createPixmap() { @@ -26,8 +26,8 @@ public: { QByteArray z(_tile->zoom().toString().toLatin1()); QImageReader reader(_file, z); - if (_tile->scaledSize()) - reader.setScaledSize(QSize(_tile->scaledSize(), _tile->scaledSize())); + if (_scaledSize) + reader.setScaledSize(QSize(_scaledSize, _scaledSize)); reader.read(&_image); } @@ -37,6 +37,7 @@ public: private: QString _file; Tile *_tile; + int _scaledSize; QImage _image; }; @@ -45,8 +46,27 @@ static void render(TileImage &ti) ti.load(); } +static QString quadKey(const QPoint &xy, int zoom) +{ + QString qk; + + for (int i = zoom; i > 0; i--) { + char digit = '0'; + unsigned mask = 1 << (i - 1); + if (xy.x() & mask) + digit++; + if (xy.y() & mask) { + digit++; + digit++; + } + qk.append(digit); + } + + return qk; +} + TileLoader::TileLoader(const QString &dir, QObject *parent) - : QObject(parent), _dir(dir) + : QObject(parent), _dir(dir), _scaledSize(0), _quadTiles(false) { if (!QDir().mkpath(_dir)) qWarning("%s: %s", qPrintable(_dir), "Error creating tiles directory"); @@ -70,11 +90,11 @@ void TileLoader::loadTilesAsync(QVector &list) QFileInfo fi(file); if (fi.exists()) - imgs.append(TileImage(file, &t)); + imgs.append(TileImage(file, &t, _scaledSize)); else { QUrl url(tileUrl(t)); if (url.isLocalFile()) - imgs.append(TileImage(url.toLocalFile(), &t)); + imgs.append(TileImage(url.toLocalFile(), &t, _scaledSize)); else dl.append(Download(url, file)); } @@ -109,11 +129,11 @@ void TileLoader::loadTilesSync(QVector &list) QFileInfo fi(file); if (fi.exists()) - imgs.append(TileImage(file, &t)); + imgs.append(TileImage(file, &t, _scaledSize)); else { QUrl url(tileUrl(t)); if (url.isLocalFile()) - imgs.append(TileImage(url.toLocalFile(), &t)); + imgs.append(TileImage(url.toLocalFile(), &t, _scaledSize)); else { dl.append(Download(url, file)); tl.append(&t); @@ -131,7 +151,7 @@ void TileLoader::loadTilesSync(QVector &list) Tile *t = tl[i]; QString file = tileFile(*t); if (QFileInfo(file).exists()) - imgs.append(TileImage(file, t)); + imgs.append(TileImage(file, t, _scaledSize)); } } @@ -164,6 +184,8 @@ QUrl TileLoader::tileUrl(const Tile &tile) const QString::number(tile.bbox().right(), 'f', 6), QString::number(tile.bbox().top(), 'f', 6)); url.replace("$bbox", bbox); + } else if (_quadTiles) { + url.replace("$quadkey", quadKey(tile.xy(), tile.zoom().toInt())); } else { url.replace("$z", tile.zoom().toString()); url.replace("$x", QString::number(tile.xy().x())); diff --git a/src/map/tileloader.h b/src/map/tileloader.h index 5365e393..ee2bd71a 100644 --- a/src/map/tileloader.h +++ b/src/map/tileloader.h @@ -16,6 +16,8 @@ public: void setUrl(const QString &url) {_url = url;} void setAuthorization(const Authorization &authorization) {_authorization = authorization;} + void setScaledSize(int size) {_scaledSize = size;} + void setQuadTiles(bool quadTiles) {_quadTiles = quadTiles;} void loadTilesAsync(QVector &list); void loadTilesSync(QVector &list); @@ -32,6 +34,8 @@ private: QString _url; QString _dir; Authorization _authorization; + int _scaledSize; + bool _quadTiles; }; #endif // TILELOADER_Honlinemap diff --git a/src/map/wmsmap.cpp b/src/map/wmsmap.cpp index e75348b0..7261fecf 100644 --- a/src/map/wmsmap.cpp +++ b/src/map/wmsmap.cpp @@ -200,7 +200,7 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, Flags flags) ? RectD(PointD(tbr.y(), tbr.x()), PointD(ttl.y(), ttl.x())) : RectD(ttl, tbr); - tiles.append(Tile(QPoint(i, j), _zoom, 0, bbox)); + tiles.append(Tile(QPoint(i, j), _zoom, bbox)); } }