package tim.prune.function.compress; import tim.prune.App; import tim.prune.UpdateMessageBroker; import tim.prune.data.DataPoint; import tim.prune.data.Distance; import tim.prune.data.RangeStats; import tim.prune.data.Track; import tim.prune.data.UnitSetLibrary; /** * Function to mark all the points going uphill on ski lifts */ public class MarkLiftsFunction extends MarkAndDeleteFunction { /** * Constructor * @param inApp App object */ public MarkLiftsFunction(App inApp) { super(inApp); } /** @return name key */ public String getNameKey() { return "function.marklifts"; } /** this function _does_ require split at deleted points */ protected boolean getShouldSplitSegments() { return true; } /** * Begin the function using the set parameters */ public void begin() { // TODO: Might need to do this in a separate thread, it might take a while if the track is big // Loop over all points in track int numMarked = 0; final Track track = _app.getTrackInfo().getTrack(); final int numPoints = track.getNumPoints(); boolean[] markFlags = new boolean[numPoints]; int previousStartIndex = -1; for (int i=0; i (i+10)) { // Found a 2 minute range to test with at least 12 points if (looksLikeLiftRange(track, i, n)) { // Passes tests, so we want to mark all points between i and n int startIndex = i; // First check if we can merge with the previous marked range if (previousStartIndex >= 0 && (looksLikeLiftRange(track, previousStartIndex, i) || looksLikeLiftRange(track, previousStartIndex, n))) { startIndex = previousStartIndex; // merge } for (int j=startIndex; j<=n; j++) { markFlags[j] = true; } // Remember start point for next one previousStartIndex = startIndex; // skip forward half the range, don't need to test the same points again i = (i+n)/2; } } } } // Copy mark flags to points for (int i=0; i 0) { optionallyDeleteMarkedPoints(numMarked); } else { // TODO: Show message that no lifts were found } } /** * Check whether the specified range looks like an uphill lift section or not * Must go at most a little bit downhill, much more uphill than down, and straight * (speed isn't checked yet, but maybe could be?) * @param inTrack track * @param inStartIndex start index of range * @param inEndIndex end index of range * @return true if it looks like a lift */ private boolean looksLikeLiftRange(Track inTrack, int inStartIndex, int inEndIndex) { RangeStats stats = new RangeStats(inTrack, inStartIndex, inEndIndex); int descent = stats.getTotalAltitudeRange().getDescent(UnitSetLibrary.UNITS_METRES); if (descent < 20) { int ascent = stats.getTotalAltitudeRange().getClimb(UnitSetLibrary.UNITS_METRES); if (ascent > (descent * 10)) { // Now check distance and compare to distance between start and end final DataPoint startPoint = inTrack.getPoint(inStartIndex); final DataPoint endPoint = inTrack.getPoint(inEndIndex); final double trackDist = stats.getTotalDistance(); final double endToEndDist = Distance.convertRadiansToDistance( DataPoint.calculateRadiansBetween(startPoint, endPoint)); if ((trackDist / endToEndDist) < 1.02) // Straight(ish) line { return true; } //else System.out.println("Not straight enough: " + (trackDist / endToEndDist)); } } return false; } }