mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Added automatic pause detection
This commit is contained in:
parent
bb238f4c7e
commit
258a9b0201
@ -949,6 +949,7 @@ void GUI::openOptions()
|
|||||||
SET_TRACK_OPTION(cadenceFilter, setCadenceFilter);
|
SET_TRACK_OPTION(cadenceFilter, setCadenceFilter);
|
||||||
SET_TRACK_OPTION(powerFilter, setPowerFilter);
|
SET_TRACK_OPTION(powerFilter, setPowerFilter);
|
||||||
SET_TRACK_OPTION(outlierEliminate, setOutlierElimination);
|
SET_TRACK_OPTION(outlierEliminate, setOutlierElimination);
|
||||||
|
SET_TRACK_OPTION(automaticPause, setAutomaticPause);
|
||||||
SET_TRACK_OPTION(pauseSpeed, setPauseSpeed);
|
SET_TRACK_OPTION(pauseSpeed, setPauseSpeed);
|
||||||
SET_TRACK_OPTION(pauseInterval, setPauseInterval);
|
SET_TRACK_OPTION(pauseInterval, setPauseInterval);
|
||||||
SET_TRACK_OPTION(useReportedSpeed, useReportedSpeed);
|
SET_TRACK_OPTION(useReportedSpeed, useReportedSpeed);
|
||||||
@ -1798,6 +1799,8 @@ void GUI::writeSettings()
|
|||||||
settings.setValue(POWER_FILTER_SETTING, _options.powerFilter);
|
settings.setValue(POWER_FILTER_SETTING, _options.powerFilter);
|
||||||
if (_options.outlierEliminate != OUTLIER_ELIMINATE_DEFAULT)
|
if (_options.outlierEliminate != OUTLIER_ELIMINATE_DEFAULT)
|
||||||
settings.setValue(OUTLIER_ELIMINATE_SETTING, _options.outlierEliminate);
|
settings.setValue(OUTLIER_ELIMINATE_SETTING, _options.outlierEliminate);
|
||||||
|
if (_options.automaticPause != AUTOMATIC_PAUSE_DEFAULT)
|
||||||
|
settings.setValue(AUTOMATIC_PAUSE_SETTING, _options.automaticPause);
|
||||||
if (_options.pauseSpeed != PAUSE_SPEED_DEFAULT)
|
if (_options.pauseSpeed != PAUSE_SPEED_DEFAULT)
|
||||||
settings.setValue(PAUSE_SPEED_SETTING, _options.pauseSpeed);
|
settings.setValue(PAUSE_SPEED_SETTING, _options.pauseSpeed);
|
||||||
if (_options.pauseInterval != PAUSE_INTERVAL_DEFAULT)
|
if (_options.pauseInterval != PAUSE_INTERVAL_DEFAULT)
|
||||||
@ -2072,6 +2075,8 @@ void GUI::readSettings()
|
|||||||
USE_REPORTED_SPEED_DEFAULT).toBool();
|
USE_REPORTED_SPEED_DEFAULT).toBool();
|
||||||
_options.dataUseDEM = settings.value(DATA_USE_DEM_SETTING,
|
_options.dataUseDEM = settings.value(DATA_USE_DEM_SETTING,
|
||||||
DATA_USE_DEM_DEFAULT).toBool();
|
DATA_USE_DEM_DEFAULT).toBool();
|
||||||
|
_options.automaticPause = settings.value(AUTOMATIC_PAUSE_SETTING,
|
||||||
|
AUTOMATIC_PAUSE_DEFAULT).toBool();
|
||||||
_options.pauseInterval = settings.value(PAUSE_INTERVAL_SETTING,
|
_options.pauseInterval = settings.value(PAUSE_INTERVAL_SETTING,
|
||||||
PAUSE_INTERVAL_DEFAULT).toInt();
|
PAUSE_INTERVAL_DEFAULT).toInt();
|
||||||
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
|
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
|
||||||
@ -2153,6 +2158,7 @@ void GUI::readSettings()
|
|||||||
Track::setCadenceFilter(_options.cadenceFilter);
|
Track::setCadenceFilter(_options.cadenceFilter);
|
||||||
Track::setPowerFilter(_options.powerFilter);
|
Track::setPowerFilter(_options.powerFilter);
|
||||||
Track::setOutlierElimination(_options.outlierEliminate);
|
Track::setOutlierElimination(_options.outlierEliminate);
|
||||||
|
Track::setAutomaticPause(_options.automaticPause);
|
||||||
Track::setPauseSpeed(_options.pauseSpeed);
|
Track::setPauseSpeed(_options.pauseSpeed);
|
||||||
Track::setPauseInterval(_options.pauseInterval);
|
Track::setPauseInterval(_options.pauseInterval);
|
||||||
Track::useReportedSpeed(_options.useReportedSpeed);
|
Track::useReportedSpeed(_options.useReportedSpeed);
|
||||||
|
@ -37,6 +37,12 @@ static QFrame *line()
|
|||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
|
|
||||||
|
void OptionsDialog::automaticPauseDetectionSet(bool set)
|
||||||
|
{
|
||||||
|
_pauseInterval->setEnabled(!set);
|
||||||
|
_pauseSpeed->setEnabled(!set);
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *OptionsDialog::createMapPage()
|
QWidget *OptionsDialog::createMapPage()
|
||||||
{
|
{
|
||||||
_projection = new LimitedComboBox(200);
|
_projection = new LimitedComboBox(200);
|
||||||
@ -343,10 +349,18 @@ QWidget *OptionsDialog::createDataPage()
|
|||||||
filterTab->setLayout(filterTabLayout);
|
filterTab->setLayout(filterTabLayout);
|
||||||
|
|
||||||
|
|
||||||
|
_automaticPause = new QRadioButton(tr("Automatic"));
|
||||||
|
_manualPause = new QRadioButton(tr("User defined"));
|
||||||
|
if (_options->automaticPause)
|
||||||
|
_automaticPause->setChecked(true);
|
||||||
|
else
|
||||||
|
_manualPause->setChecked(true);
|
||||||
|
|
||||||
_pauseSpeed = new QDoubleSpinBox();
|
_pauseSpeed = new QDoubleSpinBox();
|
||||||
_pauseSpeed->setDecimals(1);
|
_pauseSpeed->setDecimals(1);
|
||||||
_pauseSpeed->setSingleStep(0.1);
|
_pauseSpeed->setSingleStep(0.1);
|
||||||
_pauseSpeed->setMinimum(0.1);
|
_pauseSpeed->setMinimum(0.1);
|
||||||
|
_pauseSpeed->setEnabled(_manualPause->isChecked());
|
||||||
if (_options->units == Imperial) {
|
if (_options->units == Imperial) {
|
||||||
_pauseSpeed->setValue(_options->pauseSpeed * MS2MIH);
|
_pauseSpeed->setValue(_options->pauseSpeed * MS2MIH);
|
||||||
_pauseSpeed->setSuffix(UNIT_SPACE + tr("mi/h"));
|
_pauseSpeed->setSuffix(UNIT_SPACE + tr("mi/h"));
|
||||||
@ -361,10 +375,23 @@ QWidget *OptionsDialog::createDataPage()
|
|||||||
_pauseInterval->setMinimum(1);
|
_pauseInterval->setMinimum(1);
|
||||||
_pauseInterval->setSuffix(UNIT_SPACE + tr("s"));
|
_pauseInterval->setSuffix(UNIT_SPACE + tr("s"));
|
||||||
_pauseInterval->setValue(_options->pauseInterval);
|
_pauseInterval->setValue(_options->pauseInterval);
|
||||||
|
_pauseInterval->setEnabled(_manualPause->isChecked());
|
||||||
|
|
||||||
QFormLayout *pauseLayout = new QFormLayout();
|
connect(_automaticPause, SIGNAL(toggled(bool)), this,
|
||||||
pauseLayout->addRow(tr("Minimal speed:"), _pauseSpeed);
|
SLOT(automaticPauseDetectionSet(bool)));
|
||||||
pauseLayout->addRow(tr("Minimal duration:"), _pauseInterval);
|
|
||||||
|
QHBoxLayout *pauseTypeLayout = new QHBoxLayout();
|
||||||
|
pauseTypeLayout->addWidget(_automaticPause);
|
||||||
|
pauseTypeLayout->addWidget(_manualPause);
|
||||||
|
pauseTypeLayout->addStretch();
|
||||||
|
|
||||||
|
QFormLayout *pauseValuesLayout = new QFormLayout();
|
||||||
|
pauseValuesLayout->addRow(tr("Minimal speed:"), _pauseSpeed);
|
||||||
|
pauseValuesLayout->addRow(tr("Minimal duration:"), _pauseInterval);
|
||||||
|
|
||||||
|
QVBoxLayout *pauseLayout = new QVBoxLayout();
|
||||||
|
pauseLayout->addLayout(pauseTypeLayout);
|
||||||
|
pauseLayout->addLayout(pauseValuesLayout);
|
||||||
|
|
||||||
QWidget *pauseTab = new QWidget();
|
QWidget *pauseTab = new QWidget();
|
||||||
pauseTab->setLayout(pauseLayout);
|
pauseTab->setLayout(pauseLayout);
|
||||||
@ -679,6 +706,7 @@ void OptionsDialog::accept()
|
|||||||
_options->cadenceFilter = _cadenceFilter->value();
|
_options->cadenceFilter = _cadenceFilter->value();
|
||||||
_options->powerFilter = _powerFilter->value();
|
_options->powerFilter = _powerFilter->value();
|
||||||
_options->outlierEliminate = _outlierEliminate->isChecked();
|
_options->outlierEliminate = _outlierEliminate->isChecked();
|
||||||
|
_options->automaticPause = _automaticPause->isChecked();
|
||||||
qreal pauseSpeed = (_options->units == Imperial)
|
qreal pauseSpeed = (_options->units == Imperial)
|
||||||
? _pauseSpeed->value() / MS2MIH : (_options->units == Nautical)
|
? _pauseSpeed->value() / MS2MIH : (_options->units == Nautical)
|
||||||
? _pauseSpeed->value() / MS2KN : _pauseSpeed->value() / MS2KMH;
|
? _pauseSpeed->value() / MS2KN : _pauseSpeed->value() / MS2KMH;
|
||||||
|
@ -49,6 +49,7 @@ struct Options {
|
|||||||
int cadenceFilter;
|
int cadenceFilter;
|
||||||
int powerFilter;
|
int powerFilter;
|
||||||
bool outlierEliminate;
|
bool outlierEliminate;
|
||||||
|
bool automaticPause;
|
||||||
qreal pauseSpeed;
|
qreal pauseSpeed;
|
||||||
int pauseInterval;
|
int pauseInterval;
|
||||||
bool useReportedSpeed;
|
bool useReportedSpeed;
|
||||||
@ -86,6 +87,9 @@ public slots:
|
|||||||
public:
|
public:
|
||||||
OptionsDialog(Options *options, QWidget *parent = 0);
|
OptionsDialog(Options *options, QWidget *parent = 0);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void automaticPauseDetectionSet(bool set);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *createMapPage();
|
QWidget *createMapPage();
|
||||||
QWidget *createAppearancePage();
|
QWidget *createAppearancePage();
|
||||||
@ -129,6 +133,9 @@ private:
|
|||||||
OddSpinBox *_cadenceFilter;
|
OddSpinBox *_cadenceFilter;
|
||||||
OddSpinBox *_powerFilter;
|
OddSpinBox *_powerFilter;
|
||||||
QCheckBox *_outlierEliminate;
|
QCheckBox *_outlierEliminate;
|
||||||
|
|
||||||
|
QRadioButton *_automaticPause;
|
||||||
|
QRadioButton *_manualPause;
|
||||||
QDoubleSpinBox *_pauseSpeed;
|
QDoubleSpinBox *_pauseSpeed;
|
||||||
QSpinBox *_pauseInterval;
|
QSpinBox *_pauseInterval;
|
||||||
QRadioButton *_computedSpeed;
|
QRadioButton *_computedSpeed;
|
||||||
|
@ -135,6 +135,8 @@
|
|||||||
#define POWER_FILTER_DEFAULT 3
|
#define POWER_FILTER_DEFAULT 3
|
||||||
#define OUTLIER_ELIMINATE_SETTING "outlierEliminate"
|
#define OUTLIER_ELIMINATE_SETTING "outlierEliminate"
|
||||||
#define OUTLIER_ELIMINATE_DEFAULT true
|
#define OUTLIER_ELIMINATE_DEFAULT true
|
||||||
|
#define AUTOMATIC_PAUSE_SETTING "automaticPause"
|
||||||
|
#define AUTOMATIC_PAUSE_DEFAULT true
|
||||||
#define PAUSE_SPEED_SETTING "pauseSpeed"
|
#define PAUSE_SPEED_SETTING "pauseSpeed"
|
||||||
#define PAUSE_SPEED_DEFAULT 0.5 /* m/s */
|
#define PAUSE_SPEED_DEFAULT 0.5 /* m/s */
|
||||||
#define PAUSE_INTERVAL_SETTING "pauseInterval"
|
#define PAUSE_INTERVAL_SETTING "pauseInterval"
|
||||||
|
@ -7,6 +7,7 @@ int Track::_heartRateWindow = 3;
|
|||||||
int Track::_cadenceWindow = 3;
|
int Track::_cadenceWindow = 3;
|
||||||
int Track::_powerWindow = 3;
|
int Track::_powerWindow = 3;
|
||||||
|
|
||||||
|
bool Track::_automaticPause = true;
|
||||||
qreal Track::_pauseSpeed = 0.5;
|
qreal Track::_pauseSpeed = 0.5;
|
||||||
int Track::_pauseInterval = 10;
|
int Track::_pauseInterval = 10;
|
||||||
|
|
||||||
@ -14,6 +15,16 @@ bool Track::_outlierEliminate = true;
|
|||||||
bool Track::_useReportedSpeed = false;
|
bool Track::_useReportedSpeed = false;
|
||||||
|
|
||||||
|
|
||||||
|
static qreal avg(const QVector<qreal> &v)
|
||||||
|
{
|
||||||
|
qreal sum = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < v.size(); i++)
|
||||||
|
sum += v.at(i);
|
||||||
|
|
||||||
|
return sum/v.size();
|
||||||
|
}
|
||||||
|
|
||||||
static qreal median(QVector<qreal> &v)
|
static qreal median(QVector<qreal> &v)
|
||||||
{
|
{
|
||||||
qSort(v.begin(), v.end());
|
qSort(v.begin(), v.end());
|
||||||
@ -24,8 +35,7 @@ static qreal MAD(QVector<qreal> &v, qreal m)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < v.size(); i++)
|
for (int i = 0; i < v.size(); i++)
|
||||||
v[i] = qAbs(v.at(i) - m);
|
v[i] = qAbs(v.at(i) - m);
|
||||||
qSort(v.begin(), v.end());
|
return median(v);
|
||||||
return v.at(v.size() / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSet<int> eliminate(const QVector<qreal> &v)
|
static QSet<int> eliminate(const QVector<qreal> &v)
|
||||||
@ -132,15 +142,30 @@ Track::Track(const TrackData &data) : _data(data), _pause(0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
// get stop-points + pause duration
|
// get stop-points + pause duration
|
||||||
|
int pauseInterval;
|
||||||
|
qreal pauseSpeed;
|
||||||
|
|
||||||
|
if (_automaticPause) {
|
||||||
|
pauseSpeed = (avg(seg.speed) > 2.8) ? 0.55 : 0.15;
|
||||||
|
pauseInterval = 10;
|
||||||
|
} else {
|
||||||
|
pauseSpeed = _pauseSpeed;
|
||||||
|
pauseInterval = _pauseInterval;
|
||||||
|
}
|
||||||
|
|
||||||
int ss = 0, la = 0;
|
int ss = 0, la = 0;
|
||||||
for (int j = 1; j < seg.time.size(); j++) {
|
for (int j = 1; j < seg.time.size(); j++) {
|
||||||
if (seg.speed.at(j) > _pauseSpeed)
|
if (seg.speed.at(j) > pauseSpeed)
|
||||||
ss = -1;
|
ss = -1;
|
||||||
else if (ss < 0)
|
else if (ss < 0)
|
||||||
ss = j;
|
ss = j;
|
||||||
|
|
||||||
if (ss >= 0 && seg.time.at(j) > seg.time.at(ss) + _pauseInterval) {
|
if (ss >= 0 && seg.time.at(j) > seg.time.at(ss) + pauseInterval) {
|
||||||
int l = qMax(ss, la);
|
int l = qMax(ss, la);
|
||||||
_pause += seg.time.at(j) - seg.time.at(l);
|
_pause += seg.time.at(j) - seg.time.at(l);
|
||||||
for (int k = l; k <= j; k++)
|
for (int k = l; k <= j; k++)
|
||||||
@ -149,7 +174,7 @@ Track::Track(const TrackData &data) : _data(data), _pause(0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_outlierEliminate || !hasTime)
|
if (!_outlierEliminate)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
static void setHeartRateFilter(int window) {_heartRateWindow = window;}
|
static void setHeartRateFilter(int window) {_heartRateWindow = window;}
|
||||||
static void setCadenceFilter(int window) {_cadenceWindow = window;}
|
static void setCadenceFilter(int window) {_cadenceWindow = window;}
|
||||||
static void setPowerFilter(int window) {_powerWindow = window;}
|
static void setPowerFilter(int window) {_powerWindow = window;}
|
||||||
|
static void setAutomaticPause(bool set) {_automaticPause = set;}
|
||||||
static void setPauseSpeed(qreal speed) {_pauseSpeed = speed;}
|
static void setPauseSpeed(qreal speed) {_pauseSpeed = speed;}
|
||||||
static void setPauseInterval(int interval) {_pauseInterval = interval;}
|
static void setPauseInterval(int interval) {_pauseInterval = interval;}
|
||||||
static void setOutlierElimination(bool eliminate)
|
static void setOutlierElimination(bool eliminate)
|
||||||
@ -68,6 +69,7 @@ private:
|
|||||||
static int _heartRateWindow;
|
static int _heartRateWindow;
|
||||||
static int _cadenceWindow;
|
static int _cadenceWindow;
|
||||||
static int _powerWindow;
|
static int _powerWindow;
|
||||||
|
static bool _automaticPause;
|
||||||
static qreal _pauseSpeed;
|
static qreal _pauseSpeed;
|
||||||
static int _pauseInterval;
|
static int _pauseInterval;
|
||||||
static bool _useReportedSpeed;
|
static bool _useReportedSpeed;
|
||||||
|
Loading…
Reference in New Issue
Block a user