mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-21 21:25:38 +00:00
Merge branch 'master' into bug5311
This commit is contained in:
+52
-15
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -13,7 +14,10 @@ import org.json.simple.JSONObject;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
@@ -29,19 +33,33 @@ public class MarkPassingsJsonSerializer extends AbstractTrackedRaceDataJsonSeria
|
||||
public static final String BYWAYPOINT = "bywaypoint";
|
||||
public static final String MARKPASSINGS = "markpassings";
|
||||
public static final String TRACKED_RANK_AT_MARK_PASSING = "trackedRankAtMarkPassing";
|
||||
public static final String ONE_BASED_PASSING_ORDER = "oneBasedPassingOrder";
|
||||
public static final String POINTS_BASED_ON_PASSING_ORDER = "pointsBasedOnPassingOrder";
|
||||
public static final String MAX_POINTS_REASON = "maxPointsReason";
|
||||
private static SimpleDateFormat TIMEPOINT_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
/**
|
||||
* The time point for which to obtain the ranking information at the marks
|
||||
*/
|
||||
private final TimePoint timePoint;
|
||||
|
||||
/**
|
||||
* An optional leaderboard that, when provided, is used to provide the score and IRM/penalty/MaxPointsReason in
|
||||
* the output.
|
||||
*/
|
||||
private final Leaderboard leaderboard;
|
||||
|
||||
/**
|
||||
* @param timePoint time point for which to obtain the ranking information at the marks; use {@code null}
|
||||
* to use "now" minus the live delay
|
||||
* @param leaderboard
|
||||
* An optional leaderboard that, when provided, is used to provide the score and
|
||||
* IRM/penalty/MaxPointsReason in the output.
|
||||
* @param timePoint
|
||||
* time point for which to obtain the ranking information at the marks; use {@code null} to use "now"
|
||||
* minus the live delay
|
||||
*/
|
||||
public MarkPassingsJsonSerializer(TimePoint timePoint) {
|
||||
public MarkPassingsJsonSerializer(Leaderboard leaderboard, TimePoint timePoint) {
|
||||
super();
|
||||
this.leaderboard = leaderboard;
|
||||
this.timePoint = timePoint;
|
||||
}
|
||||
|
||||
@@ -55,20 +73,24 @@ public class MarkPassingsJsonSerializer extends AbstractTrackedRaceDataJsonSeria
|
||||
CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create();
|
||||
JSONArray byCompetitorJson = new JSONArray();
|
||||
result.put(BYCOMPETITOR, byCompetitorJson);
|
||||
final Map<Competitor, Integer> startOrder = new HashMap<>();
|
||||
// start mark passing; rank is ordering by start time
|
||||
final Waypoint startWaypoint = course.getFirstWaypoint();
|
||||
if (startWaypoint != null) {
|
||||
final Iterable<MarkPassing> startMarkPassings = trackedRace.getMarkPassingsInOrder(startWaypoint);
|
||||
trackedRace.lockForRead(startMarkPassings);
|
||||
try {
|
||||
int startRank = 1;
|
||||
for (final MarkPassing startMarkPassing : startMarkPassings) {
|
||||
startOrder.put(startMarkPassing.getCompetitor(), startRank++);
|
||||
final Map<Waypoint, Map<Competitor, Integer>> orderOfMarkPassings = new HashMap<>();
|
||||
trackedRace.getRace().getCourse().lockForRead();
|
||||
try {
|
||||
for (final Waypoint waypoint : course.getWaypoints()) {
|
||||
final Iterable<MarkPassing> markPassingsInOrder = trackedRace.getMarkPassingsInOrder(waypoint);
|
||||
trackedRace.lockForRead(markPassingsInOrder);
|
||||
try {
|
||||
int markPassingCounter = 1;
|
||||
for (final MarkPassing markPassing : markPassingsInOrder) {
|
||||
orderOfMarkPassings.computeIfAbsent(waypoint, wp->new HashMap<>()).put(markPassing.getCompetitor(), markPassingCounter++);
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(markPassingsInOrder);
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(startMarkPassings);
|
||||
}
|
||||
} finally {
|
||||
trackedRace.getRace().getCourse().unlockAfterRead();
|
||||
}
|
||||
final Map<TrackedLeg, LinkedHashMap<Competitor, Integer>> legRanks = new HashMap<>();
|
||||
final WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache = new LeaderboardDTOCalculationReuseCache(timePointForRanksAtMarks);
|
||||
@@ -90,13 +112,28 @@ public class MarkPassingsJsonSerializer extends AbstractTrackedRaceDataJsonSeria
|
||||
addMarkPassingTime(markPassing, markPassingJson);
|
||||
final int zeroBasedIndexOfWaypoint = course.getIndexOfWaypoint(markPassing.getWaypoint());
|
||||
final Integer rank;
|
||||
final Integer passingOrder = orderOfMarkPassings.getOrDefault(markPassing.getWaypoint(), Collections.emptyMap()).getOrDefault(competitor, /* default */ 0);
|
||||
if (zeroBasedIndexOfWaypoint == 0) {
|
||||
rank = startOrder.getOrDefault(competitor, /* default */ 0);
|
||||
rank = passingOrder; // for the start waypoint it doesn't make sense to look at the actual "ranking"; use passing order as default
|
||||
} else {
|
||||
final TrackedLeg trackedLeg = trackedRace.getTrackedLeg(course.getLeg(zeroBasedIndexOfWaypoint-1));
|
||||
rank = legRanks.computeIfAbsent(trackedLeg, tl->tl.getRanks(timePointForRanksAtMarks, cache)).get(competitor);
|
||||
}
|
||||
markPassingJson.put(TRACKED_RANK_AT_MARK_PASSING, rank);
|
||||
markPassingJson.put(ONE_BASED_PASSING_ORDER, passingOrder);
|
||||
if (leaderboard != null) {
|
||||
final Pair<RaceColumn, Fleet> raceColumnAndFleet = leaderboard.getRaceColumnAndFleet(trackedRace);
|
||||
if (raceColumnAndFleet != null) {
|
||||
// TODO apply column factor!
|
||||
final Double totalPoints = leaderboard.getScoreCorrection().getCorrectedScore(() -> passingOrder,
|
||||
competitor, raceColumnAndFleet.getA(), leaderboard, markPassing.getTimePoint(),
|
||||
leaderboard.getNumberOfCompetitorsInLeaderboardFetcher(), leaderboard.getScoringScheme(), cache)
|
||||
.getCorrectedScore();
|
||||
markPassingJson.put(POINTS_BASED_ON_PASSING_ORDER, totalPoints);
|
||||
markPassingJson.put(MAX_POINTS_REASON, leaderboard.getMaxPointsReason(competitor,
|
||||
raceColumnAndFleet.getA(), markPassing.getTimePoint()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(markPassingsForCompetitor);
|
||||
|
||||
Reference in New Issue
Block a user