]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/data/Track.java
Version 19, May 2018
[GpsPrune.git] / tim / prune / data / Track.java
index 63cd01faaf488028085a6712c5648ad9ffa8ea1d..f45854a0e3d47a1fd5fc0ee6924732b3294decc0 100644 (file)
@@ -3,7 +3,6 @@ package tim.prune.data;
 import java.util.List;
 
 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;
@@ -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;
 
@@ -64,9 +62,9 @@ public class Track
         * 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, Altitude.Format inAltFormat)
+       public void load(Field[] inFieldArray, Object[][] inPointArray, PointCreateOptions inOptions)
        {
                if (inFieldArray == null || inPointArray == null)
                {
@@ -83,12 +81,17 @@ 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
@@ -175,21 +178,30 @@ public class Track
 
        /**
         * Delete the points marked for deletion
+        * @param inSplitSegments true to split segments at deleted points
         * @return number of points deleted
         */
-       public int deleteMarkedPoints()
+       public int deleteMarkedPoints(boolean inSplitSegments)
        {
                int numCopied = 0;
-               // Copy selected points
+               // Copy selected points into a new point array
                DataPoint[] newPointArray = new DataPoint[_numPoints];
+               boolean prevPointDeleted = false;
                for (int i=0; i<_numPoints; i++)
                {
                        DataPoint point = _dataPoints[i];
                        // Don't delete photo points
                        if (point.hasMedia() || !point.getDeleteFlag())
                        {
+                               if (prevPointDeleted && inSplitSegments) {
+                                       point.setSegmentStart(true);
+                               }
                                newPointArray[numCopied] = point;
                                numCopied++;
+                               prevPointDeleted = false;
+                       }
+                       else {
+                               prevPointDeleted = true;
                        }
                }
 
@@ -308,7 +320,7 @@ public class Track
         * @param inUndo true for undo operation
         * @return true on success
         */
-       public boolean addTimeOffset(int inStart, int inEnd, long inOffset, boolean inUndo)
+       public boolean addTimeOffsetSeconds(int inStart, int inEnd, long inOffset, boolean inUndo)
        {
                // sanity check
                if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) {
@@ -318,13 +330,13 @@ public class Track
                // Loop over all points within range
                for (int i=inStart; i<=inEnd; i++)
                {
-                       Timestamp timestamp = _dataPoints[i].getTimestamp();
-                       if (timestamp != null)
+                       DataPoint p = _dataPoints[i];
+                       if (p != null && p.hasTimestamp())
                        {
                                // This point has a timestamp so add the offset to it
                                foundTimestamp = true;
-                               timestamp.addOffset(inOffset);
-                               _dataPoints[i].setModified(inUndo);
+                               p.addTimeOffsetSeconds(inOffset);
+                               p.setModified(inUndo);
                        }
                }
                return foundTimestamp;
@@ -335,12 +347,12 @@ public class Track
         * @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 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,
-        Altitude.Format inFormat, int inDecimals)
+        Unit inUnit, int inDecimals)
        {
                // sanity check
                if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) {
@@ -350,13 +362,13 @@ public class Track
                // Loop over all points within range
                for (int i=inStart; i<=inEnd; i++)
                {
-                       Altitude alt = _dataPoints[i].getAltitude();
-                       if (alt != null && alt.isValid())
+                       DataPoint p = _dataPoints[i];
+                       if (p != null && p.hasAltitude())
                        {
                                // This point has an altitude so add the offset to it
                                foundAlt = true;
-                               alt.addOffset(inOffset, inFormat, inDecimals);
-                               _dataPoints[i].setModified(false);
+                               p.addAltitudeOffset(inOffset, inUnit, inDecimals);
+                               p.setModified(false);
                        }
                }
                // needs to be scaled again
@@ -365,61 +377,6 @@ public class Track
        }
 
 
-       /**
-        * 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
-        */
-       public boolean collectWaypoints(boolean inAtStart)
-       {
-               // 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++)
-               {
-                       point = _dataPoints[i];
-                       if (point.isWaypoint())
-                       {
-                               waypoints[numWaypoints] = point;
-                               numWaypoints++;
-                               wayAfterNon |= (numNonWaypoints > 0);
-                       }
-                       else
-                       {
-                               nonWaypoints[numNonWaypoints] = point;
-                               numNonWaypoints++;
-                               nonAfterWay |= (numWaypoints > 0);
-                       }
-               }
-               // Exit if the data is already in the specified order
-               if (numWaypoints == 0 || numNonWaypoints == 0
-                       || (inAtStart && !wayAfterNon && nonAfterWay)
-                       || (!inAtStart && wayAfterNon && !nonAfterWay))
-               {
-                       return false;
-               }
-
-               // 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);
-               }
-               else
-               {
-                       System.arraycopy(nonWaypoints, 0, _dataPoints, 0, numNonWaypoints);
-                       System.arraycopy(waypoints, 0, _dataPoints, numNonWaypoints, numWaypoints);
-               }
-               // needs to be scaled again
-               _scaled = false;
-               UpdateMessageBroker.informSubscribers();
-               return true;
-       }
-
-
        /**
         * Interleave all waypoints by each nearest track point
         * @return true if successful, false if no change
@@ -580,15 +537,19 @@ 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;
+               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(altFormat);
+                       if (currPoint.hasAltitude())
+                       {
+                               totalAltitude += currPoint.getAltitude().getValue(altUnit);
+                               // Use altitude format of first valid altitude
+                               if (altUnit == null)
+                                       altUnit = currPoint.getAltitude().getUnit();
                                numAltitudes++;
                        }
                }
@@ -596,10 +557,12 @@ public class Track
                double meanLatitude = firstLatitude + (latitudeDiff / numPoints);
                double meanLongitude = firstLongitude + (longitudeDiff / numPoints);
                Altitude meanAltitude = null;
-               if (numAltitudes > 0) {meanAltitude = new Altitude((int) (totalAltitude / numAltitudes), altFormat);}
+               if (numAltitudes > 0) {
+                       meanAltitude = new Altitude((int) (totalAltitude / numAltitudes), altUnit);
+               }
 
-               DataPoint insertedPoint = new DataPoint(new Latitude(meanLatitude, Coordinate.FORMAT_NONE),
-                       new Longitude(meanLongitude, Coordinate.FORMAT_NONE), meanAltitude);
+               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);
@@ -643,16 +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
         */
@@ -666,7 +619,7 @@ public class Track
         */
        public DoubleRange getXRange()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _xRange;
        }
 
@@ -675,7 +628,7 @@ public class Track
         */
        public DoubleRange getYRange()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _yRange;
        }
 
@@ -684,7 +637,7 @@ public class Track
         */
        public DoubleRange getLatRange()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _latRange;
        }
        /**
@@ -692,7 +645,7 @@ public class Track
         */
        public DoubleRange getLonRange()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _longRange;
        }
 
@@ -702,7 +655,7 @@ public class Track
         */
        public double getX(int inPointNum)
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _xValues[inPointNum];
        }
 
@@ -712,7 +665,7 @@ public class Track
         */
        public double getY(int inPointNum)
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _yValues[inPointNum];
        }
 
@@ -779,7 +732,7 @@ public class Track
         */
        public boolean hasTrackPoints()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _hasTrackpoint;
        }
 
@@ -788,7 +741,7 @@ public class Track
         */
        public boolean hasWaypoints()
        {
-               if (!_scaled) scalePoints();
+               if (!_scaled) {scalePoints();}
                return _hasWaypoint;
        }
 
@@ -871,12 +824,11 @@ 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;
                _hasWaypoint = false; _hasTrackpoint = false;
                for (p=0; p < getNumPoints(); p++)
@@ -886,10 +838,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
@@ -930,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;
+                                       }
                                }
                        }
                }
@@ -951,6 +904,16 @@ 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