]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/data/RangeStatsWithGradients.java
Version 20, March 2020
[GpsPrune.git] / src / tim / prune / data / RangeStatsWithGradients.java
diff --git a/src/tim/prune/data/RangeStatsWithGradients.java b/src/tim/prune/data/RangeStatsWithGradients.java
new file mode 100644 (file)
index 0000000..c495c51
--- /dev/null
@@ -0,0 +1,106 @@
+package tim.prune.data;
+
+/**
+ * Class to do additional range calculations including gradients
+ * Used by full details display as well as the EstimateTime functions.
+ */
+public class RangeStatsWithGradients extends RangeStats
+{
+       private AltitudeRange _gentleAltitudeRange = new AltitudeRange();
+       private AltitudeRange _steepAltitudeRange = new AltitudeRange();
+       private Altitude _prevAltitude = null;
+       private double _radsSinceLastAltitude = 0.0;
+
+       private static final double STEEP_ANGLE = 0.15; // gradient steeper than 15% counts as steep
+
+
+       /**
+        * Default constructor
+        */
+       public RangeStatsWithGradients()
+       {
+               super();
+       }
+
+       /**
+        * Constructor
+        * @param inTrack track object
+        * @param inStartIndex start index
+        * @param inEndIndex end index
+        */
+       public RangeStatsWithGradients(Track inTrack, int inStartIndex, int inEndIndex)
+       {
+               super();
+               populateFromTrack(inTrack, inStartIndex, inEndIndex);
+       }
+
+       /**
+        * Add the given point to the calculations
+        * @param inPoint incoming point
+        */
+       protected void doFurtherCalculations(DataPoint inPoint)
+       {
+               if (_prevPoint != null)
+               {
+                       // Keep track of rads since last point with an altitude
+                       double rads = DataPoint.calculateRadiansBetween(_prevPoint, inPoint);
+                       _radsSinceLastAltitude += rads;
+               }
+
+               if (inPoint.hasAltitude())
+               {
+                       Altitude altitude = inPoint.getAltitude();
+
+                       if (!inPoint.getSegmentStart() && _prevAltitude != null)
+                       {
+                               // Work out gradient, see whether to ignore/add to gentle or steep
+                               double heightDiff = altitude.getMetricValue() - _prevAltitude.getMetricValue();
+                               double metricDist = Distance.convertRadiansToDistance(_radsSinceLastAltitude, UnitSetLibrary.UNITS_METRES);
+                               final boolean isSteep = metricDist < 0.001 || (Math.abs(heightDiff / metricDist) > STEEP_ANGLE);
+                               if (isSteep)
+                               {
+                                       _steepAltitudeRange.ignoreValue(_prevAltitude);
+                                       _steepAltitudeRange.addValue(altitude);
+                               }
+                               else
+                               {
+                                       _gentleAltitudeRange.ignoreValue(_prevAltitude);
+                                       _gentleAltitudeRange.addValue(altitude);
+                               }
+                       }
+                       _prevAltitude = altitude;
+                       _radsSinceLastAltitude = 0.0;
+               }
+
+       }
+
+       /** @return altitude range of range just considering low gradient bits */
+       public AltitudeRange getGentleAltitudeRange() {
+               return _gentleAltitudeRange;
+       }
+
+       /** @return altitude range of range just considering high gradient bits */
+       public AltitudeRange getSteepAltitudeRange() {
+               return _steepAltitudeRange;
+       }
+
+       /** @return the total gradient in % (including segment gaps) */
+       public double getTotalGradient()
+       {
+               double dist = Distance.convertRadiansToDistance(_totalDistanceRads, UnitSetLibrary.UNITS_METRES);
+               if (dist > 0.0 && _totalAltitudeRange.hasRange()) {
+                       return _totalAltitudeRange.getMetricHeightDiff() / dist * 100.0;
+               }
+               return 0.0;
+       }
+
+       /** @return the moving gradient in % (ignoring segment gaps) */
+       public double getMovingGradient()
+       {
+               double dist = Distance.convertRadiansToDistance(_movingDistanceRads, UnitSetLibrary.UNITS_METRES);
+               if (dist > 0.0 && _movingAltitudeRange.hasRange()) {
+                       return _movingAltitudeRange.getMetricHeightDiff() / dist * 100.0;
+               }
+               return 0.0;
+       }
+}