mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Added track statistics
This commit is contained in:
parent
5131a9d81d
commit
96e8415e00
10
gpxsee.pro
10
gpxsee.pro
@ -18,7 +18,10 @@ HEADERS += src/config.h \
|
||||
src/colorshop.h \
|
||||
src/keys.h \
|
||||
src/slideritem.h \
|
||||
src/markeritem.h
|
||||
src/markeritem.h \
|
||||
src/infoitem.h \
|
||||
src/elevationgraph.h \
|
||||
src/speedgraph.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/gui.cpp \
|
||||
src/gpx.cpp \
|
||||
@ -31,7 +34,10 @@ SOURCES += src/main.cpp \
|
||||
src/poiitem.cpp \
|
||||
src/colorshop.cpp \
|
||||
src/slideritem.cpp \
|
||||
src/markeritem.cpp
|
||||
src/markeritem.cpp \
|
||||
src/infoitem.cpp \
|
||||
src/elevationgraph.cpp \
|
||||
src/speedgraph.cpp
|
||||
RESOURCES += gpxsee.qrc
|
||||
TRANSLATIONS = lang/gpxsee_cs.ts
|
||||
macx:ICON = icons/gpxsee.icns
|
||||
|
@ -2,131 +2,163 @@
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="cs_CZ">
|
||||
<context>
|
||||
<name>GUI</name>
|
||||
<name>ElevationGraph</name>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="68"/>
|
||||
<source>About Qt</source>
|
||||
<translation>O Qt</translation>
|
||||
<location filename="../src/elevationgraph.cpp" line="11"/>
|
||||
<source>Distance</source>
|
||||
<translation>Vzdálenost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="185"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
|
||||
<translation>Program GPXSee je distribuován pod podmínkami licence GNU General Public License verze 3. Pro více informací navštivte stránky programu na adrese </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="193"/>
|
||||
<source>Open file</source>
|
||||
<translation>Otevřít soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="82"/>
|
||||
<source>Save as</source>
|
||||
<translation>Uložit jako</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="233"/>
|
||||
<source>Open POI file</source>
|
||||
<translation>Otevřít POI soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="73"/>
|
||||
<source>Open</source>
|
||||
<translation>Otevřít</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="61"/>
|
||||
<source>Quit</source>
|
||||
<translation>Ukončit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="77"/>
|
||||
<source>Save</source>
|
||||
<translation>Uložit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="87"/>
|
||||
<source>Close</source>
|
||||
<translation>Zavřít</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="94"/>
|
||||
<source>Load file</source>
|
||||
<translation>Nahrát soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="97"/>
|
||||
<source>Show</source>
|
||||
<translation>Zobrazit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="104"/>
|
||||
<location filename="../src/gui.cpp" line="125"/>
|
||||
<source>File</source>
|
||||
<translation>Soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="114"/>
|
||||
<location filename="../src/gui.cpp" line="133"/>
|
||||
<source>POI</source>
|
||||
<translation>POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="118"/>
|
||||
<source>Help</source>
|
||||
<translation>Nápověda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="148"/>
|
||||
<location filename="../src/gui.cpp" line="153"/>
|
||||
<source>Distance [km]</source>
|
||||
<translation>Vzdálenost [km]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="149"/>
|
||||
<source>Elevation [m.a.s.l.]</source>
|
||||
<translation>Výška [m.n.m.]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="154"/>
|
||||
<source>Speed [km/h]</source>
|
||||
<translation>Rychlost [km/h]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="159"/>
|
||||
<location filename="../src/elevationgraph.cpp" line="12"/>
|
||||
<source>Elevation</source>
|
||||
<translation>Výška</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="160"/>
|
||||
<location filename="../src/elevationgraph.cpp" line="13"/>
|
||||
<source>km</source>
|
||||
<translation>km</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/elevationgraph.cpp" line="14"/>
|
||||
<source>m</source>
|
||||
<translation>m</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/elevationgraph.cpp" line="45"/>
|
||||
<source>Ascent</source>
|
||||
<translation>Stoupání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/elevationgraph.cpp" line="46"/>
|
||||
<source>Descent</source>
|
||||
<translation>Klesání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/elevationgraph.cpp" line="47"/>
|
||||
<source>Minimum</source>
|
||||
<translation>Minimum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/elevationgraph.cpp" line="48"/>
|
||||
<source>Maximum</source>
|
||||
<translation>Maximum</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GUI</name>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="70"/>
|
||||
<source>About Qt</source>
|
||||
<translation>O Qt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="181"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
|
||||
<translation>Program GPXSee je distribuován pod podmínkami licence GNU General Public License verze 3. Pro více informací navštivte stránky programu na adrese </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="189"/>
|
||||
<source>Open file</source>
|
||||
<translation>Otevřít soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="84"/>
|
||||
<source>Save as</source>
|
||||
<translation>Uložit jako</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="239"/>
|
||||
<source>Open POI file</source>
|
||||
<translation>Otevřít POI soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="75"/>
|
||||
<source>Open</source>
|
||||
<translation>Otevřít</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="63"/>
|
||||
<source>Quit</source>
|
||||
<translation>Ukončit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="79"/>
|
||||
<source>Save</source>
|
||||
<translation>Uložit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="89"/>
|
||||
<source>Close</source>
|
||||
<translation>Zavřít</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="96"/>
|
||||
<source>Load file</source>
|
||||
<translation>Nahrát soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="99"/>
|
||||
<source>Show</source>
|
||||
<translation>Zobrazit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="106"/>
|
||||
<location filename="../src/gui.cpp" line="129"/>
|
||||
<source>File</source>
|
||||
<translation>Soubor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="118"/>
|
||||
<location filename="../src/gui.cpp" line="137"/>
|
||||
<source>POI</source>
|
||||
<translation>POI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="122"/>
|
||||
<source>Help</source>
|
||||
<translation>Nápověda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="155"/>
|
||||
<source>Elevation</source>
|
||||
<translation>Výška</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="156"/>
|
||||
<source>Speed</source>
|
||||
<translation>Rychlost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="66"/>
|
||||
<location filename="../src/gui.cpp" line="182"/>
|
||||
<location filename="../src/gui.cpp" line="68"/>
|
||||
<location filename="../src/gui.cpp" line="178"/>
|
||||
<source>About GPXSee</source>
|
||||
<translation>O aplikaci GPXSee</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="184"/>
|
||||
<location filename="../src/gui.cpp" line="180"/>
|
||||
<source>GPX viewer and analyzer</source>
|
||||
<translation>Prohlížeč a analyzátor GPX</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="223"/>
|
||||
<location filename="../src/gui.cpp" line="237"/>
|
||||
<source>%1 tracks</source>
|
||||
<translation>Počet tras: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="229"/>
|
||||
<location filename="../src/gui.cpp" line="243"/>
|
||||
<source>Error</source>
|
||||
<translation>Chyba</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="224"/>
|
||||
<location filename="../src/gui.cpp" line="230"/>
|
||||
<source>Error loading GPX file:
|
||||
%1</source>
|
||||
<translation>Soubor GPX nelze otevřít:
|
||||
%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gui.cpp" line="238"/>
|
||||
<location filename="../src/gui.cpp" line="244"/>
|
||||
<source>Error loading POI file:
|
||||
%1</source>
|
||||
<translation>Soubor POI nelze otevřít:
|
||||
@ -162,4 +194,37 @@ Line %1</source>
|
||||
Rádka %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SpeedGraph</name>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="7"/>
|
||||
<source>Distance</source>
|
||||
<translation>Vzdálenost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="8"/>
|
||||
<source>Speed</source>
|
||||
<translation>Rychlost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="9"/>
|
||||
<source>km</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="10"/>
|
||||
<source>km/h</source>
|
||||
<translation>km/h</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="42"/>
|
||||
<source>Average</source>
|
||||
<translation>Průměr</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/speedgraph.cpp" line="43"/>
|
||||
<source>Maximum</source>
|
||||
<translation>Maximum</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
61
src/elevationgraph.cpp
Normal file
61
src/elevationgraph.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <float.h>
|
||||
#include "elevationgraph.h"
|
||||
|
||||
ElevationGraph::ElevationGraph()
|
||||
{
|
||||
_ascent = 0;
|
||||
_descent = 0;
|
||||
_max = -FLT_MAX;
|
||||
_min = FLT_MAX;
|
||||
|
||||
Graph::setXLabel(tr("Distance"));
|
||||
Graph::setYLabel(tr("Elevation"));
|
||||
Graph::setXUnits(tr("km"));
|
||||
Graph::setYUnits(tr("m"));
|
||||
Graph::setXScale(0.001);
|
||||
}
|
||||
|
||||
void ElevationGraph::loadData(const QVector<QPointF> &data)
|
||||
{
|
||||
qreal ascent = 0, descent = 0;
|
||||
qreal min = data.at(0).y();
|
||||
qreal max = data.at(0).y();
|
||||
|
||||
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
qreal cur = data.at(i).y();
|
||||
qreal prev = data.at(i-1).y();
|
||||
|
||||
if (cur > prev)
|
||||
ascent += cur - prev;
|
||||
if (cur < prev)
|
||||
descent += prev - cur;
|
||||
|
||||
if (cur > max)
|
||||
max = cur;
|
||||
if (cur < min)
|
||||
min = cur;
|
||||
}
|
||||
|
||||
_ascent += ascent;
|
||||
_descent += descent;
|
||||
_max = qMax(_max, max);
|
||||
_min = qMin(_min, min);
|
||||
|
||||
addInfo(tr("Ascent"), QString::number((int)_ascent) + " " + _yUnits);
|
||||
addInfo(tr("Descent"), QString::number((int)_descent) + " " + _yUnits);
|
||||
addInfo(tr("Minimum"), QString::number((int)_min) + " " + _yUnits);
|
||||
addInfo(tr("Maximum"), QString::number((int)_max) + " " + _yUnits);
|
||||
|
||||
Graph::loadData(data);
|
||||
}
|
||||
|
||||
void ElevationGraph::clear()
|
||||
{
|
||||
_ascent = 0;
|
||||
_descent = 0;
|
||||
_max = -FLT_MAX;
|
||||
_min = FLT_MAX;
|
||||
|
||||
Graph::clear();
|
||||
}
|
19
src/elevationgraph.h
Normal file
19
src/elevationgraph.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef ELEVATIONGRAPH_H
|
||||
#define ELEVATIONGRAPH_H
|
||||
|
||||
#include "graph.h"
|
||||
|
||||
class ElevationGraph : public Graph
|
||||
{
|
||||
public:
|
||||
ElevationGraph();
|
||||
|
||||
void loadData(const QVector<QPointF> &data);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
qreal _ascent, _descent;
|
||||
qreal _max, _min;
|
||||
};
|
||||
|
||||
#endif // ELEVATIONGRAPH_H
|
23
src/gpx.cpp
23
src/gpx.cpp
@ -4,7 +4,7 @@
|
||||
#include "gpx.h"
|
||||
|
||||
|
||||
#define ALPHA_E 0.9
|
||||
#define ALPHA_E 0.5
|
||||
#define ALPHA_S 0.1
|
||||
|
||||
bool GPX::loadFile(const QString &fileName)
|
||||
@ -27,13 +27,12 @@ bool GPX::loadFile(const QString &fileName)
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<QPointF> GPX::elevationGraph() const
|
||||
void GPX::elevationGraph(QVector<QPointF> &graph) const
|
||||
{
|
||||
QVector<QPointF> graph;
|
||||
qreal dist = 0, ds, dh, acc;
|
||||
|
||||
if (!_data.size())
|
||||
return graph;
|
||||
return;
|
||||
|
||||
graph.append(QPointF(0, _data.at(0).elevation));
|
||||
for (int i = 1; i < _data.size(); i++) {
|
||||
@ -43,40 +42,34 @@ QVector<QPointF> GPX::elevationGraph() const
|
||||
acc = (i == 1) ? dh : (ALPHA_E * dh) + (1.0 - ALPHA_E) * acc;
|
||||
graph.append(QPointF(dist, acc));
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
QVector<QPointF> GPX::speedGraph() const
|
||||
void GPX::speedGraph(QVector<QPointF> &graph) const
|
||||
{
|
||||
QVector<QPointF> graph;
|
||||
qreal dist = 0, v, ds, dt, acc;
|
||||
|
||||
if (!_data.size())
|
||||
return graph;
|
||||
return;
|
||||
|
||||
graph.append(QPointF(0, 0));
|
||||
for (int i = 1; i < _data.size(); i++) {
|
||||
ds = llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
|
||||
dt = _data.at(i-1).timestamp.msecsTo(_data.at(i).timestamp) / 1000.0;
|
||||
if (dt == 0)
|
||||
continue;
|
||||
dist += ds;
|
||||
v = ds / dt;
|
||||
acc = (i == 1) ? v : (ALPHA_S * v) + (1.0 - ALPHA_S) * acc;
|
||||
graph.append(QPointF(dist, acc));
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
QVector<QPointF> GPX::track() const
|
||||
void GPX::track(QVector<QPointF> &track) const
|
||||
{
|
||||
QVector<QPointF> track;
|
||||
QPointF p;
|
||||
|
||||
for (int i = 0; i < _data.size(); i++) {
|
||||
ll2mercator(_data.at(i).coordinates, p);
|
||||
track.append(p);
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
||||
|
@ -11,9 +11,10 @@ class GPX
|
||||
public:
|
||||
bool loadFile(const QString &fileName);
|
||||
const QString &errorString() const {return _error;}
|
||||
QVector<QPointF> elevationGraph() const;
|
||||
QVector<QPointF> speedGraph() const;
|
||||
QVector<QPointF> track() const;
|
||||
|
||||
void elevationGraph(QVector<QPointF> &graph) const;
|
||||
void speedGraph(QVector<QPointF> &graph) const;
|
||||
void track(QVector<QPointF> &track) const;
|
||||
|
||||
private:
|
||||
Parser _parser;
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QEvent>
|
||||
#include "slideritem.h"
|
||||
#include "infoitem.h"
|
||||
#include "graph.h"
|
||||
|
||||
#include <QDebug>
|
||||
@ -18,9 +20,12 @@ Graph::Graph(QWidget *parent)
|
||||
_yAxis = new AxisItem(AxisItem::Y);
|
||||
|
||||
_slider = new SliderItem();
|
||||
_slider->setZValue(2.0);
|
||||
connect(_slider, SIGNAL(positionChanged(const QPointF&)), this,
|
||||
SLOT(emitSliderPositionChanged(const QPointF&)));
|
||||
|
||||
_info = new InfoItem();
|
||||
|
||||
_xMax = -FLT_MAX;
|
||||
_xMin = FLT_MAX;
|
||||
_yMax = -FLT_MAX;
|
||||
@ -40,6 +45,9 @@ Graph::~Graph()
|
||||
if (_slider->scene() != _scene)
|
||||
delete _slider;
|
||||
|
||||
if (_info->scene() != _scene)
|
||||
delete _info;
|
||||
|
||||
delete _scene;
|
||||
}
|
||||
|
||||
@ -55,6 +63,40 @@ void Graph::updateBounds(const QPointF &point)
|
||||
_yMax = point.y();
|
||||
}
|
||||
|
||||
void Graph::createXLabel()
|
||||
{
|
||||
_xAxis->setLabel(QString("%1 [%2]").arg(_xLabel).arg(_xUnits));
|
||||
}
|
||||
|
||||
void Graph::createYLabel()
|
||||
{
|
||||
_yAxis->setLabel(QString("%1 [%2]").arg(_yLabel).arg(_yUnits));
|
||||
}
|
||||
|
||||
void Graph::setXLabel(const QString &label)
|
||||
{
|
||||
_xLabel = label;
|
||||
createXLabel();
|
||||
}
|
||||
|
||||
void Graph::setYLabel(const QString &label)
|
||||
{
|
||||
_yLabel = label;
|
||||
createYLabel();
|
||||
}
|
||||
|
||||
void Graph::setXUnits(const QString &units)
|
||||
{
|
||||
_xUnits = units;
|
||||
createXLabel();
|
||||
}
|
||||
|
||||
void Graph::setYUnits(const QString &units)
|
||||
{
|
||||
_yUnits = units;
|
||||
createYLabel();
|
||||
}
|
||||
|
||||
void Graph::loadData(const QVector<QPointF> &data)
|
||||
{
|
||||
QPainterPath path;
|
||||
@ -95,20 +137,22 @@ void Graph::resize(const QSizeF &size)
|
||||
_scene->removeItem(_xAxis);
|
||||
if (_yAxis->scene() == _scene)
|
||||
_scene->removeItem(_yAxis);
|
||||
_xAxis->setRange(QPointF(_xMin * _xScale, _xMax * _xScale));
|
||||
_yAxis->setRange(QPointF(_yMin * _yScale, _yMax * _yScale));
|
||||
|
||||
if (_slider->scene() == _scene)
|
||||
_scene->removeItem(_slider);
|
||||
if (_info->scene() == _scene)
|
||||
_scene->removeItem(_info);
|
||||
|
||||
for (int i = 0; i < _graphs.size(); i++)
|
||||
_graphs.at(i)->resetTransform();
|
||||
|
||||
_xAxis->setRange(QPointF(_xMin * _xScale, _xMax * _xScale));
|
||||
_yAxis->setRange(QPointF(_yMin * _yScale, _yMax * _yScale));
|
||||
mx = _xAxis->margin();
|
||||
my = _yAxis->margin();
|
||||
r = _scene->itemsBoundingRect();
|
||||
xs = (size.width() - (my.width() + mx.width())) / r.width();
|
||||
ys = (size.height() - (mx.height() + my.height())) / r.height();
|
||||
ys = (size.height() - (mx.height() + my.height())
|
||||
- _info->boundingRect().height()) / r.height();
|
||||
transform.scale(xs, ys);
|
||||
|
||||
for (int i = 0; i < _graphs.size(); i++)
|
||||
@ -126,6 +170,11 @@ void Graph::resize(const QSizeF &size)
|
||||
_slider->setPos(r.bottomLeft());
|
||||
_scene->addItem(_slider);
|
||||
|
||||
r = _scene->itemsBoundingRect();
|
||||
_info->setPos(r.topLeft() + QPointF(r.width()/2
|
||||
- _info->boundingRect().width()/2, -_info->boundingRect().height()));
|
||||
_scene->addItem(_info);
|
||||
|
||||
_scene->setSceneRect(_scene->itemsBoundingRect());
|
||||
}
|
||||
|
||||
@ -158,6 +207,9 @@ void Graph::clear()
|
||||
if (_slider->scene() == _scene)
|
||||
_scene->removeItem(_slider);
|
||||
|
||||
if (_info->scene() == _scene)
|
||||
_scene->removeItem(_info);
|
||||
|
||||
_scene->clear();
|
||||
_graphs.clear();
|
||||
_colorShop.reset();
|
||||
@ -185,3 +237,8 @@ void Graph::setSliderPosition(qreal pos)
|
||||
{
|
||||
_slider->setPos(pos * _slider->area().width(), 0);
|
||||
}
|
||||
|
||||
void Graph::addInfo(const QString &key, const QString &value)
|
||||
{
|
||||
_info->insert(key, value);
|
||||
}
|
||||
|
24
src/graph.h
24
src/graph.h
@ -6,10 +6,12 @@
|
||||
#include <QList>
|
||||
#include <QPointF>
|
||||
#include "axisitem.h"
|
||||
#include "slideritem.h"
|
||||
#include "colorshop.h"
|
||||
|
||||
|
||||
class SliderItem;
|
||||
class InfoItem;
|
||||
|
||||
class Graph : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -19,8 +21,10 @@ public:
|
||||
~Graph();
|
||||
|
||||
void loadData(const QVector<QPointF> &data);
|
||||
void setXLabel(const QString &label) {_xAxis->setLabel(label);}
|
||||
void setYLabel(const QString &label) {_yAxis->setLabel(label);}
|
||||
void setXLabel(const QString &label);
|
||||
void setYLabel(const QString &label);
|
||||
void setXUnits(const QString &units);
|
||||
void setYUnits(const QString &units);
|
||||
void setXScale(qreal scale) {_xScale = scale;}
|
||||
void setYScale(qreal scale) {_yScale = scale;}
|
||||
|
||||
@ -30,16 +34,24 @@ public:
|
||||
qreal sliderPosition() const;
|
||||
void setSliderPosition(qreal pos);
|
||||
|
||||
void addInfo(const QString &key, const QString &value);
|
||||
|
||||
signals:
|
||||
void sliderPositionChanged(qreal);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
qreal _xScale, _yScale;
|
||||
QString _xUnits, _yUnits;
|
||||
QString _xLabel, _yLabel;
|
||||
|
||||
private slots:
|
||||
void emitSliderPositionChanged(const QPointF &pos);
|
||||
|
||||
private:
|
||||
void createXLabel();
|
||||
void createYLabel();
|
||||
void updateBounds(const QPointF &point);
|
||||
void resize(const QSizeF &size);
|
||||
|
||||
@ -47,9 +59,11 @@ private:
|
||||
QGraphicsScene *_scene;
|
||||
AxisItem *_xAxis, *_yAxis;
|
||||
SliderItem *_slider;
|
||||
qreal _xMin, _xMax, _yMin, _yMax;
|
||||
InfoItem *_info;
|
||||
QList<QGraphicsPathItem*> _graphs;
|
||||
qreal _xScale, _yScale;
|
||||
|
||||
qreal _xMin, _xMax, _yMin, _yMax;
|
||||
|
||||
ColorShop _colorShop;
|
||||
};
|
||||
|
||||
|
37
src/gui.cpp
37
src/gui.cpp
@ -13,7 +13,8 @@
|
||||
#include "icons.h"
|
||||
#include "keys.h"
|
||||
#include "gpx.h"
|
||||
#include "graph.h"
|
||||
#include "elevationgraph.h"
|
||||
#include "speedgraph.h"
|
||||
#include "track.h"
|
||||
|
||||
#include <QDebug>
|
||||
@ -45,6 +46,7 @@ GUI::GUI()
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
|
||||
_dirIndex = -1;
|
||||
_files = 0;
|
||||
|
||||
resize(600, 800);
|
||||
}
|
||||
@ -146,16 +148,8 @@ void GUI::createTrackView()
|
||||
|
||||
void GUI::createTrackGraphs()
|
||||
{
|
||||
_elevationGraph = new Graph;
|
||||
_elevationGraph->setXLabel(tr("Distance [km]"));
|
||||
_elevationGraph->setYLabel(tr("Elevation [m.a.s.l.]"));
|
||||
_elevationGraph->setXScale(0.001);
|
||||
|
||||
_speedGraph = new Graph;
|
||||
_speedGraph->setXLabel(tr("Distance [km]"));
|
||||
_speedGraph->setYLabel(tr("Speed [km/h]"));
|
||||
_speedGraph->setXScale(0.001);
|
||||
_speedGraph->setYScale(3.6);
|
||||
_elevationGraph = new ElevationGraph;
|
||||
_speedGraph = new SpeedGraph;
|
||||
|
||||
_trackGraphs = new QTabWidget;
|
||||
_trackGraphs->addTab(_elevationGraph, tr("Elevation"));
|
||||
@ -207,17 +201,28 @@ void GUI::openFile()
|
||||
bool GUI::openFile(const QString &fileName)
|
||||
{
|
||||
GPX gpx;
|
||||
QVector<QPointF> elevation;
|
||||
QVector<QPointF> speed;
|
||||
QVector<QPointF> track;
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (gpx.loadFile(fileName)) {
|
||||
_elevationGraph->loadData(gpx.elevationGraph());
|
||||
_speedGraph->loadData(gpx.speedGraph());
|
||||
_track->loadData(gpx.track());
|
||||
gpx.elevationGraph(elevation);
|
||||
gpx.speedGraph(speed);
|
||||
gpx.track(track);
|
||||
|
||||
_elevationGraph->loadData(elevation);
|
||||
_speedGraph->loadData(speed);
|
||||
_track->loadData(track);
|
||||
if (_showPOIAction->isChecked())
|
||||
_track->loadPOI(_poi);
|
||||
|
||||
_fileActionGroup->setEnabled(true);
|
||||
_fileName->setText(fileName);
|
||||
|
||||
if (++_files > 1)
|
||||
_fileName->setText(tr("%1 tracks").arg(_files));
|
||||
else
|
||||
_fileName->setText(fileName);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@ -283,6 +288,8 @@ void GUI::saveFile(const QString &fileName)
|
||||
|
||||
void GUI::closeFile()
|
||||
{
|
||||
_files = 0;
|
||||
|
||||
_elevationGraph->clear();
|
||||
_speedGraph->clear();
|
||||
_track->clear();
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include <QFileInfoList>
|
||||
#include "poi.h"
|
||||
|
||||
class Graph;
|
||||
class ElevationGraph;
|
||||
class SpeedGraph;
|
||||
class Track;
|
||||
|
||||
class GUI : public QMainWindow
|
||||
@ -70,8 +71,8 @@ private:
|
||||
QLabel *_fileName;
|
||||
QLabel *_zoom;
|
||||
|
||||
Graph *_elevationGraph;
|
||||
Graph *_speedGraph;
|
||||
ElevationGraph *_elevationGraph;
|
||||
SpeedGraph *_speedGraph;
|
||||
Track *_track;
|
||||
|
||||
POI _poi;
|
||||
@ -80,6 +81,7 @@ private:
|
||||
int _dirIndex;
|
||||
|
||||
QString _saveFileName;
|
||||
unsigned _files;
|
||||
};
|
||||
|
||||
#endif // GUI_H
|
||||
|
70
src/infoitem.cpp
Normal file
70
src/infoitem.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include <QFont>
|
||||
#include <QPainter>
|
||||
#include "infoitem.h"
|
||||
|
||||
#define FONT_FAMILY "Arial"
|
||||
#define FONT_SIZE 12
|
||||
#define PADDING 10
|
||||
|
||||
InfoItem::InfoItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QRectF InfoItem::boundingRect() const
|
||||
{
|
||||
QFont font;
|
||||
font.setPixelSize(FONT_SIZE);
|
||||
font.setFamily(FONT_FAMILY);
|
||||
QFontMetrics fm(font);
|
||||
QMap<QString, QString>::const_iterator i;
|
||||
int width = 0;
|
||||
|
||||
if (_map.isEmpty())
|
||||
return QRectF();
|
||||
|
||||
for (i = _map.constBegin(); i != _map.constEnd(); i++) {
|
||||
width += fm.width(i.key() + ": ");
|
||||
width += fm.width(i.value()) + ((i == _map.end() - 1) ? 0 : PADDING);
|
||||
}
|
||||
|
||||
return QRectF(0, 0, width, fm.height());
|
||||
}
|
||||
|
||||
void InfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
QFont font;
|
||||
font.setPixelSize(FONT_SIZE);
|
||||
font.setFamily(FONT_FAMILY);
|
||||
painter->setFont(font);
|
||||
QFontMetrics fm(font);
|
||||
QMap<QString, QString>::const_iterator i;
|
||||
int width = 0;
|
||||
|
||||
for (i = _map.constBegin(); i != _map.constEnd(); i++) {
|
||||
painter->drawText(width, fm.height() - fm.descent(), i.key() + ": ");
|
||||
width += fm.width(i.key() + ": ");
|
||||
painter->drawText(width, fm.height() - fm.descent(), i.value());
|
||||
width += fm.width(i.value()) + ((i == _map.end() - 1) ? 0 : PADDING);
|
||||
if (i != _map.end() - 1) {
|
||||
painter->save();
|
||||
painter->setPen(Qt::gray);
|
||||
painter->drawLine(width - PADDING/2, fm.descent(),
|
||||
width - PADDING/2, fm.height() - fm.descent());
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
painter->setPen(Qt::red);
|
||||
painter->drawRect(boundingRect());
|
||||
*/
|
||||
}
|
||||
|
||||
void InfoItem::insert(const QString &key, const QString &value)
|
||||
{
|
||||
_map.insert(key, value);
|
||||
}
|
22
src/infoitem.h
Normal file
22
src/infoitem.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef INFOITEM_H
|
||||
#define INFOITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QMap>
|
||||
|
||||
class InfoItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
InfoItem();
|
||||
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget);
|
||||
|
||||
void insert(const QString &key, const QString &value);
|
||||
|
||||
private:
|
||||
QMap<QString, QString> _map;
|
||||
};
|
||||
|
||||
#endif // INFOITEM_H
|
56
src/speedgraph.cpp
Normal file
56
src/speedgraph.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "speedgraph.h"
|
||||
|
||||
SpeedGraph::SpeedGraph()
|
||||
{
|
||||
_max = 0;
|
||||
|
||||
Graph::setXLabel(tr("Distance"));
|
||||
Graph::setYLabel(tr("Speed"));
|
||||
Graph::setXUnits(tr("km"));
|
||||
Graph::setYUnits(tr("km/h"));
|
||||
Graph::setXScale(0.001);
|
||||
Graph::setYScale(3.6);
|
||||
}
|
||||
|
||||
void SpeedGraph::loadData(const QVector<QPointF> &data)
|
||||
{
|
||||
qreal max = 0, sum = 0, avg, distance, w;
|
||||
|
||||
distance = (data.at(data.size() - 1).x() - data.at(0).x());
|
||||
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
qreal val = data.at(i).y();
|
||||
|
||||
sum += val;
|
||||
|
||||
if (val > max)
|
||||
max = val;
|
||||
}
|
||||
avg = sum / data.size();
|
||||
|
||||
_avg.append(QPointF(avg, distance));
|
||||
|
||||
sum = 0; w = 0;
|
||||
for (QList<QPointF>::iterator it = _avg.begin(); it != _avg.end(); it++) {
|
||||
sum += it->x() * it->y();
|
||||
w += it->y();
|
||||
}
|
||||
avg = sum / w;
|
||||
|
||||
_max = qMax(_max, max);
|
||||
|
||||
addInfo(tr("Average"), QString::number(avg * _yScale, 'f', 1)
|
||||
+ " " + _yUnits);
|
||||
addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1)
|
||||
+ " " + _yUnits);
|
||||
|
||||
Graph::loadData(data);
|
||||
}
|
||||
|
||||
void SpeedGraph::clear()
|
||||
{
|
||||
_max = 0;
|
||||
_avg.clear();
|
||||
|
||||
Graph::clear();
|
||||
}
|
20
src/speedgraph.h
Normal file
20
src/speedgraph.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef SPEEDGRAPH_H
|
||||
#define SPEEDGRAPH_H
|
||||
|
||||
#include <QList>
|
||||
#include "graph.h"
|
||||
|
||||
class SpeedGraph : public Graph
|
||||
{
|
||||
public:
|
||||
SpeedGraph();
|
||||
|
||||
void loadData(const QVector<QPointF> &data);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
qreal _max;
|
||||
QList<QPointF> _avg;
|
||||
};
|
||||
|
||||
#endif // SPEEDGRAPH_H
|
@ -62,7 +62,6 @@ void Track::loadData(const QVector<QPointF> &track)
|
||||
mi->setPos(pi->path().pointAtPercent(0));
|
||||
_markers.append(mi);
|
||||
|
||||
|
||||
for (int i = 0; i < _trackPaths.size(); i++) {
|
||||
_markers.at(i)->setTransform(t);
|
||||
_scene->addItem(_markers.at(i));
|
||||
|
Loading…
Reference in New Issue
Block a user