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 * @return the PhotoList object
61 public PhotoList getPhotoList()
67 * Get the currently selected point, if any
68 * @return DataPoint if single point selected, otherwise null
70 public DataPoint getCurrentPoint()
72 return _track.getPoint(_selection.getCurrentPointIndex());
76 * Get the currently selected photo, if any
77 * @return Photo if selected, otherwise null
79 public Photo getCurrentPhoto()
81 return _photoList.getPhoto(_selection.getCurrentPhotoIndex());
87 * @param inSet Set containing Photo objects
88 * @return array containing number of photos and number of points added
90 public int[] addPhotos(Set<Photo> inSet)
92 // Firstly count number of points and photos to add
93 int numPhotosToAdd = 0;
94 int numPointsToAdd = 0;
95 Iterator<Photo> iterator = null;
96 if (inSet != null && !inSet.isEmpty())
98 iterator = inSet.iterator();
99 while (iterator.hasNext())
103 Photo photo = iterator.next();
104 if (photo != null && !_photoList.contains(photo))
107 if (photo.getDataPoint() != null)
113 catch (ClassCastException ce) {}
116 // If there are any photos to add, add them
117 if (numPhotosToAdd > 0)
119 DataPoint[] dataPoints = new DataPoint[numPointsToAdd];
121 boolean hasAltitude = false;
122 // Add each Photo in turn
123 iterator = inSet.iterator();
124 while (iterator.hasNext())
128 Photo photo = iterator.next();
129 if (photo != null && !_photoList.contains(photo))
132 _photoList.addPhoto(photo);
133 // Add point if there is one
134 if (photo.getDataPoint() != null)
136 dataPoints[pointNum] = photo.getDataPoint();
137 // Check if any points have altitudes
138 hasAltitude |= (photo.getDataPoint().getAltitude() != null);
143 catch (ClassCastException ce) {}
145 if (numPointsToAdd > 0)
147 // add points to track
148 _track.appendPoints(dataPoints);
149 // modify track field list
150 _track.getFieldList().extendList(Field.LATITUDE);
151 _track.getFieldList().extendList(Field.LONGITUDE);
152 if (hasAltitude) {_track.getFieldList().extendList(Field.ALTITUDE);}
155 int[] result = {numPhotosToAdd, numPointsToAdd};
161 * Delete the currently selected range of points
162 * @return true if successful
164 public boolean deleteRange()
166 int startSel = _selection.getStart();
167 int endSel = _selection.getEnd();
168 boolean answer = _track.deleteRange(startSel, endSel);
169 // clear range selection
170 _selection.modifyRangeDeleted();
176 * Delete the currently selected point
177 * @return true if point deleted
179 public boolean deletePoint()
181 if (_track.deletePoint(_selection.getCurrentPointIndex()))
183 _selection.modifyPointDeleted();
184 UpdateMessageBroker.informSubscribers();
192 * Delete the currently selected photo and optionally its point too
193 * @param inPointToo true to also delete associated point
194 * @return true if delete successful
196 public boolean deleteCurrentPhoto(boolean inPointToo)
198 // delete currently selected photo
199 int photoIndex = _selection.getCurrentPhotoIndex();
202 Photo photo = _photoList.getPhoto(photoIndex);
203 _photoList.deletePhoto(photoIndex);
204 // has it got a point?
205 if (photo.getDataPoint() != null)
210 int pointIndex = _track.getPointIndex(photo.getDataPoint());
211 _track.deletePoint(pointIndex);
215 // disconnect point from photo
216 photo.getDataPoint().setPhoto(null);
217 photo.setDataPoint(null);
220 // update subscribers
221 _selection.modifyPointDeleted();
222 UpdateMessageBroker.informSubscribers();
229 * Delete all the points which have been marked for deletion
230 * @return number of points deleted
232 public int deleteMarkedPoints()
234 int numDeleted = _track.deleteMarkedPoints();
235 if (numDeleted > 0) {
236 _selection.clearAll();
237 UpdateMessageBroker.informSubscribers();
244 * Clone the selected range of data points
245 * @return shallow copy of DataPoint objects
247 public DataPoint[] cloneSelectedRange()
249 return _track.cloneRange(_selection.getStart(), _selection.getEnd());
253 * Merge the track segments within the given range
254 * @param inStart start index
255 * @param inEnd end index
256 * @return true if successful
258 public boolean mergeTrackSegments(int inStart, int inEnd)
260 boolean firstTrackPoint = true;
261 // Loop between start and end
262 for (int i=inStart; i<=inEnd; i++) {
263 DataPoint point = _track.getPoint(i);
264 // Set all segments to false apart from first track point
265 if (point != null && !point.isWaypoint()) {
266 point.setSegmentStart(firstTrackPoint);
267 firstTrackPoint = false;
270 // Find following track point, if any
271 DataPoint nextPoint = _track.getNextTrackPoint(inEnd+1);
272 if (nextPoint != null) {nextPoint.setSegmentStart(true);}
273 _selection.markInvalid();
274 UpdateMessageBroker.informSubscribers();
279 * Interpolate extra points between two selected ones
280 * @param inNumPoints num points to insert
281 * @return true if successful
283 public boolean interpolate(int inNumPoints)
285 boolean success = _track.interpolate(_selection.getStart(), inNumPoints);
287 _selection.selectRangeEnd(_selection.getEnd() + inNumPoints);
294 * Average selected points to create a new one
295 * @return true if successful
297 public boolean average()
299 boolean success = _track.average(_selection.getStart(), _selection.getEnd());
301 selectPoint(_selection.getEnd()+1);
308 * Select the given DataPoint
309 * @param inPoint DataPoint object to select
311 public void selectPoint(DataPoint inPoint)
313 selectPoint(_track.getPointIndex(inPoint));
317 * Select the data point with the given index
318 * @param inPointIndex index of DataPoint to select, or -1 for none
320 public void selectPoint(int inPointIndex)
322 if (_selection.getCurrentPointIndex() == inPointIndex || inPointIndex >= _track.getNumPoints()) {return;}
323 // get the index of the current photo
324 int photoIndex = _selection.getCurrentPhotoIndex();
325 // Check if point has photo or not
326 boolean pointHasPhoto = false;
327 if (inPointIndex >= 0)
329 Photo pointPhoto = _track.getPoint(inPointIndex).getPhoto();
330 pointHasPhoto = (pointPhoto != null);
332 photoIndex = _photoList.getPhotoIndex(pointPhoto);
335 // Might need to deselect photo
338 // selected point hasn't got a photo - deselect photo if necessary
339 if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
344 _selection.selectPhotoAndPoint(photoIndex, inPointIndex);
348 * Select the given Photo and its point if any
349 * @param inPhotoIndex index of photo to select
351 public void selectPhoto(int inPhotoIndex)
353 if (_selection.getCurrentPhotoIndex() == inPhotoIndex) {return;}
354 // Photo is primary selection here, not as a result of a point selection
355 // Therefore the photo selection takes priority, deselecting point if necessary
357 Photo photo = _photoList.getPhoto(inPhotoIndex);
360 // Find point object and its index
361 int pointIndex = _track.getPointIndex(photo.getDataPoint());
362 // Check whether to deselect current point or not if photo not correlated
365 int currPointIndex = _selection.getCurrentPointIndex();
366 if (currPointIndex >= 0 && _track.getPoint(currPointIndex).getPhoto() == null)
368 pointIndex = currPointIndex; // Keep currently selected point
371 // give to selection object
372 _selection.selectPhotoAndPoint(inPhotoIndex, pointIndex);
375 // no photo, just reset selection
376 DataPoint currPoint = getCurrentPoint();
377 if (currPoint != null && currPoint.getPhoto() == null) {
378 _selection.selectPhotoAndPoint(-1, _selection.getCurrentPointIndex()); // keep point
381 _selection.selectPhotoAndPoint(-1, -1); // deselect point too