mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-01-18 11:52:08 +01:00
Fixed broken graph handling
This commit is contained in:
parent
e9b32fb582
commit
1957a51570
@ -71,15 +71,15 @@ void ElevationGraph::loadGraph(const Graph &graph, Type type, PathItem *path)
|
|||||||
qreal ascent = 0, descent = 0;
|
qreal ascent = 0, descent = 0;
|
||||||
qreal min, max;
|
qreal min, max;
|
||||||
|
|
||||||
if (graph.y.count() < 2) {
|
if (graph.size() < 2) {
|
||||||
skipColor();
|
skipColor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
max = min = graph.y.at(0);
|
max = min = graph.at(0).y();
|
||||||
for (int j = 1; j < graph.y.size(); j++) {
|
for (int j = 1; j < graph.size(); j++) {
|
||||||
qreal cur = graph.y.at(j);
|
qreal cur = graph.at(j).y();
|
||||||
qreal prev = graph.y.at(j-1);
|
qreal prev = graph.at(j-1).y();
|
||||||
|
|
||||||
if (cur > prev)
|
if (cur > prev)
|
||||||
ascent += cur - prev;
|
ascent += cur - prev;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "graphtab.h"
|
#include "graphtab.h"
|
||||||
|
|
||||||
class GPX;
|
class GPX;
|
||||||
class Graph;
|
|
||||||
class PathItem;
|
class PathItem;
|
||||||
|
|
||||||
class ElevationGraph : public GraphTab
|
class ElevationGraph : public GraphTab
|
||||||
|
25
src/graph.h
25
src/graph.h
@ -2,15 +2,30 @@
|
|||||||
#define GRAPH_H
|
#define GRAPH_H
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
class Graph
|
enum GraphType {Distance, Time};
|
||||||
|
|
||||||
|
class GraphPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type {Distance, Time};
|
GraphPoint(qreal s = NAN, qreal t = NAN, qreal y = NAN)
|
||||||
|
: _s(s), _t(t), _y(y) {}
|
||||||
|
|
||||||
QVector<qreal> distance;
|
qreal s() const {return _s;}
|
||||||
QVector<qreal> time;
|
qreal t() const {return _t;}
|
||||||
QVector<qreal> y;
|
qreal y() const {return _y;}
|
||||||
|
|
||||||
|
void setS(qreal s) {_s = s;}
|
||||||
|
void setT(qreal t) {_t = t;}
|
||||||
|
void setY(qreal y) {_y = y;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
qreal _s;
|
||||||
|
qreal _t;
|
||||||
|
qreal _y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QVector<GraphPoint> Graph;
|
||||||
|
|
||||||
#endif // GRAPH_H
|
#endif // GRAPH_H
|
||||||
|
@ -33,21 +33,30 @@ static qreal yAtX(const QPainterPath &path, qreal x)
|
|||||||
return l.pointAt((x - l.p1().x()) / (l.p2().x() - l.p1().x())).y();
|
return l.pointAt((x - l.p1().x()) / (l.p2().x() - l.p1().x())).y();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasTime(const Graph &graph)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < graph.count(); i++)
|
||||||
|
if (std::isnan(graph.at(i).t()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent)
|
GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent)
|
||||||
: QGraphicsObject(parent)
|
: QGraphicsObject(parent)
|
||||||
{
|
{
|
||||||
_id = 0;
|
_id = 0;
|
||||||
_pen = QPen(QBrush(Qt::SolidPattern), 0);
|
_pen = QPen(QBrush(Qt::SolidPattern), 0);
|
||||||
_type = Graph::Distance;
|
_type = Distance;
|
||||||
|
|
||||||
_distancePath.moveTo(graph.distance.first(), -graph.y.first());
|
_distancePath.moveTo(graph.first().s(), -graph.first().y());
|
||||||
for (int i = 1; i < graph.y.size(); i++)
|
for (int i = 1; i < graph.size(); i++)
|
||||||
_distancePath.lineTo(graph.distance.at(i), -graph.y.at(i));
|
_distancePath.lineTo(graph.at(i).s(), -graph.at(i).y());
|
||||||
|
|
||||||
if (!graph.time.isEmpty()) {
|
if (hasTime(graph)) {
|
||||||
_timePath.moveTo(graph.time.first(), -graph.y.first());
|
_timePath.moveTo(graph.first().t(), -graph.first().y());
|
||||||
for (int i = 1; i < graph.y.size(); i++)
|
for (int i = 1; i < graph.size(); i++)
|
||||||
_timePath.lineTo(graph.time.at(i), -graph.y.at(i));
|
_timePath.lineTo(graph.at(i).t(), -graph.at(i).y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +67,7 @@ void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
|
|
||||||
painter->setPen(_pen);
|
painter->setPen(_pen);
|
||||||
painter->drawPath((_type == Graph::Distance) ? _distancePath : _timePath);
|
painter->drawPath((_type == Distance) ? _distancePath : _timePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphItem::setColor(const QColor &color)
|
void GraphItem::setColor(const QColor &color)
|
||||||
@ -69,7 +78,7 @@ void GraphItem::setColor(const QColor &color)
|
|||||||
|
|
||||||
qreal GraphItem::yAtX(qreal x)
|
qreal GraphItem::yAtX(qreal x)
|
||||||
{
|
{
|
||||||
return ::yAtX((_type == Graph::Distance) ? _distancePath : _timePath, x);
|
return ::yAtX((_type == Distance) ? _distancePath : _timePath, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal GraphItem::distanceAtTime(qreal time)
|
qreal GraphItem::distanceAtTime(qreal time)
|
||||||
@ -103,7 +112,7 @@ qreal GraphItem::distanceAtTime(qreal time)
|
|||||||
|
|
||||||
void GraphItem::emitSliderPositionChanged(qreal pos)
|
void GraphItem::emitSliderPositionChanged(qreal pos)
|
||||||
{
|
{
|
||||||
if (_type == Graph::Time) {
|
if (_type == Time) {
|
||||||
if (!_timePath.isEmpty()) {
|
if (!_timePath.isEmpty()) {
|
||||||
if (pos <= _timePath.elementAt(_timePath.elementCount() - 1).x)
|
if (pos <= _timePath.elementAt(_timePath.elementCount() - 1).x)
|
||||||
emit sliderPositionChanged(distanceAtTime(pos));
|
emit sliderPositionChanged(distanceAtTime(pos));
|
||||||
|
@ -13,12 +13,12 @@ public:
|
|||||||
GraphItem(const Graph &graph, QGraphicsItem *parent = 0);
|
GraphItem(const Graph &graph, QGraphicsItem *parent = 0);
|
||||||
|
|
||||||
QRectF boundingRect() const
|
QRectF boundingRect() const
|
||||||
{return (_type == Graph::Distance) ? _distancePath.boundingRect()
|
{return (_type == Distance) ? _distancePath.boundingRect()
|
||||||
: _timePath.boundingRect();}
|
: _timePath.boundingRect();}
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
QWidget *widget);
|
QWidget *widget);
|
||||||
|
|
||||||
void setGraphType(Graph::Type type) {_type = type;}
|
void setGraphType(GraphType type) {_type = type;}
|
||||||
int id() const {return _id;}
|
int id() const {return _id;}
|
||||||
void setId(int id) {_id = id;}
|
void setId(int id) {_id = id;}
|
||||||
void setColor(const QColor &color);
|
void setColor(const QColor &color);
|
||||||
@ -36,7 +36,7 @@ private:
|
|||||||
int _id;
|
int _id;
|
||||||
QPen _pen;
|
QPen _pen;
|
||||||
QPainterPath _distancePath, _timePath;
|
QPainterPath _distancePath, _timePath;
|
||||||
Graph::Type _type;
|
GraphType _type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GRAPHITEM_H
|
#endif // GRAPHITEM_H
|
||||||
|
@ -59,7 +59,7 @@ GraphView::GraphView(QWidget *parent)
|
|||||||
_sliderPos = 0;
|
_sliderPos = 0;
|
||||||
|
|
||||||
_units = Metric;
|
_units = Metric;
|
||||||
_graphType = Graph::Distance;
|
_graphType = Distance;
|
||||||
|
|
||||||
setGraphType(_graphType);
|
setGraphType(_graphType);
|
||||||
setUnits(_units);
|
setUnits(_units);
|
||||||
@ -105,7 +105,7 @@ void GraphView::setYUnits(const QString &units)
|
|||||||
|
|
||||||
void GraphView::setXUnits()
|
void GraphView::setXUnits()
|
||||||
{
|
{
|
||||||
if (_graphType == Graph::Distance) {
|
if (_graphType == Distance) {
|
||||||
if (_units == Metric) {
|
if (_units == Metric) {
|
||||||
if (bounds().width() < KMINM) {
|
if (bounds().width() < KMINM) {
|
||||||
_xUnits = tr("m");
|
_xUnits = tr("m");
|
||||||
@ -145,7 +145,7 @@ void GraphView::setUnits(Units units)
|
|||||||
setXUnits();
|
setXUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::setGraphType(Graph::Type type)
|
void GraphView::setGraphType(GraphType type)
|
||||||
{
|
{
|
||||||
_graphType = type;
|
_graphType = type;
|
||||||
_bounds = QRectF();
|
_bounds = QRectF();
|
||||||
@ -155,7 +155,7 @@ void GraphView::setGraphType(Graph::Type type)
|
|||||||
updateBounds(_graphs.at(i)->boundingRect());
|
updateBounds(_graphs.at(i)->boundingRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Graph::Distance)
|
if (type == Distance)
|
||||||
_xLabel = tr("Distance");
|
_xLabel = tr("Distance");
|
||||||
else
|
else
|
||||||
_xLabel = tr("Time");
|
_xLabel = tr("Time");
|
||||||
@ -166,7 +166,7 @@ void GraphView::setGraphType(Graph::Type type)
|
|||||||
|
|
||||||
void GraphView::loadGraph(const Graph &graph, PathItem *path, int id)
|
void GraphView::loadGraph(const Graph &graph, PathItem *path, int id)
|
||||||
{
|
{
|
||||||
if (graph.y.size() < 2)
|
if (graph.size() < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GraphItem *gi = new GraphItem(graph);
|
GraphItem *gi = new GraphItem(graph);
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void showGraph(bool show, int id = 0);
|
void showGraph(bool show, int id = 0);
|
||||||
void setGraphType(Graph::Type type);
|
void setGraphType(GraphType type);
|
||||||
void setUnits(Units units);
|
void setUnits(Units units);
|
||||||
|
|
||||||
const QString &yLabel() const {return _yLabel;}
|
const QString &yLabel() const {return _yLabel;}
|
||||||
@ -113,7 +113,7 @@ private:
|
|||||||
Palette _palette;
|
Palette _palette;
|
||||||
|
|
||||||
Units _units;
|
Units _units;
|
||||||
Graph::Type _graphType;
|
GraphType _graphType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GRAPHVIEW_H
|
#endif // GRAPHVIEW_H
|
||||||
|
@ -1096,13 +1096,13 @@ void GUI::setImperialUnits()
|
|||||||
void GUI::setDistanceGraph()
|
void GUI::setDistanceGraph()
|
||||||
{
|
{
|
||||||
for (int i = 0; i <_tabs.count(); i++)
|
for (int i = 0; i <_tabs.count(); i++)
|
||||||
_tabs.at(i)->setGraphType(Graph::Distance);
|
_tabs.at(i)->setGraphType(Distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::setTimeGraph()
|
void GUI::setTimeGraph()
|
||||||
{
|
{
|
||||||
for (int i = 0; i <_tabs.count(); i++)
|
for (int i = 0; i <_tabs.count(); i++)
|
||||||
_tabs.at(i)->setGraphType(Graph::Time);
|
_tabs.at(i)->setGraphType(Time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::next()
|
void GUI::next()
|
||||||
@ -1208,7 +1208,7 @@ void GUI::writeSettings()
|
|||||||
settings.beginGroup(GRAPH_SETTINGS_GROUP);
|
settings.beginGroup(GRAPH_SETTINGS_GROUP);
|
||||||
settings.setValue(SHOW_GRAPHS_SETTING, _showGraphsAction->isChecked());
|
settings.setValue(SHOW_GRAPHS_SETTING, _showGraphsAction->isChecked());
|
||||||
settings.setValue(GRAPH_TYPE_SETTING, _timeGraphAction->isChecked()
|
settings.setValue(GRAPH_TYPE_SETTING, _timeGraphAction->isChecked()
|
||||||
? Graph::Time : Graph::Distance);
|
? Time : Distance);
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
settings.beginGroup(POI_SETTINGS_GROUP);
|
settings.beginGroup(POI_SETTINGS_GROUP);
|
||||||
@ -1280,8 +1280,7 @@ void GUI::readSettings()
|
|||||||
showGraphs(false);
|
showGraphs(false);
|
||||||
else
|
else
|
||||||
_showGraphsAction->setChecked(true);
|
_showGraphsAction->setChecked(true);
|
||||||
if (settings.value(GRAPH_TYPE_SETTING, Graph::Distance).toInt()
|
if (settings.value(GRAPH_TYPE_SETTING, Distance).toInt() == Time) {
|
||||||
== Graph::Time) {
|
|
||||||
setTimeGraph();
|
setTimeGraph();
|
||||||
_timeGraphAction->setChecked(true);
|
_timeGraphAction->setChecked(true);
|
||||||
} else
|
} else
|
||||||
|
@ -30,14 +30,14 @@ void HeartRateGraph::loadGPX(const GPX &gpx, const QList<PathItem *> &paths)
|
|||||||
const Graph &graph = gpx.tracks().at(i)->heartRate();
|
const Graph &graph = gpx.tracks().at(i)->heartRate();
|
||||||
qreal sum = 0, w = 0;
|
qreal sum = 0, w = 0;
|
||||||
|
|
||||||
if (graph.y.count() < 2) {
|
if (graph.size() < 2) {
|
||||||
skipColor();
|
skipColor();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j < graph.y.size(); j++) {
|
for (int j = 1; j < graph.size(); j++) {
|
||||||
qreal ds = graph.distance.at(j) - graph.distance.at(j-1);
|
qreal ds = graph.at(j).s() - graph.at(j-1).s();
|
||||||
sum += graph.y.at(j) * ds;
|
sum += graph.at(j).y() * ds;
|
||||||
w += ds;
|
w += ds;
|
||||||
}
|
}
|
||||||
_avg.append(QPointF(gpx.tracks().at(i)->distance(), sum/w));
|
_avg.append(QPointF(gpx.tracks().at(i)->distance(), sum/w));
|
||||||
|
@ -5,10 +5,10 @@ Route::Route(const QVector<Waypoint> &data) : _data(data)
|
|||||||
{
|
{
|
||||||
qreal dist = 0;
|
qreal dist = 0;
|
||||||
|
|
||||||
_dd.append(dist);
|
_distance.append(dist);
|
||||||
for (int i = 1; i < data.count(); i++) {
|
for (int i = 1; i < data.count(); i++) {
|
||||||
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates());
|
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates());
|
||||||
_dd.append(dist);
|
_distance.append(dist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,14 +18,13 @@ Graph Route::elevation() const
|
|||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++)
|
for (int i = 0; i < _data.size(); i++)
|
||||||
if (_data.at(i).hasElevation())
|
if (_data.at(i).hasElevation())
|
||||||
graph.y.append(_data.at(i).elevation() - _data.at(i).geoidHeight());
|
graph.append(GraphPoint(_distance.at(i), NAN,
|
||||||
|
_data.at(i).elevation() - _data.at(i).geoidHeight()));
|
||||||
graph.distance = _dd;
|
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Route::distance() const
|
qreal Route::distance() const
|
||||||
{
|
{
|
||||||
return (_dd.isEmpty()) ? 0 : _dd.last();
|
return (_distance.isEmpty()) ? 0 : _distance.last();
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,11 @@ public:
|
|||||||
|
|
||||||
qreal distance() const;
|
qreal distance() const;
|
||||||
|
|
||||||
bool isNull() const {return (_dd.count() < 2);}
|
bool isNull() const {return (_data.count() < 2);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QVector<Waypoint> &_data;
|
const QVector<Waypoint> &_data;
|
||||||
QVector<qreal> _dd;
|
QVector<qreal> _distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ROUTE_H
|
#endif // ROUTE_H
|
||||||
|
@ -29,7 +29,7 @@ void SpeedGraph::loadGPX(const GPX &gpx, const QList<PathItem *> &paths)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < gpx.tracks().count(); i++) {
|
for (int i = 0; i < gpx.tracks().count(); i++) {
|
||||||
const Graph &graph = gpx.tracks().at(i)->speed();
|
const Graph &graph = gpx.tracks().at(i)->speed();
|
||||||
if (graph.y.count() < 2) {
|
if (graph.size() < 2) {
|
||||||
skipColor();
|
skipColor();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ void TemperatureGraph::loadGPX(const GPX &gpx, const QList<PathItem *> &paths)
|
|||||||
const Graph &graph = gpx.tracks().at(i)->temperature();
|
const Graph &graph = gpx.tracks().at(i)->temperature();
|
||||||
qreal sum = 0, w = 0;
|
qreal sum = 0, w = 0;
|
||||||
|
|
||||||
if (graph.y.count() < 2) {
|
if (graph.size() < 2) {
|
||||||
skipColor();
|
skipColor();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j < graph.y.size(); j++) {
|
for (int j = 1; j < graph.size(); j++) {
|
||||||
qreal ds = graph.distance.at(j) - graph.distance.at(j-1);
|
qreal ds = graph.at(j).s() - graph.at(j-1).s();
|
||||||
sum += graph.y.at(j) * ds;
|
sum += graph.at(j).y() * ds;
|
||||||
w += ds;
|
w += ds;
|
||||||
}
|
}
|
||||||
_avg.append(QPointF(gpx.tracks().at(i)->distance(), sum/w));
|
_avg.append(QPointF(gpx.tracks().at(i)->distance(), sum/w));
|
||||||
|
122
src/track.cpp
122
src/track.cpp
@ -8,39 +8,40 @@
|
|||||||
#define WINDOW_HE 11
|
#define WINDOW_HE 11
|
||||||
#define WINDOW_HF 3
|
#define WINDOW_HF 3
|
||||||
|
|
||||||
static bool lt(qreal v1, qreal v2)
|
|
||||||
|
static bool lt(const GraphPoint &v1, const GraphPoint &v2)
|
||||||
{
|
{
|
||||||
return v1 < v2;
|
return v1.y() < v2.y();
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal median(QVector<qreal> v)
|
static qreal median(QVector<GraphPoint> v)
|
||||||
{
|
{
|
||||||
qSort(v.begin(), v.end(), lt);
|
qSort(v.begin(), v.end(), lt);
|
||||||
return v.at(v.size() / 2);
|
return v.at(v.size() / 2).y();
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal MAD(QVector<qreal> v, qreal m)
|
static qreal MAD(QVector<GraphPoint> v, qreal m)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < v.size(); i++)
|
for (int i = 0; i < v.size(); i++)
|
||||||
v[i] = (qAbs(v.at(i) - m));
|
v[i].setY(qAbs(v.at(i).y() - m));
|
||||||
qSort(v.begin(), v.end(), lt);
|
qSort(v.begin(), v.end(), lt);
|
||||||
return v.at(v.size() / 2);
|
return v.at(v.size() / 2).y();
|
||||||
}
|
}
|
||||||
|
|
||||||
static QVector<qreal> eliminate(const QVector<qreal> &v, int window)
|
static QVector<GraphPoint> eliminate(const QVector<GraphPoint> &v, int window)
|
||||||
{
|
{
|
||||||
QList<int> rm;
|
QList<int> rm;
|
||||||
QVector<qreal> ret;
|
QVector<GraphPoint> ret;
|
||||||
qreal m, M;
|
qreal m, M;
|
||||||
|
|
||||||
|
|
||||||
if (v.size() < window)
|
if (v.size() < window)
|
||||||
return QVector<qreal>(v);
|
return QVector<GraphPoint>(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) - m)) / M) > 3.5)
|
if (qAbs((0.6745 * (v.at(i).y() - m)) / M) > 3.5)
|
||||||
rm.append(i);
|
rm.append(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,26 +56,26 @@ static QVector<qreal> eliminate(const QVector<qreal> &v, int window)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QVector<qreal> filter(const QVector<qreal> &v, int window)
|
static QVector<GraphPoint> filter(const QVector<GraphPoint> &v, int window)
|
||||||
{
|
{
|
||||||
qreal acc = 0;
|
qreal acc = 0;
|
||||||
QVector<qreal> ret;
|
QVector<GraphPoint> ret;
|
||||||
|
|
||||||
if (v.size() < window)
|
if (v.size() < window)
|
||||||
return QVector<qreal>(v);
|
return QVector<GraphPoint>(v);
|
||||||
|
|
||||||
for (int i = 0; i < window; i++)
|
for (int i = 0; i < window; i++)
|
||||||
acc += v.at(i);
|
acc += v.at(i).y();
|
||||||
for (int i = 0; i <= window/2; i++)
|
for (int i = 0; i <= window/2; i++)
|
||||||
ret.append(acc/window);
|
ret.append(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
|
||||||
|
|
||||||
for (int i = window/2 + 1; i < v.size() - window/2; i++) {
|
for (int i = window/2 + 1; i < v.size() - window/2; i++) {
|
||||||
acc += v.at(i + window/2) - v.at(i - (window/2 + 1));
|
acc += v.at(i + window/2).y() - v.at(i - (window/2 + 1)).y();
|
||||||
ret.append(acc/window);
|
ret.append(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = v.size() - window/2; i < v.size(); i++)
|
for (int i = v.size() - window/2; i < v.size(); i++)
|
||||||
ret.append(acc/window);
|
ret.append(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -82,112 +83,93 @@ static QVector<qreal> filter(const QVector<qreal> &v, int window)
|
|||||||
Track::Track(const QVector<Trackpoint> &data) : _data(data)
|
Track::Track(const QVector<Trackpoint> &data) : _data(data)
|
||||||
{
|
{
|
||||||
qreal dist = 0;
|
qreal dist = 0;
|
||||||
qint64 time;
|
|
||||||
|
|
||||||
_dd.append(0);
|
_distance.append(0);
|
||||||
_td.append(0);
|
_time.append(0);
|
||||||
for (int i = 1; i < data.count(); i++) {
|
for (int i = 1; i < data.count(); i++) {
|
||||||
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates());
|
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates());
|
||||||
_dd.append(dist);
|
_distance.append(dist);
|
||||||
if (data.first().hasTimestamp() && data.at(i).hasTimestamp()) {
|
|
||||||
time = _data.first().timestamp().msecsTo(_data.at(i).timestamp());
|
|
||||||
_td.append((qreal)time / 1000.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_dd.size() != _td.size())
|
if (data.first().hasTimestamp() && data.at(i).hasTimestamp())
|
||||||
_td.clear();
|
_time.append(_data.first().timestamp().msecsTo(
|
||||||
|
_data.at(i).timestamp()) / 1000.0);
|
||||||
|
else
|
||||||
|
_time.append(NAN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph Track::elevation() const
|
Graph Track::elevation() const
|
||||||
{
|
{
|
||||||
Graph ret;
|
QVector<GraphPoint> raw;
|
||||||
QVector<qreal> raw;
|
|
||||||
|
|
||||||
|
|
||||||
if (!_data.size())
|
if (!_data.size())
|
||||||
return ret;
|
return raw;
|
||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++)
|
for (int i = 0; i < _data.size(); i++)
|
||||||
if (_data.at(i).hasElevation())
|
if (_data.at(i).hasElevation())
|
||||||
raw.append(_data.at(i).elevation() - _data.at(i).geoidHeight());
|
raw.append(GraphPoint(_distance.at(i), _time.at(i),
|
||||||
|
_data.at(i).elevation() - _data.at(i).geoidHeight()));
|
||||||
|
|
||||||
ret.y = filter(raw, WINDOW_EF);
|
return filter(raw, WINDOW_EF);
|
||||||
ret.distance = _dd;
|
|
||||||
ret.time = _td;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph Track::speed() const
|
Graph Track::speed() const
|
||||||
{
|
{
|
||||||
Graph ret;
|
QVector<GraphPoint> raw;
|
||||||
qreal v, ds, dt;
|
qreal v, ds, dt;
|
||||||
QVector<qreal> raw;
|
|
||||||
|
|
||||||
|
|
||||||
if (!_data.size())
|
if (!_data.size())
|
||||||
return ret;
|
return raw;
|
||||||
|
|
||||||
raw.append(0);
|
raw.append(GraphPoint(_distance.at(0), _time.at(0), 0));
|
||||||
for (int i = 1; i < _data.size(); i++) {
|
for (int i = 1; i < _data.size(); i++) {
|
||||||
if (_data.at(i).hasSpeed())
|
if (_data.at(i).hasSpeed())
|
||||||
v = _data.at(i).speed();
|
v = _data.at(i).speed();
|
||||||
else if (_data.at(i).hasTimestamp()) {
|
else if (_data.at(i).hasTimestamp() && _data.at(i-1).hasTimestamp()) {
|
||||||
dt = _td.at(i) - _td.at(i-1);
|
dt = _time.at(i) - _time.at(i-1);
|
||||||
if (!dt)
|
if (!dt)
|
||||||
continue;
|
continue;
|
||||||
ds = _dd.at(i) - _dd.at(i-1);
|
ds = _distance.at(i) - _distance.at(i-1);
|
||||||
v = ds / dt;
|
v = ds / dt;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
raw.append(v);
|
raw.append(GraphPoint(_distance.at(i), _time.at(i), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.y = filter(eliminate(raw, WINDOW_SE), WINDOW_SF);
|
return filter(eliminate(raw, WINDOW_SE), WINDOW_SF);
|
||||||
ret.distance = _dd;
|
|
||||||
ret.time = _td;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph Track::heartRate() const
|
Graph Track::heartRate() const
|
||||||
{
|
{
|
||||||
Graph ret;
|
QVector<GraphPoint> raw;
|
||||||
QVector<qreal> raw;
|
|
||||||
|
|
||||||
if (!_data.size())
|
if (!_data.size())
|
||||||
return ret;
|
return raw;
|
||||||
|
|
||||||
for (int i = 0; i < _data.count(); i++)
|
for (int i = 0; i < _data.count(); i++)
|
||||||
if (_data.at(i).hasHeartRate())
|
if (_data.at(i).hasHeartRate())
|
||||||
raw.append(_data.at(i).heartRate());
|
raw.append(GraphPoint(_distance.at(i), _time.at(i),
|
||||||
|
_data.at(i).heartRate()));
|
||||||
|
|
||||||
ret.y = filter(eliminate(raw, WINDOW_HE), WINDOW_HF);
|
return filter(eliminate(raw, WINDOW_HE), WINDOW_HF);
|
||||||
ret.distance = _dd;
|
|
||||||
ret.time = _td;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph Track::temperature() const
|
Graph Track::temperature() const
|
||||||
{
|
{
|
||||||
Graph ret;
|
QVector<GraphPoint> raw;
|
||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++)
|
for (int i = 0; i < _data.size(); i++)
|
||||||
if (_data.at(i).hasTemperature())
|
if (_data.at(i).hasTemperature())
|
||||||
ret.y.append(_data.at(i).temperature());
|
raw.append(GraphPoint(_distance.at(i), _time.at(i),
|
||||||
|
_data.at(i).temperature()));
|
||||||
|
|
||||||
ret.distance = _dd;
|
return Graph(raw);
|
||||||
ret.time = _td;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Track::distance() const
|
qreal Track::distance() const
|
||||||
{
|
{
|
||||||
return (_dd.isEmpty()) ? 0 : _dd.last();
|
return (_distance.isEmpty()) ? 0 : _distance.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Track::time() const
|
qreal Track::time() const
|
||||||
|
@ -21,12 +21,12 @@ public:
|
|||||||
qreal time() const;
|
qreal time() const;
|
||||||
QDateTime date() const;
|
QDateTime date() const;
|
||||||
|
|
||||||
bool isNull() const {return (_dd.count() < 2);}
|
bool isNull() const {return (_data.size() < 2);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QVector<Trackpoint> &_data;
|
const QVector<Trackpoint> &_data;
|
||||||
QVector<qreal> _dd;
|
QVector<qreal> _distance;
|
||||||
QVector<qreal> _td;
|
QVector<qreal> _time;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACK_H
|
#endif // TRACK_H
|
||||||
|
@ -45,7 +45,6 @@ TrackView::TrackView(QWidget *parent)
|
|||||||
_showRouteWaypoints = true;
|
_showRouteWaypoints = true;
|
||||||
|
|
||||||
_plot = false;
|
_plot = false;
|
||||||
//_markerPos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackView::~TrackView()
|
TrackView::~TrackView()
|
||||||
@ -68,7 +67,6 @@ PathItem *TrackView::addTrack(const Track &track)
|
|||||||
ti->setScale(1.0/_scale);
|
ti->setScale(1.0/_scale);
|
||||||
ti->setColor(_palette.color());
|
ti->setColor(_palette.color());
|
||||||
ti->setVisible(_showTracks);
|
ti->setVisible(_showTracks);
|
||||||
//ti->moveMarker(_markerPos);
|
|
||||||
_scene->addItem(ti);
|
_scene->addItem(ti);
|
||||||
|
|
||||||
return ti;
|
return ti;
|
||||||
@ -90,7 +88,6 @@ PathItem *TrackView::addRoute(const Route &route)
|
|||||||
ri->setVisible(_showRoutes);
|
ri->setVisible(_showRoutes);
|
||||||
ri->showWaypoints(_showRouteWaypoints);
|
ri->showWaypoints(_showRouteWaypoints);
|
||||||
ri->showWaypointLabels(_showWaypointLabels);
|
ri->showWaypointLabels(_showWaypointLabels);
|
||||||
//ri->moveMarker(_markerPos);
|
|
||||||
_scene->addItem(ri);
|
_scene->addItem(ri);
|
||||||
|
|
||||||
return ri;
|
return ri;
|
||||||
@ -490,23 +487,8 @@ void TrackView::clear()
|
|||||||
_scale = mapScale(_zoom);
|
_scale = mapScale(_zoom);
|
||||||
|
|
||||||
_scene->setSceneRect(QRectF());
|
_scene->setSceneRect(QRectF());
|
||||||
|
|
||||||
//_markerPos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void TrackView::movePositionMarker(qreal val)
|
|
||||||
{
|
|
||||||
_markerPos = val;
|
|
||||||
|
|
||||||
for (int i = 0; i < _tracks.size(); i++)
|
|
||||||
_tracks.at(i)->moveMarker(val);
|
|
||||||
|
|
||||||
for (int i = 0; i < _routes.size(); i++)
|
|
||||||
_routes.at(i)->moveMarker(val);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TrackView::showTracks(bool show)
|
void TrackView::showTracks(bool show)
|
||||||
{
|
{
|
||||||
_showTracks = show;
|
_showTracks = show;
|
||||||
|
@ -44,7 +44,6 @@ public:
|
|||||||
int waypointCount() const {return _waypoints.count();}
|
int waypointCount() const {return _waypoints.count();}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//void movePositionMarker(qreal val);
|
|
||||||
void redraw();
|
void redraw();
|
||||||
|
|
||||||
void setPOIOverlap(bool overlap);
|
void setPOIOverlap(bool overlap);
|
||||||
@ -104,7 +103,6 @@ private:
|
|||||||
bool _showRouteWaypoints;
|
bool _showRouteWaypoints;
|
||||||
|
|
||||||
bool _plot;
|
bool _plot;
|
||||||
//qreal _markerPos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACKVIEW_H
|
#endif // TRACKVIEW_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user