X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FTrack.java;h=b28fd3642091cdc485e1a9130a72c3f2ecd14dac;hb=4d5796d02a15808311c09448d79e6e7d1de9d636;hp=08168d1fb6c348a43cc97eff367021b9c7241ab8;hpb=112bb0c9b46894adca9a33ed8c99ea712b253185;p=GpsPrune.git diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index 08168d1..b28fd36 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -2,7 +2,6 @@ package tim.prune.data; import java.util.List; -import tim.prune.Config; import tim.prune.UpdateMessageBroker; import tim.prune.function.edit.FieldEdit; import tim.prune.function.edit.FieldEditList; @@ -27,7 +26,6 @@ public class Track // Master field list private FieldList _masterFieldList = null; // variable ranges - private AltitudeRange _altitudeRange = null; private DoubleRange _latRange = null, _longRange = null; private DoubleRange _xRange = null, _yRange = null; @@ -46,6 +44,19 @@ public class Track _scaled = false; } + /** + * Constructor using fields and points from another Track + * @param inFieldList Field list from another Track object + * @param inPoints (edited) point array + */ + public Track(FieldList inFieldList, DataPoint[] inPoints) + { + _masterFieldList = inFieldList; + _dataPoints = inPoints; + if (_dataPoints == null) _dataPoints = new DataPoint[0]; + _numPoints = _dataPoints.length; + _scaled = false; + } /** * Load method, for initialising and reinitialising data @@ -101,6 +112,23 @@ public class Track _scaled = false; } + /** + * Request that a rescale be done to recalculate derived values + */ + public void requestRescale() + { + _scaled = false; + } + + /** + * Extend the track's field list with the given additional fields + * @param inFieldList list of fields to be added + */ + public void extendFieldList(FieldList inFieldList) + { + _masterFieldList = _masterFieldList.merge(inFieldList); + } + ////////////////// Modification methods ////////////////////// @@ -156,7 +184,7 @@ public class Track { DataPoint point = _dataPoints[i]; // Don't delete photo points - if (point.getPhoto() != null || !point.getDeleteFlag()) + if (point.hasMedia() || !point.getDeleteFlag()) { newPointArray[numCopied] = point; numCopied++; @@ -275,9 +303,10 @@ public class Track * @param inStart start of range * @param inEnd end of range * @param inOffset offset to add (-ve to subtract) + * @param inUndo true for undo operation * @return true on success */ - public boolean addTimeOffset(int inStart, int inEnd, long inOffset) + public boolean addTimeOffset(int inStart, int inEnd, long inOffset, boolean inUndo) { // sanity check if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) { @@ -293,6 +322,7 @@ public class Track // This point has a timestamp so add the offset to it foundTimestamp = true; timestamp.addOffset(inOffset); + _dataPoints[i].setModified(inUndo); } } return foundTimestamp; @@ -324,6 +354,7 @@ public class Track // This point has an altitude so add the offset to it foundAlt = true; alt.addOffset(inOffset, inFormat, inDecimals); + _dataPoints[i].setModified(false); } } // needs to be scaled again @@ -331,8 +362,6 @@ public class Track return foundAlt; } - // TODO: Function to collect and sort photo points by time or photo filename - // TODO: Function to convert waypoint names into timestamps /** * Collect all waypoints to the start or end of the track @@ -458,7 +487,7 @@ public class Track { // TODO: Move cut/move into separate function? // Check that indices make sense - if (inSectionStart > 0 && inSectionEnd > inSectionStart && inMoveTo >= 0 + if (inSectionStart >= 0 && inSectionEnd > inSectionStart && inMoveTo >= 0 && (inMoveTo < inSectionStart || inMoveTo > (inSectionEnd+1))) { // do the cut and move @@ -549,7 +578,7 @@ public class Track double latitudeDiff = 0.0, longitudeDiff = 0.0; double totalAltitude = 0; int numAltitudes = 0; - Altitude.Format altFormat = Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET; + Altitude.Format altFormat = Altitude.Format.NO_FORMAT; // loop between start and end points for (int i=inStartIndex; i<= inEndIndex; i++) { @@ -558,6 +587,9 @@ public class Track longitudeDiff += (currPoint.getLongitude().getDouble() - firstLongitude); if (currPoint.hasAltitude()) { totalAltitude += currPoint.getAltitude().getValue(altFormat); + // Use altitude format of first valid altitude + if (altFormat == Altitude.Format.NO_FORMAT) + altFormat = currPoint.getAltitude().getFormat(); numAltitudes++; } } @@ -612,16 +644,6 @@ public class Track return null; } - - /** - * @return altitude range of points as AltitudeRange object - */ - public AltitudeRange getAltitudeRange() - { - if (!_scaled) scalePoints(); - return _altitudeRange; - } - /** * @return the number of (valid) points in the track */ @@ -733,11 +755,14 @@ public class Track } /** - * @return true if track has altitude data (which are not all zero) + * @return true if track has altitude data */ public boolean hasAltitudeData() { - return getAltitudeRange().getMaximum() > 0; + for (int i=0; i<_numPoints; i++) { + if (_dataPoints[i].hasAltitude()) {return true;} + } + return false; } /** @@ -839,10 +864,9 @@ public class Track */ private void scalePoints() { - // Loop through all points in track, to see limits of lat, long and altitude + // Loop through all points in track, to see limits of lat, long _longRange = new DoubleRange(); _latRange = new DoubleRange(); - _altitudeRange = new AltitudeRange(); int p; _hasWaypoint = false; _hasTrackpoint = false; for (p=0; p < getNumPoints(); p++) @@ -852,10 +876,6 @@ public class Track { _longRange.addValue(point.getLongitude().getDouble()); _latRange.addValue(point.getLatitude().getDouble()); - if (point.getAltitude().isValid()) - { - _altitudeRange.addValue(point.getAltitude()); - } if (point.isWaypoint()) _hasWaypoint = true; else @@ -896,16 +916,21 @@ public class Track { int nearestPoint = 0; double nearestDist = -1.0; - double currDist; + double mDist, yDist; for (int i=0; i < getNumPoints(); i++) { if (!inJustTrackPoints || !_dataPoints[i].isWaypoint()) { - currDist = Math.abs(_xValues[i] - inX) + Math.abs(_yValues[i] - inY); - if (currDist < nearestDist || nearestDist < 0.0) + yDist = Math.abs(_yValues[i] - inY); + if (yDist < nearestDist || nearestDist < 0.0) { - nearestPoint = i; - nearestDist = currDist; + // y dist is within range, so check x too + mDist = yDist + getMinXDist(_xValues[i] - inX); + if (mDist < nearestDist || nearestDist < 0.0) + { + nearestPoint = i; + nearestDist = mDist; + } } } } @@ -917,6 +942,16 @@ public class Track return nearestPoint; } + /** + * @param inX x value of point + * @return minimum wrapped value + */ + private static final double getMinXDist(double inX) + { + // TODO: Can use some kind of floor here? + return Math.min(Math.min(Math.abs(inX), Math.abs(inX-1.0)), Math.abs(inX+1.0)); + } + /** * Get the next track point starting from the given index * @param inStartIndex index to start looking from @@ -945,6 +980,7 @@ public class Track */ public DataPoint getPreviousTrackPoint(int inStartIndex) { + // end index is given as _numPoints but actually it just counts down to -1 return getNextTrackPoint(inStartIndex, _numPoints, false); } @@ -1120,9 +1156,10 @@ public class Track * Edit the specified point * @param inPoint point to edit * @param inEditList list of edits to make + * @param inUndo true if undo operation, false otherwise * @return true if successful */ - public boolean editPoint(DataPoint inPoint, FieldEditList inEditList) + public boolean editPoint(DataPoint inPoint, FieldEditList inEditList, boolean inUndo) { if (inPoint != null && inEditList != null && inEditList.getNumEdits() > 0) { @@ -1134,7 +1171,7 @@ public class Track { FieldEdit edit = inEditList.getEdit(i); Field editField = edit.getField(); - inPoint.setFieldValue(editField, edit.getValue()); + inPoint.setFieldValue(editField, edit.getValue(), inUndo); // Check that master field list has this field already (maybe point name has been added) if (!_masterFieldList.contains(editField)) { _masterFieldList.extendList(editField); @@ -1156,4 +1193,18 @@ public class Track } return false; } + + /** + * @param inPoint point to check + * @return true if this track contains the given point + */ + public boolean containsPoint(DataPoint inPoint) + { + if (inPoint == null) return false; + for (int i=0; i < getNumPoints(); i++) + { + if (getPoint(i) == inPoint) return true; + } + return false; // not found + } }