diff --git a/gpxsee.pro b/gpxsee.pro index 4c7bc1d3..9b4fcf01 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -43,7 +43,8 @@ HEADERS += src/config.h \ src/trackinfo.h \ src/exportdialog.h \ src/fileselectwidget.h \ - src/margins.h + src/margins.h \ + src/temperaturegraph.h SOURCES += src/main.cpp \ src/gui.cpp \ src/gpx.cpp \ @@ -73,7 +74,9 @@ SOURCES += src/main.cpp \ src/app.cpp \ src/trackinfo.cpp \ src/exportdialog.cpp \ - src/fileselectwidget.cpp + src/fileselectwidget.cpp \ + src/temperaturegraph.cpp \ + src/trackpoint.cpp RESOURCES += gpxsee.qrc TRANSLATIONS = lang/gpxsee_cs.ts macx { diff --git a/lang/gpxsee_cs.ts b/lang/gpxsee_cs.ts index b1093e34..d9ee622a 100644 --- a/lang/gpxsee_cs.ts +++ b/lang/gpxsee_cs.ts @@ -1,6 +1,6 @@ - + ElevationGraph @@ -59,7 +59,7 @@ ExportDialog - + Export to PDF Exportovat do PDF @@ -124,24 +124,24 @@ Exportovat - - - + + + Error Chyba - + No output file selected. Nebyl zvolen žádný výstupní soubor. - + %1 is a directory. %1 je adresář. - + %1 is not writable. %1 nelze zapsat. @@ -149,12 +149,12 @@ FileSelectWidget - + Browse... Procházet... - + Select file Vybrat soubor @@ -162,353 +162,358 @@ GUI - + 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 - + Open POI file Otevřít POI soubor - + Open Otevřít - + Quit Ukončit - - - + + + Keyboard controls Ovládací klávesy - + 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 POI soubory - + Show POIs Zobrazit POI - + Show map Zobrazit mapu - + Clear tile cache Vymazat mezipaměť dlaždic - - - + + + Next map Následující mapa - + Show graphs Zobrazovat grafy - + Show toolbars Zobrazovat nástrojové lišty - + Metric Metrické - + Imperial Imperiální - + Fullscreen mode Celoobrazovkový režim - + 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 - + + Temperature + Teplota + + + Previous map Předchozí mapa - - + + Date Datum - + No GPX files loaded Nejsou načteny žádné GPX soubory - + Elevation Výška - + Speed Rychlost - + Heart rate Tep - + Next file Následující soubor - + Version Verze - + Print... Tisknout... - + Export to PDF... Exportovat do PDF... - + 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 (*) - + Tracks Počet tras - - + + mi mi - + ft ft - - + + About GPXSee O aplikaci GPXSee - + Navigation Navigace - + Map sources Mapové zdroje - + POIs POI body - - + + Distance Vzdálenost - + Time Čas - + m m - + %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: @@ -639,4 +644,62 @@ mi/h + + TemperatureGraph + + + Distance + Vzdálenost + + + + Temperature + Teplota + + + + Average + Průměr + + + + Minimum + Minimum + + + + Maximum + Maximum + + + + m + m + + + + km + km + + + + ft + ft + + + + mi + mi + + + + C + C + + + + F + F + + diff --git a/src/graphview.cpp b/src/graphview.cpp index f09147c4..4792ac99 100644 --- a/src/graphview.cpp +++ b/src/graphview.cpp @@ -49,6 +49,7 @@ GraphView::GraphView(QWidget *parent) _xScale = 1; _yScale = 1; + _yOffset = 0; _precision = 0; _minYRange = 0.01; @@ -116,16 +117,6 @@ void GraphView::setYUnits(const QString &units) createYLabel(); } -void GraphView::setXScale(qreal scale) -{ - _xScale = scale; -} - -void GraphView::setYScale(qreal scale) -{ - _yScale = scale; -} - void GraphView::loadData(const QVector &data) { QPainterPath path; @@ -182,7 +173,8 @@ void GraphView::redraw(const QSizeF &size) _graphs.at(i)->resetTransform(); rx = RangeF(_bounds.left() * _xScale, _bounds.right() * _xScale); - ry = RangeF(_bounds.top() * _yScale, _bounds.bottom() * _yScale); + ry = RangeF(_bounds.top() * _yScale + _yOffset, _bounds.bottom() * _yScale + + _yOffset); if (ry.size() < _minYRange) ry.resize(_minYRange); @@ -217,6 +209,8 @@ void GraphView::redraw(const QSizeF &size) _scene->addItem(_yAxis); _slider->setArea(r); + if (_sliderPos > _bounds.right() || _sliderPos < _bounds.left()) + _slider->setVisible(false); _slider->setPos((_sliderPos / _bounds.width()) * _slider->area().width(), r.bottom()); _scene->addItem(_slider); @@ -311,7 +305,7 @@ void GraphView::updateSliderInfo() { _sliderInfo->setVisible(_graphs.size() == 1); - if (_graphs.size() != 1) + if (!_slider->isVisible()) return; const QPainterPath &path = _graphs.at(0)->path(); @@ -329,7 +323,8 @@ void GraphView::updateSliderInfo() _sliderInfo->setSide(s); _sliderInfo->setPos(QPointF(0, _slider->boundingRect().height() * r)); - _sliderInfo->setText(QString::number(-y * _yScale, 'f', _precision)); + _sliderInfo->setText(QString::number(-y * _yScale + _yOffset, 'f', + _precision)); } void GraphView::emitSliderPositionChanged(const QPointF &pos) diff --git a/src/graphview.h b/src/graphview.h index 0b6a9155..eb2d0cde 100644 --- a/src/graphview.h +++ b/src/graphview.h @@ -47,13 +47,15 @@ public: const QString &yUnits() const {return _yUnits;} qreal xScale() const {return _xScale;} qreal yScale() const {return _yScale;} + qreal yOffset() const {return _yOffset;} void setXLabel(const QString &label); void setYLabel(const QString &label); void setXUnits(const QString &units); void setYUnits(const QString &units); - void setXScale(qreal scale); - void setYScale(qreal scale); + void setXScale(qreal scale) {_xScale = scale;} + void setYScale(qreal scale) {_yScale = scale;} + void setYOffset(qreal offset) {_yOffset = offset;} void setSliderPrecision(int precision) {_precision = precision;} void setMinYRange(qreal range) {_minYRange = range;} @@ -85,6 +87,7 @@ private: void updateSliderInfo(); qreal _xScale, _yScale; + qreal _yOffset; QString _xUnits, _yUnits; QString _xLabel, _yLabel; int _precision; diff --git a/src/gui.cpp b/src/gui.cpp index 6b93c24d..cf606f65 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -28,6 +28,7 @@ #include "elevationgraph.h" #include "speedgraph.h" #include "heartrategraph.h" +#include "temperaturegraph.h" #include "trackview.h" #include "trackinfo.h" #include "filebrowser.h" @@ -405,6 +406,8 @@ void GUI::createTrackGraphs() _speedGraph->setFrameShape(QFrame::NoFrame); _heartRateGraph = new HeartRateGraph; _heartRateGraph->setFrameShape(QFrame::NoFrame); + _temperatureGraph = new TemperatureGraph; + _temperatureGraph->setFrameShape(QFrame::NoFrame); _trackGraphs = new QTabWidget; connect(_trackGraphs, SIGNAL(currentChanged(int)), this, @@ -420,6 +423,7 @@ void GUI::createTrackGraphs() _tabs.append(GraphTab(_elevationGraph, tr("Elevation"))); _tabs.append(GraphTab(_speedGraph, tr("Speed"))); _tabs.append(GraphTab(_heartRateGraph, tr("Heart rate"))); + _tabs.append(GraphTab(_temperatureGraph, tr("Temperature"))); connect(_elevationGraph, SIGNAL(sliderPositionChanged(qreal)), this, SLOT(sliderPositionChanged(qreal))); @@ -427,6 +431,8 @@ void GUI::createTrackGraphs() SLOT(sliderPositionChanged(qreal))); connect(_heartRateGraph, SIGNAL(sliderPositionChanged(qreal)), this, SLOT(sliderPositionChanged(qreal))); + connect(_temperatureGraph, SIGNAL(sliderPositionChanged(qreal)), this, + SLOT(sliderPositionChanged(qreal))); } void GUI::createStatusBar() @@ -562,6 +568,7 @@ bool GUI::loadFile(const QString &fileName) _elevationGraph->loadGPX(gpx); _speedGraph->loadGPX(gpx); _heartRateGraph->loadGPX(gpx); + _temperatureGraph->loadGPX(gpx); updateGraphTabs(); _track->setHidden(false); _track->loadGPX(gpx); @@ -736,6 +743,7 @@ void GUI::reloadFile() _elevationGraph->clear(); _speedGraph->clear(); _heartRateGraph->clear(); + _temperatureGraph->clear(); _track->clear(); _sliderPos = 0; @@ -769,6 +777,7 @@ void GUI::closeFiles() _elevationGraph->clear(); _speedGraph->clear(); _heartRateGraph->clear(); + _temperatureGraph->clear(); _track->clear(); _files.clear(); @@ -1003,6 +1012,7 @@ void GUI::setMetricUnits() _elevationGraph->setUnits(Metric); _speedGraph->setUnits(Metric); _heartRateGraph->setUnits(Metric); + _temperatureGraph->setUnits(Metric); updateStatusBarInfo(); } @@ -1012,6 +1022,7 @@ void GUI::setImperialUnits() _elevationGraph->setUnits(Imperial); _speedGraph->setUnits(Imperial); _heartRateGraph->setUnits(Imperial); + _temperatureGraph->setUnits(Imperial); updateStatusBarInfo(); } diff --git a/src/gui.h b/src/gui.h index 697e00a1..56c4be03 100644 --- a/src/gui.h +++ b/src/gui.h @@ -22,6 +22,7 @@ class GraphView; class ElevationGraph; class SpeedGraph; class HeartRateGraph; +class TemperatureGraph; class TrackView; class Map; @@ -158,6 +159,7 @@ private: ElevationGraph *_elevationGraph; SpeedGraph *_speedGraph; HeartRateGraph *_heartRateGraph; + TemperatureGraph *_temperatureGraph; QList _tabs; POI _poi; diff --git a/src/parser.cpp b/src/parser.cpp index b4e26c19..7db40f9e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -7,6 +7,8 @@ void Parser::handleExtensionData(QStringRef element, const QString &value) _track->last().speed = value.toDouble(); else if (element == "hr" || element == "heartrate") _track->last().heartRate = value.toDouble(); + else if (element == "atemp" || element == "temp") + _track->last().temperature = value.toDouble(); } void Parser::handleTrekPointData(QStringRef element, const QString &value) @@ -42,7 +44,7 @@ void Parser::handleWayPointAttributes(const QXmlStreamAttributes &attr) void Parser::tpExtension() { while (_reader.readNextStartElement()) { - if (_reader.name() == "hr") + if (_reader.name() == "hr" || _reader.name() == "atemp") handleExtensionData(_reader.name(), _reader.readElementText()); else _reader.skipCurrentElement(); @@ -53,7 +55,7 @@ void Parser::extensions() { while (_reader.readNextStartElement()) { if (_reader.name() == "speed" || _reader.name() == "hr" - || _reader.name() == "heartrate") + || _reader.name() == "heartrate" || _reader.name() == "temp") handleExtensionData(_reader.name(), _reader.readElementText()); else if (_reader.name() == "TrackPointExtension") tpExtension(); diff --git a/src/track.cpp b/src/track.cpp index 667eaf68..dfc6cb8c 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -99,15 +99,13 @@ void Track::elevationGraph(QVector &graph) const if (!_data.size()) return; - if (!_data.at(0).hasElevation()) - return; - raw.append(QPointF(0, _data.at(0).elevation - _data.at(0).geoidheight)); + if (_data.at(0).hasElevation()) + raw.append(QPointF(0, _data.at(0).elevation - _data.at(0).geoidheight)); for (int i = 1; i < _data.size(); i++) { dist += _dd.at(i-1); - if (!_data.at(i).hasElevation()) - return; - raw.append(QPointF(dist, _data.at(i).elevation - - _data.at(i).geoidheight)); + if (_data.at(i).hasElevation()) + raw.append(QPointF(dist, _data.at(i).elevation + - _data.at(i).geoidheight)); } graph = filter(raw, WINDOW_EF); @@ -124,15 +122,18 @@ void Track::speedGraph(QVector &graph) const raw.append(QPointF(0, 0)); for (int i = 1; i < _data.size(); i++) { ds = _dd.at(i-1); - dt = _data.at(i-1).timestamp.msecsTo(_data.at(i).timestamp) / 1000.0; dist += ds; - if (!_data.at(i).hasSpeed()) { + if (_data.at(i).hasSpeed()) + v = _data.at(i).speed; + else if (_data.at(i).hasTimestamp()) { + dt = _data.at(i-1).timestamp.msecsTo(_data.at(i).timestamp) + / 1000.0; if (dt == 0) continue; v = ds / dt; } else - v = _data.at(i).speed; + continue; raw.append(QPointF(dist, v)); } @@ -148,19 +149,33 @@ void Track::heartRateGraph(QVector &graph) const if (!_data.size()) return; - if (!_data.at(0).hasHeartRate()) - return; - raw.append(QPointF(0, _data.at(0).heartRate)); + if (_data.at(0).hasHeartRate()) + raw.append(QPointF(0, _data.at(0).heartRate)); for (int i = 1; i < _data.count(); i++) { - if (!_data.at(i).hasHeartRate()) - return; dist += _dd.at(i-1); - raw.append(QPointF(dist, _data.at(i).heartRate)); + if (_data.at(i).hasHeartRate()) + raw.append(QPointF(dist, _data.at(i).heartRate)); } graph = filter(eliminate(raw, WINDOW_HE), WINDOW_HF); } +void Track::temperatureGraph(QVector &graph) const +{ + qreal dist = 0; + + if (!_data.size()) + return; + + if (_data.at(0).hasTemperature()) + graph.append(QPointF(0, _data.at(0).temperature)); + for (int i = 1; i < _data.size(); i++) { + dist += _dd.at(i-1); + if (_data.at(i).hasTemperature()) + graph.append(QPointF(dist, _data.at(i).temperature)); + } +} + void Track::track(QVector &track) const { for (int i = 0; i < _data.size(); i++) diff --git a/src/track.h b/src/track.h index 401a9eeb..52283f49 100644 --- a/src/track.h +++ b/src/track.h @@ -13,6 +13,7 @@ public: void elevationGraph(QVector &graph) const; void speedGraph(QVector &graph) const; void heartRateGraph(QVector &graph) const; + void temperatureGraph(QVector &graph) const; void track(QVector &track) const; qreal distance() const {return _distance;} qreal time() const; diff --git a/src/trackpoint.h b/src/trackpoint.h index 081406a5..c2601da9 100644 --- a/src/trackpoint.h +++ b/src/trackpoint.h @@ -3,6 +3,7 @@ #include #include +#include #include class Trackpoint @@ -13,11 +14,14 @@ public: geoidheight = 0; speed = NAN; heartRate = NAN; + temperature = NAN; } + bool hasTimestamp() const {return !timestamp.isNull();} bool hasElevation() const {return !std::isnan(elevation);} bool hasSpeed() const {return !std::isnan(speed);} bool hasHeartRate() const {return !std::isnan(heartRate);} + bool hasTemperature() const {return !std::isnan(temperature);} QPointF coordinates; QDateTime timestamp; @@ -25,6 +29,9 @@ public: qreal geoidheight; qreal speed; qreal heartRate; + qreal temperature; }; +QDebug operator<<(QDebug dbg, const Trackpoint &trackpoint); + #endif // TRACKPOINT_H diff --git a/src/units.h b/src/units.h index 139e9e3d..cf53388b 100644 --- a/src/units.h +++ b/src/units.h @@ -18,6 +18,9 @@ enum Units { #define MIINFT 5280 // 1 mi in ft #define MIINM 1609.344 // 1mi in m +#define C2FS 1.8 // Celsius to Farenheit - scale +#define C2FO 32 // Celsius to Farenheit - offset + #ifdef Q_OS_WIN32 #define UNIT_SPACE QString(" ") #else // Q_OS_WIN32