1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 03:35:53 +01:00

Added track scale info

This commit is contained in:
Martin Tůma 2016-01-14 00:37:51 +01:00
parent 5bd4999205
commit c2391929d3
12 changed files with 256 additions and 35 deletions

View File

@ -28,7 +28,9 @@ HEADERS += src/config.h \
src/map.h \
src/maplist.h \
src/downloader.h \
src/units.h
src/units.h \
src/scaleitem.h \
src/nicenum.h
SOURCES += src/main.cpp \
src/gui.cpp \
src/gpx.cpp \
@ -49,7 +51,9 @@ SOURCES += src/main.cpp \
src/filebrowser.cpp \
src/map.cpp \
src/maplist.cpp \
src/downloader.cpp
src/downloader.cpp \
src/scaleitem.cpp \
src/nicenum.cpp
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts
macx:ICON = icons/gpxsee.icns

View File

@ -1,6 +1,7 @@
#include <cmath>
#include <QPainter>
#include "config.h"
#include "nicenum.h"
#include "axisitem.h"
@ -15,38 +16,6 @@ struct Label {
double d;
};
static double niceNum(double x, int round)
{
int expv;
double f;
double nf;
expv = floor(log10(x));
f = x / pow(10.0, expv);
if (round) {
if (f < 1.5)
nf = 1.0;
else if (f < 3.0)
nf = 2.0;
else if (f < 7.0)
nf = 5.0;
else
nf = 10.0;
} else {
if (f <= 1.0)
nf = 1.;
else if (f <= 2.0)
nf = 2.0;
else if (f <= 5.0)
nf = 5.0;
else
nf = 10.0;
}
return nf * pow(10.0, expv);
}
static struct Label label(double min, double max, int ticks)
{
double range;
@ -123,7 +92,6 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
painter->setFont(font);
QFontMetrics fm(font);
QRect ts, ls;
struct Label l;
@ -131,6 +99,8 @@ void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
qreal val;
painter->setFont(font);
ls = fm.tightBoundingRect(_label);
if (_type == X) {

View File

@ -670,6 +670,7 @@ void GUI::updateNavigationActions()
void GUI::setMetricUnits()
{
_track->setUnits(Metric);
_elevationGraph->setUnits(Metric);
_speedGraph->setUnits(Metric);
updateStatusBarInfo();
@ -677,6 +678,7 @@ void GUI::setMetricUnits()
void GUI::setImperialUnits()
{
_track->setUnits(Imperial);
_elevationGraph->setUnits(Imperial);
_speedGraph->setUnits(Imperial);
updateStatusBarInfo();

View File

@ -68,3 +68,9 @@ int scale2zoom(qreal scale)
return ZOOM_MAX;
return zoom;
}
qreal zoom2resolution(int zoom, qreal y)
{
return (WGS84_RADIUS * 2 * M_PI / 256 * cos(2 * atan(exp(deg2rad(y)))
- M_PI/2)) / pow(2.0, zoom);
}

View File

@ -12,5 +12,6 @@ qreal llDistance(const QPointF &p1, const QPointF &p2);
QPoint mercator2tile(const QPointF &m, int zoom);
QPointF tile2mercator(const QPoint &tile, int zoom);
int scale2zoom(qreal scale);
qreal zoom2resolution(int zoom, qreal y);
#endif // LL_H

34
src/nicenum.cpp Normal file
View File

@ -0,0 +1,34 @@
#include <cmath>
#include "nicenum.h"
double niceNum(double x, int round)
{
int expv;
double f;
double nf;
expv = floor(log10(x));
f = x / pow(10.0, expv);
if (round) {
if (f < 1.5)
nf = 1.0;
else if (f < 3.0)
nf = 2.0;
else if (f < 7.0)
nf = 5.0;
else
nf = 10.0;
} else {
if (f <= 1.0)
nf = 1.0;
else if (f <= 2.0)
nf = 2.0;
else if (f <= 5.0)
nf = 5.0;
else
nf = 10.0;
}
return nf * pow(10.0, expv);
}

6
src/nicenum.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef NICENUM_H
#define NICENUM_H
double niceNum(double x, int round);
#endif // NICENUM_H

123
src/scaleitem.cpp Normal file
View File

@ -0,0 +1,123 @@
#include <QPainter>
#include "config.h"
#include "ll.h"
#include "nicenum.h"
#include "scaleitem.h"
#define SCALE_WIDTH 132
#define SCALE_HEIGHT 5
#define SEGMENTS 3
#define PADDING 4
ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
_units = Metric;
}
QRectF ScaleItem::boundingRect() const
{
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
QRect ss, es, us;
ss = fm.tightBoundingRect(QString::number(0));
es = fm.tightBoundingRect(QString::number(_length * SEGMENTS));
us = fm.tightBoundingRect(units());
return QRectF(-ss.width()/2, -(PADDING + ss.height() + fm.descent()),
_width * SEGMENTS + ss.width()/2 + qMax(us.width() + PADDING, es.width()/2),
SCALE_HEIGHT + PADDING + ss.height() + 2*fm.descent());
}
void ScaleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
painter->setFont(font);
for (int i = 0; i <= SEGMENTS; i++) {
QString label = QString::number(_length * i);
QRect br = fm.tightBoundingRect(label);
painter->drawText(_width * i - br.width()/2, -PADDING, label);
}
painter->drawText(_width * SEGMENTS + PADDING, SCALE_HEIGHT + fm.descent(),
units());
painter->drawRect(QRectF(0, 0, SEGMENTS * _width, SCALE_HEIGHT));
for (int i = 0; i < SEGMENTS; i += 2)
painter->fillRect(QRectF(i * _width, 0, _width, SCALE_HEIGHT),
Qt::black);
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
}
QString ScaleItem::units() const
{
if (_units == Imperial)
return _scale ? QObject::tr("mi") : QObject::tr("ft");
else
return _scale ? QObject::tr("km") : QObject::tr("m");
}
void ScaleItem::computeScale()
{
qreal res = zoom2resolution(_zoom, _lat);
if (_units == Imperial) {
_length = niceNum((res * M2FT * SCALE_WIDTH) / SEGMENTS, 1);
if (_length >= MIINFT) {
_length = niceNum((res * M2FT * FT2MI * SCALE_WIDTH) / SEGMENTS, 1);
_width = (_length / (res * M2FT * FT2MI));
_scale = true;
} else {
_width = (_length / (res * M2FT));
_scale = false;
}
} else {
_length = niceNum((res * SCALE_WIDTH) / SEGMENTS, 1);
if (_length >= KMINM) {
_length *= M2KM;
_width = (_length / (res * M2KM));
_scale = true;
} else {
_width = (_length / res);
_scale = false;
}
}
}
void ScaleItem::setLatitude(qreal lat)
{
_lat = lat;
computeScale();
prepareGeometryChange();
}
void ScaleItem::setZoom(int z)
{
_zoom = z;
computeScale();
prepareGeometryChange();
}
void ScaleItem::setUnits(enum Units units)
{
_units = units;
computeScale();
prepareGeometryChange();
}

32
src/scaleitem.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef SCALEITEM_H
#define SCALEITEM_H
#include <QGraphicsItem>
#include "units.h"
class ScaleItem : public QGraphicsItem
{
public:
ScaleItem(QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setLatitude(qreal lat);
void setZoom(int z);
void setUnits(enum Units units);
private:
void computeScale();
QString units() const;
int _zoom;
qreal _lat;
qreal _width;
qreal _length;
Units _units;
bool _scale;
};
#endif // SCALEITEM_H

View File

@ -5,9 +5,12 @@
#include <QWheelEvent>
#include "poiitem.h"
#include "markeritem.h"
#include "scaleitem.h"
#include "ll.h"
#include "track.h"
#include <QDebug>
#define MARGIN 10.0
#define TRACK_WIDTH 3
@ -22,6 +25,9 @@ Track::Track(QWidget *parent)
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
_mapScale = new ScaleItem();
_mapScale->setZValue(2.0);
_zoom = -1;
_scale = 1.0;
_map = 0;
@ -79,6 +85,12 @@ void Track::loadGPX(const GPX &gpx)
QRectF ba = br.adjusted(-TILE_SIZE, -TILE_SIZE, TILE_SIZE, TILE_SIZE);
_scene->setSceneRect(ba);
centerOn(ba.center());
if (_mapScale->scene() != _scene)
_scene->addItem(_mapScale);
_mapScale->setLatitude(track.at(track.size() / 2).y());
_mapScale->setZoom(_zoom);
}
QRectF Track::trackBoundingRect() const
@ -198,6 +210,11 @@ void Track::setMap(Map *map)
resetCachedContent();
}
void Track::setUnits(enum Units units)
{
_mapScale->setUnits(units);
}
void Track::redraw()
{
resetCachedContent();
@ -225,6 +242,8 @@ void Track::wheelEvent(QWheelEvent *event)
else
centerOn(pos * scale/_scale);
_mapScale->setZoom(_zoom);
resetCachedContent();
}
@ -245,6 +264,8 @@ void Track::setTrackLineWidth(qreal width)
void Track::plot(QPainter *painter, const QRectF &target)
{
_scene->removeItem(_mapScale);
QRectF orig = _scene->itemsBoundingRect();
QRectF adj;
qreal ratio, diff;
@ -264,6 +285,8 @@ void Track::plot(QPainter *painter, const QRectF &target)
_scene->render(painter, target, adj, Qt::KeepAspectRatioByExpanding);
setTrackLineWidth(TRACK_WIDTH * _scale);
showMarkers(true);
_scene->addItem(_mapScale);
}
enum QPrinter::Orientation Track::orientation() const
@ -286,6 +309,9 @@ void Track::clearPOI()
void Track::clear()
{
if (_mapScale->scene() == _scene)
_scene->removeItem(_mapScale);
_pois.clear();
_tracks.clear();
_trackPaths.clear();
@ -362,3 +388,11 @@ void Track::resizeEvent(QResizeEvent *e)
centerOn(br.center());
resetCachedContent();
}
void Track::paintEvent(QPaintEvent *e)
{
QPointF scenePos = mapToScene(rect().bottomLeft() + QPoint(10, -15));
_mapScale->setPos(scenePos);
QGraphicsView::paintEvent(e);
}

View File

@ -9,11 +9,13 @@
#include "poi.h"
#include "gpx.h"
#include "map.h"
#include "units.h"
#include "colorshop.h"
class POIItem;
class MarkerItem;
class ScaleItem;
class Track : public QGraphicsView
{
@ -30,6 +32,7 @@ public:
void clear();
void setMap(Map *map);
void setUnits(enum Units units);
void plot(QPainter *painter, const QRectF &target);
enum QPrinter::Orientation orientation() const;
@ -52,6 +55,7 @@ private:
void wheelEvent(QWheelEvent *event);
void drawBackground(QPainter *painter, const QRectF &rect);
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *e);
QGraphicsScene *_scene;
QList<QVector<QPointF> > _tracks;
@ -59,6 +63,7 @@ private:
QList<MarkerItem*> _markers;
QHash<Entry, POIItem*> _pois;
Map *_map;
ScaleItem *_mapScale;
ColorShop _colorShop;
qreal _maxLen;

View File

@ -11,5 +11,9 @@ enum Units {
#define M2FT 3.280839900000 // m -> ft
#define MS2KMH 3.600000000000 // m/s -> km/h
#define MS2MIH 2.236936290000 // m/s -> mi/h
#define FT2MI 0.000189393939 // ft -> mi
#define MIINFT 5280 // 1 mi in ft
#define KMINM 1000 // 1 km in m
#endif // UNITS_H