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; } }