X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Ffunction%2FCreateMarkerWaypointsFunction.java;fp=src%2Ftim%2Fprune%2Ffunction%2FCreateMarkerWaypointsFunction.java;h=92b4ce56c497b6dbd33924d43f2984cea20ae3a7;hp=f3dd1f1d9bca2eba8f78f42a3a136294363543e9;hb=8b20e3e027058cdf6ff52993ee5576193d08667a;hpb=2302358503c38817e19f6e529f6c9e530aac0e86 diff --git a/src/tim/prune/function/CreateMarkerWaypointsFunction.java b/src/tim/prune/function/CreateMarkerWaypointsFunction.java index f3dd1f1..92b4ce5 100644 --- a/src/tim/prune/function/CreateMarkerWaypointsFunction.java +++ b/src/tim/prune/function/CreateMarkerWaypointsFunction.java @@ -8,12 +8,14 @@ import tim.prune.UpdateMessageBroker; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.FieldList; +import tim.prune.data.RangeStats; import tim.prune.data.Track; +import tim.prune.data.UnitSetLibrary; import tim.prune.undo.UndoAppendPoints; /** - * Function to create waypoints marking either - * at regular distance intervals or time intervals + * Function to create waypoints marking regular distance intervals, + * regular time intervals, or halfway points */ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction { @@ -22,12 +24,21 @@ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction /** Counter of previously used multiple */ private int _previousMultiple = 0; + /* + * Type of halfway point + */ + private enum HalfwayType + { + HALF_DISTANCE, + HALF_CLIMB, + HALF_DESCENT + } /** * Constructor */ public CreateMarkerWaypointsFunction(App inApp) { - super(inApp); + super(inApp, true); } /** @@ -51,55 +62,34 @@ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction */ protected void performFunction() { - // Distribute either by distance or time + // Determine which kind of markers to create final int timeLimitSeconds = getTimeLimitInSeconds(); final boolean createByTime = (timeLimitSeconds > 0); - final double distLimitRadians = getDistanceLimitRadians(); - final boolean createByDistance = (distLimitRadians > 0.0); - if (!createByTime && !createByDistance) { - return; // neither option selected - } - - // Make undo object - final int numPoints = _app.getTrackInfo().getTrack().getNumPoints(); - UndoAppendPoints undo = new UndoAppendPoints(numPoints); + final double distLimitKm = getDistanceLimitKilometres(); + final boolean createByDistance = (distLimitKm > 0.0); + final boolean createHalves = isHalvesSelected(); // set up the memory from scratch to collect the created points initMemory(); - // Make new waypoints, looping through the points in the track - DataPoint currPoint = null, prevPoint = null; - double currValue = 0.0, prevValue = 0.0; - for (int i=0; i 0); + final boolean createByDistance = (inDistLimitKm > 0.0); + + // Make new waypoints, looping through the points in the track + DataPoint currPoint = null, prevPoint = null; + double currValue = 0.0, prevValue = 0.0; + RangeStats rangeStats = new RangeStats(); + final int numPoints = _app.getTrackInfo().getTrack().getNumPoints(); + for (int i=0; i 0.0) + { + final double currDist = partialStats.getMovingDistanceKilometres(); + createdDistance = processHalfValue(prevPoint, prevDistance, halfDistance, + currPoint, currDist, HalfwayType.HALF_DISTANCE); + prevDistance = currDist; + } + // climb + if (!createdClimb && totalClimb > 0.0) + { + final double currClimb = partialStats.getMovingAltitudeRange().getClimb(UnitSetLibrary.UNITS_METRES); + createdClimb = processHalfValue(prevPoint, prevClimb, halfClimb, + currPoint, currClimb, HalfwayType.HALF_CLIMB); + prevClimb = currClimb; + } + // descent + if (!createdDescent && totalDescent > 0.0) + { + final double currDescent = partialStats.getMovingAltitudeRange().getDescent(UnitSetLibrary.UNITS_METRES); + createdDescent = processHalfValue(prevPoint, prevDescent, halfDescent, + currPoint, currDescent, HalfwayType.HALF_DESCENT); + prevDescent = currDescent; + } + + prevPoint = currPoint; + } + } + } + + /** + * Consider a pair of points in the track to see if a new halfway marker should be inserted between them + * @param inPrevPoint previous point + * @param inPrevValue value of function at this previous point + * @param inTargetValue target halfway value + * @param inCurrPoint current point + * @param inCurrValue value of function at this current point + * @param inType type of halfway point + */ + private boolean processHalfValue(DataPoint inPrevPoint, double inPrevValue, double inTargetValue, + DataPoint inCurrPoint, double inCurrValue, HalfwayType inType) + { + if (inPrevValue <= inTargetValue && inCurrValue >= inTargetValue) + { + // Calculate position of limit between the two points + final double valueBeforeBreak = inTargetValue - inPrevValue; + final double valueAfterBreak = inCurrValue - inTargetValue; + final double fractionFromPrev = valueBeforeBreak / (valueBeforeBreak + valueAfterBreak); + DataPoint marker = DataPoint.interpolate(inPrevPoint, inCurrPoint, fractionFromPrev); + marker.setFieldValue(Field.WAYPT_NAME, createHalfwayName(inType), false); + _pointsToAdd.add(marker); + return true; + } + return false; + } + + /** + * Create the name of the halfway point according to type + * @param inType type of point + */ + private String createHalfwayName(HalfwayType inType) + { + String typeString = null; + switch (inType) + { + case HALF_DISTANCE: + typeString = "distance"; + break; + case HALF_CLIMB: + typeString = "climb"; + break; + case HALF_DESCENT: + typeString = "descent"; + break; + } + if (typeString != null) + { + return I18nManager.getText("dialog.markers.half." + typeString); + } + return "half"; + } }