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
|
package tim.prune.function.compress.methods;
import tim.prune.data.DataPoint;
import tim.prune.data.MarkingData;
import tim.prune.data.Track;
import tim.prune.function.compress.CompressionMethodType;
import tim.prune.function.compress.TrackDetails;
/** Parent class of all the compression methods */
public abstract class CompressionMethod
{
private boolean _active = false;
/**
* Preview the algorithm by counting the number of points deleted
* @param inTrack track object
* @param inDetails track details including span
* @param inMarkings information about deletion flags from previous algorithms
* @return number of points to be deleted by this algorithm
*/
public int preview(Track inTrack, TrackDetails inDetails, MarkingData inMarkings)
{
if (!_active) {
return 0;
}
TrackDetails modifiedDetails = inDetails.modifyUsingMarkings(inMarkings);
return compress(inTrack, modifiedDetails, inMarkings);
}
public void setActive(boolean inActive) {
_active = inActive;
}
public boolean isActive() {
return _active;
}
/**
* Perform the compression and set the results in the given array
* @param inTrack track object
* @param inDetails track details including span
* @param inMarkings information about deletion flags from previous algorithms
* @return number of points deleted by this algorithm
*/
public abstract int compress(Track inTrack, TrackDetails inDetails, MarkingData inMarkings);
/**
* @return String to save in Settings
*/
public String getTotalSettingsString() {
return (_active ? "x" : "o") + getSettingsString();
}
protected abstract String getSettingsString();
public abstract CompressionMethodType getType();
public abstract String getParam();
/** Construct a specific CompressionMethod from a string fragment */
public static CompressionMethod fromSettingsString(String inString)
{
if (inString == null || inString.isEmpty()) {
return null;
}
CompressionMethod method = fromSettingsSubstring(inString.substring(1));
if (method != null) {
method.setActive(inString.charAt(0) == 'x');
}
return method;
}
private static CompressionMethod fromSettingsSubstring(String inString)
{
if (inString == null || inString.length() < 3) {
return null;
}
if (DuplicatesMethod.recogniseString(inString)) {
return new DuplicatesMethod();
}
if (NearbyFactorMethod.recogniseString(inString)) {
return new NearbyFactorMethod(inString);
}
if (WackyPointsMethod.recogniseString(inString)) {
return new WackyPointsMethod(inString);
}
if (SingletonsMethod.recogniseString(inString)) {
return new SingletonsMethod(inString);
}
if (DouglasPeuckerMethod.recogniseString(inString)) {
return new DouglasPeuckerMethod(inString);
}
if (NearbyDistMethod.recogniseString(inString)) {
return new NearbyDistMethod(inString);
}
if (TooSlowMethod.recogniseString(inString)) {
return new TooSlowMethod(inString);
}
if (TooFastMethod.recogniseString(inString)) {
return new TooFastMethod(inString);
}
if (TooSoonMethod.recogniseString(inString)) {
return new TooSoonMethod(inString);
}
if (SkiLiftsMethod.recogniseString(inString)) {
return new SkiLiftsMethod();
}
return null;
}
protected static boolean recogniseString(String inString, CompressionMethodType inType) {
return inString != null && inString.startsWith(inType.getKey());
}
public static boolean isPointDeleted(int inIndex, MarkingData inMarkings) {
return inMarkings != null && inMarkings.isPointMarkedForDeletion(inIndex);
}
public static boolean isPointAtSegmentBoundary(int inIndex, TrackDetails inDetails, MarkingData inMarkings)
{
if (inDetails != null && (inDetails.isSegmentStart(inIndex) || inDetails.isSegmentEnd(inIndex))) {
return true;
}
// Maybe it wasn't a segment boundary before but due to the deletion flags it now is
for (int i=inIndex - 1; i >= 0; i--)
{
if (isPointDeleted(i, inMarkings))
{
if (inMarkings.isPointMarkedForSegmentBreak(i)) {
return true;
}
}
else if (!inDetails.isWaypoint(i))
{
// Found a track point before our point, so our point isn't the start
return false;
}
}
// Couldn't find any points
return true;
}
protected static DataPoint getNextTrackPoint(Track inTrack, int inIndex, MarkingData inMarkings)
{
int index = inIndex + 1;
while (index < inTrack.getNumPoints())
{
DataPoint point = inTrack.getPoint(index);
if (!point.isWaypoint() && !inMarkings.isPointMarkedForDeletion(index)) {
return point;
}
index++;
}
return null;
}
}
|