mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-25 05:23:51 +00:00
Merge branch 'master' into bug3027
This commit is contained in:
commit
4726dba201
7 files changed
+171
-45
No files matched your search
+7
-2
@@ -1,7 +1,10 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
@@ -13,6 +16,7 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition {
|
||||
private static final long serialVersionUID = -1900955198751393727L;
|
||||
private final Course course;
|
||||
private final LinkedHashMap<Serializable, Competitor> competitorsById;
|
||||
private final Set<Competitor> competitors;
|
||||
private final BoatClass boatClass;
|
||||
private final Serializable id;
|
||||
|
||||
@@ -23,11 +27,12 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition {
|
||||
public RaceDefinitionImpl(String name, Course course, BoatClass boatClass, Iterable<? extends Competitor> competitors, Serializable id) {
|
||||
super(name);
|
||||
assert name != null;
|
||||
|
||||
this.course = course;
|
||||
this.competitors = new HashSet<>();
|
||||
this.competitorsById = new LinkedHashMap<>();
|
||||
for (Competitor competitor : competitors) {
|
||||
Competitor competitorWithEqualID = competitorsById.put(competitor.getId(), competitor);
|
||||
this.competitors.add(competitor);
|
||||
if (competitorWithEqualID != null && competitorWithEqualID != competitor) {
|
||||
throw new IllegalArgumentException("Two distinct competitors with equal ID "+competitor.getId()+" are not allowed within the single race "+name);
|
||||
}
|
||||
@@ -48,7 +53,7 @@ public class RaceDefinitionImpl extends NamedImpl implements RaceDefinition {
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
return competitorsById.values();
|
||||
return Collections.unmodifiableSet(competitors);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
@@ -99,6 +99,14 @@ public interface ScoreCorrection extends Serializable {
|
||||
*/
|
||||
boolean hasCorrectionFor(RaceColumn raceInLeaderboard);
|
||||
|
||||
/**
|
||||
* Similar to {@link #hasCorrectionFor(RaceColumn)}, but returns <code>true</code> only if score corrections are found
|
||||
* for any competitor who in <code>raceInLeaderboard</code> is not in a tracked race and hence the fleet assignment
|
||||
* cannot be determined. This is helpful, e.g., for progress detection. If score corrections are present for such
|
||||
* untracked competitors then all untracked fleets need to be assumed as finished.
|
||||
*/
|
||||
boolean hasCorrectionForNonTrackedFleet(RaceColumn raceInLeaderboard);
|
||||
|
||||
/**
|
||||
* @return all race columns for which this score corrections object has at least one correction; note that this
|
||||
* object may hold corrections also for competitors that are not currently returned by
|
||||
|
||||
+13
-2
@@ -472,19 +472,30 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
|
||||
|
||||
@Override
|
||||
public boolean hasCorrectionFor(RaceColumn raceInLeaderboard) {
|
||||
return internalHasScoreCorrectionFor(raceInLeaderboard, /* considerOnlyUntrackedRaces */ false);
|
||||
}
|
||||
|
||||
private boolean internalHasScoreCorrectionFor(RaceColumn raceInLeaderboard, boolean considerOnlyUntrackedRaces) {
|
||||
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> correctedScoresKey : correctedScores.keySet()) {
|
||||
if (correctedScoresKey.getB() == raceInLeaderboard) {
|
||||
if (correctedScoresKey.getB() == raceInLeaderboard &&
|
||||
(!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(correctedScoresKey.getA()) == null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (com.sap.sse.common.Util.Pair<Competitor, RaceColumn> maxPointsReasonsKey : maxPointsReasons.keySet()) {
|
||||
if (maxPointsReasonsKey.getB() == raceInLeaderboard) {
|
||||
if (maxPointsReasonsKey.getB() == raceInLeaderboard &&
|
||||
(!considerOnlyUntrackedRaces || raceInLeaderboard.getTrackedRace(maxPointsReasonsKey.getA()) == null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCorrectionForNonTrackedFleet(RaceColumn raceInLeaderboard) {
|
||||
return internalHasScoreCorrectionFor(raceInLeaderboard, /* considerOnlyUntrackedRaces */ true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePointOfLastCorrectionsValidity() {
|
||||
return timePointOfLastCorrectionsValidity;
|
||||
|
||||
+7
-4
@@ -4,9 +4,12 @@ import java.util.Date;
|
||||
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
|
||||
import com.google.gwt.i18n.client.TimeZone;
|
||||
import com.google.gwt.text.client.DateTimeFormatRenderer;
|
||||
|
||||
public class DateAndTimeFormatterUtil {
|
||||
public static TimeZone timeZoneWithoutOffset = TimeZone.createTimeZone(0);
|
||||
|
||||
public static DateTimeFormatRenderer defaultDateFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT));
|
||||
public static DateTimeFormatRenderer defaultTimeFormatter = new DateTimeFormatRenderer(
|
||||
@@ -15,14 +18,14 @@ public class DateAndTimeFormatterUtil {
|
||||
public static DateTimeFormatRenderer longDateFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_LONG));
|
||||
public static DateTimeFormatRenderer longTimeFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat("HH:mm:ss zzz"));
|
||||
DateTimeFormat.getFormat("HH:mm:ss zzz"), timeZoneWithoutOffset);
|
||||
|
||||
private static DateTimeFormatRenderer secondsTimeFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat("m:ss"));
|
||||
DateTimeFormat.getFormat("m:ss"), timeZoneWithoutOffset);
|
||||
private static DateTimeFormatRenderer minutesAndSecondsTimeFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat("mm:ss"));
|
||||
DateTimeFormat.getFormat("mm:ss"), timeZoneWithoutOffset);
|
||||
private static DateTimeFormatRenderer hoursAndMinutesAndSecondsTimeFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat("HH:mm:ss"));
|
||||
DateTimeFormat.getFormat("HH:mm:ss"), timeZoneWithoutOffset);
|
||||
|
||||
public static String formatDateRange(Date startDate, Date endDate) {
|
||||
return defaultDateFormatter.render(startDate) + " - " + defaultDateFormatter.render(endDate);
|
||||
|
||||
+1
-1
@@ -827,7 +827,7 @@ public class PathGeneratorTreeGrow360 extends PathGeneratorBase {
|
||||
|
||||
// check for time-out
|
||||
if (this.isTimedOut()) {
|
||||
//reachedEnd = true;
|
||||
reachedEnd = true;
|
||||
}
|
||||
|
||||
} // main while-loop
|
||||
|
||||
+23
-3
@@ -1,11 +1,14 @@
|
||||
package com.sap.sailing.simulator.windfield.impl;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.simulator.TimedPosition;
|
||||
import com.sap.sailing.simulator.impl.TimedPositionImpl;
|
||||
import com.sap.sailing.simulator.windfield.WindFieldGenerator;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
@@ -21,13 +24,22 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
public class WindFieldTrackedRaceImpl extends WindFieldGeneratorImpl implements WindFieldGenerator {
|
||||
|
||||
private static final long serialVersionUID = -7005970781594631010L;
|
||||
private static final double EPSILON_DISTANCE_METER = 20;
|
||||
private static final long EPSILON_TIME_MILLIS = 5000;
|
||||
private static final double EPSILON_DISTANCE_METER = 20;
|
||||
private static final long EPSILON_TIME_MILLIS = 5000;
|
||||
private TrackedRace race;
|
||||
private final ConcurrentHashMap<TimedPosition, Wind> cache;
|
||||
private TimePoint startSimulationTime = null;
|
||||
|
||||
|
||||
public WindFieldTrackedRaceImpl(TrackedRace race) {
|
||||
super(null, null);
|
||||
this.race = race;
|
||||
this.cache = new ConcurrentHashMap<>();
|
||||
if (race.isLive(MillisecondsTimePoint.now())) {
|
||||
startSimulationTime = MillisecondsTimePoint.now();
|
||||
} else {
|
||||
startSimulationTime = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,10 +50,18 @@ public class WindFieldTrackedRaceImpl extends WindFieldGeneratorImpl implements
|
||||
double epsLng = epsLat / Math.cos(qLat * Math.PI / 180.0);
|
||||
double qLng = Math.floor(pos.getLngDeg() / epsLng) * epsLng;
|
||||
TimePoint time = timedPosition.getTimePoint();
|
||||
if ((startSimulationTime != null) && (time.after(startSimulationTime))) {
|
||||
time = startSimulationTime;
|
||||
}
|
||||
long epsTime = EPSILON_TIME_MILLIS;
|
||||
TimePoint qTime = new MillisecondsTimePoint((long) (Math.floor(time.asMillis() / epsTime) * epsTime));
|
||||
Position qPosition = new DegreePosition(qLat, qLng);
|
||||
Wind wind = this.race.getWind(qPosition, qTime);
|
||||
TimedPosition qTimedPosition = new TimedPositionImpl(qTime, qPosition);
|
||||
Wind wind = cache.get(qTimedPosition);
|
||||
if (wind == null) {
|
||||
wind = this.race.getWind(qPosition, qTime);
|
||||
cache.put(qTimedPosition, wind);
|
||||
}
|
||||
return wind;
|
||||
}
|
||||
|
||||
|
||||
+112
-33
@@ -34,8 +34,11 @@ 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.Tack;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
@@ -46,6 +49,8 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -97,7 +102,7 @@ public class LeaderboardData extends ExportAction {
|
||||
* </competitor>
|
||||
* </pre>
|
||||
*/
|
||||
private Element createLeaderboardXML(Leaderboard leaderboard, List<Element> competitors, List<Element> races, Util.Pair<Double, Vector<String>> leaderboardConfidenceAndErrorMessages) {
|
||||
private Element createLeaderboardXML(Leaderboard leaderboard, List<Element> windData, List<Element> competitors, List<Element> races, Util.Pair<Double, Vector<String>> leaderboardConfidenceAndErrorMessages) {
|
||||
Element leaderboardElement = new Element("leaderboard");
|
||||
addNamedElementWithValue(leaderboardElement, "name", leaderboard.getName());
|
||||
addNamedElementWithValue(leaderboardElement, "display_name", leaderboard.getDisplayName());
|
||||
@@ -106,6 +111,9 @@ public class LeaderboardData extends ExportAction {
|
||||
addNamedElementWithValue(leaderboardElement, "boat_class", getBoatClassName(leaderboard));
|
||||
leaderboardElement.addContent(createTimedXML("last_modification_", leaderboard.getTimePointOfLatestModification()));
|
||||
leaderboardElement.addContent(createDataConfidenceXML(leaderboardConfidenceAndErrorMessages));
|
||||
Element windContainer = new Element("wind");
|
||||
windContainer.addContent(windData);
|
||||
leaderboardElement.addContent(windContainer);
|
||||
leaderboardElement.addContent(competitors);
|
||||
leaderboardElement.addContent(races);
|
||||
return leaderboardElement;
|
||||
@@ -202,6 +210,35 @@ public class LeaderboardData extends ExportAction {
|
||||
return windElements;
|
||||
}
|
||||
|
||||
private Element createRaceXMLWithoutRaceData(final Fleet fleet, final RaceColumn column, final Leaderboard leaderboard, int sameDayGroupIndex, int raceCounter, Util.Pair<Double, Vector<String>> raceConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException {
|
||||
Element raceElement = new Element("race");
|
||||
addNamedElementWithValue(raceElement, "name", column.getName()+'-'+fleet.getName());
|
||||
addNamedElementWithValue(raceElement, "race_index_in_leaderboard", raceCounter);
|
||||
addNamedElementWithValue(raceElement, "fleet_name", fleet.getName());
|
||||
addNamedElementWithValue(raceElement, "same_day_index", sameDayGroupIndex);
|
||||
addNamedElementWithValue(raceElement, "is_live", "false");
|
||||
TimePoint timepointToBeUsed = MillisecondsTimePoint.now();
|
||||
List<Competitor> competitors = leaderboard.getCompetitorsFromBestToWorst(column, timepointToBeUsed);
|
||||
for (Competitor competitorInLeaderboard : competitors) {
|
||||
MaxPointsReason mpr = leaderboard.getScoreCorrection().getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed);
|
||||
if (mpr != null && !mpr.equals(MaxPointsReason.NONE)) {
|
||||
// add this competitor to the list to have him evaluated
|
||||
Element competitorElement = createCompetitorXML(competitorInLeaderboard, leaderboard, /*shortVersion*/ true, null);
|
||||
Element competitorRaceDataElement = new Element("competitor_race_data");
|
||||
MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString());
|
||||
boolean isDiscardedForCompetitor = leaderboard.isDiscarded(competitorInLeaderboard, column, timepointToBeUsed);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "is_discarded", isDiscardedForCompetitor == true ? "true" : "false");
|
||||
Double finalRaceScore = leaderboard.getTotalPoints(competitorInLeaderboard, column, timepointToBeUsed);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "final_race_score", finalRaceScore);
|
||||
competitorElement.addContent(competitorRaceDataElement);
|
||||
raceElement.addContent(competitorElement);
|
||||
raceConfidenceAndErrorMessages = updateConfidence("Competitor " + competitorInLeaderboard.getName() + " has no valid data for this race!", 0.2, raceConfidenceAndErrorMessages);
|
||||
}
|
||||
}
|
||||
return raceElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates elements containing information about a race
|
||||
*/
|
||||
@@ -233,7 +270,7 @@ public class LeaderboardData extends ExportAction {
|
||||
addNamedElementWithValue(raceElement, "start_of_tracking_time_as_millis", handleValue(race.getStartOfTracking()));
|
||||
addNamedElementWithValue(raceElement, "end_of_tracking_time_as_millis", handleValue(race.getEndOfTracking()));
|
||||
|
||||
LineDetails start = race.getStartLine(race.getStartOfTracking());
|
||||
LineDetails start = race.getStartLine(race.getStartOfRace());
|
||||
if (start != null) {
|
||||
if (start.getLength() != null) {
|
||||
addNamedElementWithValue(raceElement, "start_line_length_in_meters", start.getLength().getMeters());
|
||||
@@ -568,13 +605,16 @@ public class LeaderboardData extends ExportAction {
|
||||
// will kick in
|
||||
}
|
||||
}
|
||||
if (endOfRaceForLastTrackedRaceInLeaderboard != null) {
|
||||
timePointOfLatestModification = endOfRaceForLastTrackedRaceInLeaderboard;
|
||||
// first look for latest modification of leaderboard
|
||||
// if there is no latest modification then take the last races time
|
||||
if (leaderboard.getTimePointOfLatestModification() != null) {
|
||||
timePointOfLatestModification = leaderboard.getTimePointOfLatestModification();
|
||||
} else {
|
||||
if (leaderboard.getTimePointOfLatestModification() != null) {
|
||||
timePointOfLatestModification = leaderboard.getTimePointOfLatestModification();
|
||||
if (endOfRaceForLastTrackedRaceInLeaderboard != null) {
|
||||
timePointOfLatestModification = endOfRaceForLastTrackedRaceInLeaderboard;
|
||||
} else {
|
||||
timePointOfLatestModification = MillisecondsTimePoint.now();
|
||||
// make sure that the timepoint is far in the future - could be that the export is called too early
|
||||
timePointOfLatestModification = MillisecondsTimePoint.now().plus(Duration.ONE_YEAR);
|
||||
}
|
||||
}
|
||||
Duration totalTimeSailed = leaderboard.getTotalTimeSailed(competitor, timePointOfLatestModification);
|
||||
@@ -708,6 +748,36 @@ public class LeaderboardData extends ExportAction {
|
||||
return legElement;
|
||||
}
|
||||
|
||||
private List<Element> createFullWindDataXML(TrackedRace race, Fleet fleet, int sameDayIndex) {
|
||||
List<Element> windElements = new ArrayList<>();
|
||||
List<WindSource> windSourcesToDeliver = new ArrayList<WindSource>();
|
||||
WindSourceImpl windSource = new WindSourceImpl(WindSourceType.COMBINED);
|
||||
windSourcesToDeliver.add(windSource);
|
||||
TimePoint fromTimePoint = race.getStartOfRace();
|
||||
TimePoint toTimePoint = race.getEndOfRace();
|
||||
int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis()) / /*resolutionInMillis*/ 1000*60*5);
|
||||
WindTrack windTrack = race.getOrCreateWindTrack(windSource);
|
||||
TimePoint timePoint = fromTimePoint;
|
||||
for (int i = 0; i < numberOfFixes && toTimePoint != null && timePoint.compareTo(toTimePoint) < 0; i++) {
|
||||
WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> averagedWindWithConfidence = windTrack
|
||||
.getAveragedWindWithConfidence(null, timePoint);
|
||||
if (averagedWindWithConfidence != null) {
|
||||
Element windElement = new Element("windFix");
|
||||
addNamedElementWithValue(windElement, "same_day_index", sameDayIndex);
|
||||
addNamedElementWithValue(windElement, "race_name", race.getRace().getName());
|
||||
addNamedElementWithValue(windElement, "fleet_name", fleet.getName());
|
||||
windElement.addContent(createTimedXML("", averagedWindWithConfidence.getObject().getTimePoint()));
|
||||
addNamedElementWithValue(windElement, "bearingInDegrees", averagedWindWithConfidence.getObject().getBearing().getDegrees());
|
||||
addNamedElementWithValue(windElement, "directionFromInDegrees", averagedWindWithConfidence.getObject().getBearing().reverse().getDegrees());
|
||||
windElement.addContent(createWindXML("", new SpeedWithConfidenceImpl<TimePoint>(new KnotSpeedImpl(averagedWindWithConfidence.getObject().getKnots()),
|
||||
averagedWindWithConfidence.getConfidence(), toTimePoint)));
|
||||
windElements.add(windElement);
|
||||
}
|
||||
timePoint = new MillisecondsTimePoint(timePoint.asMillis() + 1000*60*5);
|
||||
}
|
||||
return windElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates xml elements that indicate confidence.
|
||||
*/
|
||||
@@ -784,24 +854,29 @@ public class LeaderboardData extends ExportAction {
|
||||
private Util.Pair<Double, Vector<String>> checkData(TrackedRace race) throws Exception {
|
||||
double simpleConfidence = 1.0; Vector<String> messages = new Vector<String>();
|
||||
TimePoint dateAtYear2000 = new MillisecondsTimePoint(946681200000l);
|
||||
if (race.getStartOfRace() == null || race.getStartOfRace().before(dateAtYear2000)) {
|
||||
messages.add("Start time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
if (race == null) {
|
||||
messages.add("Tracked race is null - no race seems to be connected!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getEndOfRace() == null || race.getEndOfRace().before(dateAtYear2000)) {
|
||||
messages.add("End time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getStartOfTracking() == null || race.getStartOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("Start tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
if (race.getEndOfTracking() == null || race.getEndOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("End tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
if (race.isLive(MillisecondsTimePoint.now())) {
|
||||
messages.add("This race is live - data for this race will not be available until the race has been finished!");
|
||||
} else {
|
||||
if (race.getStartOfRace() == null || race.getStartOfRace().before(dateAtYear2000)) {
|
||||
messages.add("Start time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getEndOfRace() == null || race.getEndOfRace().before(dateAtYear2000)) {
|
||||
messages.add("End time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getStartOfTracking() == null || race.getStartOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("Start tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
if (race.getEndOfTracking() == null || race.getEndOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("End tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
if (race.isLive(MillisecondsTimePoint.now())) {
|
||||
messages.add("This race is live - data for this race will not be available until the race has been finished!");
|
||||
}
|
||||
}
|
||||
return new Util.Pair<Double, Vector<String>>(simpleConfidence, messages);
|
||||
}
|
||||
@@ -886,24 +961,25 @@ public class LeaderboardData extends ExportAction {
|
||||
TimePoint timeSpent = MillisecondsTimePoint.now();
|
||||
log.info("Starting XML export of " + leaderboard.getName());
|
||||
Util.Pair<Double, Vector<String>> leaderboardConfidenceAndErrorMessages = checkData(leaderboard);
|
||||
|
||||
final List<Element> racesElements = new ArrayList<Element>();
|
||||
final List<Element> competitorElements = new ArrayList<Element>();
|
||||
|
||||
for (Competitor competitor : leaderboard.getAllCompetitors()) {
|
||||
Util.Pair<Double, Vector<String>> competitorConfidenceAndErrorMessages = checkData(competitor);
|
||||
competitorElements.add(createCompetitorXML(competitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages));
|
||||
}
|
||||
|
||||
List<Element> windData = new ArrayList<Element>();
|
||||
TrackedRace raceBefore = null; int sameDayGroupIndex = 0; int raceCounter = 0;
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null && trackedRace.hasGPSData()) {
|
||||
if (trackedRace != null) {
|
||||
sameDayGroupIndex += getSameDayGroupIndex(raceColumn.getTrackedRace(fleet), raceBefore);
|
||||
TimePoint timeSpentForRace = MillisecondsTimePoint.now();
|
||||
Util.Pair<Double, Vector<String>> raceConfidenceAndErrorMessages = checkData(trackedRace);
|
||||
final List<Element> legs = new ArrayList<Element>();
|
||||
}
|
||||
TimePoint timeSpentForRace = MillisecondsTimePoint.now();
|
||||
Util.Pair<Double, Vector<String>> raceConfidenceAndErrorMessages = checkData(trackedRace);
|
||||
final List<Element> legs = new ArrayList<Element>();
|
||||
if (trackedRace != null && trackedRace.hasGPSData()) {
|
||||
windData.addAll(createFullWindDataXML(trackedRace, fleet, sameDayGroupIndex));
|
||||
int legCounter = 0;
|
||||
for (TrackedLeg leg : trackedRace.getTrackedLegs()) {
|
||||
Util.Pair<Double, Vector<String>> legConfidenceAndErrorMessages = checkData(leg);
|
||||
@@ -914,12 +990,15 @@ public class LeaderboardData extends ExportAction {
|
||||
addNamedElementWithValue(raceElement, "generation_time_in_milliseconds", elapsedTimeForRace.asMillis());
|
||||
racesElements.add(raceElement);
|
||||
log.info("Exported complete race " + trackedRace.getRace().getName() + " in " + elapsedTimeForRace.asMillis() + " milliseconds!");
|
||||
raceBefore = trackedRace;
|
||||
} else {
|
||||
racesElements.add(createRaceXMLWithoutRaceData(fleet, raceColumn, leaderboard, sameDayGroupIndex, ++raceCounter, raceConfidenceAndErrorMessages));
|
||||
log.info("Exported empty race in race column " + raceColumn.getName() + " with fleet " + fleet.getName());
|
||||
}
|
||||
raceBefore = trackedRace;
|
||||
}
|
||||
}
|
||||
log.info("Finished XML export of leaderboard " + leaderboard.getName() + " in " + MillisecondsTimePoint.now().minus(timeSpent.asMillis()).asMillis() + " milliseconds");
|
||||
Element dataToExport = createLeaderboardXML(leaderboard, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages);
|
||||
Element dataToExport = createLeaderboardXML(leaderboard, windData, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages);
|
||||
sendDocument(dataToExport, leaderboard.getName() + ".xml");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user