+++ /dev/null
-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<numPoints; i++)
- {
- DataPoint currPoint = track.getPoint(i);
- if (currPoint != null && !currPoint.isWaypoint() && currPoint.hasAltitude() && currPoint.hasTimestamp())
- {
- int n = i+1;
- DataPoint endPoint = track.getPoint(n);
- while (endPoint != null && endPoint.hasAltitude() && endPoint.hasTimestamp() &&
- !endPoint.isWaypoint() && endPoint.getTimestamp().getSecondsSince(currPoint.getTimestamp()) < 120)
- {
- n++;
- endPoint = track.getPoint(n);
- }
- if (endPoint != null && endPoint.hasAltitude() && endPoint.hasTimestamp() && !endPoint.isWaypoint()
- && n > (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<numPoints; i++)
- {
- DataPoint point = track.getPoint(i);
- if (!point.isWaypoint()) point.setMarkedForDeletion(markFlags[i]);
- if (markFlags[i]) numMarked++;
- }
- // Inform subscribers to update display
- UpdateMessageBroker.informSubscribers();
- // Confirm message showing how many marked
- if (numMarked > 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;
- }
-}