package tim.prune.function.compress;
import java.awt.Component;
import java.awt.event.ActionListener;
import tim.prune.data.DataPoint;
import tim.prune.data.Track;
/**
* Algorithm for detecting close points to compress
* Only checks distance to previous point, not any earlier point
*/
public class ClosePointsAlgorithm extends SingleParameterAlgorithm
{
/**
* Constructor
* @param inTrack track object
* @param inDetails track details object
* @param inListener listener to attach to activation control
*/
public ClosePointsAlgorithm(Track inTrack, TrackDetails inDetails, ActionListener inListener)
{
super(inTrack, inDetails, inListener);
}
/**
* Perform the compression and work out which points should be deleted
* @param inFlags deletion flags from previous algorithms
* @return number of points deleted
*/
protected int compress(boolean[] inFlags)
{
// Parse parameter
double param = getParameter();
// Use 1/x if x greater than 1
if (param > 1.0) param = 1.0 / param;
if (param <= 0.0 || param >= 1.0) {
// Parameter isn't valid, don't delete any
return 0;
}
double threshold = _trackDetails.getTrackSpan() * param;
// Loop over all points checking distances to previous point
// TODO: Maybe this should also check distance to _next_ point as well!
int numPoints = _track.getNumPoints();
int prevPointIndex = 0;
int prevTrackPointIndex = 0;
double pointDist = 0.0;
int numDeleted = 0;
for (int i=1; i<numPoints; i++)
{
// don't delete points already deleted
if (!inFlags[i])
{
DataPoint currPoint = _track.getPoint(i);
// Don't consider waypoints
if (!currPoint.isWaypoint())
{
// Don't delete any photo points or start/end of segments
if (!currPoint.hasMedia()
&& !_trackDetails.isSegmentStart(i) && !_trackDetails.isSegmentEnd(i))
{
// Check current point against prevPoint
pointDist = Math.abs(_track.getX(i) - _track.getX(prevPointIndex))
+ Math.abs(_track.getY(i) - _track.getY(prevPointIndex));
if (pointDist < threshold) {
inFlags[i] = true;
numDeleted++;
}
else if (prevTrackPointIndex != prevPointIndex)
{
// Check current point against prevTrackPoint
pointDist = Math.abs(_track.getX(i) - _track.getX(prevTrackPointIndex))
+ Math.abs(_track.getY(i) - _track.getY(prevTrackPointIndex));
if (pointDist < threshold) {
inFlags[i] = true;
numDeleted++;
}
}
}
if (!inFlags[i]) {prevTrackPointIndex = i;}
}
if (!inFlags[i]) {prevPointIndex = i;}
}
}
return numDeleted;
}
/**
* @return specific gui components for dialog
*/
protected Component getSpecificGuiComponents()
{
return getSpecificGuiComponents("dialog.compress.closepoints.paramdesc", "200");
}
/**
* @return title key for box
*/
protected String getTitleTextKey()
{
return "dialog.compress.closepoints.title";
}
}