X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fdata%2FRangeStatsWithGradients.java;fp=src%2Ftim%2Fprune%2Fdata%2FRangeStatsWithGradients.java;h=c495c51a563ccddef72033c2b98f592b4f212df8;hp=0000000000000000000000000000000000000000;hb=8b20e3e027058cdf6ff52993ee5576193d08667a;hpb=2302358503c38817e19f6e529f6c9e530aac0e86 diff --git a/src/tim/prune/data/RangeStatsWithGradients.java b/src/tim/prune/data/RangeStatsWithGradients.java new file mode 100644 index 0000000..c495c51 --- /dev/null +++ b/src/tim/prune/data/RangeStatsWithGradients.java @@ -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; + } +}