Merge branch 'gwt' into spectator

This commit is contained in:
Lennart Hensler committed 2012-02-03 08:50:06 +01:00
commit a2290a770f
11 files changed
+144 -93

No files matched your search

@@ -102,12 +102,11 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
*/
@Test
public void testWindEstimationCacheInvalidationAfterLegTypeChange() throws NoWindException {
MillisecondsTimePoint fixTime = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime());
TimePoint fixTime = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime());
TimePoint checkTime = new MillisecondsTimePoint(fixTime.asMillis()+60000); // one minute later
initRace(2, new int[] { 1, 1 }, fixTime);
getTrackedRace().setRaceIsKnownToStartUpwind(false); // use only WEB wind to determine leg type
TimePoint now = getTrackedRace()
.getMarkPassingsInOrder(getTrackedRace().getRace().getCourse().getFirstWaypoint()).iterator().next()
.getTimePoint();
TimePoint now = checkTime;
setBearingForCompetitor(competitors.get(0), now, 320);
setBearingForCompetitor(competitors.get(1), now, 50);
TrackedLeg firstLeg = getTrackedRace().getTrackedLeg(getTrackedRace().getRace().getCourse().getLegs().iterator().next());
@@ -123,7 +122,7 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
}
}
};
Wind estimatedWindDirection = track.getEstimatedWind(/* position */ null, fixTime);
Wind estimatedWindDirection = track.getEstimatedWind(/* position */ null, checkTime);
assertNotNull(estimatedWindDirection);
assertEquals(185., estimatedWindDirection.getBearing().getDegrees(), 0.00000001);
assertFalse(cachedFixes.isEmpty());
@@ -132,14 +131,14 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
Iterator<Waypoint> waypointsIter = getTrackedRace().getRace().getCourse().getWaypoints().iterator();
Waypoint leewardMark = waypointsIter.next();
Waypoint windwardMark = waypointsIter.next();
Position leewardGatePosition = getTrackedRace().getApproximatePosition(leewardMark, fixTime);
Position leewardGatePosition = getTrackedRace().getApproximatePosition(leewardMark, checkTime);
Distance d = new NauticalMileDistance(1);
Wind wind = getTrackedRace().getWind(null, fixTime, WindSource.TRACK_BASED_ESTIMATION);
Wind wind = getTrackedRace().getWind(null, checkTime, WindSource.TRACK_BASED_ESTIMATION);
Position newWindwardMarkPosition = leewardGatePosition.translateGreatCircle(wind.getBearing(), d);
getTrackedRace().getOrCreateTrack(windwardMark.getBuoys().iterator().next()).addGPSFix(
new GPSFixImpl(newWindwardMarkPosition, fixTime));
new GPSFixImpl(newWindwardMarkPosition, checkTime));
assertEquals(LegType.DOWNWIND, firstLeg.getLegType(fixTime));
Wind estimatedWindDirectionDownwind = track.getEstimatedWind(/* position */ null, fixTime);
Wind estimatedWindDirectionDownwind = track.getEstimatedWind(/* position */ null, checkTime);
assertNotNull(estimatedWindDirectionDownwind);
assertEquals(5., estimatedWindDirectionDownwind.getBearing().getDegrees(), 0.00000001);
}
@@ -147,12 +146,11 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
@Test
public void testWindEstimationCaching() {
MillisecondsTimePoint fixTime = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime());
TimePoint checkTime = new MillisecondsTimePoint(fixTime.asMillis()+60000); // one minute later
initRace(2, new int[] { 1, 1 }, fixTime);
TimePoint now = getTrackedRace()
.getMarkPassingsInOrder(getTrackedRace().getRace().getCourse().getFirstWaypoint()).iterator().next()
.getTimePoint();
setBearingForCompetitor(competitors.get(0), now, 320);
setBearingForCompetitor(competitors.get(1), now, 50);
TimePoint now = checkTime;
setBearingForCompetitor(competitors.get(0), checkTime, 320);
setBearingForCompetitor(competitors.get(1), checkTime, 50);
final Map<TimePoint, Wind> cachedFixes = new HashMap<TimePoint, Wind>();
TrackBasedEstimationWindTrackImpl track = new TrackBasedEstimationWindTrackImpl(
getTrackedRace(), /* millisecondsOverWhichToAverage */ 30000) {
@@ -164,21 +162,21 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
}
}
};
Wind estimatedWindDirection = track.getEstimatedWind(/* position */ null, fixTime);
Wind estimatedWindDirection = track.getEstimatedWind(/* position */ null, checkTime);
assertNotNull(estimatedWindDirection);
assertEquals(185., estimatedWindDirection.getBearing().getDegrees(), 0.00000001);
assertFalse(cachedFixes.isEmpty());
assertEquals(185., cachedFixes.values().iterator().next().getBearing().getDegrees(), 0.00000001);
// now clear set of cached fixes, ask again and ensure nothing is cached again:
cachedFixes.clear();
Wind estimatedWindDirectionCached = track.getEstimatedWind(/* position */ null, fixTime);
Wind estimatedWindDirectionCached = track.getEstimatedWind(/* position */ null, checkTime);
assertTrue(cachedFixes.isEmpty());
assertNotNull(estimatedWindDirectionCached);
assertEquals(185., estimatedWindDirectionCached.getBearing().getDegrees(), 0.00000001);
// now add a GPS fix and make sure the cache is invalidated
now = MillisecondsTimePoint.now();
setBearingForCompetitor(competitors.get(0), now, 330);
Wind estimatedWindDirectionNew = track.getEstimatedWind(/* position */ null, fixTime);
Wind estimatedWindDirectionNew = track.getEstimatedWind(/* position */ null, checkTime);
assertFalse(cachedFixes.isEmpty());
assertNotNull(estimatedWindDirectionNew);
assertTrue("Expected estimated wind direction to now be greater than 185 degrees but was "
@@ -196,6 +194,29 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
assertEquals(185., estimatedWindDirection.getBearing().getDegrees(), 0.00000001);
}
@Test
public void testWindEstimationForSimpleTracksWithOneAncientFixToBeSuppressedByLowConfidence() throws NoWindException {
initRace(3, new int[] { 1, 1, 1 }, new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime()));
MillisecondsTimePoint now = MillisecondsTimePoint.now();
setBearingForCompetitor(competitors.get(0), now, 320);
setBearingForCompetitor(competitors.get(1), now, 50);
setBearingForCompetitor(competitors.get(2), new MillisecondsTimePoint(0), 100); // this shouldn't disturb the estimation because it's too old
Wind estimatedWindDirection = getTrackedRace().getEstimatedWindDirection(/* position */ null, now);
assertEquals(185., estimatedWindDirection.getBearing().getDegrees(), 0.00000001);
}
@Test
public void testWindEstimationForSimpleTracksWithOneFixNearMarkPassingToBeSuppressedByLowConfidence() throws NoWindException {
TimePoint markPassingTimePoint = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime());
initRace(3, new int[] { 1, 1, 1 }, markPassingTimePoint);
MillisecondsTimePoint now = MillisecondsTimePoint.now();
setBearingForCompetitor(competitors.get(0), now, 320);
setBearingForCompetitor(competitors.get(1), now, 50);
setBearingForCompetitor(competitors.get(2), markPassingTimePoint, 100); // this shouldn't disturb the estimation because it's too old
Wind estimatedWindDirection = getTrackedRace().getEstimatedWindDirection(/* position */ null, now);
assertEquals(185., estimatedWindDirection.getBearing().getDegrees(), 0.00000001);
}
@Test
public void testWindEstimationForTwoBoatsOnSameTack() throws NoWindException {
initRace(2, new int[] { 1, 1 }, new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime()));
@@ -45,7 +45,7 @@ public class WindEstimationOnStoredTracksTest extends StoredTrackBasedTestWithTr
public void testZeroConfidenceLeadsToNullBearingAverage() {
BearingWithConfidenceCluster<Void> cluster = new BearingWithConfidenceCluster<Void>(null);
cluster.add(new BearingWithConfidenceImpl<Void>(new DegreeBearingImpl(355), /* confidence */ 0., null));
assertNull(cluster.getAverage(null).getObject());
assertNull(cluster.getAverage(null));
}
@Test
@@ -14,7 +14,7 @@ public class BoatClassImpl extends NamedImpl implements BoatClass {
private static final double MINIMUM_ANGLE_BETWEEN_DIFFERENT_TACKS_UPWIND = 45.;
private static final double MINIMUM_ANGLE_BETWEEN_DIFFERENT_TACKS_DOWNWIND = 15.;
private static final double MINIMUM_ANGLE_BETWEEN_DIFFERENT_TACKS_DOWNWIND = 25.;
private static final Distance MAXIMUM_DISTANCE_FOR_COURSE_APPROXIMATION = new MeterDistance(3);
@@ -116,8 +116,13 @@ public class BearingWithConfidenceCluster<RelativeTo> {
return bearings.size();
}
/**
* Adds the <code>bearing</code> if its {@link BearingWithConfidence#getConfidence() confidence} is greater than 0.0
*/
public void add(BearingWithConfidence<RelativeTo> bearing) {
bearings.add(bearing);
if (bearing.getConfidence() > 0) {
bearings.add(bearing);
}
}
/**
@@ -479,11 +479,14 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends TrackImpl
SpeedWithBearing estimatedSpeedAtStart = getEstimatedSpeed(start);
if (estimatedSpeedAtStart != null) {
Bearing bearingAtStart = estimatedSpeedAtStart.getBearing();
SpeedWithBearing estimatedSpeedAtEnd = getEstimatedSpeed(end);
if (estimatedSpeedAtEnd != null) {
Bearing bearingAtEnd = estimatedSpeedAtEnd.getBearing();
// TODO also need to analyze the (smoothened) directions in between; example: two tacks within averaging interval
result = Math.abs(bearingAtStart.getDifferenceTo(bearingAtEnd).getDegrees()) > minimumDegreeDifference;
TimePoint next = new MillisecondsTimePoint(start.asMillis()+Math.max(1000l, getMillisecondsOverWhichToAverageSpeed()/2));
while (!result && next.compareTo(end) <= 0) {
SpeedWithBearing estimatedSpeedAtNext = getEstimatedSpeed(next);
if (estimatedSpeedAtNext != null) {
Bearing bearingAtEnd = estimatedSpeedAtNext.getBearing();
result = Math.abs(bearingAtStart.getDifferenceTo(bearingAtEnd).getDegrees()) > minimumDegreeDifference;
}
next = new MillisecondsTimePoint(next.asMillis()+Math.max(1000l, getMillisecondsOverWhichToAverageSpeed()/2));
}
}
return result;
@@ -52,6 +52,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.confidence.ConfidenceFactory;
import com.sap.sailing.domain.confidence.Weigher;
import com.sap.sailing.domain.confidence.impl.LinearTimeDifferenceWeigher;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
@@ -651,41 +652,12 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public Wind getEstimatedWindDirection(Position position, TimePoint timePoint) {
DummyMarkPassingWithTimePointOnly dummyMarkPassingForNow = new DummyMarkPassingWithTimePointOnly(timePoint);
Weigher<TimePoint> weigher = ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher(
// use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero
getMillisecondsOverWhichToAverageSpeed());
Map<LegType, BearingWithConfidenceCluster<TimePoint>> bearings = new HashMap<LegType, BearingWithConfidenceCluster<TimePoint>>();
for (LegType legType : LegType.values()) {
bearings.put(legType, new BearingWithConfidenceCluster<TimePoint>(weigher));
}
for (Competitor competitor : getRace().getCompetitors()) {
TrackedLegOfCompetitor leg = getTrackedLeg(competitor, timePoint);
if (leg != null) {
TrackedLeg trackedLeg = getTrackedLeg(leg.getLeg());
LegType legType;
try {
legType = trackedLeg.getLegType(timePoint);
} catch (NoWindException e) {
logger.warning("Unable to determine leg type for race "+getRace().getName()+" while trying to estimate wind");
return null;
}
if (legType != LegType.REACHING) {
GPSFixTrack<Competitor, GPSFixMoving> track = getTrack(competitor);
// TODO bug #167 could be fixed here by excluding competitors that are x seconds before/after a mark passing
if (!track.hasDirectionChange(timePoint, getManeuverDegreeAngleThreshold())) {
SpeedWithBearingWithConfidence<TimePoint> estimatedSpeedWithConfidence = track.getEstimatedSpeed(timePoint,
weigher);
if (estimatedSpeedWithConfidence != null) {
BearingWithConfidence<TimePoint> bearing = new BearingWithConfidenceImpl<TimePoint>(
estimatedSpeedWithConfidence.getObject().getBearing(), estimatedSpeedWithConfidence.getConfidence(),
estimatedSpeedWithConfidence.getRelativeTo());
BearingWithConfidenceCluster<TimePoint> bearingClusterForLegType = bearings.get(legType);
bearingClusterForLegType.add(bearing);
}
}
}
}
}
Map<LegType, BearingWithConfidenceCluster<TimePoint>> bearings = clusterBearingsForWindEstimation(timePoint,
dummyMarkPassingForNow, weigher);
// use the minimum confidence of the four "quadrants" as the result's confidence
BearingWithConfidenceImpl<TimePoint> reversedUpwindAverage = null;
int upwindNumberOfRelevantBoats = 0;
@@ -726,6 +698,57 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
return resultBearing == null ? null : new WindImpl(null, timePoint,
new KnotSpeedWithBearingImpl(/* speedInKnots */ numberOfBoatsRelevantForEstimate, resultBearing.getObject()));
}
private Map<LegType, BearingWithConfidenceCluster<TimePoint>> clusterBearingsForWindEstimation(TimePoint timePoint,
DummyMarkPassingWithTimePointOnly dummyMarkPassingForNow, Weigher<TimePoint> weigher) {
Weigher<TimePoint> weigherForMarkPassingProximity = new LinearTimeDifferenceWeigher(getMillisecondsOverWhichToAverageSpeed());
Map<LegType, BearingWithConfidenceCluster<TimePoint>> bearings = new HashMap<LegType, BearingWithConfidenceCluster<TimePoint>>();
for (LegType legType : LegType.values()) {
bearings.put(legType, new BearingWithConfidenceCluster<TimePoint>(weigher));
}
for (Competitor competitor : getRace().getCompetitors()) {
TrackedLegOfCompetitor leg = getTrackedLeg(competitor, timePoint);
if (leg != null) {
TrackedLeg trackedLeg = getTrackedLeg(leg.getLeg());
LegType legType;
try {
legType = trackedLeg.getLegType(timePoint);
} catch (NoWindException e) {
logger.warning("Unable to determine leg type for race "+getRace().getName()+" while trying to estimate wind");
return null;
}
if (legType != LegType.REACHING) {
GPSFixTrack<Competitor, GPSFixMoving> track = getTrack(competitor);
if (!track.hasDirectionChange(timePoint, getManeuverDegreeAngleThreshold())) {
// reduce confidence around mark passings:
NavigableSet<MarkPassing> markPassings = getMarkPassings(competitor);
NavigableSet<MarkPassing> prevMarkPassing = markPassings.headSet(dummyMarkPassingForNow, /* inclusive */ true);
NavigableSet<MarkPassing> nextMarkPassing = markPassings.tailSet(dummyMarkPassingForNow, /* inclusive */ true);
double markPassingProximityConfidenceReduction = 1.0;
if (prevMarkPassing != null && !prevMarkPassing.isEmpty()) {
markPassingProximityConfidenceReduction *= Math.max(0.0,
1.0-weigherForMarkPassingProximity.getConfidence(prevMarkPassing.last().getTimePoint(), timePoint));
}
if (nextMarkPassing != null && !nextMarkPassing.isEmpty()) {
markPassingProximityConfidenceReduction *= Math.max(0.0,
1.0-weigherForMarkPassingProximity.getConfidence(nextMarkPassing.first().getTimePoint(), timePoint));
}
SpeedWithBearingWithConfidence<TimePoint> estimatedSpeedWithConfidence = track.getEstimatedSpeed(timePoint,
weigher);
if (estimatedSpeedWithConfidence != null) {
BearingWithConfidence<TimePoint> bearing = new BearingWithConfidenceImpl<TimePoint>(
estimatedSpeedWithConfidence.getObject() == null ? null : estimatedSpeedWithConfidence.getObject().getBearing(),
markPassingProximityConfidenceReduction*estimatedSpeedWithConfidence.getConfidence(),
estimatedSpeedWithConfidence.getRelativeTo());
BearingWithConfidenceCluster<TimePoint> bearingClusterForLegType = bearings.get(legType);
bearingClusterForLegType.add(bearing);
}
}
}
}
}
return bearings;
}
/**
* This is probably best explained by example. If the wind bearing is from port to starboard, the situation looks
@@ -1,5 +1,5 @@
#Thu Feb 02 12:04:27 CET 2012
#Thu Feb 02 18:41:06 CET 2012
eclipse.preferences.version=1
entryPointModules=
filesCopiedToWebInfLib=gwt-servlet.jar
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDUxMm1dXT48L3ZtLWFyZ3M+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\=
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48L2d3dC1jb21waWxlLXNldHRpbmdzPg\=\=
@@ -150,7 +150,9 @@ public class RaceMapPanel extends FormPanel implements EventDisplayer, TimeListe
switch(timer.getPlayMode()) {
case Live:
case Replay:
timer.setTime(selectedRace.startOfRace.getTime());
if(selectedRace.startOfRace != null) {
timer.setTime(selectedRace.startOfRace.getTime());
}
break;
}
timePanel.setLegMarkers();
@@ -197,14 +197,11 @@ public class TimePanel extends FormPanel implements Component<TimePanelSettings>
} else {
timeDelayLabel = null;
}
ImageResource settingsIcon = resources.settingsIcon();
Anchor settingsAnchor = new Anchor(AbstractImagePrototype.create(settingsIcon).getSafeHtml());
settingsAnchor.setTitle(stringMessages.settings());
settingsAnchor.addClickHandler(new SettingsClickHandler(stringMessages));
controlsPanel.add(settingsAnchor);
setWidget(vp);
}
@@ -235,10 +232,12 @@ public class TimePanel extends FormPanel implements Component<TimePanelSettings>
int numTicks = 8;
sliderBar.setMinValue(new Double(min.getTime()));
sliderBar.setMaxValue(new Double(max.getTime()));
if(sliderBar.getCurrentValue() == null) {
sliderBar.setCurrentValue(new Double(min.getTime()));
}
sliderBar.setNumTickLabels(numTicks);
sliderBar.setNumTicks(numTicks);
double stepSize = (max.getTime() - min.getTime()) / numTicks;
sliderBar.setStepSize(stepSize);
sliderBar.setStepSize(60000);
}
public void changeMax(Date max) {
@@ -258,16 +257,13 @@ public class TimePanel extends FormPanel implements Component<TimePanelSettings>
public void setLegMarkers() {
if(sliderBar.isMinMaxInitialized()) {
sliderBar.clearMarkers();
Double minValue = sliderBar.getMinValue();
Double maxValue = sliderBar.getMaxValue();
int legCount = 5;
double diff = (maxValue - minValue) / (double) legCount;
for(int i = 0; i < legCount; i++)
for(int i = 0; i < legCount; i++) {
sliderBar.addMarker("L" + (i + 1), minValue + i * diff);
}
sliderBar.redraw();
}
}
@@ -306,7 +302,7 @@ public class TimePanel extends FormPanel implements Component<TimePanelSettings>
@Override
public void updateSettings(TimePanelSettings newSettings) {
boolean delayChanged = newSettings.getDelayToLivePlayInSeconds() != getSettings().getDelayToLivePlayInSeconds();
if(delayChanged && timer.getPlayMode() == PlayModes.Live) {
if (delayChanged && timer.getPlayMode() == PlayModes.Live) {
getSettings().setDelayToLivePlayInSeconds(newSettings.getDelayToLivePlayInSeconds());
timeDelayLabel.setText(String.valueOf(newSettings.getDelayToLivePlayInSeconds()) + " s");
delayChanged();
@@ -114,7 +114,7 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
return;
}
createRaceBoardPanel(selectedRace, events, eventName, leaderboardName);
createRaceBoardPanel(selectedRace, events, leaderboardGroup);
}
private RaceDTO findRace(String eventName, String raceName, List<EventDTO> events) {
@@ -132,13 +132,13 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
return null;
}
private void createRaceBoardPanel(RaceDTO selectedRace, List<EventDTO> events, String eventName, String leaderboardName) {
private void createRaceBoardPanel(RaceDTO selectedRace, List<EventDTO> events, LeaderboardGroupDTO leaderboardGroup) {
LogoAndTitlePanel logoAndTitlePanel = new LogoAndTitlePanel(stringMessages);
logoAndTitlePanel.addStyleName("LogoAndTitlePanel");
RaceSelectionModel raceSelectionModel = new RaceSelectionModel();
List<RaceIdentifier> singletonList = Collections.singletonList(selectedRace.getRaceIdentifier());
raceSelectionModel.setSelection(singletonList);
raceBoardPanel = new RaceBoardPanel(sailingService, raceSelectionModel, leaderboardName,
raceBoardPanel = new RaceBoardPanel(sailingService, raceSelectionModel, leaderboardName, leaderboardGroup,
RaceBoardEntryPoint.this, stringMessages);
raceBoardPanel.fillEvents(events);
@@ -146,7 +146,7 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
FlowPanel raceBoardHeaderPanel = new FlowPanel();
raceBoardHeaderPanel.addStyleName("RaceBoardHeaderPanel");
raceBoardHeaderPanel.add(raceBoardPanel.getHeaderWidget());
raceBoardHeaderPanel.add(raceBoardPanel.getBreadcrumbWidget());
FlowPanel contentOuterPanel = new FlowPanel(); // outer div which centered page content
contentOuterPanel.addStyleName("contentOuterPanel");
@@ -9,14 +9,14 @@ import java.util.Map;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.gwt.ui.adminconsole.RaceMap;
import com.sap.sailing.gwt.ui.adminconsole.RaceMapSettings;
import com.sap.sailing.gwt.ui.adminconsole.WindChart;
@@ -34,9 +34,11 @@ import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.components.ComponentViewer;
import com.sap.sailing.gwt.ui.shared.panels.BreadcrumbPanel;
/**
* A panel showing a list of components visualizing a race from the events announced by calls to {@link #fillEvents(List)}.
@@ -58,15 +60,14 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
private final Map<RaceIdentifier, RaceDTO> racesByIdentifier;
private final List<CollapsableComponentViewer<?>> collapsableViewers;
private final HorizontalPanel componentsHeaderPanel;
private final FlowPanel componentsNavigationPanel;
private final HorizontalPanel componentsHeaderNamePanel;
private final BreadcrumbPanel breadcrumbPanel;
private final TimePanel timePanel;
private final Timer timer;
private final RaceSelectionProvider raceSelectionProvider;
public RaceBoardPanel(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, String leaderboardName,
ErrorReporter errorReporter, final StringMessages stringMessages) {
public RaceBoardPanel(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, String leaderboardName,
LeaderboardGroupDTO leaderboardGroup, ErrorReporter errorReporter, final StringMessages stringMessages) {
this.sailingService = sailingService;
this.raceSelectionProvider = raceSelectionProvider;
raceSelectionProvider.addRaceSelectionChangeListener(this);
@@ -82,17 +83,15 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
collapsableViewers = new ArrayList<CollapsableComponentViewer<?>>();
CompetitorSelectionModel competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
componentsHeaderPanel = new HorizontalPanel();
componentsHeaderPanel.addStyleName("raceBoardPanelHeader");
mainPanel.add(componentsHeaderPanel);
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = "/gwt/Spectator.html" + (debugParam != null && !debugParam.isEmpty() ? "?gwt.codesvr=" + debugParam : "");
ArrayList<Pair<String, String>> breadcrumbLinksData = new ArrayList<Pair<String, String>>();
breadcrumbLinksData.add(new Pair<String, String>(link, stringMessages.home()));
breadcrumbPanel = new BreadcrumbPanel(breadcrumbLinksData, selectedRaceIdentifier.getRaceName());
mainPanel.add(breadcrumbPanel);
componentsNavigationPanel = new FlowPanel();
componentsNavigationPanel.addStyleName("raceBoardNavigation");
componentsHeaderNamePanel = new HorizontalPanel();
componentsHeaderPanel.add(componentsHeaderNamePanel);
Label eventNameLabel = new Label(selectedRaceIdentifier.getRaceName());
eventNameLabel.setStyleName("raceBoardPanelHeader-name");
componentsHeaderNamePanel.add(eventNameLabel);
// create the default leaderboard and select the right race
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, selectedRaceIdentifier, competitorSelectionModel,
@@ -146,8 +145,8 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
return componentsNavigationPanel;
}
public Widget getHeaderWidget() {
return componentsHeaderPanel;
public Widget getBreadcrumbWidget() {
return breadcrumbPanel;
}
public Widget getTimeWidget() {
@@ -210,7 +209,9 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
switch(timer.getPlayMode()) {
case Live:
case Replay:
timer.setTime(selectedRace.startOfRace.getTime());
if(selectedRace.startOfRace != null) {
timer.setTime(selectedRace.startOfRace.getTime());
}
break;
}
timePanel.setLegMarkers();