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:
parent
b398f04839
commit
da81839529
65
src/gpx.cpp
65
src/gpx.cpp
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user