File: InterpolateTimestamps.java

package info (click to toggle)
gpsprune 26.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,824 kB
  • sloc: java: 52,154; sh: 25; makefile: 21; python: 15
file content (122 lines) | stat: -rw-r--r-- 3,741 bytes parent folder | download | duplicates (4)
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
package tim.prune.function;

import tim.prune.App;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
import tim.prune.cmd.EditSingleFieldCmd;
import tim.prune.data.*;
import tim.prune.function.edit.PointEdit;

import java.util.ArrayList;

public class InterpolateTimestamps extends GenericFunction
{
	private final ArrayList<PointEdit> _edits = new ArrayList<>();


	public InterpolateTimestamps(App inApp) {
		super(inApp);
	}

	/** Execute the function on the selected range */
	public void begin()
	{
		_edits.clear();
		double distanceSoFar = 0.0;
		ArrayList<IndexAndDistance> pointList = new ArrayList<>();
		final int selStart = _app.getTrackInfo().getSelection().getStart();
		final int selEnd = _app.getTrackInfo().getSelection().getEnd();
		if (selStart < 0 || selEnd <= selStart) {
			return;
		}

		DataPoint fromPoint = null;
		DataPoint latestPoint = null;
		for (int i=selStart; i<=selEnd; i++)
		{
			DataPoint point = _app.getTrackInfo().getTrack().getPoint(i);
			if (point.isWaypoint()) {
				continue;
			}
			if (point.getSegmentStart())
			{
				pointList.clear();
				fromPoint = null;
			}
			if (point.hasTimestamp())
			{
				if (fromPoint != null && !pointList.isEmpty())
				{
				   distanceSoFar += distanceBetween(latestPoint, point);
				   processPointList(pointList, distanceSoFar,
						fromPoint.getTimestamp(), point.getTimestamp());
				}
				fromPoint = point;
				pointList.clear();
				distanceSoFar = 0.0;
			}
			else if (fromPoint != null)
			{
				distanceSoFar += distanceBetween(latestPoint, point);
				pointList.add(new IndexAndDistance(i, distanceSoFar));
			}
			latestPoint = point;
		}

		if (_edits.isEmpty()) {
			_app.showErrorMessage(getNameKey(), "error.interpolatetimestamps.notpossible");
		}
		else
		{
			EditSingleFieldCmd command = new EditSingleFieldCmd(Field.TIMESTAMP, _edits, null);
			command.setDescription(I18nManager.getText("undo.applytimestamps"));
			command.setConfirmText(I18nManager.getText("confirm.applytimestamps"));
			_app.execute(command);
		}
	}

	/**
	 * Handle a range of points without timestamps
	 * @param inPointList list of point indexes and their distances
	 * @param inTotalDistance total distance between the two end points
	 * @param inStartTimestamp timestamp of point before the range
	 * @param inEndTimestamp timestamp of point after the range
	 */
	private void processPointList(ArrayList<IndexAndDistance> inPointList, double inTotalDistance,
								  Timestamp inStartTimestamp, Timestamp inEndTimestamp)
	{
		for (IndexAndDistance idxDist : inPointList)
		{
			final double fraction = idxDist._distance / inTotalDistance;
			final long millisAfter = (long) (inEndTimestamp.getMillisecondsSince(inStartTimestamp) * fraction);
			Timestamp stamp = inStartTimestamp.addOffsetMilliseconds(millisAfter);
			String stampText = stamp.getText(Timestamp.Format.ISO8601, null);
			_edits.add(new PointEdit(idxDist._pointIndex, stampText));
		}
	}

	/** @return the distance between two points */
	private static double distanceBetween(DataPoint inPoint1, DataPoint inPoint2)
	{
		double radians = DataPoint.calculateRadiansBetween(inPoint1, inPoint2);
		return Distance.convertRadiansToDistance(radians, UnitSetLibrary.UNITS_METRES);
	}

	public String getNameKey() {
		return "function.interpolatetimestamps";
	}


	/** Inner class to hold points and distances in a list */
	private static class IndexAndDistance
	{
		private final int _pointIndex;
		private final double _distance;

		private IndexAndDistance(int inIndex, double inDistance)
		{
			_pointIndex = inIndex;
			_distance = inDistance;
		}
	}
}