File: TrackInfo.java

package info (click to toggle)
gpsprune 17-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,984 kB
  • ctags: 5,218
  • sloc: java: 39,403; sh: 25; makefile: 17; python: 15
file content (501 lines) | stat: -rw-r--r-- 13,414 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
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
package tim.prune.data;

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;
	private AudioList _audioList = null;


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


	/**
	 * @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;
	}

	/**
	 * @return the AudioList object
	 */
	public AudioList getAudioList() {
		return _audioList;
	}

	/**
	 * 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());
	}

	/**
	 * Get the currently selected audio clip, if any
	 * @return AudioClip if selected, otherwise null
	 */
	public AudioClip getCurrentAudio() {
		return _audioList.getAudio(_selection.getCurrentAudioIndex());
	}


	/**
	 * 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;
		if (inSet != null && !inSet.isEmpty())
		{
			for (Photo photo : inSet)
			{
				if (photo != null && !_photoList.contains(photo))
				{
					numPhotosToAdd++;
					if (photo.getDataPoint() != null) {
						numPointsToAdd++;
					}
				}
			}
		}
		// 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
			for (Photo photo : inSet)
			{
				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++;
					}
				}
			}
			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;
	}

	/**
	 * Add a Set of Audio objects
	 * @param inSet Set containing Audio objects
	 * @return number of audio objects added
	 */
	public int addAudios(Set<AudioClip> inSet)
	{
		int numAudiosAdded = 0;
		if (inSet != null && !inSet.isEmpty())
		{
			for (AudioClip audio : inSet)
			{
				if (audio != null && !_audioList.contains(audio))
				{
					// Add audio object
					_audioList.addAudio(audio);
					numAudiosAdded++;
					// audio objects never have points when they're loaded
				}
			}
		}
		return numAudiosAdded;
	}

	/**
	 * Delete the currently selected point
	 * @return true if point deleted
	 */
	public boolean deletePoint()
	{
		if (_track.deletePoint(_selection.getCurrentPointIndex()))
		{
			_selection.modifyPointDeleted();
			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)
	{
		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 the currently selected audio item and optionally its point too
	 * @param inPointToo true to also delete associated point
	 * @return true if delete successful
	 */
	public boolean deleteCurrentAudio(boolean inPointToo)
	{
		int audioIndex = _selection.getCurrentAudioIndex();
		if (audioIndex >= 0)
		{
			AudioClip audio = _audioList.getAudio(audioIndex);
			_audioList.deleteAudio(audioIndex);
			// has it got a point?
			if (audio.getDataPoint() != null)
			{
				if (inPointToo)
				{
					// delete point
					int pointIndex = _track.getPointIndex(audio.getDataPoint());
					_track.deletePoint(pointIndex);
				}
				else
				{
					// disconnect point from audio
					audio.getDataPoint().setAudio(null);
					audio.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;
	}


	/**
	 * 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));
	}

	/**
	 * Increment the selected point index by the given increment
	 * @param inPointIncrement +1 for next point, -1 for previous etc
	 */
	public void incrementPointIndex(int inPointIncrement)
	{
		int index = _selection.getCurrentPointIndex() + inPointIncrement;
		if (index < 0) index = 0;
		else if (index >= _track.getNumPoints()) index = _track.getNumPoints()-1;
		selectPoint(index);
	}

	/**
	 * 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;}
		DataPoint selectedPoint = _track.getPoint(inPointIndex);
		// get the index of the current photo
		int photoIndex = _selection.getCurrentPhotoIndex();
		// Check if point has photo or not
		boolean pointHasPhoto = inPointIndex >= 0 && selectedPoint.getPhoto() != null;
		if (pointHasPhoto) {
			photoIndex = _photoList.getPhotoIndex(selectedPoint.getPhoto());
		}
		else if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
			// selected point hasn't got a photo - deselect photo if necessary
			photoIndex = -1;
		}
		// Check if point has an audio item or not
		int audioIndex = _selection.getCurrentAudioIndex();
		boolean pointHasAudio = inPointIndex >= 0 && selectedPoint.getAudio() != null;
		if (pointHasAudio) {
			audioIndex = _audioList.getAudioIndex(selectedPoint.getAudio());
		}
		else if (audioIndex < 0 || _audioList.getAudio(audioIndex).isConnected()) {
			// deselect current audio clip
			audioIndex = -1;
		}
		// give to selection
		_selection.selectPointPhotoAudio(inPointIndex, photoIndex, audioIndex);
	}

	/**
	 * 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);
		int pointIndex = _selection.getCurrentPointIndex();
		DataPoint currPoint = getCurrentPoint();
		if (photo != null)
		{
			// Has the photo got a point?
			if (photo.isConnected()) {
				pointIndex = _track.getPointIndex(photo.getDataPoint());
			}
			else {
				// Check whether to deselect current point or not if photo not correlated
				if (pointIndex >= 0 && _track.getPoint(pointIndex).getPhoto() != null) {
					pointIndex = -1;
				}
			}
		}
		else {
			// no photo, but maybe need to deselect point
			if (currPoint != null && currPoint.getPhoto() != null) {
				pointIndex = -1;
			}
		}
		// Has the new point got an audio clip?
		DataPoint selectedPoint = _track.getPoint(pointIndex);
		int audioIndex = _selection.getCurrentAudioIndex();
		if (selectedPoint != null && selectedPoint.getAudio() != null) {
			// New point has an audio, so select it
			audioIndex = _audioList.getAudioIndex(selectedPoint.getAudio());
		}
		else if (currPoint != null && selectedPoint != currPoint && currPoint.getAudio() != null) {
			// Old point had an audio, so deselect it
			audioIndex = -1;
		}
		// give to selection object
		_selection.selectPointPhotoAudio(pointIndex, inPhotoIndex, audioIndex);
	}

	/**
	 * Select the given audio object and its point if any
	 * @param inAudioIndex index of audio item to select
	 */
	public void selectAudio(int inAudioIndex)
	{
		if (_selection.getCurrentAudioIndex() == inAudioIndex) {return;}
		// Audio selection takes priority, deselecting point if necessary
		AudioClip audio = _audioList.getAudio(inAudioIndex);
		int pointIndex = _selection.getCurrentPointIndex();
		DataPoint currPoint = getCurrentPoint();
		if (audio != null)
		{
			// Find point object and its index
			if (audio.isConnected()) {
				pointIndex = _track.getPointIndex(audio.getDataPoint());
			}
			else {
				// Check whether to deselect current point or not if audio not correlated
				if (pointIndex >= 0 && _track.getPoint(pointIndex).getAudio() != null) {
					pointIndex = -1;
				}
			}
		}
		else {
			// check if current point has audio or not
			if (currPoint != null && currPoint.getAudio() != null) {
				pointIndex = -1;
			}
		}
		// Has the new point got a photo?
		DataPoint selectedPoint = _track.getPoint(pointIndex);
		int photoIndex = _selection.getCurrentPhotoIndex();
		if (selectedPoint != null && selectedPoint.getPhoto() != null) {
			// New point has a photo, so select it
			photoIndex = _photoList.getPhotoIndex(selectedPoint.getPhoto());
		}
		else if (currPoint != null && selectedPoint != currPoint && currPoint.getPhoto() != null) {
			// Old point had a photo, so deselect it
			photoIndex = -1;
		}
		// give to selection object
		_selection.selectPointPhotoAudio(pointIndex, photoIndex, inAudioIndex);
	}


	/**
	 * 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);
		}
	}
}