more failing test cases for bug 1054; fix for 1054 by adjusting GPSFixTrackImpl.getEstimatedPositionTimePeriodAffectedBy

This commit is contained in:
Axel Uhl
2012-11-23 16:19:45 +01:00
parent 415bf1730b
commit 4839f03c36
3 changed files with 70 additions and 8 deletions
@@ -687,7 +687,7 @@ public class TrackTest {
}
@Test
public void testInvalidationIntervalForPositionEstimationForEmptyTrack() {
public void testInvalidationIntervalBeginningForPositionEstimation() {
track.lockForRead();
final GPSFixMoving firstFixSoFar;
try {
@@ -710,4 +710,44 @@ public class TrackTest {
assertFalse(newPositionAtBeginningOfTime.equals(positionAtBeginningOfTime));
assertTrue(!intervalAffected.getA().after(beginningOfTime));
}
@Test
public void testInvalidationIntervalEndForPositionEstimation() {
TimePoint endOfTime = new MillisecondsTimePoint(Long.MAX_VALUE);
final GPSFixMoving lastFixSoFar = track.getLastFixBefore(endOfTime);
assertNotNull(lastFixSoFar);
Position positionAtEndOfTime = track.getEstimatedPosition(endOfTime, /* extrapolate */false);
long timespan = 2 /* hours */ * 3600 /* seconds/hour */ * 1000 /* millis/s */;
SpeedWithBearing speed = new KnotSpeedWithBearingImpl(45, new DegreeBearingImpl(123));
TimePoint slightlyAfterLastFix = lastFixSoFar.getTimePoint().plus(timespan);
Position newPosition = lastFixSoFar.getPosition().translateGreatCircle(speed.getBearing(),
speed.travel(lastFixSoFar.getTimePoint(), lastFixSoFar.getTimePoint().plus(timespan)));
GPSFixMoving newLastFix = new GPSFixMovingImpl(newPosition, slightlyAfterLastFix, speed);
track.addGPSFix(newLastFix);
Pair<TimePoint, TimePoint> intervalAffected = track.getEstimatedPositionTimePeriodAffectedBy(newLastFix);
Position newPositionAtEndOfTime = track.getEstimatedPosition(endOfTime, /* extrapolate */false);
assertFalse(newPositionAtEndOfTime.equals(positionAtEndOfTime));
assertTrue(!intervalAffected.getB().before(endOfTime));
}
@Test
public void testInvalidationIntervalForPositionEstimationForEmptyTrack() {
TimePoint now = MillisecondsTimePoint.now();
DynamicGPSFixMovingTrackImpl<Object> myTrack = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */5000);
TimePoint beginningOfTime = new MillisecondsTimePoint(0);
Position positionAtBeginningOfTime = myTrack.getEstimatedPosition(beginningOfTime, /* extrapolate */false);
TimePoint endOfTime = new MillisecondsTimePoint(Long.MAX_VALUE);
Position positionAtEndOfTime = myTrack.getEstimatedPosition(endOfTime, /* extrapolate */false);
assertNull(positionAtBeginningOfTime);
assertNull(positionAtEndOfTime);
GPSFixMoving newFix = new GPSFixMovingImpl(new DegreePosition(12, 34), now, new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)));
myTrack.addGPSFix(newFix);
Pair<TimePoint, TimePoint> intervalAffected = myTrack.getEstimatedPositionTimePeriodAffectedBy(newFix);
Position newPositionAtBeginningOfTime = myTrack.getEstimatedPosition(beginningOfTime, /* extrapolate */false);
Position newPositionAtEndOfTime = myTrack.getEstimatedPosition(now, /* extrapolate */false);
assertFalse(newPositionAtBeginningOfTime.equals(positionAtBeginningOfTime));
assertTrue(!intervalAffected.getA().after(beginningOfTime));
assertFalse(newPositionAtEndOfTime.equals(positionAtEndOfTime));
assertTrue(!intervalAffected.getB().before(endOfTime));
}
}
@@ -102,16 +102,15 @@ public interface GPSFixTrack<ItemType, FixType extends GPSFix> extends Track<Fix
SpeedWithBearing getRawEstimatedSpeed(TimePoint at);
/**
* FIXME see bug 1054: if the fix is added to one end of the track, this will affect all queries beyond this end!
*
* Finds out which position estimation time interval has been affected by inserting <code>fix</code>.
*
* @param fix
* assumed to already have been inserted into this track, but it's OK to pass a fix that's not in the
* track yet
*
* @return if no fix before <code>fix</code> is found, the first component is <code>fix.getTimePoint()</code>. If no fix after
* <code>fix</code> is found, the second component is <code>fix.getTimePoint()</code>.
* @return if no fix before <code>fix</code> is found, the first component is the beginning of the epoch (
* <code>new MillisecondsTimePoint(0)</code>). If no fix after <code>fix</code> is found, the second
* component is the end of time (<code>new MillisecondsTimePoint(Long.MAX_VALUE)</code>).
*/
Pair<TimePoint, TimePoint> getEstimatedPositionTimePeriodAffectedBy(GPSFix fix);
@@ -272,12 +272,35 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends TrackImpl
@Override
public Pair<TimePoint, TimePoint> getEstimatedPositionTimePeriodAffectedBy(GPSFix fix) {
if (fix == null) {
throw new IllegalArgumentException("fix must not be null");
}
lockForRead();
try {
Pair<FixType, FixType> fixesForPositionEstimation = getFixesForPositionEstimation(fix.getTimePoint(), /* inclusive */ true);
return new Pair<TimePoint, TimePoint>(fixesForPositionEstimation.getA() == null ? fix.getTimePoint()
: fixesForPositionEstimation.getA().getTimePoint(),
fixesForPositionEstimation.getB() == null ? fix.getTimePoint() : fixesForPositionEstimation.getB().getTimePoint());
final TimePoint start;
if (fix.equals(fixesForPositionEstimation.getA())) {
if (getLastFixBefore(fix.getTimePoint()) == null) {
// fix is the first fix in the track; all position estimation before this point may be affected
start = new MillisecondsTimePoint(0);
} else {
start = fix.getTimePoint();
}
} else {
start = fixesForPositionEstimation.getA().getTimePoint();
}
final TimePoint end;
if (fix.equals(fixesForPositionEstimation.getB())) {
if (getFirstFixAfter(fix.getTimePoint()) == null) {
// fix is the first fix in the track; all position estimation before this point may be affected
end = new MillisecondsTimePoint(Long.MAX_VALUE);
} else {
end = fix.getTimePoint();
}
} else {
end = fixesForPositionEstimation.getB().getTimePoint();
}
return new Pair<TimePoint, TimePoint>(start, end);
} finally {
unlockAfterRead();
}