1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Added elevation correction(geoidheight subtraction)

Improved info output in PDF exports.
This commit is contained in:
Martin Tůma 2015-10-19 00:35:08 +02:00
parent ac3614f81c
commit cfc669bc33
9 changed files with 198 additions and 122 deletions

View File

@ -24,22 +24,22 @@
<translation>m</translation> <translation>m</translation>
</message> </message>
<message> <message>
<location filename="../src/elevationgraph.cpp" line="45"/> <location filename="../src/elevationgraph.cpp" line="50"/>
<source>Ascent</source> <source>Ascent</source>
<translation>Stoupání</translation> <translation>Stoupání</translation>
</message> </message>
<message> <message>
<location filename="../src/elevationgraph.cpp" line="46"/> <location filename="../src/elevationgraph.cpp" line="51"/>
<source>Descent</source> <source>Descent</source>
<translation>Klesání</translation> <translation>Klesání</translation>
</message> </message>
<message> <message>
<location filename="../src/elevationgraph.cpp" line="48"/> <location filename="../src/elevationgraph.cpp" line="53"/>
<source>Minimum</source> <source>Minimum</source>
<translation>Minimum</translation> <translation>Minimum</translation>
</message> </message>
<message> <message>
<location filename="../src/elevationgraph.cpp" line="47"/> <location filename="../src/elevationgraph.cpp" line="52"/>
<source>Maximum</source> <source>Maximum</source>
<translation>Maximum</translation> <translation>Maximum</translation>
</message> </message>
@ -47,123 +47,162 @@
<context> <context>
<name>GUI</name> <name>GUI</name>
<message> <message>
<location filename="../src/gui.cpp" line="84"/> <location filename="../src/gui.cpp" line="86"/>
<source>About Qt</source> <source>About Qt</source>
<translation>O Qt</translation> <translation>O Qt</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="198"/> <location filename="../src/gui.cpp" line="200"/>
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source> <source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at </source>
<translation>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 </translation> <translation>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 </translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="206"/> <location filename="../src/gui.cpp" line="208"/>
<source>Open file</source> <source>Open file</source>
<translation>Otevřít soubor</translation> <translation>Otevřít soubor</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="98"/> <location filename="../src/gui.cpp" line="100"/>
<source>Save as</source> <source>Save as</source>
<translation>Uložit jako</translation> <translation>Uložit jako</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="261"/> <location filename="../src/gui.cpp" line="251"/>
<source>Open POI file</source> <source>Open POI file</source>
<translation>Otevřít POI soubor</translation> <translation>Otevřít POI soubor</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="89"/> <location filename="../src/gui.cpp" line="91"/>
<source>Open</source> <source>Open</source>
<translation>Otevřít</translation> <translation>Otevřít</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="77"/> <location filename="../src/gui.cpp" line="79"/>
<source>Quit</source> <source>Quit</source>
<translation>Ukončit</translation> <translation>Ukončit</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="93"/> <location filename="../src/gui.cpp" line="95"/>
<source>Save</source> <source>Save</source>
<translation>Uložit</translation> <translation>Uložit</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="103"/> <location filename="../src/gui.cpp" line="105"/>
<source>Close</source> <source>Close</source>
<translation>Zavřít</translation> <translation>Zavřít</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="110"/> <location filename="../src/gui.cpp" line="112"/>
<source>Load file</source> <source>Load file</source>
<translation>Nahrát soubor</translation> <translation>Nahrát soubor</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="113"/> <location filename="../src/gui.cpp" line="115"/>
<source>Show</source> <source>Show</source>
<translation>Zobrazit</translation> <translation>Zobrazit</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="120"/> <location filename="../src/gui.cpp" line="122"/>
<location filename="../src/gui.cpp" line="143"/> <location filename="../src/gui.cpp" line="145"/>
<source>File</source> <source>File</source>
<translation>Soubor</translation> <translation>Soubor</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="132"/> <location filename="../src/gui.cpp" line="134"/>
<location filename="../src/gui.cpp" line="151"/> <location filename="../src/gui.cpp" line="153"/>
<source>POI</source> <source>POI</source>
<translation>POI</translation> <translation>POI</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="136"/> <location filename="../src/gui.cpp" line="138"/>
<source>Help</source> <source>Help</source>
<translation>Nápověda</translation> <translation>Nápověda</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="169"/> <location filename="../src/gui.cpp" line="171"/>
<source>Elevation</source> <source>Elevation</source>
<translation>Výška</translation> <translation>Výška</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="170"/> <location filename="../src/gui.cpp" line="172"/>
<source>Speed</source> <source>Speed</source>
<translation>Rychlost</translation> <translation>Rychlost</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="82"/> <location filename="../src/gui.cpp" line="307"/>
<location filename="../src/gui.cpp" line="195"/> <source>Maximum</source>
<translation>Maximum</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="309"/>
<source>Minimum</source>
<translation>Minimum</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="84"/>
<location filename="../src/gui.cpp" line="197"/>
<source>About GPXSee</source> <source>About GPXSee</source>
<translation>O aplikaci GPXSee</translation> <translation>O aplikaci GPXSee</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="197"/> <location filename="../src/gui.cpp" line="199"/>
<source>GPX viewer and analyzer</source> <source>GPX viewer and analyzer</source>
<translation>Prohlížeč a analyzátor GPX</translation> <translation>Prohlížeč a analyzátor GPX</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="240"/> <location filename="../src/gui.cpp" line="300"/>
<source>Distance</source>
<translation>Vzdálenost</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="302"/>
<source>Time</source>
<translation>Čas</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="303"/>
<source>Ascent</source>
<translation>Stoupání</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="304"/>
<location filename="../src/gui.cpp" line="306"/>
<location filename="../src/gui.cpp" line="308"/>
<location filename="../src/gui.cpp" line="310"/>
<source>m</source>
<translation>m</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="305"/>
<source>Descent</source>
<translation>Klesání</translation>
</message>
<message>
<location filename="../src/gui.cpp" line="344"/>
<source>%1 tracks</source> <source>%1 tracks</source>
<translation>Počet tras: %1</translation> <translation>Počet tras: %1</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="245"/> <location filename="../src/gui.cpp" line="301"/>
<location filename="../src/gui.cpp" line="349"/>
<source>km</source> <source>km</source>
<translation>km</translation> <translation>km</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="251"/> <location filename="../src/gui.cpp" line="241"/>
<location filename="../src/gui.cpp" line="265"/> <location filename="../src/gui.cpp" line="255"/>
<source>Error</source> <source>Error</source>
<translation>Chyba</translation> <translation>Chyba</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="252"/> <location filename="../src/gui.cpp" line="242"/>
<source>Error loading GPX file: <source>Error loading GPX file:
%1</source> %1</source>
<translation>Soubor GPX nelze otevřít: <translation>Soubor GPX nelze otevřít:
%1</translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../src/gui.cpp" line="266"/> <location filename="../src/gui.cpp" line="256"/>
<source>Error loading POI file: <source>Error loading POI file:
%1</source> %1</source>
<translation>Soubor POI nelze otevřít: <translation>Soubor POI nelze otevřít:
@ -173,12 +212,12 @@
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../src/parser.cpp" line="73"/> <location filename="../src/parser.cpp" line="97"/>
<source>Not a GPX file.</source> <source>Not a GPX file.</source>
<translation>Neplatný GPX soubor.</translation> <translation>Neplatný GPX soubor.</translation>
</message> </message>
<message> <message>
<location filename="../src/parser.cpp" line="82"/> <location filename="../src/parser.cpp" line="106"/>
<source>%1 <source>%1
Line %2</source> Line %2</source>
<translation>%1 <translation>%1
@ -202,32 +241,32 @@ Rádka %1</translation>
<context> <context>
<name>SpeedGraph</name> <name>SpeedGraph</name>
<message> <message>
<location filename="../src/speedgraph.cpp" line="7"/> <location filename="../src/speedgraph.cpp" line="9"/>
<source>Distance</source> <source>Distance</source>
<translation>Vzdálenost</translation> <translation>Vzdálenost</translation>
</message> </message>
<message> <message>
<location filename="../src/speedgraph.cpp" line="8"/> <location filename="../src/speedgraph.cpp" line="10"/>
<source>Speed</source> <source>Speed</source>
<translation>Rychlost</translation> <translation>Rychlost</translation>
</message> </message>
<message> <message>
<location filename="../src/speedgraph.cpp" line="9"/> <location filename="../src/speedgraph.cpp" line="11"/>
<source>km</source> <source>km</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/speedgraph.cpp" line="10"/> <location filename="../src/speedgraph.cpp" line="12"/>
<source>km/h</source> <source>km/h</source>
<translation>km/h</translation> <translation>km/h</translation>
</message> </message>
<message> <message>
<location filename="../src/speedgraph.cpp" line="42"/> <location filename="../src/speedgraph.cpp" line="35"/>
<source>Average</source> <source>Average</source>
<translation>Průměr</translation> <translation>Průměr</translation>
</message> </message>
<message> <message>
<location filename="../src/speedgraph.cpp" line="44"/> <location filename="../src/speedgraph.cpp" line="37"/>
<source>Maximum</source> <source>Maximum</source>
<translation>Maximum</translation> <translation>Maximum</translation>
</message> </message>

View File

@ -14,6 +14,11 @@ public:
void loadGPX(const GPX &gpx); void loadGPX(const GPX &gpx);
void clear(); void clear();
qreal ascent() const {return _ascent;}
qreal descent() const {return _descent;}
qreal max() const {return _max;}
qreal min() const {return _min;}
private: private:
qreal _ascent, _descent; qreal _ascent, _descent;
qreal _max, _min; qreal _max, _min;

View File

@ -11,68 +11,6 @@
#define WINDOW_SF 11 #define WINDOW_SF 11
bool GPX::loadFile(const QString &fileName)
{
QFile file(fileName);
bool ret;
_data.clear();
_error.clear();
if (!file.open(QFile::ReadOnly | QFile::Text)) {
_error = qPrintable(file.errorString());
return false;
}
if (!(ret = _parser.loadFile(&file, _data)))
_error = _parser.errorString();
file.close();
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
{
qreal dist = 0;
QVector<QPointF> raw;
if (!_data.size())
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);
raw.append(QPointF(dist, _data.at(i).elevation));
}
graph = filter(raw, WINDOW_EF);
}
static bool lt(const QPointF &p1, const QPointF &p2) static bool lt(const QPointF &p1, const QPointF &p2)
{ {
return p1.y() < p2.y(); return p1.y() < p2.y();
@ -120,6 +58,69 @@ static QVector<QPointF> eliminate(const QVector<QPointF> &v, int window)
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;
}
bool GPX::loadFile(const QString &fileName)
{
QFile file(fileName);
bool ret;
_data.clear();
_error.clear();
if (!file.open(QFile::ReadOnly | QFile::Text)) {
_error = qPrintable(file.errorString());
return false;
}
if (!(ret = _parser.loadFile(&file, _data)))
_error = _parser.errorString();
file.close();
return ret;
}
void GPX::elevationGraph(QVector<QPointF> &graph) const
{
qreal dist = 0;
QVector<QPointF> raw;
if (!_data.size())
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);
raw.append(QPointF(dist, _data.at(i).elevation
- _data.at(i).geoidheight));
}
graph = filter(raw, WINDOW_EF);
}
void GPX::speedGraph(QVector<QPointF> &graph) const void GPX::speedGraph(QVector<QPointF> &graph) const
{ {
qreal dist = 0, v, ds, dt; qreal dist = 0, v, ds, dt;

View File

@ -216,9 +216,11 @@ void Graph::plot(QPainter *painter, const QRectF &target)
QSizeF canvas = QSizeF(orig.height() * ratio, orig.height()); QSizeF canvas = QSizeF(orig.height() * ratio, orig.height());
resize(canvas); resize(canvas);
_slider->setVisible(false); _slider->hide();
_info->hide();
_scene->render(painter, target, QRectF(), Qt::KeepAspectRatioByExpanding); _scene->render(painter, target, QRectF(), Qt::KeepAspectRatioByExpanding);
_slider->setVisible(true); _slider->show();
_info->show();
resize(orig); resize(orig);
} }

View File

@ -8,7 +8,6 @@
#include <QPainter> #include <QPainter>
#include <QKeyEvent> #include <QKeyEvent>
#include <QDir> #include <QDir>
#include "gui.h"
#include "config.h" #include "config.h"
#include "icons.h" #include "icons.h"
#include "keys.h" #include "keys.h"
@ -16,10 +15,13 @@
#include "elevationgraph.h" #include "elevationgraph.h"
#include "speedgraph.h" #include "speedgraph.h"
#include "track.h" #include "track.h"
#include "infoitem.h"
#include "gui.h"
#include <QDebug> #include <QDebug>
static QString timeSpan(qreal time) static QString timeSpan(qreal time)
{ {
unsigned h, m, s; unsigned h, m, s;
@ -287,12 +289,28 @@ void GUI::saveFile(const QString &fileName)
printer.setOutputFileName(fileName); printer.setOutputFileName(fileName);
QPainter p(&printer); QPainter p(&printer);
int margin = (printer.paperRect().height() - printer.pageRect().height())
/ 2; _track->plot(&p, QRectF(0, 300, printer.width(), (0.80 * printer.height())
_track->plot(&p, QRectF(0, 0, printer.width(), (0.80 * printer.height()) - 400));
- margin));
_elevationGraph->plot(&p, QRectF(0, 0.80 * printer.height(), _elevationGraph->plot(&p, QRectF(0, 0.80 * printer.height(),
printer.width(), printer.height() * 0.20)); printer.width(), printer.height() * 0.20));
QGraphicsScene scene;
InfoItem info;
info.insert(tr("Distance"), QString::number(_distance / 1000, 'f', 1) + " "
+ tr("km"));
info.insert(tr("Time"), timeSpan(_time));
info.insert(tr("Ascent"), QString::number(_elevationGraph->ascent(), 'f', 0)
+ " " + tr("m"));
info.insert(tr("Descent"), QString::number(_elevationGraph->descent(), 'f',
0) + " " + tr("m"));
info.insert(tr("Maximum"), QString::number(_elevationGraph->max(), 'f', 0)
+ " " + tr("m"));
info.insert(tr("Minimum"), QString::number(_elevationGraph->min(), 'f', 0)
+ " " + tr("m"));
scene.addItem(&info);
scene.render(&p, QRectF(0, 0, printer.width(), 200));
p.end(); p.end();
} }

View File

@ -18,6 +18,8 @@ void Parser::handleTrekPointData(QVector<TrackPoint> &data,
if (element == "time") if (element == "time")
data.last().timestamp = QDateTime::fromString(value.toLatin1(), data.last().timestamp = QDateTime::fromString(value.toLatin1(),
Qt::ISODate); Qt::ISODate);
if (element == "geoidheight")
data.last().geoidheight = value.toLatin1().toDouble();
} }
void Parser::handleTrekPointAttributes(QVector<TrackPoint> &data, void Parser::handleTrekPointAttributes(QVector<TrackPoint> &data,
@ -41,7 +43,8 @@ void Parser::extensions(QVector<TrackPoint> &data)
void Parser::trekPointData(QVector<TrackPoint> &data) void Parser::trekPointData(QVector<TrackPoint> &data)
{ {
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "ele" || _reader.name() == "time") if (_reader.name() == "ele" || _reader.name() == "time"
|| _reader.name() == "geoidheight")
handleTrekPointData(data, _reader.name(), _reader.readElementText()); handleTrekPointData(data, _reader.name(), _reader.readElementText());
else if (_reader.name() == "extensions") else if (_reader.name() == "extensions")
extensions(data); extensions(data);

View File

@ -10,9 +10,10 @@ struct TrackPoint
QPointF coordinates; QPointF coordinates;
QDateTime timestamp; QDateTime timestamp;
qreal elevation; qreal elevation;
qreal geoidheight;
qreal speed; qreal speed;
TrackPoint() {speed = -1;} TrackPoint() {elevation = 0; geoidheight = 0; speed = -1;}
}; };
class Parser class Parser

View File

@ -18,30 +18,21 @@ SpeedGraph::SpeedGraph(QWidget *parent) : Graph(parent)
void SpeedGraph::loadGPX(const GPX &gpx) void SpeedGraph::loadGPX(const GPX &gpx)
{ {
QVector<QPointF> data; QVector<QPointF> data;
qreal max = 0, sum = 0, w = 0, avg; qreal max = 0;
gpx.speedGraph(data); gpx.speedGraph(data);
if (data.isEmpty()) if (data.isEmpty())
return; return;
avg = gpx.distance() / gpx.time(); _avg.append(QPointF(gpx.distance(), gpx.distance() / gpx.time()));
_avg.append(QPointF(gpx.distance(), avg));
for (int i = 0; i < data.size(); i++) for (int i = 0; i < data.size(); i++)
max = qMax(max, data.at(i).y()); max = qMax(max, data.at(i).y());
sum = 0; w = 0;
for (QList<QPointF>::iterator it = _avg.begin(); it != _avg.end(); it++) {
sum += it->y() * it->x();
w += it->x();
}
avg = sum / w;
_max = qMax(_max, max); _max = qMax(_max, max);
addInfo(tr("Average"), QString::number(avg * _yScale, 'f', 1) + " " addInfo(tr("Average"), QString::number(avg() * _yScale, 'f', 1) + " "
+ _yUnits); + _yUnits);
addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1) + " " addInfo(tr("Maximum"), QString::number(_max * _yScale, 'f', 1) + " "
+ _yUnits); + _yUnits);
@ -49,6 +40,19 @@ void SpeedGraph::loadGPX(const GPX &gpx)
Graph::loadData(data); Graph::loadData(data);
} }
qreal SpeedGraph::avg() const
{
qreal sum = 0, w = 0;
QList<QPointF>::const_iterator it;
for (it = _avg.begin(); it != _avg.end(); it++) {
sum += it->y() * it->x();
w += it->x();
}
return (sum / w);
}
void SpeedGraph::clear() void SpeedGraph::clear()
{ {
_max = 0; _max = 0;

View File

@ -15,6 +15,9 @@ public:
void loadGPX(const GPX &gpx); void loadGPX(const GPX &gpx);
void clear(); void clear();
qreal avg() const;
qreal max() const {return _max;}
private: private:
qreal _max; qreal _max;
QList<QPointF> _avg; QList<QPointF> _avg;