]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/function/sew/SegmentEnd.java
Version 16, February 2014
[GpsPrune.git] / tim / prune / function / sew / SegmentEnd.java
1 package tim.prune.function.sew;
2
3 import tim.prune.data.Coordinate;
4 import tim.prune.data.DataPoint;
5
6 /**
7  * Class to represent one end of a segment, including the
8  * coordinates and the other end of the segment
9  */
10 public class SegmentEnd implements Comparable<SegmentEnd>
11 {
12         private SegmentEnd _otherEnd = null;
13         private Coordinate _longitude = null;
14         private Coordinate _latitude  = null;
15         private int        _pointIndex = 0;
16         private boolean    _active = true;
17
18
19         /**
20          * Constructor
21          * @param inPoint data point
22          * @param inIndex point index within track
23          */
24         public SegmentEnd(DataPoint inPoint, int inIndex)
25         {
26                 _longitude = inPoint.getLongitude();
27                 _latitude  = inPoint.getLatitude();
28                 _pointIndex = inIndex;
29                 _active    = true;
30         }
31
32         /**
33          * @param inOther other end of the segment
34          */
35         public void setOtherEnd(SegmentEnd inOther)
36         {
37                 _otherEnd = inOther;
38         }
39
40         /**
41          * @return other end
42          */
43         public SegmentEnd getOtherEnd()
44         {
45                 return _otherEnd;
46         }
47
48         /**
49          * @return true if this is the start of the segment
50          */
51         public boolean isStart()
52         {
53                 return _otherEnd == null || _otherEnd._pointIndex > _pointIndex;
54         }
55
56         /** @return point index */
57         public int getPointIndex() {
58                 return _pointIndex;
59         }
60
61         /** @return point index of other end */
62         public int getOtherPointIndex()
63         {
64                 return _otherEnd == null ? _pointIndex : _otherEnd._pointIndex;
65         }
66
67         /** @return get the earlier of the two point indices */
68         public int getEarlierIndex() {
69                 return isStart() ? _pointIndex : _otherEnd._pointIndex;
70         }
71
72         /** @return get the later of the two point indices */
73         public int getLaterIndex() {
74                 return isStart() ? _otherEnd._pointIndex : _pointIndex;
75         }
76
77         /**
78          * @return earlier end of this segment
79          */
80         public SegmentEnd getEarlierEnd() {
81                 return isStart() ? this : _otherEnd;
82         }
83
84         /**
85          * @return later end of this segment
86          */
87         public SegmentEnd getLaterEnd() {
88                 return isStart() ? _otherEnd : this;
89         }
90
91         /**
92          * Reverse this segment, by swapping the point indices of the start and end
93          * isStart() will thereby also be reversed for both ends
94          */
95         public void reverseSegment()
96         {
97                 if (_otherEnd != null)
98                 {
99                         int pointIndex = _pointIndex;
100                         _pointIndex = _otherEnd._pointIndex;
101                         _otherEnd._pointIndex = pointIndex;
102                 }
103         }
104
105         /**
106          * @return true if this node is still active
107          */
108         public boolean isActive() {
109                 return _active;
110         }
111
112         /**
113          * Deactive this node, don't use it any more (it's already been merged)
114          */
115         public void deactivate() {
116                 _active = false;
117         }
118
119         /**
120          * @param inOther other segment end
121          * @return true if the coordinates are identical
122          */
123         public boolean atSamePointAs(SegmentEnd inOther)
124         {
125                 return inOther != null && _latitude.equals(inOther._latitude) && _longitude.equals(inOther._longitude);
126         }
127
128         /**
129          * Compare two objects for sorting
130          */
131         public int compareTo(SegmentEnd o)
132         {
133                 if (o == null) return -1;
134                 // First, sort by latitude
135                 if (!_latitude.equals(o._latitude)) {
136                         return (_latitude.getDouble() < o._latitude.getDouble() ? -1 : 1);
137                 }
138                 // Latitudes same, so sort by longitude
139                 if (!_longitude.equals(o._longitude)) {
140                         return (_longitude.getDouble() < o._longitude.getDouble() ? -1 : 1);
141                 }
142                 // Points are identical so just sort by index
143                 return _pointIndex - o._pointIndex;
144         }
145
146         /**
147          * Adjust the point index as a result of a cut/move operation on the track
148          * @param inSegmentStart index of start of segment to be moved
149          * @param inSegmentEnd index of end of segment to be moved
150          * @param inMoveTo index of point before which the segment should be moved
151          */
152         public void adjustPointIndex(int inSegmentStart, int inSegmentEnd, int inMoveTo)
153         {
154                 final int segmentSize = inSegmentEnd - inSegmentStart + 1; // number of points moved
155                 final boolean forwardsMove = inMoveTo > inSegmentEnd;
156                 // Min and max indices of affected points (apart from segment to be moved)
157                 final int minIndex = forwardsMove ? inSegmentEnd + 1 : inMoveTo;
158                 final int maxIndex = forwardsMove ? inMoveTo - 1 : inSegmentStart - 1;
159                 if (_pointIndex >= minIndex && _pointIndex <= maxIndex)
160                 {
161                         // final int origIndex = _pointIndex;
162                         if (forwardsMove) {
163                                 _pointIndex -= segmentSize; // segment moved forwards, point indices reduced
164                         }
165                         else {
166                                 _pointIndex += segmentSize; // segment moved backwards, point indices shifted forwards
167                         }
168                         // System.out.println("    Need to adjust index: " + origIndex + " -> " + _pointIndex);
169                 }
170                 else if (_pointIndex == inSegmentStart)
171                 {
172                         // final int origIndex = _pointIndex;
173                         if (forwardsMove) {
174                                 _pointIndex = inMoveTo - segmentSize;
175                         }
176                         else
177                         {
178                                 // Point index moves to moveTo
179                                 _pointIndex = inMoveTo;
180                         }
181                         // System.out.println("    Need to adjust movedseg: " + origIndex + " -> " + _pointIndex);
182                 }
183                 else if (_pointIndex == inSegmentEnd)
184                 {
185                         // final int origEndIndex = _otherEnd._pointIndex;
186                         if (forwardsMove) {
187                                 _pointIndex = inMoveTo - 1;
188                         }
189                         else
190                         {
191                                 // Point index moves to moveTo
192                                 _pointIndex = inMoveTo + inSegmentEnd - inSegmentStart;
193                         }
194                         // System.out.println("    Need to adjust movedseg: " + origEndIndex + " -> " + _pointIndex);
195                 }
196         }
197 }