mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-26 23:46:36 +00:00
bug5217: unfinished (5) ; first version of the race comparison
This commit is contained in:
+52
-65
@@ -1,95 +1,82 @@
|
||||
package com.sap.sailing.domain.test.hash;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||
import com.sap.sailing.domain.test.OnlineTracTracBasedTest;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class CalculatingHashTest extends OnlineTracTracBasedTest{
|
||||
public class CalculatingHashTest extends OnlineTracTracBasedTest {
|
||||
private static final Logger logger = Logger.getLogger(CalculatingHashTest.class.getName());
|
||||
DynamicTrackedRaceImpl trackedRace1;
|
||||
DynamicTrackedRaceImpl trackedRace2;
|
||||
|
||||
|
||||
public CalculatingHashTest() throws MalformedURLException, URISyntaxException {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getExpectedEventName() {
|
||||
return "Academy Tracking 2011";
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception{
|
||||
public void setUp() throws Exception {
|
||||
super.setUp("event_20110505_SailingTea", // Semifinale
|
||||
/* raceId */ "01ea3604-02ef-11e1-9efc-406186cbf87c",
|
||||
/* liveUri */ null, /* storedUri */ null,
|
||||
new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA});
|
||||
/* raceId */ "01ea3604-02ef-11e1-9efc-406186cbf87c", /* liveUri */ null, /* storedUri */ null,
|
||||
new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE,
|
||||
ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA });
|
||||
trackedRace1 = getTrackedRace();
|
||||
super.setUp();
|
||||
super.setUp("event_20110505_SailingTea", // Semifinale
|
||||
/* raceId */ "01ea3604-02ef-11e1-9efc-406186cbf87c",
|
||||
/* liveUri */ null, /* storedUri */ null,
|
||||
new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA});
|
||||
/* raceId */ "01ea3604-02ef-11e1-9efc-406186cbf87c", /* liveUri */ null, /* storedUri */ null,
|
||||
new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE,
|
||||
ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA });
|
||||
trackedRace2 = getTrackedRace();
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testWithoutChangesInRace() {
|
||||
// trackedRace1.calculateHash();
|
||||
// int[] hash1 = trackedRace1.getHashValue();
|
||||
// trackedRace2.calculateHash();
|
||||
// int[] hash2 = trackedRace2.getHashValue();
|
||||
//
|
||||
// assertEquals("0: Hash1: " + hash1[0] + " Hash2: " + hash2[0], hash1[0], hash2[0]);
|
||||
// assertEquals("1: Hash1: " + hash1[1] + " Hash2: " + hash2[1], hash1[1], hash2[1]);
|
||||
// assertEquals("2: Hash1: " + hash1[2] + " Hash2: " + hash2[2], hash1[2], hash2[2]);
|
||||
// assertEquals("3: Hash1: " + hash1[3] + " Hash2: " + hash2[3], hash1[3], hash2[3]);
|
||||
// assertEquals("4: Hash1: " + hash1[4] + " Hash2: " + hash2[4], hash1[4], hash2[4]);
|
||||
// assertEquals("5: Hash1: " + hash1[5] + " Hash2: " + hash2[5], hash1[5], hash2[5]);
|
||||
// assertEquals("6: Hash1: " + hash1[6] + " Hash2: " + hash2[6], hash1[6], hash2[6]);
|
||||
// //assertEquals("7: Hash1: " + hash1[7] + " Hash2: " + hash2[7], hash1[7], hash2[7]);
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void testWithChangesInRace() {
|
||||
// trackedRace1.calculateHash();
|
||||
// int[] hash1 = trackedRace1.getHashValue();
|
||||
//// Change of the race should result in a different hash
|
||||
// TimePoint epoch = new MillisecondsTimePoint(0l);
|
||||
// TimePoint now = MillisecondsTimePoint.now();
|
||||
// Map<String, Position> markPositions = new HashMap<String, Position>();
|
||||
// markPositions.put("CR Start (1)", new DegreePosition(53.562944999999985, 10.010104000000046));
|
||||
// markPositions.put("CR Start (2)", new DegreePosition(53.562944999999985, 10.010104000000046));
|
||||
// markPositions.put("Leeward mark", new DegreePosition(53.562145000000015, 10.009252));
|
||||
// markPositions.put("Luvtonne", new DegreePosition(53.560581899999995, 10.005657));
|
||||
// for (Waypoint w : getTrackedRace().getRace().getCourse().getWaypoints()) {
|
||||
// for (Mark mark : w.getMarks()) {
|
||||
// trackedRace2.getOrCreateTrack(mark).addGPSFix(new GPSFixImpl(markPositions.get(mark.getName()), epoch));
|
||||
// trackedRace2.getOrCreateTrack(mark).addGPSFix(new GPSFixImpl(markPositions.get(mark.getName()), now));
|
||||
// }
|
||||
// }
|
||||
// trackedRace2.calculateHash();
|
||||
// int[] hash2 = trackedRace2.getHashValue();
|
||||
//
|
||||
// assertNotEquals("Hash1 and Hash2 are equal", hash1, hash2);
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void testWithoutChangesInRace() {
|
||||
// trackedRace1.calculateHash();
|
||||
// int[] hash1 = trackedRace1.getHashValue();
|
||||
// trackedRace2.calculateHash();
|
||||
// int[] hash2 = trackedRace2.getHashValue();
|
||||
//
|
||||
// assertEquals("0: Hash1: " + hash1[0] + " Hash2: " + hash2[0], hash1[0], hash2[0]);
|
||||
// assertEquals("1: Hash1: " + hash1[1] + " Hash2: " + hash2[1], hash1[1], hash2[1]);
|
||||
// assertEquals("2: Hash1: " + hash1[2] + " Hash2: " + hash2[2], hash1[2], hash2[2]);
|
||||
// assertEquals("3: Hash1: " + hash1[3] + " Hash2: " + hash2[3], hash1[3], hash2[3]);
|
||||
// assertEquals("4: Hash1: " + hash1[4] + " Hash2: " + hash2[4], hash1[4], hash2[4]);
|
||||
// assertEquals("5: Hash1: " + hash1[5] + " Hash2: " + hash2[5], hash1[5], hash2[5]);
|
||||
// assertEquals("6: Hash1: " + hash1[6] + " Hash2: " + hash2[6], hash1[6], hash2[6]);
|
||||
// //assertEquals("7: Hash1: " + hash1[7] + " Hash2: " + hash2[7], hash1[7], hash2[7]);
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void testWithChangesInRace() {
|
||||
// trackedRace1.calculateHash();
|
||||
// int[] hash1 = trackedRace1.getHashValue();
|
||||
//// Change of the race should result in a different hash
|
||||
// TimePoint epoch = new MillisecondsTimePoint(0l);
|
||||
// TimePoint now = MillisecondsTimePoint.now();
|
||||
// Map<String, Position> markPositions = new HashMap<String, Position>();
|
||||
// markPositions.put("CR Start (1)", new DegreePosition(53.562944999999985, 10.010104000000046));
|
||||
// markPositions.put("CR Start (2)", new DegreePosition(53.562944999999985, 10.010104000000046));
|
||||
// markPositions.put("Leeward mark", new DegreePosition(53.562145000000015, 10.009252));
|
||||
// markPositions.put("Luvtonne", new DegreePosition(53.560581899999995, 10.005657));
|
||||
// for (Waypoint w : getTrackedRace().getRace().getCourse().getWaypoints()) {
|
||||
// for (Mark mark : w.getMarks()) {
|
||||
// trackedRace2.getOrCreateTrack(mark).addGPSFix(new GPSFixImpl(markPositions.get(mark.getName()), epoch));
|
||||
// trackedRace2.getOrCreateTrack(mark).addGPSFix(new GPSFixImpl(markPositions.get(mark.getName()), now));
|
||||
// }
|
||||
// }
|
||||
// trackedRace2.calculateHash();
|
||||
// int[] hash2 = trackedRace2.getHashValue();
|
||||
//
|
||||
// assertNotEquals("Hash1 and Hash2 are equal", hash1, hash2);
|
||||
// }
|
||||
}
|
||||
|
||||
+3
-3
@@ -50,6 +50,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.impl.CompetitorProviderFromRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
|
||||
@@ -89,7 +90,6 @@ import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindSummary;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceHashForMarkPassingComperatorImpl.typeOfHash;
|
||||
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
|
||||
import com.sap.sailing.domain.windestimation.IncrementalWindEstimation;
|
||||
import com.sap.sse.common.Bearing;
|
||||
@@ -1365,11 +1365,11 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHashValuesForMarkPassingCalculation(Map<typeOfHash, Integer> hashValues) {
|
||||
public void setHashValuesForMarkPassingCalculation(Map<TypeOfHash, Integer> hashValues) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<typeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
public Map<TypeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -41,6 +41,7 @@ import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
@@ -69,7 +70,6 @@ import com.sap.sailing.domain.tracking.WindSummary;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceHashForMarkPassingComperatorImpl.typeOfHash;
|
||||
import com.sap.sailing.domain.windestimation.IncrementalWindEstimation;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -876,11 +876,11 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHashValuesForMarkPassingCalculation(Map<typeOfHash, Integer> hashValues) {
|
||||
public void setHashValuesForMarkPassingCalculation(Map<TypeOfHash, Integer> hashValues) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<typeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
public Map<TypeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Export-Package: com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.markpassingcalculation,
|
||||
com.sap.sailing.domain.markpassingcalculation.impl,
|
||||
com.sap.sailing.domain.markpassingcalculation.splining,
|
||||
com.sap.sailing.domain.markpassinghash.impl;x-friends:="com.sap.sailing.domain.persistence",
|
||||
com.sap.sailing.domain.masterdataimport,
|
||||
com.sap.sailing.domain.orc,
|
||||
com.sap.sailing.domain.orc.impl;x-friends:="com.sap.sailing.domain.test,com.sap.sailing.domain.test,com.sap.sailing.mongodb.test",
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.sap.sailing.domain.markpassinghash;
|
||||
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
|
||||
public interface TrackedRaceHashForMarkPassingCalculation {
|
||||
|
||||
boolean equals(TrackedRaceImpl trackedRace);
|
||||
}
|
||||
+29
-27
@@ -1,67 +1,69 @@
|
||||
package com.sap.sailing.domain.tracking;
|
||||
package com.sap.sailing.domain.markpassinghash;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* This comperator is used to calculate a set of hashes for a {@link trackedRace}
|
||||
* in order to lay the foundation to decide if the {@link markpassings} are recalculated or
|
||||
* loaded out of the database, when restarting a server.
|
||||
* This comperator is used to calculate a set of hashes for a {@link trackedRace} in order to lay the foundation to
|
||||
* decide if the {@link markpassings} are recalculated or loaded out of the database, when restarting a server.
|
||||
*
|
||||
* @author Fabian Kallenbach (I550803)
|
||||
*
|
||||
*/
|
||||
|
||||
public interface TrackedRaceHashForMarkPassingComperator {
|
||||
public interface TrackedRaceHashForMarkPassingComparator {
|
||||
/**
|
||||
* This Method loads the individual hashes into the local hashmap and then {@link #setHashValuesForMarkPassingCalculation} in {@link TrackedRace}.
|
||||
* This Method loads the individual hashes into the local hashmap and then
|
||||
* {@link #setHashValuesForMarkPassingCalculation} in {@link TrackedRace}.
|
||||
*/
|
||||
void CalculateHash();
|
||||
|
||||
void calculateHash();
|
||||
|
||||
/**
|
||||
* Calculates the hash for the {@link competitor} on the basis of it's ID.
|
||||
*/
|
||||
int CalculateHashForCompetitor (Competitor c);
|
||||
|
||||
int calculateHashForCompetitor(Competitor c);
|
||||
|
||||
/**
|
||||
* Calculates the hash for the {@link boat} on the basis of it's ID.
|
||||
*/
|
||||
int CalculateHashForBoat (Boat b);
|
||||
|
||||
int calculateHashForBoat(Boat b);
|
||||
|
||||
/**
|
||||
* Calculates the hash for the race start on the basis of {@link #getStartOfTracking} and if it isn't inferred also on the {@link #getStartOfRace}.
|
||||
* Calculates the hash for the race start on the basis of {@link #getStartOfTracking} and if it isn't inferred also
|
||||
* on the {@link #getStartOfRace}.
|
||||
*/
|
||||
int CalculateHashForStart ();
|
||||
|
||||
int calculateHashForStart();
|
||||
|
||||
/**
|
||||
* Calculates the hash for the race end on the basis of {@link #getEndOfTracking}.
|
||||
*/
|
||||
int CalculateHashForEnd ();
|
||||
|
||||
int calculateHashForEnd();
|
||||
|
||||
/**
|
||||
* Calculates the hash for the number of GPSFixes of the {@link trackedRace}.
|
||||
* Calculates the hash for the number of GPSFixes of the {@link trackedRace}.
|
||||
*/
|
||||
int CalculateHashForNumberOfGPSFixes ();
|
||||
|
||||
int calculateHashForNumberOfGPSFixes();
|
||||
|
||||
/**
|
||||
* Calculates the hash for all {@link GPSFix} on the basis of theire {@link TimePoint}s and {@link Position}s.
|
||||
*/
|
||||
int CalculateHashForGPSFixes ();
|
||||
|
||||
int calculateHashForGPSFixes();
|
||||
|
||||
/**
|
||||
* Calculates the hash for a {@link TimePoint}.
|
||||
*/
|
||||
int CalculateHashForTimePoint (TimePoint tp);
|
||||
|
||||
int calculateHashForTimePoint(TimePoint tp);
|
||||
|
||||
/**
|
||||
* Calculates the hash for a {@link Position}.
|
||||
*/
|
||||
int CalculateHashForPosition (Position p);
|
||||
|
||||
int calculateHashForPosition(Position p);
|
||||
|
||||
/**
|
||||
* Calculates the hash for a {@link Waypoint}.
|
||||
*/
|
||||
int CalculateHashForWaypoints ();
|
||||
int calculateHashForWaypoints();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.sap.sailing.domain.markpassinghash;
|
||||
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingCalculationImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
|
||||
public interface TrackedRaceHashForMaskPassingCalculationFactory {
|
||||
|
||||
TrackedRaceHashForMarkPassingCalculationImpl create(TrackedRaceImpl trackedRace);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.sap.sailing.domain.markpassinghash.impl;
|
||||
|
||||
import com.sap.sailing.domain.markpassinghash.TrackedRaceHashForMaskPassingCalculationFactory;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
|
||||
public class TrackedRaceHashForMarkPassingCalculationFactoryImpl implements TrackedRaceHashForMaskPassingCalculationFactory{
|
||||
private final TrackedRace trackedRace;
|
||||
|
||||
public TrackedRaceHashForMarkPassingCalculationFactoryImpl(TrackedRaceImpl trackedRace) {
|
||||
this.trackedRace = trackedRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedRaceHashForMarkPassingCalculationImpl create(TrackedRaceImpl trackedRace) {
|
||||
|
||||
TrackedRaceHashForMarkPassingCalculationImpl hashValues = new TrackedRaceHashForMarkPassingCalculationImpl(trackedRace.getHashValuesForMarkPassingCalculation());
|
||||
return hashValues;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.sap.sailing.domain.markpassinghash.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
|
||||
public class TrackedRaceHashForMarkPassingCalculationImpl {
|
||||
private final int competitor;
|
||||
private final int start;
|
||||
private final int end;
|
||||
private final int waypoints;
|
||||
private final int numberOfGPSFixes;
|
||||
private final int gpsFixes;
|
||||
|
||||
public TrackedRaceHashForMarkPassingCalculationImpl(Map<TypeOfHash, Integer> hashValues) {
|
||||
this.competitor = hashValues.get(TypeOfHash.COMPETITOR);
|
||||
this.start = hashValues.get(TypeOfHash.START);
|
||||
this.end = hashValues.get(TypeOfHash.END);
|
||||
this.waypoints = hashValues.get(TypeOfHash.WAYPOINTS);
|
||||
this.numberOfGPSFixes = hashValues.get(TypeOfHash.NUMBEROFGPSFIXES);
|
||||
this.gpsFixes = hashValues.get(TypeOfHash.GPSFIXES);
|
||||
|
||||
}
|
||||
|
||||
public boolean equals(TrackedRaceImpl trackedRace) {
|
||||
TrackedRaceHashForMarkPassingComparatorImpl hashCalculator = new TrackedRaceHashForMarkPassingComparatorImpl(
|
||||
trackedRace);
|
||||
int competitorHash = 0;
|
||||
|
||||
if (hashCalculator.calculateHashForWaypoints() != waypoints)
|
||||
return false;
|
||||
|
||||
for (Competitor c : trackedRace.getRace().getCompetitors()) {
|
||||
competitorHash = competitorHash + hashCalculator.calculateHashForCompetitor(c);
|
||||
}
|
||||
|
||||
if (competitorHash != competitor)
|
||||
return false;
|
||||
|
||||
if (hashCalculator.calculateHashForStart() != start)
|
||||
return false;
|
||||
|
||||
if (hashCalculator.calculateHashForEnd() != end)
|
||||
return false;
|
||||
|
||||
if (hashCalculator.calculateHashForNumberOfGPSFixes() != numberOfGPSFixes)
|
||||
return false;
|
||||
|
||||
if (hashCalculator.calculateHashForGPSFixes() != gpsFixes)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+70
-79
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
package com.sap.sailing.domain.markpassinghash.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -10,54 +10,46 @@ import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.tracking.TrackedRaceHashForMarkPassingComperator;
|
||||
import com.sap.sailing.domain.markpassinghash.TrackedRaceHashForMarkPassingComparator;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceHashForMarkPassingComperator{
|
||||
public class TrackedRaceHashForMarkPassingComparatorImpl implements TrackedRaceHashForMarkPassingComparator {
|
||||
|
||||
public enum TypeOfHash {
|
||||
COMPETITOR, START, END, WAYPOINTS, NUMBEROFGPSFIXES, GPSFIXES
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TrackedRaceHashForMarkPassingComparatorImpl.class.getName());
|
||||
|
||||
public enum typeOfHash {
|
||||
COMPETITOR,
|
||||
BOAT,
|
||||
START,
|
||||
END,
|
||||
WAYPOINTS,
|
||||
NUMBEROFGPSFIXES,
|
||||
GPSFIXES
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TrackedRaceHashForMarkPassingComperatorImpl.class.getName());
|
||||
|
||||
private TrackedRaceImpl trackedRace;
|
||||
private final Iterable<Waypoint> waypoints;
|
||||
private Map<typeOfHash, Integer> hashValues;
|
||||
|
||||
public TrackedRaceHashForMarkPassingComperatorImpl (TrackedRaceImpl trackedRace) {
|
||||
private Map<TypeOfHash, Integer> hashValues;
|
||||
|
||||
public TrackedRaceHashForMarkPassingComparatorImpl(TrackedRaceImpl trackedRace) {
|
||||
this.trackedRace = trackedRace;
|
||||
this.waypoints = trackedRace.getRace().getCourse().getWaypoints();
|
||||
this.hashValues = new HashMap<>();
|
||||
}
|
||||
|
||||
public void CalculateHash() {
|
||||
|
||||
public void calculateHash() {
|
||||
int competitorHash = 0;
|
||||
int boatHash = 0;
|
||||
hashValues.put(typeOfHash.WAYPOINTS, CalculateHashForWaypoints());
|
||||
hashValues.put(TypeOfHash.WAYPOINTS, calculateHashForWaypoints());
|
||||
for (Competitor c : trackedRace.getRace().getCompetitors()) {
|
||||
competitorHash = competitorHash + CalculateHashForCompetitor(c);
|
||||
boatHash = boatHash + CalculateHashForBoat(trackedRace.getRace().getBoatOfCompetitor(c));
|
||||
competitorHash = competitorHash + calculateHashForCompetitor(c);
|
||||
}
|
||||
hashValues.put(typeOfHash.COMPETITOR, competitorHash);
|
||||
hashValues.put(typeOfHash.BOAT, boatHash);
|
||||
hashValues.put(typeOfHash.START, CalculateHashForStart());
|
||||
hashValues.put(typeOfHash.END, CalculateHashForEnd());
|
||||
|
||||
hashValues.put(typeOfHash.NUMBEROFGPSFIXES, CalculateHashForNumberOfGPSFixes());
|
||||
hashValues.put(typeOfHash.GPSFIXES, CalculateHashForGPSFixes());
|
||||
|
||||
hashValues.put(TypeOfHash.COMPETITOR, competitorHash);
|
||||
hashValues.put(TypeOfHash.START, calculateHashForStart());
|
||||
hashValues.put(TypeOfHash.END, calculateHashForEnd());
|
||||
hashValues.put(TypeOfHash.NUMBEROFGPSFIXES, calculateHashForNumberOfGPSFixes());
|
||||
hashValues.put(TypeOfHash.GPSFIXES, calculateHashForGPSFixes());
|
||||
|
||||
trackedRace.setHashValuesForMarkPassingCalculation(hashValues);
|
||||
}
|
||||
|
||||
public int CalculateHashForCompetitor (Competitor c) {
|
||||
int res = 0;
|
||||
|
||||
public int calculateHashForCompetitor(Competitor c) {
|
||||
int res = 0;
|
||||
try {
|
||||
res = res ^ c.getId().hashCode();
|
||||
res = (res << 5) - res;
|
||||
@@ -66,50 +58,50 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForBoat (Boat b) {
|
||||
int res = 0;
|
||||
|
||||
public int calculateHashForBoat(Boat b) {
|
||||
int res = 0;
|
||||
try {
|
||||
res = res ^ b.getBoatClass().getName().hashCode();
|
||||
res = (res << 5) - res;
|
||||
} catch (Exception e) {
|
||||
logger.info("Hash calculation for competitor " + b + " failed: " + e);
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForStart () {
|
||||
|
||||
public int calculateHashForStart() {
|
||||
int res = 0;
|
||||
try {
|
||||
res = res ^ CalculateHashForTimePoint(trackedRace.getStartOfTracking());
|
||||
res = (res << 5) - res;
|
||||
res = res ^ calculateHashForTimePoint(trackedRace.getStartOfTracking());
|
||||
res = (res << 5) - res;
|
||||
} catch (Exception e) {
|
||||
logger.info("An error occured when getting the start of tracking: " + e);
|
||||
}
|
||||
try {
|
||||
//Maybe that could be solved by using .getStartOfRace(boolean inferred)
|
||||
if( trackedRace.getTrackedRegatta().getRegatta().useStartTimeInference() == false) {
|
||||
res = res ^ CalculateHashForTimePoint(trackedRace.getStartOfRace());
|
||||
// Maybe that could be solved by using .getStartOfRace(boolean inferred)
|
||||
if (trackedRace.getTrackedRegatta().getRegatta().useStartTimeInference() == false) {
|
||||
res = res ^ calculateHashForTimePoint(trackedRace.getStartOfRace());
|
||||
res = (res << 5) - res;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("An error occured when getting the starttime: " + e);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForEnd () {
|
||||
int res = 0;
|
||||
|
||||
public int calculateHashForEnd() {
|
||||
int res = 0;
|
||||
try {
|
||||
res = res ^ CalculateHashForTimePoint(trackedRace.getEndOfTracking());
|
||||
res = (res << 5) - res;
|
||||
res = res ^ calculateHashForTimePoint(trackedRace.getEndOfTracking());
|
||||
res = (res << 5) - res;
|
||||
} catch (Exception e) {
|
||||
logger.info("Hash calculation for end of Tracking failed: " + e);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForNumberOfGPSFixes () {
|
||||
|
||||
public int calculateHashForNumberOfGPSFixes() {
|
||||
int count = 0;
|
||||
for (Waypoint w : waypoints) {
|
||||
for (Mark m : w.getMarks()) {
|
||||
@@ -117,8 +109,8 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
try {
|
||||
trackedRace.getTrack(m).lockForRead();
|
||||
gpsTrack = trackedRace.getTrack(m).getFixes();
|
||||
//Unused warning since we need the individual Fixes only to count
|
||||
for (GPSFix gf : gpsTrack) {
|
||||
// Unused warning since we need the individual Fixes only to count
|
||||
for (int i = 0; i < Util.size(gpsTrack); i++) {
|
||||
count++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -130,9 +122,8 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
public int CalculateHashForGPSFixes () {
|
||||
|
||||
public int calculateHashForGPSFixes() {
|
||||
int res = 0;
|
||||
for (Waypoint w : waypoints) {
|
||||
for (Mark m : w.getMarks()) {
|
||||
@@ -141,9 +132,9 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
trackedRace.getTrack(m).lockForRead();
|
||||
gpsTrack = trackedRace.getTrack(m).getFixes();
|
||||
for (GPSFix gf : gpsTrack) {
|
||||
res = res ^ CalculateHashForTimePoint(gf.getTimePoint());
|
||||
res = res ^ calculateHashForTimePoint(gf.getTimePoint());
|
||||
res = (res << 5) - res;
|
||||
res = res ^ CalculateHashForPosition(gf.getPosition());
|
||||
res = res ^ calculateHashForPosition(gf.getPosition());
|
||||
res = (res << 5) - res;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -155,31 +146,31 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForTimePoint (TimePoint tp) {
|
||||
int res = 0;
|
||||
//How problematic is this cast?
|
||||
|
||||
public int calculateHashForTimePoint(TimePoint tp) {
|
||||
int res = 0;
|
||||
// How problematic is this cast?
|
||||
try {
|
||||
res = res ^ (int) tp.asMillis();
|
||||
res = (res << 5) - res;
|
||||
} catch (Exception e) {
|
||||
logger.info("Ther");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForPosition (Position p) {
|
||||
int res = 0;
|
||||
res = res ^ (int) p.getLatDeg();
|
||||
res = res ^ (int) p.getLngDeg();
|
||||
res = (res << 5) - res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public int CalculateHashForWaypoints () {
|
||||
|
||||
public int calculateHashForPosition(Position p) {
|
||||
int res = 0;
|
||||
for(Waypoint p : waypoints) {
|
||||
res = res ^ (int) p.getLatDeg();
|
||||
res = res ^ (int) p.getLngDeg();
|
||||
res = (res << 5) - res;
|
||||
return res;
|
||||
}
|
||||
|
||||
public int calculateHashForWaypoints() {
|
||||
int res = 0;
|
||||
for (Waypoint p : waypoints) {
|
||||
res = res ^ p.getId().hashCode();
|
||||
try {
|
||||
res = res ^ p.getPassingInstructions().hashCode();
|
||||
@@ -187,6 +178,6 @@ public class TrackedRaceHashForMarkPassingComperatorImpl implements TrackedRaceH
|
||||
logger.info("Hash calculation for Waypoints failed: " + e);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -35,13 +35,13 @@ import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceHashForMarkPassingComperatorImpl.typeOfHash;
|
||||
import com.sap.sailing.domain.windestimation.IncrementalWindEstimation;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -814,11 +814,11 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHashValuesForMarkPassingCalculation(Map<typeOfHash, Integer> hashValues) {
|
||||
public void setHashValuesForMarkPassingCalculation(Map<TypeOfHash, Integer> hashValues) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<typeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
public Map<TypeOfHash, Integer> getHashValuesForMarkPassingCalculation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+264
-224
@@ -52,6 +52,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
|
||||
@@ -60,7 +61,6 @@ import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.impl.NonCachingMarkPositionAtTimePointCache;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceHashForMarkPassingComperatorImpl.typeOfHash;
|
||||
import com.sap.sailing.domain.windestimation.IncrementalWindEstimation;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -74,6 +74,7 @@ import com.sap.sse.security.shared.HasPermissions;
|
||||
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
|
||||
/**
|
||||
* Live tracking data of a single race. The race follows a defined {@link Course} with a sequence of {@link Leg}s. The
|
||||
* course may change over time as the race committee decides to change it. Therefore, a {@link TrackedRace} instance
|
||||
@@ -89,8 +90,7 @@ import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface TrackedRace
|
||||
extends Serializable, IsManagedByCache<DomainFactory>, WithQualifiedObjectIdentifier {
|
||||
public interface TrackedRace extends Serializable, IsManagedByCache<DomainFactory>, WithQualifiedObjectIdentifier {
|
||||
final Duration START_TRACKING_THIS_MUCH_BEFORE_RACE_START = Duration.ONE_MINUTE.times(5);
|
||||
final Duration STOP_TRACKING_THIS_MUCH_AFTER_RACE_FINISH = Duration.ONE_SECOND.times(30);
|
||||
|
||||
@@ -101,7 +101,7 @@ public interface TrackedRace
|
||||
RaceDefinition getRace();
|
||||
|
||||
RegattaAndRaceIdentifier getRaceIdentifier();
|
||||
|
||||
|
||||
/**
|
||||
* Tells how ranks are to be assigned to the competitors at any time during the race. For one-design boat classes
|
||||
* this will usually happen by projecting the competitors to the wind direction for upwind and downwind legs or to
|
||||
@@ -116,17 +116,17 @@ public interface TrackedRace
|
||||
* Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time
|
||||
* point which is expected to be before the race start time). The highest precedence take the
|
||||
* {@link #attachedRaceLogs race logs} and their start time events, followed by the field {@link #startTimeReceived}
|
||||
* which can explicitly be set using {@link #setStartTimeReceived(TimePoint)}. When there are no {@link MarkPassing}s
|
||||
* for the first mark, <code>null</code> is returned. If there are mark passings for the first mark and the start
|
||||
* time is less than {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} before the first mark
|
||||
* passing for the first mark. Otherwise, the first mark passing for the first mark minus
|
||||
* which can explicitly be set using {@link #setStartTimeReceived(TimePoint)}. When there are no
|
||||
* {@link MarkPassing}s for the first mark, <code>null</code> is returned. If there are mark passings for the first
|
||||
* mark and the start time is less than {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS}
|
||||
* before the first mark passing for the first mark. Otherwise, the first mark passing for the first mark minus
|
||||
* {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} is returned as the race start time.
|
||||
* <p>
|
||||
*
|
||||
* If no start time can be determined this way, <code>null</code> is returned.
|
||||
*/
|
||||
TimePoint getStartOfRace();
|
||||
|
||||
|
||||
/**
|
||||
* Like {@link #getStartOfRace()}, but ignoring any inference from start mark passings in case {@code inferred} is
|
||||
* {@code false}. In this case, if no official start time was set, e.g., in the {@link RaceLog} or explicitly using
|
||||
@@ -137,15 +137,15 @@ public interface TrackedRace
|
||||
|
||||
/**
|
||||
* @return the time point taken from a valid, non-revoked {@link RaceLogRaceStatusEvent} that transfers the race
|
||||
* into status {@link RaceLogRaceStatus#FINISHING} or {@code null} if no such event is found.
|
||||
* into status {@link RaceLogRaceStatus#FINISHING} or {@code null} if no such event is found.
|
||||
*/
|
||||
TimePoint getFinishingTime();
|
||||
|
||||
/**
|
||||
* @return the time point taken from a valid, non-revoked {@link RaceLogRaceStatusEvent} that transfers the race
|
||||
* into status {@link RaceLogRaceStatus#FINISHED} from any of the {@link RaceLog}s attached to this race,
|
||||
* or {@code null} if no such event is found.
|
||||
*
|
||||
* into status {@link RaceLogRaceStatus#FINISHED} from any of the {@link RaceLog}s attached to this race, or
|
||||
* {@code null} if no such event is found.
|
||||
*
|
||||
* @see {@link RaceChangeListener#finishedTimeChanged(TimePoint, TimePoint)}
|
||||
*/
|
||||
TimePoint getFinishedTime();
|
||||
@@ -172,18 +172,18 @@ public interface TrackedRace
|
||||
* Shorthand for <code>{@link #getStart()}.{@link TimePoint#compareTo(TimePoint) compareTo(at)} <= 0</code>
|
||||
*/
|
||||
boolean hasStarted(TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* A race is considered "live" if it
|
||||
* {@link TrackedRaceDTO#hasGPSData has GPS data} and {@link TrackedRaceDTO#hasWindData wind data} and if the
|
||||
* <code>at</code> time point is between the start and the end of the race.
|
||||
* A race is considered "live" if it {@link TrackedRaceDTO#hasGPSData has GPS data} and
|
||||
* {@link TrackedRaceDTO#hasWindData wind data} and if the <code>at</code> time point is between the start and the
|
||||
* end of the race.
|
||||
* <p>
|
||||
*
|
||||
* The pre-start phase of a race is interesting also in live mode. Therefore, if a {@link TrackedRace#getStartOfRace start
|
||||
* time} is available for the race, the {@link TimingConstants#PRE_START_PHASE_DURATION_IN_MILLIS} is subtracted
|
||||
* from the actual start time so that the pre-start phase also counts as live. If no start time is known for the
|
||||
* race, but a {@link TrackedRace#getStartOfTracking start of tracking time} is known, it is used as the start of
|
||||
* the "live" interval.
|
||||
* The pre-start phase of a race is interesting also in live mode. Therefore, if a {@link TrackedRace#getStartOfRace
|
||||
* start time} is available for the race, the {@link TimingConstants#PRE_START_PHASE_DURATION_IN_MILLIS} is
|
||||
* subtracted from the actual start time so that the pre-start phase also counts as live. If no start time is known
|
||||
* for the race, but a {@link TrackedRace#getStartOfTracking start of tracking time} is known, it is used as the
|
||||
* start of the "live" interval.
|
||||
* <p>
|
||||
*
|
||||
* If an {@link TrackedRace#getEndOfRace end time} is already known for the race,
|
||||
@@ -193,8 +193,8 @@ public interface TrackedRace
|
||||
* <p>
|
||||
*
|
||||
* @param at
|
||||
* the time point at which to determine whether the race for <code>fleet</code>
|
||||
* is/was live. A <code>null</code> value will use the start time of the race.
|
||||
* the time point at which to determine whether the race for <code>fleet</code> is/was live. A
|
||||
* <code>null</code> value will use the start time of the race.
|
||||
* @return
|
||||
*/
|
||||
boolean isLive(TimePoint at);
|
||||
@@ -222,12 +222,12 @@ public interface TrackedRace
|
||||
TrackedLeg getCurrentLeg(TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* Tells the number of the last started leg at <code>timePoint</code>
|
||||
* The leg number is 0 before the start, the number of the current leg during the race
|
||||
* and the number of the last leg at the end of the race even if the race has finished.
|
||||
* Tells the number of the last started leg at <code>timePoint</code> The leg number is 0 before the start, the
|
||||
* number of the current leg during the race and the number of the last leg at the end of the race even if the race
|
||||
* has finished.
|
||||
*/
|
||||
int getLastLegStarted(TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Precondition: waypoint must still be part of {@link #getRace()}.{@link RaceDefinition#getCourse() getCourse()}.
|
||||
* Returns {@code null} for the first waypoint of the course. If the waypoint is not part of the course, an
|
||||
@@ -251,16 +251,21 @@ public interface TrackedRace
|
||||
* So every type of track has an associated name. With this construct you can have track implementations that
|
||||
* provide specific functionality based on the contained fix type.
|
||||
*
|
||||
* @param competitor the competitor to get the track for
|
||||
* @param trackName the name of the track to get
|
||||
* @param competitor
|
||||
* the competitor to get the track for
|
||||
* @param trackName
|
||||
* the name of the track to get
|
||||
* @return the track associated to the given Competitor and name or <code>null</code> if there is none.
|
||||
*/
|
||||
<FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> TrackT getSensorTrack(Competitor competitor, String trackName);
|
||||
|
||||
<FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> TrackT getSensorTrack(
|
||||
Competitor competitor, String trackName);
|
||||
|
||||
/**
|
||||
* Returns all contained {@link SensorFixTrack SensorFixTracks} for the given trackName and associated to any competitor.
|
||||
* Returns all contained {@link SensorFixTrack SensorFixTracks} for the given trackName and associated to any
|
||||
* competitor.
|
||||
*/
|
||||
<FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> Iterable<TrackT> getSensorTracks(String trackName);
|
||||
<FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> Iterable<TrackT> getSensorTracks(
|
||||
String trackName);
|
||||
|
||||
/**
|
||||
* Tells the leg on which the <code>competitor</code> was at time <code>at</code>. If the competitor hasn't passed
|
||||
@@ -329,7 +334,7 @@ public interface TrackedRace
|
||||
* @see #getTrack(Mark)
|
||||
*/
|
||||
GPSFixTrack<Mark, GPSFix> getOrCreateTrack(Mark mark);
|
||||
|
||||
|
||||
/**
|
||||
* Yields the track describing <code>mark</code>'s movement over time; <code>null</code> if no track exists for
|
||||
* <code>mark</code> so far.
|
||||
@@ -357,7 +362,7 @@ public interface TrackedRace
|
||||
default Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint) {
|
||||
return getApproximatePosition(waypoint, timePoint, new NonCachingMarkPositionAtTimePointCache(this, timePoint));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as {@link #getApproximatePosition(Waypoint, TimePoint)}, but giving the caller the possibility to pass a
|
||||
* cache of mark positions and related information that can help speed up compound operations requiring frequent
|
||||
@@ -411,18 +416,19 @@ public interface TrackedRace
|
||||
/**
|
||||
* Retrieves the wind sources used so far by this race that have the specified <code>type</code> as their
|
||||
* {@link WindSource#getType() type}. Always returns a non-<code>null</code> iterable which may be empty in case the
|
||||
* race does not use any wind source of the specified type (yet).<p>
|
||||
* race does not use any wind source of the specified type (yet).
|
||||
* <p>
|
||||
*
|
||||
* It is possible to ask for the {@link WindSourceType#COMBINED} and {@link WindSourceType#LEG_MIDDLE} types and
|
||||
* get a non-empty result although those sources are never returned by {@link #getWindSources()}.
|
||||
* It is possible to ask for the {@link WindSourceType#COMBINED} and {@link WindSourceType#LEG_MIDDLE} types and get
|
||||
* a non-empty result although those sources are never returned by {@link #getWindSources()}.
|
||||
*/
|
||||
Set<WindSource> getWindSources(WindSourceType type);
|
||||
|
||||
/**
|
||||
* Retrieves all wind sources known to this race, including those {@link #getWindSourcesToExclude() to exclude}.
|
||||
* Callers can freely iterate because the set returned is weakly-consistent and never throws a {@link ConcurrentModificationException}
|
||||
* upon iteration. The {@link WindSourceType#COMBINED} wind source
|
||||
* as well as the {@link WindSourceType#LEG_MIDDLE} sources are never part of the result.
|
||||
* Callers can freely iterate because the set returned is weakly-consistent and never throws a
|
||||
* {@link ConcurrentModificationException} upon iteration. The {@link WindSourceType#COMBINED} wind source as well
|
||||
* as the {@link WindSourceType#LEG_MIDDLE} sources are never part of the result.
|
||||
*/
|
||||
Set<WindSource> getWindSources();
|
||||
|
||||
@@ -475,7 +481,7 @@ public interface TrackedRace
|
||||
* lock.
|
||||
*/
|
||||
NavigableSet<MarkPassing> getMarkPassings(Competitor competitor);
|
||||
|
||||
|
||||
/**
|
||||
* Returns competitor's mark passings.
|
||||
*
|
||||
@@ -490,18 +496,20 @@ public interface TrackedRace
|
||||
/**
|
||||
* This obtains the course's read lock before asking for the read lock for the <code>markPassings</code> structure.
|
||||
* See also bug 1370 (http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=1370). This is necessary because the
|
||||
* code that executes a course update will first ask the course's write lock and then relay execution to the
|
||||
* course change listeners among which there is a {@link TrackedRace} which will then update the mark passings
|
||||
* for all competitors and therefore will need to ask the write lock for those. If the thread calling this method
|
||||
* first obtains the mark passings read lock and later, while holding on to that lock, asks for the course's read
|
||||
* lock, a deadlock may result.<p>
|
||||
* code that executes a course update will first ask the course's write lock and then relay execution to the course
|
||||
* change listeners among which there is a {@link TrackedRace} which will then update the mark passings for all
|
||||
* competitors and therefore will need to ask the write lock for those. If the thread calling this method first
|
||||
* obtains the mark passings read lock and later, while holding on to that lock, asks for the course's read lock, a
|
||||
* deadlock may result.
|
||||
* <p>
|
||||
*
|
||||
* Furthermore, when trying to acquire both, a lock for the {@link #getMarkPassings(Competitor) mark passings for a competitor}
|
||||
* and a lock for the {@link #getMarkPassingsInOrder(Waypoint) mark passings for a waypoint, this needs to happen in exactly
|
||||
* this order, or a deadlock may result.<p>
|
||||
* Furthermore, when trying to acquire both, a lock for the {@link #getMarkPassings(Competitor) mark passings for a
|
||||
* competitor} and a lock for the {@link #getMarkPassingsInOrder(Waypoint) mark passings for a waypoint, this needs
|
||||
* to happen in exactly this order, or a deadlock may result.
|
||||
* <p>
|
||||
*
|
||||
* The {@link #unlockAfterRead(Iterable)} method will symmetrically unlock the course's read lock after releasing the
|
||||
* read lock for the mark passings.
|
||||
* The {@link #unlockAfterRead(Iterable)} method will symmetrically unlock the course's read lock after releasing
|
||||
* the read lock for the mark passings.
|
||||
*/
|
||||
void lockForRead(Iterable<MarkPassing> markPassings);
|
||||
|
||||
@@ -559,7 +567,7 @@ public interface TrackedRace
|
||||
* {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the competitors' GPS tracks.
|
||||
*/
|
||||
Tack getTack(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
|
||||
/**
|
||||
* Based on the wind direction at <code>timePoint</code> and at position <code>where</code>, compares the
|
||||
* <code>boatBearing</code> to the wind's bearing at that time and place and determined the tack.
|
||||
@@ -585,8 +593,8 @@ public interface TrackedRace
|
||||
|
||||
/**
|
||||
* Computes a default wind direction based on the direction of the first leg at time <code>at</code>, with a default
|
||||
* speed of zero knots. Note that this wind direction can only be used if {@link #raceIsKnownToStartUpwind()} returns
|
||||
* <code>true</code>.
|
||||
* speed of zero knots. Note that this wind direction can only be used if {@link #raceIsKnownToStartUpwind()}
|
||||
* returns <code>true</code>.
|
||||
*
|
||||
* @param at
|
||||
* usually the {@link #getStart() start time} should be used; if no valid start time is provided, the
|
||||
@@ -618,7 +626,7 @@ public interface TrackedRace
|
||||
* for the <code>key</code> is still ongoing, the result of that ongoing re-calculation is returned.
|
||||
*/
|
||||
Iterable<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest);
|
||||
|
||||
|
||||
/**
|
||||
* @return a non-<code>null</code> but perhaps empty list of the maneuvers that <code>competitor</code> performed in
|
||||
* this race. Depending on <code>waitForLatest</code> the result is taken from the cache straight away
|
||||
@@ -659,7 +667,8 @@ public interface TrackedRace
|
||||
* tracked race. This runs synchronized with the otherwise asynchronous loading of wind tracks, triggered by the
|
||||
* constructor of the {@link TrackedRace} implementation classes. This procedure guarantees that eventually the
|
||||
* listener will have received a notification for all wind fixes, regardless of whether they were already loaded at
|
||||
* the time the listener is registered or they are loaded after the registration has completed.<p>
|
||||
* the time the listener is registered or they are loaded after the registration has completed.
|
||||
* <p>
|
||||
*
|
||||
* The same is true for the GPS fixes for marks and competitors.
|
||||
*/
|
||||
@@ -667,10 +676,10 @@ public interface TrackedRace
|
||||
boolean notifyAboutGPSFixesAlreadyLoaded);
|
||||
|
||||
void removeListener(RaceChangeListener listener);
|
||||
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race
|
||||
* or if the competitor has not finished one of the legs in the race.
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race or if the
|
||||
* competitor has not finished one of the legs in the race.
|
||||
*/
|
||||
Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
@@ -680,32 +689,35 @@ public interface TrackedRace
|
||||
Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race
|
||||
* or if the competitor has not finished one of the legs in the race.
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race or if the
|
||||
* competitor has not finished one of the legs in the race.
|
||||
*/
|
||||
Distance getDistanceFoiled(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race
|
||||
* or if the competitor has not finished one of the legs in the race.
|
||||
* @return <code>null</code> if there are no mark passings for the <code>competitor</code> in this race or if the
|
||||
* competitor has not finished one of the legs in the race.
|
||||
*/
|
||||
Duration getDurationFoiled(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* See {@link TrackedLegOfCompetitor#getWindwardDistanceToCompetitorFarthestAhead(TimePoint, WindPositionMode, RankingInfo)}
|
||||
* See
|
||||
* {@link TrackedLegOfCompetitor#getWindwardDistanceToCompetitorFarthestAhead(TimePoint, WindPositionMode, RankingInfo)}
|
||||
*/
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode);
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode);
|
||||
|
||||
/**
|
||||
* Same as {@link #getWindwardDistanceToCompetitorFarthestAhead(Competitor, TimePoint, WindPositionMode)}, only with an
|
||||
* additional cache to speed up wind and leg type and leg bearing calculations in case of multiple similar look-ups
|
||||
* for the same time point.
|
||||
* Same as {@link #getWindwardDistanceToCompetitorFarthestAhead(Competitor, TimePoint, WindPositionMode)}, only with
|
||||
* an additional cache to speed up wind and leg type and leg bearing calculations in case of multiple similar
|
||||
* look-ups for the same time point.
|
||||
*
|
||||
* @param rankingInfo
|
||||
* materialized ranking information that is expensive to calculate, avoiding redundant calculations
|
||||
*/
|
||||
Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
WindPositionMode windPositionMode, RankingInfo rankingInfo,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
/**
|
||||
* Calls {@link #getWindWithConfidence(Position, TimePoint, Iterable)} and excludes those wind sources listed in
|
||||
@@ -729,8 +741,8 @@ public interface TrackedRace
|
||||
Set<WindSource> windSourcesToExclude);
|
||||
|
||||
/**
|
||||
* Same as {@link #getEstimatedWindDirection(TimePoint)}, but propagates the confidence of the wind
|
||||
* estimation, relative to the <code>timePoint</code> for which the request is made, in the result. The
|
||||
* Same as {@link #getEstimatedWindDirection(TimePoint)}, but propagates the confidence of the wind estimation,
|
||||
* relative to the <code>timePoint</code> for which the request is made, in the result. The
|
||||
* {@link Wind#getPosition() position} of all {@link Wind} fixes returned is <code>null</code>.
|
||||
*/
|
||||
WindWithConfidence<TimePoint> getEstimatedWindDirectionWithConfidence(TimePoint timePoint);
|
||||
@@ -748,16 +760,18 @@ public interface TrackedRace
|
||||
* if <code>true</code> and any cache update is currently going on, wait for the update to complete and
|
||||
* then fetch the updated value; otherwise, serve this requests from whatever is currently in the cache
|
||||
*/
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis);
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint,
|
||||
boolean waitForLatestAnalysis);
|
||||
|
||||
/**
|
||||
* Same as {@link #getAverageAbsoluteCrossTrackError(Competitor, TimePoint, boolean)}, only that a cache for leg type,
|
||||
* wind on leg and leg bearing is provided.
|
||||
* Same as {@link #getAverageAbsoluteCrossTrackError(Competitor, TimePoint, boolean)}, only that a cache for leg
|
||||
* type, wind on leg and leg bearing is provided.
|
||||
*/
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses);
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint,
|
||||
boolean waitForLatestAnalyses, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly,
|
||||
boolean waitForLatestAnalyses);
|
||||
|
||||
Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis);
|
||||
|
||||
@@ -776,13 +790,13 @@ public interface TrackedRace
|
||||
WindStore getWindStore();
|
||||
|
||||
Competitor getOverallLeader(TimePoint timePoint);
|
||||
|
||||
|
||||
Competitor getOverallLeader(TimePoint timePoint, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
Boat getBoatOfCompetitor(Competitor competitor);
|
||||
|
||||
|
||||
Competitor getCompetitorOfBoat(Boat boat);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the competitors of this tracked race, according to their ranking. Competitors whose
|
||||
* {@link #getRank(Competitor)} is 0 will be sorted "worst".
|
||||
@@ -790,34 +804,34 @@ public interface TrackedRace
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* Same as {@link #getCompetitorsFromBestToWorst(TimePoint)}, using a cache for wind, leg type and leg
|
||||
* bearing values.
|
||||
* Same as {@link #getCompetitorsFromBestToWorst(TimePoint)}, using a cache for wind, leg type and leg bearing
|
||||
* values.
|
||||
*/
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
/**
|
||||
* When provided with a {@link WindStore} during construction, the tracked race will
|
||||
* asynchronously load the wind data for this tracked race from the wind store and the GPS store in a
|
||||
* background thread and update this tracked race with the results. Clients that want to wait for the wind
|
||||
* loading process to complete can do so by calling this method which will block until the wind loading has
|
||||
* completed.
|
||||
* When provided with a {@link WindStore} during construction, the tracked race will asynchronously load the wind
|
||||
* data for this tracked race from the wind store and the GPS store in a background thread and update this tracked
|
||||
* race with the results. Clients that want to wait for the wind loading process to complete can do so by calling
|
||||
* this method which will block until the wind loading has completed.
|
||||
*/
|
||||
void waitUntilLoadingFromWindStoreComplete() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Whenever a {@link RegattaLog} is attached, fixes are loaded from the {@link SensorFixStore} for all mappings
|
||||
* found in the {@code RegattaLog} in a separate thread. This method blocks if there is such a thread loading
|
||||
* fixes, until that thread is finished.
|
||||
* found in the {@code RegattaLog} in a separate thread. This method blocks if there is such a thread loading fixes,
|
||||
* until that thread is finished.
|
||||
*/
|
||||
void waitForLoadingToFinish() throws InterruptedException;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current status of the {@link TrackedRace}. This consists of one of the {@link TrackedRaceStatusEnum}
|
||||
* values plus a progress for LOADING state.<br>
|
||||
* Due to the fact that multiple loaders can exist that load data into the {@link TrackedRace}, the returned status
|
||||
* is a composite of those loader statuses. When a loader is finished, its status isn't tracked anymore. This causes
|
||||
* the overall progress to not be guaranteed to be monotonic (progress may jump to a lower percentage when one loader
|
||||
* that had a progress of 100% is finished and thus removed).
|
||||
* the overall progress to not be guaranteed to be monotonic (progress may jump to a lower percentage when one
|
||||
* loader that had a progress of 100% is finished and thus removed).
|
||||
*
|
||||
* @see TrackedRaceStatus
|
||||
* @see DynamicTrackedRace#onStatusChanged(TrackingDataLoader, TrackedRaceStatus)
|
||||
@@ -825,8 +839,8 @@ public interface TrackedRace
|
||||
TrackedRaceStatus getStatus();
|
||||
|
||||
/**
|
||||
* If the {@link #getStatus() status} is currently {@link TrackedRaceStatusEnum#LOADING}, blocks until the status changes to any
|
||||
* other status.
|
||||
* If the {@link #getStatus() status} is currently {@link TrackedRaceStatusEnum#LOADING}, blocks until the status
|
||||
* changes to any other status.
|
||||
*/
|
||||
void waitUntilNotLoading();
|
||||
|
||||
@@ -836,64 +850,64 @@ public interface TrackedRace
|
||||
* @return the race log detached or {@code null} if no race log can be found by the {@code identifier}
|
||||
*/
|
||||
RaceLog detachRaceLog(Serializable identifier);
|
||||
|
||||
|
||||
/**
|
||||
* Detaches the link {@link RaceExecutionOrderProvider}
|
||||
*/
|
||||
void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider);
|
||||
|
||||
|
||||
/**
|
||||
* Attaches the passed race log with this {@link TrackedRace}.
|
||||
* This causes fixes from the {@link SensorFixStore} to be loaded for such {@link RegattaLogDeviceMappingEvent RegattaLogDeviceMappingEvents}
|
||||
* that are present in the {@link RaceLog raceLog}. This loading is offloaded into a separate thread, that blocks
|
||||
* serialization until it is finished. If multiple race logs are attached, the loading process is
|
||||
* forced to be serialized.
|
||||
* To guarantee that a the fixes for a race log have been fully loaded before continuing,
|
||||
* {@link #waitForLoadingToFinish()} can be used.
|
||||
* @param raceLog to be attached.
|
||||
* Attaches the passed race log with this {@link TrackedRace}. This causes fixes from the {@link SensorFixStore} to
|
||||
* be loaded for such {@link RegattaLogDeviceMappingEvent RegattaLogDeviceMappingEvents} that are present in the
|
||||
* {@link RaceLog raceLog}. This loading is offloaded into a separate thread, that blocks serialization until it is
|
||||
* finished. If multiple race logs are attached, the loading process is forced to be serialized. To guarantee that a
|
||||
* the fixes for a race log have been fully loaded before continuing, {@link #waitForLoadingToFinish()} can be used.
|
||||
*
|
||||
* @param raceLog
|
||||
* to be attached.
|
||||
*/
|
||||
void attachRaceLog(RaceLog raceLog);
|
||||
|
||||
|
||||
/**
|
||||
* Attaches the passed {@link RegattaLog} with this {@link TrackedRace}.
|
||||
* This also causes fixes from the {@link SensorFixStore} to be loaded (see {@link #attachRaceLog(RaceLog)} for details).
|
||||
* Attaches the passed {@link RegattaLog} with this {@link TrackedRace}. This also causes fixes from the
|
||||
* {@link SensorFixStore} to be loaded (see {@link #attachRaceLog(RaceLog)} for details).
|
||||
*/
|
||||
void attachRegattaLog(RegattaLog regattaLog);
|
||||
|
||||
|
||||
/**
|
||||
* @return all currently attached {@link RegattaLog}s or an empty Iterable if there aren't any
|
||||
*/
|
||||
Iterable<RegattaLog> getAttachedRegattaLogs();
|
||||
|
||||
|
||||
/**
|
||||
* Attaches a {@link RaceExecutionOrderProvider} to make a {@link TrackedRace} aware
|
||||
* which races are scheduled around it in the execution order of a {@link Regatta}.
|
||||
* */
|
||||
* Attaches a {@link RaceExecutionOrderProvider} to make a {@link TrackedRace} aware which races are scheduled
|
||||
* around it in the execution order of a {@link Regatta}.
|
||||
*/
|
||||
void attachRaceExecutionProvider(RaceExecutionOrderProvider raceExecutionOrderProvider);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the attached race log event track for this race if any.
|
||||
* Otherwise <code>null</code>.
|
||||
* Returns the attached race log event track for this race if any. Otherwise <code>null</code>.
|
||||
*/
|
||||
RaceLog getRaceLog(Serializable identifier);
|
||||
|
||||
|
||||
/**
|
||||
* A setter for the listener on course design changes suggested by one of the {@link RaceLog RaceLog} attached to this
|
||||
* race. The listener is mostly part of the tracking provider adapter.
|
||||
* A setter for the listener on course design changes suggested by one of the {@link RaceLog RaceLog} attached to
|
||||
* this race. The listener is mostly part of the tracking provider adapter.
|
||||
*
|
||||
* @param listener
|
||||
* the listener to operate with.
|
||||
*/
|
||||
void addCourseDesignChangedListener(CourseDesignChangedListener listener);
|
||||
|
||||
|
||||
void addStartTimeChangedListener(StartTimeChangedListener listener);
|
||||
|
||||
|
||||
void removeStartTimeChangedListener(StartTimeChangedListener listener);
|
||||
|
||||
void addRaceAbortedListener(RaceAbortedListener listener);
|
||||
|
||||
/**
|
||||
* Tells how far the given <code>competitor</code> was from the start line at the time point of the given seconds before the start.
|
||||
* Tells how far the given <code>competitor</code> was from the start line at the time point of the given seconds
|
||||
* before the start.
|
||||
* <p>
|
||||
*
|
||||
* The distance to the line is calculated by projecting the competitor's position onto the line orthogonally and
|
||||
@@ -938,8 +952,9 @@ public interface TrackedRace
|
||||
* Like {@link #getWindwardDistanceToFavoredSideOfStartLine(Competitor, long)}, but with a cache to accelerate
|
||||
* repetitive requests for wind and leg types.
|
||||
*/
|
||||
Distance getWindwardDistanceToFavoredSideOfStartLine(Competitor competitor, long millisecondsBeforeRaceStart, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
Distance getWindwardDistanceToFavoredSideOfStartLine(Competitor competitor, long millisecondsBeforeRaceStart,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
/**
|
||||
* Tells how far, projected onto the wind for upwind/downwind and projected onto the course middle line for reaching
|
||||
* starts, the given <code>competitor</code> was from the favored end of the start line at the given
|
||||
@@ -952,7 +967,8 @@ public interface TrackedRace
|
||||
* returned. If the competitor's position cannot be determined, <code>null</code> is returned.
|
||||
*/
|
||||
default Distance getWindwardDistanceToFavoredSideOfStartLine(Competitor competitor, TimePoint timePoint) {
|
||||
return getWindwardDistanceToFavoredSideOfStartLine(competitor, timePoint, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
return getWindwardDistanceToFavoredSideOfStartLine(competitor, timePoint,
|
||||
new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -963,19 +979,19 @@ public interface TrackedRace
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache);
|
||||
|
||||
/**
|
||||
* When the <code>competitor</code> has started, this method returns the distance to the starboard end of the start line
|
||||
* or---if the start waypoint was a single mark---the distance to the single start mark at the time the competitor started.
|
||||
* If the competitor hasn't started yet, <code>null</code> is returned.
|
||||
* When the <code>competitor</code> has started, this method returns the distance to the starboard end of the start
|
||||
* line or---if the start waypoint was a single mark---the distance to the single start mark at the time the
|
||||
* competitor started. If the competitor hasn't started yet, <code>null</code> is returned.
|
||||
*/
|
||||
Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor);
|
||||
|
||||
|
||||
/**
|
||||
* At the given timepoint and for the competitor, this method returns the distance to the starboard end of the start line
|
||||
* or---if the start waypoint was a single mark---the distance to the single start mark at the timepoint.
|
||||
* If the competitor hasn't started yet, <code>null</code> is returned.
|
||||
* At the given timepoint and for the competitor, this method returns the distance to the starboard end of the start
|
||||
* line or---if the start waypoint was a single mark---the distance to the single start mark at the timepoint. If
|
||||
* the competitor hasn't started yet, <code>null</code> is returned.
|
||||
*/
|
||||
Distance getDistanceFromStarboardSideOfStartLine(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* At the given timepoint and for the competitor, this method returns the distance between the starboard end of the
|
||||
* start line and the competitor position projected perpendicularly onto the line. If the start waypoint was a
|
||||
@@ -984,7 +1000,7 @@ public interface TrackedRace
|
||||
* hasn't started yet, <code>null</code> is returned.
|
||||
*/
|
||||
Distance getDistanceFromStarboardSideOfStartLineProjectedOntoLine(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* For all competitors in this race computes their
|
||||
* {@link #getDistanceFromStarboardSideOfStartLineProjectedOntoLine(Competitor, TimePoint)} and puts the results in
|
||||
@@ -992,50 +1008,62 @@ public interface TrackedRace
|
||||
* finding adjacent records, using {@link SortedMap#headMap(Object)} and {@link SortedMap#tailMap(Object)}.
|
||||
* <p>
|
||||
*
|
||||
* Competitors who are part of this race but for which no such {@link Distance} can be calculated, a record is
|
||||
* put to the resulting map with a {@code null} value associated. Those entries are sorted to the end of the map,
|
||||
* meaning that "{@code null} is greater" than other values.</p>
|
||||
* Competitors who are part of this race but for which no such {@link Distance} can be calculated, a record is put
|
||||
* to the resulting map with a {@code null} value associated. Those entries are sorted to the end of the map,
|
||||
* meaning that "{@code null} is greater" than other values.
|
||||
* </p>
|
||||
*
|
||||
* Results are cached in a fixed-size LRU cache which is invalidated by competitor or mark positions within the
|
||||
* averaging time range of {@code timePoint}. With this, repeated requests for equal {@code timePoint}s have a good
|
||||
* chance of being fulfilled from a previous computation result.<p>
|
||||
* chance of being fulfilled from a previous computation result.
|
||||
* <p>
|
||||
*
|
||||
* Boats are not considered in this if they are {@link MaxPointsReason#DNC DNC} or {@link MaxPointsReason#DNC DNS}
|
||||
* which both suggest the boat may not have made a serious attempt to start.
|
||||
*/
|
||||
SortedMap<Competitor, Distance> getDistancesFromStarboardSideOfStartLineProjectedOntoLine(TimePoint timePoint,
|
||||
BiFunction<Competitor, TimePoint, MaxPointsReason> maxPointsReasonSupplier);
|
||||
|
||||
|
||||
/**
|
||||
* Based on the result of {@link #getDistancesFromStarboardSideOfStartLineProjectedOntoLine(TimePoint, Function<Triple<Competitor, RaceColumn, TimePoint>, MaxPointsReason>)}, finds the
|
||||
* next competitor to port regarding their start line projection at {@code timePoint}. Returns {@code null} if
|
||||
* the start line cannot be determined or if there is no competitor further to port.<p>
|
||||
* Based on the result of {@link #getDistancesFromStarboardSideOfStartLineProjectedOntoLine(TimePoint,
|
||||
* Function<Triple<Competitor, RaceColumn, TimePoint>, MaxPointsReason>)}, finds the next competitor to port
|
||||
* regarding their start line projection at {@code timePoint}. Returns {@code null} if the start line cannot be
|
||||
* determined or if there is no competitor further to port.
|
||||
* <p>
|
||||
*
|
||||
* Boats are not considered in this if they are {@link MaxPointsReason#DNC DNC} or {@link MaxPointsReason#DNC DNS}
|
||||
* which both suggest the boat may not have made a serious attempt to start.
|
||||
* @param maxPointsReasonSupplier TODO
|
||||
*
|
||||
* @param maxPointsReasonSupplier
|
||||
* TODO
|
||||
*/
|
||||
Competitor getNextCompetitorToPortOnStartLine(Competitor relativeTo, TimePoint timePoint, BiFunction<Competitor, TimePoint, MaxPointsReason> maxPointsReasonSupplier);
|
||||
|
||||
Competitor getNextCompetitorToPortOnStartLine(Competitor relativeTo, TimePoint timePoint,
|
||||
BiFunction<Competitor, TimePoint, MaxPointsReason> maxPointsReasonSupplier);
|
||||
|
||||
/**
|
||||
* Based on the result of {@link #getDistancesFromStarboardSideOfStartLineProjectedOntoLine(TimePoint, Function<Triple<Competitor, RaceColumn, TimePoint>, MaxPointsReason>)}, finds the
|
||||
* next competitor to starboard regarding their start line projection at {@code timePoint}. Returns {@code null} if
|
||||
* the start line cannot be determined or if there is no competitor further to starboard.<p>
|
||||
* Based on the result of {@link #getDistancesFromStarboardSideOfStartLineProjectedOntoLine(TimePoint,
|
||||
* Function<Triple<Competitor, RaceColumn, TimePoint>, MaxPointsReason>)}, finds the next competitor to starboard
|
||||
* regarding their start line projection at {@code timePoint}. Returns {@code null} if the start line cannot be
|
||||
* determined or if there is no competitor further to starboard.
|
||||
* <p>
|
||||
*
|
||||
* Boats are not considered in this if they are {@link MaxPointsReason#DNC DNC} or {@link MaxPointsReason#DNC DNS}
|
||||
* which both suggest the boat may not have made a serious attempt to start.
|
||||
* @param maxPointsReasonSupplier TODO
|
||||
*
|
||||
* @param maxPointsReasonSupplier
|
||||
* TODO
|
||||
*/
|
||||
Competitor getNextCompetitorToStarboardOnStartLine(Competitor relativeTo, TimePoint timePoint, BiFunction<Competitor, TimePoint, MaxPointsReason> maxPointsReasonSupplier);
|
||||
|
||||
Competitor getNextCompetitorToStarboardOnStartLine(Competitor relativeTo, TimePoint timePoint,
|
||||
BiFunction<Competitor, TimePoint, MaxPointsReason> maxPointsReasonSupplier);
|
||||
|
||||
/**
|
||||
* The estimated speed of the competitor at the time point of the given seconds before the start of race.
|
||||
* The estimated speed of the competitor at the time point of the given seconds before the start of race.
|
||||
*/
|
||||
Speed getSpeed(Competitor competitor, long millisecondsBeforeRaceStart);
|
||||
|
||||
|
||||
/**
|
||||
* The speed of the competitor when crossing the start line. It will return null if there are no recorded
|
||||
* mark passings for this competitor (competitor did not yet or never pass the start line).
|
||||
* The speed of the competitor when crossing the start line. It will return null if there are no recorded mark
|
||||
* passings for this competitor (competitor did not yet or never pass the start line).
|
||||
*/
|
||||
Speed getSpeedWhenCrossingStartLine(Competitor competitor);
|
||||
|
||||
@@ -1043,56 +1071,58 @@ public interface TrackedRace
|
||||
* Start time received by the tracking infrastructure. To determine real start time use {@link #getStartOfRace()}.
|
||||
*/
|
||||
TimePoint getStartTimeReceived();
|
||||
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if the start waypoint does not have two marks or the course
|
||||
* is empty or the start waypoint is the only waypoint
|
||||
* @return <code>null</code> if the start waypoint does not have two marks or the course is empty or the start
|
||||
* waypoint is the only waypoint
|
||||
*/
|
||||
LineDetails getStartLine(TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if the finish waypoint does not have two marks or the course
|
||||
* is empty or the finish waypoint is the only waypoint
|
||||
* @return <code>null</code> if the finish waypoint does not have two marks or the course is empty or the finish
|
||||
* waypoint is the only waypoint
|
||||
*/
|
||||
LineDetails getFinishLine(TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* Length of course if there are mark passings for competitors.
|
||||
*/
|
||||
Distance getCourseLength();
|
||||
|
||||
|
||||
/**
|
||||
* The average wind speed with confidence for this race. It uses the timepoint of the {@link #getEndOfRace race end} as
|
||||
* a reference point, or, if that is {@code null}, the {@link #getTimePointOfNewestEvent()}.
|
||||
* The average wind speed with confidence for this race. It uses the timepoint of the {@link #getEndOfRace race end}
|
||||
* as a reference point, or, if that is {@code null}, the {@link #getTimePointOfNewestEvent()}.
|
||||
*/
|
||||
SpeedWithConfidence<TimePoint> getAverageWindSpeedWithConfidence(long resolutionInMillis);
|
||||
|
||||
|
||||
SpeedWithConfidence<TimePoint> getAverageWindSpeedWithConfidenceWithNumberOfSamples(int numberOfSamples);
|
||||
|
||||
|
||||
/**
|
||||
* The average wind speed with confidence for this race.
|
||||
*/
|
||||
SpeedWithConfidence<TimePoint> getAverageWindSpeedWithConfidence(TimePoint fromTimePoint, TimePoint toTimePoint, int numberOfSamples);
|
||||
|
||||
SpeedWithConfidence<TimePoint> getAverageWindSpeedWithConfidence(TimePoint fromTimePoint, TimePoint toTimePoint,
|
||||
int numberOfSamples);
|
||||
|
||||
/**
|
||||
* Computes the center point of the course's marks at the given time point.
|
||||
*/
|
||||
Position getCenterOfCourse(TimePoint at);
|
||||
|
||||
/**
|
||||
* If the {@link RacingProcedure} defined by any of the {@link #attachedRaceLogs attached} {@link RaceLog}s
|
||||
* has type {@link RacingProcedureType#GateStart}, this method returns <code>true</code>, <code>false</code> for
|
||||
* any other type found. If no type is found, e.g., because no race log is currently attached to this tracked race,
|
||||
* If the {@link RacingProcedure} defined by any of the {@link #attachedRaceLogs attached} {@link RaceLog}s has type
|
||||
* {@link RacingProcedureType#GateStart}, this method returns <code>true</code>, <code>false</code> for any other
|
||||
* type found. If no type is found, e.g., because no race log is currently attached to this tracked race,
|
||||
* <code>null</code> is returned, meaning that the type is not known.
|
||||
*/
|
||||
Boolean isGateStart();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the time in milliseconds when the line was closed with lowering flag {@link Flags#GOLF} if {@link #isGateStart()} is <code>true</code>.
|
||||
* If flag was not raised or {@link #isGateStart()} is <code>false</code> it returns <code>null</code>.
|
||||
* Returns the time in milliseconds when the line was closed with lowering flag {@link Flags#GOLF} if
|
||||
* {@link #isGateStart()} is <code>true</code>. If flag was not raised or {@link #isGateStart()} is
|
||||
* <code>false</code> it returns <code>null</code>.
|
||||
*/
|
||||
long getGateStartGolfDownTime();
|
||||
|
||||
|
||||
/**
|
||||
* If the race was started with a gate start (see {@link #isGateStart()}, this method returns the distance between
|
||||
* the competitor's starting position and the port side of the start line (pin end); otherwise, returns a zero
|
||||
@@ -1101,7 +1131,7 @@ public interface TrackedRace
|
||||
Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
boolean isUsingMarkPassingCalculator();
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the estimated time it takes a competitor to sail the race, from start to finish.
|
||||
*
|
||||
@@ -1109,13 +1139,15 @@ public interface TrackedRace
|
||||
* Used for positions of marks and wind information; note that sometimes the marks are not in place yet
|
||||
* when the race starts and that a windward mark may be collected already before the race finishes.
|
||||
*
|
||||
* @return estimated time it takes to complete the race, plus more useful information about how this result came about
|
||||
* @return estimated time it takes to complete the race, plus more useful information about how this result came
|
||||
* about
|
||||
*
|
||||
* @throws NotEnoughDataHasBeenAddedException
|
||||
* thrown if not enough polar data has been added or polar data service is not available
|
||||
* @throws NoWindException
|
||||
*/
|
||||
TargetTimeInfo getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, NoWindException;
|
||||
TargetTimeInfo getEstimatedTimeToComplete(TimePoint timepoint)
|
||||
throws NotEnoughDataHasBeenAddedException, NoWindException;
|
||||
|
||||
/**
|
||||
* Determine the time sailed for the {@code competitor} at {@code timePoint} in this race. This ignores whether or
|
||||
@@ -1154,38 +1186,40 @@ public interface TrackedRace
|
||||
default Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> getTrackingTimesFromRaceLogs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
default Pair<TimePoint, TimePoint> getStartAndFinishedTimeFromRaceLogs() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all marks found in the {@link #markTracks} map and the mark device mappings and mark
|
||||
* definition events in all attached race and regatta logs. Note that usually a device mapping should
|
||||
* exist for a mark only if that mark is also defined by a {@link RegattaLogDefineMarkEvent}, so for
|
||||
* this standard case, adding the marks from the device mark mappings would be redundant.
|
||||
* Returns all marks found in the {@link #markTracks} map and the mark device mappings and mark definition events in
|
||||
* all attached race and regatta logs. Note that usually a device mapping should exist for a mark only if that mark
|
||||
* is also defined by a {@link RegattaLogDefineMarkEvent}, so for this standard case, adding the marks from the
|
||||
* device mark mappings would be redundant.
|
||||
*/
|
||||
default Iterable<Mark> getMarksFromRegattaLogs() {
|
||||
return getMarks();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the start and end of tracking in the following precedence order:
|
||||
*
|
||||
* <ol>
|
||||
* <li>start/end of tracking in Racelog</li>
|
||||
* <li>manually set start/end of tracking via {@link #setStartOfTrackingReceived(TimePoint, boolean)} and {@link #setEndOfTrackingReceived(TimePoint, boolean)}</li>
|
||||
* <li>start/end of race in Racelog -/+ {@link #START_TRACKING_THIS_MUCH_BEFORE_RACE_START}/{@link #STOP_TRACKING_THIS_MUCH_AFTER_RACE_FINISH}</li>
|
||||
* <li>manually set start/end of tracking via {@link #setStartOfTrackingReceived(TimePoint, boolean)} and
|
||||
* {@link #setEndOfTrackingReceived(TimePoint, boolean)}</li>
|
||||
* <li>start/end of race in Racelog -/+
|
||||
* {@link #START_TRACKING_THIS_MUCH_BEFORE_RACE_START}/{@link #STOP_TRACKING_THIS_MUCH_AFTER_RACE_FINISH}</li>
|
||||
* </ol>
|
||||
*/
|
||||
public void updateStartAndEndOfTracking(boolean waitForGPSFixesToLoad);
|
||||
|
||||
|
||||
default void lockForSerializationRead() {
|
||||
}
|
||||
|
||||
|
||||
default void unlockAfterSerializationRead() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return all currently attached {@link RaceLog}s or an empty Iterable if there aren't any
|
||||
*/
|
||||
@@ -1201,7 +1235,6 @@ public interface TrackedRace
|
||||
*/
|
||||
Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Computes the competitor's speed projected onto the wind (if wind data is available and the competitor is not
|
||||
* between start and finish (not racing) or not on a {@link LegType#REACHING reaching} leg; if outside a race and no
|
||||
@@ -1214,21 +1247,25 @@ public interface TrackedRace
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getVelocityMadeGood(Competitor, TimePoint)}, but allowing callers to specify a {@link WindPositionMode}
|
||||
* other than the default {@link WindPositionMode#EXACT}. If {@link WindPositionMode#LEG_MIDDLE} is used and the
|
||||
* competitor is not currently sailing on a leg (hasn't started or has already finished), {@code null} is returned.
|
||||
* Like {@link #getVelocityMadeGood(Competitor, TimePoint)}, but allowing callers to specify a
|
||||
* {@link WindPositionMode} other than the default {@link WindPositionMode#EXACT}. If
|
||||
* {@link WindPositionMode#LEG_MIDDLE} is used and the competitor is not currently sailing on a leg (hasn't started
|
||||
* or has already finished), {@code null} is returned.
|
||||
*/
|
||||
default SpeedWithBearing getVelocityMadeGood(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
||||
return getVelocityMadeGood(competitor, timePoint, windPositionMode, new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
default SpeedWithBearing getVelocityMadeGood(Competitor competitor, TimePoint timePoint,
|
||||
WindPositionMode windPositionMode) {
|
||||
return getVelocityMadeGood(competitor, timePoint, windPositionMode,
|
||||
new LeaderboardDTOCalculationReuseCache(timePoint));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Computes the angle between the competitors direction and the wind's "from" direction. The angle's direction is chosen such that
|
||||
* it can be added to the boat's course over ground to arrive at the wind's {@link Wind#getFrom() "from"} direction. Example: wind
|
||||
* from the north (0deg), boat's course over ground 90deg (moving east), then the bearing returned is -90deg.
|
||||
* Computes the angle between the competitors direction and the wind's "from" direction. The angle's direction is
|
||||
* chosen such that it can be added to the boat's course over ground to arrive at the wind's {@link Wind#getFrom()
|
||||
* "from"} direction. Example: wind from the north (0deg), boat's course over ground 90deg (moving east), then the
|
||||
* bearing returned is -90deg.
|
||||
*/
|
||||
default Bearing getTWA(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
default Bearing getTWA(Competitor competitor, TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
Bearing twa = null;
|
||||
final GPSFixTrack<Competitor, GPSFixMoving> sogTrack = this.getTrack(competitor);
|
||||
if (sogTrack != null) {
|
||||
@@ -1241,20 +1278,21 @@ public interface TrackedRace
|
||||
}
|
||||
return twa;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as {@link #getTWA}, only that additionally a cache is provided that can allow the method to use
|
||||
* cached wind and leg type values.
|
||||
* Same as {@link #getTWA}, only that additionally a cache is provided that can allow the method to use cached wind
|
||||
* and leg type values.
|
||||
*/
|
||||
default Bearing getTWA(Competitor competitor, TimePoint at){
|
||||
default Bearing getTWA(Competitor competitor, TimePoint at) {
|
||||
return getTWA(competitor, at, new LeaderboardDTOCalculationReuseCache(at));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Like {@link #getVelocityMadeGood(Competitor, TimePoint)}, but allowing callers to specify a cache that can
|
||||
* accelerate requests for wind directions, the leg type and the competitor's current leg's bearing.
|
||||
*/
|
||||
default SpeedWithBearing getVelocityMadeGood(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
default SpeedWithBearing getVelocityMadeGood(Competitor competitor, TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
return getVelocityMadeGood(competitor, timePoint, WindPositionMode.EXACT, cache);
|
||||
}
|
||||
|
||||
@@ -1274,6 +1312,7 @@ public interface TrackedRace
|
||||
|
||||
/**
|
||||
* Gets polar service which is currently set in this tracked race instance.
|
||||
*
|
||||
* @see #setPolarDataService(PolarDataService)
|
||||
*/
|
||||
PolarDataService getPolarDataService();
|
||||
@@ -1291,16 +1330,16 @@ public interface TrackedRace
|
||||
|
||||
/**
|
||||
* Obtains a quick, rough summary of the wind conditions during this race, based on a few wind samples at the
|
||||
* beginning, in the middle and at the end of the race. This is summarized in a min and max wind speed as well
|
||||
* as a single average wind direction.
|
||||
* beginning, in the middle and at the end of the race. This is summarized in a min and max wind speed as well as a
|
||||
* single average wind direction.
|
||||
*/
|
||||
WindSummary getWindSummary();
|
||||
|
||||
|
||||
@Override
|
||||
default QualifiedObjectIdentifier getIdentifier() {
|
||||
return getIdentifier(getRaceIdentifier());
|
||||
}
|
||||
|
||||
|
||||
public static QualifiedObjectIdentifier getIdentifier(RegattaAndRaceIdentifier regattaAndRaceId) {
|
||||
return getSecuredDomainType().getQualifiedObjectIdentifier(regattaAndRaceId.getTypeRelativeObjectIdentifier());
|
||||
}
|
||||
@@ -1318,7 +1357,7 @@ public interface TrackedRace
|
||||
default HasPermissions getPermissionType() {
|
||||
return getSecuredDomainType();
|
||||
}
|
||||
|
||||
|
||||
public static HasPermissions getSecuredDomainType() {
|
||||
return SecuredDomainType.TRACKED_RACE;
|
||||
}
|
||||
@@ -1341,13 +1380,14 @@ public interface TrackedRace
|
||||
* the maximum across their competitors' implied winds, or in case the implied wind was explicitly fixed by a
|
||||
* corresponding {@link RaceLogORCImpliedWindSourceEvent}, that fixed implied wind speed.
|
||||
*/
|
||||
default Speed getReferenceImpliedWind(TimePoint timePoint, WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
default Speed getReferenceImpliedWind(TimePoint timePoint,
|
||||
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
|
||||
return getRankingMetric().getReferenceImpliedWind(timePoint, cache);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gets a {@link TrackingConnectorInfo}, which contains a String representation of the Tracking-Service used to Track the Race and a web-URL for the Event Event;
|
||||
* may be {@code null}, particularly in test set-ups
|
||||
* gets a {@link TrackingConnectorInfo}, which contains a String representation of the Tracking-Service used to
|
||||
* Track the Race and a web-URL for the Event Event; may be {@code null}, particularly in test set-ups
|
||||
*/
|
||||
TrackingConnectorInfo getTrackingConnectorInfo();
|
||||
|
||||
@@ -1381,8 +1421,8 @@ public interface TrackedRace
|
||||
* hypothetical "line" perpendicular to the first leg's bearing.
|
||||
*/
|
||||
Pair<Bearing, Position> getStartLineBearingAndStarboardMarkPosition(TimePoint timePoint);
|
||||
|
||||
void setHashValuesForMarkPassingCalculation(Map<typeOfHash, Integer> hashValues);
|
||||
|
||||
Map<typeOfHash, Integer> getHashValuesForMarkPassingCalculation ();
|
||||
|
||||
void setHashValuesForMarkPassingCalculation(Map<TypeOfHash, Integer> hashValues);
|
||||
|
||||
Map<TypeOfHash, Integer> getHashValuesForMarkPassingCalculation();
|
||||
}
|
||||
|
||||
+4
-4
@@ -123,6 +123,7 @@ import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
|
||||
import com.sap.sailing.domain.maneuverdetection.ShortTimeAfterLastHitCache;
|
||||
import com.sap.sailing.domain.maneuverdetection.impl.IncrementalManeuverDetectorImpl;
|
||||
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
||||
import com.sap.sailing.domain.markpassinghash.impl.TrackedRaceHashForMarkPassingComparatorImpl.TypeOfHash;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
|
||||
@@ -158,7 +159,6 @@ import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindSummary;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceHashForMarkPassingComperatorImpl.typeOfHash;
|
||||
import com.sap.sailing.domain.windestimation.IncrementalWindEstimation;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -444,7 +444,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
private transient ConcurrentMap<TimePoint, SortedMap<Competitor, Distance>> distancesFromStarboardSideOfStartLineProjectedOntoLineCache;
|
||||
private transient ConcurrentMap<TimePoint, TimePoint> distancesFromStarboardSideOfStartLineProjectedOntoLineCacheLastAccessTimes;
|
||||
|
||||
private Map<typeOfHash, Integer> hashValuesForMarkPassingCalculation;
|
||||
private Map<TypeOfHash, Integer> hashValuesForMarkPassingCalculation;
|
||||
|
||||
/**
|
||||
* When a regatta's {@link Regatta#useStartTimeInference()} or {@link Regatta#isControlTrackingFromStartAndFinishTimes()}
|
||||
@@ -4307,11 +4307,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
return trackingConnectorInfo;
|
||||
}
|
||||
|
||||
public void setHashValuesForMarkPassingCalculation(Map<typeOfHash, Integer> hashValues) {
|
||||
public void setHashValuesForMarkPassingCalculation(Map<TypeOfHash, Integer> hashValues) {
|
||||
this.hashValuesForMarkPassingCalculation = hashValues;
|
||||
}
|
||||
|
||||
public Map<typeOfHash, Integer> getHashValuesForMarkPassingCalculation () {
|
||||
public Map<TypeOfHash, Integer> getHashValuesForMarkPassingCalculation () {
|
||||
return this.hashValuesForMarkPassingCalculation;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user