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:
parent
5581cff55b
commit
1a29ab6304
105
src/pathview.cpp
105
src/pathview.cpp
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user