X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FTrack.java;h=63cd01faaf488028085a6712c5648ad9ffa8ea1d;hb=f1b92378a792131ac8fb33a869405851d5b2d1f7;hp=df51e8f27e3c8963189b664adefc7534861188ea;hpb=54b9d8bc8f0025ccf97a67d9dd217ef1f9cf082f;p=GpsPrune.git diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index df51e8f..63cd01f 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -2,8 +2,8 @@ package tim.prune.data; import java.util.List; -import tim.prune.Config; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; import tim.prune.function.edit.FieldEdit; import tim.prune.function.edit.FieldEditList; import tim.prune.gui.map.MapUtils; @@ -22,7 +22,8 @@ public class Track private double[] _yValues = null; private boolean _scaled = false; private int _numPoints = 0; - private boolean _mixedData = false; + private boolean _hasTrackpoint = false; + private boolean _hasWaypoint = false; // Master field list private FieldList _masterFieldList = null; // variable ranges @@ -45,6 +46,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 @@ -100,6 +114,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 ////////////////////// @@ -154,8 +185,8 @@ public class Track for (int i=0; i<_numPoints; i++) { DataPoint point = _dataPoints[i]; - // Don't delete waypoints or photo points - if (point.isWaypoint() || point.getPhoto() != null || !point.getDeleteFlag()) + // Don't delete photo points + if (point.hasMedia() || !point.getDeleteFlag()) { newPointArray[numCopied] = point; numCopied++; @@ -274,9 +305,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) { @@ -292,37 +324,47 @@ 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; } - /** - * Merge the track segments within the given range - * @param inStart start index - * @param inEnd end index - * @return true if successful + * Add the given altitude offset to the specified range + * @param inStart start of range + * @param inEnd end of range + * @param inOffset offset to add (-ve to subtract) + * @param inFormat altitude format of offset + * @param inDecimals number of decimal places in offset + * @return true on success */ - public boolean mergeTrackSegments(int inStart, int inEnd) + public boolean addAltitudeOffset(int inStart, int inEnd, double inOffset, + Altitude.Format inFormat, int inDecimals) { - boolean firstTrackPoint = true; - // Loop between start and end - for (int i=inStart; i<=inEnd; i++) { - DataPoint point = getPoint(i); - // Set all segments to false apart from first track point - if (point != null && !point.isWaypoint()) { - point.setSegmentStart(firstTrackPoint); - firstTrackPoint = false; + // sanity check + if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) { + return false; + } + boolean foundAlt = false; + // Loop over all points within range + for (int i=inStart; i<=inEnd; i++) + { + Altitude alt = _dataPoints[i].getAltitude(); + if (alt != null && alt.isValid()) + { + // This point has an altitude so add the offset to it + foundAlt = true; + alt.addOffset(inOffset, inFormat, inDecimals); + _dataPoints[i].setModified(false); } } - // Find following track point, if any - DataPoint nextPoint = getNextTrackPoint(inEnd+1); - if (nextPoint != null) {nextPoint.setSegmentStart(true);} - UpdateMessageBroker.informSubscribers(); - return true; + // needs to be scaled again + _scaled = false; + return foundAlt; } + /** * Collect all waypoints to the start or end of the track * @param inAtStart true to collect at start, false for end @@ -445,8 +487,9 @@ public class Track */ public boolean cutAndMoveSection(int inSectionStart, int inSectionEnd, int inMoveTo) { + // 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 @@ -457,30 +500,34 @@ public class Track { int sectionLength = inSectionEnd - inSectionStart + 1; // move section to earlier point - if (inMoveTo > 0) + if (inMoveTo > 0) { System.arraycopy(_dataPoints, 0, newPointArray, 0, inMoveTo); // unchanged points before + } System.arraycopy(_dataPoints, inSectionStart, newPointArray, inMoveTo, sectionLength); // moved bit // after insertion point, before moved bit - if (inSectionStart > (inMoveTo + 1)) - System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo + sectionLength, inSectionStart - inMoveTo); + System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo + sectionLength, inSectionStart - inMoveTo); // after moved bit - if (inSectionEnd < (_numPoints - 1)) + if (inSectionEnd < (_numPoints - 1)) { System.arraycopy(_dataPoints, inSectionEnd+1, newPointArray, inSectionEnd+1, _numPoints - inSectionEnd - 1); + } } else { // Move section to later point - if (inSectionStart > 0) + if (inSectionStart > 0) { System.arraycopy(_dataPoints, 0, newPointArray, 0, inSectionStart); // unchanged points before + } // from end of section to move to point - if (inMoveTo > (inSectionEnd + 1)) + if (inMoveTo > (inSectionEnd + 1)) { System.arraycopy(_dataPoints, inSectionEnd+1, newPointArray, inSectionStart, inMoveTo - inSectionEnd - 1); + } // moved bit System.arraycopy(_dataPoints, inSectionStart, newPointArray, inSectionStart + inMoveTo - inSectionEnd - 1, inSectionEnd - inSectionStart + 1); // unchanged bit after - if (inSectionEnd < (_numPoints - 1)) + if (inSectionEnd < (_numPoints - 1)) { System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo, _numPoints - inMoveTo); + } } // Copy array references _dataPoints = newPointArray; @@ -533,7 +580,7 @@ public class Track double latitudeDiff = 0.0, longitudeDiff = 0.0; double totalAltitude = 0; int numAltitudes = 0; - Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET; + Altitude.Format altFormat = Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET; // loop between start and end points for (int i=inStartIndex; i<= inEndIndex; i++) { @@ -605,6 +652,7 @@ public class Track if (!_scaled) scalePoints(); return _altitudeRange; } + /** * @return the number of (valid) points in the track */ @@ -684,6 +732,8 @@ public class Track */ public boolean hasData(Field inField) { + // Don't use this method for altitudes + if (inField.equals(Field.ALTITUDE)) {return hasAltitudeData();} return hasData(inField, 0, _numPoints-1); } @@ -713,14 +763,33 @@ public class Track return false; } + /** + * @return true if track has altitude data + */ + public boolean hasAltitudeData() + { + for (int i=0; i<_numPoints; i++) { + if (_dataPoints[i].hasAltitude()) {return true;} + } + return false; + } + + /** + * @return true if track contains at least one trackpoint + */ + public boolean hasTrackPoints() + { + if (!_scaled) scalePoints(); + return _hasTrackpoint; + } /** - * @return true if track contains waypoints and trackpoints + * @return true if track contains waypoints */ - public boolean hasMixedData() + public boolean hasWaypoints() { if (!_scaled) scalePoints(); - return _mixedData; + return _hasWaypoint; } /** @@ -809,7 +878,7 @@ public class Track _latRange = new DoubleRange(); _altitudeRange = new AltitudeRange(); int p; - boolean hasWaypoint = false, hasTrackpoint = false; + _hasWaypoint = false; _hasTrackpoint = false; for (p=0; p < getNumPoints(); p++) { DataPoint point = getPoint(p); @@ -822,12 +891,11 @@ public class Track _altitudeRange.addValue(point.getAltitude()); } if (point.isWaypoint()) - hasWaypoint = true; + _hasWaypoint = true; else - hasTrackpoint = true; + _hasTrackpoint = true; } } - _mixedData = hasWaypoint && hasTrackpoint; // Loop over points and calculate scales _xValues = new double[getNumPoints()]; @@ -911,6 +979,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); } @@ -1086,9 +1155,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) { @@ -1099,10 +1169,15 @@ public class Track for (int i=0; i