Now using a strict horizontal map scale
[GPXSee.git] / src / map / emptymap.cpp
blobbbdc19865e8a05d4e5792a874f479638fa0b6579
1 #include <QtGlobal>
2 #include <QPainter>
3 #include "common/coordinates.h"
4 #include "common/rectc.h"
5 #include "common/wgs84.h"
6 #include "emptymap.h"
9 #define ZOOM_MIN 0
10 #define ZOOM_MAX 19
11 #define TILE_SIZE 256
13 static QPointF ll2m(const Coordinates &c)
15 return QPointF(c.lon(), rad2deg(log(tan(M_PI_4 + deg2rad(c.lat())/2.0))));
18 static Coordinates m2ll(const QPointF &p)
20 return Coordinates(p.x(), rad2deg(2.0 * atan(exp(deg2rad(p.y()))) - M_PI_2));
23 static qreal zoom2scale(int zoom)
25 return (360.0/(qreal)((1<<zoom) * TILE_SIZE));
28 static int scale2zoom(qreal scale)
30 return (int)log2(360.0/(scale * (qreal)TILE_SIZE));
33 static int limitZoom(int zoom)
35 if (zoom < ZOOM_MIN)
36 return ZOOM_MIN;
37 if (zoom > ZOOM_MAX)
38 return ZOOM_MAX;
40 return zoom;
44 EmptyMap::EmptyMap(QObject *parent) : Map(parent)
46 _zoom = ZOOM_MAX;
49 QRectF EmptyMap::bounds() const
51 return QRectF(ll2xy(Coordinates(-180, 85)), ll2xy(Coordinates(180, -85)));
54 int EmptyMap::zoomFit(const QSize &size, const RectC &rect)
56 if (!rect.isValid())
57 _zoom = ZOOM_MAX;
58 else {
59 QRectF tbr(ll2m(rect.topLeft()), ll2m(rect.bottomRight()));
60 QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
62 _zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y())));
65 return _zoom;
68 qreal EmptyMap::resolution(const QRectF &rect)
70 qreal scale = zoom2scale(_zoom);
72 return (WGS84_RADIUS * 2.0 * M_PI * scale / 360.0
73 * cos(2.0 * atan(exp(deg2rad(-rect.center().y() * scale))) - M_PI/2));
76 int EmptyMap::zoomIn()
78 _zoom = qMin(_zoom + 1, ZOOM_MAX);
79 return _zoom;
82 int EmptyMap::zoomOut()
84 _zoom = qMax(_zoom - 1, ZOOM_MIN);
85 return _zoom;
88 void EmptyMap::draw(QPainter *painter, const QRectF &rect, bool block)
90 Q_UNUSED(painter);
91 Q_UNUSED(rect);
92 Q_UNUSED(block);
95 QPointF EmptyMap::ll2xy(const Coordinates &c) const
97 qreal scale = zoom2scale(_zoom);
98 QPointF m = ll2m(c);
99 return QPointF(m.x() / scale, m.y() / -scale);
102 Coordinates EmptyMap::xy2ll(const QPointF &p) const
104 qreal scale = zoom2scale(_zoom);
105 return m2ll(QPointF(p.x() * scale, -p.y() * scale));