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

Added data filtering settings

This commit is contained in:
2017-05-22 14:54:22 +02:00
parent 4386e1f2e1
commit 223a13583c
14 changed files with 582 additions and 131 deletions

View File

@ -874,6 +874,7 @@ void GUI::printFile()
void GUI::openOptions()
{
Options options(_options);
bool reload = false;
OptionsDialog dialog(&options, this);
if (dialog.exec() != QDialog::Accepted)
@ -903,6 +904,39 @@ void GUI::openOptions()
_tabs.at(i)->setRenderHint(QPainter::Antialiasing,
options.graphAntiAliasing);
if (options.elevationFilter != _options.elevationFilter) {
Track::setElevationFilter(options.elevationFilter);
reload = true;
}
if (options.speedFilter != _options.speedFilter) {
Track::setSpeedFilter(options.speedFilter);
reload = true;
}
if (options.heartRateFilter != _options.heartRateFilter) {
Track::setHeartRateFilter(options.heartRateFilter);
reload = true;
}
if (options.cadenceFilter != _options.cadenceFilter) {
Track::setCadenceFilter(options.cadenceFilter);
reload = true;
}
if (options.powerFilter != _options.powerFilter) {
Track::setPowerFilter(options.powerFilter);
reload = true;
}
if (options.outlierEliminate != _options.outlierEliminate) {
Track::setOutlierElimination(options.outlierEliminate);
reload = true;
}
if (options.pauseSpeed != _options.pauseSpeed) {
Track::setPauseSpeed(options.pauseSpeed);
reload = true;
}
if (options.pauseInterval != _options.pauseInterval) {
Track::setPauseInterval(options.pauseInterval);
reload = true;
}
if (options.poiRadius != _options.poiRadius)
_poi->setRadius(options.poiRadius);
@ -914,6 +948,9 @@ void GUI::openOptions()
if (options.pixmapCache != _options.pixmapCache)
QPixmapCache::setCacheLimit(options.pixmapCache * 1024);
if (reload)
reloadFile();
_options = options;
}
@ -1580,6 +1617,22 @@ void GUI::writeSettings()
settings.setValue(PATH_AA_SETTING, _options.pathAntiAliasing);
if (_options.graphAntiAliasing != GRAPH_AA_DEFAULT)
settings.setValue(GRAPH_AA_SETTING, _options.graphAntiAliasing);
if (_options.elevationFilter != ELEVATION_FILTER_DEFAULT)
settings.setValue(ELEVATION_FILTER_SETTING, _options.elevationFilter);
if (_options.speedFilter != SPEED_FILTER_DEFAULT)
settings.setValue(SPEED_FILTER_SETTING, _options.speedFilter);
if (_options.heartRateFilter != HEARTRATE_FILTER_DEFAULT)
settings.setValue(HEARTRATE_FILTER_SETTING, _options.heartRateFilter);
if (_options.cadenceFilter != CADENCE_FILTER_DEFAULT)
settings.setValue(CADENCE_FILTER_SETTING, _options.cadenceFilter);
if (_options.powerFilter != POWER_FILTER_DEFAULT)
settings.setValue(POWER_FILTER_SETTING, _options.powerFilter);
if (_options.outlierEliminate != OUTLIER_ELIMINATE_DEFAULT)
settings.setValue(OUTLIER_ELIMINATE_SETTING, _options.outlierEliminate);
if (_options.pauseSpeed != PAUSE_SPEED_DEFAULT)
settings.setValue(PAUSE_SPEED_SETTING, _options.pauseSpeed);
if (_options.pauseInterval != PAUSE_INTERVAL_DEFAULT)
settings.setValue(PAUSE_INTERVAL_SETTING, _options.pauseInterval);
if (_options.poiRadius != POI_RADIUS_DEFAULT)
settings.setValue(POI_RADIUS_SETTING, _options.poiRadius);
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
@ -1759,6 +1812,22 @@ void GUI::readSettings()
GRAPH_WIDTH_DEFAULT).toInt();
_options.graphAntiAliasing = settings.value(GRAPH_AA_SETTING,
GRAPH_AA_DEFAULT).toBool();
_options.elevationFilter = settings.value(ELEVATION_FILTER_SETTING,
ELEVATION_FILTER_DEFAULT).toInt();
_options.speedFilter = settings.value(SPEED_FILTER_SETTING,
SPEED_FILTER_DEFAULT).toInt();
_options.heartRateFilter = settings.value(HEARTRATE_FILTER_SETTING,
HEARTRATE_FILTER_DEFAULT).toInt();
_options.cadenceFilter = settings.value(CADENCE_FILTER_SETTING,
CADENCE_FILTER_DEFAULT).toInt();
_options.powerFilter = settings.value(POWER_FILTER_SETTING,
POWER_FILTER_DEFAULT).toInt();
_options.outlierEliminate = settings.value(OUTLIER_ELIMINATE_SETTING,
OUTLIER_ELIMINATE_DEFAULT).toBool();
_options.pauseSpeed = settings.value(PAUSE_SPEED_SETTING,
PAUSE_SPEED_DEFAULT).toFloat();
_options.pauseInterval = settings.value(PAUSE_INTERVAL_SETTING,
PAUSE_INTERVAL_DEFAULT).toInt();
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
.toInt();
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
@ -1798,6 +1867,15 @@ void GUI::readSettings()
_tabs.at(i)->useOpenGL(true);
}
Track::setElevationFilter(_options.elevationFilter);
Track::setSpeedFilter(_options.speedFilter);
Track::setHeartRateFilter(_options.heartRateFilter);
Track::setCadenceFilter(_options.cadenceFilter);
Track::setPowerFilter(_options.powerFilter);
Track::setOutlierElimination(_options.outlierEliminate);
Track::setPauseSpeed(_options.pauseSpeed);
Track::setPauseInterval(_options.pauseInterval);
_poi->setRadius(_options.poiRadius);
QPixmapCache::setCacheLimit(_options.pixmapCache * 1024);

View File

@ -10,7 +10,7 @@
#define CLOSE_FILE_ICON ":/icons/dialog-close.png"
#define SHOW_POI_ICON ":/icons/flag.png"
#define SHOW_MAP_ICON ":/icons/applications-internet.png"
#define SHOW_GRAPHS_ICON ":/icons/office-chart-line-stacked.png"
#define SHOW_GRAPHS_ICON ":/icons/office-chart-line.png"
#define QUIT_ICON ":/icons/application-exit.png"
#define RELOAD_FILE_ICON ":/icons/view-refresh.png"
#define NEXT_FILE_ICON ":/icons/arrow-right.png"
@ -24,5 +24,6 @@
#define POI_ICON ":/icons/flag_48.png"
#define SYSTEM_ICON ":/icons/system-run.png"
#define PRINT_EXPORT_ICON ":/icons/document-print-preview.png"
#define DATA_ICON ":/icons/view-filter.png"
#endif /* ICONS_H */

View File

@ -117,6 +117,77 @@ QWidget *OptionsDialog::createAppearancePage()
return appearancePage;
}
QWidget *OptionsDialog::createDataPage()
{
QString filterToolTip = tr("Moving average window size");
_elevationFilter = new QSpinBox();
_elevationFilter->setValue(_options->elevationFilter);
_elevationFilter->setToolTip(filterToolTip);
_speedFilter = new QSpinBox();
_speedFilter->setValue(_options->speedFilter);
_speedFilter->setToolTip(filterToolTip);
_heartRateFilter = new QSpinBox();
_heartRateFilter->setValue(_options->heartRateFilter);
_heartRateFilter->setToolTip(filterToolTip);
_cadenceFilter = new QSpinBox();
_cadenceFilter->setValue(_options->cadenceFilter);
_cadenceFilter->setToolTip(filterToolTip);
_powerFilter = new QSpinBox();
_powerFilter->setValue(_options->powerFilter);
_powerFilter->setToolTip(filterToolTip);
QFormLayout *filterLayout = new QFormLayout();
filterLayout->addRow(tr("Elevation:"), _elevationFilter);
filterLayout->addRow(tr("Speed:"), _speedFilter);
filterLayout->addRow(tr("Heart rate:"), _heartRateFilter);
filterLayout->addRow(tr("Cadence:"), _cadenceFilter);
filterLayout->addRow(tr("Power:"), _powerFilter);
_outlierEliminate = new QCheckBox(tr("Outlier elimination"));
_outlierEliminate->setChecked(_options->outlierEliminate);
QFormLayout *outlierLayout = new QFormLayout();
outlierLayout->addWidget(_outlierEliminate);
QWidget *filterTab = new QWidget();
QVBoxLayout *filterTabLayout = new QVBoxLayout();
filterTabLayout->addLayout(filterLayout);
filterTabLayout->addLayout(outlierLayout);
filterTabLayout->addStretch();
filterTab->setLayout(filterTabLayout);
_pauseSpeed = new QDoubleSpinBox();
_pauseSpeed->setDecimals(1);
_pauseSpeed->setSingleStep(0.1);
_pauseSpeed->setMinimum(0.1);
if (_options->units == Imperial) {
_pauseSpeed->setValue(_options->pauseSpeed * MS2MIH);
_pauseSpeed->setSuffix(UNIT_SPACE + tr("mi/h"));
} else {
_pauseSpeed->setValue(_options->pauseSpeed * MS2KMH);
_pauseSpeed->setSuffix(UNIT_SPACE + tr("km/h"));
}
_pauseInterval = new QSpinBox();
_pauseInterval->setMinimum(1);
_pauseInterval->setSuffix(UNIT_SPACE + tr("s"));
_pauseInterval->setValue(_options->pauseInterval);
QFormLayout *pauseLayout = new QFormLayout();
pauseLayout->addRow(tr("Minimal speed:"), _pauseSpeed);
pauseLayout->addRow(tr("Minimal duration:"), _pauseInterval);
QWidget *pauseTab = new QWidget();
pauseTab->setLayout(pauseLayout);
QTabWidget *filterPage = new QTabWidget();
filterPage->addTab(filterTab, tr("Filtering"));
filterPage->addTab(pauseTab, tr("Pause detection"));
return filterPage;
}
QWidget *OptionsDialog::createPOIPage()
{
_poiRadius = new QDoubleSpinBox();
@ -226,6 +297,7 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
{
QStackedWidget *pages = new QStackedWidget();
pages->addWidget(createAppearancePage());
pages->addWidget(createDataPage());
pages->addWidget(createPOIPage());
pages->addWidget(createExportPage());
pages->addWidget(createSystemPage());
@ -234,6 +306,7 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
menu->setIconSize(QSize(MENU_ICON_SIZE, MENU_ICON_SIZE));
new QListWidgetItem(QIcon(QPixmap(APPEARANCE_ICON)), tr("Appearance"),
menu);
new QListWidgetItem(QIcon(QPixmap(DATA_ICON)), tr("Data"), menu);
new QListWidgetItem(QIcon(QPixmap(POI_ICON)), tr("POI"), menu);
new QListWidgetItem(QIcon(QPixmap(PRINT_EXPORT_ICON)), tr("Print & Export"),
menu);
@ -282,10 +355,18 @@ void OptionsDialog::accept()
_options->graphWidth = _graphWidth->value();
_options->graphAntiAliasing = _graphAA->isChecked();
if (_options->units == Imperial)
_options->poiRadius = _poiRadius->value() * MIINM;
else
_options->poiRadius = _poiRadius->value() * KMINM;
_options->elevationFilter = _elevationFilter->value();
_options->speedFilter = _speedFilter->value();
_options->heartRateFilter = _heartRateFilter->value();
_options->cadenceFilter = _cadenceFilter->value();
_options->powerFilter = _powerFilter->value();
_options->outlierEliminate = _outlierEliminate->isChecked();
_options->pauseSpeed = (_options->units == Imperial)
? _pauseSpeed->value() / MS2MIH : _pauseSpeed->value() / MS2KMH;
_options->pauseInterval = _pauseInterval->value();
_options->poiRadius = (_options->units == Imperial)
? _poiRadius->value() * MIINM : _poiRadius->value() * KMINM;
_options->useOpenGL = _useOpenGL->isChecked();
_options->pixmapCache = _pixmapCache->value();

View File

@ -22,6 +22,15 @@ struct Options {
int graphWidth;
bool pathAntiAliasing;
bool graphAntiAliasing;
// Data
int elevationFilter;
int speedFilter;
int heartRateFilter;
int cadenceFilter;
int powerFilter;
bool outlierEliminate;
qreal pauseSpeed;
int pauseInterval;
// POI
int poiRadius;
// System
@ -51,12 +60,14 @@ public slots:
private:
QWidget *createAppearancePage();
QWidget *createDataPage();
QWidget *createPOIPage();
QWidget *createSystemPage();
QWidget *createExportPage();
Options *_options;
// Appearance
ColorBox *_baseColor;
QDoubleSpinBox *_colorOffset;
QSpinBox *_trackWidth;
@ -66,9 +77,21 @@ private:
QCheckBox *_pathAA;
QSpinBox *_graphWidth;
QCheckBox *_graphAA;
// Data
QSpinBox *_elevationFilter;
QSpinBox *_speedFilter;
QSpinBox *_heartRateFilter;
QSpinBox *_cadenceFilter;
QSpinBox *_powerFilter;
QCheckBox *_outlierEliminate;
QDoubleSpinBox *_pauseSpeed;
QSpinBox *_pauseInterval;
// POI
QDoubleSpinBox *_poiRadius;
// System
QSpinBox *_pixmapCache;
QCheckBox *_useOpenGL;
// Print/Export
QCheckBox *_name;
QCheckBox *_date;
QCheckBox *_distance;

View File

@ -2,6 +2,7 @@
#include <QGraphicsScene>
#include <QWheelEvent>
#include <QApplication>
#include <QPixmapCache>
#include "opengl.h"
#include "misc.h"
#include "poi.h"
@ -301,6 +302,7 @@ void PathView::setMap(Map *map)
_mapScale->setResolution(_res);
resetCachedContent();
QPixmapCache::clear();
}
void PathView::setPOI(POI *poi)
@ -542,6 +544,7 @@ void PathView::clear()
resetDigitalZoom();
resetCachedContent();
QPixmapCache::clear();
}
void PathView::showTracks(bool show)

View File

@ -90,12 +90,28 @@
#define PATH_AA_DEFAULT true
#define GRAPH_AA_SETTING "graphAntiAliasing"
#define GRAPH_AA_DEFAULT false
#define ELEVATION_FILTER_SETTING "elevationFilter"
#define ELEVATION_FILTER_DEFAULT 3
#define SPEED_FILTER_SETTING "speedFilter"
#define SPEED_FILTER_DEFAULT 7
#define HEARTRATE_FILTER_SETTING "heartrateFilter"
#define HEARTRATE_FILTER_DEFAULT 3
#define CADENCE_FILTER_SETTING "cadenceFilter"
#define CADENCE_FILTER_DEFAULT 3
#define POWER_FILTER_SETTING "powerFilter"
#define POWER_FILTER_DEFAULT 3
#define OUTLIER_ELIMINATE_SETTING "outlierEliminate"
#define OUTLIER_ELIMINATE_DEFAULT true
#define PAUSE_SPEED_SETTING "pauseSpeed"
#define PAUSE_SPEED_DEFAULT 0.5 /* m/s */
#define PAUSE_INTERVAL_SETTING "pauseInterval"
#define PAUSE_INTERVAL_DEFAULT 10 /* s */
#define POI_RADIUS_SETTING "poiRadius"
#define POI_RADIUS_DEFAULT (IMPERIAL_UNITS() ? MIINM : KMINM)
#define USE_OPENGL_SETTING "useOpenGL"
#define USE_OPENGL_DEFAULT false
#define PIXMAP_CACHE_SETTING "pixmapCache"
#define PIXMAP_CACHE_DEFAULT 64
#define PIXMAP_CACHE_DEFAULT 64 /* MB */
#define PRINT_NAME_SETTING "printName"
#define PRINT_NAME_DEFAULT true
#define PRINT_DATE_SETTING "printDate"

View File

@ -1,16 +1,17 @@
#include "track.h"
#define OUTLIER_WINDOW 31
#define WINDOW_OE 31
int Track::_elevationWindow = 3;
int Track::_speedWindow = 7;
int Track::_heartRateWindow = 3;
int Track::_cadenceWindow = 3;
int Track::_powerWindow = 3;
#define WINDOW_EF 3
#define WINDOW_SF 7
#define WINDOW_HF 3
#define WINDOW_CF 3
#define WINDOW_PF 3
qreal Track::_pauseSpeed = 0.5;
int Track::_pauseInterval = 10;
#define PAUSE_SPEED 0.5
#define PAUSE_TIME_DIFF 10
bool Track::_outlierEliminate = true;
static qreal median(QVector<qreal> v)
@ -104,15 +105,16 @@ 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) {
if (_time.at(i) > _time.at(i-1) + _pauseInterval
&& _speed.at(i) < _pauseSpeed) {
_pause += _time.at(i) - _time.at(i-1);
_stop.insert(i-1);
_stop.insert(i);
}
}
_outliers = eliminate(_speed, WINDOW_OE);
if (_outlierEliminate)
_outliers = eliminate(_speed, OUTLIER_WINDOW);
QSet<int>::const_iterator it;
for (it = _stop.constBegin(); it != _stop.constEnd(); ++it)
@ -137,7 +139,7 @@ Graph Track::elevation() const
raw.append(GraphPoint(_distance.at(i), _time.at(i),
_data.at(i).elevation()));
return filter(raw, WINDOW_EF);
return filter(raw, _elevationWindow);
}
Graph Track::speed() const
@ -161,7 +163,7 @@ Graph Track::speed() const
raw.append(GraphPoint(_distance.at(i), _time.at(i), v));
}
filtered = filter(raw, WINDOW_SF);
filtered = filter(raw, _speedWindow);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)
@ -179,7 +181,7 @@ Graph Track::heartRate() const
raw.append(GraphPoint(_distance.at(i), _time.at(i),
_data.at(i).heartRate()));
return filter(raw, WINDOW_HF);
return filter(raw, _heartRateWindow);
}
Graph Track::temperature() const
@ -212,7 +214,7 @@ Graph Track::cadence() const
raw.append(GraphPoint(_distance.at(i), _time.at(i), c));
}
filtered = filter(raw, WINDOW_CF);
filtered = filter(raw, _cadenceWindow);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)
@ -239,7 +241,7 @@ Graph Track::power() const
raw.append(GraphPoint(_distance.at(i), _time.at(i), p));
}
filtered = filter(raw, WINDOW_PF);
filtered = filter(raw, _powerWindow);
QSet<int>::const_iterator it;
for (it = stop.constBegin(); it != stop.constEnd(); ++it)

View File

@ -33,6 +33,16 @@ public:
bool isNull() const {return (_data.size() < 2);}
static void setElevationFilter(int window) {_elevationWindow = window;}
static void setSpeedFilter(int window) {_speedWindow = window;}
static void setHeartRateFilter(int window) {_heartRateWindow = window;}
static void setCadenceFilter(int window) {_cadenceWindow = window;}
static void setPowerFilter(int window) {_powerWindow = window;}
static void setPauseSpeed(qreal speed) {_pauseSpeed = speed;}
static void setPauseInterval(int interval) {_pauseInterval = interval;}
static void setOutlierElimination(bool eliminate)
{_outlierEliminate = eliminate;}
private:
bool discardStopPoint(int i) const;
@ -46,6 +56,17 @@ private:
QSet<int> _stop;
qreal _pause;
static bool _outlierEliminate;
static int _elevationWindow;
static int _speedWindow;
static int _heartRateWindow;
static int _cadenceWindow;
static int _powerWindow;
static qreal _pauseSpeed;
static int _pauseInterval;
};
#endif // TRACK_H