mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-21 21:25:38 +00:00
Merge branch 'main' into translation
This commit is contained in:
@@ -7,6 +7,9 @@ Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: com.sap.sailing.geocoding,
|
||||
com.sap.sailing.server.interfaces,
|
||||
com.sap.sailing.server.preferences,
|
||||
com.sap.sse.replication,
|
||||
com.sap.sse.security,
|
||||
org.osgi.framework;version="1.7.0"
|
||||
Export-Package: com.sap.sailing.datamining,
|
||||
com.sap.sailing.datamining.data,
|
||||
|
||||
+4
-2
@@ -119,7 +119,7 @@ TackAtStart=Tack at Start
|
||||
SpeedTenSecondsAfterStart=Speed 10s After Start
|
||||
RankThirtySecondsAfterStart=Rank 30s After Start
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Windward Distance to Advantageous End of Line at Start of Race
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Windward Distance to Starboard Side of Line at Start of Competitor
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Windward Distance to Advantageous Side of Line at Start of Competitor
|
||||
RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg
|
||||
AdvantageousEndOfLine=Advantageous End of Line
|
||||
AdvantageOfStarboardSideOfStartLine=Advantage of starboard side of start line
|
||||
@@ -133,6 +133,7 @@ WindSourceType=Wind Source Type
|
||||
AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor=Absolute Windward Distance to Starboardside of Line at Start of Competitor
|
||||
WindSourceName=Wind Source Name
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Relative Distance to Advantageous End of Line at Start of Race
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Relative Distance to Advantageous End of Line at Start of Competitor
|
||||
windFrom=True Wind Direction (TWD)
|
||||
windSpeedKnots=True Wind Speed (kts)
|
||||
speedInKnots=Speed (kts)
|
||||
@@ -284,4 +285,5 @@ RatioDurationLongVsShortTack=Ratio duration long tack / short tack
|
||||
Discarded=Discarded
|
||||
DurationFromRaceStartToFirstTack=Duration from race start to first tack
|
||||
TypeOfFirstLeg=Type of first leg
|
||||
TenthInLeg=Which tenth of the leg (1-10)
|
||||
TenthInLeg=Which tenth of the leg (1-10)
|
||||
SailorProfile=Sailor Profile
|
||||
+5
-3
@@ -143,6 +143,7 @@ pitch=Neigung
|
||||
heel=Krängung
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens (X) vs. Relative Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens (Y)
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Relative Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Relative Distanz zum Bevorteilten Ende der Startlinie zum Startzeitpunkt des Teilnehmers
|
||||
rideHeight=Foiling-Höhe
|
||||
rideHeightPort=Foiling-Höhe Backbord-Rumpf
|
||||
rideHeightStarboard=Foiling-Höhe Steuerbord-Rumpf
|
||||
@@ -258,8 +259,8 @@ XTERelativeSigned=Relative Querabweichung, mit Vorzeichen (-1 = 1/2 Schenkellän
|
||||
XTERelativeUnsigned=Relative Querabweichung, ohne Vorzeichen (0 = Mitte, 1 = ganz aussen)
|
||||
XTEToWindAxisUnsigned=Querabweichung zur Windachse, ohne Vorzeichen
|
||||
XTEToWindAxisSigned=Querabweichung zur Windachse, vorzeichenbehaftet (- = links, + = rechts)
|
||||
XTEToWindAxisRelativeUnsigned=Relative Querabweichung zur Windachse, mit Vorzeichen (-1 = 1/2 Schenkellänge links, 0 = Mitte, +1 = 1/2 Schenkellänge rechts)
|
||||
XTEToWindAxisRelativeSigned=Relative Querabweichung zur Windachse, ohne Vorzeichen (0 = Mitte, 1 = ganz aussen)
|
||||
XTEToWindAxisRelativeUnsigned=Relative Querabweichung zur Windachse, ohne Vorzeichen (0 = Mitte, 1 = ganz aussen)
|
||||
XTEToWindAxisRelativeSigned=Relative Querabweichung zur Windachse, mit Vorzeichen (-1 = 1/2 Schenkellänge links, 0 = Mitte, +1 = 1/2 Schenkellänge rechts)
|
||||
Day=Tag
|
||||
CompetitorDay=Teilnehmer-Tag
|
||||
CompetitorDaySailingDomainRetrieverChain=Teilnehmer-Tag für Wettfahrt
|
||||
@@ -282,4 +283,5 @@ RatioDurationLongVsShortTack=Verhältnis gesegelte Dauer auf Streck- zu Holebug
|
||||
Discarded=Gestrichen
|
||||
DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende
|
||||
TypeOfFirstLeg=Art des ersten Bahnschenkels
|
||||
TenthInLeg=Zehntel des Bahnschenkels (1-10)
|
||||
TenthInLeg=Zehntel des Bahnschenkels (1-10)
|
||||
SailorProfile=Seglerprofil
|
||||
+37
-37
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
@@ -19,86 +18,87 @@ import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface AbstractHasTrackedLegSliceOfCompetitorContext extends HasWindOnTrackedLeg {
|
||||
public interface AbstractHasTrackedLegSliceOfCompetitorContext extends HasWindOnTrackedLeg, HasSomethingOfCompetitorContext {
|
||||
@Connector(scanForStatistics=false)
|
||||
public HasTrackedLegContext getTrackedLegContext();
|
||||
HasTrackedLegContext getTrackedLegContext();
|
||||
|
||||
public TrackedLegOfCompetitor getTrackedLegOfCompetitor();
|
||||
TrackedLegOfCompetitor getTrackedLegOfCompetitor();
|
||||
|
||||
default HasTrackedRaceContext getTrackedRaceContext() {
|
||||
return getTrackedLegContext().getTrackedRaceContext();
|
||||
}
|
||||
|
||||
@Dimension(messageKey="RelativeScoreInRaceInPercent", ordinal=12)
|
||||
public ClusterDTO getPercentageClusterForRelativeScoreInRace();
|
||||
ClusterDTO getPercentageClusterForRelativeScoreInRace();
|
||||
|
||||
@Connector(messageKey="Boat")
|
||||
public Boat getBoat();
|
||||
|
||||
@Connector(messageKey="Competitor")
|
||||
public Competitor getCompetitor();
|
||||
Boat getBoat();
|
||||
|
||||
@Statistic(messageKey="DistanceTraveled", resultDecimals=2, ordinal=0)
|
||||
public Distance getDistanceTraveled();
|
||||
Distance getDistanceTraveled();
|
||||
|
||||
@Statistic(messageKey="SpeedAverage", resultDecimals=2, ordinal=0)
|
||||
public Double getSpeedAverageInKnots();
|
||||
Double getSpeedAverageInKnots();
|
||||
|
||||
@Statistic(messageKey="RankGainsOrLosses", resultDecimals=2, ordinal=1)
|
||||
public Integer getRankGainsOrLosses();
|
||||
Integer getRankGainsOrLosses();
|
||||
|
||||
@Statistic(messageKey="RelativeScore", resultDecimals=2, ordinal=2)
|
||||
public Double getRelativeRank();
|
||||
Double getRelativeRank();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRank", resultDecimals=0, ordinal=3)
|
||||
public Integer getRankAtSliceFinish();
|
||||
Integer getRankAtSliceFinish();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankAfterFirstQuarter", resultDecimals=0, ordinal=4)
|
||||
public Integer getRankAfterFirstQuarter();
|
||||
Integer getRankAfterFirstQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankAfterSecondQuarter", resultDecimals=0, ordinal=5)
|
||||
public Integer getRankAfterSecondQuarter();
|
||||
Integer getRankAfterSecondQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankAfterThirdQuarter", resultDecimals=0, ordinal=6)
|
||||
public Integer getRankAfterThirdQuarter();
|
||||
Integer getRankAfterThirdQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=7)
|
||||
public Double getRankAverageAcrossFirstThreeQuarters();
|
||||
Double getRankAverageAcrossFirstThreeQuarters();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterFirstQuarter", resultDecimals=0, ordinal=8)
|
||||
public Integer getRankRhumbLineBasedAfterFirstQuarter();
|
||||
Integer getRankRhumbLineBasedAfterFirstQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterSecondQuarter", resultDecimals=0, ordinal=9)
|
||||
public Integer getRankRhumbLineBasedAfterSecondQuarter();
|
||||
Integer getRankRhumbLineBasedAfterSecondQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterThirdQuarter", resultDecimals=0, ordinal=10)
|
||||
public Integer getRankRhumbLineBasedAfterThirdQuarter();
|
||||
Integer getRankRhumbLineBasedAfterThirdQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=11)
|
||||
public Double getRankRhumbLineBasedAverageAcrossFirstThreeQuarters();
|
||||
Double getRankRhumbLineBasedAverageAcrossFirstThreeQuarters();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterFirstQuarter", resultDecimals=2, ordinal=12)
|
||||
public Double getRankPredictionErrorAfterFirstQuarter();
|
||||
Double getRankPredictionErrorAfterFirstQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterSecondQuarter", resultDecimals=2, ordinal=13)
|
||||
public Double getRankPredictionErrorAfterSecondQuarter();
|
||||
Double getRankPredictionErrorAfterSecondQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterThirdQuarter", resultDecimals=2, ordinal=14)
|
||||
public Double getRankPredictionErrorAfterThirdQuarter();
|
||||
Double getRankPredictionErrorAfterThirdQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorAcrossFirstThreeQuarters", resultDecimals=2, ordinal=15)
|
||||
public Double getRankPredictionErrorAcrossFirstThreeQuarters();
|
||||
Double getRankPredictionErrorAcrossFirstThreeQuarters();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterFirstQuarter", resultDecimals=2, ordinal=16)
|
||||
public Double getRankPredictionErrorRhumbLineBasedAfterFirstQuarter();
|
||||
Double getRankPredictionErrorRhumbLineBasedAfterFirstQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterSecondQuarter", resultDecimals=2, ordinal=17)
|
||||
public Double getRankPredictionErrorRhumbLineBasedAfterSecondQuarter();
|
||||
Double getRankPredictionErrorRhumbLineBasedAfterSecondQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterThirdQuarter", resultDecimals=2, ordinal=18)
|
||||
public Double getRankPredictionErrorRhumbLineBasedAfterThirdQuarter();
|
||||
Double getRankPredictionErrorRhumbLineBasedAfterThirdQuarter();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters", resultDecimals=2, ordinal=19)
|
||||
public Double getRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters();
|
||||
Double getRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters();
|
||||
|
||||
@Statistic(messageKey="TimeSpentInSeconds", resultDecimals=0, ordinal=4)
|
||||
public Long getTimeTakenInSeconds();
|
||||
Long getTimeTakenInSeconds();
|
||||
|
||||
@Statistic(messageKey="timeSpentFoiling", resultDecimals=1)
|
||||
Duration getTimeSpentFoiling();
|
||||
@@ -107,20 +107,20 @@ public interface AbstractHasTrackedLegSliceOfCompetitorContext extends HasWindOn
|
||||
Distance getDistanceSpentFoiling();
|
||||
|
||||
@Statistic(messageKey="NumberOfManeuvers", resultDecimals=0)
|
||||
public Integer getNumberOfManeuvers();
|
||||
Integer getNumberOfManeuvers();
|
||||
|
||||
@Statistic(messageKey="NumberOfJibes", resultDecimals=0)
|
||||
public Integer getNumberOfJibes();
|
||||
Integer getNumberOfJibes();
|
||||
|
||||
@Statistic(messageKey="NumberOfTacks", resultDecimals=0)
|
||||
public Integer getNumberOfTacks();
|
||||
Integer getNumberOfTacks();
|
||||
|
||||
@Statistic(messageKey="VMG", resultDecimals=2)
|
||||
public Speed getVelocityMadeGood();
|
||||
Speed getVelocityMadeGood();
|
||||
|
||||
@Statistic(messageKey="RatioDurationLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDurationLongVsShortTack();
|
||||
double getRatioDurationLongVsShortTack();
|
||||
|
||||
@Statistic(messageKey="RatioDistanceLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDistanceLongVsShortTack();
|
||||
double getRatioDistanceLongVsShortTack();
|
||||
}
|
||||
+5
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
|
||||
public interface HasLeaderboardGroupContext {
|
||||
@Connector(messageKey="LeaderboardGroup", ordinal=0)
|
||||
@@ -12,4 +13,8 @@ public interface HasLeaderboardGroupContext {
|
||||
PolarDataService getPolarDataService();
|
||||
|
||||
DomainFactory getBaseDomainFactory();
|
||||
|
||||
SecurityService getSecurityService();
|
||||
|
||||
SailorProfiles getSailorProfiles();
|
||||
}
|
||||
|
||||
+5
-7
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
@@ -14,15 +13,11 @@ import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public interface HasRaceOfCompetitorContext {
|
||||
|
||||
public interface HasRaceOfCompetitorContext extends HasSomethingOfCompetitorContext {
|
||||
@Override
|
||||
@Connector(scanForStatistics=false)
|
||||
HasTrackedRaceContext getTrackedRaceContext();
|
||||
|
||||
@Connector(messageKey="Competitor")
|
||||
@Statistic(messageKey="Competitor")
|
||||
Competitor getCompetitor();
|
||||
|
||||
@Dimension(messageKey="TackAtStart", ordinal=12)
|
||||
Tack getTackAtStart() throws NoWindException;
|
||||
|
||||
@@ -140,6 +135,9 @@ public interface HasRaceOfCompetitorContext {
|
||||
@Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLineAtStartOfRace", resultDecimals=2)
|
||||
Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace();
|
||||
|
||||
@Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLineAtStartOfCompetitor", resultDecimals=2)
|
||||
Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfCompetitor();
|
||||
|
||||
@Statistic(messageKey="RaceDuration")
|
||||
Duration getDuration();
|
||||
|
||||
|
||||
+11
-15
@@ -1,32 +1,28 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public interface HasRaceResultOfCompetitorContext {
|
||||
|
||||
public interface HasRaceResultOfCompetitorContext extends HasSomethingOfCompetitorContext {
|
||||
@Connector(scanForStatistics=false)
|
||||
public HasLeaderboardContext getLeaderboardContext();
|
||||
HasLeaderboardContext getLeaderboardContext();
|
||||
|
||||
@Override
|
||||
@Connector(scanForStatistics=false)
|
||||
public HasTrackedRaceContext getTrackedRaceContext();
|
||||
HasTrackedRaceContext getTrackedRaceContext();
|
||||
|
||||
@Connector(messageKey="Competitor", ordinal=2)
|
||||
public Competitor getCompetitor();
|
||||
|
||||
@Connector(messageKey="Boat")
|
||||
public Boat getBoat();
|
||||
Boat getBoat();
|
||||
|
||||
@Dimension(messageKey="Regatta", ordinal=4)
|
||||
String getRegattaName();
|
||||
|
||||
@Dimension(messageKey="RelativeScoreInPercent", ordinal=6)
|
||||
public ClusterDTO getPercentageClusterForRelativeScore();
|
||||
ClusterDTO getPercentageClusterForRelativeScore();
|
||||
|
||||
@Dimension(messageKey="WindSpeedInBeaufort", ordinal=7)
|
||||
int getAverageWindSpeedInRoundedBeaufort();
|
||||
@@ -35,20 +31,20 @@ public interface HasRaceResultOfCompetitorContext {
|
||||
* 0 means the competitor won the race, 1 means the competitor ranked last
|
||||
*/
|
||||
@Statistic(messageKey="RelativeScore", ordinal=1, resultDecimals=2)
|
||||
public Double getRelativeRank();
|
||||
Double getRelativeRank();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRank", ordinal=2, resultDecimals=2)
|
||||
public Double getAbsoluteRank();
|
||||
Double getAbsoluteRank();
|
||||
|
||||
@Dimension(messageKey="IRM")
|
||||
public MaxPointsReason getMaxPointsReason();
|
||||
MaxPointsReason getMaxPointsReason();
|
||||
|
||||
@Dimension(messageKey="Discarded")
|
||||
boolean isDiscarded();
|
||||
|
||||
@Statistic(messageKey="NumberOfPodiumFinish", ordinal=3)
|
||||
public Boolean isPodiumFinish();
|
||||
Boolean isPodiumFinish();
|
||||
|
||||
@Statistic(messageKey="NumberOfWins", ordinal=4)
|
||||
public Boolean isWin();
|
||||
Boolean isWin();
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
|
||||
public interface HasSomethingOfCompetitorContext {
|
||||
HasTrackedRaceContext getTrackedRaceContext();
|
||||
|
||||
@Connector(messageKey="Competitor", ordinal=2)
|
||||
Competitor getCompetitor();
|
||||
|
||||
@Connector(messageKey="SailorProfile")
|
||||
default SailorProfile getSailorProfile() {
|
||||
return getTrackedRaceContext().getLeaderboardContext().getLeaderboardGroupContext().getSailorProfiles().getProfileForCompetitor(getCompetitor());
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreference;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreferences;
|
||||
import com.sap.sse.common.NamedWithUUID;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* A sailor profile currently mainly consists of a set of competitors that it consolidates into a single profile. It can
|
||||
* be used particularly in a data mining context when there are multiple distinct records that from a user's point of
|
||||
* view represent the same sailor/competitor. With this, a user can define a {@link SailorProfile} like an "equivalence
|
||||
* class" that allows the user to, e.g., filter or group data mining results based on a competitor's "equivalence
|
||||
* class."
|
||||
* <p>
|
||||
*
|
||||
* A typical example would be a single-handed class, say "ILCA 6," where the same person has been participating in
|
||||
* several events, but each time captured with a different technical competitor ID, maybe even competing under different
|
||||
* sail numbers. Yet, during analysis, it may make sense to group the results for all of these entities under one sailor
|
||||
* profile.
|
||||
* <p>
|
||||
*
|
||||
* Technically, the sailor profiles are managed as user preferences in the user store. A preference converter can turn
|
||||
* the underlying JSON string into an {@link SailorProfilePreferences} object which contains
|
||||
* {@link SailorProfilePreference}. These, in turn, can be converted to instances of a type implementing this interface.
|
||||
* <p>
|
||||
*
|
||||
* Comparability is defined such that no two profiles with different {@link #getId() IDs} will ever compare equal.
|
||||
* Beyond this, {@link SailorProfile}s with a greater number of {@link #getCompetitors() competitors} than another will
|
||||
* be considered "greater." In case of an equal number of competitors, the sailor profile {@link #getName() name} will
|
||||
* be used for lexicographic ordering. In case of equal names, sorting will work by the stringified version of the
|
||||
* {@link #getId() UUID}.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface SailorProfile extends NamedWithUUID, Comparable<SailorProfile> {
|
||||
Iterable<Competitor> getCompetitors();
|
||||
|
||||
@Override
|
||||
default int compareTo(SailorProfile o) {
|
||||
int result = Integer.compare(Util.size(getCompetitors()), Util.size(o.getCompetitors()));
|
||||
if (result == 0) {
|
||||
result = getName().compareTo(o.getName());
|
||||
if (result == 0) {
|
||||
result = getId().compareTo(o.getId());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
/**
|
||||
* A "data mining" view on the current user's sailor profiles as defined in the user preferences. When an instance is
|
||||
* constructed, it collects all of the user's sailor profiles and builds a map from the {@link Competitor} objects to
|
||||
* the {@link SailorProfile} objects that refer to that {@link Competitor}.
|
||||
* <p>
|
||||
*
|
||||
* When more than one of the user's {@link SailorProfile}s comprise the same {@link Competitor}, a stable algorithm
|
||||
* for determining a single preferred {@link SailorProfile} for the {@link Competitor} will be used in the
|
||||
* {@link #getProfileForCompetitor(Competitor)}, finding the "greatest" (as defined by the {@link Comparable} property
|
||||
* of the {@link SailorProfile} interface) profile for the {@link Competitor}.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface SailorProfiles {
|
||||
SailorProfile getProfileForCompetitor(Competitor competitor);
|
||||
}
|
||||
+1
-2
@@ -30,9 +30,8 @@ public class LeaderboardGroupRetrievalProcessor extends AbstractRetrievalProcess
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
data.add(new LeaderboardGroupWithContext(leaderboardGroup, polarDataService, element.getBaseDomainFactory()));
|
||||
data.add(new LeaderboardGroupWithContext(leaderboardGroup, polarDataService, element.getBaseDomainFactory(), element.getSecurityService()));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
-1
@@ -1,19 +1,34 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.datamining.data.SailorProfiles;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreference;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreferences;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
|
||||
public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
|
||||
private final LeaderboardGroup leaderboardGroup;
|
||||
private final PolarDataService polarDataService;
|
||||
private final DomainFactory baseDomainFactory;
|
||||
private final SecurityService securityService;
|
||||
|
||||
/**
|
||||
* Access has to be synchronized; it is constructed lazily by the {@link #getSailorProfiles()} method.
|
||||
*/
|
||||
private SailorProfiles sailorProfiles;
|
||||
|
||||
public LeaderboardGroupWithContext(LeaderboardGroup leaderboardGroup, PolarDataService polarDataService, DomainFactory baseDomainFactory) {
|
||||
public LeaderboardGroupWithContext(LeaderboardGroup leaderboardGroup, PolarDataService polarDataService, DomainFactory baseDomainFactory, SecurityService securityService) {
|
||||
this.leaderboardGroup = leaderboardGroup;
|
||||
this.polarDataService = polarDataService;
|
||||
this.baseDomainFactory = baseDomainFactory;
|
||||
this.securityService = securityService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,4 +45,25 @@ public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
|
||||
public DomainFactory getBaseDomainFactory() {
|
||||
return baseDomainFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityService getSecurityService() {
|
||||
return securityService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized SailorProfiles getSailorProfiles() {
|
||||
if (sailorProfiles == null) {
|
||||
final SailorProfilePreferences sailorProfilePreferences = getSecurityService().getPreferenceObject(getSecurityService().getCurrentUser().getName(), SailorProfilePreferences.PREF_NAME);
|
||||
if (sailorProfilePreferences != null) {
|
||||
final List<SailorProfile> theSailorProfiles = new ArrayList<>();
|
||||
for (final SailorProfilePreference sailorProfilePreference : sailorProfilePreferences.getSailorProfiles()) {
|
||||
final SailorProfile sailorProfile = new SailorProfileImpl(sailorProfilePreference.getUuid(), sailorProfilePreference.getName(), sailorProfilePreference.getCompetitors());
|
||||
theSailorProfiles.add(sailorProfile);
|
||||
}
|
||||
sailorProfiles = new SailorProfilesImpl(theSailorProfiles);
|
||||
}
|
||||
}
|
||||
return sailorProfiles;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-11
@@ -360,9 +360,18 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
|
||||
@Override
|
||||
public Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace() {
|
||||
TrackedRace trackedRace = getTrackedRace();
|
||||
TimePoint startOfRace = trackedRace.getStartOfRace();
|
||||
LineDetails startLine = trackedRace.getStartLine(startOfRace);
|
||||
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
return getRelativeDistanceToAdvantageousEndOfLine(startOfRace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfCompetitor() {
|
||||
final TimePoint competitorStartTimePoint = getTrackedRace().getTrackedLeg(getCompetitor(), getTrackedRace().getRace().getCourse().getFirstLeg()).getStartTime();
|
||||
return getRelativeDistanceToAdvantageousEndOfLine(competitorStartTimePoint);
|
||||
}
|
||||
|
||||
private Double getRelativeDistanceToAdvantageousEndOfLine(final TimePoint timePoint) {
|
||||
final LineDetails startLine = getTrackedRace().getStartLine(timePoint);
|
||||
Mark advantageousMark = null;
|
||||
switch (startLine.getAdvantageousSideWhileApproachingLine()) {
|
||||
case PORT:
|
||||
@@ -375,14 +384,14 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
if (advantageousMark == null) {
|
||||
return null;
|
||||
}
|
||||
GPSFixTrack<Mark, GPSFix> advantageousMarkTrack = trackedRace.getOrCreateTrack(advantageousMark);
|
||||
Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(startOfRace, false);
|
||||
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(getCompetitor());
|
||||
Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false);
|
||||
Double distance = competitorPosition.getDistance(advantageousMarkPosition).getMeters();
|
||||
TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, trackedRace.getRace().getCourse().getFirstLeg());
|
||||
TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime();
|
||||
Double length = trackedRace.getStartLine(competitorStartTime).getLength().getMeters();
|
||||
final GPSFixTrack<Mark, GPSFix> advantageousMarkTrack = getTrackedRace().getOrCreateTrack(advantageousMark);
|
||||
final Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(timePoint, false);
|
||||
final GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = getTrackedRace().getTrack(getCompetitor());
|
||||
final Position competitorPosition = competitorTrack.getEstimatedPosition(timePoint, false);
|
||||
final Double distance = competitorPosition.getDistance(advantageousMarkPosition).getMeters();
|
||||
final TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, getTrackedRace().getRace().getCourse().getFirstLeg());
|
||||
final TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime();
|
||||
final Double length = getTrackedRace().getStartLine(competitorStartTime).getLength().getMeters();
|
||||
return distance / length;
|
||||
}
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.NamedWithUUIDImpl;
|
||||
|
||||
public class SailorProfileImpl extends NamedWithUUIDImpl implements SailorProfile {
|
||||
private static final long serialVersionUID = 5851705759679719738L;
|
||||
|
||||
private final List<Competitor> competitors;
|
||||
|
||||
public SailorProfileImpl(UUID id, String name, Iterable<Competitor> competitors) {
|
||||
super(name, id);
|
||||
final List<Competitor> myCompetitors = new ArrayList<>();
|
||||
Util.addAll(competitors, myCompetitors);
|
||||
this.competitors = myCompetitors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
return Collections.unmodifiableList(competitors);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.datamining.data.SailorProfiles;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
public class SailorProfilesImpl implements SailorProfiles {
|
||||
final Map<Competitor, SailorProfile> profilesForCompetitor;
|
||||
|
||||
/**
|
||||
* Constructs the mapping from {@link Competitor} to {@link SailorProfile} based on the
|
||||
* {@link SailorProfile#compareTo(SailorProfile) ordering} of the {@link SailorProfile}s. For each competitor,
|
||||
* {@link #getProfileForCompetitor(Competitor)} will return the "greatest" profile found that
|
||||
* {@link SailorProfile#getCompetitors() contains} that competitor.
|
||||
*/
|
||||
public SailorProfilesImpl(final Iterable<SailorProfile> sailorProfiles) {
|
||||
this.profilesForCompetitor = new HashMap<>();
|
||||
for (final SailorProfile sailorProfile : sailorProfiles) {
|
||||
for (final Competitor competitor : sailorProfile.getCompetitors()) {
|
||||
final SailorProfile existingSailorProfileForCompetitor = profilesForCompetitor.get(competitor);
|
||||
if (existingSailorProfileForCompetitor == null || existingSailorProfileForCompetitor.compareTo(sailorProfile) < 0) {
|
||||
profilesForCompetitor.put(competitor, sailorProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SailorProfile getProfileForCompetitor(Competitor competitor) {
|
||||
return profilesForCompetitor.get(competitor);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user