mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-02 17:19:37 +00:00
made RankingMetric serializable, added serialVersionUIDs. Implemented getCorrectedTime for TimeOnTimeAndDistanceRankingMetric
This commit is contained in:
1 parent
d2e318899c
commit
636bc9e925
8 files changed
+296
-40
No files matched your search
Executable
+69
@@ -0,0 +1,69 @@
|
|||||||
|
package com.sap.sailing.domain.ranking;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.base.Waypoint;
|
||||||
|
import com.sap.sailing.domain.common.Distance;
|
||||||
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
import com.sap.sse.common.Duration;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
public abstract class AbstractRankingMetric implements RankingMetric {
|
||||||
|
private static final long serialVersionUID = -3671039530564696392L;
|
||||||
|
private final TrackedRace trackedRace;
|
||||||
|
|
||||||
|
protected AbstractRankingMetric(TrackedRace trackedRace) {
|
||||||
|
super();
|
||||||
|
this.trackedRace = trackedRace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackedRace getTrackedRace() {
|
||||||
|
return trackedRace;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Duration getActualTimeSinceStartOfRace(Competitor competitor, TimePoint timePoint) {
|
||||||
|
final Duration result;
|
||||||
|
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||||
|
if (startOfRace == null) {
|
||||||
|
result = null;
|
||||||
|
} else {
|
||||||
|
final Waypoint finish = getTrackedRace().getRace().getCourse().getLastWaypoint();
|
||||||
|
if (finish == null) {
|
||||||
|
result = null;
|
||||||
|
} else {
|
||||||
|
final MarkPassing finishingMarkPassing = getTrackedRace().getMarkPassing(competitor, finish);
|
||||||
|
if (finishingMarkPassing != null) {
|
||||||
|
result = startOfRace.until(finishingMarkPassing.getTimePoint());
|
||||||
|
} else {
|
||||||
|
result = startOfRace.until(timePoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Distance getWindwardDistanceTraveled(Competitor competitor, TimePoint timePoint) {
|
||||||
|
TrackedLegOfCompetitor currentLeg = getTrackedRace().getCurrentLeg(competitor, timePoint);
|
||||||
|
final Distance result;
|
||||||
|
if (currentLeg == null) {
|
||||||
|
result = null;
|
||||||
|
} else {
|
||||||
|
Distance d = Distance.NULL;
|
||||||
|
for (TrackedLeg trackedLeg : getTrackedRace().getTrackedLegs()) {
|
||||||
|
if (trackedLeg.getLeg() == currentLeg.getLeg()) {
|
||||||
|
// partial distance sailed:
|
||||||
|
d = d.add(trackedLeg.getWindwardDistanceFromLegStart(getTrackedRace().getTrack(competitor)
|
||||||
|
.getEstimatedPosition(timePoint, /* extrapolate */true)));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
d = d.add(trackedLeg.getWindwardDistance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = d;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/ORCPerformanceCurveRankingMetric.java
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package com.sap.sailing.domain.ranking;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
||||||
|
import com.sap.sse.common.Duration;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||||
|
private static final long serialVersionUID = -7814822523533929816L;
|
||||||
|
|
||||||
|
public ORCPerformanceCurveRankingMetric(TrackedRace trackedRace) {
|
||||||
|
super(trackedRace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<Competitor> getRaceRankingComparator(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<TrackedLegOfCompetitor> getLegRankingComparator(TrackedLeg trackedLeg, TimePoint timePoint,
|
||||||
|
WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getTimeToImprove(Competitor trailing, Competitor leading, TimePoint timePoint,
|
||||||
|
WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+14
-28
@@ -3,8 +3,6 @@ package com.sap.sailing.domain.ranking;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.Waypoint;
|
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
|
||||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
@@ -15,10 +13,16 @@ import com.sap.sailing.domain.tracking.impl.WindwardToGoComparator;
|
|||||||
import com.sap.sse.common.Duration;
|
import com.sap.sse.common.Duration;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
public class OneDesignRankingMetric implements RankingMetric {
|
public class OneDesignRankingMetric extends AbstractRankingMetric {
|
||||||
|
private static final long serialVersionUID = -8141113385324184349L;
|
||||||
|
|
||||||
|
public OneDesignRankingMetric(TrackedRace trackedRace) {
|
||||||
|
super(trackedRace);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparator<Competitor> getRaceRankingComparator(TrackedRace trackedRace, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
public Comparator<Competitor> getRaceRankingComparator(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
return new RaceRankComparator(trackedRace, timePoint, cache);
|
return new RaceRankComparator(getTrackedRace(), timePoint, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -28,10 +32,10 @@ public class OneDesignRankingMetric implements RankingMetric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Duration getTimeToImprove(TrackedRace trackedRace, Competitor trailing, Competitor leading,
|
public Duration getTimeToImprove(Competitor trailing, Competitor leading, TimePoint timePoint,
|
||||||
TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
WindLegTypeAndLegBearingCache cache) {
|
||||||
final Duration result;
|
final Duration result;
|
||||||
final TrackedLegOfCompetitor currentLeg = trackedRace.getCurrentLeg(trailing, timePoint);
|
final TrackedLegOfCompetitor currentLeg = getTrackedRace().getCurrentLeg(trailing, timePoint);
|
||||||
if (currentLeg != null) {
|
if (currentLeg != null) {
|
||||||
result = currentLeg.getGapToLeader(timePoint, leading, WindPositionMode.LEG_MIDDLE, cache);
|
result = currentLeg.getGapToLeader(timePoint, leading, WindPositionMode.LEG_MIDDLE, cache);
|
||||||
} else {
|
} else {
|
||||||
@@ -41,25 +45,7 @@ public class OneDesignRankingMetric implements RankingMetric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Duration getCorrectedTime(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint,
|
public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
WindLegTypeAndLegBearingCache cache) {
|
return getActualTimeSinceStartOfRace(competitor, timePoint);
|
||||||
final Duration result;
|
|
||||||
final TimePoint startOfRace = trackedRace.getStartOfRace();
|
|
||||||
if (startOfRace == null) {
|
|
||||||
result = null;
|
|
||||||
} else {
|
|
||||||
final Waypoint finish = trackedRace.getRace().getCourse().getLastWaypoint();
|
|
||||||
if (finish == null) {
|
|
||||||
result = null;
|
|
||||||
} else {
|
|
||||||
final MarkPassing finishingMarkPassing = trackedRace.getMarkPassing(competitor, finish);
|
|
||||||
if (finishingMarkPassing != null) {
|
|
||||||
result = startOfRace.until(finishingMarkPassing.getTimePoint());
|
|
||||||
} else {
|
|
||||||
result = startOfRace.until(timePoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sap.sailing.domain.ranking;
|
package com.sap.sailing.domain.ranking;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
@@ -7,7 +8,6 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
|
|||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
||||||
import com.sap.sailing.domain.tracking.impl.NoCachingWindLegTypeAndLegBearingCache;
|
|
||||||
import com.sap.sse.common.Duration;
|
import com.sap.sse.common.Duration;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
@@ -32,12 +32,13 @@ import com.sap.sse.common.TimePoint;
|
|||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public interface RankingMetric {
|
public interface RankingMetric extends Serializable {
|
||||||
default Comparator<Competitor> getRankingComparator(TrackedRace trackedRace, TimePoint timePoint) {
|
/**
|
||||||
return getRaceRankingComparator(trackedRace, null, new NoCachingWindLegTypeAndLegBearingCache());
|
* @return the tracked race to which this ranking metric is specific
|
||||||
}
|
*/
|
||||||
|
TrackedRace getTrackedRace();
|
||||||
Comparator<Competitor> getRaceRankingComparator(TrackedRace trackedRace, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
|
||||||
|
Comparator<Competitor> getRaceRankingComparator(TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||||
|
|
||||||
Comparator<TrackedLegOfCompetitor> getLegRankingComparator(TrackedLeg trackedLeg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
Comparator<TrackedLegOfCompetitor> getLegRankingComparator(TrackedLeg trackedLeg, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||||
|
|
||||||
@@ -53,8 +54,7 @@ public interface RankingMetric {
|
|||||||
* uncertain prediction of the <code>trailing</code> competitor's performance in the next leg which is not considered to be
|
* uncertain prediction of the <code>trailing</code> competitor's performance in the next leg which is not considered to be
|
||||||
* useful here.
|
* useful here.
|
||||||
*/
|
*/
|
||||||
Duration getTimeToImprove(TrackedRace trackedRace, Competitor trailing, Competitor leading, TimePoint timePoint,
|
Duration getTimeToImprove(Competitor trailing, Competitor leading, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||||
WindLegTypeAndLegBearingCache cache);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How much time did the <code>competitor</code> spend in the {@link TrackedRace#getRace() race} described by
|
* How much time did the <code>competitor</code> spend in the {@link TrackedRace#getRace() race} described by
|
||||||
@@ -72,5 +72,5 @@ public interface RankingMetric {
|
|||||||
* This method can also be used to calculate the corrected times at the end of each leg, simply by passing the time
|
* This method can also be used to calculate the corrected times at the end of each leg, simply by passing the time
|
||||||
* when the competitor finished the respective leg as <code>timePoint</code>.
|
* when the competitor finished the respective leg as <code>timePoint</code>.
|
||||||
*/
|
*/
|
||||||
Duration getCorrectedTime(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache);
|
||||||
}
|
}
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
package com.sap.sailing.domain.ranking;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.common.Distance;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
||||||
|
import com.sap.sse.common.Duration;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
|
||||||
|
private static final long serialVersionUID = -2321904208518686420L;
|
||||||
|
|
||||||
|
public TimeOnTimeAndDistanceRankingMetric(TrackedRace trackedRace) {
|
||||||
|
super(trackedRace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<Competitor> getRaceRankingComparator(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<TrackedLegOfCompetitor> getLegRankingComparator(TrackedLeg trackedLeg, TimePoint timePoint,
|
||||||
|
WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getTimeToImprove(Competitor trailing, Competitor leading, TimePoint timePoint,
|
||||||
|
WindLegTypeAndLegBearingCache cache) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
|
||||||
|
final Duration timeActuallySpent = getActualTimeSinceStartOfRace(competitor, timePoint);
|
||||||
|
final Duration result;
|
||||||
|
if (timeActuallySpent == null) {
|
||||||
|
result = null;
|
||||||
|
} else {
|
||||||
|
final Distance windwardDistanceSailed = getWindwardDistanceTraveled(competitor, timePoint);
|
||||||
|
final Duration correctedTimeByTimeOnTime = timeActuallySpent.times(Double.valueOf(getTimeOnTimeFactor(competitor, timePoint)).longValue());
|
||||||
|
if (windwardDistanceSailed == null) {
|
||||||
|
result = correctedTimeByTimeOnTime;
|
||||||
|
} else {
|
||||||
|
final Duration timeOnDistanceAllowance = Duration.ONE_SECOND.times(Double.valueOf(
|
||||||
|
windwardDistanceSailed.getNauticalMiles() * getTimeOnDistanceFactorInSecondsPerNauticalMile(competitor, timePoint)).
|
||||||
|
longValue());
|
||||||
|
result = correctedTimeByTimeOnTime.minus(timeOnDistanceAllowance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getTimeOnTimeFactor(Competitor competitor, TimePoint timePoint) {
|
||||||
|
return 1.0; // TODO see bug 2765; obtain this from the Competitor
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getTimeOnDistanceFactorInSecondsPerNauticalMile(Competitor competitor, TimePoint timePoint) {
|
||||||
|
return 0.0; // TODO see bug 2765; obtain this from the Competitor
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -100,6 +100,23 @@ public interface TrackedLeg extends Serializable {
|
|||||||
* leg's direction, or a positive distance otherwise.
|
* leg's direction, or a positive distance otherwise.
|
||||||
*/
|
*/
|
||||||
Distance getWindwardDistance(Position pos1, Position pos2, TimePoint at, WindPositionMode windPositionMode);
|
Distance getWindwardDistance(Position pos1, Position pos2, TimePoint at, WindPositionMode windPositionMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the windward distance for upwind/downwind legs or the great circle distance between this leg's waypoints
|
||||||
|
* that competitors need to travel in this leg. Due to the dynamics of the wind direction and the mark positions,
|
||||||
|
* the result is time dependent. The wind direction is determined at the leg's middle at the time point <code>at</code>.
|
||||||
|
*/
|
||||||
|
Distance getWindwardDistance(TimePoint at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the windward distance for upwind/downwind legs or the great circle distance between this leg's waypoints
|
||||||
|
* that competitors need to travel in this leg. Due to the dynamics of the wind direction and the mark positions,
|
||||||
|
* the result is time dependent. As time point, the middle of the interval defined by the first mark passing starting the
|
||||||
|
* leg and the last mark passing finishing the leg is used, where both time points default to "now."
|
||||||
|
*
|
||||||
|
* @see #getWindwardDistance(TimePoint)
|
||||||
|
*/
|
||||||
|
Distance getWindwardDistance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The middle (traveling half the length) of the course middle line, connecting the center of gravity of the leg's start
|
* The middle (traveling half the length) of the course middle line, connecting the center of gravity of the leg's start
|
||||||
@@ -107,4 +124,11 @@ public interface TrackedLeg extends Serializable {
|
|||||||
*/
|
*/
|
||||||
Position getMiddleOfLeg(TimePoint at);
|
Position getMiddleOfLeg(TimePoint at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the windward distance (for upwind/downwind legs) or the along-course distance (for reaching legs) at a reference time point
|
||||||
|
* between the leg's start waypoint position and <code>pos</code>. The reference time point is chosen as the middle between the first
|
||||||
|
* leg entry and the last leg exit, both defaulting to "now" if no such time point exists.
|
||||||
|
*/
|
||||||
|
Distance getWindwardDistanceFromLegStart(Position pos);
|
||||||
|
|
||||||
}
|
}
|
||||||
+60
@@ -6,6 +6,7 @@ import java.io.Serializable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -24,6 +25,7 @@ import com.sap.sailing.domain.common.Wind;
|
|||||||
import com.sap.sailing.domain.common.WindSource;
|
import com.sap.sailing.domain.common.WindSource;
|
||||||
import com.sap.sailing.domain.common.WindSourceType;
|
import com.sap.sailing.domain.common.WindSourceType;
|
||||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||||
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
@@ -32,6 +34,7 @@ import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
|||||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
public class TrackedLegImpl implements TrackedLeg {
|
public class TrackedLegImpl implements TrackedLeg {
|
||||||
private static final long serialVersionUID = -1944668527284130545L;
|
private static final long serialVersionUID = -1944668527284130545L;
|
||||||
@@ -336,11 +339,68 @@ public class TrackedLegImpl implements TrackedLeg {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Distance getWindwardDistanceFromLegStart(Position pos) {
|
||||||
|
final TimePoint referenceTimePoint = getReferenceTimePoint();
|
||||||
|
return getWindwardDistance(getTrackedRace().getApproximatePosition(getLeg().getFrom(), referenceTimePoint),
|
||||||
|
pos, referenceTimePoint, WindPositionMode.LEG_MIDDLE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distance getWindwardDistance(Position pos1, Position pos2, TimePoint at, WindPositionMode windPositionMode) {
|
public Distance getWindwardDistance(Position pos1, Position pos2, TimePoint at, WindPositionMode windPositionMode) {
|
||||||
return getWindwardDistance(pos1, pos2, at, windPositionMode, new NoCachingWindLegTypeAndLegBearingCache());
|
return getWindwardDistance(pos1, pos2, at, windPositionMode, new NoCachingWindLegTypeAndLegBearingCache());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Distance getWindwardDistance() {
|
||||||
|
final TimePoint middle = getReferenceTimePoint();
|
||||||
|
return getWindwardDistance(middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a reference time point for this leg that is the same for all competitors and that is the middle between
|
||||||
|
* the time points of first leg entry and last leg exit. If no competitor has entered the leg, "now" is used as a
|
||||||
|
* default. If competitors have entered the leg but none has finished it yet, the middle between first entry and
|
||||||
|
* "now" is used.
|
||||||
|
*/
|
||||||
|
private TimePoint getReferenceTimePoint() {
|
||||||
|
Iterable<MarkPassing> legStartMarkPassings = getTrackedRace().getMarkPassingsInOrder(getLeg().getFrom());
|
||||||
|
Iterable<MarkPassing> legFinishMarkPassings = getTrackedRace().getMarkPassingsInOrder(getLeg().getTo());
|
||||||
|
getTrackedRace().lockForRead(legStartMarkPassings);
|
||||||
|
final TimePoint firstLegStartMarkPassingTimePoint;
|
||||||
|
final TimePoint lastLegFinishMarkPassingTimePoint;
|
||||||
|
try {
|
||||||
|
Iterator<MarkPassing> i = legStartMarkPassings.iterator();
|
||||||
|
if (i.hasNext()) {
|
||||||
|
firstLegStartMarkPassingTimePoint = i.next().getTimePoint();
|
||||||
|
} else {
|
||||||
|
firstLegStartMarkPassingTimePoint = MillisecondsTimePoint.now();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
getTrackedRace().unlockAfterRead(legStartMarkPassings);
|
||||||
|
}
|
||||||
|
getTrackedRace().lockForRead(legFinishMarkPassings);
|
||||||
|
try {
|
||||||
|
Iterator<MarkPassing> i = legFinishMarkPassings.iterator();
|
||||||
|
if (i.hasNext()) {
|
||||||
|
lastLegFinishMarkPassingTimePoint = i.next().getTimePoint();
|
||||||
|
} else {
|
||||||
|
lastLegFinishMarkPassingTimePoint = MillisecondsTimePoint.now();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
getTrackedRace().unlockAfterRead(legFinishMarkPassings);
|
||||||
|
}
|
||||||
|
final TimePoint middle = firstLegStartMarkPassingTimePoint.plus(firstLegStartMarkPassingTimePoint.until(lastLegFinishMarkPassingTimePoint).divide(2));
|
||||||
|
return middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Distance getWindwardDistance(final TimePoint middle) {
|
||||||
|
final Position fromPos = getTrackedRace().getApproximatePosition(getLeg().getFrom(), middle);
|
||||||
|
final Position toPos = getTrackedRace().getApproximatePosition(getLeg().getTo(), middle);
|
||||||
|
return getWindwardDistance(fromPos, toPos, middle, WindPositionMode.LEG_MIDDLE);
|
||||||
|
}
|
||||||
|
|
||||||
Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
|
||||||
Distance result;
|
Distance result;
|
||||||
try {
|
try {
|
||||||
|
|||||||
+2
-2
@@ -335,7 +335,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
|
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
|
||||||
boolean useInternalMarkPassingAlgorithm) {
|
boolean useInternalMarkPassingAlgorithm) {
|
||||||
super(race, trackedRegatta, windStore, millisecondsOverWhichToAverageWind);
|
super(race, trackedRegatta, windStore, millisecondsOverWhichToAverageWind);
|
||||||
rankingMetric = new OneDesignRankingMetric(); // for now we can only do one-design classes; see bug 1018
|
rankingMetric = new OneDesignRankingMetric(this); // for now we can only do one-design classes; see bug 1018
|
||||||
raceStates = new WeakHashMap<>();
|
raceStates = new WeakHashMap<>();
|
||||||
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
|
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
|
||||||
locksForMarkPassings = new IdentityHashMap<>();
|
locksForMarkPassings = new IdentityHashMap<>();
|
||||||
@@ -1173,7 +1173,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
// RaceRankComparator requires course read lock
|
// RaceRankComparator requires course read lock
|
||||||
getRace().getCourse().lockForRead();
|
getRace().getCourse().lockForRead();
|
||||||
try {
|
try {
|
||||||
Comparator<Competitor> comparator = getRankingMetric().getRaceRankingComparator(this, timePoint, cache);
|
Comparator<Competitor> comparator = getRankingMetric().getRaceRankingComparator(timePoint, cache);
|
||||||
rankedCompetitors = new ArrayList<Competitor>();
|
rankedCompetitors = new ArrayList<Competitor>();
|
||||||
for (Competitor c : getRace().getCompetitors()) {
|
for (Competitor c : getRace().getCompetitors()) {
|
||||||
rankedCompetitors.add(c);
|
rankedCompetitors.add(c);
|
||||||
|
|||||||
Reference in new issue
Block a user