]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/data/MidpointData.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / data / MidpointData.java
diff --git a/src/tim/prune/data/MidpointData.java b/src/tim/prune/data/MidpointData.java
new file mode 100644 (file)
index 0000000..3fdebb2
--- /dev/null
@@ -0,0 +1,98 @@
+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;
+       }
+}