1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-06-27 11:39:16 +02:00

Added moving time info.

Added special track data processing for "pause states".
This commit is contained in:
2017-01-31 09:37:01 +01:00
parent ddacac8d2e
commit 961eac9324
11 changed files with 380 additions and 245 deletions

View File

@ -78,6 +78,7 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent)
_trackDistance = 0;
_routeDistance = 0;
_time = 0;
_movingTime = 0;
_sliderPos = 0;
@ -661,6 +662,7 @@ bool GUI::loadFile(const QString &fileName)
for (int i = 0; i < data.tracks().count(); i++) {
_trackDistance += data.tracks().at(i)->distance();
_time += data.tracks().at(i)->time();
_movingTime += data.tracks().at(i)->movingTime();
const QDate &date = data.tracks().at(i)->date().date();
if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date;
@ -822,9 +824,9 @@ void GUI::plot(QPrinter *printer)
QPainter p(printer);
TrackInfo info;
qreal ih, gh, mh, ratio;
Units units = _imperialUnitsAction->isChecked() ? Imperial : Metric;
qreal d = distance();
qreal t = time();
qreal tm = movingTime();
if (!_pathName.isNull() && _options.printName)
info.insert(tr("Name"), _pathName);
@ -851,9 +853,11 @@ void GUI::plot(QPrinter *printer)
}
if (d > 0 && _options.printDistance)
info.insert(tr("Distance"), Format::distance(d, units));
info.insert(tr("Distance"), Format::distance(d, units()));
if (t > 0 && _options.printTime)
info.insert(tr("Time"), Format::timeSpan(t));
if (tm > 0 && _options.printMovingTime)
info.insert(tr("Moving Time"), Format::timeSpan(tm));
ratio = p.paintEngine()->paintDevice()->logicalDpiX() / SCREEN_DPI;
@ -908,6 +912,7 @@ void GUI::reloadFile()
_trackDistance = 0;
_routeDistance = 0;
_time = 0;
_movingTime = 0;
_dateRange = DateRange(QDate(), QDate());
_pathName = QString();
@ -942,6 +947,7 @@ void GUI::closeFiles()
_trackDistance = 0;
_routeDistance = 0;
_time = 0;
_movingTime = 0;
_dateRange = DateRange(QDate(), QDate());
_pathName = QString();
@ -1063,18 +1069,20 @@ void GUI::updateStatusBarInfo()
else
_fileNameLabel->setText(tr("%n files", "", _files.count()));
qreal d = distance();
Units units = _imperialUnitsAction->isChecked() ? Imperial : Metric;
if (d > 0)
_distanceLabel->setText(Format::distance(distance(), units));
if (distance() > 0)
_distanceLabel->setText(Format::distance(distance(), units()));
else
_distanceLabel->clear();
qreal t = time();
if (t > 0)
if (time() > 0)
_timeLabel->setText(Format::timeSpan(time()));
else
_timeLabel->clear();
if (movingTime() > 0)
_timeLabel->setToolTip(Format::timeSpan(movingTime()));
else
_timeLabel->setToolTip(QString());
}
void GUI::updateWindowTitle()
@ -1429,6 +1437,8 @@ void GUI::writeSettings()
settings.setValue(PRINT_DISTANCE_SETTING, _options.printDistance);
if (_options.printTime != PRINT_TIME_DEFAULT)
settings.setValue(PRINT_TIME_SETTING, _options.printTime);
if (_options.printMovingTime != PRINT_MOVING_TIME_DEFAULT)
settings.setValue(PRINT_MOVING_TIME_SETTING, _options.printMovingTime);
if (_options.printItemCount != PRINT_ITEM_COUNT_DEFAULT)
settings.setValue(PRINT_ITEM_COUNT_SETTING, _options.printItemCount);
if (_options.separateGraphPage != SEPARATE_GRAPH_PAGE_DEFAULT)
@ -1598,6 +1608,8 @@ void GUI::readSettings()
PRINT_DISTANCE_DEFAULT).toBool();
_options.printTime = settings.value(PRINT_TIME_SETTING, PRINT_TIME_DEFAULT)
.toBool();
_options.printMovingTime = settings.value(PRINT_MOVING_TIME_SETTING,
PRINT_MOVING_TIME_DEFAULT).toBool();
_options.printItemCount = settings.value(PRINT_ITEM_COUNT_SETTING,
PRINT_ITEM_COUNT_DEFAULT).toBool();
_options.separateGraphPage = settings.value(SEPARATE_GRAPH_PAGE_SETTING,
@ -1635,6 +1647,11 @@ int GUI::mapIndex(const QString &name)
return 0;
}
Units GUI::units() const
{
return _imperialUnitsAction->isChecked() ? Imperial : Metric;
}
qreal GUI::distance() const
{
qreal dist = 0;
@ -1651,3 +1668,8 @@ qreal GUI::time() const
{
return (_showTracksAction->isChecked()) ? _time : 0;
}
qreal GUI::movingTime() const
{
return (_showTracksAction->isChecked()) ? _movingTime : 0;
}

View File

@ -102,11 +102,13 @@ private:
void updateGraphTabs();
void updatePathView();
Units units() const;
void setUnits(Units units);
void setGraphType(GraphType type);
qreal distance() const;
qreal time() const;
qreal movingTime() const;
int mapIndex(const QString &name);
void readSettings();
void writeSettings();
@ -188,6 +190,7 @@ private:
qreal _trackDistance;
qreal _routeDistance;
qreal _time;
qreal _movingTime;
DateRange _dateRange;
QString _pathName;

View File

@ -152,6 +152,8 @@ QWidget *OptionsDialog::createExportPage()
_distance->setChecked(_options->printDistance);
_time = new QCheckBox(tr("Time"));
_time->setChecked(_options->printTime);
_movingTime = new QCheckBox(tr("Moving Time"));
_movingTime->setChecked(_options->printMovingTime);
_itemCount = new QCheckBox(tr("Item count (>1)"));
_itemCount->setChecked(_options->printItemCount);
@ -160,6 +162,7 @@ QWidget *OptionsDialog::createExportPage()
headerTabLayout->addWidget(_date);
headerTabLayout->addWidget(_distance);
headerTabLayout->addWidget(_time);
headerTabLayout->addWidget(_movingTime);
headerTabLayout->addItem(new QSpacerItem(10, 10));
headerTabLayout->addWidget(_itemCount);
QWidget *headerTab = new QWidget();
@ -277,6 +280,7 @@ void OptionsDialog::accept()
_options->printDate = _date->isChecked();
_options->printDistance = _distance->isChecked();
_options->printTime = _time->isChecked();
_options->printMovingTime = _movingTime->isChecked();
_options->printItemCount = _itemCount->isChecked();
_options->separateGraphPage = _separateGraphPage->isChecked();

View File

@ -31,6 +31,7 @@ struct Options {
bool printDate;
bool printDistance;
bool printTime;
bool printMovingTime;
bool printItemCount;
bool separateGraphPage;
@ -70,6 +71,7 @@ private:
QCheckBox *_date;
QCheckBox *_distance;
QCheckBox *_time;
QCheckBox *_movingTime;
QCheckBox *_itemCount;
QCheckBox *_separateGraphPage;
};

View File

@ -100,6 +100,8 @@
#define PRINT_DISTANCE_DEFAULT true
#define PRINT_TIME_SETTING "printTime"
#define PRINT_TIME_DEFAULT true
#define PRINT_MOVING_TIME_SETTING "printMovingTime"
#define PRINT_MOVING_TIME_DEFAULT false
#define PRINT_ITEM_COUNT_SETTING "printItemCount"
#define PRINT_ITEM_COUNT_DEFAULT true
#define SEPARATE_GRAPH_PAGE_SETTING "separateGraphPage"

View File

@ -9,6 +9,9 @@
#define WINDOW_CF 3
#define WINDOW_PF 3
#define PAUSE_SPEED 0.5
#define PAUSE_TIME_DIFF 10
static qreal median(QVector<qreal> v)
{
@ -43,30 +46,31 @@ static QSet<int> eliminate(const QVector<qreal> &v, int window)
return rm;
}
static Graph filter(const Graph &v, int window)
static Graph filter(const Graph &g, int window)
{
qreal acc = 0;
Graph ret;
if (v.size() < window)
if (g.size() < window)
return ret;
for (int i = 0; i < window; i++)
acc += v.at(i).y();
acc += g.at(i).y();
for (int i = 0; i <= window/2; i++)
ret.append(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
ret.append(GraphPoint(g.at(i).s(), g.at(i).t(), 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(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
for (int i = window/2 + 1; i < g.size() - window/2; i++) {
acc += g.at(i + window/2).y() - g.at(i - (window/2 + 1)).y();
ret.append(GraphPoint(g.at(i).s(), g.at(i).t(), acc/window));
}
for (int i = v.size() - window/2; i < v.size(); i++)
ret.append(GraphPoint(v.at(i).s(), v.at(i).t(), acc/window));
for (int i = g.size() - window/2; i < g.size(); i++)
ret.append(GraphPoint(g.at(i).s(), g.at(i).t(), acc/window));
return ret;
}
Track::Track(const TrackData &data) : _data(data)
{
qreal dt, ds, total;
@ -98,13 +102,28 @@ Track::Track(const TrackData &data) : _data(data)
}
}
_pause = 0;
for (int i = 1; i < data.count(); i++) {
if (_time.at(i) > _time.at(i-1) + PAUSE_TIME_DIFF
&& _speed.at(i) < PAUSE_SPEED) {
_pause += _time.at(i) - _time.at(i-1);
_stop.insert(i-1);
_stop.insert(i);
}
}
_outliers = eliminate(_speed, WINDOW_OE);
QSet<int>::const_iterator it;
for (it = _stop.constBegin(); it != _stop.constEnd(); ++it)
_outliers.remove(*it);
total = 0;
for (int i = 0; i < _data.size(); i++) {
if (_outliers.contains(i))
continue;
total += _distance.at(i);
if (!discardStopPoint(i))
total += _distance.at(i);
_distance[i] = total;
}
}
@ -113,9 +132,6 @@ Graph Track::elevation() const
{
Graph raw;
if (!_data.size())
return raw;
for (int i = 0; i < _data.size(); i++)
if (_data.at(i).hasElevation() && !_outliers.contains(i))
raw.append(GraphPoint(_distance.at(i), _time.at(i),
@ -126,14 +142,16 @@ Graph Track::elevation() const
Graph Track::speed() const
{
Graph raw;
Graph raw, filtered;
qreal v;
if (!_data.size())
return raw;
QSet<int> stop;
for (int i = 0; i < _data.size(); i++) {
if (_data.at(i).hasSpeed() && !_outliers.contains(i))
if (_stop.contains(i) && (!std::isnan(_speed.at(i))
|| _data.at(i).hasSpeed())) {
v = 0;
stop.insert(raw.size());
} else if (_data.at(i).hasSpeed() && !_outliers.contains(i))
v = _data.at(i).speed();
else if (!std::isnan(_speed.at(i)) && !_outliers.contains(i))
v = _speed.at(i);
@ -143,16 +161,19 @@ Graph Track::speed() const
raw.append(GraphPoint(_distance.at(i), _time.at(i), v));
}
return filter(raw, WINDOW_SF);
filtered = filter(raw, WINDOW_SF);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)
filtered[*it].setY(0);
return filtered;
}
Graph Track::heartRate() const
{
Graph raw;
if (!_data.size())
return raw;
for (int i = 0; i < _data.count(); i++)
if (_data.at(i).hasHeartRate() && !_outliers.contains(i))
raw.append(GraphPoint(_distance.at(i), _time.at(i),
@ -175,26 +196,56 @@ Graph Track::temperature() const
Graph Track::cadence() const
{
Graph raw;
Graph raw, filtered;
QSet<int> stop;
qreal c;
for (int i = 0; i < _data.size(); i++)
if (_data.at(i).hasCadence() && !_outliers.contains(i))
raw.append(GraphPoint(_distance.at(i), _time.at(i),
_data.at(i).cadence()));
for (int i = 0; i < _data.size(); i++) {
if (_data.at(i).hasCadence() && _stop.contains(i)) {
c = 0;
stop.insert(raw.size());
} else if (_data.at(i).hasCadence() && !_outliers.contains(i))
c = _data.at(i).cadence();
else
continue;
return filter(raw, WINDOW_CF);
raw.append(GraphPoint(_distance.at(i), _time.at(i), c));
}
filtered = filter(raw, WINDOW_CF);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)
filtered[*it].setY(0);
return filtered;
}
Graph Track::power() const
{
Graph raw;
Graph raw, filtered;
QSet<int> stop;
qreal p;
for (int i = 0; i < _data.size(); i++)
if (_data.at(i).hasPower() && !_outliers.contains(i))
raw.append(GraphPoint(_distance.at(i), _time.at(i),
_data.at(i).power()));
for (int i = 0; i < _data.size(); i++) {
if (_data.at(i).hasPower() && _stop.contains(i)) {
p = 0;
stop.insert(raw.size());
} else if (_data.at(i).hasPower() && !_outliers.contains(i))
p = _data.at(i).power();
else
continue;
return filter(raw, WINDOW_PF);
raw.append(GraphPoint(_distance.at(i), _time.at(i), p));
}
filtered = filter(raw, WINDOW_PF);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)
filtered[*it].setY(0);
return filtered;
}
qreal Track::distance() const
@ -208,6 +259,11 @@ qreal Track::time() const
(_data.first().timestamp().msecsTo(_data.last().timestamp()) / 1000.0);
}
qreal Track::movingTime() const
{
return (time() - _pause);
}
QDateTime Track::date() const
{
return (_data.size()) ? _data.first().timestamp() : QDateTime();
@ -218,8 +274,14 @@ Path Track::path() const
Path ret;
for (int i = 0; i < _data.size(); i++)
if (!_outliers.contains(i))
if (!_outliers.contains(i) && !discardStopPoint(i))
ret.append(PathPoint(_data.at(i).coordinates(), _distance.at(i)));
return ret;
}
bool Track::discardStopPoint(int i) const
{
return (_stop.contains(i) && i > 0 && _stop.contains(i-1)
&& i < _data.size() - 1 && _stop.contains(i+1));
}

View File

@ -24,6 +24,7 @@ public:
qreal distance() const;
qreal time() const;
qreal movingTime() const;
QDateTime date() const;
const QString &name() const {return _data.name();}
@ -32,6 +33,8 @@ public:
bool isNull() const {return (_data.size() < 2);}
private:
bool discardStopPoint(int i) const;
const TrackData &_data;
QVector<qreal> _distance;
@ -39,6 +42,9 @@ private:
QVector<qreal> _speed;
QSet<int> _outliers;
QSet<int> _stop;
qreal _pause;
};
#endif // TRACK_H

View File

@ -15,6 +15,8 @@ QString TrackItem::toolTip()
tt.insert(tr("Distance"), Format::distance(_distance.last(), _units));
if (_time > 0)
tt.insert(tr("Time"), Format::timeSpan(_time));
if (_movingTime > 0)
tt.insert(tr("Moving Time"), Format::timeSpan(_movingTime));
if (!_date.isNull())
tt.insert(tr("Date"), _date.toString(Qt::SystemLocaleShortDate));
@ -45,6 +47,7 @@ TrackItem::TrackItem(const Track &track, QGraphicsItem *parent)
_desc = track.description();
_date = track.date();
_time = track.time();
_movingTime = track.movingTime();
_marker->setPos(_path.elementAt(0));

View File

@ -23,6 +23,7 @@ private:
QString _desc;
QDateTime _date;
qreal _time;
qreal _movingTime;
};
#endif // TRACKITEM_H