mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-30 17:36:40 +00:00
Merge branch 'gwt' into spectator
This commit is contained in:
commit
a2290a770f
11 files changed
+144
-93
No files matched your search
+38
-17
@@ -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()));
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
|
||||
+6
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-5
@@ -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;
|
||||
|
||||
+55
-32
@@ -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\=\=
|
||||
+3
-1
@@ -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();
|
||||
|
||||
+7
-11
@@ -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();
|
||||
|
||||
+4
-4
@@ -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");
|
||||
|
||||
+19
-18
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user