started implementing the mark position-related services in SailingServiceImpl

Change-Id: I37d1eaa1b04e40948bbeeaa1b845c995de60b4c6
This commit is contained in:
Axel Uhl committed 2016-03-22 14:40:25 +01:00
1 parent 3d934b3450
commit 41ce0c5430
6 files changed
+113 -32

No files matched your search

@@ -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
@@ -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
@@ -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.
@@ -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();
@@ -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 {
@@ -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
}