File: RangeStatsWithGradients.java

package info (click to toggle)
gpsprune 26.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,824 kB
  • sloc: java: 52,154; sh: 25; makefile: 21; python: 15
file content (110 lines) | stat: -rw-r--r-- 3,405 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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 final AltitudeRange _gentleAltitudeRange;
	private final AltitudeRange _steepAltitudeRange;
	private Altitude _prevAltitude = null;
	private double _radsSinceLastAltitude = 0.0;

	private static final double STEEP_ANGLE = 0.15; // gradient steeper than 15% counts as steep


	/**
	 * Constructor
	 * @param inAltitudeTolerance altitude tolerance in metres
	 */
	public RangeStatsWithGradients(int inAltitudeTolerance)
	{
		super(inAltitudeTolerance);
		_gentleAltitudeRange = new AltitudeRange(inAltitudeTolerance);
		_steepAltitudeRange = new AltitudeRange(inAltitudeTolerance);
	}

	/**
	 * Constructor
	 * @param inTrack track object
	 * @param inStartIndex start index
	 * @param inEndIndex end index
	 * @param inAltitudeTolerance altitude tolerance in metres
	 */
	public RangeStatsWithGradients(Track inTrack, int inStartIndex, int inEndIndex, int inAltitudeTolerance)
	{
		this(inAltitudeTolerance);
		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;
	}
}