]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/data/RangeStatsWithGradients.java
Version 20.4, May 2021
[GpsPrune.git] / src / tim / prune / data / RangeStatsWithGradients.java
1 package tim.prune.data;
2
3 /**
4  * Class to do additional range calculations including gradients
5  * Used by full details display as well as the EstimateTime functions.
6  */
7 public class RangeStatsWithGradients extends RangeStats
8 {
9         private AltitudeRange _gentleAltitudeRange = new AltitudeRange();
10         private AltitudeRange _steepAltitudeRange = new AltitudeRange();
11         private Altitude _prevAltitude = null;
12         private double _radsSinceLastAltitude = 0.0;
13
14         private static final double STEEP_ANGLE = 0.15; // gradient steeper than 15% counts as steep
15
16
17         /**
18          * Default constructor
19          */
20         public RangeStatsWithGradients()
21         {
22                 super();
23         }
24
25         /**
26          * Constructor
27          * @param inTrack track object
28          * @param inStartIndex start index
29          * @param inEndIndex end index
30          */
31         public RangeStatsWithGradients(Track inTrack, int inStartIndex, int inEndIndex)
32         {
33                 super();
34                 populateFromTrack(inTrack, inStartIndex, inEndIndex);
35         }
36
37         /**
38          * Add the given point to the calculations
39          * @param inPoint incoming point
40          */
41         protected void doFurtherCalculations(DataPoint inPoint)
42         {
43                 if (_prevPoint != null)
44                 {
45                         // Keep track of rads since last point with an altitude
46                         double rads = DataPoint.calculateRadiansBetween(_prevPoint, inPoint);
47                         _radsSinceLastAltitude += rads;
48                 }
49
50                 if (inPoint.hasAltitude())
51                 {
52                         Altitude altitude = inPoint.getAltitude();
53
54                         if (!inPoint.getSegmentStart() && _prevAltitude != null)
55                         {
56                                 // Work out gradient, see whether to ignore/add to gentle or steep
57                                 double heightDiff = altitude.getMetricValue() - _prevAltitude.getMetricValue();
58                                 double metricDist = Distance.convertRadiansToDistance(_radsSinceLastAltitude, UnitSetLibrary.UNITS_METRES);
59                                 final boolean isSteep = metricDist < 0.001 || (Math.abs(heightDiff / metricDist) > STEEP_ANGLE);
60                                 if (isSteep)
61                                 {
62                                         _steepAltitudeRange.ignoreValue(_prevAltitude);
63                                         _steepAltitudeRange.addValue(altitude);
64                                 }
65                                 else
66                                 {
67                                         _gentleAltitudeRange.ignoreValue(_prevAltitude);
68                                         _gentleAltitudeRange.addValue(altitude);
69                                 }
70                         }
71                         _prevAltitude = altitude;
72                         _radsSinceLastAltitude = 0.0;
73                 }
74
75         }
76
77         /** @return altitude range of range just considering low gradient bits */
78         public AltitudeRange getGentleAltitudeRange() {
79                 return _gentleAltitudeRange;
80         }
81
82         /** @return altitude range of range just considering high gradient bits */
83         public AltitudeRange getSteepAltitudeRange() {
84                 return _steepAltitudeRange;
85         }
86
87         /** @return the total gradient in % (including segment gaps) */
88         public double getTotalGradient()
89         {
90                 double dist = Distance.convertRadiansToDistance(_totalDistanceRads, UnitSetLibrary.UNITS_METRES);
91                 if (dist > 0.0 && _totalAltitudeRange.hasRange()) {
92                         return _totalAltitudeRange.getMetricHeightDiff() / dist * 100.0;
93                 }
94                 return 0.0;
95         }
96
97         /** @return the moving gradient in % (ignoring segment gaps) */
98         public double getMovingGradient()
99         {
100                 double dist = Distance.convertRadiansToDistance(_movingDistanceRads, UnitSetLibrary.UNITS_METRES);
101                 if (dist > 0.0 && _movingAltitudeRange.hasRange()) {
102                         return _movingAltitudeRange.getMetricHeightDiff() / dist * 100.0;
103                 }
104                 return 0.0;
105         }
106 }