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

Yet another graph filtering change

This commit is contained in:
Martin Tůma 2015-10-16 18:28:47 +02:00
parent b398f04839
commit da81839529
5 changed files with 66 additions and 41 deletions

View File

@ -6,8 +6,9 @@
#include <QDebug>
#define ALPHA 0.5
#define WINDOW 11
#define WINDOW_EF 3
#define WINDOW_SE 11
#define WINDOW_SF 11
bool GPX::loadFile(const QString &fileName)
@ -30,20 +31,46 @@ bool GPX::loadFile(const QString &fileName)
return ret;
}
static QVector<QPointF> filter(const QVector<QPointF> &v, int window)
{
qreal acc = 0;
QVector<QPointF> ret;
if (v.size() < window)
return QVector<QPointF>(v);
for (int i = 0; i < window; i++)
acc += v.at(i).y();
for (int i = 0; i <= window/2; i++)
ret.append(QPointF(v.at(i).x(), acc/window));
for (int i = window/2 + 1; i < v.size() - window/2; i++) {
acc += v.at(i + window/2).y() - v.at(i - (window/2 + 1)).y();
ret.append(QPointF(v.at(i).x(), acc/window));
}
for (int i = v.size() - window/2; i < v.size(); i++)
ret.append(QPointF(v.at(i).x(), acc/window));
return ret;
}
void GPX::elevationGraph(QVector<QPointF> &graph) const
{
qreal dist = 0, dh, acc;
qreal dist = 0;
QVector<QPointF> raw;
if (!_data.size())
return;
graph.append(QPointF(0, _data.at(0).elevation));
raw.append(QPointF(0, _data.at(0).elevation));
for (int i = 1; i < _data.size(); i++) {
dist += llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
dh = _data.at(i).elevation;
acc = (i == 1) ? dh : (ALPHA * dh) + (1.0 - ALPHA) * acc;
graph.append(QPointF(dist, acc));
raw.append(QPointF(dist, _data.at(i).elevation));
}
graph = filter(raw, WINDOW_EF);
}
static bool lt(const QPointF &p1, const QPointF &p2)
@ -65,19 +92,19 @@ static qreal MAD(QVector<QPointF> v, qreal m)
return v.at(v.size() / 2).y();
}
static QVector<QPointF> filter(const QVector<QPointF> &v)
static QVector<QPointF> eliminate(const QVector<QPointF> &v, int window)
{
QList<int> rm;
QVector<QPointF> ret;
qreal m, M;
if (v.size() < WINDOW)
if (v.size() < window)
return QVector<QPointF>(v);
for (int i = WINDOW/2; i < v.size() - WINDOW/2; i++) {
m = median(v.mid(i - WINDOW/2, WINDOW));
M = MAD(v.mid(i - WINDOW/2, WINDOW), m);
for (int i = window/2; i < v.size() - window/2; i++) {
m = median(v.mid(i - window/2, window));
M = MAD(v.mid(i - window/2, window), m);
if (qAbs((0.6745 * (v.at(i).y() - m)) / M) > 3.5)
rm.append(i);
}
@ -117,7 +144,7 @@ void GPX::speedGraph(QVector<QPointF> &graph) const
raw.append(QPointF(dist, v));
}
graph = filter(raw);
graph = filter(eliminate(raw, WINDOW_SE), WINDOW_SF);
}
void GPX::track(QVector<QPointF> &track) const
@ -130,7 +157,7 @@ void GPX::track(QVector<QPointF> &track) const
}
}
qreal GPX::distance()
qreal GPX::distance() const
{
qreal dist = 0;
@ -140,7 +167,7 @@ qreal GPX::distance()
return dist;
}
qreal GPX::time()
qreal GPX::time() const
{
if (_data.size() < 2)
return 0;
@ -148,3 +175,11 @@ qreal GPX::time()
return (_data.at(0).timestamp.msecsTo(_data.at(_data.size() - 1).timestamp)
/ 1000.0);
}
QDateTime GPX::date() const
{
if (_data.size())
return _data.at(0).timestamp;
else
return QDateTime();
}

View File

@ -15,8 +15,9 @@ public:
void elevationGraph(QVector<QPointF> &graph) const;
void speedGraph(QVector<QPointF> &graph) const;
void track(QVector<QPointF> &track) const;
qreal distance();
qreal time();
qreal distance() const;
qreal time() const;
QDateTime date() const;
private:
Parser _parser;

View File

@ -229,7 +229,7 @@ bool GUI::openFile(const QString &fileName)
gpx.track(track);
_elevationGraph->loadData(elevation);
_speedGraph->loadData(speed);
_speedGraph->loadData(speed, gpx.time());
_track->loadData(track);
if (_showPOIAction->isChecked())
_track->loadPOI(_poi);

View File

@ -14,7 +14,7 @@ SpeedGraph::SpeedGraph()
Graph::setYScale(3.6);
}
void SpeedGraph::loadData(const QVector<QPointF> &data)
void SpeedGraph::loadData(const QVector<QPointF> &data, qreal time)
{
qreal max = 0, sum = 0, w = 0, avg;
qreal dist;
@ -23,37 +23,26 @@ void SpeedGraph::loadData(const QVector<QPointF> &data)
return;
dist = data.at(data.size() - 1).x() - data.at(0).x();
for (int i = 1; i < data.size(); i++) {
QPointF cur = data.at(i);
QPointF prev = data.at(i-1);
qreal ds = cur.x() - prev.x();
if (cur.y() == 0)
continue;
sum += ds;
w += ds / cur.y();
max = qMax(max, cur.y());
}
avg = sum / w;
avg = dist / time;
_avg.append(QPointF(dist, avg));
for (int i = 0; i < data.size(); i++)
max = qMax(max, data.at(i).y());
sum = 0; w = 0;
for (QList<QPointF>::iterator it = _avg.begin(); it != _avg.end(); it++) {
sum += it->y() * it->x();
w += it->x();
}
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);
addInfo(tr("Average"), QString::number(avg * _yScale, 'f', 1) + " "
+ _yUnits);
addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1) + " "
+ _yUnits);
Graph::loadData(data);
}

View File

@ -11,7 +11,7 @@ class SpeedGraph : public Graph
public:
SpeedGraph();
void loadData(const QVector<QPointF> &data);
void loadData(const QVector<QPointF> &data, qreal time);
void clear();
private: