mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-04 10:09:42 +00:00
started to make tracking quality column relative to average duration between fixes on competitor's track
This commit is contained in:
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);
|
||||
}
|
||||
+12
-7
@@ -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,14 +61,19 @@ 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
|
||||
* haven't been requested from the server yet. Otherwise, the list holds one entry per <code>Leg</code> of the
|
||||
@@ -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)
|
||||
|
||||
+6
@@ -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);
|
||||
|
||||
+4
-3
@@ -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;
|
||||
|
||||
+10
-2
@@ -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;
|
||||
}
|
||||
|
||||
+4
-8
@@ -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));
|
||||
|
||||
Reference in new issue
Block a user