From 4b8a7a47797fc9bd6af6baf9e7b8723b9dcaf5bc Mon Sep 17 00:00:00 2001 From: peri4 Date: Fri, 20 Jan 2023 23:28:08 +0300 Subject: [PATCH] MapView scale less detailed levels on current level feature --- libs/map/mapview.cpp | 21 +++++++++++++++++---- libs/map/mapview.h | 1 + libs/map/osm_tile_cache.cpp | 28 ++++++++++++++++++++++++++-- libs/map/osm_tile_cache_p.h | 3 ++- utils/mapviewer/main.cpp | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/libs/map/mapview.cpp b/libs/map/mapview.cpp index dc2d9e2..33e1b1f 100644 --- a/libs/map/mapview.cpp +++ b/libs/map/mapview.cpp @@ -66,6 +66,7 @@ QPointF MapView::center() const { void MapView::setCenter(QPointF c) { center_ = OSM::geo2xy(c); + checkCenter(); updateViewRect(); drawBackground(); } @@ -100,6 +101,7 @@ void MapView::mouseMoveEvent(QMouseEvent * e) { if (is_pan) { double mins = qMin(width(), height()); center_ -= QPointF(e->pos() - press_point) / scale_ / mins; + checkCenter(); press_point = e->pos(); updateViewRect(); drawBackground(); @@ -133,7 +135,7 @@ void MapView::paintEvent(QPaintEvent *) { void MapView::resizeEvent(QResizeEvent *) { - cache->setMinimumCacheSize((width() + tileSize) * (height() + tileSize) * 4); + cache->setMinimumCacheSize((width() + tileSize) * (height() + tileSize) * 4 * 3); checkZoom(); updateZoomLevel(); updateViewRect(); @@ -158,9 +160,10 @@ void MapView::drawBackground() { for (int iy = sy; iy < ey; ++iy) { QRectF r((ix)*ts, (iy)*ts, ts, ts); r.translate(-offset); - auto tile = cache->getTile((OSM::TileIndex){zoom_level, ix, iy}); + QRectF px_rct(QPointF(), QSizeF(tileSize, tileSize)); + auto tile = cache->getTile((OSM::TileIndex){zoom_level, ix, iy}, px_rct); if (!tile.isEmpty()) { - p.drawPixmap(r, tile.pixmap, QRectF(tile.pixmap.rect())); + p.drawPixmap(r, tile.pixmap, px_rct); } else { p.fillRect(r, brush_tr); } @@ -212,6 +215,14 @@ void MapView::checkZoom() { } +void MapView::checkCenter() { + if (center_.x() < 0.) center_.setX(0.); + if (center_.x() > 1.) center_.setX(1.); + if (center_.y() < 0.) center_.setY(0.); + if (center_.y() > 1.) center_.setY(1.); +} + + void MapView::zoomLevelChanged(int new_level) { zoom_level = qBound(0, new_level, max_level); // qDebug() << "level changed" << new_level << zoom_level; @@ -296,7 +307,8 @@ void MapView::zoom(double factor, QPoint anchor) { checkZoom(); QPointF new_center = mapToNorm(anchor); center_ += prev_center - new_center; - view_rect.translate(prev_center - new_center); + checkCenter(); + view_rect.moveCenter(center_); updateZoomLevel(); drawBackground(); } @@ -312,6 +324,7 @@ void MapView::zoomTo(double level) { void MapView::centerTo(QPointF coord) { center_ = OSM::geo2xy(coord); + checkCenter(); updateViewRect(); drawBackground(); } diff --git a/libs/map/mapview.h b/libs/map/mapview.h index b3e68e8..d68b4ac 100644 --- a/libs/map/mapview.h +++ b/libs/map/mapview.h @@ -64,6 +64,7 @@ private: void drawBackground(); void drawItems(QPainter & p); void checkZoom(); + void checkCenter(); void zoomLevelChanged(int new_level); void updateZoomLevel(); void updateViewRect(); diff --git a/libs/map/osm_tile_cache.cpp b/libs/map/osm_tile_cache.cpp index 0f63253..cd8b34f 100644 --- a/libs/map/osm_tile_cache.cpp +++ b/libs/map/osm_tile_cache.cpp @@ -32,7 +32,32 @@ void OSMTileCache::tileDownloaded(OSM::TileIndex index, const QPixmap & pixmap) } -OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index) { +OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index, QRectF & rect_src) { + OSM::TilePixmap ret = getTileFromCache(index); + if (ret.isEmpty()) { + parent->downloader->queueTile(index); + QVector offsets; + while (index.z >= 0) { + index.z--; + offsets << QPointF(index.x % 2, index.y % 2); + index.x /= 2; + index.y /= 2; + ret = getTileFromCache(index); + if (!ret.isEmpty()) { + for (int i = offsets.size() - 1; i >= 0; --i) { + rect_src.setSize(rect_src.size() / 2.); + rect_src.translate(offsets[i].x() * rect_src.width(), offsets[i].y() * rect_src.height()); + } + return ret; + } + } + } else + rect_src = ret.pixmap.rect(); + return ret; +} + + +OSM::TilePixmap OSMTileCache::getTileFromCache(OSM::TileIndex index) { OSM::TilePixmap ret; ret.index = index; auto * tile = tile_cache[index.hash()]; @@ -51,7 +76,6 @@ OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index) { return ret; } } - parent->downloader->queueTile(index); } return ret; } diff --git a/libs/map/osm_tile_cache_p.h b/libs/map/osm_tile_cache_p.h index b3bcfe1..ba0b306 100644 --- a/libs/map/osm_tile_cache_p.h +++ b/libs/map/osm_tile_cache_p.h @@ -48,9 +48,10 @@ public: } void tileDownloaded(OSM::TileIndex index, const QPixmap & pixmap); - OSM::TilePixmap getTile(OSM::TileIndex index); + OSM::TilePixmap getTile(OSM::TileIndex index, QRectF & rect_src); private: + OSM::TilePixmap getTileFromCache(OSM::TileIndex index); void updateCacheSize(); void saveTile(OSM::TilePixmap * tile); void writeToDisk(const OSM::TilePixmap & tile); diff --git a/utils/mapviewer/main.cpp b/utils/mapviewer/main.cpp index 054a865..b8ceb74 100644 --- a/utils/mapviewer/main.cpp +++ b/utils/mapviewer/main.cpp @@ -67,6 +67,6 @@ int main(int argc, char * argv[]) { w.addItem(it); w.addItem(ell);*/ w.centerTo({55.583055, 37.580008}); - w.zoomTo(17); + w.zoomTo(2); return a.exec(); }