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;
}
}
|