package tim.prune.data;
/**
* Class to hold information about the mid-points between
* adjacent track points. Used by the MapCanvas for creating
* points by dragging.
*/
public class MidpointData
{
// track object
private Track _track = null;
// Scaled x, y values
private double[] _xValues = null;
private double[] _yValues = null;
// Validity flags
private boolean[] _valids = null;
// Flag to set data stale
private boolean _needRefresh = true;
/**
* Flag the data as needing to be updated
* @param inTrack track object from which to get the data
*/
public void updateData(Track inTrack)
{
_track = inTrack;
_needRefresh = true;
}
/**
* Update the arrays of data from the track
*/
private synchronized void updateData()
{
_needRefresh = false;
if (_track == null) return;
// Make arrays the right size
final int numPoints = _track.getNumPoints();
if (_xValues == null || _xValues.length != numPoints)
{
_xValues = new double[numPoints];
_yValues = new double[numPoints];
_valids = new boolean[numPoints];
}
if (numPoints <= 0) return;
_valids[0] = false;
// Loop over the points in the track
for (int i=1; i<numPoints; i++)
{
boolean pointValid = false;
DataPoint point = _track.getPoint(i);
if (point != null && !point.getSegmentStart() && !point.isWaypoint())
{
_xValues[i] = (_track.getX(i) + _track.getX(i-1)) / 2.0;
_yValues[i] = (_track.getY(i) + _track.getY(i-1)) / 2.0;
pointValid = true;
}
_valids[i] = pointValid;
}
}
/**
* Find the nearest point to the specified x and y coordinates
* or -1 if no point is within the specified max distance
* @param inX x coordinate
* @param inY y coordinate
* @param inMaxDist maximum distance from selected coordinates
* @return index of nearest point or -1 if not found
*/
public int getNearestPointIndex(double inX, double inY, double inMaxDist)
{
if (_track == null) return -1;
if (_needRefresh) updateData();
final int numPoints = _track.getNumPoints();
int nearestPoint = 0;
double nearestDist = -1.0;
double currDist;
for (int i=1; i < numPoints; i++)
{
if (_valids[i])
{
currDist = Math.abs(_xValues[i] - inX) + Math.abs(_yValues[i] - inY);
if (currDist < nearestDist || nearestDist < 0.0)
{
nearestPoint = i;
nearestDist = currDist;
}
}
}
// Check whether it's within required distance
if (nearestDist > inMaxDist && inMaxDist > 0.0) {
return -1;
}
return nearestPoint;
}
}