]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/data/TrackInfo.java
Version 10, May 2010
[GpsPrune.git] / tim / prune / data / TrackInfo.java
1 package tim.prune.data;
2
3 import java.util.Iterator;
4 import java.util.Set;
5 import tim.prune.UpdateMessageBroker;
6
7 /**
8  * Class to hold all track information, including data
9  * and the selection information
10  */
11 public class TrackInfo
12 {
13         private Track _track = null;
14         private Selection _selection = null;
15         private FileInfo _fileInfo = null;
16         private PhotoList _photoList = null;
17
18
19         /**
20          * Constructor
21          * @param inTrack Track object
22          */
23         public TrackInfo(Track inTrack)
24         {
25                 _track = inTrack;
26                 _selection = new Selection(_track);
27                 _fileInfo = new FileInfo();
28                 _photoList = new PhotoList();
29         }
30
31
32         /**
33          * @return the Track object
34          */
35         public Track getTrack()
36         {
37                 return _track;
38         }
39
40
41         /**
42          * @return the Selection object
43          */
44         public Selection getSelection()
45         {
46                 return _selection;
47         }
48
49
50         /**
51          * @return the FileInfo object
52          */
53         public FileInfo getFileInfo()
54         {
55                 return _fileInfo;
56         }
57
58         /**
59          * Replace the file info with a previously made clone
60          * @param inInfo cloned file info
61          */
62         public void setFileInfo(FileInfo inInfo) {
63                 _fileInfo = inInfo;
64         }
65
66         /**
67          * @return the PhotoList object
68          */
69         public PhotoList getPhotoList()
70         {
71                 return _photoList;
72         }
73
74         /**
75          * Get the currently selected point, if any
76          * @return DataPoint if single point selected, otherwise null
77          */
78         public DataPoint getCurrentPoint()
79         {
80                 return _track.getPoint(_selection.getCurrentPointIndex());
81         }
82
83         /**
84          * Get the currently selected photo, if any
85          * @return Photo if selected, otherwise null
86          */
87         public Photo getCurrentPhoto()
88         {
89                 return _photoList.getPhoto(_selection.getCurrentPhotoIndex());
90         }
91
92
93         /**
94          * Add a Set of Photos
95          * @param inSet Set containing Photo objects
96          * @return array containing number of photos and number of points added
97          */
98         public int[] addPhotos(Set<Photo> inSet)
99         {
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())
105                 {
106                         iterator = inSet.iterator();
107                         while (iterator.hasNext())
108                         {
109                                 try
110                                 {
111                                         Photo photo = iterator.next();
112                                         if (photo != null && !_photoList.contains(photo))
113                                         {
114                                                 numPhotosToAdd++;
115                                                 if (photo.getDataPoint() != null)
116                                                 {
117                                                         numPointsToAdd++;
118                                                 }
119                                         }
120                                 }
121                                 catch (ClassCastException ce) {}
122                         }
123                 }
124                 // If there are any photos to add, add them
125                 if (numPhotosToAdd > 0)
126                 {
127                         DataPoint[] dataPoints = new DataPoint[numPointsToAdd];
128                         int pointNum = 0;
129                         boolean hasAltitude = false;
130                         // Add each Photo in turn
131                         iterator = inSet.iterator();
132                         while (iterator.hasNext())
133                         {
134                                 try
135                                 {
136                                         Photo photo = iterator.next();
137                                         if (photo != null && !_photoList.contains(photo))
138                                         {
139                                                 // Add photo
140                                                 _photoList.addPhoto(photo);
141                                                 // Add point if there is one
142                                                 if (photo.getDataPoint() != null)
143                                                 {
144                                                         dataPoints[pointNum] = photo.getDataPoint();
145                                                         // Check if any points have altitudes
146                                                         hasAltitude |= (photo.getDataPoint().getAltitude() != null);
147                                                         pointNum++;
148                                                 }
149                                         }
150                                 }
151                                 catch (ClassCastException ce) {}
152                         }
153                         if (numPointsToAdd > 0)
154                         {
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);}
161                         }
162                 }
163                 int[] result = {numPhotosToAdd, numPointsToAdd};
164                 return result;
165         }
166
167
168         /**
169          * Delete the currently selected range of points
170          * @return true if successful
171          */
172         public boolean deleteRange()
173         {
174                 int startSel = _selection.getStart();
175                 int endSel = _selection.getEnd();
176                 boolean answer = _track.deleteRange(startSel, endSel);
177                 // clear range selection
178                 _selection.modifyRangeDeleted();
179                 return answer;
180         }
181
182
183         /**
184          * Delete the currently selected point
185          * @return true if point deleted
186          */
187         public boolean deletePoint()
188         {
189                 if (_track.deletePoint(_selection.getCurrentPointIndex()))
190                 {
191                         _selection.modifyPointDeleted();
192                         UpdateMessageBroker.informSubscribers();
193                         return true;
194                 }
195                 return false;
196         }
197
198
199         /**
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
203          */
204         public boolean deleteCurrentPhoto(boolean inPointToo)
205         {
206                 // delete currently selected photo
207                 int photoIndex = _selection.getCurrentPhotoIndex();
208                 if (photoIndex >= 0)
209                 {
210                         Photo photo = _photoList.getPhoto(photoIndex);
211                         _photoList.deletePhoto(photoIndex);
212                         // has it got a point?
213                         if (photo.getDataPoint() != null)
214                         {
215                                 if (inPointToo)
216                                 {
217                                         // delete point
218                                         int pointIndex = _track.getPointIndex(photo.getDataPoint());
219                                         _track.deletePoint(pointIndex);
220                                 }
221                                 else
222                                 {
223                                         // disconnect point from photo
224                                         photo.getDataPoint().setPhoto(null);
225                                         photo.setDataPoint(null);
226                                 }
227                         }
228                         // update subscribers
229                         _selection.modifyPointDeleted();
230                         UpdateMessageBroker.informSubscribers();
231                 }
232                 return true;
233         }
234
235
236         /**
237          * Delete all the points which have been marked for deletion
238          * @return number of points deleted
239          */
240         public int deleteMarkedPoints()
241         {
242                 int numDeleted = _track.deleteMarkedPoints();
243                 if (numDeleted > 0) {
244                         _selection.clearAll();
245                         UpdateMessageBroker.informSubscribers();
246                 }
247                 return numDeleted;
248         }
249
250
251         /**
252          * Clone the selected range of data points
253          * @return shallow copy of DataPoint objects
254          */
255         public DataPoint[] cloneSelectedRange()
256         {
257                 return _track.cloneRange(_selection.getStart(), _selection.getEnd());
258         }
259
260         /**
261          * Merge the track segments within the given range
262          * @param inStart start index
263          * @param inEnd end index
264          * @return true if successful
265          */
266         public boolean mergeTrackSegments(int inStart, int inEnd)
267         {
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;
276                         }
277                 }
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();
283                 return true;
284         }
285
286         /**
287          * Interpolate extra points between two selected ones
288          * @param inNumPoints num points to insert
289          * @return true if successful
290          */
291         public boolean interpolate(int inNumPoints)
292         {
293                 boolean success = _track.interpolate(_selection.getStart(), inNumPoints);
294                 if (success) {
295                         _selection.selectRangeEnd(_selection.getEnd() + inNumPoints);
296                 }
297                 return success;
298         }
299
300
301         /**
302          * Average selected points to create a new one
303          * @return true if successful
304          */
305         public boolean average()
306         {
307                 boolean success = _track.average(_selection.getStart(), _selection.getEnd());
308                 if (success) {
309                         selectPoint(_selection.getEnd()+1);
310                 }
311                 return success;
312         }
313
314
315         /**
316          * Select the given DataPoint
317          * @param inPoint DataPoint object to select
318          */
319         public void selectPoint(DataPoint inPoint)
320         {
321                 selectPoint(_track.getPointIndex(inPoint));
322         }
323
324         /**
325          * Select the data point with the given index
326          * @param inPointIndex index of DataPoint to select, or -1 for none
327          */
328         public void selectPoint(int inPointIndex)
329         {
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)
336                 {
337                         Photo pointPhoto = _track.getPoint(inPointIndex).getPhoto();
338                         pointHasPhoto = (pointPhoto != null);
339                         if (pointHasPhoto) {
340                                 photoIndex = _photoList.getPhotoIndex(pointPhoto);
341                         }
342                 }
343                 // Might need to deselect photo
344                 if (!pointHasPhoto)
345                 {
346                         // selected point hasn't got a photo - deselect photo if necessary
347                         if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
348                                 photoIndex = -1;
349                         }
350                 }
351                 // give to selection
352                 _selection.selectPhotoAndPoint(photoIndex, inPointIndex);
353         }
354
355         /**
356          * Select the given Photo and its point if any
357          * @param inPhotoIndex index of photo to select
358          */
359         public void selectPhoto(int inPhotoIndex)
360         {
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
364                 // Find Photo object
365                 Photo photo = _photoList.getPhoto(inPhotoIndex);
366                 if (photo != null)
367                 {
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
371                         if (pointIndex < 0)
372                         {
373                                 int currPointIndex = _selection.getCurrentPointIndex();
374                                 if (currPointIndex >= 0 && _track.getPoint(currPointIndex).getPhoto() == null)
375                                 {
376                                         pointIndex = currPointIndex; // Keep currently selected point
377                                 }
378                         }
379                         // give to selection object
380                         _selection.selectPhotoAndPoint(inPhotoIndex, pointIndex);
381                 }
382                 else {
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
387                         }
388                         else {
389                                 _selection.selectPhotoAndPoint(-1, -1); // deselect point too
390                         }
391                 }
392         }
393
394         /**
395          * Extend the current selection to end at the given point, eg by shift-clicking
396          * @param inPointNum index of end point
397          */
398         public void extendSelection(int inPointNum)
399         {
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();
404                 }
405                 selectPoint(inPointNum);
406                 if (rangeStart < inPointNum) {
407                         _selection.selectRange(rangeStart, inPointNum);
408                 }
409         }
410 }