mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-27 07:56:38 +00:00
Merge branch 'master' into foiling
This commit is contained in:
Binary file not shown.
+16
-4
@@ -151,16 +151,28 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna
|
||||
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds);
|
||||
zoomTypes.add(ZoomTypes.BUOYS);
|
||||
}
|
||||
RaceMapZoomSettings raceMapZoomSettings = new RaceMapZoomSettings(zoomTypes, false);
|
||||
|
||||
AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
RaceMapSettings raceMapSettings = RaceMapSettings.readSettingsFromURL();
|
||||
RaceMapSettings defaultRaceMapSettings = RaceMapSettings.readSettingsFromURL(
|
||||
/* defaultForShowMapControls */ true, /* defaultForShowCourseGeometry */ false,
|
||||
/* defaultForMapOrientationWindUp */ false, /* defaultForViewShowStreamlets */ false,
|
||||
/* defaultForViewShowStreamletColors */ false, /* defaultForViewShowSimulation */ false);
|
||||
final RaceMapSettings raceMapSettings = new RaceMapSettings(raceMapZoomSettings, getHelpLineSettings(),
|
||||
defaultRaceMapSettings.getTransparentHoverlines(), defaultRaceMapSettings.getHoverlineStrokeWeight(),
|
||||
startAnalysisDTO.tailLenghtInMilliseconds, defaultRaceMapSettings.isWindUp(),
|
||||
defaultRaceMapSettings.getBuoyZoneRadiusInMeters(), defaultRaceMapSettings.isShowOnlySelectedCompetitors(),
|
||||
defaultRaceMapSettings.isShowSelectedCompetitorsInfo(), defaultRaceMapSettings.isShowWindStreamletColors(),
|
||||
defaultRaceMapSettings.isShowWindStreamletOverlay(), defaultRaceMapSettings.isShowSimulationOverlay(),
|
||||
defaultRaceMapSettings.isShowMapControls(), defaultRaceMapSettings.getManeuverTypesToShow(),
|
||||
defaultRaceMapSettings.isShowDouglasPeuckerPoints());
|
||||
|
||||
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingServiceAsync,
|
||||
asyncActionsExecutor, null, Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier), 5000l /* requestInterval */);
|
||||
raceMap = new RaceMap(new RaceMapLifecycle(StringMessages.INSTANCE), raceMapSettings, sailingServiceAsync, asyncActionsExecutor, null, timer, competitorSelectionModel,
|
||||
StringMessages.INSTANCE, startAnalysisDTO.regattaAndRaceIdentifier,
|
||||
raceMapResources, /* isSimulationEnabled */ false, /* showHeaderPanel */ true);
|
||||
raceMap.getSettings().setZoomSettings(new RaceMapZoomSettings(zoomTypes, false));
|
||||
raceMap.getSettings().setHelpLinesSettings(getHelpLineSettings());
|
||||
raceMap.getSettings().setTailLengthInMilliseconds(startAnalysisDTO.tailLenghtInMilliseconds);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.setSize("100%", "100%");
|
||||
card_map_container.getElement().getStyle().setHeight(getHeightForRaceMapInPixels(), Unit.PX);
|
||||
|
||||
+133
@@ -2084,4 +2084,137 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
||||
assertTrue(leaderboard.isDiscarded(rankedCompetitor, qColumn, later));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See bug 3752: when the medal race participants do not race in a "Last Race" gold fleet and the "Last Race" column comes before the
|
||||
* medal race column, medal race participants must still rank better than all others; participants not in the medal race and not in
|
||||
* any of the gold and silver fleet of the last race may rank between gold and silver fleet based on the "extreme fleet" idea.
|
||||
*/
|
||||
@Test
|
||||
public void testTotalRankComparatorForOrderedSplitFleetsWithMedalRaceParticipantsNotRacingInLastRaceGoldFleet() throws NoWindException {
|
||||
series = new ArrayList<Series>();
|
||||
// -------- qualification series ------------
|
||||
{
|
||||
List<Fleet> qualificationFleets = new ArrayList<Fleet>();
|
||||
for (String qualificationFleetName : new String[] { "Yellow", "Blue" }) {
|
||||
qualificationFleets.add(new FleetImpl(qualificationFleetName));
|
||||
}
|
||||
List<String> qualificationRaceColumnNames = new ArrayList<String>();
|
||||
qualificationRaceColumnNames.add("Q");
|
||||
Series qualificationSeries = new SeriesImpl("Qualification", /* isMedal */false, /* isFleetsCanRunInParallel */ true, qualificationFleets, qualificationRaceColumnNames, /* trackedRegattaRegistry */ null);
|
||||
// discard the one and only qualification race; it doesn't score
|
||||
qualificationSeries.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(new int[] { 1 }));
|
||||
series.add(qualificationSeries);
|
||||
}
|
||||
|
||||
// -------- final series ------------
|
||||
{
|
||||
List<Fleet> finalFleets = new ArrayList<Fleet>();
|
||||
int fleetOrdering = 1;
|
||||
for (String finalFleetName : new String[] { "Gold", "Silver" }) {
|
||||
finalFleets.add(new FleetImpl(finalFleetName, fleetOrdering++));
|
||||
}
|
||||
List<String> finalRaceColumnNames = new ArrayList<String>();
|
||||
finalRaceColumnNames.add("F");
|
||||
Series finalSeries = new SeriesImpl("Final", /* isMedal */false, /* isFleetsCanRunInParallel */ true, finalFleets, finalRaceColumnNames, /* trackedRegattaRegistry */ null);
|
||||
series.add(finalSeries);
|
||||
}
|
||||
// -------- last race series ------------
|
||||
{
|
||||
List<Fleet> lastRaceFleets = new ArrayList<Fleet>();
|
||||
int fleetOrdering = 1;
|
||||
for (String finalFleetName : new String[] { "Gold", "Silver" }) {
|
||||
lastRaceFleets.add(new FleetImpl(finalFleetName, fleetOrdering++));
|
||||
}
|
||||
List<String> lastRaceColumnNames = new ArrayList<String>();
|
||||
lastRaceColumnNames.add("L");
|
||||
Series lastRaceSeries = new SeriesImpl("Last Race", /* isMedal */false, /* isFleetsCanRunInParallel */ true, lastRaceFleets, lastRaceColumnNames, /* trackedRegattaRegistry */ null);
|
||||
series.add(lastRaceSeries);
|
||||
}
|
||||
// -------- medal series ------------
|
||||
{
|
||||
Set<? extends Fleet> medalFleets = Collections.singleton(new FleetImpl("Default"));
|
||||
List<String> medalRaceColumnNames = new ArrayList<String>();
|
||||
medalRaceColumnNames.add("M");
|
||||
Series medalSeries = new SeriesImpl("Medal", /* isMedal */true, /* isFleetsCanRunInParallel */ true, medalFleets, medalRaceColumnNames, /* trackedRegattaRegistry */ null);
|
||||
series.add(medalSeries);
|
||||
}
|
||||
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true);
|
||||
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, /*startDate*/ null, /*endDate*/ null,
|
||||
series, /* persistent */false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* course area */null, OneDesignRankingMetric::new);
|
||||
List<Competitor> competitors = createCompetitors(12);
|
||||
final int firstYellowCompetitorIndex = 3;
|
||||
List<Competitor> yellow = new ArrayList<>(competitors.subList(firstYellowCompetitorIndex, firstYellowCompetitorIndex+6));
|
||||
List<Competitor> blue = new ArrayList<>(competitors);
|
||||
blue.removeAll(yellow);
|
||||
Collections.shuffle(yellow);
|
||||
Collections.shuffle(blue);
|
||||
final int firstGoldCompetitorIndex = 5;
|
||||
List<Competitor> gold = new ArrayList<>(competitors.subList(firstGoldCompetitorIndex, firstGoldCompetitorIndex+6));
|
||||
List<Competitor> silver = new ArrayList<>(competitors);
|
||||
silver.removeAll(gold);
|
||||
Collections.shuffle(gold);
|
||||
Collections.shuffle(silver);
|
||||
List<Competitor> lastRaceSilver = new ArrayList<>(silver);
|
||||
final Competitor theUntrackedCompetitorInLastRace = lastRaceSilver.get(lastRaceSilver.size()-1);
|
||||
lastRaceSilver.remove(theUntrackedCompetitorInLastRace); // one participant accidentally not tracked; expected to end up between silver and gold
|
||||
List<Competitor> medal = new ArrayList<>(gold.subList(0, 2)); // take two gold race participants as medal race participants
|
||||
List<Competitor> lastRaceGold = new ArrayList<>(gold);
|
||||
lastRaceGold.removeAll(medal); // no medal race participant participates in the last race's gold fleet
|
||||
|
||||
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimePoint later = new MillisecondsTimePoint(now.asMillis()+1000);
|
||||
RaceColumn qColumn = series.get(0).getRaceColumnByName("Q");
|
||||
TrackedRace qYellow = new MockedTrackedRaceWithStartTimeAndRanks(now, yellow);
|
||||
qColumn.setTrackedRace(qColumn.getFleetByName("Yellow"), qYellow);
|
||||
TrackedRace qBlue = new MockedTrackedRaceWithStartTimeAndRanks(now, blue);
|
||||
qColumn.setTrackedRace(qColumn.getFleetByName("Blue"), qBlue);
|
||||
RaceColumn fColumn = series.get(1).getRaceColumnByName("F");
|
||||
TrackedRace f1Gold = new MockedTrackedRaceWithStartTimeAndRanks(now, gold);
|
||||
fColumn.setTrackedRace(fColumn.getFleetByName("Gold"), f1Gold);
|
||||
TrackedRace f1Silver = new MockedTrackedRaceWithStartTimeAndRanks(now, silver);
|
||||
fColumn.setTrackedRace(fColumn.getFleetByName("Silver"), f1Silver);
|
||||
RaceColumn lastRaceColumn = series.get(2).getRaceColumnByName("L");
|
||||
TrackedRace lGold = new MockedTrackedRaceWithStartTimeAndRanks(now, lastRaceGold);
|
||||
lastRaceColumn.setTrackedRace(lastRaceColumn.getFleetByName("Gold"), lGold);
|
||||
TrackedRace lSilver = new MockedTrackedRaceWithStartTimeAndRanks(now, lastRaceSilver);
|
||||
lastRaceColumn.setTrackedRace(lastRaceColumn.getFleetByName("Silver"), lSilver);
|
||||
RaceColumn medalColumn = series.get(3).getRaceColumnByName("M");
|
||||
TrackedRace mDefault = new MockedTrackedRaceWithStartTimeAndRanks(now, medal);
|
||||
medalColumn.setTrackedRace(medalColumn.getFleetByName("Default"), mDefault);
|
||||
|
||||
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
|
||||
Map<Competitor, Double> netPoints = new LinkedHashMap<>();
|
||||
for (Competitor rankedCompetitor : rankedCompetitors) {
|
||||
netPoints.put(rankedCompetitor, leaderboard.getNetPoints(rankedCompetitor, later));
|
||||
}
|
||||
// assert that all medal participants rank better than all other participants
|
||||
for (final Competitor medalCompetitor : medal) {
|
||||
for (final Competitor c : competitors) {
|
||||
if (!medal.contains(c)) {
|
||||
assertTrue(rankedCompetitors.indexOf(medalCompetitor) < rankedCompetitors.indexOf(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
// assert that all last race's gold participants rank better than all silver participants
|
||||
for (final Competitor lastRaceGoldParticipant : lastRaceGold) {
|
||||
for (final Competitor silverParticipant : silver) {
|
||||
assertTrue(rankedCompetitors.indexOf(lastRaceGoldParticipant) < rankedCompetitors.indexOf(silverParticipant));
|
||||
}
|
||||
}
|
||||
// assert that theUntrackedCompetitorInLastRace ended up between the last race's silver and gold fleet participants
|
||||
// based on the "extreme fleet" rule:
|
||||
for (final Competitor c : competitors) {
|
||||
if (c != theUntrackedCompetitorInLastRace) {
|
||||
if (lastRaceGold.contains(c) || medal.contains(c)) {
|
||||
assertTrue(rankedCompetitors.indexOf(c) < rankedCompetitors.indexOf(theUntrackedCompetitorInLastRace));
|
||||
} else {
|
||||
assertTrue(silver.contains(c));
|
||||
assertTrue(rankedCompetitors.indexOf(c) > rankedCompetitors.indexOf(theUntrackedCompetitorInLastRace));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+54
-10
@@ -113,6 +113,7 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
// the competitor scored in this or any subsequent columns
|
||||
boolean needToResetO1ScoreUponNextValidResult = false;
|
||||
boolean needToResetO2ScoreUponNextValidResult = false;
|
||||
int defaultFleetBasedComparisonResult = 0; // relevant if no authoritative fleet-based comparison result was determined; based on extreme fleet vs. no fleet comparison
|
||||
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
||||
needToResetO1ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore();
|
||||
needToResetO2ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore();
|
||||
@@ -173,13 +174,20 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score);
|
||||
}
|
||||
if (preemptiveColumnResult == 0 && raceColumn.isTotalOrderDefinedByFleet()) {
|
||||
preemptiveColumnResult = compareByFleet(raceColumn, o1, o2);
|
||||
final FleetComparisonResult compareByFleetResult = compareByFleet(raceColumn, o1, o2);
|
||||
preemptiveColumnResult = compareByFleetResult.getAuthoritativeFleetComparisonResult();
|
||||
if (defaultFleetBasedComparisonResult == 0) {
|
||||
defaultFleetBasedComparisonResult = compareByFleetResult.getDefaultFleetComparisonResultBasedOnUnknownFleetAssignment();
|
||||
}
|
||||
}
|
||||
if (preemptiveColumnResult != 0) {
|
||||
return preemptiveColumnResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defaultFleetBasedComparisonResult != 0) {
|
||||
return defaultFleetBasedComparisonResult;
|
||||
}
|
||||
// now count the races in which they scored; if they scored in a different number of races, prefer the
|
||||
// competitor who scored more often; otherwise, prefer the competitor who has a better score sum; if score sums are equal,
|
||||
// break tie by sorting scores and looking for the first score difference.
|
||||
@@ -220,27 +228,63 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
}
|
||||
}
|
||||
|
||||
private int compareByFleet(RaceColumn raceColumn, Competitor o1, Competitor o2) {
|
||||
private static class FleetComparisonResult {
|
||||
/**
|
||||
* Is non-{@code 0} if the two competitors have been identified as having raced in different fleets in
|
||||
* {@code raceColumn} with those fleets having different {@link Fleet#getOrdering() orderings}.
|
||||
* Evaluation of further comparison criteria is not necessary in this case.
|
||||
*/
|
||||
private final int authoritativeFleetComparisonResult;
|
||||
|
||||
/**
|
||||
* When for one of the two competitors compared the fleet in which she raced in a race column
|
||||
* could not be determined and the other competitor can be identified as having competed in the
|
||||
* best or in the worst fleet in that column, a default comparison result is derived from this
|
||||
* such that the competitor with the unknown fleet assignment would be considered worse than
|
||||
* a participant of the best, and better than a participant of the worst fleet.<p>
|
||||
*
|
||||
* This result only has relevance if no non-{@code 0} authoritative result can be acquired across
|
||||
* all columns of the leaderboard.
|
||||
*/
|
||||
private final int defaultFleetComparisonResultBasedOnUnknownFleetAssignment;
|
||||
|
||||
public FleetComparisonResult(int authoritativeFleetComparisonResult,
|
||||
int defaultFleetComparisonResultBasedOnUnknownFleetAssignment) {
|
||||
super();
|
||||
this.authoritativeFleetComparisonResult = authoritativeFleetComparisonResult;
|
||||
this.defaultFleetComparisonResultBasedOnUnknownFleetAssignment = defaultFleetComparisonResultBasedOnUnknownFleetAssignment;
|
||||
}
|
||||
|
||||
public int getAuthoritativeFleetComparisonResult() {
|
||||
return authoritativeFleetComparisonResult;
|
||||
}
|
||||
|
||||
public int getDefaultFleetComparisonResultBasedOnUnknownFleetAssignment() {
|
||||
return defaultFleetComparisonResultBasedOnUnknownFleetAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
private FleetComparisonResult compareByFleet(RaceColumn raceColumn, Competitor o1, Competitor o2) {
|
||||
Fleet o1f = raceColumn.getFleetOfCompetitor(o1);
|
||||
Fleet o2f = raceColumn.getFleetOfCompetitor(o2);
|
||||
// if the fleet for both was identified because both were tracked in this column, then if the fleets
|
||||
// don't compare equal, return the fleet comparison as result immediately. Example: o1 competed in Gold fleet,
|
||||
// o2 in Silver fleet; Gold compares better to Silver, so o1 is compared better to o2.
|
||||
int result = 0;
|
||||
final FleetComparisonResult result;
|
||||
if (o1f != null) {
|
||||
if (o2f != null) {
|
||||
if (o1f.compareTo(o2f) != 0) {
|
||||
result = o1f.compareTo(o2f);
|
||||
}
|
||||
result = new FleetComparisonResult(o1f.compareTo(o2f), 0);
|
||||
} else {
|
||||
// check if o1's fleet is best or worst in column; in that case, o1's membership in this fleet and the fact
|
||||
// that o2 is not part of that fleet determines the result
|
||||
result = extremeFleetComparison(raceColumn, o1f);
|
||||
result = new FleetComparisonResult(0, extremeFleetComparison(raceColumn, o1f));
|
||||
}
|
||||
} else if (o2f != null) {
|
||||
// check if o1's fleet is best or worst in column; in that case, o1's membership in this fleet and the fact
|
||||
// that o2 is not part of that fleet determines the result
|
||||
result = -extremeFleetComparison(raceColumn, o2f);
|
||||
// check if o2's fleet is best or worst in column; in that case, o2's membership in this fleet and the fact
|
||||
// that o1 is not part of that fleet determines the result
|
||||
result = new FleetComparisonResult(0, -extremeFleetComparison(raceColumn, o2f));
|
||||
} else {
|
||||
result = new FleetComparisonResult(0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+26
-35
@@ -329,7 +329,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
private RaceMapImageManager raceMapImageManager;
|
||||
|
||||
private final RaceMapSettings settings;
|
||||
private RaceMapSettings settings;
|
||||
private final RaceMapLifecycle raceMapLifecycle;
|
||||
|
||||
private final StringMessages stringMessages;
|
||||
@@ -557,7 +557,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
if (!autoZoomIn && !autoZoomOut && !orientationChangeInProgress) {
|
||||
// stop automatic zoom after a manual zoom event; automatic zoom in zoomMapToNewBounds will restore old settings
|
||||
final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList();
|
||||
settings.getZoomSettings().setTypesToConsiderOnZoom(emptyList);
|
||||
RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, settings.getZoomSettings().isZoomToSelectedCompetitors());
|
||||
settings = new RaceMapSettings(settings, clearedZoomSettings);
|
||||
}
|
||||
// TODO bug489 when in wind-up mode, avoid zooming out too far; perhaps zoom back in if zoomed out too far
|
||||
}
|
||||
@@ -569,7 +570,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
autoZoomIn = false;
|
||||
autoZoomOut = false;
|
||||
final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList();
|
||||
settings.getZoomSettings().setTypesToConsiderOnZoom(emptyList);
|
||||
RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, settings.getZoomSettings().isZoomToSelectedCompetitors());
|
||||
settings = new RaceMapSettings(settings, clearedZoomSettings);
|
||||
}
|
||||
});
|
||||
map.addIdleHandler(new IdleMapHandler() {
|
||||
@@ -650,7 +652,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
*/
|
||||
protected void showAdditionalControls(MapWidget map) {
|
||||
}
|
||||
|
||||
|
||||
private void setHasPolar() {
|
||||
GetPolarAction getPolar = new GetPolarAction(sailingService, raceIdentifier);
|
||||
asyncActionsExecutor.execute(getPolar, GET_POLAR_CATEGORY,
|
||||
@@ -1799,7 +1801,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|| !BoundsUtil.contains((currentMapBounds = map.getBounds()), newBounds)
|
||||
|| graticuleAreaRatio(currentMapBounds, newBounds) > 10) {
|
||||
// only change bounds if the new bounds don't fit into the current map zoom
|
||||
Iterable<ZoomTypes> oldZoomSettings = settings.getZoomSettings().getTypesToConsiderOnZoom();
|
||||
Iterable<ZoomTypes> oldZoomTypesToConsiderSettings = settings.getZoomSettings().getTypesToConsiderOnZoom();
|
||||
setAutoZoomInProgress(true);
|
||||
autoZoomLatLngBounds = newBounds;
|
||||
int newZoomLevel = getZoomLevel(autoZoomLatLngBounds);
|
||||
@@ -1821,7 +1823,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
} else {
|
||||
map.panTo(autoZoomLatLngBounds.getCenter());
|
||||
}
|
||||
settings.getZoomSettings().setTypesToConsiderOnZoom(oldZoomSettings);
|
||||
RaceMapZoomSettings restoredZoomSettings = new RaceMapZoomSettings(oldZoomTypesToConsiderSettings, settings.getZoomSettings().isZoomToSelectedCompetitors());
|
||||
settings = new RaceMapSettings(settings, restoredZoomSettings);
|
||||
setAutoZoomInProgress(false);
|
||||
}
|
||||
}
|
||||
@@ -2445,11 +2448,12 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
@Override
|
||||
public void updateSettings(RaceMapSettings newSettings) {
|
||||
boolean maneuverTypeSelectionChanged = false;
|
||||
boolean requiredRedraw = false;
|
||||
boolean requiresRedraw = false;
|
||||
boolean requiresUpdateCoordinateSystem = false;
|
||||
|
||||
for (ManeuverType maneuverType : ManeuverType.values()) {
|
||||
if (newSettings.isShowManeuverType(maneuverType) != settings.isShowManeuverType(maneuverType)) {
|
||||
maneuverTypeSelectionChanged = true;
|
||||
settings.showManeuverType(maneuverType, newSettings.isShowManeuverType(maneuverType));
|
||||
}
|
||||
}
|
||||
if (maneuverTypeSelectionChanged) {
|
||||
@@ -2460,65 +2464,52 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
if (newSettings.isShowDouglasPeuckerPoints() != settings.isShowDouglasPeuckerPoints()) {
|
||||
if (!(timer.getPlayState() == PlayStates.Playing) && lastDouglasPeuckerResult != null && newSettings.isShowDouglasPeuckerPoints()) {
|
||||
settings.setShowDouglasPeuckerPoints(true);
|
||||
removeAllMarkDouglasPeuckerpoints();
|
||||
showMarkDouglasPeuckerPoints(lastDouglasPeuckerResult);
|
||||
} else if (!newSettings.isShowDouglasPeuckerPoints()) {
|
||||
settings.setShowDouglasPeuckerPoints(false);
|
||||
removeAllMarkDouglasPeuckerpoints();
|
||||
}
|
||||
}
|
||||
if (newSettings.getTailLengthInMilliseconds() != settings.getTailLengthInMilliseconds()) {
|
||||
settings.setTailLengthInMilliseconds(newSettings.getTailLengthInMilliseconds());
|
||||
requiredRedraw = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
if (newSettings.getBuoyZoneRadiusInMeters() != settings.getBuoyZoneRadiusInMeters()) {
|
||||
settings.setBuoyZoneRadiusInMeters(newSettings.getBuoyZoneRadiusInMeters());
|
||||
requiredRedraw = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
if (newSettings.isShowOnlySelectedCompetitors() != settings.isShowOnlySelectedCompetitors()) {
|
||||
settings.setShowOnlySelectedCompetitors(newSettings.isShowOnlySelectedCompetitors());
|
||||
requiredRedraw = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
if (newSettings.isShowSelectedCompetitorsInfo() != settings.isShowSelectedCompetitorsInfo()) {
|
||||
settings.setShowSelectedCompetitorsInfo(newSettings.isShowSelectedCompetitorsInfo());
|
||||
requiredRedraw = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
if (!newSettings.getZoomSettings().equals(settings.getZoomSettings())) {
|
||||
settings.setZoomSettings(newSettings.getZoomSettings());
|
||||
if (!settings.getZoomSettings().containsZoomType(ZoomTypes.NONE)) {
|
||||
if (!newSettings.getZoomSettings().containsZoomType(ZoomTypes.NONE)) {
|
||||
removeTransitions();
|
||||
zoomMapToNewBounds(settings.getZoomSettings().getNewBounds(this));
|
||||
zoomMapToNewBounds(newSettings.getZoomSettings().getNewBounds(this));
|
||||
}
|
||||
}
|
||||
if (!newSettings.getHelpLinesSettings().equals(settings.getHelpLinesSettings())) {
|
||||
settings.setHelpLinesSettings(newSettings.getHelpLinesSettings());
|
||||
requiredRedraw = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
if (newSettings.isShowWindStreamletOverlay() != settings.isShowWindStreamletOverlay()) {
|
||||
settings.setShowWindStreamletOverlay(newSettings.isShowWindStreamletOverlay());
|
||||
streamletOverlay.setVisible(newSettings.isShowWindStreamletOverlay());
|
||||
}
|
||||
if (newSettings.isShowWindStreamletColors() != settings.isShowWindStreamletColors()) {
|
||||
settings.setShowWindStreamletColors(newSettings.isShowWindStreamletColors());
|
||||
streamletOverlay.setColors(newSettings.isShowWindStreamletColors());
|
||||
}
|
||||
if (newSettings.isShowSimulationOverlay() != settings.isShowSimulationOverlay()) {
|
||||
settings.setShowSimulationOverlay(newSettings.isShowSimulationOverlay());
|
||||
showSimulationOverlay(newSettings.isShowSimulationOverlay());
|
||||
}
|
||||
if (newSettings.isWindUp() != settings.isWindUp()) {
|
||||
settings.setWindUp(newSettings.isWindUp());
|
||||
requiresUpdateCoordinateSystem = true;
|
||||
requiresRedraw = true;
|
||||
}
|
||||
this.settings = newSettings;
|
||||
|
||||
if (requiresUpdateCoordinateSystem) {
|
||||
updateCoordinateSystemFromSettings();
|
||||
requiredRedraw = true;
|
||||
}
|
||||
if (newSettings.getTransparentHoverlines() != settings.getTransparentHoverlines()) {
|
||||
settings.setTransparentHoverlines(newSettings.getTransparentHoverlines());
|
||||
}
|
||||
if (newSettings.getHoverlineStrokeWeight() != settings.getHoverlineStrokeWeight()) {
|
||||
settings.setHoverlineStrokeWeight(newSettings.getHoverlineStrokeWeight());
|
||||
}
|
||||
if (requiredRedraw) {
|
||||
if (requiresRedraw) {
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
+108
-92
@@ -6,39 +6,45 @@ import java.util.Set;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
|
||||
public class RaceMapSettings extends AbstractSettings {
|
||||
public static final String PARAM_SHOW_MAPCONTROLS = "showMapControls";
|
||||
|
||||
private boolean showDouglasPeuckerPoints = false;
|
||||
public static final String PARAM_SHOW_COURSE_GEOMETRY = "showCourseGeometry";
|
||||
public static final String PARAM_MAP_ORIENTATION_WIND_UP = "windUp";
|
||||
public static final String PARAM_VIEW_SHOW_STREAMLETS = "viewShowStreamlets";
|
||||
public static final String PARAM_VIEW_SHOW_STREAMLET_COLORS = "viewShowStreamletColors";
|
||||
public static final String PARAM_VIEW_SHOW_SIMULATION = "viewShowSimulation";
|
||||
|
||||
private final boolean showDouglasPeuckerPoints;
|
||||
|
||||
private final Set<ManeuverType> maneuverTypesToShow;
|
||||
|
||||
private boolean showOnlySelectedCompetitors = false;
|
||||
private final boolean showOnlySelectedCompetitors;
|
||||
|
||||
private RaceMapZoomSettings zoomSettings;
|
||||
private final RaceMapZoomSettings zoomSettings;
|
||||
|
||||
private RaceMapHelpLinesSettings helpLinesSettings;
|
||||
private final RaceMapHelpLinesSettings helpLinesSettings;
|
||||
|
||||
private boolean transparentHoverlines = false; // as discussed with Stefan on 2015-12-08
|
||||
private final boolean transparentHoverlines;
|
||||
|
||||
private int hoverlineStrokeWeight = 15; // as discussed with Stefan on 2015-12-08
|
||||
private final int hoverlineStrokeWeight;
|
||||
|
||||
private long tailLengthInMilliseconds = 100000l;
|
||||
private final long tailLengthInMilliseconds;
|
||||
|
||||
private double buoyZoneRadiusInMeters = 0.0;
|
||||
private final double buoyZoneRadiusInMeters;
|
||||
|
||||
private boolean showSelectedCompetitorsInfo = true;
|
||||
private final boolean showSelectedCompetitorsInfo;
|
||||
|
||||
private boolean showWindStreamletColors = false;
|
||||
private final boolean showWindStreamletColors;
|
||||
|
||||
private boolean showWindStreamletOverlay = false;
|
||||
private final boolean showWindStreamletOverlay;
|
||||
|
||||
private boolean showSimulationOverlay = false;
|
||||
private final boolean showSimulationOverlay;
|
||||
|
||||
private boolean showMapControls = true;
|
||||
private final boolean showMapControls;
|
||||
|
||||
/**
|
||||
* If <code>true</code>, all map contents will be transformed to a water-only environment, rotating all directions /
|
||||
@@ -48,23 +54,85 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
* positions to any other coordinate space that is translated and rotated compared to the original
|
||||
* coordinate space.
|
||||
*/
|
||||
private boolean windUp = false;
|
||||
private final boolean windUp;
|
||||
|
||||
public RaceMapSettings() {
|
||||
this.maneuverTypesToShow = getDefaultManeuvers();
|
||||
this.zoomSettings = new RaceMapZoomSettings();
|
||||
this.helpLinesSettings = new RaceMapHelpLinesSettings();
|
||||
this(
|
||||
/* showMapControls */ true,
|
||||
new RaceMapHelpLinesSettings(),
|
||||
/* windUp */ false,
|
||||
/* showWindStreamletOverlay */ false,
|
||||
/* showWindStreamletColors */ false,
|
||||
/* showSimulationOverlay */ false);
|
||||
}
|
||||
|
||||
public RaceMapSettings(boolean showMapCcontrol) {
|
||||
this();
|
||||
this.showMapControls = showMapCcontrol;
|
||||
public RaceMapSettings(RaceMapZoomSettings zoomSettings, RaceMapHelpLinesSettings helpLinesSettings,
|
||||
boolean transparentHoverlines, int hoverlineStrokeWeight, long tailLengthInMilliseconds, boolean windUp,
|
||||
double buoyZoneRadiusInMeters, boolean showOnlySelectedCompetitors, boolean showSelectedCompetitorsInfo,
|
||||
boolean showWindStreamletColors, boolean showWindStreamletOverlay, boolean showSimulationOverlay,
|
||||
boolean showMapControls, Set<ManeuverType> maneuverTypesToShow, boolean showDouglasPeuckerPoints) {
|
||||
this.zoomSettings = zoomSettings;
|
||||
this.helpLinesSettings = helpLinesSettings;
|
||||
this.transparentHoverlines = transparentHoverlines;
|
||||
this.hoverlineStrokeWeight = hoverlineStrokeWeight;
|
||||
this.tailLengthInMilliseconds = tailLengthInMilliseconds;
|
||||
this.windUp = windUp;
|
||||
this.buoyZoneRadiusInMeters = buoyZoneRadiusInMeters;
|
||||
this.showOnlySelectedCompetitors = showOnlySelectedCompetitors;
|
||||
this.showSelectedCompetitorsInfo = showSelectedCompetitorsInfo;
|
||||
this.showWindStreamletColors = showWindStreamletColors;
|
||||
this.showWindStreamletOverlay = showWindStreamletOverlay;
|
||||
this.showSimulationOverlay = showSimulationOverlay;
|
||||
this.showMapControls = showMapControls;
|
||||
this.maneuverTypesToShow = maneuverTypesToShow;
|
||||
this.showDouglasPeuckerPoints = showDouglasPeuckerPoints;
|
||||
}
|
||||
|
||||
private RaceMapSettings(boolean showMapControls, boolean showCourseGeometry, boolean windUp, boolean showWindStreamletOverlay, boolean showWindStreamletColors, boolean showSimulationOverlay) {
|
||||
this(showMapControls, new RaceMapHelpLinesSettings(createHelpLineSettings(showCourseGeometry)), windUp, showWindStreamletOverlay, showWindStreamletColors, showSimulationOverlay);
|
||||
}
|
||||
|
||||
private RaceMapSettings(boolean showMapControls, RaceMapHelpLinesSettings helpLineSettings, boolean windUp, boolean showWindStreamletOverlay, boolean showWindStreamletColors, boolean showSimulationOverlay) {
|
||||
this(
|
||||
new RaceMapZoomSettings(),
|
||||
helpLineSettings,
|
||||
/* transparentHoverlines as discussed with Stefan on 2015-12-08 */ false,
|
||||
/* hoverlineStrokeWeight as discussed with Stefan on 2015-12-08 */ 15,
|
||||
/* tailLengthInMilliseconds */ 100000l,
|
||||
/* windUp */ windUp,
|
||||
/* buoyZoneRadiusInMeters */ 0.0,
|
||||
/* showOnlySelectedCompetitors */ false,
|
||||
/* showSelectedCompetitorsInfo */ true,
|
||||
/* showWindStreamletColors */ showWindStreamletColors,
|
||||
/* showWindStreamletOverlay */ showWindStreamletOverlay,
|
||||
/* showSimulationOverlay */ showSimulationOverlay,
|
||||
/* showMapControls */ showMapControls,
|
||||
/* maneuverTypesToShow */ getDefaultManeuvers(),
|
||||
/* showDouglasPeuckerPoints */ false);
|
||||
}
|
||||
|
||||
private static Set<HelpLineTypes> createHelpLineSettings(boolean showCourseGeometry) {
|
||||
final Set<HelpLineTypes> helpLineTypes = new HashSet<>();
|
||||
Util.addAll(new RaceMapHelpLinesSettings().getVisibleHelpLineTypes(), helpLineTypes);
|
||||
if (showCourseGeometry) {
|
||||
helpLineTypes.add(HelpLineTypes.COURSEGEOMETRY);
|
||||
} else {
|
||||
helpLineTypes.remove(HelpLineTypes.COURSEGEOMETRY);
|
||||
}
|
||||
return helpLineTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Copy constructor" that produces a new settings object that equals the one passed as argument
|
||||
* copy constructor that produces a new settings object that equals the one passed as argument
|
||||
*/
|
||||
public RaceMapSettings(RaceMapSettings settings) {
|
||||
this(settings, new RaceMapZoomSettings(settings.zoomSettings.getTypesToConsiderOnZoom(), settings.zoomSettings.isZoomToSelectedCompetitors()));
|
||||
}
|
||||
|
||||
/**
|
||||
* copy constructor that produces a new settings object that equals the one passed as argument but takes the zoom settings from the second parameter
|
||||
*/
|
||||
public RaceMapSettings(RaceMapSettings settings, RaceMapZoomSettings zoomSettings) {
|
||||
this.buoyZoneRadiusInMeters = settings.buoyZoneRadiusInMeters;
|
||||
this.helpLinesSettings = new RaceMapHelpLinesSettings(settings.getHelpLinesSettings().getVisibleHelpLineTypes());
|
||||
this.transparentHoverlines = settings.transparentHoverlines;
|
||||
@@ -79,9 +147,9 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
this.showMapControls = settings.showMapControls;
|
||||
this.tailLengthInMilliseconds = settings.tailLengthInMilliseconds;
|
||||
this.windUp = settings.windUp;
|
||||
this.zoomSettings = new RaceMapZoomSettings(settings.zoomSettings.getTypesToConsiderOnZoom(), settings.zoomSettings.isZoomToSelectedCompetitors());
|
||||
this.zoomSettings = zoomSettings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return 0 if the tails are not visible {@link #getTailLengthInMilliseconds()} otherwise
|
||||
*/
|
||||
@@ -97,50 +165,22 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
return tailLengthInMilliseconds;
|
||||
}
|
||||
|
||||
public void setTailLengthInMilliseconds(long tailLengthInMilliseconds) {
|
||||
this.tailLengthInMilliseconds = tailLengthInMilliseconds;
|
||||
}
|
||||
|
||||
public boolean isShowDouglasPeuckerPoints() {
|
||||
return showDouglasPeuckerPoints;
|
||||
}
|
||||
|
||||
public void setShowDouglasPeuckerPoints(boolean showDouglasPeuckerPoints) {
|
||||
this.showDouglasPeuckerPoints = showDouglasPeuckerPoints;
|
||||
}
|
||||
|
||||
public boolean isShowWindStreamletOverlay() {
|
||||
return showWindStreamletOverlay;
|
||||
}
|
||||
|
||||
public void setShowWindStreamletOverlay(boolean showWindStreamletOverlay) {
|
||||
this.showWindStreamletOverlay = showWindStreamletOverlay;
|
||||
}
|
||||
|
||||
public boolean isShowWindStreamletColors() {
|
||||
return showWindStreamletColors;
|
||||
}
|
||||
|
||||
public void setShowWindStreamletColors(boolean showWindStreamletColors) {
|
||||
this.showWindStreamletColors = showWindStreamletColors;
|
||||
}
|
||||
|
||||
public boolean isShowSimulationOverlay() {
|
||||
return showSimulationOverlay;
|
||||
}
|
||||
|
||||
public void setShowSimulationOverlay(boolean showSimulationOverlay) {
|
||||
this.showSimulationOverlay = showSimulationOverlay;
|
||||
}
|
||||
|
||||
public void showManeuverType(ManeuverType maneuverType, boolean show) {
|
||||
if (show) {
|
||||
maneuverTypesToShow.add(maneuverType);
|
||||
} else {
|
||||
maneuverTypesToShow.remove(maneuverType);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowManeuverType(ManeuverType maneuverType) {
|
||||
return maneuverTypesToShow.contains(maneuverType);
|
||||
}
|
||||
@@ -149,75 +189,39 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
return showOnlySelectedCompetitors;
|
||||
}
|
||||
|
||||
public void setShowOnlySelectedCompetitors(boolean showOnlySelectedCompetitors) {
|
||||
this.showOnlySelectedCompetitors = showOnlySelectedCompetitors;
|
||||
}
|
||||
|
||||
public RaceMapZoomSettings getZoomSettings() {
|
||||
return zoomSettings;
|
||||
}
|
||||
|
||||
public void setZoomSettings(RaceMapZoomSettings zoomSettings) {
|
||||
this.zoomSettings = zoomSettings;
|
||||
}
|
||||
|
||||
public RaceMapHelpLinesSettings getHelpLinesSettings() {
|
||||
return helpLinesSettings;
|
||||
}
|
||||
|
||||
public void setHelpLinesSettings(RaceMapHelpLinesSettings helpLinesSettings) {
|
||||
this.helpLinesSettings = helpLinesSettings;
|
||||
}
|
||||
|
||||
public boolean getTransparentHoverlines() {
|
||||
return this.transparentHoverlines;
|
||||
}
|
||||
|
||||
public void setTransparentHoverlines(boolean transparentHoverlines) {
|
||||
this.transparentHoverlines = transparentHoverlines;
|
||||
}
|
||||
|
||||
public int getHoverlineStrokeWeight() {
|
||||
return this.hoverlineStrokeWeight;
|
||||
}
|
||||
|
||||
public void setHoverlineStrokeWeight(int hoverlineStrokeWeight) {
|
||||
this.hoverlineStrokeWeight = hoverlineStrokeWeight;
|
||||
}
|
||||
|
||||
public boolean isShowSelectedCompetitorsInfo() {
|
||||
return showSelectedCompetitorsInfo;
|
||||
}
|
||||
|
||||
public void setShowSelectedCompetitorsInfo(boolean showSelectedCompetitorsInfo) {
|
||||
this.showSelectedCompetitorsInfo = showSelectedCompetitorsInfo;
|
||||
}
|
||||
|
||||
public double getBuoyZoneRadiusInMeters() {
|
||||
return buoyZoneRadiusInMeters;
|
||||
}
|
||||
|
||||
public void setBuoyZoneRadiusInMeters(double buoyZoneRadiusInMeters) {
|
||||
this.buoyZoneRadiusInMeters = buoyZoneRadiusInMeters;
|
||||
}
|
||||
|
||||
public boolean isWindUp() {
|
||||
return windUp;
|
||||
}
|
||||
|
||||
public void setWindUp(boolean windUp) {
|
||||
this.windUp = windUp;
|
||||
}
|
||||
|
||||
public boolean isShowMapControls() {
|
||||
return showMapControls;
|
||||
}
|
||||
|
||||
public void setShowMapControls(boolean showMapControls) {
|
||||
this.showMapControls = showMapControls;
|
||||
}
|
||||
|
||||
private HashSet<ManeuverType> getDefaultManeuvers() {
|
||||
private static HashSet<ManeuverType> getDefaultManeuvers() {
|
||||
HashSet<ManeuverType> types = new HashSet<ManeuverType>();
|
||||
types.add(ManeuverType.JIBE);
|
||||
types.add(ManeuverType.TACK);
|
||||
@@ -225,8 +229,20 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
return types;
|
||||
}
|
||||
|
||||
public static RaceMapSettings readSettingsFromURL() {
|
||||
final boolean showMapControls = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_MAPCONTROLS, true /* default */);
|
||||
return new RaceMapSettings(showMapControls);
|
||||
public static RaceMapSettings readSettingsFromURL(boolean defaultForShowMapControls,
|
||||
boolean defaultForShowCourseGeometry, boolean defaultForMapOrientationWindUp,
|
||||
boolean defaultForViewShowStreamlets, boolean defaultForViewShowStreamletColors,
|
||||
boolean defaultForViewShowSimulation) {
|
||||
final boolean showMapControls = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_MAPCONTROLS, defaultForShowMapControls /* default */);
|
||||
final boolean showCourseGeometry = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_COURSE_GEOMETRY, defaultForShowCourseGeometry /* default */);
|
||||
final boolean windUp = GwtHttpRequestUtils.getBooleanParameter(PARAM_MAP_ORIENTATION_WIND_UP, defaultForMapOrientationWindUp /* default */);
|
||||
final boolean showWindStreamletOverlay = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_STREAMLETS, defaultForViewShowStreamlets /* default */);
|
||||
final boolean showWindStreamletColors = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_STREAMLET_COLORS, defaultForViewShowStreamletColors /* default */);
|
||||
final boolean showSimulationOverlay = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_SIMULATION, defaultForViewShowSimulation /* default */);
|
||||
return new RaceMapSettings(showMapControls, showCourseGeometry, windUp, showWindStreamletOverlay, showWindStreamletColors, showSimulationOverlay);
|
||||
}
|
||||
|
||||
public Set<ManeuverType> getManeuverTypesToShow() {
|
||||
return maneuverTypesToShow;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-28
@@ -257,37 +257,31 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
|
||||
@Override
|
||||
public RaceMapSettings getResult() {
|
||||
RaceMapSettings result = new RaceMapSettings();
|
||||
Set<ManeuverType> maneuverTypesToShow = new HashSet<ManeuverType>();
|
||||
for (Util.Pair<CheckBox, ManeuverType> p : checkboxAndManeuverType) {
|
||||
result.showManeuverType(p.getB(), p.getA().getValue());
|
||||
}
|
||||
RaceMapHelpLinesSettings helpLinesSettings = getHelpLinesSettings();
|
||||
result.setZoomSettings(getZoomSettings());
|
||||
result.setHelpLinesSettings(helpLinesSettings);
|
||||
result.setShowDouglasPeuckerPoints(showDouglasPeuckerPointsCheckBox.getValue());
|
||||
result.setShowOnlySelectedCompetitors(showOnlySelectedCompetitorsCheckBox.getValue());
|
||||
result.setShowWindStreamletOverlay(showWindStreamletOverlayCheckbox.getValue());
|
||||
result.setShowWindStreamletColors(showWindStreamletColorsCheckbox.getValue());
|
||||
result.setShowMapControls(initialSettings.isShowMapControls());
|
||||
if (isSimulationEnabled) {
|
||||
result.setShowSimulationOverlay(showSimulationOverlayCheckbox.getValue());
|
||||
} else {
|
||||
result.setShowSimulationOverlay(false);
|
||||
}
|
||||
result.setWindUp(windUpCheckbox.getValue());
|
||||
result.setShowSelectedCompetitorsInfo(showSelectedCompetitorsInfoCheckBox.getValue());
|
||||
if (helpLinesSettings.isVisible(HelpLineTypes.BOATTAILS)) {
|
||||
result.setTailLengthInMilliseconds(tailLengthBox.getValue() == null ? -1 : tailLengthBox.getValue() * 1000l);
|
||||
}
|
||||
if (helpLinesSettings.isVisible(HelpLineTypes.BUOYZONE)) {
|
||||
final Double value = buoyZoneRadiusBox.getValue();
|
||||
if (value != null) {
|
||||
result.setBuoyZoneRadiusInMeters(value);
|
||||
if (p.getA().getValue() == true) {
|
||||
maneuverTypesToShow.add(p.getB());
|
||||
}
|
||||
}
|
||||
result.setTransparentHoverlines(transparentHoverlines.getValue());
|
||||
result.setHoverlineStrokeWeight(hoverlineStrokeWeight.getValue());
|
||||
return result;
|
||||
RaceMapHelpLinesSettings helpLinesSettings = getHelpLinesSettings();
|
||||
RaceMapZoomSettings zoomSettings = getZoomSettings();
|
||||
|
||||
boolean showSimulationOverlay = isSimulationEnabled ? showSimulationOverlayCheckbox.getValue() : false;
|
||||
long tailLengthInMilliseconds = initialSettings.getTailLengthInMilliseconds();
|
||||
if (helpLinesSettings.isVisible(HelpLineTypes.BOATTAILS)) {
|
||||
tailLengthInMilliseconds = tailLengthBox.getValue() == null ? -1 : tailLengthBox.getValue() * 1000l;
|
||||
}
|
||||
|
||||
double buoyZoneRadiusInMeters = initialSettings.getBuoyZoneRadiusInMeters();
|
||||
if (helpLinesSettings.isVisible(HelpLineTypes.BUOYZONE) && buoyZoneRadiusBox.getValue() != null) {
|
||||
buoyZoneRadiusInMeters = buoyZoneRadiusBox.getValue();
|
||||
}
|
||||
|
||||
return new RaceMapSettings(zoomSettings, helpLinesSettings,
|
||||
transparentHoverlines.getValue(), hoverlineStrokeWeight.getValue(), tailLengthInMilliseconds, windUpCheckbox.getValue(),
|
||||
buoyZoneRadiusInMeters, showOnlySelectedCompetitorsCheckBox.getValue(), showSelectedCompetitorsInfoCheckBox.getValue(),
|
||||
showWindStreamletColorsCheckbox.getValue(), showWindStreamletOverlayCheckbox.getValue(), showSimulationOverlay,
|
||||
initialSettings.isShowMapControls(), maneuverTypesToShow, showDouglasPeuckerPointsCheckBox.getValue());
|
||||
}
|
||||
|
||||
private RaceMapZoomSettings getZoomSettings() {
|
||||
|
||||
+8
-18
@@ -30,23 +30,23 @@ public class RaceMapZoomSettings {
|
||||
}
|
||||
};
|
||||
|
||||
private Iterable<ZoomTypes> typesToConsiderOnZoom;
|
||||
private boolean zoomToSelectedCompetitors;
|
||||
private final List<ZoomTypes> typesToConsiderOnZoom;
|
||||
private final boolean zoomToSelectedCompetitors;
|
||||
|
||||
/**
|
||||
* Creates new RaceMapZoomSettings with the {@link ZoomTypes} <code>BOATS</code> and <code>TAILS</code>.<br />
|
||||
* Creates default RaceMapZoomSettings with the {@link ZoomTypes} <code>BUOYS</code>.<br />
|
||||
* The attribute <code>zoomToSelectedCompetitors</code> will be <code>false</code>.
|
||||
*/
|
||||
public RaceMapZoomSettings() {
|
||||
final List<ZoomTypes> myTypesToConsiderOnZoom = new ArrayList<>();
|
||||
typesToConsiderOnZoom = myTypesToConsiderOnZoom;
|
||||
typesToConsiderOnZoom = new ArrayList<>();
|
||||
// Other zoom types such as BOATS, TAILS or WINDSENSORS are not currently used as default zoom types.
|
||||
myTypesToConsiderOnZoom.add(ZoomTypes.BUOYS);
|
||||
typesToConsiderOnZoom.add(ZoomTypes.BUOYS);
|
||||
zoomToSelectedCompetitors = false;
|
||||
}
|
||||
|
||||
public RaceMapZoomSettings(Iterable<ZoomTypes> typesToConsiderOnZoom, boolean zoomToSelected) {
|
||||
this.typesToConsiderOnZoom = typesToConsiderOnZoom;
|
||||
public RaceMapZoomSettings(Iterable<ZoomTypes> typesToConsider, boolean zoomToSelected) {
|
||||
this.typesToConsiderOnZoom = new ArrayList<>();
|
||||
Util.addAll(typesToConsider, this.typesToConsiderOnZoom);
|
||||
this.zoomToSelectedCompetitors = zoomToSelected;
|
||||
}
|
||||
|
||||
@@ -73,16 +73,6 @@ public class RaceMapZoomSettings {
|
||||
return typesToConsiderOnZoom;
|
||||
}
|
||||
|
||||
public void setTypesToConsiderOnZoom(Iterable<ZoomTypes> typesToConsiderOnZoom) {
|
||||
List<ZoomTypes> newTypesToConsiderOnZoom = new ArrayList<>();
|
||||
Util.addAll(typesToConsiderOnZoom, newTypesToConsiderOnZoom);
|
||||
this.typesToConsiderOnZoom = newTypesToConsiderOnZoom;
|
||||
}
|
||||
|
||||
public void setZoomToSelectedCompetitors(boolean zoomToSelectedCompetitors) {
|
||||
this.zoomToSelectedCompetitors = zoomToSelectedCompetitors;
|
||||
}
|
||||
|
||||
public boolean isZoomToSelectedCompetitors() {
|
||||
return zoomToSelectedCompetitors;
|
||||
}
|
||||
|
||||
+12
-13
@@ -7,7 +7,6 @@ import com.google.gwt.i18n.client.NumberFormat;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
|
||||
/**
|
||||
* A true north indicator that can be added as a control to the map. Clicking / tapping the control toggles
|
||||
@@ -44,18 +43,18 @@ public class TrueNorthIndicatorPanel extends FlowPanel {
|
||||
canvas.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
// a bit clumsy, but there is no copy constructor on RaceMapSettings, and the RaceMapSettingsDialogComponent
|
||||
// class has all we need to clone a RaceMapSettings object, without showing it
|
||||
final RaceMapSettingsDialogComponent settingsCloner = new RaceMapSettingsDialogComponent(map.getSettings(), stringMessages, /* showViewSimulation */true);
|
||||
settingsCloner.getAdditionalWidget(new DataEntryDialog<RaceMapSettings>("dummy", "dummy", "OK", "Cancel", /* validator */null, /* callback */null) {
|
||||
@Override
|
||||
protected RaceMapSettings getResult() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
final RaceMapSettings newSettings = settingsCloner.getResult();
|
||||
newSettings.setWindUp(!newSettings.isWindUp());
|
||||
map.updateSettings(newSettings);
|
||||
RaceMapSettings oldRaceMapSettings = map.getSettings();
|
||||
boolean newWindUpSettings = !oldRaceMapSettings.isWindUp();
|
||||
|
||||
final RaceMapSettings newRaceMapSettings = new RaceMapSettings(oldRaceMapSettings.getZoomSettings(),
|
||||
oldRaceMapSettings.getHelpLinesSettings(), oldRaceMapSettings.getTransparentHoverlines(),
|
||||
oldRaceMapSettings.getHoverlineStrokeWeight(), oldRaceMapSettings.getTailLengthInMilliseconds(), newWindUpSettings,
|
||||
oldRaceMapSettings.getBuoyZoneRadiusInMeters(), oldRaceMapSettings.isShowOnlySelectedCompetitors(),
|
||||
oldRaceMapSettings.isShowSelectedCompetitorsInfo(), oldRaceMapSettings.isShowWindStreamletColors(),
|
||||
oldRaceMapSettings.isShowWindStreamletOverlay(), oldRaceMapSettings.isShowSimulationOverlay(),
|
||||
oldRaceMapSettings.isShowMapControls(), oldRaceMapSettings.getManeuverTypesToShow(),
|
||||
oldRaceMapSettings.isShowDouglasPeuckerPoints());
|
||||
map.updateSettings(newRaceMapSettings);
|
||||
}
|
||||
});
|
||||
textLabel = new Label("");
|
||||
|
||||
+30
-18
@@ -63,8 +63,6 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
private static final String PARAM_FLEET_NAME = "fleetName";
|
||||
private static final String PARAM_SHOW_COMPETITORS = "showCompetitors";
|
||||
private static final String PARAM_PLAY = "play";
|
||||
private static final String PARAM_SHOW_COURSE_GEOMETRY = "showCourseGeometry";
|
||||
private static final String PARAM_MAP_ORIENTATION_WIND_UP = "windUp";
|
||||
|
||||
private String regattaLikeName;
|
||||
private String raceColumnName;
|
||||
@@ -88,12 +86,36 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
}
|
||||
|
||||
// read optional parameters
|
||||
final RaceBoardPerspectiveSettings raceboardPerspectiveSettings = RaceBoardPerspectiveSettings.readSettingsFromURL();
|
||||
final RaceMapSettings raceMapSettings = RaceMapSettings.readSettingsFromURL();
|
||||
final RaceBoardPerspectiveSettings raceboardPerspectiveSettings = RaceBoardPerspectiveSettings
|
||||
.readSettingsFromURL(/* defaultForViewShowLeaderboard */ true, /* defaultForViewShowWindchart */ true,
|
||||
/* defaultForViewSimulationEnabled */ false, /* defaultForViewShowCompetitorsChart */ false,
|
||||
/* defaultForViewCompetitorFilter */ null, /* defaultForCanReplayDuringLiveRaces */ false);
|
||||
final RaceMapSettings defaultRaceMapSettings = RaceMapSettings.readSettingsFromURL(
|
||||
/* defaultForShowMapControls */ true, /* defaultForShowCourseGeometry */ true,
|
||||
/* defaultForMapOrientationWindUp */ true, /* defaultForViewShowStreamlets */ false,
|
||||
/* defaultForViewShowStreamletColors */ false, /* defaultForViewShowSimulation */ false);
|
||||
final boolean showCompetitors = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_COMPETITORS, false /* default */);
|
||||
final boolean play = GwtHttpRequestUtils.getBooleanParameter(PARAM_PLAY, false /* default */);
|
||||
final boolean showCourseGeometry = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_COURSE_GEOMETRY, true /* default */);
|
||||
final boolean windUp = GwtHttpRequestUtils.getBooleanParameter(PARAM_MAP_ORIENTATION_WIND_UP, true /* default */);
|
||||
final boolean showCourseGeometry = GwtHttpRequestUtils.getBooleanParameter(RaceMapSettings.PARAM_SHOW_COURSE_GEOMETRY, true /* default */);
|
||||
final boolean windUp = GwtHttpRequestUtils.getBooleanParameter(RaceMapSettings.PARAM_MAP_ORIENTATION_WIND_UP, true /* default */);
|
||||
|
||||
RaceMapZoomSettings raceMapZoomSettings = new RaceMapZoomSettings(Arrays.asList(ZoomTypes.BUOYS), /* zoom to selection */ false);
|
||||
Set<HelpLineTypes> helpLineTypes = new HashSet<>();
|
||||
Util.addAll(defaultRaceMapSettings.getHelpLinesSettings().getVisibleHelpLineTypes(), helpLineTypes);
|
||||
if (showCourseGeometry) {
|
||||
helpLineTypes.add(HelpLineTypes.COURSEGEOMETRY);
|
||||
}
|
||||
RaceMapHelpLinesSettings raceMapHelpLinesSettings = new RaceMapHelpLinesSettings(helpLineTypes);
|
||||
|
||||
final RaceMapSettings raceMapSettings = new RaceMapSettings(raceMapZoomSettings, raceMapHelpLinesSettings,
|
||||
defaultRaceMapSettings.getTransparentHoverlines(), defaultRaceMapSettings.getHoverlineStrokeWeight(),
|
||||
defaultRaceMapSettings.getTailLengthInMilliseconds(), windUp,
|
||||
defaultRaceMapSettings.getBuoyZoneRadiusInMeters(), defaultRaceMapSettings.isShowOnlySelectedCompetitors(),
|
||||
defaultRaceMapSettings.isShowSelectedCompetitorsInfo(), defaultRaceMapSettings.isShowWindStreamletColors(),
|
||||
defaultRaceMapSettings.isShowWindStreamletOverlay(), defaultRaceMapSettings.isShowSimulationOverlay(),
|
||||
defaultRaceMapSettings.isShowMapControls(), defaultRaceMapSettings.getManeuverTypesToShow(),
|
||||
defaultRaceMapSettings.isShowDouglasPeuckerPoints());
|
||||
|
||||
sailingService.getRaceIdentifier(regattaLikeName, raceColumnName, fleetName, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
@Override
|
||||
public void onSuccess(final RegattaAndRaceIdentifier selectedRaceIdentifier) {
|
||||
@@ -104,7 +126,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
@Override
|
||||
public void onSuccess(Map<CompetitorDTO, BoatDTO> result) {
|
||||
createEmbeddedMap(selectedRaceIdentifier, result, raceboardPerspectiveSettings, raceMapSettings,
|
||||
showCompetitors, play, showCourseGeometry, windUp);
|
||||
showCompetitors, play);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,7 +155,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
|
||||
private void createEmbeddedMap(final RegattaAndRaceIdentifier selectedRaceIdentifier, Map<CompetitorDTO, BoatDTO> competitorBoats,
|
||||
final RaceBoardPerspectiveSettings raceboardPerspectiveSettings, final RaceMapSettings raceMapSettings,
|
||||
final boolean showCompetitors, final boolean play, final boolean showCourseGeometry, final boolean windUp) {
|
||||
final boolean showCompetitors, final boolean play) {
|
||||
final StringBuilder title = new StringBuilder(regattaLikeName);
|
||||
title.append('/');
|
||||
title.append(raceColumnName);
|
||||
@@ -184,16 +206,6 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
map.setControls(ControlPosition.RIGHT_BOTTOM, backToLivePlayButton);
|
||||
}
|
||||
};
|
||||
final RaceMapSettings mapSettings = new RaceMapSettings(raceMap.getSettings());
|
||||
mapSettings.setZoomSettings(new RaceMapZoomSettings(Arrays.asList(ZoomTypes.BUOYS), /* zoom to selection */ false));
|
||||
if (showCourseGeometry) {
|
||||
Set<HelpLineTypes> helpLineTypes = new HashSet<>();
|
||||
Util.addAll(mapSettings.getHelpLinesSettings().getVisibleHelpLineTypes(), helpLineTypes);
|
||||
helpLineTypes.add(HelpLineTypes.COURSEGEOMETRY);
|
||||
mapSettings.setHelpLinesSettings(new RaceMapHelpLinesSettings(helpLineTypes));
|
||||
}
|
||||
mapSettings.setWindUp(windUp);
|
||||
raceMap.updateSettings(mapSettings);
|
||||
final WindChart windChart;
|
||||
if (raceboardPerspectiveSettings.isShowWindChart()) {
|
||||
windChart = new WindChart(new WindChartLifecycle(getStringMessages()), sailingService, selectedRaceIdentifier, timer,
|
||||
|
||||
+4
-1
@@ -75,7 +75,10 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
|
||||
// read perspective settings parameters from URL
|
||||
final RaceBoardPerspectiveSettings perspectiveSettings = RaceBoardPerspectiveSettings.readSettingsFromURL();
|
||||
final RaceBoardPerspectiveSettings perspectiveSettings = RaceBoardPerspectiveSettings.readSettingsFromURL(
|
||||
/* defaultForViewShowLeaderboard */ true, /* defaultForViewShowWindchart */ false,
|
||||
/* defaultForViewSimulationEnabled */ false, /* defaultForViewShowCompetitorsChart */ false,
|
||||
/* defaultForViewCompetitorFilter */ null, /* defaultForCanReplayDuringLiveRaces */ false);
|
||||
// Determine if the charts, such as the competitor chart or the wind chart, the edit marks
|
||||
// panels, such as mark passing and mark position editors and manage media buttons should be shown.
|
||||
// Automatic selection of attached video (if any) also depends on this flag.
|
||||
|
||||
+10
-7
@@ -74,13 +74,16 @@ public class RaceBoardPerspectiveSettings extends AbstractSettings {
|
||||
return canReplayDuringLiveRaces;
|
||||
}
|
||||
|
||||
public static RaceBoardPerspectiveSettings readSettingsFromURL() {
|
||||
final boolean showLeaderboard = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_LEADERBOARD, true /* default */);
|
||||
final boolean showWindChart = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_WINDCHART, false /* default */);
|
||||
final boolean simulationEnabled = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SIMULATION_ENABLED, false /* default */);
|
||||
final boolean showCompetitorsChart = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_COMPETITORSCHART, false /* default */);
|
||||
String activeCompetitorsFilterSetName = GwtHttpRequestUtils.getStringParameter(PARAM_VIEW_COMPETITOR_FILTER, null /* default */);
|
||||
final boolean canReplayWhileLiveIsPossible = GwtHttpRequestUtils.getBooleanParameter(PARAM_CAN_REPLAY_DURING_LIVE_RACES, false /* default */);
|
||||
public static RaceBoardPerspectiveSettings readSettingsFromURL(boolean defaultForViewShowLeaderboard,
|
||||
boolean defaultForViewShowWindchart, boolean defaultForViewSimulationEnabled,
|
||||
boolean defaultForViewShowCompetitorsChart, String defaultForViewCompetitorFilter,
|
||||
boolean defaultForCanReplayDuringLiveRaces) {
|
||||
final boolean showLeaderboard = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_LEADERBOARD, defaultForViewShowLeaderboard /* default */);
|
||||
final boolean showWindChart = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_WINDCHART, defaultForViewShowWindchart /* default */);
|
||||
final boolean simulationEnabled = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SIMULATION_ENABLED, defaultForViewSimulationEnabled /* default */);
|
||||
final boolean showCompetitorsChart = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_COMPETITORSCHART, defaultForViewShowCompetitorsChart /* default */);
|
||||
String activeCompetitorsFilterSetName = GwtHttpRequestUtils.getStringParameter(PARAM_VIEW_COMPETITOR_FILTER, defaultForViewCompetitorFilter /* default */);
|
||||
final boolean canReplayWhileLiveIsPossible = GwtHttpRequestUtils.getBooleanParameter(PARAM_CAN_REPLAY_DURING_LIVE_RACES, defaultForCanReplayDuringLiveRaces /* default */);
|
||||
|
||||
final Duration initialDurationAfterRaceStartInReplay = parseDuration(GwtHttpRequestUtils.getStringParameter(
|
||||
PARAM_TIME_AFTER_RACE_START_AS_HOURS_COLON_MILLIS_COLON_SECONDS, null /* default */));
|
||||
|
||||
+1
-1
@@ -389,7 +389,7 @@ public class WindFragment extends BaseFragment implements CompassDirectionListen
|
||||
WebSettings settings = mMapWebView.getSettings();
|
||||
if (showMap) {
|
||||
settings.setJavaScriptEnabled(true);
|
||||
loadRaceMap(true, false, false, true);
|
||||
loadRaceMap(/* showWindCharts */ true, /* showStreamlets */ false, /* showSimulation */ false, /* showMapControls */ true);
|
||||
mMapLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mMapWebView.loadUrl("about:blank");
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class WindHelper {
|
||||
return isTracked;
|
||||
}
|
||||
|
||||
public static String generateMapURL(Context context, ManagedRace race ,boolean showWindCharts, boolean showStreamlets, boolean showSimulation, boolean showMapControls){
|
||||
public static String generateMapURL(Context context, ManagedRace race, boolean showWindCharts, boolean showStreamlets, boolean showSimulation, boolean showMapControls) {
|
||||
ReadonlyDataManager dataManager = OnlineDataManager.create(context);
|
||||
return dataManager.getMapUrl(AppPreferences.on(context).getServerBaseURL(), race, getEventId(context), showWindCharts, showStreamlets, showSimulation, showMapControls);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user