diff --git a/src/atlas.cpp b/src/atlas.cpp index 6c19192a..b2848e1f 100644 --- a/src/atlas.cpp +++ b/src/atlas.cpp @@ -227,6 +227,26 @@ qreal Atlas::zoomFit(const QSize &size, const QRectF &br) return _zoom; } +qreal Atlas::zoomFit(qreal resolution, const Coordinates &c) +{ + _zoom = 0; + + for (int z = 0; z < _zooms.count(); z++) { + for (int i = _zooms.at(z).first; i <= _zooms.at(z).second; i++) { + if (!_bounds.at(i).first.contains(_maps.at(i)->ll2pp(c))) + continue; + + if (_maps.at(i)->resolution(_maps.at(i)->ll2xy(c)) < resolution) + return _zoom; + + _zoom = z; + break; + } + } + + return _zoom; +} + qreal Atlas::zoomIn() { _zoom = qMin(_zoom + 1, _zooms.size() - 1); diff --git a/src/atlas.h b/src/atlas.h index 80b8f6b6..ac3ab464 100644 --- a/src/atlas.h +++ b/src/atlas.h @@ -21,6 +21,7 @@ public: qreal zoom() const; qreal zoomFit(const QSize &size, const QRectF &br); + qreal zoomFit(qreal resolution, const Coordinates &c); qreal zoomIn(); qreal zoomOut(); diff --git a/src/emptymap.cpp b/src/emptymap.cpp index 681b2d39..2fcf4ec4 100644 --- a/src/emptymap.cpp +++ b/src/emptymap.cpp @@ -41,6 +41,17 @@ qreal EmptyMap::zoomFit(const QSize &size, const QRectF &br) return _scale; } +qreal EmptyMap::zoomFit(qreal resolution, const Coordinates &c) +{ + _scale = (360.0 * resolution) / (WGS84_RADIUS * 2 * M_PI + * cos(deg2rad(c.lat()))); + + _scale = qMax(_scale, SCALE_MAX); + _scale = qMin(_scale, SCALE_MIN); + + return _scale; +} + qreal EmptyMap::resolution(const QPointF &p) const { return (WGS84_RADIUS * 2 * M_PI * _scale / 360.0 diff --git a/src/emptymap.h b/src/emptymap.h index 0ccf3fce..ddf644bd 100644 --- a/src/emptymap.h +++ b/src/emptymap.h @@ -17,6 +17,7 @@ public: qreal zoom() const {return _scale;} qreal zoomFit(const QSize &size, const QRectF &br); + qreal zoomFit(qreal resolution, const Coordinates &c); qreal zoomIn(); qreal zoomOut(); diff --git a/src/map.h b/src/map.h index add0db07..479b04d2 100644 --- a/src/map.h +++ b/src/map.h @@ -22,6 +22,7 @@ public: virtual qreal zoom() const = 0; virtual qreal zoomFit(const QSize &size, const QRectF &br) = 0; + virtual qreal zoomFit(qreal resolution, const Coordinates &c) = 0; virtual qreal zoomIn() = 0; virtual qreal zoomOut() = 0; diff --git a/src/offlinemap.h b/src/offlinemap.h index 25e9d1e3..81b965b4 100644 --- a/src/offlinemap.h +++ b/src/offlinemap.h @@ -28,6 +28,7 @@ public: qreal zoom() const {return 0;} qreal zoomFit(const QSize &, const QRectF &) {return 0;} + qreal zoomFit(qreal, const Coordinates &) {return 0;} qreal zoomIn() {return 0;} qreal zoomOut() {return 0;} diff --git a/src/onlinemap.cpp b/src/onlinemap.cpp index 0c83105d..173d3b62 100644 --- a/src/onlinemap.cpp +++ b/src/onlinemap.cpp @@ -27,19 +27,12 @@ static QPoint mercator2tile(const QPointF &m, int z) static qreal zoom2scale(int zoom) { - return ((360.0/(qreal)(1< ZOOM_MAX) - return ZOOM_MAX; - - return zoom; + return (int)log2(360.0/(scale * (qreal)TILE_SIZE)); } @@ -181,12 +174,30 @@ qreal OnlineMap::zoomFit(const QSize &size, const QRectF &br) Coordinates bottomRight(br.bottomRight()); QRectF tbr(Mercator().ll2xy(topLeft), Mercator().ll2xy(bottomRight)); QPointF sc(tbr.width() / size.width(), tbr.height() / size.height()); + _zoom = scale2zoom(qMax(sc.x(), sc.y())); + if (_zoom < ZOOM_MIN) + _zoom = ZOOM_MIN; + if (_zoom > ZOOM_MAX) + _zoom = ZOOM_MAX; } return _zoom; } +qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c) +{ + _zoom = (int)(log2((WGS84_RADIUS * 2 * M_PI * cos(deg2rad(c.lat()))) + / resolution) - log2(TILE_SIZE)); + + if (_zoom < ZOOM_MIN) + _zoom = ZOOM_MIN; + if (_zoom > ZOOM_MAX) + _zoom = ZOOM_MAX; + + return _zoom; +} + qreal OnlineMap::resolution(const QPointF &p) const { qreal scale = zoom2scale(_zoom); diff --git a/src/onlinemap.h b/src/onlinemap.h index 326db096..6809fee7 100644 --- a/src/onlinemap.h +++ b/src/onlinemap.h @@ -20,6 +20,7 @@ public: qreal zoom() const {return _zoom;} qreal zoomFit(const QSize &size, const QRectF &br); + qreal zoomFit(qreal resolution, const Coordinates &c); qreal zoomIn(); qreal zoomOut(); diff --git a/src/pathview.cpp b/src/pathview.cpp index 5cbf89a5..560b69ba 100644 --- a/src/pathview.cpp +++ b/src/pathview.cpp @@ -8,7 +8,6 @@ #include "poi.h" #include "data.h" #include "map.h" -#include "emptymap.h" #include "trackitem.h" #include "routeitem.h" #include "waypointitem.h" @@ -16,10 +15,11 @@ #include "keys.h" #include "pathview.h" -#define MAX_ZOOM 1 -#define MIN_ZOOM -3 -#define MARGIN 10.0 -#define SCALE_OFFSET 7 + +#define MAX_DIGITAL_ZOOM 1 +#define MIN_DIGITAL_ZOOM -3 +#define MARGIN 10.0 +#define SCALE_OFFSET 7 static void unite(QRectF &rect, const QPointF &p) { @@ -271,6 +271,10 @@ void PathView::setPalette(const Palette &palette) void PathView::setMap(Map *map) { + QPointF pos = mapToScene(QRect(QPoint(), viewport()->size()).center()); + Coordinates center = _map->xy2ll(pos); + qreal resolution = _map->resolution(pos); + _map->unload(); disconnect(_map, SIGNAL(loaded()), this, SLOT(redraw())); @@ -280,7 +284,7 @@ void PathView::setMap(Map *map) resetDigitalZoom(); - mapScale(); + _map->zoomFit(resolution, center); _scene->setSceneRect(_map->bounds()); for (int i = 0; i < _tracks.size(); i++) @@ -295,10 +299,9 @@ void PathView::setMap(Map *map) it.value()->setMap(_map); updatePOIVisibility(); - QPointF center = contentCenter(); - centerOn(center); + centerOn(_map->ll2xy(center)); - _res = _map->resolution(center); + _res = _map->resolution(_map->ll2xy(center)); _mapScale->setResolution(_res); resetCachedContent(); @@ -420,8 +423,8 @@ void PathView::zoom(int zoom, const QPoint &pos, const Coordinates &c) if (_digitalZoom) { if (((_digitalZoom > 0 && zoom > 0) && (!shift || _digitalZoom - >= MAX_ZOOM)) || ((_digitalZoom < 0 && zoom < 0) && (!shift - || _digitalZoom <= MIN_ZOOM))) + >= MAX_DIGITAL_ZOOM)) || ((_digitalZoom < 0 && zoom < 0) && (!shift + || _digitalZoom <= MIN_DIGITAL_ZOOM))) return; digitalZoom(zoom);