mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-01 08:40:52 +00:00
provided an efficient getRankingInfo implementation for one-design ranking
This commit is contained in:
1 parent
ada309e959
commit
1990caec67
4 files changed
+114
-23
No files matched your search
+16
-13
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.ranking;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@@ -115,11 +116,6 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
return estimatedActualDurationToCompetitorFarthestAhead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead() {
|
||||
return getTrackedRace().getStartOfRace().until(getTimePoint()).plus(getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead() {
|
||||
return correctedTimeAtEstimatedArrivalAtCompetitorFarthestAhead;
|
||||
@@ -139,7 +135,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
* about actual and corrected times needed to reach the position of the competitor farthest ahead at
|
||||
* {@link #timePoint}.
|
||||
*/
|
||||
private final Map<Competitor, RankingMetric.CompetitorRankingInfo> competitorRankingInfo;
|
||||
private final Function<Competitor, RankingMetric.CompetitorRankingInfo> competitorRankingInfo;
|
||||
|
||||
private final Competitor competitorFarthestAhead;
|
||||
|
||||
@@ -151,7 +147,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
|
||||
public RankingInfoImpl(TimePoint timePoint, Map<Competitor, RankingMetric.CompetitorRankingInfo> competitorRankingInfo, Competitor competitorFarthestAhead) {
|
||||
this.timePoint = timePoint;
|
||||
this.competitorRankingInfo = competitorRankingInfo;
|
||||
this.competitorRankingInfo = c->competitorRankingInfo.get(c);
|
||||
this.competitorFarthestAhead = competitorFarthestAhead;
|
||||
leaderByCorrectedEstimatedTimeToCompetitorFarthestAhead = competitorRankingInfo.keySet().stream().sorted(
|
||||
(c1, c2) -> competitorRankingInfo.get(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead().
|
||||
@@ -164,7 +160,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Competitor, RankingMetric.CompetitorRankingInfo> getCompetitorRankingInfo() {
|
||||
public Function<Competitor, CompetitorRankingInfo> getCompetitorRankingInfo() {
|
||||
return competitorRankingInfo;
|
||||
}
|
||||
|
||||
@@ -217,7 +213,12 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
.stream(getTrackedRace().getRace().getCompetitors().spliterator(), /* parallel */true).
|
||||
sorted(oneDesignComparator).findFirst().get();
|
||||
final Distance totalWindwardDistanceTraveled = getWindwardDistanceTraveled(competitorFarthestAhead, timePoint, cache);
|
||||
final Duration actualRaceDuration = getTrackedRace().getStartOfRace().until(timePoint);
|
||||
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
final Duration actualRaceDuration;
|
||||
if (startOfRace == null) {
|
||||
actualRaceDuration = null;
|
||||
} else {
|
||||
actualRaceDuration = startOfRace.until(timePoint);
|
||||
for (Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
|
||||
final Duration predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead =
|
||||
getPredictedDurationToReachWindwardPositionOf(competitor, competitorFarthestAhead, timePoint, cache);
|
||||
@@ -233,10 +234,11 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
actualRaceDuration, totalWindwardDistanceTraveled);
|
||||
RankingMetric.CompetitorRankingInfo rankingInfo = new CompetitorRankingInfoImpl(timePoint, competitor,
|
||||
getWindwardDistanceTraveled(competitor, timePoint, cache), actualRaceDuration, correctedTime,
|
||||
totalEstimatedDurationSinceRaceStartToCompetitorFarthestAhead,
|
||||
predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead,
|
||||
correctedEstimatedTimeWhenReachingCompetitorFarthestAhead);
|
||||
result.put(competitor, rankingInfo);
|
||||
}
|
||||
}
|
||||
return new RankingInfoImpl(timePoint, result, competitorFarthestAhead);
|
||||
}
|
||||
|
||||
@@ -245,9 +247,10 @@ public abstract class AbstractRankingMetric implements RankingMetric {
|
||||
getRankingInfo(timePoint, new NoCachingWindLegTypeAndLegBearingCache()).getCompetitorRankingInfo());
|
||||
}
|
||||
|
||||
protected Comparator<Competitor> getComparatorByEstimatedCorrectedTimeWhenReachingCompetitorFarthestAhead(final Map<Competitor, RankingMetric.CompetitorRankingInfo> rankingInfos) {
|
||||
return (c1, c2) -> rankingInfos.get(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead()
|
||||
.compareTo(rankingInfos.get(c2).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead());
|
||||
protected Comparator<Competitor> getComparatorByEstimatedCorrectedTimeWhenReachingCompetitorFarthestAhead(
|
||||
final Function<Competitor, RankingMetric.CompetitorRankingInfo> rankingInfos) {
|
||||
return (c1, c2) -> rankingInfos.apply(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead()
|
||||
.compareTo(rankingInfos.apply(c2).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+85
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.ranking;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
@@ -38,7 +39,7 @@ public class OneDesignRankingMetric extends AbstractRankingMetric {
|
||||
|
||||
@Override
|
||||
public Duration getGapToLeaderInOwnTime(RankingMetric.RankingInfo rankingInfo, Competitor competitor, WindLegTypeAndLegBearingCache cache) {
|
||||
return rankingInfo.getCompetitorRankingInfo().get(competitor).getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead();
|
||||
return rankingInfo.getCompetitorRankingInfo().apply(competitor).getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,4 +63,87 @@ public class OneDesignRankingMetric extends AbstractRankingMetric {
|
||||
Duration totalDurationSinceRaceStart, Distance totalWindwardDistanceTraveled) {
|
||||
return totalDurationSinceRaceStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RankingInfo getRankingInfo(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) {
|
||||
return new RankingInfo() {
|
||||
private static final long serialVersionUID = 25689357311324825L;
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Competitor, CompetitorRankingInfo> getCompetitorRankingInfo() {
|
||||
return competitor -> getCompetitorRankingInfo(competitor);
|
||||
}
|
||||
|
||||
private CompetitorRankingInfo getCompetitorRankingInfo(final Competitor competitor) {
|
||||
return new CompetitorRankingInfo() {
|
||||
private static final long serialVersionUID = 1164789004900690406L;
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceSailed() {
|
||||
return getWindwardDistanceTraveled(competitor, timePoint, cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getActualTime() {
|
||||
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
final Duration result;
|
||||
if (startOfRace == null) {
|
||||
result = null;
|
||||
} else {
|
||||
result = startOfRace.until(timePoint);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrected time is the same as actual time for one-design ranking
|
||||
*/
|
||||
@Override
|
||||
public Duration getCorrectedTime() {
|
||||
return getActualTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead() {
|
||||
return getPredictedDurationToReachWindwardPositionOf(competitor, getCompetitorFarthestAhead(), timePoint, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrected time is the same as actual time for one-design ranking
|
||||
*/
|
||||
@Override
|
||||
public Duration getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead() {
|
||||
return getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitorFarthestAhead() {
|
||||
return getTrackedRace().getOverallLeader(timePoint, cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead() {
|
||||
return getCompetitorFarthestAhead();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.sap.sailing.domain.ranking;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
@@ -55,7 +55,8 @@ public interface RankingMetric extends Serializable {
|
||||
Distance getWindwardDistanceSailed();
|
||||
|
||||
/**
|
||||
* Usually the difference between {@link #timePoint} and the start of the race
|
||||
* Usually the difference between {@link #timePoint} and the start of the race; <code>null</code> if the
|
||||
* race start time is not known.
|
||||
*/
|
||||
Duration getActualTime();
|
||||
|
||||
@@ -72,7 +73,10 @@ public interface RankingMetric extends Serializable {
|
||||
*/
|
||||
Duration getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead();
|
||||
|
||||
Duration getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
default Duration getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead() {
|
||||
return getActualTime() == null ? null : getActualTime().plus(
|
||||
getEstimatedActualDurationFromTimePointToCompetitorFarthestAhead());
|
||||
}
|
||||
|
||||
/**
|
||||
* The corrections applied to the time and distance sailed when the {@link #competitor} would have reached the
|
||||
@@ -93,7 +97,7 @@ public interface RankingMetric extends Serializable {
|
||||
* about actual and corrected times needed to reach the position of the competitor farthest ahead at
|
||||
* {@link #timePoint}.
|
||||
*/
|
||||
Map<Competitor, CompetitorRankingInfo> getCompetitorRankingInfo();
|
||||
Function<Competitor, CompetitorRankingInfo> getCompetitorRankingInfo();
|
||||
|
||||
Competitor getCompetitorFarthestAhead();
|
||||
|
||||
|
||||
+5
-5
@@ -79,8 +79,8 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
@Override
|
||||
public Comparator<Competitor> getRaceRankingComparator(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||
final RankingMetric.RankingInfo rankingInfo = getRankingInfo(timePoint, cache);
|
||||
return (c1, c2) -> rankingInfo.getCompetitorRankingInfo().get(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead().compareTo(
|
||||
rankingInfo.getCompetitorRankingInfo().get(c2).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead());
|
||||
return (c1, c2) -> rankingInfo.getCompetitorRankingInfo().apply(c1).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead().compareTo(
|
||||
rankingInfo.getCompetitorRankingInfo().apply(c2).getCorrectedTimeAtEstimatedArrivalAtCompetitorFarthestAhead());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -264,14 +264,14 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||
*/
|
||||
@Override
|
||||
public Duration getGapToLeaderInOwnTime(RankingMetric.RankingInfo rankingInfo, Competitor competitor, WindLegTypeAndLegBearingCache cache) {
|
||||
final Duration t_k = rankingInfo.getCompetitorRankingInfo().get(rankingInfo.getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead()).
|
||||
final Duration t_k = rankingInfo.getCompetitorRankingInfo().apply(rankingInfo.getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead()).
|
||||
getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final double f_k = getTimeOnTimeFactor(rankingInfo.getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead());
|
||||
final double g_k = getTimeOnDistanceFactorInSecondsPerNauticalMile(rankingInfo.getLeaderByCorrectedEstimatedTimeToCompetitorFarthestAhead());
|
||||
final Duration t_i = rankingInfo.getCompetitorRankingInfo().get(competitor).getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final Duration t_i = rankingInfo.getCompetitorRankingInfo().apply(competitor).getEstimatedActualDurationFromRaceStartToCompetitorFarthestAhead();
|
||||
final double f_i = getTimeOnTimeFactor(competitor);
|
||||
final double g_i = getTimeOnDistanceFactorInSecondsPerNauticalMile(competitor);
|
||||
final Distance d = rankingInfo.getCompetitorRankingInfo().get(rankingInfo.getCompetitorFarthestAhead()).getWindwardDistanceSailed();
|
||||
final Distance d = rankingInfo.getCompetitorRankingInfo().apply(rankingInfo.getCompetitorFarthestAhead()).getWindwardDistanceSailed();
|
||||
|
||||
final Duration diff_t_i = t_i.minus(t_k.times(f_k).plus(Duration.ONE_SECOND.times(d.getNauticalMiles() * (g_i - g_k))).divide(f_i));
|
||||
return diff_t_i;
|
||||
|
||||
Reference in new issue
Block a user