diff --git a/gpxsee.pro b/gpxsee.pro
index a594cc3e..df040db6 100644
--- a/gpxsee.pro
+++ b/gpxsee.pro
@@ -33,7 +33,8 @@ HEADERS += src/config.h \
src/graphview.h \
src/trackpoint.h \
src/waypointitem.h \
- src/palette.h
+ src/palette.h \
+ src/heartrategraph.h
SOURCES += src/main.cpp \
src/gui.cpp \
src/gpx.cpp \
@@ -57,7 +58,8 @@ SOURCES += src/main.cpp \
src/track.cpp \
src/graphview.cpp \
src/waypointitem.cpp \
- src/palette.cpp
+ src/palette.cpp \
+ src/heartrategraph.cpp
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts
macx:ICON = icons/gpxsee.icns
diff --git a/lang/gpxsee_cs.ts b/lang/gpxsee_cs.ts
index 67166b53..19739463 100644
--- a/lang/gpxsee_cs.ts
+++ b/lang/gpxsee_cs.ts
@@ -15,43 +15,43 @@
-
+
km
-
+
m
-
+
Stoupání
-
+
Klesání
-
+
Minimum
-
+
mi
-
+
ft
-
+
Maximum
@@ -59,352 +59,396 @@
GUI
-
+
O Qt
-
+
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
-
+
Otevřít soubor
-
+
Uložit jako
-
+
Otevřít POI soubor
-
+
Otevřít
-
+
Ukončit
-
-
-
+
+
+
Ovládací klávesy
-
+
Uložit
-
+
Zavřít
-
+
Znovu načíst
-
+
Zobrazit
-
-
+
+
Soubor
-
-
-
+
+
+
Zdroje dat
-
+
Nahrát POI soubor
-
+
Zavřit soubory POI
-
+
Zobrazit POI
-
+
Zobrazit mapu
-
+
Zobrazovat grafy
-
+
Zobrazovat nástrojové lišty
-
+
Metrické
-
+
Imperiální
-
+
Následující
-
+
Předchozí
-
+
Poslední
-
+
První
-
+
Mapa
-
+
POI
-
+
POI soubory
-
+
Nastavení
-
+
Jednotky
-
+
Nápověda
-
+
Výška
-
+
Rychlost
-
+
+
+ Tep
+
+
+
Následující soubor
-
+
Předchozí soubor
-
+
První soubor
-
+
Poslední soubor
-
+
Modifikátor nahradit/přidat
-
+
URL mapových zdrojů (dlaždic) jsou načteny při startu programu z následujícího souboru:
-
+
Formát souboru je jeden mapový záznam na řádku, kde mapový záznam sestává ze jména mapy a URL dlaždic navzájem oddělených tabulátorem. Souřadnice dlaždice jsou v URL nahrazeny řetězci $x a $y, úroven přiblížení (zoom) pak řetězcem $z. Příklad:
-
+
POI soubory, které se mají automaticky nahrát při startu programu jsou načítány z následujícího adresáře:
-
+
soubory GPX (*.gpx);;všechny soubory (*)
-
-
+
+
Řádka: %1
-
+
soubory GPX (*.gpx);;soubory CSV (*.csv);;všechny soubory (*)
-
-
+
+
mi
-
-
-
-
+
+
+
+
ft
-
-
+
+
Maximum
-
-
+
+
Minimum
-
-
+
+
O aplikaci GPXSee
-
+
Navigace
-
+
Prohlížeč a analyzátor GPX
-
+
Mapové zdroje
-
+
POI body
-
-
+
+
Vzdálenost
-
-
+
+
Čas
-
-
+
+
Stoupání
-
-
-
-
+
+
+
+
m
-
-
+
+
Klesání
-
+
Počet tras: %1
-
-
+
+
km
-
-
+
+
Chyba
-
+
Soubor GPX nelze otevřít:
%1
-
+
Soubor POI nelze otevřít:
%1
+
+ HeartRateGraph
+
+
+
+ Vzdálenost
+
+
+
+
+ Tep
+
+
+
+
+
+ km
+
+
+
+
+ 1/min
+
+
+
+
+ Průměr
+
+
+
+
+ Maximum
+
+
+
+
+ mi
+
+
QObject
diff --git a/src/elevationgraph.cpp b/src/elevationgraph.cpp
index 34a69d0b..69360a65 100644
--- a/src/elevationgraph.cpp
+++ b/src/elevationgraph.cpp
@@ -11,12 +11,12 @@ ElevationGraph::ElevationGraph(QWidget *parent) : GraphView(parent)
_max = -FLT_MAX;
_min = FLT_MAX;
- GraphView::setXLabel(tr("Distance"));
- GraphView::setYLabel(tr("Elevation"));
- GraphView::setXUnits(tr("km"));
- GraphView::setYUnits(tr("m"));
- GraphView::setXScale(M2KM);
- GraphView::setMinRange(50.0);
+ setXLabel(tr("Distance"));
+ setYLabel(tr("Elevation"));
+ setXUnits(tr("km"));
+ setYUnits(tr("m"));
+ setXScale(M2KM);
+ setMinRange(50.0);
}
void ElevationGraph::addInfo()
@@ -38,14 +38,16 @@ void ElevationGraph::loadGPX(const GPX &gpx)
qreal min, max, ascent = 0, descent = 0;
gpx.track(i).elevationGraph(data);
- if (data.isEmpty())
+ if (data.count() < 2) {
+ skipColor();
continue;
+ }
min = 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();
+ for (int j = 1; j < data.size(); j++) {
+ qreal cur = data.at(j).y();
+ qreal prev = data.at(j-1).y();
if (cur > prev)
ascent += cur - prev;
@@ -81,15 +83,15 @@ void ElevationGraph::clear()
void ElevationGraph::setUnits(enum Units units)
{
if (units == Metric) {
- GraphView::setXUnits(tr("km"));
- GraphView::setYUnits(tr("m"));
- GraphView::setXScale(M2KM);
- GraphView::setYScale(1);
+ setXUnits(tr("km"));
+ setYUnits(tr("m"));
+ setXScale(M2KM);
+ setYScale(1);
} else {
- GraphView::setXUnits(tr("mi"));
- GraphView::setYUnits(tr("ft"));
- GraphView::setXScale(M2MI);
- GraphView::setYScale(M2FT);
+ setXUnits(tr("mi"));
+ setYUnits(tr("ft"));
+ setXScale(M2MI);
+ setYScale(M2FT);
}
clearInfo();
diff --git a/src/graphview.cpp b/src/graphview.cpp
index fa4064e2..eaaeb20d 100644
--- a/src/graphview.cpp
+++ b/src/graphview.cpp
@@ -294,7 +294,7 @@ void GraphView::emitSliderPositionChanged(const QPointF &pos)
return;
qreal val = pos.x() / _slider->area().width();
- emit sliderPositionChanged(val);
+ emit sliderPositionChanged(val * (_xMax - _xMin));
const QPainterPath &path = _graphs.at(0)->path();
QRectF br = path.boundingRect();
@@ -309,18 +309,27 @@ void GraphView::emitSliderPositionChanged(const QPointF &pos)
qreal GraphView::sliderPosition() const
{
- return _slider->pos().x() / _slider->area().width();
+ if (!_slider->isVisible())
+ return -1;
+ else
+ return (_slider->pos().x() / _slider->area().width()) * (_xMax - _xMin);
}
void GraphView::setSliderPosition(qreal pos)
{
- _slider->setPos(pos * _slider->area().width(), 0);
+ if (pos > (_xMax - _xMin))
+ _slider->setVisible(false);
+ else {
+ _slider->setPos((pos / (_xMax - _xMin)) * _slider->area().width(), 0);
+ _slider->setVisible(true);
+ }
}
void GraphView::newSliderPosition(const QPointF &pos)
{
if (_slider->area().contains(pos)) {
_slider->setPos(pos);
+ _slider->setVisible(true);
emitSliderPositionChanged(pos);
}
}
diff --git a/src/graphview.h b/src/graphview.h
index 8373b7da..3768b8be 100644
--- a/src/graphview.h
+++ b/src/graphview.h
@@ -55,6 +55,8 @@ public:
void addInfo(const QString &key, const QString &value);
void clearInfo();
+ void skipColor() {_palette.color();}
+
signals:
void sliderPositionChanged(qreal);
diff --git a/src/gui.cpp b/src/gui.cpp
index 2132af31..98f9bef5 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -22,6 +22,7 @@
#include "maplist.h"
#include "elevationgraph.h"
#include "speedgraph.h"
+#include "heartrategraph.h"
#include "trackview.h"
#include "infoitem.h"
#include "filebrowser.h"
@@ -56,6 +57,8 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent)
SLOT(movePositionMarker(qreal)));
connect(_speedGraph, SIGNAL(sliderPositionChanged(qreal)), _track,
SLOT(movePositionMarker(qreal)));
+ connect(_heartRateGraph, SIGNAL(sliderPositionChanged(qreal)), _track,
+ SLOT(movePositionMarker(qreal)));
_browser = new FileBrowser(this);
_browser->setFilter(QStringList("*.gpx"));
@@ -75,6 +78,9 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent)
_time = 0;
_trackCount = 0;
+ _lastGraph = static_cast(_trackGraphs->currentWidget());
+ _lastSliderPos = _lastGraph->sliderPosition();
+
resize(600, 800);
}
@@ -349,10 +355,12 @@ void GUI::createTrackGraphs()
{
_elevationGraph = new ElevationGraph;
_speedGraph = new SpeedGraph;
+ _heartRateGraph = new HeartRateGraph;
_trackGraphs = new QTabWidget;
_trackGraphs->addTab(_elevationGraph, tr("Elevation"));
_trackGraphs->addTab(_speedGraph, tr("Speed"));
+ _trackGraphs->addTab(_heartRateGraph, tr("Heart rate"));
connect(_trackGraphs, SIGNAL(currentChanged(int)), this,
SLOT(graphChanged(int)));
@@ -478,6 +486,7 @@ bool GUI::loadFile(const QString &fileName)
if (gpx.loadFile(fileName)) {
_elevationGraph->loadGPX(gpx);
_speedGraph->loadGPX(gpx);
+ _heartRateGraph->loadGPX(gpx);
_track->loadGPX(gpx);
if (_showPOIAction->isChecked())
_track->loadPOI(_poi);
@@ -611,6 +620,7 @@ void GUI::reloadFile()
_elevationGraph->clear();
_speedGraph->clear();
+ _heartRateGraph->clear();
_track->clear();
for (int i = 0; i < _files.size(); i++) {
@@ -635,6 +645,7 @@ void GUI::closeFile()
_elevationGraph->clear();
_speedGraph->clear();
+ _heartRateGraph->clear();
_track->clear();
_files.clear();
@@ -721,10 +732,11 @@ void GUI::poiFileChecked(int index)
void GUI::graphChanged(int index)
{
- if (_trackGraphs->widget(index) == _elevationGraph)
- _elevationGraph->setSliderPosition(_speedGraph->sliderPosition());
- else if (_trackGraphs->widget(index) == _speedGraph)
- _speedGraph->setSliderPosition(_elevationGraph->sliderPosition());
+ GraphView *tv = static_cast(_trackGraphs->widget(index));
+ if (_lastGraph->sliderPosition() >= 0)
+ _lastSliderPos = _lastGraph->sliderPosition();
+ tv->setSliderPosition(_lastSliderPos);
+ _lastGraph = tv;
}
void GUI::updateNavigationActions()
@@ -751,6 +763,7 @@ void GUI::setMetricUnits()
_track->setUnits(Metric);
_elevationGraph->setUnits(Metric);
_speedGraph->setUnits(Metric);
+ _heartRateGraph->setUnits(Metric);
updateStatusBarInfo();
}
@@ -759,6 +772,7 @@ void GUI::setImperialUnits()
_track->setUnits(Imperial);
_elevationGraph->setUnits(Imperial);
_speedGraph->setUnits(Imperial);
+ _heartRateGraph->setUnits(Imperial);
updateStatusBarInfo();
}
diff --git a/src/gui.h b/src/gui.h
index 06132556..f224da76 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -14,8 +14,10 @@ class QAction;
class QLabel;
class QSignalMapper;
class FileBrowser;
+class GraphView;
class ElevationGraph;
class SpeedGraph;
+class HeartRateGraph;
class TrackView;
class Map;
@@ -124,6 +126,7 @@ private:
ElevationGraph *_elevationGraph;
SpeedGraph *_speedGraph;
+ HeartRateGraph *_heartRateGraph;
TrackView *_track;
POI _poi;
@@ -137,6 +140,9 @@ private:
qreal _distance;
qreal _time;
int _trackCount;
+
+ GraphView *_lastGraph;
+ qreal _lastSliderPos;
};
#endif // GUI_H
diff --git a/src/heartrategraph.cpp b/src/heartrategraph.cpp
new file mode 100644
index 00000000..b3043e10
--- /dev/null
+++ b/src/heartrategraph.cpp
@@ -0,0 +1,87 @@
+#include "gpx.h"
+#include "heartrategraph.h"
+
+
+HeartRateGraph::HeartRateGraph(QWidget *parent) : GraphView(parent)
+{
+ _max = 0;
+
+ setXLabel(tr("Distance"));
+ setYLabel(tr("Heart rate"));
+ setXUnits(tr("km"));
+ setYUnits(tr("1/min"));
+ setXScale(M2KM);
+ setPrecision(0);
+}
+
+void HeartRateGraph::addInfo()
+{
+ GraphView::addInfo(tr("Average"), QString::number(avg() * _yScale, 'f', 0)
+ + UNIT_SPACE + _yUnits);
+ GraphView::addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 0)
+ + UNIT_SPACE + _yUnits);
+}
+
+void HeartRateGraph::loadGPX(const GPX &gpx)
+{
+ for (int i = 0; i < gpx.trackCount(); i++) {
+ QVector data;
+ qreal max = 0, sum = 0, w = 0;
+
+ gpx.track(i).heartRateGraph(data);
+ if (data.count() < 2) {
+ skipColor();
+ continue;
+ }
+
+ for (int j = 1; j < data.size(); j++) {
+ sum += data.at(j).y() * (data.at(j).x() - data.at(j-1).x());
+ w += data.at(j).x() - data.at(j-1).x();
+ }
+ _avg.append(QPointF(gpx.track(i).distance(), sum/w));
+
+ for (int j = 0; j < data.size(); j++)
+ max = qMax(max, data.at(j).y());
+ _max = qMax(_max, max);
+
+ addInfo();
+ loadData(data);
+ }
+}
+
+qreal HeartRateGraph::avg() const
+{
+ qreal sum = 0, w = 0;
+ QList::const_iterator it;
+
+ for (it = _avg.begin(); it != _avg.end(); it++) {
+ sum += it->y() * it->x();
+ w += it->x();
+ }
+
+ return (sum / w);
+}
+
+void HeartRateGraph::clear()
+{
+ _max = 0;
+ _avg.clear();
+
+ GraphView::clear();
+}
+
+void HeartRateGraph::setUnits(enum Units units)
+{
+ if (units == Metric) {
+ setXUnits(tr("km"));
+ setXScale(M2KM);
+ } else {
+ setXUnits(tr("mi"));
+ setXScale(M2MI);
+ }
+
+ clearInfo();
+ addInfo();
+
+ redraw();
+}
diff --git a/src/heartrategraph.h b/src/heartrategraph.h
new file mode 100644
index 00000000..372c78a5
--- /dev/null
+++ b/src/heartrategraph.h
@@ -0,0 +1,30 @@
+#ifndef HEARTRATEGRAPH_H
+#define HEARTRATEGRAPH_H
+
+#include "graphview.h"
+#include "units.h"
+
+class GPX;
+
+class HeartRateGraph : public GraphView
+{
+ Q_OBJECT
+
+public:
+ HeartRateGraph(QWidget *parent = 0);
+
+ void loadGPX(const GPX &gpx);
+ void clear();
+ void setUnits(enum Units units);
+
+ qreal avg() const;
+ qreal max() const {return _max;}
+
+private:
+ void addInfo();
+
+ qreal _max;
+ QList _avg;
+};
+
+#endif // HEARTRATEGRAPH_H
diff --git a/src/parser.cpp b/src/parser.cpp
index 805a32af..963f0051 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -5,16 +5,18 @@ void Parser::handleExtensionData(QStringRef element, const QString &value)
{
if (element == "speed")
_track->last().speed = value.toDouble();
+ else if (element == "hr" || element == "heartrate")
+ _track->last().heartRate = value.toDouble();
}
void Parser::handleTrekPointData(QStringRef element, const QString &value)
{
if (element == "ele")
_track->last().elevation = value.toLatin1().toDouble();
- if (element == "time")
+ else if (element == "time")
_track->last().timestamp = QDateTime::fromString(value.toLatin1(),
Qt::ISODate);
- if (element == "geoidheight")
+ else if (element == "geoidheight")
_track->last().geoidheight = value.toLatin1().toDouble();
}
@@ -40,7 +42,8 @@ void Parser::handleWayPointAttributes(const QXmlStreamAttributes &attr)
void Parser::extensions()
{
while (_reader.readNextStartElement()) {
- if (_reader.name() == "speed")
+ if (_reader.name() == "speed" || _reader.name() == "hr"
+ || _reader.name() == "heartrate")
handleExtensionData(_reader.name(), _reader.readElementText());
else
_reader.skipCurrentElement();
diff --git a/src/speedgraph.cpp b/src/speedgraph.cpp
index e7c1723e..e4465df0 100644
--- a/src/speedgraph.cpp
+++ b/src/speedgraph.cpp
@@ -7,13 +7,13 @@ SpeedGraph::SpeedGraph(QWidget *parent) : GraphView(parent)
{
_max = 0;
- GraphView::setXLabel(tr("Distance"));
- GraphView::setYLabel(tr("Speed"));
- GraphView::setXUnits(tr("km"));
- GraphView::setYUnits(tr("km/h"));
- GraphView::setXScale(M2KM);
- GraphView::setYScale(MS2KMH);
- GraphView::setPrecision(1);
+ setXLabel(tr("Distance"));
+ setYLabel(tr("Speed"));
+ setXUnits(tr("km"));
+ setYUnits(tr("km/h"));
+ setXScale(M2KM);
+ setYScale(MS2KMH);
+ setPrecision(1);
}
void SpeedGraph::addInfo()
@@ -31,14 +31,16 @@ void SpeedGraph::loadGPX(const GPX &gpx)
qreal max = 0;
gpx.track(i).speedGraph(data);
- if (data.isEmpty())
+ if (data.count() < 2) {
+ skipColor();
continue;
+ }
_avg.append(QPointF(gpx.track(i).distance(), gpx.track(i).distance()
/ gpx.track(i).time()));
- for (int i = 0; i < data.size(); i++)
- max = qMax(max, data.at(i).y());
+ for (int j = 0; j < data.size(); j++)
+ max = qMax(max, data.at(j).y());
_max = qMax(_max, max);
addInfo();
@@ -70,15 +72,15 @@ void SpeedGraph::clear()
void SpeedGraph::setUnits(enum Units units)
{
if (units == Metric) {
- GraphView::setXUnits(tr("km"));
- GraphView::setYUnits(tr("km/h"));
- GraphView::setXScale(M2KM);
- GraphView::setYScale(MS2KMH);
+ setXUnits(tr("km"));
+ setYUnits(tr("km/h"));
+ setXScale(M2KM);
+ setYScale(MS2KMH);
} else {
- GraphView::setXUnits(tr("mi"));
- GraphView::setYUnits(tr("mi/h"));
- GraphView::setXScale(M2MI);
- GraphView::setYScale(MS2MIH);
+ setXUnits(tr("mi"));
+ setYUnits(tr("mi/h"));
+ setXScale(M2MI);
+ setYScale(MS2MIH);
}
clearInfo();
diff --git a/src/track.cpp b/src/track.cpp
index 806cea01..b798f542 100644
--- a/src/track.cpp
+++ b/src/track.cpp
@@ -6,6 +6,8 @@
#define WINDOW_EF 3
#define WINDOW_SE 11
#define WINDOW_SF 11
+#define WINDOW_HE 7
+#define WINDOW_HF 5
static bool lt(const QPointF &p1, const QPointF &p2)
{
@@ -78,6 +80,18 @@ static QVector filter(const QVector &v, int window)
return ret;
}
+Track::Track(const QVector &data) : _data(data)
+{
+ _distance = 0;
+
+ for (int i = 1; i < _data.count(); i++)
+ _dd.append(llDistance(_data.at(i).coordinates,
+ _data.at(i-1).coordinates));
+
+ for (int i = 0; i < _dd.size(); i++)
+ _distance += _dd.at(i);
+}
+
void Track::elevationGraph(QVector &graph) const
{
qreal dist = 0;
@@ -86,12 +100,12 @@ void Track::elevationGraph(QVector &graph) const
if (!_data.size())
return;
- if (isnan(_data.at(0).elevation))
+ if (std::isnan(_data.at(0).elevation))
return;
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);
- if (isnan(_data.at(i).elevation))
+ dist += _dd.at(i-1);
+ if (std::isnan(_data.at(i).elevation))
return;
raw.append(QPointF(dist, _data.at(i).elevation
- _data.at(i).geoidheight));
@@ -110,11 +124,11 @@ void Track::speedGraph(QVector &graph) const
raw.append(QPointF(0, 0));
for (int i = 1; i < _data.size(); i++) {
- ds = llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
+ ds = _dd.at(i-1);
dt = _data.at(i-1).timestamp.msecsTo(_data.at(i).timestamp) / 1000.0;
dist += ds;
- if (isnan(_data.at(i).speed)) {
+ if (std::isnan(_data.at(i).speed)) {
if (dt == 0)
continue;
v = ds / dt;
@@ -127,22 +141,30 @@ void Track::speedGraph(QVector &graph) const
graph = filter(eliminate(raw, WINDOW_SE), WINDOW_SF);
}
+void Track::heartRateGraph(QVector &graph) const
+{
+ qreal dist = 0;
+ QVector raw;
+
+ if (std::isnan(_data.at(0).heartRate))
+ return;
+ raw.append(QPointF(0, _data.at(0).heartRate));
+ for (int i = 1; i < _data.count(); i++) {
+ if (std::isnan(_data.at(i).heartRate))
+ return;
+ dist += _dd.at(i-1);
+ raw.append(QPointF(dist, _data.at(i).heartRate));
+ }
+
+ graph = filter(eliminate(raw, WINDOW_HE), WINDOW_HF);
+}
+
void Track::track(QVector &track) const
{
for (int i = 0; i < _data.size(); i++)
track.append(_data.at(i).coordinates);
}
-qreal Track::distance() const
-{
- qreal dist = 0;
-
- for (int i = 1; i < _data.size(); i++)
- dist += llDistance(_data.at(i).coordinates, _data.at(i-1).coordinates);
-
- return dist;
-}
-
qreal Track::time() const
{
if (_data.size() < 2)
diff --git a/src/track.h b/src/track.h
index c1074183..401a9eeb 100644
--- a/src/track.h
+++ b/src/track.h
@@ -8,17 +8,20 @@
class Track
{
public:
- Track(const QVector &data) : _data(data) {}
+ Track(const QVector &data);
void elevationGraph(QVector &graph) const;
void speedGraph(QVector &graph) const;
+ void heartRateGraph(QVector &graph) const;
void track(QVector &track) const;
- qreal distance() const;
+ qreal distance() const {return _distance;}
qreal time() const;
QDateTime date() const;
private:
const QVector &_data;
+ QVector _dd;
+ qreal _distance;
};
#endif // TRACK_H
diff --git a/src/trackpoint.h b/src/trackpoint.h
index 773e3e21..05793fc3 100644
--- a/src/trackpoint.h
+++ b/src/trackpoint.h
@@ -12,8 +12,14 @@ struct Trackpoint
qreal elevation;
qreal geoidheight;
qreal speed;
+ qreal heartRate;
- Trackpoint() {elevation = NAN; geoidheight = 0; speed = NAN;}
+ Trackpoint() {
+ elevation = NAN;
+ geoidheight = 0;
+ speed = NAN;
+ heartRate = NAN;
+ }
};
#endif // TRACKPOINT_H
diff --git a/src/trackview.cpp b/src/trackview.cpp
index 7c64b636..c51e55d1 100644
--- a/src/trackview.cpp
+++ b/src/trackview.cpp
@@ -34,7 +34,8 @@ TrackView::TrackView(QWidget *parent)
_zoom = ZOOM_MAX;
_scale = mapScale(_zoom);
_map = 0;
- _maxLen = 0;
+ _maxPath = 0;
+ _maxDistance = 0;
}
TrackView::~TrackView()
@@ -61,8 +62,7 @@ void TrackView::addTrack(const QVector &track)
path.lineTo(ll2mercator(QPointF(p.x(), -p.y())));
}
- _maxLen = qMax(path.length(), _maxLen);
-
+ _maxPath = qMax(path.length(), _maxPath);
pi = new QGraphicsPathItem(path);
_paths.append(pi);
@@ -108,6 +108,7 @@ void TrackView::loadGPX(const GPX &gpx)
QVector track;
gpx.track(i).track(track);
addTrack(track);
+ _maxDistance = qMax(gpx.track(i).distance(), _maxDistance);
}
addWaypoints(gpx.waypoints());
@@ -403,7 +404,8 @@ void TrackView::clear()
_tracks.clear();
_waypoints.clear();
- _maxLen = 0;
+ _maxPath = 0;
+ _maxDistance = 0;
_zoom = ZOOM_MAX;
_scale = mapScale(_zoom);
@@ -412,11 +414,17 @@ void TrackView::clear()
void TrackView::movePositionMarker(qreal val)
{
+ qreal mp = val / _maxDistance;
+
for (int i = 0; i < _paths.size(); i++) {
- qreal f = _maxLen / _paths.at(i)->path().length();
- QPointF pos = _paths.at(i)->path().pointAtPercent(qMin(val * f,
- 1.0));
- _markers.at(i)->setPos(pos);
+ qreal f = _maxPath / _paths.at(i)->path().length();
+ if (mp * f > 1.0)
+ _markers.at(i)->setVisible(false);
+ else {
+ QPointF pos = _paths.at(i)->path().pointAtPercent(mp * f);
+ _markers.at(i)->setPos(pos);
+ _markers.at(i)->setVisible(true);
+ }
}
}
diff --git a/src/trackview.h b/src/trackview.h
index 7d55faf9..b22a325e 100644
--- a/src/trackview.h
+++ b/src/trackview.h
@@ -75,7 +75,7 @@ private:
ScaleItem *_mapScale;
Palette _palette;
- qreal _maxLen;
+ qreal _maxPath, _maxDistance;
qreal _scale;
int _zoom;