1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Enabled free map scroll.

This commit is contained in:
Martin Tůma 2017-01-16 09:54:12 +01:00
parent 5581cff55b
commit 1a29ab6304
4 changed files with 69 additions and 88 deletions

View File

@ -4,6 +4,7 @@
#include <QSysInfo> #include <QSysInfo>
#include "opengl.h" #include "opengl.h"
#include "rd.h" #include "rd.h"
#include "wgs84.h"
#include "poi.h" #include "poi.h"
#include "data.h" #include "data.h"
#include "map.h" #include "map.h"
@ -56,10 +57,10 @@ qreal mapScale(int zoom)
return ((360.0/(qreal)(1<<zoom))/(qreal)Tile::size()); return ((360.0/(qreal)(1<<zoom))/(qreal)Tile::size());
} }
static QRectF qrectf(const QPointF &p1, const QPointF &p2) static qreal zoom2resolution(int zoom, qreal y)
{ {
return QRectF(QPointF(qMin(p1.x(), p2.x()), qMin(p1.y(), p2.y())), return (WGS84_RADIUS * 2 * M_PI / Tile::size()
QPointF(qMax(p1.x(), p2.x()), qMax(p1.y(), p2.y()))); * cos(2.0 * atan(exp(deg2rad(y))) - M_PI/2)) / (qreal)(1<<zoom);
} }
static void unite(QRectF &rect, const QPointF &p) static void unite(QRectF &rect, const QPointF &p)
@ -98,6 +99,7 @@ PathView::PathView(QWidget *parent)
_mapScale->setZValue(2.0); _mapScale->setZValue(2.0);
_zoom = ZOOM_MAX; _zoom = ZOOM_MAX;
_res = 1.0;
_map = 0; _map = 0;
_poi = 0; _poi = 0;
@ -206,24 +208,28 @@ QList<PathItem *> PathView::loadData(const Data &data)
for (int i = 0; i < data.tracks().count(); i++) for (int i = 0; i < data.tracks().count(); i++)
paths.append(addTrack(*(data.tracks().at(i)))); paths.append(addTrack(*(data.tracks().at(i))));
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)
paths.append(addRoute(*(data.routes().at(i)))); paths.append(addRoute(*(data.routes().at(i))));
addWaypoints(data.waypoints()); addWaypoints(data.waypoints());
if (_tracks.empty() && _routes.empty() && _waypoints.empty()) if (_tracks.empty() && _routes.empty() && _waypoints.empty())
return paths; return paths;
if ((_tracks.size() + _routes.size() > 1 && _zoom < zoom) if (_zoom < zoom)
|| (_waypoints.size() && _zoom < zoom))
rescale(_zoom); rescale(_zoom);
else else {
_scene->setSceneRect(scaled(QRectF(QPointF(-180, -180),
QSizeF(360, 360)), 1.0 / mapScale(_zoom)));
updatePOIVisibility(); updatePOIVisibility();
}
QRectF sr = contentsSceneRect(); QPointF center = contentsCenter();
_scene->setSceneRect(sr); centerOn(center);
centerOn(sr.center());
_mapScale->setZoom(_zoom, -(sr.center().ry() * mapScale(_zoom))); _res = zoom2resolution(_zoom, -(center.y() * mapScale(_zoom)));
_mapScale->setResolution(_res);
if (_mapScale->scene() != _scene) if (_mapScale->scene() != _scene)
_scene->addItem(_mapScale); _scene->addItem(_mapScale);
@ -236,7 +242,7 @@ void PathView::updateWaypointsBoundingRect(const QPointF &wp)
if (_wp.isNull()) if (_wp.isNull())
_wp = wp; _wp = wp;
else { else {
_wr = qrectf(_wp, wp); _wr = QRectF(_wp, wp).normalized();
_wp = QPointF(); _wp = QPointF();
} }
} else } else
@ -258,19 +264,18 @@ qreal PathView::contentsScale() const
return qMax(sc.x(), sc.y()); return qMax(sc.x(), sc.y());
} }
QRectF PathView::contentsSceneRect() const QPointF PathView::contentsCenter() const
{ {
qreal scale = mapScale(_zoom);
QRectF br = _tr | _rr | _wr; QRectF br = _tr | _rr | _wr;
if (!br.isNull() && !_wp.isNull()) if (!br.isNull() && !_wp.isNull())
unite(br, _wp); unite(br, _wp);
qreal scale = mapScale(_zoom);
if (br.isNull()) if (br.isNull())
return QRectF(QPointF(_wp.x() / scale - Tile::size()/2, return _wp / scale;
_wp.y() /scale - Tile::size()/2), QSizeF(Tile::size(), Tile::size()));
else else
return scaled(br, 1.0/scale).adjusted(-Tile::size(), -Tile::size(), return scaled(br, 1.0/scale).center();
Tile::size(), Tile::size());
} }
void PathView::updatePOIVisibility() void PathView::updatePOIVisibility()
@ -299,6 +304,9 @@ void PathView::rescale(int zoom)
_zoom = zoom; _zoom = zoom;
qreal scale = mapScale(zoom); qreal scale = mapScale(zoom);
_scene->setSceneRect(scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)),
1.0 / scale));
for (int i = 0; i < _tracks.size(); i++) for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setScale(1.0/scale); _tracks.at(i)->setScale(1.0/scale);
@ -418,16 +426,6 @@ void PathView::redraw()
resetCachedContent(); resetCachedContent();
} }
void PathView::rescale()
{
int zoom = scale2zoom(contentsScale());
if (zoom != _zoom) {
rescale(zoom);
_mapScale->setZoom(zoom);
}
}
void PathView::zoom(int z, const QPoint &pos) void PathView::zoom(int z, const QPoint &pos)
{ {
if (_tracks.isEmpty() && _routes.isEmpty() && _waypoints.isEmpty()) if (_tracks.isEmpty() && _routes.isEmpty() && _waypoints.isEmpty())
@ -441,16 +439,11 @@ void PathView::zoom(int z, const QPoint &pos)
rescale(_zoom); rescale(_zoom);
QRectF sr = contentsSceneRect(); QPointF center = (spos * (os/mapScale(_zoom))) - offset;
_scene->setSceneRect(sr); centerOn(center);
if (sr.width() < viewport()->size().width() _res = zoom2resolution(_zoom, -(center.y() * mapScale(_zoom)));
&& sr.height() < viewport()->size().height()) _mapScale->setResolution(_res);
centerOn(sr.center());
else
centerOn((spos * (os/mapScale(_zoom))) - offset);
_mapScale->setZoom(_zoom);
resetCachedContent(); resetCachedContent();
} }
@ -536,6 +529,7 @@ void PathView::clear()
_palette.reset(); _palette.reset();
_zoom = ZOOM_MAX; _zoom = ZOOM_MAX;
_res = 1.0;
_tr = QRectF(); _rr = QRectF(); _wr = QRectF(); _tr = QRectF(); _rr = QRectF(); _wr = QRectF();
_wp = QPointF(); _wp = QPointF();
@ -663,8 +657,8 @@ void PathView::drawBackground(QPainter *painter, const QRectF &rect)
QList<Tile> tiles; QList<Tile> tiles;
for (int i = 0; i <= rr.size().width() / Tile::size() + 1; i++) for (int i = 0; i <= ceil(rr.size().width() / Tile::size()); i++)
for (int j = 0; j <= rr.size().height() / Tile::size() + 1; j++) for (int j = 0; j <= ceil(rr.size().height() / Tile::size()); j++)
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom)); tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
_map->loadTiles(tiles, _plot); _map->loadTiles(tiles, _plot);
@ -679,24 +673,20 @@ void PathView::drawBackground(QPainter *painter, const QRectF &rect)
void PathView::resizeEvent(QResizeEvent *event) void PathView::resizeEvent(QResizeEvent *event)
{ {
Q_UNUSED(event);
if (_tracks.isEmpty() && _routes.isEmpty() && _waypoints.isEmpty()) if (_tracks.isEmpty() && _routes.isEmpty() && _waypoints.isEmpty())
return; return;
rescale(); int zoom = scale2zoom(contentsScale());
if (zoom != _zoom)
rescale(zoom);
QRectF sr = contentsSceneRect(); QPointF center = contentsCenter();
centerOn(center);
if (sr.width() < event->size().width()) { _res = zoom2resolution(_zoom, -(center.y() * mapScale(_zoom)));
qreal diff = event->size().width() - sr.width(); _mapScale->setResolution(_res);
sr.adjust(-diff/2, 0, diff/2, 0);
}
if (sr.height() < event->size().height()) {
qreal diff = event->size().height() - sr.height();
sr.adjust(0, -diff/2, 0, diff/2);
}
_scene->setSceneRect(sr);
centerOn(sr.center());
resetCachedContent(); resetCachedContent();
} }
@ -712,6 +702,19 @@ void PathView::paintEvent(QPaintEvent *event)
QGraphicsView::paintEvent(event); QGraphicsView::paintEvent(event);
} }
void PathView::scrollContentsBy(int dx, int dy)
{
QGraphicsView::scrollContentsBy(dx, dy);
QPointF center = mapToScene(viewport()->rect().center());
qreal res = zoom2resolution(_zoom, -(center.y() * mapScale(_zoom)));
if (qMax(res, _res) / qMin(res, _res) > 1.1) {
_mapScale->setResolution(res);
_res = res;
}
}
void PathView::useOpenGL(bool use) void PathView::useOpenGL(bool use)
{ {
if (use) { if (use) {

View File

@ -73,9 +73,8 @@ private:
void clearPOI(); void clearPOI();
qreal contentsScale() const; qreal contentsScale() const;
QRectF contentsSceneRect() const; QPointF contentsCenter() const;
void rescale(int zoom); void rescale(int zoom);
void rescale();
void zoom(int z, const QPoint &pos); void zoom(int z, const QPoint &pos);
void updatePOIVisibility(); void updatePOIVisibility();
void updateWaypointsBoundingRect(const QPointF &wp); void updateWaypointsBoundingRect(const QPointF &wp);
@ -86,6 +85,7 @@ private:
void drawBackground(QPainter *painter, const QRectF &rect); void drawBackground(QPainter *painter, const QRectF &rect);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
void scrollContentsBy(int dx, int dy);
QGraphicsScene *_scene; QGraphicsScene *_scene;
ScaleItem *_mapScale; ScaleItem *_mapScale;
@ -97,6 +97,7 @@ private:
int _zoom; int _zoom;
QRectF _tr, _rr, _wr; QRectF _tr, _rr, _wr;
QPointF _wp; QPointF _wp;
qreal _res;
Map *_map; Map *_map;
POI *_poi; POI *_poi;

View File

@ -1,8 +1,5 @@
#include <QPainter> #include <QPainter>
#include "config.h" #include "config.h"
#include "rd.h"
#include "wgs84.h"
#include "tile.h"
#include "misc.h" #include "misc.h"
#include "scaleitem.h" #include "scaleitem.h"
@ -13,17 +10,11 @@
#define SEGMENTS 3 #define SEGMENTS 3
#define PADDING 4 #define PADDING 4
static qreal zoom2resolution(int zoom, qreal y)
{
return (WGS84_RADIUS * 2 * M_PI / Tile::size()
* cos(2.0 * atan(exp(deg2rad(y))) - M_PI/2)) / (qreal)(1<<zoom);
}
ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent) ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{ {
_units = Metric; _units = Metric;
_zoom = 0; _res = 1.0;
_lat = 0;
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
setCacheMode(QGraphicsItem::DeviceCoordinateCache); setCacheMode(QGraphicsItem::DeviceCoordinateCache);
@ -96,45 +87,33 @@ QString ScaleItem::units() const
void ScaleItem::computeScale() void ScaleItem::computeScale()
{ {
qreal res = zoom2resolution(_zoom, _lat);
if (_units == Imperial) { if (_units == Imperial) {
_length = niceNum((res * M2FT * SCALE_WIDTH) / SEGMENTS, 1); _length = niceNum((_res * M2FT * SCALE_WIDTH) / SEGMENTS, 1);
if (_length >= MIINFT) { if (_length >= MIINFT) {
_length = niceNum((res * M2FT * FT2MI * SCALE_WIDTH) / SEGMENTS, 1); _length = niceNum((_res * M2FT * FT2MI * SCALE_WIDTH) / SEGMENTS, 1);
_width = (_length / (res * M2FT * FT2MI)); _width = (_length / (_res * M2FT * FT2MI));
_scale = true; _scale = true;
} else { } else {
_width = (_length / (res * M2FT)); _width = (_length / (_res * M2FT));
_scale = false; _scale = false;
} }
} else { } else {
_length = niceNum((res * SCALE_WIDTH) / SEGMENTS, 1); _length = niceNum((_res * SCALE_WIDTH) / SEGMENTS, 1);
if (_length >= KMINM) { if (_length >= KMINM) {
_length *= M2KM; _length *= M2KM;
_width = (_length / (res * M2KM)); _width = (_length / (_res * M2KM));
_scale = true; _scale = true;
} else { } else {
_width = (_length / res); _width = (_length / _res);
_scale = false; _scale = false;
} }
} }
} }
void ScaleItem::setZoom(int z, qreal lat) void ScaleItem::setResolution(qreal res)
{ {
prepareGeometryChange(); prepareGeometryChange();
_zoom = z; _res = res;
_lat = lat;
computeScale();
updateBoundingRect();
update();
}
void ScaleItem::setZoom(int z)
{
prepareGeometryChange();
_zoom = z;
computeScale(); computeScale();
updateBoundingRect(); updateBoundingRect();
update(); update();

View File

@ -13,8 +13,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
void setZoom(int z); void setResolution(qreal res);
void setZoom(int z, qreal lat);
void setUnits(enum Units units); void setUnits(enum Units units);
private: private:
@ -22,8 +21,7 @@ private:
void computeScale(); void computeScale();
QString units() const; QString units() const;
int _zoom; qreal _res;
qreal _lat;
qreal _width; qreal _width;
qreal _length; qreal _length;
Units _units; Units _units;