mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-25 21:43:49 +00:00
Merge remote-tracking branch 'origin/master' into dataMining
This commit is contained in:
commit
e0a9f552b6
2 files changed
+67
-6
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.xmlexport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -19,6 +20,8 @@ import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
@@ -27,6 +30,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
@@ -246,6 +250,42 @@ public abstract class ExportAction {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<Maneuver> getManeuvers(TrackedRace trackedRace, Competitor competitor, boolean waitForLatest) throws NoWindException {
|
||||
List<Maneuver> maneuvers = trackedRace.getManeuvers(competitor,
|
||||
trackedRace.getStartOfRace(), trackedRace.getEndOfRace(), waitForLatest);
|
||||
return maneuvers;
|
||||
}
|
||||
|
||||
public Integer getNumberOfJibes(List<Maneuver> maneuvers) throws NoWindException {
|
||||
int result = 0;
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
if (maneuver.getType() == ManeuverType.JIBE) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Integer getNumberOfPenaltyCircles(List<Maneuver> maneuvers) throws NoWindException {
|
||||
int result = 0;
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
if (maneuver.getType() == ManeuverType.PENALTY_CIRCLE) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Integer getNumberOfTacks(List<Maneuver> maneuvers) throws NoWindException {
|
||||
int result = 0;
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
if (maneuver.getType() == ManeuverType.TACK) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String cleanSailId(String sailId, Competitor competitor) {
|
||||
if (sailId.matches("^[A-Z]{3}\\s[0-9]*")) {
|
||||
Pattern regex = Pattern.compile("(^[A-Z]{3})\\s([0-9]*)");
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.sap.sailing.domain.base.SpeedWithConfidence;
|
||||
import com.sap.sailing.domain.base.impl.SpeedWithConfidenceImpl;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Duration;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
@@ -39,6 +40,7 @@ import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.LineDetails;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
@@ -167,7 +169,7 @@ public class LeaderboardData extends ExportAction {
|
||||
windSpeedAsInterval = "16-20kn";
|
||||
} else if (speedInKnots > 20) {
|
||||
windSpeedAsHumanReadableString = VERY_STRONG_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "20-"+Math.rint(speedInKnots)+"kn";
|
||||
windSpeedAsInterval = "20-80kn";
|
||||
}
|
||||
windElements.add(createNamedElementWithValue(prefix+"human_readable", windSpeedAsHumanReadableString));
|
||||
windElements.add(createNamedElementWithValue(prefix+"knots_interval", windSpeedAsInterval));
|
||||
@@ -184,6 +186,7 @@ public class LeaderboardData extends ExportAction {
|
||||
|
||||
addNamedElementWithValue(raceElement, "start_type", race.getTrackedLeg(race.getRace().getCourse().getFirstLeg()).getLegType(race.getStartOfRace()).name());
|
||||
addNamedElementWithValue(raceElement, "delay_to_live_in_millis", race.getDelayToLiveInMillis());
|
||||
addNamedElementWithValue(raceElement, "multiplication_factor", column.getExplicitFactor() == null ? 1.0d : column.getExplicitFactor());
|
||||
|
||||
addNamedElementWithValue(raceElement, "timepoint_of_last_event_as_millis", handleValue(race.getTimePointOfLastEvent()));
|
||||
addNamedElementWithValue(raceElement, "timepoint_of_newest_event_as_millis", handleValue(race.getTimePointOfNewestEvent()));
|
||||
@@ -250,6 +253,11 @@ public class LeaderboardData extends ExportAction {
|
||||
Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null);
|
||||
Element competitorRaceDataElement = new Element("competitor_race_data");
|
||||
MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, column, race.getEndOfRace());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString());
|
||||
boolean isDiscardedForCompetitor = leaderboard.isDiscarded(competitor, column, race.getEndOfRace());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "is_discarded", isDiscardedForCompetitor == true ? "true" : "false");
|
||||
Double finalRaceScore = leaderboard.getTotalPoints(competitor, column, race.getEndOfRace());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "final_race_score", finalRaceScore);
|
||||
if (maxPointsReason.equals(MaxPointsReason.DNS) || race.getMarkPassings(competitor).isEmpty()) {
|
||||
// we do not want to include competitors that did not start the race
|
||||
competitorElement.addContent(competitorRaceDataElement);
|
||||
@@ -264,6 +272,24 @@ public class LeaderboardData extends ExportAction {
|
||||
addNamedElementWithValue(competitorRaceDataElement, "speed_"+i+"seconds_before_start_of_race_in_knots", race.getTrack(competitor).getEstimatedSpeed(beforeRaceStartTime).getKnots());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "distance_from_starboard_side_of_start_line_"+i+"seconds_before_start_in_meters", race.getDistanceFromStarboardSideOfStartLine(competitor, beforeRaceStartTime).getMeters());
|
||||
|
||||
List<Maneuver> maneuvers = getManeuvers(race, competitor, /*waitForLatest*/ false);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "number_of_maneuvers", maneuvers != null ? maneuvers.size() : 0);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "number_of_tacks", getNumberOfTacks(maneuvers));
|
||||
addNamedElementWithValue(competitorRaceDataElement, "number_of_jibes", getNumberOfJibes(maneuvers));
|
||||
addNamedElementWithValue(competitorRaceDataElement, "number_of_penalty_circles", getNumberOfPenaltyCircles(maneuvers));
|
||||
|
||||
GPSFixTrack<Competitor, GPSFixMoving> gpsFixesForCompetitor = race.getTrack(competitor);
|
||||
if (gpsFixesForCompetitor != null) {
|
||||
Duration averageIntervall = gpsFixesForCompetitor.getAverageIntervalBetweenFixes();
|
||||
if (averageIntervall != null) {
|
||||
addNamedElementWithValue(competitorRaceDataElement, "average_interval_between_fixes_outliers_removed_as_millis", averageIntervall.asMillis());
|
||||
}
|
||||
Duration averageIntervallRaw = gpsFixesForCompetitor.getAverageIntervalBetweenRawFixes();
|
||||
if (averageIntervallRaw != null) {
|
||||
addNamedElementWithValue(competitorRaceDataElement, "average_interval_between_fixes_raw_as_millis", averageIntervallRaw.asMillis());
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Mark> marksForStartLine = race.getStartLine(beforeRaceStartTime).getWaypoint().getControlPoint().getMarks().iterator();
|
||||
Mark first = marksForStartLine.next();
|
||||
Mark second = null;
|
||||
@@ -331,13 +357,8 @@ public class LeaderboardData extends ExportAction {
|
||||
raceConfidenceAndErrorMessages.getB().add("It seems that competitor " + competitor.getName() + " has not finished first leg!");
|
||||
addNamedElementWithValue(competitorRaceDataElement, "rank_at_end_of_first_leg", 0);
|
||||
}
|
||||
Double finalRaceScore = leaderboard.getTotalPoints(competitor, column, race.getEndOfRace());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "final_race_score", finalRaceScore);
|
||||
boolean isDiscardedForCompetitor = leaderboard.isDiscarded(competitor, column, race.getEndOfRace());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "is_discarded", isDiscardedForCompetitor == true ? "true" : "false");
|
||||
Distance averageCrossTrackError = race.getAverageCrossTrackError(competitor, race.getEndOfRace(), /*waitForLatestAnalysis*/ false);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "average_cross_track_error_in_meters", averageCrossTrackError != null ? averageCrossTrackError.getMeters() : -1.0);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString());
|
||||
competitorElement.addContent(competitorRaceDataElement);
|
||||
raceElement.addContent(competitorElement);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user