X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FTrack.java;h=f45854a0e3d47a1fd5fc0ee6924732b3294decc0;hb=92dad5df664287acb51728e9ea599f150765d34a;hp=f6ad709b05e3bde338749607e3526426e85b3a9a;hpb=63f178fd6c6b30b99a01f2a2d700963ea2dfef8b;p=GpsPrune.git diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index f6ad709..f45854a 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -3,8 +3,9 @@ package tim.prune.data; import java.util.List; import tim.prune.UpdateMessageBroker; -import tim.prune.edit.FieldEdit; -import tim.prune.edit.FieldEditList; +import tim.prune.function.edit.FieldEdit; +import tim.prune.function.edit.FieldEditList; +import tim.prune.gui.map.MapUtils; /** @@ -13,8 +14,6 @@ import tim.prune.edit.FieldEditList; */ public class Track { - // Broker object - UpdateMessageBroker _broker = null; // Data points private DataPoint[] _dataPoints = null; // Scaled x, y values @@ -22,22 +21,20 @@ 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 - private AltitudeRange _altitudeRange = null; private DoubleRange _latRange = null, _longRange = null; private DoubleRange _xRange = null, _yRange = null; /** * Constructor for empty track - * @param inBroker message broker object */ - public Track(UpdateMessageBroker inBroker) + public Track() { - _broker = inBroker; // create field list _masterFieldList = new FieldList(null); // make empty DataPoint array @@ -47,14 +44,27 @@ 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 * @param inFieldArray array of Field objects describing fields * @param inPointArray 2d object array containing data - * @param inAltFormat altitude format + * @param inOptions load options such as units */ - public void load(Field[] inFieldArray, Object[][] inPointArray, int inAltFormat) + public void load(Field[] inFieldArray, Object[][] inPointArray, PointCreateOptions inOptions) { if (inFieldArray == null || inPointArray == null) { @@ -71,25 +81,65 @@ public class Track { dataArray = (String[]) inPointArray[p]; // Convert to DataPoint objects - DataPoint point = new DataPoint(dataArray, _masterFieldList, inAltFormat); + DataPoint point = new DataPoint(dataArray, _masterFieldList, inOptions); if (point.isValid()) { _dataPoints[pointIndex] = point; pointIndex++; } + else + { + // TODO: Maybe report this somehow? + // System.out.println("point is not valid!"); + } } _numPoints = pointIndex; + // Set first track point to be start of segment + DataPoint firstTrackPoint = getNextTrackPoint(0); + if (firstTrackPoint != null) { + firstTrackPoint.setSegmentStart(true); + } // needs to be scaled _scaled = false; } + /** + * Load the track by transferring the contents from a loaded Track object + * @param inOther Track object containing loaded data + */ + public void load(Track inOther) + { + _numPoints = inOther._numPoints; + _masterFieldList = inOther._masterFieldList; + _dataPoints = inOther._dataPoints; + // needs to be scaled + _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 ////////////////////// /** * Combine this Track with new data - * @param inOtherTrack + * @param inOtherTrack other track to combine */ public void combine(Track inOtherTrack) { @@ -106,7 +156,7 @@ public class Track // needs to be scaled again _scaled = false; // inform listeners - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); } @@ -121,55 +171,37 @@ public class Track _numPoints = inNewSize; // needs to be scaled again _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); } } /** - * Compress the track to the given resolution - * @param inResolution resolution + * Delete the points marked for deletion + * @param inSplitSegments true to split segments at deleted points * @return number of points deleted */ - public int compress(int inResolution) + public int deleteMarkedPoints(boolean inSplitSegments) { - // (maybe should be separate thread?) - // (maybe should be in separate class?) - // (maybe should be based on subtended angles instead of distances?) - - if (inResolution <= 0) return 0; int numCopied = 0; - // Establish range of track and minimum range between points - scalePoints(); - double wholeScale = _xRange.getMaximum() - _xRange.getMinimum(); - double yscale = _yRange.getMaximum() - _yRange.getMinimum(); - if (yscale > wholeScale) wholeScale = yscale; - double minDist = wholeScale / inResolution; - - // Copy selected points + // Copy selected points into a new point array DataPoint[] newPointArray = new DataPoint[_numPoints]; - int[] pointIndices = new int[_numPoints]; + boolean prevPointDeleted = false; for (int i=0; i<_numPoints; i++) { - boolean keepPoint = true; - // Don't delete waypoints or photo points - if (!_dataPoints[i].isWaypoint() && _dataPoints[i].getPhoto() == null) + DataPoint point = _dataPoints[i]; + // Don't delete photo points + if (point.hasMedia() || !point.getDeleteFlag()) { - // go through newPointArray to check for range - for (int j=0; j 0) - { - // Make new resized array and copy DataPoints over - DataPoint[] newPointArray = new DataPoint[_numPoints - numDupes]; - j = 0; - for (i=0; i<_numPoints; i++) - { - if (!dupes[i]) - { - newPointArray[j] = _dataPoints[i]; - j++; - } - } - // Copy array references - _dataPoints = newPointArray; - _numPoints = _dataPoints.length; - _scaled = false; - } - return numDupes; - } - - /** * Reverse the specified range of points * @param inStart start index @@ -324,65 +298,82 @@ public class Track _dataPoints[inStart + i] = _dataPoints[inEnd - i]; _dataPoints[inEnd - i] = p; } + // adjust segment starts + shiftSegmentStarts(inStart, inEnd); + // Find first track point and following track point, and set segment starts to true + DataPoint firstTrackPoint = getNextTrackPoint(inStart); + if (firstTrackPoint != null) {firstTrackPoint.setSegmentStart(true);} + DataPoint nextTrackPoint = getNextTrackPoint(inEnd+1); + if (nextTrackPoint != null) {nextTrackPoint.setSegmentStart(true);} // needs to be scaled again _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); return true; } /** - * Collect all waypoints to the start or end of the track - * @param inAtStart true to collect at start, false for end - * @return true if successful, false if no change + * Add the given time offset to the specified range + * @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 collectWaypoints(boolean inAtStart) + public boolean addTimeOffsetSeconds(int inStart, int inEnd, long inOffset, boolean inUndo) { - // Check for mixed data, numbers of waypoints & nons - int numWaypoints = 0, numNonWaypoints = 0; - boolean wayAfterNon = false, nonAfterWay = false; - DataPoint[] waypoints = new DataPoint[_numPoints]; - DataPoint[] nonWaypoints = new DataPoint[_numPoints]; - DataPoint point = null; - for (int i=0; i<_numPoints; i++) + // sanity check + if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) { + return false; + } + boolean foundTimestamp = false; + // Loop over all points within range + for (int i=inStart; i<=inEnd; i++) { - point = _dataPoints[i]; - if (point.isWaypoint()) + DataPoint p = _dataPoints[i]; + if (p != null && p.hasTimestamp()) { - waypoints[numWaypoints] = point; - numWaypoints++; - wayAfterNon |= (numNonWaypoints > 0); - } - else - { - nonWaypoints[numNonWaypoints] = point; - numNonWaypoints++; - nonAfterWay |= (numWaypoints > 0); + // This point has a timestamp so add the offset to it + foundTimestamp = true; + p.addTimeOffsetSeconds(inOffset); + p.setModified(inUndo); } } - // Exit if the data is already in the specified order - if (numWaypoints == 0 || numNonWaypoints == 0 - || (inAtStart && !wayAfterNon && nonAfterWay) - || (!inAtStart && wayAfterNon && !nonAfterWay)) - { - return false; - } + return foundTimestamp; + } - // Copy the arrays back into _dataPoints in the specified order - if (inAtStart) - { - System.arraycopy(waypoints, 0, _dataPoints, 0, numWaypoints); - System.arraycopy(nonWaypoints, 0, _dataPoints, numWaypoints, numNonWaypoints); + /** + * 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 inUnit altitude unit of offset + * @param inDecimals number of decimal places in offset + * @return true on success + */ + public boolean addAltitudeOffset(int inStart, int inEnd, double inOffset, + Unit inUnit, int inDecimals) + { + // sanity check + if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) { + return false; } - else + boolean foundAlt = false; + // Loop over all points within range + for (int i=inStart; i<=inEnd; i++) { - System.arraycopy(nonWaypoints, 0, _dataPoints, 0, numNonWaypoints); - System.arraycopy(waypoints, 0, _dataPoints, numNonWaypoints, numWaypoints); + DataPoint p = _dataPoints[i]; + if (p != null && p.hasAltitude()) + { + // This point has an altitude so add the offset to it + foundAlt = true; + p.addAltitudeOffset(inOffset, inUnit, inDecimals); + p.setModified(false); + } } // needs to be scaled again _scaled = false; - _broker.informSubscribers(); - return true; + return foundAlt; } @@ -439,11 +430,71 @@ public class Track _dataPoints = dataCopy; // needs to be scaled again to recalc x, y _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); return true; } + /** + * Cut and move the specified section + * @param inSectionStart start index of section + * @param inSectionEnd end index of section + * @param inMoveTo index of move to point + * @return true if move successful + */ + 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 + && (inMoveTo < inSectionStart || inMoveTo > (inSectionEnd+1))) + { + // do the cut and move + DataPoint[] newPointArray = new DataPoint[_numPoints]; + // System.out.println("Cut/move section (" + inSectionStart + " - " + inSectionEnd + ") to before point " + inMoveTo); + // Is it a forward copy or a backward copy? + if (inSectionStart > inMoveTo) + { + int sectionLength = inSectionEnd - inSectionStart + 1; + // move section to earlier point + 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 + System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo + sectionLength, inSectionStart - inMoveTo); + // after moved bit + if (inSectionEnd < (_numPoints - 1)) { + System.arraycopy(_dataPoints, inSectionEnd+1, newPointArray, inSectionEnd+1, _numPoints - inSectionEnd - 1); + } + } + else + { + // Move section to later point + 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)) { + 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)) { + System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo, _numPoints - inMoveTo); + } + } + // Copy array references + _dataPoints = newPointArray; + _scaled = false; + return true; + } + return false; + } + + /** * Interpolate extra points between two selected ones * @param inStartIndex start index of interpolation @@ -468,6 +519,59 @@ public class Track } + /** + * Average selected points + * @param inStartIndex start index of selection + * @param inEndIndex end index of selection + * @return true if successful + */ + public boolean average(int inStartIndex, int inEndIndex) + { + // check parameters + if (inStartIndex < 0 || inStartIndex >= _numPoints || inEndIndex <= inStartIndex) + return false; + + DataPoint startPoint = getPoint(inStartIndex); + double firstLatitude = startPoint.getLatitude().getDouble(); + double firstLongitude = startPoint.getLongitude().getDouble(); + double latitudeDiff = 0.0, longitudeDiff = 0.0; + double totalAltitude = 0; + int numAltitudes = 0; + Unit altUnit = null; + // loop between start and end points + for (int i=inStartIndex; i<= inEndIndex; i++) + { + DataPoint currPoint = getPoint(i); + latitudeDiff += (currPoint.getLatitude().getDouble() - firstLatitude); + longitudeDiff += (currPoint.getLongitude().getDouble() - firstLongitude); + if (currPoint.hasAltitude()) + { + totalAltitude += currPoint.getAltitude().getValue(altUnit); + // Use altitude format of first valid altitude + if (altUnit == null) + altUnit = currPoint.getAltitude().getUnit(); + numAltitudes++; + } + } + int numPoints = inEndIndex - inStartIndex + 1; + double meanLatitude = firstLatitude + (latitudeDiff / numPoints); + double meanLongitude = firstLongitude + (longitudeDiff / numPoints); + Altitude meanAltitude = null; + if (numAltitudes > 0) { + meanAltitude = new Altitude((int) (totalAltitude / numAltitudes), altUnit); + } + + DataPoint insertedPoint = new DataPoint(new Latitude(meanLatitude, Coordinate.FORMAT_DECIMAL_FORCE_POINT), + new Longitude(meanLongitude, Coordinate.FORMAT_DECIMAL_FORCE_POINT), meanAltitude); + // Make into singleton + insertedPoint.setSegmentStart(true); + DataPoint nextPoint = getNextTrackPoint(inEndIndex+1); + if (nextPoint != null) {nextPoint.setSegmentStart(true);} + // Insert points into track + return insertRange(new DataPoint[] {insertedPoint}, inEndIndex + 1); + } + + /** * Append the specified points to the end of the track * @param inPoints DataPoint objects to add @@ -481,7 +585,7 @@ public class Track } // needs to be scaled again to recalc x, y _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); } @@ -502,15 +606,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 */ @@ -524,7 +619,7 @@ public class Track */ public DoubleRange getXRange() { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _xRange; } @@ -533,7 +628,7 @@ public class Track */ public DoubleRange getYRange() { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _yRange; } @@ -542,7 +637,7 @@ public class Track */ public DoubleRange getLatRange() { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _latRange; } /** @@ -550,7 +645,7 @@ public class Track */ public DoubleRange getLonRange() { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _longRange; } @@ -560,7 +655,7 @@ public class Track */ public double getX(int inPointNum) { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _xValues[inPointNum]; } @@ -570,7 +665,7 @@ public class Track */ public double getY(int inPointNum) { - if (!_scaled) scalePoints(); + if (!_scaled) {scalePoints();} return _yValues[inPointNum]; } @@ -590,6 +685,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); } @@ -603,32 +700,86 @@ public class Track */ public boolean hasData(Field inField, int inStart, int inEnd) { + // Loop over selected point range for (int i=inStart; i<=inEnd; i++) { if (_dataPoints[i].getFieldValue(inField) != null) { - return true; + // Check altitudes and timestamps + if ((inField != Field.ALTITUDE || _dataPoints[i].getAltitude().isValid()) + && (inField != Field.TIMESTAMP || _dataPoints[i].getTimestamp().isValid())) + { + return true; + } } } 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 + */ + public boolean hasWaypoints() + { + if (!_scaled) {scalePoints();} + return _hasWaypoint; + } /** - * @return true if track contains waypoints and trackpoints + * @return true if track contains any points marked for deletion */ - public boolean hasMixedData() + public boolean hasMarkedPoints() { - if (!_scaled) scalePoints(); - return _mixedData; + if (_numPoints < 1) { + return false; + } + // Loop over points looking for any marked for deletion + for (int i=0; i<=_numPoints-1; i++) + { + if (_dataPoints[i] != null && _dataPoints[i].getDeleteFlag()) { + return true; + } + } + // None found + return false; } + /** + * Clear all the deletion markers + */ + public void clearDeletionMarkers() + { + for (int i=0; i<_numPoints; i++) + { + _dataPoints[i].setMarkedForDeletion(false); + } + } /** * Collect all the waypoints into the given List * @param inList List to fill with waypoints */ - public void getWaypoints(List inList) + public void getWaypoints(List inList) { // clear list inList.clear(); @@ -673,14 +824,13 @@ public class Track * Scale all the points in the track to gain x and y values * ready for plotting */ - private void scalePoints() + private synchronized 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; - boolean hasWaypoint = false, hasTrackpoint = false; + _hasWaypoint = false; _hasTrackpoint = false; for (p=0; p < getNumPoints(); p++) { DataPoint point = getPoint(p); @@ -688,22 +838,12 @@ 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; + _hasWaypoint = true; else - hasTrackpoint = true; + _hasTrackpoint = true; } } - _mixedData = hasWaypoint && hasTrackpoint; - - // Use medians to centre at 0 - double longMedian = (_longRange.getMaximum() + _longRange.getMinimum()) / 2.0; - double latMedian = (_latRange.getMaximum() + _latRange.getMinimum()) / 2.0; - double longFactor = Math.cos(latMedian / 180.0 * Math.PI); // Function of median latitude // Loop over points and calculate scales _xValues = new double[getNumPoints()]; @@ -715,9 +855,9 @@ public class Track DataPoint point = getPoint(p); if (point != null) { - _xValues[p] = (point.getLongitude().getDouble() - longMedian) * longFactor; + _xValues[p] = MapUtils.getXFromLongitude(point.getLongitude().getDouble()); _xRange.addValue(_xValues[p]); - _yValues[p] = (point.getLatitude().getDouble() - latMedian); + _yValues[p] = MapUtils.getYFromLatitude(point.getLatitude().getDouble()); _yRange.addValue(_yValues[p]); } } @@ -738,16 +878,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; + } } } } @@ -759,6 +904,95 @@ public class Track return nearestPoint; } + /** + * @param inX x value of point + * @return minimum wrapped value + */ + private static final double getMinXDist(double inX) + { + // TODO: Should be abs(mod(inX-0.5,1)-0.5) - means two adds, one mod, one abs instead of two adds, 3 abss and two compares + 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 + * @return next track point, or null if end of data reached + */ + public DataPoint getNextTrackPoint(int inStartIndex) + { + return getNextTrackPoint(inStartIndex, _numPoints, true); + } + + /** + * Get the next track point in the given range + * @param inStartIndex index to start looking from + * @param inEndIndex index to stop looking + * @return next track point, or null if end of data reached + */ + public DataPoint getNextTrackPoint(int inStartIndex, int inEndIndex) + { + return getNextTrackPoint(inStartIndex, inEndIndex, true); + } + + /** + * Get the previous track point starting from the given index + * @param inStartIndex index to start looking from + * @return next track point, or null if end of data reached + */ + public DataPoint getPreviousTrackPoint(int inStartIndex) + { + // end index is given as _numPoints but actually it just counts down to -1 + return getNextTrackPoint(inStartIndex, _numPoints, false); + } + + /** + * Get the next track point starting from the given index + * @param inStartIndex index to start looking from + * @param inEndIndex index to stop looking (inclusive) + * @param inCountUp true for next, false for previous + * @return next track point, or null if end of data reached + */ + private DataPoint getNextTrackPoint(int inStartIndex, int inEndIndex, boolean inCountUp) + { + // Loop forever over points + int increment = inCountUp?1:-1; + for (int i=inStartIndex; i<=inEndIndex; i+=increment) + { + DataPoint point = getPoint(i); + // Exit if end of data reached - there wasn't a track point + if (point == null) {return null;} + if (point.isValid() && !point.isWaypoint()) { + // next track point found + return point; + } + } + return null; + } + + /** + * Shift all the segment start flags in the given range by 1 + * Method used by reverse range and its undo + * @param inStartIndex start of range, inclusive + * @param inEndIndex end of range, inclusive + */ + public void shiftSegmentStarts(int inStartIndex, int inEndIndex) + { + boolean prevFlag = true; + boolean currFlag = true; + for (int i=inStartIndex; i<= inEndIndex; i++) + { + DataPoint point = getPoint(i); + if (point != null && !point.isWaypoint()) + { + // remember flag + currFlag = point.getSegmentStart(); + // shift flag by 1 + point.setSegmentStart(prevFlag); + prevFlag = currFlag; + } + } + } ////////////////// Cloning and replacing /////////////////// @@ -824,7 +1058,7 @@ public class Track _numPoints++; // needs to be scaled again _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); return true; } @@ -857,7 +1091,7 @@ public class Track _numPoints += inPoints.length; // needs to be scaled again _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); return true; } @@ -875,7 +1109,7 @@ public class Track _dataPoints = inContents; _numPoints = _dataPoints.length; _scaled = false; - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); return true; } @@ -884,9 +1118,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) { @@ -897,22 +1132,41 @@ public class Track for (int i=0; i