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>
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
#define ALPHA 0.5
|
#define WINDOW_EF 3
|
||||||
#define WINDOW 11
|
#define WINDOW_SE 11
|
||||||
|
#define WINDOW_SF 11
|
||||||
|
|
||||||
|
|
||||||
bool GPX::loadFile(const QString &fileName)
|
bool GPX::loadFile(const QString &fileName)
|
||||||
@ -30,20 +31,46 @@ bool GPX::loadFile(const QString &fileName)
|
|||||||
return ret;
|
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
|
void GPX::elevationGraph(QVector<QPointF> &graph) const
|
||||||
{
|
{
|
||||||
qreal dist = 0, dh, acc;
|
qreal dist = 0;
|
||||||
|
QVector<QPointF> raw;
|
||||||
|
|
||||||
if (!_data.size())
|
if (!_data.size())
|
||||||
return;
|
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++) {
|
for (int i = 1; i < _data.size(); i++) {
|
||||||
dist += llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
|
dist += llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
|
||||||
dh = _data.at(i).elevation;
|
raw.append(QPointF(dist, _data.at(i).elevation));
|
||||||
acc = (i == 1) ? dh : (ALPHA * dh) + (1.0 - ALPHA) * acc;
|
|
||||||
graph.append(QPointF(dist, acc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graph = filter(raw, WINDOW_EF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lt(const QPointF &p1, const QPointF &p2)
|
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();
|
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;
|
QList<int> rm;
|
||||||
QVector<QPointF> ret;
|
QVector<QPointF> ret;
|
||||||
qreal m, M;
|
qreal m, M;
|
||||||
|
|
||||||
|
|
||||||
if (v.size() < WINDOW)
|
if (v.size() < window)
|
||||||
return QVector<QPointF>(v);
|
return QVector<QPointF>(v);
|
||||||
|
|
||||||
for (int i = WINDOW/2; i < v.size() - WINDOW/2; i++) {
|
for (int i = window/2; i < v.size() - window/2; i++) {
|
||||||
m = median(v.mid(i - WINDOW/2, WINDOW));
|
m = median(v.mid(i - window/2, window));
|
||||||
M = MAD(v.mid(i - WINDOW/2, WINDOW), m);
|
M = MAD(v.mid(i - window/2, window), m);
|
||||||
if (qAbs((0.6745 * (v.at(i).y() - m)) / M) > 3.5)
|
if (qAbs((0.6745 * (v.at(i).y() - m)) / M) > 3.5)
|
||||||
rm.append(i);
|
rm.append(i);
|
||||||
}
|
}
|
||||||
@ -117,7 +144,7 @@ void GPX::speedGraph(QVector<QPointF> &graph) const
|
|||||||
raw.append(QPointF(dist, v));
|
raw.append(QPointF(dist, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
graph = filter(raw);
|
graph = filter(eliminate(raw, WINDOW_SE), WINDOW_SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPX::track(QVector<QPointF> &track) const
|
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;
|
qreal dist = 0;
|
||||||
|
|
||||||
@ -140,7 +167,7 @@ qreal GPX::distance()
|
|||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal GPX::time()
|
qreal GPX::time() const
|
||||||
{
|
{
|
||||||
if (_data.size() < 2)
|
if (_data.size() < 2)
|
||||||
return 0;
|
return 0;
|
||||||
@ -148,3 +175,11 @@ qreal GPX::time()
|
|||||||
return (_data.at(0).timestamp.msecsTo(_data.at(_data.size() - 1).timestamp)
|
return (_data.at(0).timestamp.msecsTo(_data.at(_data.size() - 1).timestamp)
|
||||||
/ 1000.0);
|
/ 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 elevationGraph(QVector<QPointF> &graph) const;
|
||||||
void speedGraph(QVector<QPointF> &graph) const;
|
void speedGraph(QVector<QPointF> &graph) const;
|
||||||
void track(QVector<QPointF> &track) const;
|
void track(QVector<QPointF> &track) const;
|
||||||
qreal distance();
|
qreal distance() const;
|
||||||
qreal time();
|
qreal time() const;
|
||||||
|
QDateTime date() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Parser _parser;
|
Parser _parser;
|
||||||
|
@ -229,7 +229,7 @@ bool GUI::openFile(const QString &fileName)
|
|||||||
gpx.track(track);
|
gpx.track(track);
|
||||||
|
|
||||||
_elevationGraph->loadData(elevation);
|
_elevationGraph->loadData(elevation);
|
||||||
_speedGraph->loadData(speed);
|
_speedGraph->loadData(speed, gpx.time());
|
||||||
_track->loadData(track);
|
_track->loadData(track);
|
||||||
if (_showPOIAction->isChecked())
|
if (_showPOIAction->isChecked())
|
||||||
_track->loadPOI(_poi);
|
_track->loadPOI(_poi);
|
||||||
|
@ -14,7 +14,7 @@ SpeedGraph::SpeedGraph()
|
|||||||
Graph::setYScale(3.6);
|
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 max = 0, sum = 0, w = 0, avg;
|
||||||
qreal dist;
|
qreal dist;
|
||||||
@ -23,37 +23,26 @@ void SpeedGraph::loadData(const QVector<QPointF> &data)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
dist = data.at(data.size() - 1).x() - data.at(0).x();
|
dist = data.at(data.size() - 1).x() - data.at(0).x();
|
||||||
|
avg = dist / time;
|
||||||
|
|
||||||
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.append(QPointF(dist, avg));
|
_avg.append(QPointF(dist, avg));
|
||||||
|
|
||||||
|
for (int i = 0; i < data.size(); i++)
|
||||||
|
max = qMax(max, data.at(i).y());
|
||||||
|
|
||||||
|
|
||||||
sum = 0; w = 0;
|
sum = 0; w = 0;
|
||||||
for (QList<QPointF>::iterator it = _avg.begin(); it != _avg.end(); it++) {
|
for (QList<QPointF>::iterator it = _avg.begin(); it != _avg.end(); it++) {
|
||||||
sum += it->y() * it->x();
|
sum += it->y() * it->x();
|
||||||
w += it->x();
|
w += it->x();
|
||||||
}
|
}
|
||||||
avg = sum / w;
|
avg = sum / w;
|
||||||
|
|
||||||
_max = qMax(_max, max);
|
_max = qMax(_max, max);
|
||||||
|
|
||||||
addInfo(tr("Average"), QString::number(avg * _yScale, 'f', 1)
|
|
||||||
+ " " + _yUnits);
|
addInfo(tr("Average"), QString::number(avg * _yScale, 'f', 1) + " "
|
||||||
addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1)
|
+ _yUnits);
|
||||||
+ " " + _yUnits);
|
addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1) + " "
|
||||||
|
+ _yUnits);
|
||||||
|
|
||||||
Graph::loadData(data);
|
Graph::loadData(data);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ class SpeedGraph : public Graph
|
|||||||
public:
|
public:
|
||||||
SpeedGraph();
|
SpeedGraph();
|
||||||
|
|
||||||
void loadData(const QVector<QPointF> &data);
|
void loadData(const QVector<QPointF> &data, qreal time);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user