File: TrackInfo.java

package info (click to toggle)
gpsprune 10-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 2,220 kB
  • ctags: 3,013
  • sloc: java: 22,662; sh: 23; makefile: 16; python: 15
file content (410 lines) | stat: -rw-r--r-- 10,121 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
package tim.prune.data;

import java.util.Iterator;
import java.util.Set;
import tim.prune.UpdateMessageBroker;

/**
 * Class to hold all track information, including data
 * and the selection information
 */
public class TrackInfo
{
	private Track _track = null;
	private Selection _selection = null;
	private FileInfo _fileInfo = null;
	private PhotoList _photoList = null;


	/**
	 * Constructor
	 * @param inTrack Track object
	 */
	public TrackInfo(Track inTrack)
	{
		_track = inTrack;
		_selection = new Selection(_track);
		_fileInfo = new FileInfo();
		_photoList = new PhotoList();
	}


	/**
	 * @return the Track object
	 */
	public Track getTrack()
	{
		return _track;
	}


	/**
	 * @return the Selection object
	 */
	public Selection getSelection()
	{
		return _selection;
	}


	/**
	 * @return the FileInfo object
	 */
	public FileInfo getFileInfo()
	{
		return _fileInfo;
	}

	/**
	 * Replace the file info with a previously made clone
	 * @param inInfo cloned file info
	 */
	public void setFileInfo(FileInfo inInfo) {
		_fileInfo = inInfo;
	}

	/**
	 * @return the PhotoList object
	 */
	public PhotoList getPhotoList()
	{
		return _photoList;
	}

	/**
	 * Get the currently selected point, if any
	 * @return DataPoint if single point selected, otherwise null
	 */
	public DataPoint getCurrentPoint()
	{
		return _track.getPoint(_selection.getCurrentPointIndex());
	}

	/**
	 * Get the currently selected photo, if any
	 * @return Photo if selected, otherwise null
	 */
	public Photo getCurrentPhoto()
	{
		return _photoList.getPhoto(_selection.getCurrentPhotoIndex());
	}


	/**
	 * Add a Set of Photos
	 * @param inSet Set containing Photo objects
	 * @return array containing number of photos and number of points added
	 */
	public int[] addPhotos(Set<Photo> inSet)
	{
		// Firstly count number of points and photos to add
		int numPhotosToAdd = 0;
		int numPointsToAdd = 0;
		Iterator<Photo> iterator = null;
		if (inSet != null && !inSet.isEmpty())
		{
			iterator = inSet.iterator();
			while (iterator.hasNext())
			{
				try
				{
					Photo photo = iterator.next();
					if (photo != null && !_photoList.contains(photo))
					{
						numPhotosToAdd++;
						if (photo.getDataPoint() != null)
						{
							numPointsToAdd++;
						}
					}
				}
				catch (ClassCastException ce) {}
			}
		}
		// If there are any photos to add, add them
		if (numPhotosToAdd > 0)
		{
			DataPoint[] dataPoints = new DataPoint[numPointsToAdd];
			int pointNum = 0;
			boolean hasAltitude = false;
			// Add each Photo in turn
			iterator = inSet.iterator();
			while (iterator.hasNext())
			{
				try
				{
					Photo photo = iterator.next();
					if (photo != null && !_photoList.contains(photo))
					{
						// Add photo
						_photoList.addPhoto(photo);
						// Add point if there is one
						if (photo.getDataPoint() != null)
						{
							dataPoints[pointNum] = photo.getDataPoint();
							// Check if any points have altitudes
							hasAltitude |= (photo.getDataPoint().getAltitude() != null);
							pointNum++;
						}
					}
				}
				catch (ClassCastException ce) {}
			}
			if (numPointsToAdd > 0)
			{
				// add points to track
				_track.appendPoints(dataPoints);
				// modify track field list
				_track.getFieldList().extendList(Field.LATITUDE);
				_track.getFieldList().extendList(Field.LONGITUDE);
				if (hasAltitude) {_track.getFieldList().extendList(Field.ALTITUDE);}
			}
		}
		int[] result = {numPhotosToAdd, numPointsToAdd};
		return result;
	}


	/**
	 * Delete the currently selected range of points
	 * @return true if successful
	 */
	public boolean deleteRange()
	{
		int startSel = _selection.getStart();
		int endSel = _selection.getEnd();
		boolean answer = _track.deleteRange(startSel, endSel);
		// clear range selection
		_selection.modifyRangeDeleted();
		return answer;
	}


	/**
	 * Delete the currently selected point
	 * @return true if point deleted
	 */
	public boolean deletePoint()
	{
		if (_track.deletePoint(_selection.getCurrentPointIndex()))
		{
			_selection.modifyPointDeleted();
			UpdateMessageBroker.informSubscribers();
			return true;
		}
		return false;
	}


	/**
	 * Delete the currently selected photo and optionally its point too
	 * @param inPointToo true to also delete associated point
	 * @return true if delete successful
	 */
	public boolean deleteCurrentPhoto(boolean inPointToo)
	{
		// delete currently selected photo
		int photoIndex = _selection.getCurrentPhotoIndex();
		if (photoIndex >= 0)
		{
			Photo photo = _photoList.getPhoto(photoIndex);
			_photoList.deletePhoto(photoIndex);
			// has it got a point?
			if (photo.getDataPoint() != null)
			{
				if (inPointToo)
				{
					// delete point
					int pointIndex = _track.getPointIndex(photo.getDataPoint());
					_track.deletePoint(pointIndex);
				}
				else
				{
					// disconnect point from photo
					photo.getDataPoint().setPhoto(null);
					photo.setDataPoint(null);
				}
			}
			// update subscribers
			_selection.modifyPointDeleted();
			UpdateMessageBroker.informSubscribers();
		}
		return true;
	}


	/**
	 * Delete all the points which have been marked for deletion
	 * @return number of points deleted
	 */
	public int deleteMarkedPoints()
	{
		int numDeleted = _track.deleteMarkedPoints();
		if (numDeleted > 0) {
			_selection.clearAll();
			UpdateMessageBroker.informSubscribers();
		}
		return numDeleted;
	}


	/**
	 * Clone the selected range of data points
	 * @return shallow copy of DataPoint objects
	 */
	public DataPoint[] cloneSelectedRange()
	{
		return _track.cloneRange(_selection.getStart(), _selection.getEnd());
	}

	/**
	 * Merge the track segments within the given range
	 * @param inStart start index
	 * @param inEnd end index
	 * @return true if successful
	 */
	public boolean mergeTrackSegments(int inStart, int inEnd)
	{
		boolean firstTrackPoint = true;
		// Loop between start and end
		for (int i=inStart; i<=inEnd; i++) {
			DataPoint point = _track.getPoint(i);
			// Set all segments to false apart from first track point
			if (point != null && !point.isWaypoint()) {
				point.setSegmentStart(firstTrackPoint);
				firstTrackPoint = false;
			}
		}
		// Find following track point, if any
		DataPoint nextPoint = _track.getNextTrackPoint(inEnd+1);
		if (nextPoint != null) {nextPoint.setSegmentStart(true);}
		_selection.markInvalid();
		UpdateMessageBroker.informSubscribers();
		return true;
	}

	/**
	 * Interpolate extra points between two selected ones
	 * @param inNumPoints num points to insert
	 * @return true if successful
	 */
	public boolean interpolate(int inNumPoints)
	{
		boolean success = _track.interpolate(_selection.getStart(), inNumPoints);
		if (success) {
			_selection.selectRangeEnd(_selection.getEnd() + inNumPoints);
		}
		return success;
	}


	/**
	 * Average selected points to create a new one
	 * @return true if successful
	 */
	public boolean average()
	{
		boolean success = _track.average(_selection.getStart(), _selection.getEnd());
		if (success) {
			selectPoint(_selection.getEnd()+1);
		}
		return success;
	}


	/**
	 * Select the given DataPoint
	 * @param inPoint DataPoint object to select
	 */
	public void selectPoint(DataPoint inPoint)
	{
		selectPoint(_track.getPointIndex(inPoint));
	}

	/**
	 * Select the data point with the given index
	 * @param inPointIndex index of DataPoint to select, or -1 for none
	 */
	public void selectPoint(int inPointIndex)
	{
		if (_selection.getCurrentPointIndex() == inPointIndex || inPointIndex >= _track.getNumPoints()) {return;}
		// get the index of the current photo
		int photoIndex = _selection.getCurrentPhotoIndex();
		// Check if point has photo or not
		boolean pointHasPhoto = false;
		if (inPointIndex >= 0)
		{
			Photo pointPhoto = _track.getPoint(inPointIndex).getPhoto();
			pointHasPhoto = (pointPhoto != null);
			if (pointHasPhoto) {
				photoIndex = _photoList.getPhotoIndex(pointPhoto);
			}
		}
		// Might need to deselect photo
		if (!pointHasPhoto)
		{
			// selected point hasn't got a photo - deselect photo if necessary
			if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
				photoIndex = -1;
			}
		}
		// give to selection
		_selection.selectPhotoAndPoint(photoIndex, inPointIndex);
	}

	/**
	 * Select the given Photo and its point if any
	 * @param inPhotoIndex index of photo to select
	 */
	public void selectPhoto(int inPhotoIndex)
	{
		if (_selection.getCurrentPhotoIndex() == inPhotoIndex) {return;}
		// Photo is primary selection here, not as a result of a point selection
		// Therefore the photo selection takes priority, deselecting point if necessary
		// Find Photo object
		Photo photo = _photoList.getPhoto(inPhotoIndex);
		if (photo != null)
		{
			// Find point object and its index
			int pointIndex = _track.getPointIndex(photo.getDataPoint());
			// Check whether to deselect current point or not if photo not correlated
			if (pointIndex < 0)
			{
				int currPointIndex = _selection.getCurrentPointIndex();
				if (currPointIndex >= 0 && _track.getPoint(currPointIndex).getPhoto() == null)
				{
					pointIndex = currPointIndex; // Keep currently selected point
				}
			}
			// give to selection object
			_selection.selectPhotoAndPoint(inPhotoIndex, pointIndex);
		}
		else {
			// no photo, just reset selection
			DataPoint currPoint = getCurrentPoint();
			if (currPoint != null && currPoint.getPhoto() == null) {
				_selection.selectPhotoAndPoint(-1, _selection.getCurrentPointIndex()); // keep point
			}
			else {
				_selection.selectPhotoAndPoint(-1, -1); // deselect point too
			}
		}
	}

	/**
	 * Extend the current selection to end at the given point, eg by shift-clicking
	 * @param inPointNum index of end point
	 */
	public void extendSelection(int inPointNum)
	{
		// See whether to start selection from current range start or current point
		int rangeStart = _selection.getStart();
		if (rangeStart < 0 || _selection.getCurrentPointIndex() != _selection.getEnd()) {
			rangeStart = _selection.getCurrentPointIndex();
		}
		selectPoint(inPointNum);
		if (rangeStart < inPointNum) {
			_selection.selectRange(rangeStart, inPointNum);
		}
	}
}