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);
}
}
}