From 4348a6279cba8587e363f1bf3cf9be2dfee2fe9b Mon Sep 17 00:00:00 2001 From: ericchristoffersen <46055145+ericchristoffersen@users.noreply.github.com> Date: Mon, 25 May 2020 15:03:26 -0700 Subject: [PATCH] Issue 3373: FixGps to run on altitude alone. (#3374) Fixes #3373 --- src/FileIO/FixGPS.cpp | 100 +++++++++++++---------- src/FileIO/GeometricTools_BSplineCurve.h | 4 +- 2 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/FileIO/FixGPS.cpp b/src/FileIO/FixGPS.cpp index 52433d7e9..6a2f944d1 100644 --- a/src/FileIO/FixGPS.cpp +++ b/src/FileIO/FixGPS.cpp @@ -113,7 +113,7 @@ class FixGPSConfig : public DataProcessorConfig // Altitude Outlier Criteria QLabel *outlierLabel; - QSpinBox *outlierSpinBox; + QDoubleSpinBox *outlierSpinBox; // Altitude Stats QLabel *minSlopeLabel; @@ -132,7 +132,7 @@ class FixGPSConfig : public DataProcessorConfig // Route Outlier Criteria QLabel *outlierLabelRoute; - QSpinBox *outlierSpinBoxRoute; + QDoubleSpinBox *outlierSpinBoxRoute; // Route Stats QLabel *variance0LabelRoute; @@ -367,9 +367,10 @@ class FixGPSConfig : public DataProcessorConfig // Altitude Outlier Criteria outlierLabel = new QLabel(fUseShortDescription ? tr("Crit") : tr("Altitude Outlier criteria %:")); - outlierSpinBox = new QSpinBox(); - outlierSpinBox->setRange(1, 10000); + outlierSpinBox = new QDoubleSpinBox(); + outlierSpinBox->setRange(0.001, 10000); outlierSpinBox->setSingleStep(10); + outlierSpinBox->setDecimals(3); outlierSpinBox->setValue(appsettings->value(this, GC_FIXGPS_ALTITUDE_OUTLIER_PERCENT, s_Default_AltitudeOutlierPercent).toInt()); outlierSpinBox->setToolTip(tr("ALTITUDE OUTLIER CRITERIA (%)\n" "Outlier percent is used to decide outlier points that will be discarded after\n" @@ -413,9 +414,10 @@ class FixGPSConfig : public DataProcessorConfig "used for the second pass spline made after outliers are removed.\n")); outlierLabelRoute = new QLabel(fUseShortDescription ? tr("Crit") : tr("Route Outlier criteria %:")); - outlierSpinBoxRoute = new QSpinBox(); - outlierSpinBoxRoute->setRange(1, 10000); + outlierSpinBoxRoute = new QDoubleSpinBox(); + outlierSpinBoxRoute->setRange(0.001, 10000); outlierSpinBoxRoute->setSingleStep(10); + outlierSpinBoxRoute->setDecimals(3); outlierSpinBoxRoute->setValue(appsettings->value(this, GC_FIXGPS_ROUTE_OUTLIER_PERCENT, s_Default_RouteOutlierPercent).toInt()); outlierSpinBoxRoute->setToolTip(tr("ROUTE OUTLIER CRITERIA (%)" "Outlier percent is used to decide outlier points that will be discarded after\n" @@ -1096,55 +1098,61 @@ bool FixGPS::postProcess(RideFile *ride, DataProcessorConfig *config, QString op Q_UNUSED(config) Q_UNUSED(op) - // ignore null or files without GPS data - if (!ride || ride->areDataPresent()->lat == false || ride->areDataPresent()->lon == false) - return false; + if (!ride) return false; - // Interpolate altitude if its available. bool fHasAlt = ride->areDataPresent()->alt; + bool fHasLoc = ride->areDataPresent()->lat && ride->areDataPresent()->lon; + + // We can operate on alt and/or loc, but cannot operate if there are neither. + if (!fHasAlt && !fHasLoc) + return false; int errors=0; ride->command->startLUW("Fix GPS Errors"); - GeoPointInterpolator gpi; - int ii = 0; // interpolation input index + // Default behavior: Interpolate missing points. + if (fHasLoc) { - for (int i=0; idataPoints().count(); i++) { - const RideFilePoint * pi = (ride->dataPoints()[i]); - geolocation curLoc(pi->lat, pi->lon, fHasAlt ? pi->alt : 0.0); + GeoPointInterpolator gpi; + int ii = 0; // interpolation input index - // Activate interpolation if this sample isn't reasonable. - if (!IsReasonableGeoLocation(&curLoc)) { - double km = pi->km; + for (int i = 0; i < ride->dataPoints().count(); i++) { + const RideFilePoint* pi = (ride->dataPoints()[i]); + geolocation curLoc(pi->lat, pi->lon, fHasAlt ? pi->alt : 0.0); - // Feed interpolator until it has samples that span current distance. - while (gpi.WantsInput(km)) { - if (ii < ride->dataPoints().count()) { - const RideFilePoint * pii = (ride->dataPoints()[ii]); - geolocation geo(pii->lat, pii->lon, fHasAlt ? pii->alt : 0.0); + // Activate interpolation if this sample isn't reasonable. + if (!IsReasonableGeoLocation(&curLoc)) { + double km = pi->km; - // Only feed reasonable locations to interpolator - if (IsReasonableGeoLocation(&geo)) { - gpi.Push(pii->km, geo); + // Feed interpolator until it has samples that span current distance. + while (gpi.WantsInput(km)) { + if (ii < ride->dataPoints().count()) { + const RideFilePoint* pii = (ride->dataPoints()[ii]); + geolocation geo(pii->lat, pii->lon, fHasAlt ? pii->alt : 0.0); + + // Only feed reasonable locations to interpolator + if (IsReasonableGeoLocation(&geo)) { + gpi.Push(pii->km, geo); + } + ii++; + } else { + gpi.NotifyInputComplete(); + break; } - ii++; - } else { - gpi.NotifyInputComplete(); - break; } + + geolocation interpLoc = gpi.Location(km); + + ride->command->setPointValue(i, RideFile::lat, interpLoc.Lat()); + ride->command->setPointValue(i, RideFile::lon, interpLoc.Long()); + + if (fHasAlt) { + ride->command->setPointValue(i, RideFile::alt, interpLoc.Alt()); + } + + errors++; } - - geolocation interpLoc = gpi.Location(km); - - ride->command->setPointValue(i, RideFile::lat, interpLoc.Lat()); - ride->command->setPointValue(i, RideFile::lon, interpLoc.Long()); - - if (fHasAlt) { - ride->command->setPointValue(i, RideFile::alt, interpLoc.Alt()); - } - - errors++; } } @@ -1177,6 +1185,16 @@ bool FixGPS::postProcess(RideFile *ride, DataProcessorConfig *config, QString op outlierCriteriaRoute = appsettings->value(NULL, GC_FIXGPS_ROUTE_OUTLIER_PERCENT, 100).toInt(); } + // If no alt then dont try to smooth it. + if (!fHasAlt) { + fDoSmoothAltitude = false; + } + + // If no loc then dont try to smooth it. + if (!fHasLoc) { + fDoSmoothRoute = false; + } + std::vector> inControls2, outControls2; if (fDoSmoothAltitude) { ride->command->startLUW("Smooth Altitude"); diff --git a/src/FileIO/GeometricTools_BSplineCurve.h b/src/FileIO/GeometricTools_BSplineCurve.h index 0125cbf8e..21fa83d82 100644 --- a/src/FileIO/GeometricTools_BSplineCurve.h +++ b/src/FileIO/GeometricTools_BSplineCurve.h @@ -2,8 +2,8 @@ // BSplineCurve.h from Geometric Tools along with all the GTC headers // it requires. -#define LogError(a) (a); return 0; -#define LogAssert(a,b) (a) +#define LogError(a) (0); return 0; +#define LogAssert(a,b) (0) // ----------------------------------------------------------------------- // Mathematics/Math.h