Merge branch 'master' into translation

This commit is contained in:
Axel Uhl committed 2017-02-14 21:13:37 +01:00
commit f76e161ba6
275 files changed
+10282 -1302

No files matched your search

@@ -1,5 +0,0 @@
eclipse.preferences.version=1
encoding//resources/stringmessages/Sailing_StringMessages_ja.properties=UTF-8
encoding//resources/stringmessages/Sailing_StringMessages_ru.properties=UTF-8
encoding//resources/stringmessages/Sailing_StringMessages_zh.properties=UTF-8
encoding//resources/stringmessages/Sailing_StringMessages_zh_CN.properties=UTF-8
@@ -21,6 +21,9 @@ LeaderboardSailingDomainRetrieverChain=Leaderboards
RaceSailingDomainRetrieverChain=Races
LegSailingDomainRetrieverChain=Legs
GPSFixSailingDomainRetrieverChain=GPS Fixes
BravoFixSailingDomainRetrieverChain=Bravo Fixes
BravoFixTrackSailingDomainRetrieverChain=Bravo Tracks
FoilingSegmentsSailingDomainRetrieverChain=Foiled Segments
WindFixSailingDomainRetrieverChain=Wind Fixes
MarkPassingSailingDomainRetrieverChain=Mark Passings
RaceResultSailingDomainRetrieverChain=Race Results
@@ -32,6 +35,8 @@ Leg=Leg
MarkPassing=Mark Passing
LegOfCompetitor=Leg of competitor
GpsFix=GPS Fix
BravoFix=Bravo Fix
BravoFixTrack=Bravo Fix Track
WindFix=Wind Fix
Maneuver=Maneuver
WindStrengthInBeaufort=Wind Strength in Beaufort
@@ -92,5 +97,29 @@ WindSourceName=Wind Source Name
windFrom=True Wind Direction (TWD)
windSpeedKnots=True Wind Speed (kts)
speedInKnots=Speed (kts)
bearing=Course over Ground (°T)
WindTrack=Wind Track
bearing=Direction (°T)
WindTrack=Wind Track
timeSpentFoiling=Time spent foiling
yaw=Yaw
pitch=Pitch
roll=Heel
rideHeight=Ride Height
rideHeightPort=Ride Height Port Hull
rideHeightStarboard=Ride Height Starboard Hull
IsFoiling=Is Foiling
FoilingDuration=Foiling Duration
FoilingDistance=Distance Foiled
TakeoffSpeedInKnotsInKnots=Takeoff speed in knots
LandingSpeedInKnots=Landing speed in knots
AbsoluteTrueWindAngleAtTakeoff=Absolute true wind angle (TWA) at takeoff
AbsoluteTrueWindAngleAtLanding=Absolute true wind angle (TWA) at landing
WindStrengthInBeaufortAtTakeoff=Wind strength in beaufort at takeoff
WindStrengthInBeaufortAtLanding=Wind strength in beaufort at landing
WindAtTakeoff=Wind at takeoff
WindAtLanding=Wind at landing
StartsOnLegType=Type of leg at takeoff
EndsOnLegType=Type of leg at landing
FoilingSegments=Foiled Segments
AverageAbsoluteTrueWindAngle=Average absolute true wind angle
AbsoluteTrueWindAngle=Absolute true wind angle (TWA)
Wind=Wind
@@ -19,6 +19,9 @@ LeaderboardSailingDomainRetrieverChain=Leaderboards
RaceSailingDomainRetrieverChain=Rennen
LegSailingDomainRetrieverChain=Schenkel
GPSFixSailingDomainRetrieverChain=GPS-Fixes
BravoFixSailingDomainRetrieverChain=Bravo-Fixes
BravoFixTrackSailingDomainRetrieverChain=Bravo Messreihen
FoilingSegmentsSailingDomainRetrieverChain=Gefoilte Abschnitte
WindFixSailingDomainRetrieverChain=Windmessungen
MarkPassingSailingDomainRetrieverChain=Tonnenrundungen
RaceResultSailingDomainRetrieverChain=Rennergebnisse
@@ -30,6 +33,8 @@ Leg=Schenkel
MarkPassing=Tonnenrundung
LegOfCompetitor=Schenkel eines Teilnehmers
GpsFix=GPS-Fix
BravoFix=Bravo-Fix
BravoFixTrack=Bravo-Messreihe
WindFix=Windmessung
Maneuver=Manöver
Speed=Geschwindigkeit
@@ -92,5 +97,29 @@ WindSourceName=Name der Windmessreihe
windFrom=Wind aus Richtung (TWD)
windSpeedKnots=Wahre Windgeschwindigkeit (kn)
speedInKnots=Fahrt (kn)
bearing=Kurs über Grund (°)
WindTrack=Windmessreihe
bearing=Richtung (°)
WindTrack=Windmessreihe
timeSpentFoiling=Zeit auf Foils
yaw=Gierung
pitch=Neigung
roll=Krängung
rideHeight=Foiling-Höhe
rideHeightPort=Foiling-Höhe Backbord-Rumpf
rideHeightStarboard=Foiling-Höhe Steuerbord-Rumpf
IsFoiling=Foilt
FoilingDuration=Foilingdauer
FoilingDistance=Gefoilte Distanz
TakeoffSpeedInKnotsInKnots=Abhebegeschwindigkeit in Knoten
LandingSpeedInKnots=Landegeschwindigkeit in Knoten
AbsoluteTrueWindAngleAtTakeoff=Absoluter Winkel zum wahren Wind (TWA) beim Abheben
AbsoluteTrueWindAngleAtLanding=Absoluter Winkel zum wahren Wind (TWA) beim Landen
WindStrengthInBeaufortAtTakeoff=Windstärke beim Abheben in Beaufort
WindStrengthInBeaufortAtLanding=Windstärke beim Landen in Beaufort
WindAtTakeoff=Wind beim Abheben
WindAtLanding=Wind beim Landen
StartsOnLegType=Bahnschnenkeltyp beim Abheben
EndsOnLegType=Bahnschenkeltyp beim Landen
FoilingSegments=Gefoilte Abschnitte
AverageAbsoluteTrueWindAngle=Durchschnittlicher absoluter Winkel zum wahren Wind (TWA)
AbsoluteTrueWindAngle=Absoluter Winkel zum wahren Wind (TWA)
Wind=Wind
@@ -7,6 +7,9 @@ import java.util.Set;
import org.osgi.framework.BundleContext;
import com.sap.sailing.datamining.data.HasBravoFixContext;
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
@@ -20,12 +23,18 @@ import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.data.HasWindFixContext;
import com.sap.sailing.datamining.data.HasWindTrackContext;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelBearingAverageDegreesAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelBearingMaxAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelBearingMinAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelBoolSumAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceAverageAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMaxAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMedianAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMinAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceSumAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDurationAverageAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDurationMaxAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDurationMinAggregationProcessor;
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDurationSumAggregationProcessor;
import com.sap.sailing.datamining.provider.RacingEventServiceProvider;
import com.sap.sse.datamining.DataSourceProvider;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
@@ -87,6 +96,9 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
internalClasses.add(HasGPSFixContext.class);
internalClasses.add(HasWindTrackContext.class);
internalClasses.add(HasWindFixContext.class);
internalClasses.add(HasBravoFixContext.class);
internalClasses.add(HasBravoFixTrackContext.class);
internalClasses.add(HasFoilingSegmentContext.class);
internalClasses.add(HasManeuverContext.class);
internalClasses.add(HasMarkPassingContext.class);
internalClasses.add(HasRaceOfCompetitorContext.class);
@@ -118,7 +130,13 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
aggregators.add(ParallelDistanceMaxAggregationProcessor.getDefinition());
aggregators.add(ParallelDistanceMinAggregationProcessor.getDefinition());
aggregators.add(ParallelDistanceMedianAggregationProcessor.getDefinition());
aggregators.add(ParallelDurationSumAggregationProcessor.getDefinition());
aggregators.add(ParallelDurationAverageAggregationProcessor.getDefinition());
aggregators.add(ParallelDurationMaxAggregationProcessor.getDefinition());
aggregators.add(ParallelDurationMinAggregationProcessor.getDefinition());
aggregators.add(ParallelBearingAverageDegreesAggregationProcessor.getDefinition());
aggregators.add(ParallelBearingMaxAggregationProcessor.getDefinition());
aggregators.add(ParallelBearingMinAggregationProcessor.getDefinition());
return aggregators;
}
@@ -3,6 +3,9 @@ package com.sap.sailing.datamining;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.data.HasBravoFixContext;
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.datamining.data.HasManeuverContext;
@@ -14,7 +17,10 @@ import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.data.HasWindFixContext;
import com.sap.sailing.datamining.data.HasWindTrackContext;
import com.sap.sailing.datamining.impl.components.BravoFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.BravoFixTrackRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.CompetitorOfRaceInLeaderboardRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.FoilingSegmentRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardRetrievalProcessor;
@@ -60,6 +66,18 @@ public class SailingDataRetrievalChainDefinitions {
raceOfCompetitorRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, RaceOfCompetitorRetrievalProcessor.class, HasRaceOfCompetitorContext.class, "Competitor");
dataRetrieverChainDefinitions.add(raceOfCompetitorRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasBravoFixTrackContext> bravoFixTrackRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
raceOfCompetitorRetrieverChainDefinition, HasBravoFixTrackContext.class, "BravoFixTrackSailingDomainRetrieverChain");
bravoFixTrackRetrieverChainDefinition.endWith(RaceOfCompetitorRetrievalProcessor.class, BravoFixTrackRetrievalProcessor.class,
HasBravoFixTrackContext.class, "BravoFixTrack");
dataRetrieverChainDefinitions.add(bravoFixTrackRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasFoilingSegmentContext> foilingSegmentsRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
raceOfCompetitorRetrieverChainDefinition, HasFoilingSegmentContext.class, "FoilingSegmentsSailingDomainRetrieverChain");
foilingSegmentsRetrieverChainDefinition.endWith(RaceOfCompetitorRetrievalProcessor.class, FoilingSegmentRetrievalProcessor.class,
HasFoilingSegmentContext.class, "FoilingSegments");
dataRetrieverChainDefinitions.add(foilingSegmentsRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegOfCompetitorContext> legOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
trackedRaceRetrieverChainDefinition, HasTrackedLegOfCompetitorContext.class, "LegSailingDomainRetrieverChain");
legOfCompetitorRetrieverChainDefinition.addAfter(TrackedRaceRetrievalProcessor.class, TrackedLegRetrievalProcessor.class, HasTrackedLegContext.class, "Leg");
@@ -73,6 +91,12 @@ public class SailingDataRetrievalChainDefinitions {
HasGPSFixContext.class, "GpsFix");
dataRetrieverChainDefinitions.add(gpsFixRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasBravoFixContext> bravoFixRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
legOfCompetitorRetrieverChainDefinition, HasBravoFixContext.class, "BravoFixSailingDomainRetrieverChain");
bravoFixRetrieverChainDefinition.endWith(TrackedLegOfCompetitorRetrievalProcessor.class, BravoFixRetrievalProcessor.class,
HasBravoFixContext.class, "BravoFix");
dataRetrieverChainDefinitions.add(bravoFixRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasWindFixContext> windFixRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
trackedRaceRetrieverChainDefinition, HasWindFixContext.class, "WindFixSailingDomainRetrieverChain");
windFixRetrieverChainDefinition.addAfter(TrackedRaceRetrievalProcessor.class, WindTrackRetrievalProcessor.class, HasWindTrackContext.class, "WindTrack");
@@ -0,0 +1,32 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sse.common.TimePoint;
import com.sap.sse.datamining.annotations.Connector;
import com.sap.sse.datamining.annotations.Statistic;
public interface HasBravoFixContext extends HasWindOnTrackedLeg {
@Connector(scanForStatistics=false)
HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
@Connector(ordinal=1)
BravoFix getBravoFix();
@Connector(messageKey="Speed")
SpeedWithBearing getSpeed();
@Connector(messageKey="Wind")
Wind getWind();
@Statistic(messageKey="AbsoluteTrueWindAngle")
Bearing getAbsoluteTrueWindAngle() throws NoWindException;
@Override
default TimePoint getTimePoint() {
return getBravoFix().getTimePoint();
}
}
@@ -0,0 +1,17 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sse.common.Duration;
import com.sap.sse.datamining.annotations.Connector;
import com.sap.sse.datamining.annotations.Statistic;
public interface HasBravoFixTrackContext {
@Connector(scanForStatistics=false)
HasRaceOfCompetitorContext getRaceOfCompetitorContext();
BravoFixTrack<Competitor> getBravoFixTrack();
@Statistic(messageKey="timeSpentFoiling", resultDecimals=1)
Duration getTimeSpentFoiling();
}
@@ -0,0 +1,64 @@
package com.sap.sailing.datamining.data;
import java.util.Locale;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Wind;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
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;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public interface HasFoilingSegmentContext {
@Connector(scanForStatistics=false)
HasBravoFixTrackContext getBravoFixTrackContext();
TimePoint getStartOfFoilingSegment();
TimePoint getEndOfFoilingSegment();
@Statistic(messageKey="FoilingDuration")
Duration getDuration();
@Statistic(messageKey="FoilingDistance")
Distance getDistance();
@Statistic(messageKey="TakeoffSpeedInKnotsInKnots", resultDecimals=1)
Double getTakeoffSpeedInKnots();
@Statistic(messageKey="LandingSpeedInKnots", resultDecimals=1)
Double getLandingSpeedInKnots();
@Statistic(messageKey="AbsoluteTrueWindAngleAtTakeoff", resultDecimals=1)
Bearing getAbsoluteTrueWindAngleAtTakeoffInDegrees() throws NoWindException;
@Statistic(messageKey="AbsoluteTrueWindAngleAtLanding", resultDecimals=1)
Bearing getAbsoluteTrueWindAngleAtLandingInDegrees() throws NoWindException;
@Statistic(messageKey="AverageAbsoluteTrueWindAngle", resultDecimals=1)
Bearing getAverageAbsoluteTrueWindAngle() throws NoWindException;
@Dimension(messageKey="WindStrengthInBeaufortAtTakeoff")
ClusterDTO getWindStrengthAsBeaufortClusterAtTakeoff(Locale locale, ResourceBundleStringMessages stringMessages);
@Dimension(messageKey="WindStrengthInBeaufortAtLanding")
ClusterDTO getWindStrengthAsBeaufortClusterAtLanding(Locale locale, ResourceBundleStringMessages stringMessages);
@Connector(messageKey="WindAtTakeoff")
Wind getWindAtTakeoff();
@Connector(messageKey="WindAtLanding")
Wind getWindAtLanding();
@Dimension(messageKey="StartsOnLegType")
LegType getStartsOnLegType() throws NoWindException;
@Dimension(messageKey="EndsOnLegType")
LegType getEndsOnLegType() throws NoWindException;
}
@@ -9,6 +9,6 @@ public interface HasLeaderboardContext {
PolarDataService getPolarDataService();
@Dimension(messageKey="Leaderboard")
@Dimension(messageKey="Leaderboard", ordinal=1)
String getName();
}
@@ -20,6 +20,9 @@ public interface HasManeuverContext extends HasWindOnTrackedLeg, HasManeuver, Ha
@Dimension(messageKey="Tack", ordinal=13)
Tack getTack();
@Dimension(messageKey="ToSide")
NauticalSide getToSide();
@Connector(messageKey="SpeedBefore", ordinal=0)
SpeedWithBearing getSpeedBefore();
@@ -28,14 +31,10 @@ public interface HasManeuverContext extends HasWindOnTrackedLeg, HasManeuver, Ha
@Statistic(messageKey="DirectionChange", resultDecimals=2, ordinal=2)
Double getDirectionChangeInDegrees();
@Statistic(messageKey="AbsoluteDirectionChange", resultDecimals=2, ordinal=2)
@Statistic(messageKey="AbsoluteDirectionChange", resultDecimals=2, ordinal=3)
Double getAbsoluteDirectionChangeInDegrees();
@Dimension(messageKey="ToSide")
NauticalSide getToSide();
@Statistic(messageKey="ManeuverLoss", resultDecimals=0, ordinal=3)
@Statistic(messageKey="ManeuverLoss", resultDecimals=0, ordinal=4)
Distance getManeuverLoss();
}
@@ -5,25 +5,29 @@ import com.sap.sailing.domain.base.Competitor;
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 {
@Connector(scanForStatistics=false)
public HasLeaderboardContext getLeaderboardContext();
@Connector(messageKey="Competitor")
@Connector(messageKey="Competitor", ordinal=2)
public Competitor getCompetitor();
@Connector(messageKey="BoatClass")
@Connector(messageKey="BoatClass", ordinal=3)
BoatClass getBoatClass();
@Dimension(messageKey="Regatta")
@Dimension(messageKey="Regatta", ordinal=4)
String getRegattaName();
@Dimension(messageKey="CompetitorSearchTag", ordinal=11) // TODO Clean me: Move Dimension to Competitor when possible
@Dimension(messageKey="CompetitorSearchTag", ordinal=5) // TODO Clean me: Move Dimension to Competitor when possible
public String getCompetitorSearchTag();
@Dimension(messageKey="RelativeScoreInPercent", ordinal=6)
public ClusterDTO getPercentageClusterForRelativeScore();
@Dimension(messageKey="WindSpeedInBeaufort")
@Dimension(messageKey="WindSpeedInBeaufort", ordinal=7)
int getAverageWindSpeedInRoundedBeaufort();
/**
@@ -17,7 +17,7 @@ public interface HasWind extends Positioned, Timed {
@Dimension(messageKey="WindStrengthInBeaufort", ordinal=11)
default ClusterDTO getWindStrengthAsBeaufortCluster(Locale locale, ResourceBundleStringMessages stringMessages) {
Wind wind = getWind();
Cluster<?> cluster = Activator.getClusterGroups().getWindStrengthInBeaufortClusterGroup().getClusterFor(wind);
return new ClusterDTO(cluster.asLocalizedString(locale, stringMessages));
final Cluster<?> cluster = Activator.getClusterGroups().getWindStrengthInBeaufortClusterGroup().getClusterFor(wind);
return new ClusterDTO(cluster.toString(), ()->cluster.asLocalizedString(locale, stringMessages));
}
}
@@ -11,13 +11,13 @@ public interface HasWindFixContext extends HasWind {
@Connector(scanForStatistics=false)
public HasTrackedRaceContext getTrackedRaceContext();
@Statistic(messageKey="")
@Statistic(messageKey="", ordinal=0)
public Wind getWind();
@Statistic(messageKey="windFrom", resultDecimals=1)
@Statistic(messageKey="windFrom", resultDecimals=1, ordinal=1)
double getWindFromDegrees();
@Statistic(messageKey="windSpeedKnots", resultDecimals=1)
@Statistic(messageKey="windSpeedKnots", resultDecimals=1, ordinal=2)
double getWindSpeedInKnots();
@Override
@@ -0,0 +1,44 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.data.HasBravoFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.BravoFixWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
public class BravoFixRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedLegOfCompetitorContext, HasBravoFixContext> {
public BravoFixRetrievalProcessor(ExecutorService executor, Collection<Processor<HasBravoFixContext, ?>> resultReceivers, int retrievalLevel) {
super(HasTrackedLegOfCompetitorContext.class, HasBravoFixContext.class, executor, resultReceivers, retrievalLevel);
}
@Override
protected Iterable<HasBravoFixContext> retrieveData(HasTrackedLegOfCompetitorContext element) {
Collection<HasBravoFixContext> bravoFixesWithContext = new ArrayList<>();
BravoFixTrack<Competitor> bravoFixTrack = element.getTrackedLegContext().getTrackedRaceContext().getTrackedRace().getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME);
if (bravoFixTrack != null) {
bravoFixTrack.lockForRead();
try {
TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor();
if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) {
for (BravoFix bravoFix : bravoFixTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) {
BravoFixWithContext gpsFixWithContext = new BravoFixWithContext(element, bravoFix);
bravoFixesWithContext.add(gpsFixWithContext);
}
}
} finally {
bravoFixTrack.unlockAfterRead();
}
}
return bravoFixesWithContext;
}
}
@@ -0,0 +1,40 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.BravoFixTrackWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
/**
* Retrieves all wind fixes from a {@link TrackedRace} that are provided by wind sources that are not currently
* {@link TrackedRace#getWindSourcesToExclude() excluded}.
*
* @author Axel Uhl (d043530)
*
*/
public class BravoFixTrackRetrievalProcessor extends AbstractRetrievalProcessor<HasRaceOfCompetitorContext, HasBravoFixTrackContext> {
public BravoFixTrackRetrievalProcessor(ExecutorService executor, Collection<Processor<HasBravoFixTrackContext, ?>> resultReceivers, int retrievalLevel) {
super(HasRaceOfCompetitorContext.class, HasBravoFixTrackContext.class, executor, resultReceivers, retrievalLevel);
}
@Override
protected Iterable<HasBravoFixTrackContext> retrieveData(HasRaceOfCompetitorContext element) {
Collection<HasBravoFixTrackContext> bravoTracksWithContext = new ArrayList<>();
final TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace();
final BravoFixTrack<Competitor> bravoFixTrack = trackedRace.getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME);
if (bravoFixTrack != null) {
bravoTracksWithContext.add(new BravoFixTrackWithContext(element, bravoFixTrack));
}
return bravoTracksWithContext;
}
}
@@ -0,0 +1,76 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.BravoFixTrackWithContext;
import com.sap.sailing.datamining.impl.data.FoilingSegmentWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
public class FoilingSegmentRetrievalProcessor extends AbstractRetrievalProcessor<HasRaceOfCompetitorContext, HasFoilingSegmentContext> {
public FoilingSegmentRetrievalProcessor(ExecutorService executor, Collection<Processor<HasFoilingSegmentContext, ?>> resultReceivers, int retrievalLevel) {
super(HasRaceOfCompetitorContext.class, HasFoilingSegmentContext.class, executor, resultReceivers, retrievalLevel);
}
@Override
protected Iterable<HasFoilingSegmentContext> retrieveData(HasRaceOfCompetitorContext element) {
Collection<HasFoilingSegmentContext> foilingSegments = new ArrayList<>();
final TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace();
final TimePoint startOfRace = element.getTrackedRaceContext().getTrackedRace().getStartOfRace();
if (startOfRace != null) {
final TimePoint endOfRace = element.getTrackedRaceContext().getTrackedRace().getEndOfRace();
final TimePoint end;
if (endOfRace == null) {
final TimePoint endOfTracking = element.getTrackedRaceContext().getTrackedRace().getEndOfTracking();
end = endOfTracking == null ? MillisecondsTimePoint.now() : endOfTracking;
} else {
end = endOfRace;
}
final BravoFixTrack<Competitor> bravoFixTrack = trackedRace.getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME);
if (bravoFixTrack != null) {
boolean isFoiling = false;
TimePoint startOfSegment = null;
bravoFixTrack.lockForRead();
try {
for (final BravoFix bravoFix : bravoFixTrack.getFixes(startOfRace, /* fromInclusive */ true, end, /* toInclusive */ false)) {
if (isFoiling) {
if (!bravoFix.isFoiling()) {
isFoiling = false;
foilingSegments.add(createFoilingSegment(startOfSegment, bravoFix.getTimePoint(), element, bravoFixTrack));
startOfSegment = null;
}
} else {
if (bravoFix.isFoiling()) {
isFoiling = true;
startOfSegment = bravoFix.getTimePoint();
}
}
}
} finally {
bravoFixTrack.unlockAfterRead();
}
if (isFoiling) {
foilingSegments.add(createFoilingSegment(startOfSegment, end, element, bravoFixTrack));
}
}
}
return foilingSegments;
}
private HasFoilingSegmentContext createFoilingSegment(TimePoint startOfSegment, TimePoint endOfSegment,
HasRaceOfCompetitorContext raceOfCompetitorContext, BravoFixTrack<Competitor> bravoFixTrack) {
return new FoilingSegmentWithContext(new BravoFixTrackWithContext(raceOfCompetitorContext, bravoFixTrack), startOfSegment, endOfSegment);
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMaxAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelBearingMaxAggregationProcessor extends
AbstractParallelComparableMaxAggregationProcessor<Bearing> {
private static final AggregationProcessorDefinition<Bearing, Bearing> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Bearing.class, Bearing.class, "Maximum", ParallelBearingMaxAggregationProcessor.class);
public static AggregationProcessorDefinition<Bearing, Bearing> getDefinition() {
return DEFINITION;
}
public ParallelBearingMaxAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Bearing>, ?>> resultReceivers) {
super(executor, resultReceivers);
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMaxAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelBearingMinAggregationProcessor extends
AbstractParallelComparableMaxAggregationProcessor<Bearing> {
private static final AggregationProcessorDefinition<Bearing, Bearing> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Bearing.class, Bearing.class, "Minimum", ParallelBearingMinAggregationProcessor.class);
public static AggregationProcessorDefinition<Bearing, Bearing> getDefinition() {
return DEFINITION;
}
public ParallelBearingMinAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Bearing>, ?>> resultReceivers) {
super(executor, resultReceivers);
}
}
@@ -8,28 +8,21 @@ import com.sap.sailing.domain.common.Distance;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelSingleGroupedValueAggregationProcessor;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMaxAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDistanceMaxAggregationProcessor extends
AbstractParallelSingleGroupedValueAggregationProcessor<Distance> {
AbstractParallelComparableMaxAggregationProcessor<Distance> {
private static final AggregationProcessorDefinition<Distance, Distance> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Distance.class, Distance.class, "Minimum", ParallelDistanceMaxAggregationProcessor.class);
new SimpleAggregationProcessorDefinition<>(Distance.class, Distance.class, "Maximum", ParallelDistanceMaxAggregationProcessor.class);
public static AggregationProcessorDefinition<Distance, Distance> getDefinition() {
return DEFINITION;
}
public ParallelDistanceMaxAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Distance>, ?>> resultReceivers) {
super(executor, resultReceivers, "Minimum");
super(executor, resultReceivers);
}
@Override
protected Distance compareValuesAndReturnNewResult(Distance currentResult, Distance newValue) {
return currentResult.getMeters() >= newValue.getMeters() ? currentResult : newValue;
}
}
@@ -8,11 +8,11 @@ import com.sap.sailing.domain.common.Distance;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelSingleGroupedValueAggregationProcessor;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMinAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDistanceMinAggregationProcessor extends
AbstractParallelSingleGroupedValueAggregationProcessor<Distance> {
AbstractParallelComparableMinAggregationProcessor<Distance> {
private static final AggregationProcessorDefinition<Distance, Distance> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Distance.class, Distance.class, "Minimum", ParallelDistanceMinAggregationProcessor.class);
@@ -24,12 +24,6 @@ public class ParallelDistanceMinAggregationProcessor extends
public ParallelDistanceMinAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Distance>, ?>> resultReceivers) {
super(executor, resultReceivers, "Minimum");
super(executor, resultReceivers);
}
@Override
protected Distance compareValuesAndReturnNewResult(Distance currentResult, Distance newValue) {
return currentResult.getMeters() <= newValue.getMeters() ? currentResult : newValue;
}
}
@@ -0,0 +1,63 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Duration;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelGroupedDataStoringAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDurationAverageAggregationProcessor
extends AbstractParallelGroupedDataStoringAggregationProcessor<Duration, Duration> {
private static final AggregationProcessorDefinition<Duration, Duration> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Duration.class, Duration.class, "Average", ParallelDurationAverageAggregationProcessor.class);
public static AggregationProcessorDefinition<Duration, Duration> getDefinition() {
return DEFINITION;
}
private final ParallelDurationSumAggregationProcessor sumAggregationProcessor;
private final Map<GroupKey, Integer> elementAmountPerKey;
public ParallelDurationAverageAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Duration>, ?>> resultReceivers) {
super(executor, resultReceivers, "Average");
elementAmountPerKey = new HashMap<>();
sumAggregationProcessor = new ParallelDurationSumAggregationProcessor(executor, resultReceivers);
}
@Override
protected void storeElement(GroupedDataEntry<Duration> element) {
incrementElementAmount(element);
sumAggregationProcessor.handleElement(element);
}
private void incrementElementAmount(GroupedDataEntry<Duration> element) {
GroupKey key = element.getKey();
if (!elementAmountPerKey.containsKey(key)) {
elementAmountPerKey.put(key, 0);
}
Integer currentAmount = elementAmountPerKey.get(key);
elementAmountPerKey.put(key, currentAmount + 1);
}
@Override
protected Map<GroupKey, Duration> aggregateResult() {
Map<GroupKey, Duration> result = new HashMap<>();
Map<GroupKey, Duration> sumAggregation = sumAggregationProcessor.getResult();
for (Entry<GroupKey, Duration> sumAggregationEntry : sumAggregation.entrySet()) {
GroupKey key = sumAggregationEntry.getKey();
result.put(key, sumAggregationEntry.getValue().divide(elementAmountPerKey.get(key).doubleValue()));
}
return result;
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Duration;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMaxAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDurationMaxAggregationProcessor extends
AbstractParallelComparableMaxAggregationProcessor<Duration> {
private static final AggregationProcessorDefinition<Duration, Duration> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Duration.class, Duration.class, "Maximum", ParallelDurationMaxAggregationProcessor.class);
public static AggregationProcessorDefinition<Duration, Duration> getDefinition() {
return DEFINITION;
}
public ParallelDurationMaxAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Duration>, ?>> resultReceivers) {
super(executor, resultReceivers);
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Duration;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelComparableMinAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDurationMinAggregationProcessor extends
AbstractParallelComparableMinAggregationProcessor<Duration> {
private static final AggregationProcessorDefinition<Duration, Duration> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Duration.class, Duration.class, "Minimum", ParallelDurationMinAggregationProcessor.class);
public static AggregationProcessorDefinition<Duration, Duration> getDefinition() {
return DEFINITION;
}
public ParallelDurationMinAggregationProcessor(ExecutorService executor,
Collection<Processor<Map<GroupKey, Duration>, ?>> resultReceivers) {
super(executor, resultReceivers);
}
}
@@ -0,0 +1,47 @@
package com.sap.sailing.datamining.impl.components.aggregators;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Duration;
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition;
import com.sap.sse.datamining.impl.components.aggregators.AbstractParallelGroupedDataAggregationProcessor;
import com.sap.sse.datamining.shared.GroupKey;
public class ParallelDurationSumAggregationProcessor extends
AbstractParallelGroupedDataAggregationProcessor<Duration, Duration> {
private static final AggregationProcessorDefinition<Duration, Duration> DEFINITION =
new SimpleAggregationProcessorDefinition<>(Duration.class, Duration.class, "Sum", ParallelDurationSumAggregationProcessor.class);
public static AggregationProcessorDefinition<Duration, Duration> getDefinition() {
return DEFINITION;
}
private final Map<GroupKey, Duration> results;
public ParallelDurationSumAggregationProcessor(ExecutorService executor, Collection<Processor<Map<GroupKey, Duration>, ?>> resultReceivers) {
super(executor, resultReceivers, "Sum");
results = new HashMap<>();
}
@Override
protected void handleElement(GroupedDataEntry<Duration> element) {
GroupKey key = element.getKey();
if (!results.containsKey(key)) {
results.put(key, element.getDataEntry());
} else {
results.put(key, results.get(key).plus(element.getDataEntry()));
}
}
@Override
protected Map<GroupKey, Duration> getResult() {
return results;
}
}
@@ -0,0 +1,46 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class BravoFixTrackWithContext implements HasBravoFixTrackContext {
private final HasRaceOfCompetitorContext raceOfCompetitorContext;
private final BravoFixTrack<Competitor> bravoFixTrack;
public BravoFixTrackWithContext(HasRaceOfCompetitorContext raceOfCompetitorContext, BravoFixTrack<Competitor> bravoFixTrack) {
this.raceOfCompetitorContext = raceOfCompetitorContext;
this.bravoFixTrack = bravoFixTrack;
}
@Override
public HasRaceOfCompetitorContext getRaceOfCompetitorContext() {
return raceOfCompetitorContext;
}
@Override
public BravoFixTrack<Competitor> getBravoFixTrack() {
return bravoFixTrack;
}
@Override
public Duration getTimeSpentFoiling() {
final TimePoint endOfRace = getRaceOfCompetitorContext().getTrackedRaceContext().getTrackedRace().getEndOfRace();
final TimePoint startOfRace = getRaceOfCompetitorContext().getTrackedRaceContext().getTrackedRace().getStartOfRace();
final TimePoint end;
if (endOfRace == null) {
final TimePoint endOfTracking = getRaceOfCompetitorContext().getTrackedRaceContext().getTrackedRace().getEndOfTracking();
end = endOfTracking == null ? MillisecondsTimePoint.now() : endOfTracking;
} else {
end = endOfRace;
}
return bravoFixTrack.getTimeSpentFoiling(startOfRace, end);
}
}
@@ -0,0 +1,80 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasBravoFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
public class BravoFixWithContext implements HasBravoFixContext {
private static final long serialVersionUID = -4537126043228674949L;
private final HasTrackedLegOfCompetitorContext trackedLegOfCompetitorContext;
private final BravoFix bravoFix;
private Wind wind;
public BravoFixWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitorContext, BravoFix bravoFix) {
this.trackedLegOfCompetitorContext = trackedLegOfCompetitorContext;
this.bravoFix = bravoFix;
}
@Override
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext() {
return trackedLegOfCompetitorContext;
}
@Override
public BravoFix getBravoFix() {
return bravoFix;
}
@Override
public Wind getWindInternal() {
return wind;
}
@Override
public void setWindInternal(Wind wind) {
this.wind = wind;
}
@Override
public SpeedWithBearing getSpeed() {
return getGpsFixTrack().getEstimatedSpeed(getTimePoint());
}
@Override
public Wind getWind() {
return getTrackedRace().getWind(getGpsFixTrack().getEstimatedPosition(getTimePoint(), /* extrapolate */ true), getTimePoint());
}
@Override
public Bearing getAbsoluteTrueWindAngle() throws NoWindException {
return getTrackedRace().getTrackedLeg(getCompetitor(), getTimePoint()).getBeatAngle(getTimePoint()).abs();
}
private Competitor getCompetitor() {
return getTrackedLegOfCompetitorContext().getCompetitor();
}
@Override
public Position getPosition() {
return getGpsFixTrack().getEstimatedPosition(getTimePoint(), /* extrapolate */ true);
}
private GPSFixTrack<Competitor, GPSFixMoving> getGpsFixTrack() {
return getTrackedRace().getTrack(getTrackedLegOfCompetitorContext().getCompetitor());
}
private TrackedRace getTrackedRace() {
return getTrackedLegOfCompetitorContext().getTrackedLegOfCompetitor().getTrackedLeg().getTrackedRace();
}
}
@@ -0,0 +1,164 @@
package com.sap.sailing.datamining.impl.data;
import java.util.Locale;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.BearingCluster;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.BravoFixTrack;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class FoilingSegmentWithContext implements HasFoilingSegmentContext {
private final HasBravoFixTrackContext bravoFixTrackContext;
private final TimePoint startOfFoilingSegment;
private final TimePoint endOfFoilingSegment;
public FoilingSegmentWithContext(HasBravoFixTrackContext bravoFixTrackContext, TimePoint startOfFoilingSegment,
TimePoint endOfFoilingSegment) {
super();
this.bravoFixTrackContext = bravoFixTrackContext;
this.startOfFoilingSegment = startOfFoilingSegment;
this.endOfFoilingSegment = endOfFoilingSegment;
}
@Override
public HasBravoFixTrackContext getBravoFixTrackContext() {
return bravoFixTrackContext;
}
@Override
public TimePoint getStartOfFoilingSegment() {
return startOfFoilingSegment;
}
@Override
public TimePoint getEndOfFoilingSegment() {
return endOfFoilingSegment;
}
@Override
public Duration getDuration() {
return getStartOfFoilingSegment().until(getEndOfFoilingSegment());
}
@Override
public Distance getDistance() {
return getGpsFixTrack().
getDistanceTraveled(getStartOfFoilingSegment(), getEndOfFoilingSegment());
}
private GPSFixTrack<Competitor, GPSFixMoving> getGpsFixTrack() {
return getTrackedRace().getTrack(getCompetitor());
}
private Competitor getCompetitor() {
return getBravoFixTrackContext().getRaceOfCompetitorContext().getCompetitor();
}
private TrackedRace getTrackedRace() {
return getBravoFixTrackContext().getRaceOfCompetitorContext().getTrackedRaceContext().getTrackedRace();
}
@Override
public Double getTakeoffSpeedInKnots() {
final SpeedWithBearing estimatedSpeed = getGpsFixTrack().getEstimatedSpeed(getStartOfFoilingSegment());
return estimatedSpeed==null?null:estimatedSpeed.getKnots();
}
@Override
public Double getLandingSpeedInKnots() {
final SpeedWithBearing estimatedSpeed = getGpsFixTrack().getEstimatedSpeed(getEndOfFoilingSegment());
return estimatedSpeed==null?null:estimatedSpeed.getKnots();
}
@Override
public Bearing getAbsoluteTrueWindAngleAtTakeoffInDegrees() throws NoWindException {
return getAbsoluteTrueWindAngle(getStartOfFoilingSegment());
}
@Override
public Bearing getAbsoluteTrueWindAngleAtLandingInDegrees() throws NoWindException {
final TimePoint timePoint = getEndOfFoilingSegment();
return getAbsoluteTrueWindAngle(timePoint);
}
private Bearing getAbsoluteTrueWindAngle(final TimePoint timePoint) throws NoWindException {
return getTrackedRace().getTrackedLeg(getCompetitor(), timePoint).getBeatAngle(timePoint).abs();
}
@Override
public Bearing getAverageAbsoluteTrueWindAngle() throws NoWindException {
final BearingCluster bearingCluster = new BearingCluster();
final BravoFixTrack<Competitor> bravoFixTrack = getBravoFixTrackContext().getBravoFixTrack();
bravoFixTrack.lockForRead();
try {
for (final BravoFix bravoFix : bravoFixTrack.getFixes(getStartOfFoilingSegment(), /* fromInclusive */ true, getEndOfFoilingSegment(), /* toInclusive */ false)) {
bearingCluster.add(getAbsoluteTrueWindAngle(bravoFix.getTimePoint()));
}
} finally {
bravoFixTrack.unlockAfterRead();
}
return bearingCluster.getAverage();
}
@Override
public ClusterDTO getWindStrengthAsBeaufortClusterAtTakeoff(Locale locale,
ResourceBundleStringMessages stringMessages) {
return getWindStrengthAsBeaufortCluster(locale, stringMessages, getWindAtTakeoff());
}
@Override
public ClusterDTO getWindStrengthAsBeaufortClusterAtLanding(Locale locale,
ResourceBundleStringMessages stringMessages) {
return getWindStrengthAsBeaufortCluster(locale, stringMessages, getWindAtLanding());
}
private Wind getWind(TimePoint timePoint) {
return getTrackedRace().getWind(getGpsFixTrack().getEstimatedPosition(timePoint, /* extrapolate */ true), timePoint);
}
@Override
public Wind getWindAtTakeoff() {
return getWind(getStartOfFoilingSegment());
}
@Override
public Wind getWindAtLanding() {
return getWind(getEndOfFoilingSegment());
}
private ClusterDTO getWindStrengthAsBeaufortCluster(Locale locale, ResourceBundleStringMessages stringMessages, Wind wind) {
Cluster<?> cluster = Activator.getClusterGroups().getWindStrengthInBeaufortClusterGroup().getClusterFor(wind);
return new ClusterDTO(cluster.toString(), ()->cluster.asLocalizedString(locale, stringMessages));
}
@Override
public LegType getStartsOnLegType() throws NoWindException {
return getLegType(getStartOfFoilingSegment());
}
private LegType getLegType(final TimePoint timePoint) throws NoWindException {
return getTrackedRace().getTrackedLeg(getCompetitor(), timePoint).getTrackedLeg().getLegType(timePoint);
}
@Override
public LegType getEndsOnLegType() throws NoWindException {
return getLegType(getEndOfFoilingSegment());
}
}
@@ -5,6 +5,8 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.SailingClusterGroups;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
import com.sap.sailing.domain.base.BoatClass;
@@ -31,6 +33,8 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
public class RaceResultOfCompetitorWithContext implements HasRaceResultOfCompetitorContext {
private final static Logger logger = Logger.getLogger(RaceResultOfCompetitorWithContext.class.getName());
@@ -78,6 +82,18 @@ public class RaceResultOfCompetitorWithContext implements HasRaceResultOfCompeti
public String getCompetitorSearchTag() {
return getCompetitor().getSearchTag();
}
@Override
public ClusterDTO getPercentageClusterForRelativeScore() {
Double relativeScore = getRelativeRank();
if (relativeScore == null) {
return null;
}
SailingClusterGroups clusterGroups = Activator.getClusterGroups();
Cluster<Double> cluster = clusterGroups.getPercentageClusterGroup().getClusterFor(relativeScore);
return new ClusterDTO(clusterGroups.getPercentageClusterFormatter().format(cluster));
}
@Override
public int getAverageWindSpeedInRoundedBeaufort() {