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
km
-
+
m
m
-
+
Ascent
Stoupání
-
+
Descent
Klesání
-
+
Minimum
Minimum
-
+
mi
mi
-
+
ft
ft
-
+
Maximum
Maximum
@@ -59,352 +59,396 @@
GUI
-
+
About Qt
O Qt
-
+
GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at
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
-
+
Open file
Otevřít soubor
-
+
Save as
Uložit jako
-
+
Open POI file
Otevřít POI soubor
-
+
Open
Otevřít
-
+
Quit
Ukončit
-
-
-
+
+
+
Keyboard controls
Ovládací klávesy
-
+
Save
Uložit
-
+
Close
Zavřít
-
+
Reload
Znovu načíst
-
+
Show
Zobrazit
-
-
+
+
File
Soubor
-
-
-
+
+
+
Data sources
Zdroje dat
-
+
Load POI file
Nahrát POI soubor
-
+
Close POI files
Zavřit soubory POI
-
+
Show POIs
Zobrazit POI
-
+
Show map
Zobrazit mapu
-
+
Show graphs
Zobrazovat grafy
-
+
Show toolbars
Zobrazovat nástrojové lišty
-
+
Metric
Metrické
-
+
Imperial
Imperiální
-
+
Next
Následující
-
+
Previous
Předchozí
-
+
Last
Poslední
-
+
First
První
-
+
Map
Mapa
-
+
POI
POI
-
+
POI files
POI soubory
-
+
Settings
Nastavení
-
+
Units
Jednotky
-
+
Help
Nápověda
-
+
Elevation
Výška
-
+
Speed
Rychlost
-
+
+ Heart rate
+ Tep
+
+
+
Next file
Následující soubor
-
+
Previous file
Předchozí soubor
-
+
First file
První soubor
-
+
Last file
Poslední soubor
-
+
Append modifier
Modifikátor nahradit/přidat
-
+
Map (tiles) source URLs are read on program startup from the following file:
URL mapových zdrojů (dlaždic) jsou načteny při startu programu z následujícího souboru:
-
+
The file format is one map entry per line, consisting of the map name and tiles URL delimited by a TAB character. The tile X and Y coordinates are replaced with $x and $y in the URL and the zoom level is replaced with $z. An example map file could look like:
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:
-
+
To make GPXSee load a POI file automatically on startup, add the file to the following directory:
POI soubory, které se mají automaticky nahrát při startu programu jsou načítány z následujícího adresáře:
-
+
GPX files (*.gpx);;All files (*)
soubory GPX (*.gpx);;všechny soubory (*)
-
-
+
+
Line: %1
Řádka: %1
-
+
GPX files (*.gpx);;CSV files (*.csv);;All files (*)
soubory GPX (*.gpx);;soubory CSV (*.csv);;všechny soubory (*)
-
-
+
+
mi
mi
-
-
-
-
+
+
+
+
ft
ft
-
-
+
+
Maximum
Maximum
-
-
+
+
Minimum
Minimum
-
-
+
+
About GPXSee
O aplikaci GPXSee
-
+
Navigation
Navigace
-
+
GPX viewer and analyzer
Prohlížeč a analyzátor GPX
-
+
Map sources
Mapové zdroje
-
+
POIs
POI body
-
-
+
+
Distance
Vzdálenost
-
-
+
+
Time
Čas
-
-
+
+
Ascent
Stoupání
-
-
-
-
+
+
+
+
m
m
-
-
+
+
Descent
Klesání
-
+
%1 tracks
Počet tras: %1
-
-
+
+
km
km
-
-
+
+
Error
Chyba
-
+
Error loading GPX file:
%1
Soubor GPX nelze otevřít:
%1
-
+
Error loading POI file:
%1
Soubor POI nelze otevřít:
%1
+
+ HeartRateGraph
+
+
+ Distance
+ Vzdálenost
+
+
+
+ Heart rate
+ Tep
+
+
+
+
+ km
+ km
+
+
+
+ 1/min
+ 1/min
+
+
+
+ Average
+ Průměr
+
+
+
+ Maximum
+ Maximum
+
+
+
+ mi
+ 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;