]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/function/sew/SegmentEnd.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / function / sew / SegmentEnd.java
diff --git a/src/tim/prune/function/sew/SegmentEnd.java b/src/tim/prune/function/sew/SegmentEnd.java
new file mode 100644 (file)
index 0000000..9f075f1
--- /dev/null
@@ -0,0 +1,197 @@
+package tim.prune.function.sew;
+
+import tim.prune.data.Coordinate;
+import tim.prune.data.DataPoint;
+
+/**
+ * Class to represent one end of a segment, including the
+ * coordinates and the other end of the segment
+ */
+public class SegmentEnd implements Comparable<SegmentEnd>
+{
+       private SegmentEnd _otherEnd = null;
+       private Coordinate _longitude = null;
+       private Coordinate _latitude  = null;
+       private int        _pointIndex = 0;
+       private boolean    _active = true;
+
+
+       /**
+        * Constructor
+        * @param inPoint data point
+        * @param inIndex point index within track
+        */
+       public SegmentEnd(DataPoint inPoint, int inIndex)
+       {
+               _longitude = inPoint.getLongitude();
+               _latitude  = inPoint.getLatitude();
+               _pointIndex = inIndex;
+               _active    = true;
+       }
+
+       /**
+        * @param inOther other end of the segment
+        */
+       public void setOtherEnd(SegmentEnd inOther)
+       {
+               _otherEnd = inOther;
+       }
+
+       /**
+        * @return other end
+        */
+       public SegmentEnd getOtherEnd()
+       {
+               return _otherEnd;
+       }
+
+       /**
+        * @return true if this is the start of the segment
+        */
+       public boolean isStart()
+       {
+               return _otherEnd == null || _otherEnd._pointIndex > _pointIndex;
+       }
+
+       /** @return point index */
+       public int getPointIndex() {
+               return _pointIndex;
+       }
+
+       /** @return point index of other end */
+       public int getOtherPointIndex()
+       {
+               return _otherEnd == null ? _pointIndex : _otherEnd._pointIndex;
+       }
+
+       /** @return get the earlier of the two point indices */
+       public int getEarlierIndex() {
+               return isStart() ? _pointIndex : _otherEnd._pointIndex;
+       }
+
+       /** @return get the later of the two point indices */
+       public int getLaterIndex() {
+               return isStart() ? _otherEnd._pointIndex : _pointIndex;
+       }
+
+       /**
+        * @return earlier end of this segment
+        */
+       public SegmentEnd getEarlierEnd() {
+               return isStart() ? this : _otherEnd;
+       }
+
+       /**
+        * @return later end of this segment
+        */
+       public SegmentEnd getLaterEnd() {
+               return isStart() ? _otherEnd : this;
+       }
+
+       /**
+        * Reverse this segment, by swapping the point indices of the start and end
+        * isStart() will thereby also be reversed for both ends
+        */
+       public void reverseSegment()
+       {
+               if (_otherEnd != null)
+               {
+                       int pointIndex = _pointIndex;
+                       _pointIndex = _otherEnd._pointIndex;
+                       _otherEnd._pointIndex = pointIndex;
+               }
+       }
+
+       /**
+        * @return true if this node is still active
+        */
+       public boolean isActive() {
+               return _active;
+       }
+
+       /**
+        * Deactive this node, don't use it any more (it's already been merged)
+        */
+       public void deactivate() {
+               _active = false;
+       }
+
+       /**
+        * @param inOther other segment end
+        * @return true if the coordinates are identical
+        */
+       public boolean atSamePointAs(SegmentEnd inOther)
+       {
+               return inOther != null && _latitude.equals(inOther._latitude) && _longitude.equals(inOther._longitude);
+       }
+
+       /**
+        * Compare two objects for sorting
+        */
+       public int compareTo(SegmentEnd o)
+       {
+               if (o == null) return -1;
+               // First, sort by latitude
+               if (!_latitude.equals(o._latitude)) {
+                       return (_latitude.getDouble() < o._latitude.getDouble() ? -1 : 1);
+               }
+               // Latitudes same, so sort by longitude
+               if (!_longitude.equals(o._longitude)) {
+                       return (_longitude.getDouble() < o._longitude.getDouble() ? -1 : 1);
+               }
+               // Points are identical so just sort by index
+               return _pointIndex - o._pointIndex;
+       }
+
+       /**
+        * Adjust the point index as a result of a cut/move operation on the track
+        * @param inSegmentStart index of start of segment to be moved
+        * @param inSegmentEnd index of end of segment to be moved
+        * @param inMoveTo index of point before which the segment should be moved
+        */
+       public void adjustPointIndex(int inSegmentStart, int inSegmentEnd, int inMoveTo)
+       {
+               final int segmentSize = inSegmentEnd - inSegmentStart + 1; // number of points moved
+               final boolean forwardsMove = inMoveTo > inSegmentEnd;
+               // Min and max indices of affected points (apart from segment to be moved)
+               final int minIndex = forwardsMove ? inSegmentEnd + 1 : inMoveTo;
+               final int maxIndex = forwardsMove ? inMoveTo - 1 : inSegmentStart - 1;
+               if (_pointIndex >= minIndex && _pointIndex <= maxIndex)
+               {
+                       // final int origIndex = _pointIndex;
+                       if (forwardsMove) {
+                               _pointIndex -= segmentSize; // segment moved forwards, point indices reduced
+                       }
+                       else {
+                               _pointIndex += segmentSize; // segment moved backwards, point indices shifted forwards
+                       }
+                       // System.out.println("    Need to adjust index: " + origIndex + " -> " + _pointIndex);
+               }
+               else if (_pointIndex == inSegmentStart)
+               {
+                       // final int origIndex = _pointIndex;
+                       if (forwardsMove) {
+                               _pointIndex = inMoveTo - segmentSize;
+                       }
+                       else
+                       {
+                               // Point index moves to moveTo
+                               _pointIndex = inMoveTo;
+                       }
+                       // System.out.println("    Need to adjust movedseg: " + origIndex + " -> " + _pointIndex);
+               }
+               else if (_pointIndex == inSegmentEnd)
+               {
+                       // final int origEndIndex = _otherEnd._pointIndex;
+                       if (forwardsMove) {
+                               _pointIndex = inMoveTo - 1;
+                       }
+                       else
+                       {
+                               // Point index moves to moveTo
+                               _pointIndex = inMoveTo + inSegmentEnd - inSegmentStart;
+                       }
+                       // System.out.println("    Need to adjust movedseg: " + origEndIndex + " -> " + _pointIndex);
+               }
+       }
+}