1 package tim.prune.data;
3 import tim.prune.UpdateMessageBroker;
6 * Class to represent a selected portion of a Track
11 private Track _track = null;
12 private UpdateMessageBroker _broker = null;
13 private int _currentPoint = -1;
14 private boolean _valid = false;
15 private int _startIndex = -1, _endIndex = -1;
16 private int _currentPhotoIndex = -1;
17 private IntegerRange _altitudeRange = null;
18 private int _climb = -1, _descent = -1;
19 private int _altitudeFormat = Altitude.FORMAT_NONE;
20 private long _seconds = 0L;
21 private double _angDistance = -1.0; //, _averageSpeed = -1.0;
26 * @param inTrack track object
27 * @param inBroker broker object
29 public Selection(Track inTrack, UpdateMessageBroker inBroker)
37 * Reset selection to be recalculated
46 * Select the point at the given index
47 * @param inIndex index number of selected point
49 public void selectPoint(int inIndex)
53 _currentPoint = inIndex;
59 * Select the specified point and range in one go
60 * @param inPointIndex point selection
61 * @param inStart range start
62 * @param inEnd range end
64 public void select(int inPointIndex, int inStart, int inEnd)
66 _currentPoint = inPointIndex;
67 _startIndex = inStart;
75 * Select the previous point
77 public void selectPreviousPoint()
79 if (_currentPoint > 0)
80 selectPoint(_currentPoint - 1);
84 * Select the next point
86 public void selectNextPoint()
88 selectPoint(_currentPoint + 1);
92 * @return the current point index
94 public int getCurrentPointIndex()
101 * @return true if range is selected
103 public boolean hasRangeSelected()
105 return _startIndex >= 0 && _endIndex > _startIndex;
110 * Recalculate all selection details
112 private void recalculate()
114 _altitudeFormat = Altitude.FORMAT_NONE;
115 if (_track.getNumPoints() > 0 && hasRangeSelected())
117 _altitudeRange = new IntegerRange();
120 Altitude altitude = null;
121 Timestamp time = null, startTime = null, endTime = null;
122 DataPoint lastPoint = null, currPoint = null;
125 int lastAltValue = 0;
126 boolean foundAlt = false;
127 for (int i=_startIndex; i<=_endIndex; i++)
129 currPoint = _track.getPoint(i);
130 altitude = currPoint.getAltitude();
131 // Ignore waypoints in altitude calculations
132 if (!currPoint.isWaypoint() && altitude.isValid())
134 altValue = altitude.getValue(_altitudeFormat);
135 if (_altitudeFormat == Altitude.FORMAT_NONE)
136 _altitudeFormat = altitude.getFormat();
137 _altitudeRange.addValue(altValue);
140 if (altValue > lastAltValue)
141 _climb += (altValue - lastAltValue);
143 _descent += (lastAltValue - altValue);
145 lastAltValue = altValue;
148 // Store the first and last timestamp in the range
149 time = currPoint.getTimestamp();
152 if (startTime == null) startTime = time;
155 // Calculate distances, again ignoring waypoints
156 if (!currPoint.isWaypoint())
158 if (lastPoint != null)
160 _angDistance += DataPoint.calculateRadiansBetween(lastPoint, currPoint);
162 lastPoint = currPoint;
167 _seconds = endTime.getSecondsSince(startTime);
179 * @return start index
181 public int getStart()
183 if (!_valid) recalculate();
193 if (!_valid) recalculate();
199 * @return the altitude format, ie feet or metres
201 public int getAltitudeFormat()
203 return _altitudeFormat;
207 * @return altitude range
209 public IntegerRange getAltitudeRange()
211 if (!_valid) recalculate();
212 return _altitudeRange;
219 public int getClimb()
221 if (!_valid) recalculate();
228 public int getDescent()
230 if (!_valid) recalculate();
236 * @return number of seconds spanned by selection
238 public long getNumSeconds()
240 if (!_valid) recalculate();
246 * @param inFormat distance units to use, from class Distance
247 * @return distance of Selection in specified units
249 public double getDistance(int inUnits)
251 return Distance.convertRadians(_angDistance, inUnits);
256 * Clear selected point and range
258 public void clearAll()
269 public void deselectRange()
271 _startIndex = _endIndex = -1;
278 * Select the range from the current point
280 public void selectRangeStart()
282 selectRangeStart(_currentPoint);
287 * Set the index for the start of the range selection
288 * @param inStartIndex start index
290 public void selectRangeStart(int inStartIndex)
292 if (inStartIndex < 0)
294 _startIndex = _endIndex = -1;
298 _startIndex = inStartIndex;
299 // Move end of selection to max if necessary
300 if (_endIndex <= _startIndex)
302 _endIndex = _track.getNumPoints() - 1;
306 _broker.informSubscribers();
311 * Select the range up to the current point
313 public void selectRangeEnd()
315 selectRangeEnd(_currentPoint);
320 * Set the index for the end of the range selection
321 * @param inEndIndex end index
323 public void selectRangeEnd(int inEndIndex)
327 _startIndex = _endIndex = -1;
331 _endIndex = inEndIndex;
332 // Move start of selection to min if necessary
333 if (_startIndex > _endIndex || _startIndex < 0)
339 _broker.informSubscribers();
344 * Modify the selection given that the selected range has been deleted
346 public void modifyRangeDeleted()
348 // Modify current point, if any
349 if (_currentPoint > _endIndex)
351 _currentPoint -= (_endIndex - _startIndex);
353 else if (_currentPoint > _startIndex)
355 _currentPoint = _startIndex;
357 // Clear selected range
358 _startIndex = _endIndex = -1;
359 // Check for consistency and fire update
365 * Modify the selection when a point is deleted
367 public void modifyPointDeleted()
369 // current point index doesn't change, just gets checked
370 // range needs to get altered if deleted point is inside or before
371 if (hasRangeSelected() && _currentPoint <= _endIndex)
374 if (_currentPoint < _startIndex)
385 public void deselectPhoto()
387 _currentPhotoIndex = -1;
393 * Select the specified photo and point
394 * @param inPhotoIndex index of selected photo in PhotoList
395 * @param inPointIndex index of selected point
397 public void selectPhotoAndPoint(int inPhotoIndex, int inPointIndex)
399 _currentPhotoIndex = inPhotoIndex;
400 if (inPointIndex > -1)
402 // select associated point, if any
403 selectPoint(inPointIndex);
407 // Check if not already done
414 * @return currently selected photo index
416 public int getCurrentPhotoIndex()
418 // System.out.println("Current photo index = " + _currentPhotoIndex);
419 return _currentPhotoIndex;
424 * Check that the selection still makes sense
425 * and fire update message to listeners
431 if (_track.getNumPoints() > 0)
433 int maxIndex = _track.getNumPoints() - 1;
434 if (_currentPoint > maxIndex)
436 _currentPoint = maxIndex;
438 if (_endIndex > maxIndex)
440 _endIndex = maxIndex;
442 if (_startIndex > maxIndex)
444 _startIndex = maxIndex;
449 // track is empty, clear selections
450 _currentPoint = _startIndex = _endIndex = -1;
453 _broker.informSubscribers();