]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/data/Selection.java
Version 14, October 2012
[GpsPrune.git] / tim / prune / data / Selection.java
index cdbe58ecca33035a7a012d5ee5e3be402e422ccc..f5c41ffd91f6015d8d4762e546fe8385c5dadc8e 100644 (file)
@@ -12,13 +12,14 @@ public class Selection
        private Track _track = null;
        private int _currentPoint = -1;
        private boolean _valid = false;
+       private int _prevNumPoints = 0;
        private int _startIndex = -1, _endIndex = -1;
        private int _currentPhotoIndex = -1;
-       private IntegerRange _altitudeRange = null;
-       private int _climb = -1, _descent = -1;
-       private int _altitudeFormat = Altitude.FORMAT_NONE;
-       private long _seconds = 0L;
-       private double _angDistance = -1.0; //, _averageSpeed = -1.0;
+       private int _currentAudioIndex = -1;
+       private AltitudeRange _altitudeRange = null;
+       private long _totalSeconds = 0L, _movingSeconds = 0L;
+       private double _angDistance = -1.0, _angMovingDistance = -1.0;
+       private int _numSegments = 0;
 
 
        /**
@@ -32,60 +33,14 @@ public class Selection
 
 
        /**
-        * Reset selection to be recalculated
+        * Mark selection invalid so it will be recalculated
         */
-       private void reset()
+       public void markInvalid()
        {
                _valid = false;
        }
 
 
-       /**
-        * Select the point at the given index
-        * @param inIndex index number of selected point
-        */
-       public void selectPoint(int inIndex)
-       {
-               if (inIndex >= -1)
-               {
-                       _currentPoint = inIndex;
-                       check();
-               }
-       }
-
-       /**
-        * Select the specified point and range in one go
-        * @param inPointIndex point selection
-        * @param inStart range start
-        * @param inEnd range end
-        */
-       public void select(int inPointIndex, int inStart, int inEnd)
-       {
-               _currentPoint = inPointIndex;
-               _startIndex = inStart;
-               _endIndex = inEnd;
-               reset();
-               check();
-       }
-
-
-       /**
-        * Select the previous point
-        */
-       public void selectPreviousPoint()
-       {
-               if (_currentPoint > 0)
-                       selectPoint(_currentPoint - 1);
-       }
-
-       /**
-        * Select the next point
-        */
-       public void selectNextPoint()
-       {
-               selectPoint(_currentPoint + 1);
-       }
-
        /**
         * @return the current point index
         */
@@ -109,19 +64,23 @@ public class Selection
         */
        private void recalculate()
        {
-               _altitudeFormat = Altitude.FORMAT_NONE;
-               if (_track.getNumPoints() > 0 && hasRangeSelected())
+               _numSegments = 0;
+               final int numPoints = _track.getNumPoints();
+               // Recheck if the number of points has changed
+               if (numPoints != _prevNumPoints) {
+                       _prevNumPoints = numPoints;
+                       check();
+               }
+               if (numPoints > 0 && hasRangeSelected())
                {
-                       _altitudeRange = new IntegerRange();
-                       _climb = 0;
-                       _descent = 0;
+                       _altitudeRange = new AltitudeRange();
                        Altitude altitude = null;
                        Timestamp time = null, startTime = null, endTime = null;
+                       Timestamp previousTime = null;
                        DataPoint lastPoint = null, currPoint = null;
-                       _angDistance = 0.0;
-                       int altValue = 0;
-                       int lastAltValue = 0;
-                       boolean foundAlt = false;
+                       _angDistance = 0.0; _angMovingDistance = 0.0;
+                       _totalSeconds = 0L; _movingSeconds = 0L;
+                       // Loop over points in selection
                        for (int i=_startIndex; i<=_endIndex; i++)
                        {
                                currPoint = _track.getPoint(i);
@@ -129,44 +88,41 @@ public class Selection
                                // Ignore waypoints in altitude calculations
                                if (!currPoint.isWaypoint() && altitude.isValid())
                                {
-                                       altValue = altitude.getValue(_altitudeFormat);
-                                       if (_altitudeFormat == Altitude.FORMAT_NONE)
-                                               _altitudeFormat = altitude.getFormat();
-                                       _altitudeRange.addValue(altValue);
-                                       if (foundAlt)
-                                       {
-                                               if (altValue > lastAltValue)
-                                                       _climb += (altValue - lastAltValue);
-                                               else
-                                                       _descent += (lastAltValue - altValue);
-                                       }
-                                       lastAltValue = altValue;
-                                       foundAlt = true;
+                                       _altitudeRange.addValue(altitude);
                                }
                                // Store the first and last timestamp in the range
                                time = currPoint.getTimestamp();
                                if (time.isValid())
                                {
-                                       if (startTime == null) startTime = time;
-                                       endTime = time;
+                                       if (startTime == null || startTime.isAfter(time)) startTime = time;
+                                       if (endTime == null || time.isAfter(endTime)) endTime = time;
+                                       // add moving time
+                                       if (!currPoint.getSegmentStart() && previousTime != null && time.isAfter(previousTime)) {
+                                               _movingSeconds += time.getSecondsSince(previousTime);
+                                       }
+                                       previousTime = time;
                                }
                                // Calculate distances, again ignoring waypoints
                                if (!currPoint.isWaypoint())
                                {
                                        if (lastPoint != null)
                                        {
-                                               _angDistance += DataPoint.calculateRadiansBetween(lastPoint, currPoint);
+                                               double radians = DataPoint.calculateRadiansBetween(lastPoint, currPoint);
+                                               _angDistance += radians;
+                                               if (currPoint.getSegmentStart()) {
+                                                       _numSegments++;
+                                               }
+                                               else {
+                                                       _angMovingDistance += radians;
+                                               }
                                        }
                                        lastPoint = currPoint;
+                                       // If it's a track point then there must be at least one segment
+                                       if (_numSegments == 0) {_numSegments = 1;}
                                }
                        }
-                       if (endTime != null)
-                       {
-                               _seconds = endTime.getSecondsSince(startTime);
-                       }
-                       else
-                       {
-                               _seconds = 0L;
+                       if (endTime != null) {
+                               _totalSeconds = endTime.getSecondsSince(startTime);
                        }
                }
                _valid = true;
@@ -192,19 +148,10 @@ public class Selection
                return _endIndex;
        }
 
-
-       /**
-        * @return the altitude format, ie feet or metres
-        */
-       public int getAltitudeFormat()
-       {
-               return _altitudeFormat;
-       }
-
        /**
         * @return altitude range
         */
-       public IntegerRange getAltitudeRange()
+       public AltitudeRange getAltitudeRange()
        {
                if (!_valid) recalculate();
                return _altitudeRange;
@@ -212,62 +159,70 @@ public class Selection
 
 
        /**
-        * @return climb
+        * @return number of seconds spanned by selection
         */
-       public int getClimb()
+       public long getNumSeconds()
        {
                if (!_valid) recalculate();
-               return _climb;
+               return _totalSeconds;
        }
 
        /**
-        * @return descent
+        * @return number of seconds spanned by segments within selection
         */
-       public int getDescent()
+       public long getMovingSeconds()
        {
                if (!_valid) recalculate();
-               return _descent;
+               return _movingSeconds;
        }
 
-
        /**
-        * @return number of seconds spanned by selection
+        * @return distance of Selection in specified units
         */
-       public long getNumSeconds()
+       public double getDistance()
        {
-               if (!_valid) recalculate();
-               return _seconds;
+               return Distance.convertRadiansToDistance(_angDistance);
        }
 
-
        /**
-        * @param inUnits distance units to use, from class Distance
-        * @return distance of Selection in specified units
+        * @return moving distance of Selection in current units
         */
-       public double getDistance(int inUnits)
+       public double getMovingDistance()
        {
-               return Distance.convertRadiansToDistance(_angDistance, inUnits);
+               return Distance.convertRadiansToDistance(_angMovingDistance);
        }
 
+       /**
+        * @return number of segments in selection
+        */
+       public int getNumSegments()
+       {
+               return _numSegments;
+       }
 
        /**
-        * Clear selected point and range
+        * Clear selected point, range, photo and audio
         */
        public void clearAll()
        {
                _currentPoint = -1;
-               deselectRange();
-               deselectPhoto();
+               selectRange(-1, -1);
+               _currentPhotoIndex = -1;
+               _currentAudioIndex = -1;
+               check();
        }
 
 
        /**
-        * Deselect range
+        * Select range from start to end
+        * @param inStartIndex index of start of range
+        * @param inEndIndex index of end of range
         */
-       public void deselectRange()
+       public void selectRange(int inStartIndex, int inEndIndex)
        {
-               _startIndex = _endIndex = -1;
-               reset();
+               _startIndex = inStartIndex;
+               _endIndex = inEndIndex;
+               markInvalid();
                check();
        }
 
@@ -285,7 +240,7 @@ public class Selection
         * Set the index for the start of the range selection
         * @param inStartIndex start index
         */
-       public void selectRangeStart(int inStartIndex)
+       private void selectRangeStart(int inStartIndex)
        {
                if (inStartIndex < 0)
                {
@@ -300,7 +255,7 @@ public class Selection
                                _endIndex = _track.getNumPoints() - 1;
                        }
                }
-               reset();
+               markInvalid();
                UpdateMessageBroker.informSubscribers();
        }
 
@@ -328,12 +283,11 @@ public class Selection
                {
                        _endIndex = inEndIndex;
                        // Move start of selection to min if necessary
-                       if (_startIndex > _endIndex || _startIndex < 0)
-                       {
+                       if (_startIndex > _endIndex || _startIndex < 0) {
                                _startIndex = 0;
                        }
                }
-               reset();
+               markInvalid();
                UpdateMessageBroker.informSubscribers();
        }
 
@@ -371,40 +325,24 @@ public class Selection
                        _endIndex--;
                        if (_currentPoint < _startIndex)
                                _startIndex--;
-                       reset();
+                       markInvalid();
                }
                check();
        }
 
 
-       /**
-        * Deselect photo
-        */
-       public void deselectPhoto()
-       {
-               _currentPhotoIndex = -1;
-               check();
-       }
-
-
        /**
         * Select the specified photo and point
-        * @param inPhotoIndex index of selected photo in PhotoList
         * @param inPointIndex index of selected point
+        * @param inPhotoIndex index of selected photo in PhotoList
+        * @param inAudioIndex index of selected audio item
         */
-       public void selectPhotoAndPoint(int inPhotoIndex, int inPointIndex)
+       public void selectPointPhotoAudio(int inPointIndex, int inPhotoIndex, int inAudioIndex)
        {
+               _currentPoint = inPointIndex;
                _currentPhotoIndex = inPhotoIndex;
-               if (inPointIndex > -1)
-               {
-                       // select associated point, if any
-                       selectPoint(inPointIndex);
-               }
-               else
-               {
-                       // Check if not already done
-                       check();
-               }
+               _currentAudioIndex = inAudioIndex;
+               check();
        }
 
 
@@ -416,35 +354,40 @@ public class Selection
                return _currentPhotoIndex;
        }
 
+       /**
+        * @return currently selected audio index
+        */
+       public int getCurrentAudioIndex()
+       {
+               return _currentAudioIndex;
+       }
+
        /**
         * Check that the selection still makes sense
         * and fire update message to listeners
         */
        private void check()
        {
-               if (_track != null)
+               if (_track != null && _track.getNumPoints() > 0)
                {
-                       if (_track.getNumPoints() > 0)
+                       int maxIndex = _track.getNumPoints() - 1;
+                       if (_currentPoint > maxIndex)
                        {
-                               int maxIndex = _track.getNumPoints() - 1;
-                               if (_currentPoint > maxIndex)
-                               {
-                                       _currentPoint = maxIndex;
-                               }
-                               if (_endIndex > maxIndex)
-                               {
-                                       _endIndex = maxIndex;
-                               }
-                               if (_startIndex > maxIndex)
-                               {
-                                       _startIndex = maxIndex;
-                               }
+                               _currentPoint = maxIndex;
                        }
-                       else
+                       if (_endIndex > maxIndex)
                        {
-                               // track is empty, clear selections
-                               _currentPoint = _startIndex = _endIndex = -1;
+                               _endIndex = maxIndex;
                        }
+                       if (_startIndex > maxIndex)
+                       {
+                               _startIndex = maxIndex;
+                       }
+               }
+               else
+               {
+                       // track is empty, clear selections
+                       _currentPoint = _startIndex = _endIndex = -1;
                }
                UpdateMessageBroker.informSubscribers(DataSubscriber.SELECTION_CHANGED);
        }