File: RearrangeWaypointsFunction.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 (171 lines) | stat: -rw-r--r-- 4,713 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
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
package tim.prune.function;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.JOptionPane;

import tim.prune.App;
import tim.prune.I18nManager;
import tim.prune.cmd.PointReference;
import tim.prune.cmd.RearrangePointsCmd;
import tim.prune.data.Checker;
import tim.prune.data.DataPoint;
import tim.prune.data.SortMode;
import tim.prune.data.Track;


/**
 * Class to provide the function for rearranging waypoints
 */
public class RearrangeWaypointsFunction extends RearrangeFunction
{
	/**
	 * Constructor
	 * @param inApp app object
	 */
	public RearrangeWaypointsFunction(App inApp) {
		super(inApp, true);
	}

	/** Get the name key */
	public String getNameKey() {
		return "function.rearrangewaypoints";
	}

	/** Get whether sorting by time is allowed or not */
	protected boolean isSortByTimeAllowed() {
		return Checker.haveWaypointsGotTimestamps(_app.getTrackInfo().getTrack());
	}

	/** Get the description key */
	public String getDescriptionKey() {
		return "dialog.rearrangewaypoints.desc";
	}

	/** Sort by name key */
	protected String getSortNameKey() {
		return "sortbyname";
	}

	/**
	 * Perform the rearrange and sort according to the radio buttons
	 */
	protected void finish()
	{
		// Figure out what is required from the radio buttons
		Rearrange rearrangeOption = getRearrangeOption();
		SortMode sortOption = getSortMode();

		final List<PointReference> result;
		if (rearrangeOption == Rearrange.TO_START || rearrangeOption == Rearrange.TO_END)
		{
			// Collect the waypoints to the start or end of the track
			result = collectWaypoints(rearrangeOption, sortOption);
		}
		else
		{
			// Interleave the waypoints into track order
			result = interleaveWaypoints();
		}

		if (result == null || isResultANop(result)) {
			JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.rearrange.noop"),
					I18nManager.getText("error.function.noop.title"), JOptionPane.WARNING_MESSAGE);
		}
		else
		{
			RearrangePointsCmd command = RearrangePointsCmd.from(result);
			command.setDescription(getName());
			command.setConfirmText(I18nManager.getText("confirm.rearrangewaypoints"));
			_app.execute(command);
		}
	}


	/**
	 * Do the collection and sorting of the waypoints
	 * @param inRearrangeOption beginning or end
	 * @param inSortOption optional sort criterion
	 * @return list of point references
	 */
	private List<PointReference> collectWaypoints(Rearrange inRearrangeOption, SortMode inSortOption)
	{
		Track track = _app.getTrackInfo().getTrack();
		final int numPoints = track.getNumPoints();
		ArrayList<PointReference> waypoints = new ArrayList<>();
		ArrayList<PointReference> nonWaypoints = new ArrayList<>();
		boolean wayAfterNon = false, nonAfterWay = false;
		for (int i=0; i<numPoints; i++)
		{
			DataPoint point = track.getPoint(i);
			PointReference pointReference = new PointReference(i,
					inSortOption == SortMode.SORTBY_NAME ? point.getWaypointName() : null,
					inSortOption == SortMode.SORTBY_TIME ? point.getTimestamp() : null);
			if (point.isWaypoint())
			{
				waypoints.add(pointReference);
				wayAfterNon |= !nonWaypoints.isEmpty();
			}
			else
			{
				nonWaypoints.add(pointReference);
				nonAfterWay |= !waypoints.isEmpty();
			}
		}

		// Exit if the data is already in the specified order
		final boolean wpsToStart = (inRearrangeOption == Rearrange.TO_START);
		final boolean doSort = (inSortOption != SortMode.DONT_SORT);
		if (waypoints.isEmpty()
			|| (wpsToStart && !wayAfterNon && nonAfterWay && !doSort)
			|| (!wpsToStart && wayAfterNon && !nonAfterWay && !doSort)
			|| inRearrangeOption == Rearrange.TO_NEAREST)
		{
			return null;
		}
		// Note: it could still be that the rearrange and sort has no effect, but we don't know yet

		if (doSort) {
			Collections.sort(waypoints);
		}

		// Combine the two lists into a single one
		List<PointReference> result = new ArrayList<>();
		if (wpsToStart)
		{
			result.addAll(waypoints);
			result.addAll(nonWaypoints);
		}
		else
		{
			result.addAll(nonWaypoints);
			result.addAll(waypoints);
		}
		return result;
	}

	/**
	 * Interleave all waypoints by each nearest track point
	 * @return list of point references
	 */
	private List<PointReference> interleaveWaypoints()
	{
		Track track = _app.getTrackInfo().getTrack();
		final int numPoints = track.getNumPoints();
		ArrayList<PointReference> result = new ArrayList<>();
		for (int i=0; i<numPoints; i++)
		{
			DataPoint point = track.getPoint(i);
			if (point.isWaypoint()) {
				result.add(new PointReference(i, track.getNearestTrackPointIndex(i)));
			}
			else {
				result.add(new PointReference(i, i));
		}
		}
		Collections.sort(result);
		return result;
	}
}