mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-04 10:09:42 +00:00
consolidated acquisition of mark position from tracked races, regatta log and race logs
This commit is contained in:
1 parent
7500d8ed96
commit
29284adfa4
8 files changed
+97
-66
No files matched your search
-1
@@ -120,7 +120,6 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore {
|
|||||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, AbstractLog<?, ?> log, Mark mark)
|
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, AbstractLog<?, ?> log, Mark mark)
|
||||||
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
||||||
List<DeviceMapping<Mark>> mappings = new DeviceMarkMappingFinder<>(log).analyze().get(mark);
|
List<DeviceMapping<Mark>> mappings = new DeviceMarkMappingFinder<>(log).analyze().get(mark);
|
||||||
|
|
||||||
if (mappings != null) {
|
if (mappings != null) {
|
||||||
for (DeviceMapping<Mark> mapping : mappings) {
|
for (DeviceMapping<Mark> mapping : mappings) {
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ import com.sap.sailing.domain.base.RaceColumn;
|
|||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.base.Series;
|
import com.sap.sailing.domain.base.Series;
|
||||||
import com.sap.sailing.domain.common.Renamable;
|
import com.sap.sailing.domain.common.Renamable;
|
||||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
|
||||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||||
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,7 +23,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
|||||||
* @author Axel Uhl (D043530)
|
* @author Axel Uhl (D043530)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface FlexibleLeaderboard extends Leaderboard, Renamable, HasRegattaLike, IsRegattaLike {
|
public interface FlexibleLeaderboard extends LeaderboardThatHasRegattaLike, Renamable, IsRegattaLike {
|
||||||
/**
|
/**
|
||||||
* Moves the column with the name <code>name</code> up.
|
* Moves the column with the name <code>name</code> up.
|
||||||
* @param name The name of the column to move.
|
* @param name The name of the column to move.
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@ package com.sap.sailing.domain.leaderboard;
|
|||||||
|
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.common.Renamable;
|
import com.sap.sailing.domain.common.Renamable;
|
||||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
|
|
||||||
public interface RegattaLeaderboard extends Leaderboard, Renamable, HasRegattaLike {
|
public interface RegattaLeaderboard extends Renamable, LeaderboardThatHasRegattaLike {
|
||||||
Regatta getRegatta();
|
Regatta getRegatta();
|
||||||
}
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package com.sap.sailing.domain.regattalike;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
|
|
||||||
|
public interface LeaderboardThatHasRegattaLike extends Leaderboard, HasRegattaLike {
|
||||||
|
}
|
||||||
+9
-19
@@ -71,14 +71,12 @@ import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.Readon
|
|||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.ReadonlyRRS26RacingProcedure;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.ReadonlyRRS26RacingProcedure;
|
||||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.DefinedMarkFinder;
|
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.DefinedMarkFinder;
|
||||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogLastPingMappingEventFinder;
|
|
||||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogOpenEndedDeviceMappingCloser;
|
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogOpenEndedDeviceMappingCloser;
|
||||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
|
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.DeviceCompetitorMappingFinder;
|
import com.sap.sailing.domain.abstractlog.shared.analyzing.DeviceCompetitorMappingFinder;
|
||||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.DeviceMarkMappingFinder;
|
import com.sap.sailing.domain.abstractlog.shared.analyzing.DeviceMarkMappingFinder;
|
||||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
||||||
import com.sap.sailing.domain.abstractlog.shared.events.DeviceMappingEvent;
|
|
||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.ControlPoint;
|
import com.sap.sailing.domain.base.ControlPoint;
|
||||||
@@ -220,6 +218,7 @@ import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
|||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
||||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||||
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
|
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
|
||||||
@@ -253,7 +252,6 @@ import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
|||||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||||
import com.sap.sailing.domain.tracking.WindTrack;
|
import com.sap.sailing.domain.tracking.WindTrack;
|
||||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
|
||||||
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||||
@@ -4884,28 +4882,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Serializable id = UUID.randomUUID();
|
Serializable id = UUID.randomUUID();
|
||||||
|
|
||||||
return baseDomainFactory.getOrCreateMark(id, dto.getName(), dto.type, dto.color, dto.shape, dto.pattern);
|
return baseDomainFactory.getOrCreateMark(id, dto.getName(), dto.type, dto.color, dto.shape, dto.pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Also finds the last position of the marks, if set by pinging them
|
* Also finds the last position of the marks, if set by pinging them
|
||||||
*/
|
*/
|
||||||
private Collection<MarkDTO> convertToMarkDTOs(RaceLog raceLog, Iterable<Mark> marks) {
|
private Collection<MarkDTO> convertToMarkDTOs(LeaderboardThatHasRegattaLike leaderboard, RaceLog raceLog, Iterable<Mark> marks) {
|
||||||
List<MarkDTO> dtos = new ArrayList<MarkDTO>();
|
List<MarkDTO> dtos = new ArrayList<MarkDTO>();
|
||||||
|
final TimePoint now = MillisecondsTimePoint.now();
|
||||||
for (Mark mark : marks) {
|
for (Mark mark : marks) {
|
||||||
DynamicGPSFixTrackImpl<Mark> track = new DynamicGPSFixTrackImpl<Mark>(mark, 0);
|
final Position lastPos = getService().getMarkPosition(mark, leaderboard, now, raceLog);
|
||||||
DeviceMappingEvent<?, Mark> lastPingMappingEvent = new RaceLogLastPingMappingEventFinder<Mark>(raceLog, mark).analyze();
|
|
||||||
if (lastPingMappingEvent != null) {
|
|
||||||
try {
|
|
||||||
getService().getGPSFixStore().loadMarkTrack(track, DeviceMappingImpl.convertToDeviceMapping(lastPingMappingEvent));
|
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
|
||||||
logger.log(Level.WARNING, "Could not convert to Mark DTO: " + mark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Position lastPos = track.getLastRawFix() == null ? null : track.getLastRawFix().getPosition();
|
|
||||||
dtos.add(convertToMarkDTO(mark, lastPos));
|
dtos.add(convertToMarkDTO(mark, lastPos));
|
||||||
}
|
}
|
||||||
return dtos;
|
return dtos;
|
||||||
@@ -4924,14 +4912,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
public Iterable<MarkDTO> getMarksInRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
|
public Iterable<MarkDTO> getMarksInRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
|
||||||
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
|
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
|
||||||
Iterable<Mark> marks = new DefinedMarkFinder(raceLog).analyze();
|
Iterable<Mark> marks = new DefinedMarkFinder(raceLog).analyze();
|
||||||
return convertToMarkDTOs(raceLog, marks);
|
return convertToMarkDTOs((LeaderboardThatHasRegattaLike) getService().getLeaderboardByName(leaderboardName), raceLog, marks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<MarkDTO> getMarksInRaceLogsAndTrackedRaces(String leaderboardName) {
|
public Iterable<MarkDTO> getMarksInRaceLogsAndTrackedRaces(String leaderboardName) {
|
||||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||||
if (leaderboard == null) {
|
if (leaderboard == null) {
|
||||||
//TODO: implement proper Exception Handling
|
// TODO: implement proper Exception Handling
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Set<MarkDTO> markDTOs = new HashSet<>();
|
Set<MarkDTO> markDTOs = new HashSet<>();
|
||||||
@@ -4948,7 +4936,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
marksById.put(markFromTrackedRace.getId(), markFromTrackedRace);
|
marksById.put(markFromTrackedRace.getId(), markFromTrackedRace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Util.addAll(convertToMarkDTOs(raceLog, marksById.values()), markDTOs);
|
Util.addAll(convertToMarkDTOs(
|
||||||
|
(LeaderboardThatHasRegattaLike) getService().getLeaderboardByName(leaderboardName),
|
||||||
|
raceLog, marksById.values()), markDTOs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return markDTOs;
|
return markDTOs;
|
||||||
|
|||||||
+11
-42
@@ -54,6 +54,7 @@ import com.sap.sailing.domain.common.Distance;
|
|||||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||||
import com.sap.sailing.domain.common.NoWindException;
|
import com.sap.sailing.domain.common.NoWindException;
|
||||||
|
import com.sap.sailing.domain.common.Position;
|
||||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||||
import com.sap.sailing.domain.common.dto.FleetDTO;
|
import com.sap.sailing.domain.common.dto.FleetDTO;
|
||||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||||
@@ -64,18 +65,16 @@ import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
|
|||||||
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
|
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
|
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDIdentifierImpl;
|
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDIdentifierImpl;
|
||||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||||
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.GPSFix;
|
import com.sap.sailing.domain.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
|
||||||
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.GPSFixTrackImpl;
|
import com.sap.sailing.domain.tracking.impl.GPSFixTrackImpl;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
@@ -654,9 +653,10 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
|||||||
return Response.status(Status.NOT_FOUND).entity("Could not find a mark with ID '" + markId + "'.")
|
return Response.status(Status.NOT_FOUND).entity("Could not find a mark with ID '" + markId + "'.")
|
||||||
.type(MediaType.TEXT_PLAIN).build();
|
.type(MediaType.TEXT_PLAIN).build();
|
||||||
}
|
}
|
||||||
|
MillisecondsTimePoint now = MillisecondsTimePoint.now();
|
||||||
GPSFix lastKnownFix = getLastKnownFix(leaderboard, mark, regattaLog);
|
Position lastKnownPosition = getService().getMarkPosition(mark,
|
||||||
|
(LeaderboardThatHasRegattaLike) leaderboard, now,
|
||||||
|
/* raceLog==null means use all race logs */ null);
|
||||||
GPSFix fix = null;
|
GPSFix fix = null;
|
||||||
try {
|
try {
|
||||||
Object requestBody = JSONValue.parseWithException(json);
|
Object requestBody = JSONValue.parseWithException(json);
|
||||||
@@ -671,11 +671,11 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
|||||||
RaceLogTrackingAdapter adapter = getRaceLogTrackingAdapter();
|
RaceLogTrackingAdapter adapter = getRaceLogTrackingAdapter();
|
||||||
RacingEventService service = getService();
|
RacingEventService service = getService();
|
||||||
try {
|
try {
|
||||||
if (lastKnownFix != null) {
|
if (lastKnownPosition != null) {
|
||||||
// ping again to avoid interpolation, avoid filtering by paying attention to maxSpeedForSmoothing
|
// ping again to avoid interpolation, avoid filtering by paying attention to maxSpeedForSmoothing
|
||||||
final Distance distance = lastKnownFix.getPosition().getDistance(fix.getPosition());
|
final Distance distance = lastKnownPosition.getDistance(fix.getPosition());
|
||||||
final Duration minDuration = GPSFixTrackImpl.getDefaultMaxSpeedForSmoothing().getDuration(distance);
|
final Duration minDuration = GPSFixTrackImpl.getDefaultMaxSpeedForSmoothing().getDuration(distance);
|
||||||
final GPSFix repeatedFixAvoidingCreepingMark = new GPSFixImpl(lastKnownFix.getPosition(), fix.getTimePoint().minus(minDuration));
|
final GPSFix repeatedFixAvoidingCreepingMark = new GPSFixImpl(lastKnownPosition, fix.getTimePoint().minus(minDuration));
|
||||||
adapter.pingMark(regattaLog, mark, repeatedFixAvoidingCreepingMark, service);
|
adapter.pingMark(regattaLog, mark, repeatedFixAvoidingCreepingMark, service);
|
||||||
}
|
}
|
||||||
adapter.pingMark(regattaLog, mark, fix, service);
|
adapter.pingMark(regattaLog, mark, fix, service);
|
||||||
@@ -684,43 +684,12 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
|||||||
logger.log(Level.WARNING, "Could not ping mark " + mark.getName());
|
logger.log(Level.WARNING, "Could not ping mark " + mark.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastKnownFix != null) {
|
if (lastKnownPosition != null) {
|
||||||
JSONObject lastKnownFixJson = fixSerializer.serialize(lastKnownFix);
|
JSONObject lastKnownFixJson = fixSerializer.serialize(new GPSFixImpl(lastKnownPosition, now));
|
||||||
String fixJson = lastKnownFixJson.toJSONString();
|
String fixJson = lastKnownFixJson.toJSONString();
|
||||||
return Response.ok(fixJson, MediaType.APPLICATION_JSON).build();
|
return Response.ok(fixJson, MediaType.APPLICATION_JSON).build();
|
||||||
} else {
|
} else {
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks at the mark tracks in the tracked races attached to the <code>leaderboard</code>
|
|
||||||
* and if it doesn't find the <code>mark</code> requested there, looks in the <code>regattaLog</code>
|
|
||||||
* for device mappings for the mark and tried to load fixes from the {@link GPSFixStore}.
|
|
||||||
* The latter is only necessary if the mark isn't found in any tracked race because should there
|
|
||||||
* be a tracked race in the leaderboard that has the mark, it will also have received the fixes
|
|
||||||
* from the {@link GPSFixStore} through the regatta log mapping.
|
|
||||||
*/
|
|
||||||
private GPSFix getLastKnownFix(Leaderboard leaderboard, Mark mark, RegattaLog regattaLog) {
|
|
||||||
GPSFixTrack<Mark, GPSFix> track = null;
|
|
||||||
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
|
|
||||||
if (Util.contains(trackedRace.getMarks(), mark)) {
|
|
||||||
track = trackedRace.getOrCreateTrack(mark);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (track == null) { // not found in any tracked race, or no tracked races found
|
|
||||||
// try to load from store
|
|
||||||
DynamicGPSFixTrackImpl<Mark> loadedTrack = new DynamicGPSFixTrackImpl<Mark>(mark, 0);
|
|
||||||
track = loadedTrack;
|
|
||||||
try {
|
|
||||||
getService().getGPSFixStore().loadMarkTrack(loadedTrack, regattaLog, mark);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.log(Level.WARNING, "Couldn't load mark track for mark "+mark, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GPSFix lastKnownFix = track.getLastFixAtOrBefore(MillisecondsTimePoint.now());
|
|
||||||
return lastKnownFix;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@ import com.sap.sailing.domain.base.EventBase;
|
|||||||
import com.sap.sailing.domain.base.Fleet;
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||||
|
import com.sap.sailing.domain.base.Mark;
|
||||||
import com.sap.sailing.domain.base.RaceColumn;
|
import com.sap.sailing.domain.base.RaceColumn;
|
||||||
import com.sap.sailing.domain.base.RaceDefinition;
|
import com.sap.sailing.domain.base.RaceDefinition;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
@@ -35,6 +36,7 @@ import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
|
|||||||
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
|
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
|
||||||
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||||
import com.sap.sailing.domain.common.DataImportProgress;
|
import com.sap.sailing.domain.common.DataImportProgress;
|
||||||
|
import com.sap.sailing.domain.common.Position;
|
||||||
import com.sap.sailing.domain.common.RaceFetcher;
|
import com.sap.sailing.domain.common.RaceFetcher;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
import com.sap.sailing.domain.common.RegattaFetcher;
|
import com.sap.sailing.domain.common.RegattaFetcher;
|
||||||
@@ -54,6 +56,7 @@ import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
|||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.RaceListener;
|
import com.sap.sailing.domain.tracking.RaceListener;
|
||||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||||
@@ -124,6 +127,22 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
|||||||
*/
|
*/
|
||||||
Leaderboard getLeaderboardByName(String name);
|
Leaderboard getLeaderboardByName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks at the mark tracks in the tracked races attached to the <code>leaderboard</code>. If it doesn't find a
|
||||||
|
* track for the <code>mark</code> requested there which has fixes before and after <code>timePoint</code> (to
|
||||||
|
* ensure that no track cropping has taken place, removing the fixes for the interesting time period), looks in the
|
||||||
|
* leaderboard's regatta log and the specific <code>raceLog</code> (if provided) or all race logs attached to the
|
||||||
|
* leaderboard (if not provided) for device mappings for the mark and tries to load fixes from the
|
||||||
|
* {@link GPSFixStore}. The latter is only necessary if the mark isn't found in any tracked race with fixes
|
||||||
|
* surrounding <code>timePoint</code> because should there be a tracked race in the leaderboard that has the mark
|
||||||
|
* then it will also have received the fixes from the {@link GPSFixStore} through the regatta log mapping.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @return the position obtained by interpolation but never extrapolation from the track identified as described
|
||||||
|
* above
|
||||||
|
*/
|
||||||
|
Position getMarkPosition(Mark mark, LeaderboardThatHasRegattaLike leaderboard, TimePoint timePoint, RaceLog raceLog);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops tracking all races of the regatta specified. This will also stop tracking wind for all races of this regatta.
|
* Stops tracking all races of the regatta specified. This will also stop tracking wind for all races of this regatta.
|
||||||
* See {@link #stopTrackingWind(Regatta, RaceDefinition)}. If there were multiple calls to
|
* See {@link #stopTrackingWind(Regatta, RaceDefinition)}. If there were multiple calls to
|
||||||
@@ -581,4 +600,5 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
|||||||
FileStorageManagementService getFileStorageManagementService();
|
FileStorageManagementService getFileStorageManagementService();
|
||||||
|
|
||||||
ClassLoader getCombinedMasterDataClassLoader();
|
ClassLoader getCombinedMasterDataClassLoader();
|
||||||
|
|
||||||
}
|
}
|
||||||
+47
@@ -43,6 +43,7 @@ import org.osgi.framework.BundleContext;
|
|||||||
import org.osgi.framework.ServiceReference;
|
import org.osgi.framework.ServiceReference;
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.AbstractLog;
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
@@ -85,6 +86,7 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
|
|||||||
import com.sap.sailing.domain.base.impl.RemoteSailingServerReferenceImpl;
|
import com.sap.sailing.domain.base.impl.RemoteSailingServerReferenceImpl;
|
||||||
import com.sap.sailing.domain.common.DataImportProgress;
|
import com.sap.sailing.domain.common.DataImportProgress;
|
||||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||||
|
import com.sap.sailing.domain.common.Position;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
import com.sap.sailing.domain.common.RegattaIdentifier;
|
import com.sap.sailing.domain.common.RegattaIdentifier;
|
||||||
import com.sap.sailing.domain.common.RegattaName;
|
import com.sap.sailing.domain.common.RegattaName;
|
||||||
@@ -125,11 +127,13 @@ import com.sap.sailing.domain.racelog.RaceLogStore;
|
|||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||||
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.GPSFix;
|
import com.sap.sailing.domain.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||||
import com.sap.sailing.domain.tracking.RaceHandle;
|
import com.sap.sailing.domain.tracking.RaceHandle;
|
||||||
@@ -144,6 +148,7 @@ import com.sap.sailing.domain.tracking.WindStore;
|
|||||||
import com.sap.sailing.domain.tracking.WindTracker;
|
import com.sap.sailing.domain.tracking.WindTracker;
|
||||||
import com.sap.sailing.domain.tracking.WindTrackerFactory;
|
import com.sap.sailing.domain.tracking.WindTrackerFactory;
|
||||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||||
|
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||||
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.polars.PolarDataService;
|
||||||
@@ -970,6 +975,48 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
return leaderboardsByName.get(name);
|
return leaderboardsByName.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Position getMarkPosition(Mark mark, LeaderboardThatHasRegattaLike leaderboard, TimePoint timePoint, RaceLog raceLog) {
|
||||||
|
GPSFixTrack<Mark, GPSFix> track = null;
|
||||||
|
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
|
||||||
|
if (Util.contains(trackedRace.getMarks(), mark)) {
|
||||||
|
GPSFixTrack<Mark, GPSFix> trackCandidate = trackedRace.getOrCreateTrack(mark);
|
||||||
|
if (spansTimePoint(trackCandidate, timePoint)) {
|
||||||
|
track = trackCandidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (track == null) { // no spanning track found in any tracked race, or no tracked races found
|
||||||
|
// try to load from store
|
||||||
|
DynamicGPSFixTrackImpl<Mark> loadedTrack = new DynamicGPSFixTrackImpl<Mark>(mark, 0);
|
||||||
|
track = loadedTrack;
|
||||||
|
Set<AbstractLog<?, ?>> logs = new HashSet<>();
|
||||||
|
logs.add(leaderboard.getRegattaLike().getRegattaLog());
|
||||||
|
if (raceLog == null) { // no race log explicitly provided --> use all race logs
|
||||||
|
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||||
|
for (Fleet fleet : raceColumn.getFleets()) {
|
||||||
|
logs.add(raceColumn.getRaceLog(fleet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logs.add(raceLog);
|
||||||
|
}
|
||||||
|
for (AbstractLog<?, ?> log : logs) {
|
||||||
|
try {
|
||||||
|
getGPSFixStore().loadMarkTrack(loadedTrack, log, mark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Couldn't load mark track for mark " + mark + " from log " + log, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return track.getEstimatedPosition(timePoint, /* extrapolate */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean spansTimePoint(GPSFixTrack<Mark, GPSFix> track, TimePoint timePoint) {
|
||||||
|
return track.getLastFixAtOrBefore(timePoint) != null && track.getFirstFixAtOrAfter(timePoint) != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Leaderboard> getLeaderboards() {
|
public Map<String, Leaderboard> getLeaderboards() {
|
||||||
return Collections.unmodifiableMap(new HashMap<String, Leaderboard>(leaderboardsByName));
|
return Collections.unmodifiableMap(new HashMap<String, Leaderboard>(leaderboardsByName));
|
||||||
|
|||||||
Reference in new issue
Block a user