started to make tracking quality column relative to average duration between fixes on competitor's track

This commit is contained in:
Axel Uhl committed 2014-02-10 13:45:31 +01:00
1 parent 2f2259c4d6
commit a4fbbc0a01
6 files changed
+41 -21

No files matched your search

@@ -1,13 +1,17 @@
package com.sap.sailing.domain.common;
import java.io.Serializable;
/**
* A time duration that can be converted to various time units and that interoperates with {@link TimePoint}.
*
* @author Axel Uhl (D043530)
*
*/
public interface Duration {
public interface Duration extends Serializable {
long asMillis();
double asSeconds();
Duration divide(long divisor);
}
@@ -1,9 +1,9 @@
package com.sap.sailing.domain.common.dto;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import com.sap.sailing.domain.common.Duration;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.Tack;
@@ -61,13 +61,18 @@ public class LeaderboardEntryDTO implements Serializable {
public Tack startTack;
/**
* If we have GPS data for the competitor for whom this is a leaderboard entry, tells the time point of the last
* If we have GPS data for the competitor for whom this is a leaderboard entry, tells the time since the last
* non-extrapolated GPS fix that was really received from the tracking device at or before the time point for which
* the leaderboard was queried. The user interface may---particularly in live mode---choose to visualize the time
* that passed between the last fix and the query time point for which this entry was created.
*/
public Date timePointOfLastPositionFixAtOrBeforeQueryTimePoint;
public Double timeSinceLastPositionFixInSeconds;
/**
* For the competitor's track in the race represented by this object, if a track is present and the track has more
* than one fix, this field tells the average duration between two fixes on the competitor's track.
*/
public Duration averageSamplingInterval;
/**
* If <code>null</code>, no leg details are known yet, the race is not being tracked or the details
@@ -117,7 +122,7 @@ public class LeaderboardEntryDTO implements Serializable {
result = prime * result
+ ((speedOverGroundAtStartOfRaceInKnots == null) ? 0 : speedOverGroundAtStartOfRaceInKnots.hashCode());
result = prime * result + ((startTack == null) ? 0 : startTack.hashCode());
result = prime * result + ((timePointOfLastPositionFixAtOrBeforeQueryTimePoint == null) ? 0 : timePointOfLastPositionFixAtOrBeforeQueryTimePoint.hashCode());
result = prime * result + ((averageSamplingInterval == null) ? 0 : averageSamplingInterval.hashCode());
result = prime * result + ((timeSinceLastPositionFixInSeconds == null) ? 0 : timeSinceLastPositionFixInSeconds.hashCode());
result = prime * result + ((totalPoints == null) ? 0 : totalPoints.hashCode());
result = prime
@@ -190,10 +195,10 @@ public class LeaderboardEntryDTO implements Serializable {
return false;
if (startTack != other.startTack)
return false;
if (timePointOfLastPositionFixAtOrBeforeQueryTimePoint == null) {
if (other.timePointOfLastPositionFixAtOrBeforeQueryTimePoint != null)
if (averageSamplingInterval == null) {
if (other.averageSamplingInterval != null)
return false;
} else if (!timePointOfLastPositionFixAtOrBeforeQueryTimePoint.equals(other.timePointOfLastPositionFixAtOrBeforeQueryTimePoint))
} else if (!averageSamplingInterval.equals(other.averageSamplingInterval))
return false;
if (timeSinceLastPositionFixInSeconds == null) {
if (other.timeSinceLastPositionFixInSeconds != null)
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.common.impl;
import com.sap.sailing.domain.common.Duration;
public class MillisecondsDurationImpl implements Duration {
private static final long serialVersionUID = -4257982564719184723L;
private final long millis;
public MillisecondsDurationImpl(long millis) {
@@ -15,6 +16,11 @@ public class MillisecondsDurationImpl implements Duration {
return millis;
}
@Override
public double asSeconds() {
return ((double) asMillis()) / 1000.;
}
@Override
public Duration divide(long divisor) {
return new MillisecondsDurationImpl(asMillis() / divisor);
@@ -1254,9 +1254,10 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
entryDTO.reasonForMaxPoints = entry.getMaxPointsReason();
entryDTO.discarded = entry.isDiscarded();
if (trackedRace != null) {
entryDTO.timePointOfLastPositionFixAtOrBeforeQueryTimePoint = getTimePointOfLastFixAtOrBefore(competitor, trackedRace, timePoint);
if(entryDTO.timePointOfLastPositionFixAtOrBeforeQueryTimePoint != null) {
long timeDifferenceInMs = timePoint.asMillis() - entryDTO.timePointOfLastPositionFixAtOrBeforeQueryTimePoint.getTime();
Date timePointOfLastPositionFixAtOrBeforeQueryTimePoint = getTimePointOfLastFixAtOrBefore(competitor, trackedRace, timePoint);
entryDTO.averageSamplingInterval = trackedRace.getTrack(competitor).getAverageIntervalBetweenFixes();
if (timePointOfLastPositionFixAtOrBeforeQueryTimePoint != null) {
long timeDifferenceInMs = timePoint.asMillis() - timePointOfLastPositionFixAtOrBeforeQueryTimePoint.getTime();
entryDTO.timeSinceLastPositionFixInSeconds = timeDifferenceInMs == 0 ? 0.0 : timeDifferenceInMs / 1000.0;
} else {
entryDTO.timeSinceLastPositionFixInSeconds = null;
@@ -880,13 +880,21 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
return result;
}
/**
* Reports the ratio of the time that passed since the last position fix and the average sampling interval of the
* competitor's track. On a perfect track, this value will never exceed 1.0. Immediately when a fix is received, this
* value goes to 0.0. For a competitor whose tracker is lagging, this value can grow considerably greater than 1.
*
* @author Axel Uhl (D043530)
*
*/
private class RaceTrackingQuality implements LegDetailField<Double> {
@Override
public Double get(LeaderboardRowDTO row) {
Double result = null;
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName());
if (fieldsForRace != null) {
result = fieldsForRace.timeSinceLastPositionFixInSeconds;
if (fieldsForRace != null && fieldsForRace.timeSinceLastPositionFixInSeconds != null && fieldsForRace.averageSamplingInterval != null) {
result = fieldsForRace.timeSinceLastPositionFixInSeconds / fieldsForRace.averageSamplingInterval.asSeconds();
}
return result;
}
@@ -34,20 +34,16 @@ public class TrackingQualityColumn extends DetailTypeColumn<Double, Double> {
}
@Override
public void render(Double timeSinceLastPositionFixInSeconds, SafeHtmlBuilder builder) {
if (timeSinceLastPositionFixInSeconds != null) {
public void render(Double ratioOfLagAndAverageSamplingInterval, SafeHtmlBuilder builder) {
if (ratioOfLagAndAverageSamplingInterval != null) {
builder.append(SafeHtmlUtils.fromTrustedString("<div class=\"" + STYLE_TRACKING_QUALITY_CIRCLE + " "));
// builder.append(SafeHtmlUtils.fromTrustedString(diffInSeconds + "s"));
if(timeSinceLastPositionFixInSeconds < 5.0) {
if (ratioOfLagAndAverageSamplingInterval < 3.0) {
builder.append(SafeHtmlUtils.fromTrustedString(STYLE_TRACKING_QUALITY_CIRCLE_GREEN));
} else if(timeSinceLastPositionFixInSeconds < 10) {
} else if (ratioOfLagAndAverageSamplingInterval < 5) {
builder.append(SafeHtmlUtils.fromTrustedString(STYLE_TRACKING_QUALITY_CIRCLE_YELLOW));
} else {
builder.append(SafeHtmlUtils.fromTrustedString(STYLE_TRACKING_QUALITY_CIRCLE_RED));
}
builder.append(SafeHtmlUtils.fromTrustedString("\"></div>"));
} else {
builder.append(SafeHtmlUtils.fromTrustedString(STYLE_TRACKING_QUALITY_CIRCLE_GREEN));