mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-20 19:20:04 +00:00
added Track.getInterpolatedValue, preparing for re-use across NMEA and Igtimi connector
Change-Id: Ia956d8ca0d9e40f275ade9f2c3764887e0de195a
This commit is contained in:
1 parent
1026fcf044
commit
82da2ccb51
5 files changed
+102
-9
No files matched your search
+8
@@ -17,6 +17,8 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util.Function;
|
||||
import com.sap.sse.common.scalablevalue.ScalableValue;
|
||||
|
||||
/**
|
||||
* Wrapper for a {@link RaceLog} which will ignore all calls trying to add an {@link RaceLogEvent}. All other
|
||||
@@ -250,4 +252,10 @@ public class NoAddingRaceLogWrapper implements RaceLog {
|
||||
public void revokeEvent(AbstractLogEventAuthor author, RaceLogEvent toRevoke) throws NotRevokableException {
|
||||
innerRaceLog.revokeEvent(author, toRevoke);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <InternalType, ValueType> ValueType getInterpolatedValue(TimePoint timePoint,
|
||||
Function<RaceLogEvent, ScalableValue<InternalType, ValueType>> converter) {
|
||||
return innerRaceLog.getInterpolatedValue(timePoint, converter);
|
||||
}
|
||||
}
|
||||
+25
@@ -4,9 +4,12 @@ import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.Util.Function;
|
||||
import com.sap.sse.common.scalablevalue.ScalableValue;
|
||||
|
||||
/**
|
||||
* A track records {@link Timed} items for an object of type <code>ItemType</code>. It allows clients to ask for a value
|
||||
@@ -117,6 +120,27 @@ public interface Track<FixType extends Timed> extends Serializable {
|
||||
*/
|
||||
FixType getLastRawFix();
|
||||
|
||||
/**
|
||||
* Interpolates an aspect of the fixes in this track for a given {@code timePoint}. If {@code timePoint} matches
|
||||
* exactly a fix in this track, that fix is used. If this track is empty, {@code null} is returned. If the
|
||||
* {@code timePoint} is after the last fix of this track, the last fix is used; if before the first fix, the first
|
||||
* fix is used.
|
||||
* <p>
|
||||
*
|
||||
* The fix(es) are converted to {@link ScalableValue}s using the {@code converter} which gives callers a choice
|
||||
* which aspect of the fixes to project and interpolate. If more than one value results because two fixes (one
|
||||
* before, one after) are used, linear interpolation based on the fixes' time points takes place.
|
||||
* <p>
|
||||
*
|
||||
* Example: for a track of {@link GPSFixMoving} fixes the course over ground shall be determined for a given time
|
||||
* point. The call would look like this:
|
||||
* {@code getInterpolatedValue(timePoint, f->new ScalableBearing(f.getSpeed().getBearing()))}
|
||||
*
|
||||
* @return the projected interpolated value, typed by what the {@link ScalableValue#divide(double)} method returns.
|
||||
*/
|
||||
<InternalType, ValueType> ValueType getInterpolatedValue(TimePoint timePoint,
|
||||
Function<FixType, ScalableValue<InternalType, ValueType>> converter);
|
||||
|
||||
/**
|
||||
* Returns an iterator starting at the first fix after <code>startingAt</code> (or "at or after" in case
|
||||
* <code>inclusive</code> is <code>true</code>). The fixes returned by the iterator are the smoothened fixes (see
|
||||
@@ -184,4 +208,5 @@ public interface Track<FixType extends Timed> extends Serializable {
|
||||
* more than one raw fix in the track
|
||||
*/
|
||||
Duration getAverageIntervalBetweenRawFixes();
|
||||
|
||||
}
|
||||
+44
@@ -10,6 +10,9 @@ import com.sap.sailing.domain.tracking.Track;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.Util.Function;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.scalablevalue.ScalableValue;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
import com.sap.sse.util.impl.ArrayListNavigableSet;
|
||||
@@ -251,6 +254,47 @@ public class TrackImpl<FixType extends Timed> implements Track<FixType> {
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<FixType, FixType> getSurroundingFixes(TimePoint timePoint) {
|
||||
FixType left = getLastFixAtOrBefore(timePoint);
|
||||
FixType right = getFirstFixAtOrAfter(timePoint);
|
||||
com.sap.sse.common.Util.Pair<FixType, FixType> result = new com.sap.sse.common.Util.Pair<>(left, right);
|
||||
return result;
|
||||
}
|
||||
|
||||
private <V, T> T timeBasedAverage(TimePoint timePoint, ScalableValue<V, T> value1, TimePoint timePoint1, ScalableValue<V, T> value2, TimePoint timePoint2) {
|
||||
final T acc;
|
||||
if (timePoint1.equals(timePoint2)) {
|
||||
acc = value1.add(value2).divide(2);
|
||||
} else {
|
||||
long timeDiff1 = Math.abs(timePoint1.asMillis() - timePoint.asMillis());
|
||||
long timeDiff2 = Math.abs(timePoint2.asMillis() - timePoint.asMillis());
|
||||
acc = value1.multiply(timeDiff2).add(value2.multiply(timeDiff1)).divide(timeDiff1 + timeDiff2);
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <InternalType, ValueType> ValueType getInterpolatedValue(TimePoint timePoint, Function<FixType, ScalableValue<InternalType, ValueType>> converter) {
|
||||
final ValueType aws;
|
||||
Pair<FixType, FixType> awsPair = getSurroundingFixes(timePoint);
|
||||
if (awsPair.getA() == null) {
|
||||
if (awsPair.getB() == null) {
|
||||
aws = null;
|
||||
} else {
|
||||
aws = converter.get(awsPair.getB()).divide(1);
|
||||
}
|
||||
} else {
|
||||
if (awsPair.getB() == null) {
|
||||
aws = converter.get(awsPair.getA()).divide(1);
|
||||
} else {
|
||||
aws = timeBasedAverage(timePoint,
|
||||
converter.get(awsPair.getA()), awsPair.getA().getTimePoint(),
|
||||
converter.get(awsPair.getB()), awsPair.getB().getTimePoint());
|
||||
}
|
||||
}
|
||||
return aws;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<FixType> getFixesIterator(TimePoint startingAt, boolean inclusive) {
|
||||
assertReadLock();
|
||||
|
||||
Reference in new issue
Block a user