1 package tim.prune.data;
3 import java.util.Iterator;
5 import tim.prune.UpdateMessageBroker;
8 * Class to hold all track information, including data
9 * and the selection information
11 public class TrackInfo
13 private Track _track = null;
14 private Selection _selection = null;
15 private FileInfo _fileInfo = null;
16 private PhotoList _photoList = null;
21 * @param inTrack Track object
23 public TrackInfo(Track inTrack)
26 _selection = new Selection(_track);
27 _fileInfo = new FileInfo();
28 _photoList = new PhotoList();
33 * @return the Track object
35 public Track getTrack()
42 * @return the Selection object
44 public Selection getSelection()
51 * @return the FileInfo object
53 public FileInfo getFileInfo()
59 * Replace the file info with a previously made clone
60 * @param inInfo cloned file info
62 public void setFileInfo(FileInfo inInfo) {
67 * @return the PhotoList object
69 public PhotoList getPhotoList()
75 * Get the currently selected point, if any
76 * @return DataPoint if single point selected, otherwise null
78 public DataPoint getCurrentPoint()
80 return _track.getPoint(_selection.getCurrentPointIndex());
84 * Get the currently selected photo, if any
85 * @return Photo if selected, otherwise null
87 public Photo getCurrentPhoto()
89 return _photoList.getPhoto(_selection.getCurrentPhotoIndex());
95 * @param inSet Set containing Photo objects
96 * @return array containing number of photos and number of points added
98 public int[] addPhotos(Set<Photo> inSet)
100 // Firstly count number of points and photos to add
101 int numPhotosToAdd = 0;
102 int numPointsToAdd = 0;
103 Iterator<Photo> iterator = null;
104 if (inSet != null && !inSet.isEmpty())
106 iterator = inSet.iterator();
107 while (iterator.hasNext())
111 Photo photo = iterator.next();
112 if (photo != null && !_photoList.contains(photo))
115 if (photo.getDataPoint() != null)
121 catch (ClassCastException ce) {}
124 // If there are any photos to add, add them
125 if (numPhotosToAdd > 0)
127 DataPoint[] dataPoints = new DataPoint[numPointsToAdd];
129 boolean hasAltitude = false;
130 // Add each Photo in turn
131 iterator = inSet.iterator();
132 while (iterator.hasNext())
136 Photo photo = iterator.next();
137 if (photo != null && !_photoList.contains(photo))
140 _photoList.addPhoto(photo);
141 // Add point if there is one
142 if (photo.getDataPoint() != null)
144 dataPoints[pointNum] = photo.getDataPoint();
145 // Check if any points have altitudes
146 hasAltitude |= (photo.getDataPoint().getAltitude() != null);
151 catch (ClassCastException ce) {}
153 if (numPointsToAdd > 0)
155 // add points to track
156 _track.appendPoints(dataPoints);
157 // modify track field list
158 _track.getFieldList().extendList(Field.LATITUDE);
159 _track.getFieldList().extendList(Field.LONGITUDE);
160 if (hasAltitude) {_track.getFieldList().extendList(Field.ALTITUDE);}
163 int[] result = {numPhotosToAdd, numPointsToAdd};
169 * Delete the currently selected range of points
170 * @return true if successful
172 public boolean deleteRange()
174 int startSel = _selection.getStart();
175 int endSel = _selection.getEnd();
176 boolean answer = _track.deleteRange(startSel, endSel);
177 // clear range selection
178 _selection.modifyRangeDeleted();
184 * Delete the currently selected point
185 * @return true if point deleted
187 public boolean deletePoint()
189 if (_track.deletePoint(_selection.getCurrentPointIndex()))
191 _selection.modifyPointDeleted();
192 UpdateMessageBroker.informSubscribers();
200 * Delete the currently selected photo and optionally its point too
201 * @param inPointToo true to also delete associated point
202 * @return true if delete successful
204 public boolean deleteCurrentPhoto(boolean inPointToo)
206 // delete currently selected photo
207 int photoIndex = _selection.getCurrentPhotoIndex();
210 Photo photo = _photoList.getPhoto(photoIndex);
211 _photoList.deletePhoto(photoIndex);
212 // has it got a point?
213 if (photo.getDataPoint() != null)
218 int pointIndex = _track.getPointIndex(photo.getDataPoint());
219 _track.deletePoint(pointIndex);
223 // disconnect point from photo
224 photo.getDataPoint().setPhoto(null);
225 photo.setDataPoint(null);
228 // update subscribers
229 _selection.modifyPointDeleted();
230 UpdateMessageBroker.informSubscribers();
237 * Delete all the points which have been marked for deletion
238 * @return number of points deleted
240 public int deleteMarkedPoints()
242 int numDeleted = _track.deleteMarkedPoints();
243 if (numDeleted > 0) {
244 _selection.clearAll();
245 UpdateMessageBroker.informSubscribers();
252 * Clone the selected range of data points
253 * @return shallow copy of DataPoint objects
255 public DataPoint[] cloneSelectedRange()
257 return _track.cloneRange(_selection.getStart(), _selection.getEnd());
261 * Merge the track segments within the given range
262 * @param inStart start index
263 * @param inEnd end index
264 * @return true if successful
266 public boolean mergeTrackSegments(int inStart, int inEnd)
268 boolean firstTrackPoint = true;
269 // Loop between start and end
270 for (int i=inStart; i<=inEnd; i++) {
271 DataPoint point = _track.getPoint(i);
272 // Set all segments to false apart from first track point
273 if (point != null && !point.isWaypoint()) {
274 point.setSegmentStart(firstTrackPoint);
275 firstTrackPoint = false;
278 // Find following track point, if any
279 DataPoint nextPoint = _track.getNextTrackPoint(inEnd+1);
280 if (nextPoint != null) {nextPoint.setSegmentStart(true);}
281 _selection.markInvalid();
282 UpdateMessageBroker.informSubscribers();
287 * Interpolate extra points between two selected ones
288 * @param inNumPoints num points to insert
289 * @return true if successful
291 public boolean interpolate(int inNumPoints)
293 boolean success = _track.interpolate(_selection.getStart(), inNumPoints);
295 _selection.selectRangeEnd(_selection.getEnd() + inNumPoints);
302 * Average selected points to create a new one
303 * @return true if successful
305 public boolean average()
307 boolean success = _track.average(_selection.getStart(), _selection.getEnd());
309 selectPoint(_selection.getEnd()+1);
316 * Select the given DataPoint
317 * @param inPoint DataPoint object to select
319 public void selectPoint(DataPoint inPoint)
321 selectPoint(_track.getPointIndex(inPoint));
325 * Select the data point with the given index
326 * @param inPointIndex index of DataPoint to select, or -1 for none
328 public void selectPoint(int inPointIndex)
330 if (_selection.getCurrentPointIndex() == inPointIndex || inPointIndex >= _track.getNumPoints()) {return;}
331 // get the index of the current photo
332 int photoIndex = _selection.getCurrentPhotoIndex();
333 // Check if point has photo or not
334 boolean pointHasPhoto = false;
335 if (inPointIndex >= 0)
337 Photo pointPhoto = _track.getPoint(inPointIndex).getPhoto();
338 pointHasPhoto = (pointPhoto != null);
340 photoIndex = _photoList.getPhotoIndex(pointPhoto);
343 // Might need to deselect photo
346 // selected point hasn't got a photo - deselect photo if necessary
347 if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
352 _selection.selectPhotoAndPoint(photoIndex, inPointIndex);
356 * Select the given Photo and its point if any
357 * @param inPhotoIndex index of photo to select
359 public void selectPhoto(int inPhotoIndex)
361 if (_selection.getCurrentPhotoIndex() == inPhotoIndex) {return;}
362 // Photo is primary selection here, not as a result of a point selection
363 // Therefore the photo selection takes priority, deselecting point if necessary
365 Photo photo = _photoList.getPhoto(inPhotoIndex);
368 // Find point object and its index
369 int pointIndex = _track.getPointIndex(photo.getDataPoint());
370 // Check whether to deselect current point or not if photo not correlated
373 int currPointIndex = _selection.getCurrentPointIndex();
374 if (currPointIndex >= 0 && _track.getPoint(currPointIndex).getPhoto() == null)
376 pointIndex = currPointIndex; // Keep currently selected point
379 // give to selection object
380 _selection.selectPhotoAndPoint(inPhotoIndex, pointIndex);
383 // no photo, just reset selection
384 DataPoint currPoint = getCurrentPoint();
385 if (currPoint != null && currPoint.getPhoto() == null) {
386 _selection.selectPhotoAndPoint(-1, _selection.getCurrentPointIndex()); // keep point
389 _selection.selectPhotoAndPoint(-1, -1); // deselect point too
395 * Extend the current selection to end at the given point, eg by shift-clicking
396 * @param inPointNum index of end point
398 public void extendSelection(int inPointNum)
400 // See whether to start selection from current range start or current point
401 int rangeStart = _selection.getStart();
402 if (rangeStart < 0 || _selection.getCurrentPointIndex() != _selection.getEnd()) {
403 rangeStart = _selection.getCurrentPointIndex();
405 selectPoint(inPointNum);
406 if (rangeStart < inPointNum) {
407 _selection.selectRange(rangeStart, inPointNum);