X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Ffunction%2Fcompress%2FMarkLiftsFunction.java;fp=tim%2Fprune%2Ffunction%2Fcompress%2FMarkLiftsFunction.java;h=5e3986621c73e46083373b6d30ed806d277faa21;hp=0000000000000000000000000000000000000000;hb=0a2480df5845e2d7190dfdec9b2653b1609e853d;hpb=2154b1969ac2995cca46546f217f53c066b0b749 diff --git a/tim/prune/function/compress/MarkLiftsFunction.java b/tim/prune/function/compress/MarkLiftsFunction.java new file mode 100644 index 0000000..5e39866 --- /dev/null +++ b/tim/prune/function/compress/MarkLiftsFunction.java @@ -0,0 +1,143 @@ +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; + } +}