mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
started implementing the mark position-related services in SailingServiceImpl
Change-Id: I37d1eaa1b04e40948bbeeaa1b845c995de60b4c6
This commit is contained in:
1 parent
3d934b3450
commit
41ce0c5430
6 files changed
+113
-32
No files matched your search
+3
@@ -2,11 +2,14 @@ package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.common.BoatHullType;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public interface BoatClass extends Named, IsManagedByCache<SharedDomainFactory> {
|
||||
final Duration APPROXIMATE_AVERAGE_MANEUVER_DURATION = Duration.ONE_SECOND.times(8); // as discussed with Dennis Gehrlein
|
||||
|
||||
/**
|
||||
* The distance returned by this method should be appropriate for use in
|
||||
* {@link TrackedRace#approximate(Competitor, Distance, TimePoint, TimePoint)} so that penalty circles and other
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ public class BoatClassImpl extends NamedImpl implements BoatClass {
|
||||
this.hullLength = hullLength;
|
||||
this.hullBeam = hullBeam;
|
||||
this.hullType = hullType;
|
||||
approximateManeuverDurationInMilliseconds = 8000; // as discussed with Dennis Gehrlein
|
||||
approximateManeuverDurationInMilliseconds = APPROXIMATE_AVERAGE_MANEUVER_DURATION.asMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+28
-16
@@ -3248,22 +3248,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
logger.info("Finished loading competitor tracks for " + getRace().getName());
|
||||
logger.info("Started loading mark tracks for " + getRace().getName());
|
||||
for (Mark mark : getMarksFromRegattaLogs()) {
|
||||
try {
|
||||
gpsFixStore.loadMarkTrack((DynamicGPSFixTrack<Mark, GPSFix>) getOrCreateTrack(mark),
|
||||
log, mark, startOfTimeWindowToLoad, endOfTimeWindowToLoad);
|
||||
if (getOrCreateTrack(mark).getFirstRawFix() == null) {
|
||||
logger.fine("Loading mark positions from outside of start/end of tracking interval ("+
|
||||
startOfTimeWindowToLoad+".."+endOfTimeWindowToLoad+
|
||||
") because no fixes were found in that interval");
|
||||
// got an empty track for the mark; try again without constraining the mapping interval
|
||||
// by start/end of tracking to at least attempt to get fixes at all in case there were any
|
||||
// within the device mapping interval specified
|
||||
gpsFixStore.loadMarkTrack((DynamicGPSFixTrack<Mark, GPSFix>) getOrCreateTrack(mark),
|
||||
log, mark, /* startOfTimeWindowToLoad */ null, /* endOfTimeWindowToLoad */ null);
|
||||
}
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not load track for " + mark, e);
|
||||
}
|
||||
final DynamicGPSFixTrack<Mark, GPSFix> markTrack = (DynamicGPSFixTrack<Mark, GPSFix>) getOrCreateTrack(mark);
|
||||
loadMarkTrack(log, mark, markTrack, startOfTimeWindowToLoad, endOfTimeWindowToLoad);
|
||||
}
|
||||
logger.info("Finished loading mark tracks for " + getRace().getName());
|
||||
} finally {
|
||||
@@ -3287,6 +3273,32 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the GPS fixes for a mark from the {@link #gpsFixStore} and adds them to {@code intoTrack}. The device
|
||||
* mappings are expected to be found in {@code logWithDeviceMappings}. The fixes added have to be within
|
||||
* {@code from} and {@code to}, inclusively, with one exception: if no fix is found within this interval at all, all
|
||||
* fixes found for the mark are loaded to make sure that any position data that may give a hint for the interval
|
||||
* requests is loaded.
|
||||
*/
|
||||
private void loadMarkTrack(final RegattaLog logWithDeviceMappings, Mark mark,
|
||||
final DynamicGPSFixTrack<Mark, GPSFix> intoTrack, final TimePoint from, final TimePoint to) {
|
||||
try {
|
||||
gpsFixStore.loadMarkTrack(intoTrack, logWithDeviceMappings, mark, from, to);
|
||||
if (intoTrack.getFirstRawFix() == null) {
|
||||
logger.fine("Loading mark positions from outside of start/end of tracking interval ("+
|
||||
from+".."+to+
|
||||
") because no fixes were found in that interval");
|
||||
// got an empty track for the mark; try again without constraining the mapping interval
|
||||
// by start/end of tracking to at least attempt to get fixes at all in case there were any
|
||||
// within the device mapping interval specified
|
||||
gpsFixStore.loadMarkTrack(intoTrack,
|
||||
logWithDeviceMappings, mark, /* startOfTimeWindowToLoad */ null, /* endOfTimeWindowToLoad */ null);
|
||||
}
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not load track for " + mark, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if currently the race is loading GPS fixes from the {@link GPSFixStore}. Clients may {@link Object#wait()} on <code>this</code>
|
||||
* object and will be notified whenever a change of this flag's value occurs.
|
||||
|
||||
+3
-3
@@ -608,13 +608,13 @@ public class EditMarkPositionPanel extends AbstractRaceChart implements Componen
|
||||
|
||||
@Override
|
||||
public void onSuccess(MarkTracksDTO markTracks) {
|
||||
Map<MarkDTO, List<GPSFixDTO>> result = new HashMap<>();
|
||||
Map<MarkDTO, Iterable<GPSFixDTO>> result = new HashMap<>();
|
||||
for (MarkTrackDTO track : markTracks.getTracks()) {
|
||||
result.put(track.mark, track.fixes);
|
||||
result.put(track.getMark(), track.getFixes());
|
||||
marks = new HashMap<MarkDTO, SortedMap<GPSFixDTO, FixOverlay>>();
|
||||
raceFromTime = timeRangeWithZoomProvider.getFromTime();
|
||||
raceToTime = timeRangeWithZoomProvider.getToTime();
|
||||
for (final Map.Entry<MarkDTO, List<GPSFixDTO>> fixes : result.entrySet()) {
|
||||
for (final Map.Entry<MarkDTO, Iterable<GPSFixDTO>> fixes : result.entrySet()) {
|
||||
Date fromTime = raceFromTime;
|
||||
Date toTime = raceToTime;
|
||||
PolylineOptions options = PolylineOptions.newInstance();
|
||||
|
||||
+16
-6
@@ -1,7 +1,5 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.RaceIdentifierToLeaderboardRaceColumnAndFleetMapper.LeaderboardNameRaceColumnNameAndFleetName;
|
||||
@@ -10,15 +8,27 @@ import com.sap.sailing.gwt.ui.shared.MarkDTO;
|
||||
|
||||
public interface MarkPositionService {
|
||||
public static class MarkTrackDTO {
|
||||
public MarkDTO mark;
|
||||
public List<GPSFixDTO> fixes;
|
||||
public boolean thinnedOut;
|
||||
private final MarkDTO mark;
|
||||
private final Iterable<GPSFixDTO> fixes;
|
||||
private final boolean thinnedOut;
|
||||
|
||||
public MarkTrackDTO(MarkDTO mark, List<GPSFixDTO> fixes, boolean thinnedOut) {
|
||||
public MarkTrackDTO(MarkDTO mark, Iterable<GPSFixDTO> fixes, boolean thinnedOut) {
|
||||
this.mark = mark;
|
||||
this.fixes = fixes;
|
||||
this.thinnedOut = thinnedOut;
|
||||
}
|
||||
|
||||
public MarkDTO getMark() {
|
||||
return mark;
|
||||
}
|
||||
|
||||
public Iterable<GPSFixDTO> getFixes() {
|
||||
return fixes;
|
||||
}
|
||||
|
||||
public boolean isThinnedOut() {
|
||||
return thinnedOut;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MarkTracksDTO {
|
||||
|
||||
+62
-6
@@ -274,6 +274,7 @@ import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.MarkPassingManeuver;
|
||||
import com.sap.sailing.domain.tracking.RaceHandle;
|
||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||
import com.sap.sailing.domain.tracking.Track;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -281,6 +282,7 @@ import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
||||
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.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.RaceRecord;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracAdapter;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracAdapterFactory;
|
||||
@@ -6111,13 +6113,54 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
if (fleet != null) {
|
||||
for (final Mark mark : raceColumn.getMarks(fleet)) {
|
||||
final MarkDTO markDTO = convertToMarkDTO(mark, /* position */ null);
|
||||
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
final GPSFixTrack<Mark, ? extends GPSFix> markTrack;
|
||||
if (trackedRace != null) {
|
||||
markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
} else {
|
||||
DynamicGPSFixTrackImpl<Mark> writeableMarkTrack = new DynamicGPSFixTrackImpl<Mark>(mark, BoatClass.APPROXIMATE_AVERAGE_MANEUVER_DURATION.asMillis());
|
||||
markTrack = writeableMarkTrack;
|
||||
final RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
final RegattaLog regattaLog = raceColumn.getRegattaLog();
|
||||
final TrackingTimesFinder trackingTimesFinder = new TrackingTimesFinder(raceLog);
|
||||
final Pair<TimePoint, TimePoint> trackingTimes = trackingTimesFinder.analyze();
|
||||
try {
|
||||
getService().getGPSFixStore().loadMarkTrack(writeableMarkTrack, regattaLog, mark, trackingTimes.getA(), trackingTimes.getB());
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.info("Error trying to load mark track for mark "+mark+" from "+trackingTimes.getA()+" to "+trackingTimes.getB());
|
||||
}
|
||||
}
|
||||
Iterable<GPSFixDTO> gpsFixDTOTrack = convertToGPSFixDTOTrack(markTrack);
|
||||
final MarkTrackDTO markTrackDTO = new MarkTrackDTO(markDTO, gpsFixDTOTrack, /* thinned out */ false);
|
||||
markTracks.add(markTrackDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new MarkTracksDTO(markTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses all fixed from {@code track} with the outliers removed, {@link #convertToGPSFixDTO(GPSFix) converts} each
|
||||
* of them to a {@link GPSFixDTO} and adds them to the resulting list.
|
||||
*/
|
||||
private Iterable<GPSFixDTO> convertToGPSFixDTOTrack(Track<? extends GPSFix> track) {
|
||||
final List<GPSFixDTO> result = new ArrayList<>();
|
||||
for (final GPSFix fix : track.getFixes()) {
|
||||
result.add(convertToGPSFixDTO(fix));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private GPSFixDTO convertToGPSFixDTO(GPSFix fix) {
|
||||
final GPSFixDTO result;
|
||||
if (fix == null) {
|
||||
result = null;
|
||||
} else {
|
||||
result = new GPSFixDTO(fix.getTimePoint().asDate(), fix.getPosition());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemoveMarkFix(String leaderboardName, String raceColumnName, String fleetName,
|
||||
@@ -6143,14 +6186,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMarkFix(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString,
|
||||
GPSFixDTO fix) {
|
||||
// TODO Auto-generated method stub
|
||||
public void removeMarkFix(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString, GPSFixDTO fix) {
|
||||
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
final RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn != null) {
|
||||
final Fleet fleet = raceColumn.getFleetByName(fleetName);
|
||||
if (fleet != null) {
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
// TODO need to find all mappings that span fix's time point; revoke all those mappings and instead create two replacements that end before/start after fix's time point to skip it;
|
||||
// TODO if an existing mapping starts at or ends with the fix's time point, only one or no replacement mapping may be required ("ping" case).
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMarkFix(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString,
|
||||
GPSFixDTO newFix) {
|
||||
public void addMarkFix(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString, GPSFixDTO newFix) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user