mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-15 06:49:56 +00:00
Merge remote-tracking branch 'origin/master' into 60_inch
This commit is contained in:
commit
8da357fb9c
15 files changed
+377
-711
No files matched your search
+22
-4
@@ -65,6 +65,7 @@ import com.tractrac.subscription.lib.api.ISubscriberFactory;
|
||||
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
|
||||
import com.tractrac.subscription.lib.api.SubscriptionLocator;
|
||||
import com.tractrac.subscription.lib.api.competitor.ICompetitorsListener;
|
||||
import com.tractrac.subscription.lib.api.control.IControlsListener;
|
||||
import com.tractrac.subscription.lib.api.event.IConnectionStatusListener;
|
||||
import com.tractrac.subscription.lib.api.event.ILiveDataEvent;
|
||||
import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
|
||||
@@ -194,6 +195,9 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
private final com.sap.sailing.domain.base.Regatta regatta;
|
||||
private final IEventSubscriber eventSubscriber;
|
||||
private final IRaceSubscriber raceSubscriber;
|
||||
private final IRacesListener racesListener;
|
||||
private final IControlsListener controlsListener;
|
||||
private final ICompetitorsListener competitorsListener;
|
||||
private final Set<Receiver> receivers;
|
||||
private final DomainFactory domainFactory;
|
||||
private final WindStore windStore;
|
||||
@@ -331,7 +335,16 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
// Initialize data controller using live and stored data sources
|
||||
ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
|
||||
eventSubscriber = subscriberFactory.createEventSubscriber(tractracEvent, liveURI, effectifeStoredURI);
|
||||
eventSubscriber.subscribeCompetitors(new ICompetitorsListener() {
|
||||
controlsListener = new IControlsListener() {
|
||||
@Override
|
||||
public void updateControl(IControl control) {}
|
||||
@Override
|
||||
public void deleteControl(UUID controlId) {}
|
||||
@Override
|
||||
public void addControl(IControl control) {}
|
||||
};
|
||||
eventSubscriber.subscribeControls(controlsListener);
|
||||
competitorsListener = new ICompetitorsListener() {
|
||||
@Override
|
||||
public void updateCompetitor(ICompetitor competitor) {
|
||||
if (!competitor.isNonCompeting()) {
|
||||
@@ -349,8 +362,9 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
@Override
|
||||
public void addCompetitor(ICompetitor competitor) {
|
||||
}
|
||||
});
|
||||
eventSubscriber.subscribeRaces(new IRacesListener() {
|
||||
};
|
||||
eventSubscriber.subscribeCompetitors(competitorsListener);
|
||||
racesListener = new IRacesListener() {
|
||||
@Override public void abandonRace(UUID raceId) {}
|
||||
@Override public void addRace(IRace race) {}
|
||||
@Override public void deleteRace(UUID raceId) {}
|
||||
@@ -369,7 +383,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
eventSubscriber.subscribeRaces(racesListener);
|
||||
// Start live and stored data streams
|
||||
final Regatta effectiveRegatta;
|
||||
raceSubscriber = subscriberFactory.createRaceSubscriber(tractracRace, liveURI, effectifeStoredURI);
|
||||
@@ -532,6 +547,9 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
protected void onStop(boolean stopReceiversPreemtively) throws InterruptedException {
|
||||
if (!stopped) {
|
||||
stopped = true;
|
||||
eventSubscriber.unsubscribeRaces(racesListener);
|
||||
eventSubscriber.unsubscribeCompetitors(competitorsListener);
|
||||
eventSubscriber.unsubscribeControls(controlsListener);
|
||||
raceSubscriber.stop();
|
||||
eventSubscriber.stop();
|
||||
raceSubscriber.unsubscribeConnectionStatus(this);
|
||||
|
||||
+6
-1
@@ -453,7 +453,12 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
} else {
|
||||
Distance distanceToNextMark = getTrackedRace().getTrackedLeg(leg)
|
||||
.getAbsoluteWindwardDistance(currentPosition, nextMarkPosition, timePoint, windPositionMode, cache);
|
||||
result = new MeterDistance(result.getMeters() + distanceToNextMark.getMeters());
|
||||
if (distanceToNextMark != null) {
|
||||
result = new MeterDistance(result.getMeters() + distanceToNextMark.getMeters());
|
||||
} else {
|
||||
result = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentPosition = nextMarkPosition;
|
||||
} else {
|
||||
|
||||
+55
@@ -4,6 +4,61 @@
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Analytics</h4>
|
||||
<div class="innerContent">
|
||||
|
||||
<h5 class="articleSubheadline">May 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>It's now possible to show nationality flags in addition to competitor images in leaderboards if both are available.
|
||||
If no competitor images are available, this won't have any effect.
|
||||
You can activate this option through the leaderboard settings dialog to be found in various views.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Several pages are now enabled to save user settings. In settings dialogs there is a "Make default"
|
||||
button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
|
||||
button causes the system to use the new settings as default values for the same page for any other context opened, e.g. another event.
|
||||
A click on OK button causes the system to store current settings for the current context and restore the same settings
|
||||
when the user opens the page with the same context again unless there are specific parameters given by the URL. Settings saved this way are
|
||||
stored locally in the browser's local storage and in the user profile if you are logged in.
|
||||
Some settings are only valid in a specific context (e.g. the selected race columns to show are stored for a specific leaderboard only).
|
||||
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
|
||||
Affected pages:
|
||||
<ul>
|
||||
<li><code>/gwt/Leaderboard.html</code></li>
|
||||
<li><code>/gwt/RegattaOverview.html</code></li>
|
||||
<li>Leaderboards embedded in <code>/gwt/Home.html</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The maneuver loss calculation for penalty circles has been improved. Previously, the end of the
|
||||
penalty circle maneuver was considered to be at the last of the two adjacent tack/gybe maneuvers.
|
||||
This, usually, is earlier than when approaching the course over ground at the beginning of the
|
||||
penalty circle again. With this, the extrapolation of the speed/course at the beginning of
|
||||
the maneuver did not last long enough. Furthermore, penalties with strong accelerations during
|
||||
the gybing phase could have led to an incorrect inference of the speed and course at the
|
||||
beginning of the maneuver. Both of these issues have now been fixed, leading to good results
|
||||
also in very specific and unusual speed developments during a penalty circle maneuver.
|
||||
</li>
|
||||
<li>The advantage line display has been fixed for legs changing their type (upwind/downwind/reach)
|
||||
while the race is going on. It now uses the leg type at the same current time point that the
|
||||
leaderboard uses for calculating the competitor ranking.
|
||||
</li>
|
||||
<li>Images in the overall image gallery ("Photographers love Sailing") are now linked with the
|
||||
events to which they belong. Clicking the image navigates to the event page.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The SAP Sailing Analytics are now also available in French, Portugese, as well as Spanish.
|
||||
Find the language chooser in the lower right corner of the footer, or when signed in, go to your user
|
||||
profile and set your preferred language.
|
||||
</li>
|
||||
<li>The application's locale now switches based on the client's "Accept-Language" HTTP header field.
|
||||
This means that the application in all its parts will show in the user's default language if
|
||||
supported, defaulting to English otherwise.
|
||||
</li>
|
||||
</ul>
|
||||
<h5 class="articleSubheadline">February 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The definition of "ride height" for foiling sensors has been changed. Instead of showing
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class BoatClassVectorGraphicsResolver {
|
||||
BoatClassMasterdata.D_35, BoatClassMasterdata.SKUD_18, BoatClassMasterdata.WETA);
|
||||
BoatClassVectorGraphics gc32 = new GC32VectorGraphics(BoatClassMasterdata.GC_32, BoatClassMasterdata.M32);
|
||||
BoatClassVectorGraphics smallMultihull = new SmallMultihullVectorGraphics(BoatClassMasterdata.NACRA_17,
|
||||
BoatClassMasterdata.F_16, BoatClassMasterdata.F_18, BoatClassMasterdata.HOBIE_WILD_CAT,
|
||||
BoatClassMasterdata.F_16, BoatClassMasterdata.F_18, BoatClassMasterdata.HOBIE_WILD_CAT, BoatClassMasterdata.HOBIE_16,
|
||||
BoatClassMasterdata.HOBIE_TIGER, BoatClassMasterdata.A_CAT, BoatClassMasterdata.TORNADO,
|
||||
BoatClassMasterdata.FLYING_PHANTOM);
|
||||
BoatClassVectorGraphics keelBoatWithGennaker = new KeelBoatWithGennakerVectorGraphics(BoatClassMasterdata.J70,
|
||||
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.client.NumberFormatterFactory;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.QuickRanksDTOProvider.QuickRanksListener;
|
||||
import com.sap.sailing.gwt.ui.shared.GPSFixDTOWithSpeedWindTackAndLegType;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
|
||||
/**
|
||||
* Manages the collection of all {@link CompetitorInfoOverlay} objects shown in the {@link RaceMap}. In particular, it
|
||||
* keeps track of the information used for the text in the overlays and allows for incremental updates, e.g., if a
|
||||
* competitor's rank has been updated. It can act as a {@link QuickRanksListener} and as such be subscribed for rank
|
||||
* changes, e.g., with a {@link QuickRanksDTOProvider}. It will track all rank updates for any competitor whose info
|
||||
* overlay is managed by this instance.
|
||||
* <p>
|
||||
*
|
||||
* Competitor positions are expected to be explicitly announced by calling
|
||||
* {@link #updatePosition(CompetitorDTO, GPSFixDTOWithSpeedWindTackAndLegType, long)} in case new position data is
|
||||
* known.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorInfoOverlays implements QuickRanksListener {
|
||||
private final RaceMap raceMap;
|
||||
|
||||
/**
|
||||
* html5 canvases used for competitor info display on the map; keys are the competitor IDs as strings
|
||||
*/
|
||||
private final Map<String, CompetitorInfoOverlay> competitorInfoOverlays;
|
||||
|
||||
/**
|
||||
* keys are the competitor IDs as strings
|
||||
*/
|
||||
private final Map<String, Integer> ranks;
|
||||
|
||||
/**
|
||||
* keys are the competitor IDs as strings
|
||||
*/
|
||||
private final Map<String, GPSFixDTOWithSpeedWindTackAndLegType> lastPositions;
|
||||
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
public CompetitorInfoOverlays(RaceMap raceMap, final StringMessages stringMessages) {
|
||||
competitorInfoOverlays = new HashMap<>();
|
||||
ranks = new HashMap<>();
|
||||
lastPositions = new HashMap<>();
|
||||
this.stringMessages = stringMessages;
|
||||
this.raceMap = raceMap;
|
||||
}
|
||||
|
||||
public CompetitorInfoOverlay createCompetitorInfoOverlay(int zIndex, final CompetitorDTO competitorDTO, GPSFixDTOWithSpeedWindTackAndLegType gpsFixDTO, Integer rank, long timeForPositionTransitionMillis) {
|
||||
CompetitorInfoOverlay result = new CompetitorInfoOverlay(raceMap.getMap(), zIndex,
|
||||
raceMap.getCompetitorSelection().getColor(competitorDTO, raceMap.getRaceIdentifier()),
|
||||
/* info text */ "", raceMap.getCoordinateSystem());
|
||||
competitorInfoOverlays.put(competitorDTO.getIdAsString(), result);
|
||||
updatePosition(competitorDTO, gpsFixDTO, timeForPositionTransitionMillis);
|
||||
result.setInfoText(createInfoText(competitorDTO));
|
||||
updateRank(competitorDTO, rank);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the {@link CompetitorInfoOverlay} for the competitor specified as {@code competitorDTO} from the map and
|
||||
* from this structure.
|
||||
*/
|
||||
public void remove(final CompetitorDTO competitorDTO) {
|
||||
remove(competitorDTO.getIdAsString());
|
||||
}
|
||||
|
||||
public void remove(final String competitorIdAsString) {
|
||||
CompetitorInfoOverlay overlay = competitorInfoOverlays.remove(competitorIdAsString);
|
||||
if (overlay != null) {
|
||||
overlay.removeFromMap();
|
||||
}
|
||||
ranks.remove(competitorIdAsString);
|
||||
lastPositions.remove(competitorIdAsString);
|
||||
}
|
||||
|
||||
public CompetitorInfoOverlay get(final CompetitorDTO competitorDTO) {
|
||||
return competitorInfoOverlays.get(competitorDTO.getIdAsString());
|
||||
}
|
||||
|
||||
public Iterable<CompetitorInfoOverlay> getCompetitorInfoOverlays() {
|
||||
return competitorInfoOverlays.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates {@link #ranks} and re-draws the corresponding overlay
|
||||
*/
|
||||
public void updateRank(CompetitorDTO competitorDTO, Integer rank) {
|
||||
CompetitorInfoOverlay overlay = competitorInfoOverlays.get(competitorDTO.getIdAsString());
|
||||
if (overlay != null) {
|
||||
ranks.put(competitorDTO.getIdAsString(), rank);
|
||||
overlay.setInfoText(createInfoText(competitorDTO));
|
||||
overlay.draw();
|
||||
}
|
||||
}
|
||||
|
||||
private GPSFixDTOWithSpeedWindTackAndLegType getLastPosition(CompetitorDTO competitorDTO) {
|
||||
return lastPositions.get(competitorDTO.getIdAsString());
|
||||
}
|
||||
|
||||
public void removeTransitions() {
|
||||
for (CompetitorInfoOverlay infoOverlay : getCompetitorInfoOverlays()) {
|
||||
infoOverlay.removeCanvasPositionAndRotationTransition();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the competitor's position data and and, if the competitor has an overlay managed by this instance,
|
||||
* adjusts the overlay's position on the map using the transition timeout specified by
|
||||
* {@code timeForPositionTransitionMillis}.
|
||||
*/
|
||||
public void updatePosition(CompetitorDTO competitorDTO, GPSFixDTOWithSpeedWindTackAndLegType gpsFixDTO, long timeForPositionTransitionMillis) {
|
||||
lastPositions.put(competitorDTO.getIdAsString(), gpsFixDTO);
|
||||
CompetitorInfoOverlay overlay = competitorInfoOverlays.get(competitorDTO.getIdAsString());
|
||||
if (overlay != null) {
|
||||
overlay.setPosition(gpsFixDTO.position, timeForPositionTransitionMillis);
|
||||
overlay.draw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a text for the competitor info window for competitor {@code competitorDTO} based on the contents
|
||||
* of {@link #ranks} and {@link #lastPositions}. If no {@link #ranks} entry exists, no rank is shown. However,
|
||||
* a {@link #lastPosition} is required in order to produce the speed/course information.
|
||||
*/
|
||||
private String createInfoText(CompetitorDTO competitorDTO) {
|
||||
StringBuilder infoText = new StringBuilder();
|
||||
infoText.append(competitorDTO.getSailID()).append("\n");
|
||||
infoText.append(NumberFormatterFactory.getDecimalFormat(1).format(getLastPosition(competitorDTO).speedWithBearing.speedInKnots))
|
||||
.append(" ").append(stringMessages.knotsUnit()).append("\n");
|
||||
final Integer rank = ranks.get(competitorDTO.getIdAsString());
|
||||
if (rank != null && rank != 0) {
|
||||
infoText.append(stringMessages.rank()).append(" : ").append(rank);
|
||||
}
|
||||
return infoText.toString();
|
||||
}
|
||||
|
||||
public Iterable<String> getCompetitorIdsAsStrings() {
|
||||
return Collections.unmodifiableCollection(competitorInfoOverlays.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all overlays managed by this structure from the map and from this structure
|
||||
*/
|
||||
public void clear() {
|
||||
for (final Iterator<Entry<String, CompetitorInfoOverlay>> i=competitorInfoOverlays.entrySet().iterator(); i.hasNext(); ) {
|
||||
final Entry<String, CompetitorInfoOverlay> e = i.next();
|
||||
e.getValue().removeFromMap();
|
||||
i.remove();
|
||||
}
|
||||
lastPositions.clear();
|
||||
ranks.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param quickRanks
|
||||
* uses the {@link QuickRankDTO#oneBasedRank} and {@link QuickRankDTO#competitor} fields
|
||||
*/
|
||||
@Override
|
||||
public void rankChanged(String competitorIdAsString, QuickRankDTO quickRanks) {
|
||||
final CompetitorInfoOverlay competitorInfoOverlay = competitorInfoOverlays.get(competitorIdAsString);
|
||||
ranks.put(competitorIdAsString, quickRanks.oneBasedRank);
|
||||
if (competitorInfoOverlay != null) {
|
||||
competitorInfoOverlay.setInfoText(createInfoText(quickRanks.competitor));
|
||||
competitorInfoOverlay.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -1,15 +1,20 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.sap.sailing.gwt.ui.raceboard.AbstractQuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
|
||||
public class DefaultQuickRanksDTOProvider implements QuickRanksDTOProvider {
|
||||
public class DefaultQuickRanksDTOProvider extends AbstractQuickRanksDTOProvider {
|
||||
private LinkedHashMap<String, QuickRankDTO> quickRanksFromServer;
|
||||
|
||||
@Override
|
||||
public void quickRanksReceivedFromServer(LinkedHashMap<String, QuickRankDTO> quickRanksFromServer) {
|
||||
this.quickRanksFromServer = quickRanksFromServer;
|
||||
for (final Entry<String, QuickRankDTO> e : quickRanksFromServer.entrySet()) {
|
||||
notifyListeners(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
@@ -23,6 +23,14 @@ import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO;
|
||||
*
|
||||
*/
|
||||
public interface QuickRanksDTOProvider {
|
||||
public interface QuickRanksListener {
|
||||
void rankChanged(String competitorIdAsString, QuickRankDTO quickRanks);
|
||||
}
|
||||
|
||||
void addQuickRanksListener(QuickRanksListener listener);
|
||||
|
||||
void removeQuickRanksListener(QuickRanksListener listener);
|
||||
|
||||
/**
|
||||
* The strategy may or may not use this quick ranks information provided directly from the server. This information
|
||||
* may have been provided with some delay and may be slightly inconsistent with a {@link LeaderboardDTO leaderboard}
|
||||
|
||||
+26
-41
@@ -269,7 +269,7 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
/**
|
||||
* html5 canvases used for competitor info display on the map
|
||||
*/
|
||||
private final Map<CompetitorDTO, CompetitorInfoOverlay> competitorInfoOverlays;
|
||||
private final CompetitorInfoOverlays competitorInfoOverlays;
|
||||
|
||||
private SmallTransparentInfoOverlay countDownOverlay;
|
||||
|
||||
@@ -431,7 +431,8 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
courseMiddleLines = new HashMap<>();
|
||||
infoOverlaysForLinesForCourseGeometry = new HashMap<>();
|
||||
boatOverlays = new HashMap<CompetitorDTO, BoatOverlay>();
|
||||
competitorInfoOverlays = new HashMap<CompetitorDTO, CompetitorInfoOverlay>();
|
||||
competitorInfoOverlays = new CompetitorInfoOverlays(this, stringMessages);
|
||||
quickRanksDTOProvider.addQuickRanksListener(competitorInfoOverlays);
|
||||
windSensorOverlays = new HashMap<WindSource, WindSensorOverlay>();
|
||||
courseMarkOverlays = new HashMap<String, CourseMarkOverlay>();
|
||||
courseMarkClickHandlers = new HashMap<String, HandlerRegistration>();
|
||||
@@ -741,9 +742,7 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
boatOverlay.removeCanvasPositionAndRotationTransition();
|
||||
}
|
||||
// remove the canvas animations for the info overlays of the selected boats
|
||||
for (CompetitorInfoOverlay infoOverlay : competitorInfoOverlays.values()) {
|
||||
infoOverlay.removeCanvasPositionAndRotationTransition();
|
||||
}
|
||||
competitorInfoOverlays.removeTransitions();
|
||||
for (CourseMarkOverlay markOverlay : courseMarkOverlays.values()) {
|
||||
markOverlay.removeCanvasPositionAndRotationTransition();
|
||||
}
|
||||
@@ -761,6 +760,18 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
return Collections.unmodifiableMap(boatOverlays);
|
||||
}
|
||||
|
||||
protected CompetitorSelectionProvider getCompetitorSelection() {
|
||||
return competitorSelection;
|
||||
}
|
||||
|
||||
protected Timer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
protected RegattaAndRaceIdentifier getRaceIdentifier() {
|
||||
return raceIdentifier;
|
||||
}
|
||||
|
||||
public MapWidget getMap() {
|
||||
return map;
|
||||
}
|
||||
@@ -1215,38 +1226,30 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
private void showCompetitorInfoOnMap(final Date newTime, final long timeForPositionTransitionMillis, final Iterable<CompetitorDTO> competitorsToShow) {
|
||||
if (map != null) {
|
||||
if (settings.isShowSelectedCompetitorsInfo()) {
|
||||
Set<CompetitorDTO> toRemoveCompetorInfoOverlays = new HashSet<CompetitorDTO>(
|
||||
competitorInfoOverlays.keySet());
|
||||
Set<String> toRemoveCompetorInfoOverlaysIdsAsStrings = new HashSet<>();
|
||||
Util.addAll(competitorInfoOverlays.getCompetitorIdsAsStrings(), toRemoveCompetorInfoOverlaysIdsAsStrings);
|
||||
for (CompetitorDTO competitorDTO : competitorsToShow) {
|
||||
if (fixesAndTails.hasFixesFor(competitorDTO)) {
|
||||
GPSFixDTOWithSpeedWindTackAndLegType lastBoatFix = getBoatFix(competitorDTO, newTime);
|
||||
if (lastBoatFix != null) {
|
||||
CompetitorInfoOverlay competitorInfoOverlay = competitorInfoOverlays.get(competitorDTO);
|
||||
final Integer rank = getRank(competitorDTO);
|
||||
if (competitorInfoOverlay == null) {
|
||||
competitorInfoOverlay = createCompetitorInfoOverlay(RaceMapOverlaysZIndexes.INFO_OVERLAY_ZINDEX, competitorDTO);
|
||||
competitorInfoOverlays.put(competitorDTO, competitorInfoOverlay);
|
||||
competitorInfoOverlay.setInfoText(createInfoText(competitorDTO, lastBoatFix));
|
||||
competitorInfoOverlay.setPosition(lastBoatFix.position, timeForPositionTransitionMillis);
|
||||
competitorInfoOverlay = competitorInfoOverlays.createCompetitorInfoOverlay(RaceMapOverlaysZIndexes.INFO_OVERLAY_ZINDEX, competitorDTO,
|
||||
lastBoatFix, rank, timeForPositionTransitionMillis);
|
||||
competitorInfoOverlay.addToMap();
|
||||
} else {
|
||||
competitorInfoOverlay.setInfoText(createInfoText(competitorDTO, lastBoatFix));
|
||||
competitorInfoOverlay.setPosition(lastBoatFix.position, timeForPositionTransitionMillis);
|
||||
competitorInfoOverlay.draw();
|
||||
competitorInfoOverlays.updatePosition(competitorDTO, lastBoatFix, timeForPositionTransitionMillis);
|
||||
}
|
||||
toRemoveCompetorInfoOverlays.remove(competitorDTO);
|
||||
toRemoveCompetorInfoOverlaysIdsAsStrings.remove(competitorDTO.getIdAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (CompetitorDTO toRemoveCompetorDTO : toRemoveCompetorInfoOverlays) {
|
||||
CompetitorInfoOverlay competitorInfoOverlay = competitorInfoOverlays.get(toRemoveCompetorDTO);
|
||||
competitorInfoOverlay.removeFromMap();
|
||||
competitorInfoOverlays.remove(toRemoveCompetorDTO);
|
||||
for (String toRemoveCompetitorOverlayIdAsString : toRemoveCompetorInfoOverlaysIdsAsStrings) {
|
||||
competitorInfoOverlays.remove(toRemoveCompetitorOverlayIdAsString);
|
||||
}
|
||||
} else {
|
||||
// remove all overlays
|
||||
for (CompetitorInfoOverlay competitorInfoOverlay : competitorInfoOverlays.values()) {
|
||||
competitorInfoOverlay.removeFromMap();
|
||||
}
|
||||
competitorInfoOverlays.clear();
|
||||
}
|
||||
}
|
||||
@@ -1966,23 +1969,6 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
}
|
||||
}
|
||||
|
||||
private CompetitorInfoOverlay createCompetitorInfoOverlay(int zIndex, final CompetitorDTO competitorDTO) {
|
||||
GPSFixDTOWithSpeedWindTackAndLegType gpsFixDTO = getBoatFix(competitorDTO, timer.getTime());
|
||||
return new CompetitorInfoOverlay(map, zIndex, competitorSelection.getColor(competitorDTO, raceIdentifier), createInfoText(competitorDTO, gpsFixDTO), coordinateSystem);
|
||||
}
|
||||
|
||||
private String createInfoText(CompetitorDTO competitorDTO, GPSFixDTOWithSpeedWindTackAndLegType gpsFixDTO) {
|
||||
StringBuilder infoText = new StringBuilder();
|
||||
infoText.append(competitorDTO.getSailID()).append("\n");
|
||||
infoText.append(NumberFormatterFactory.getDecimalFormat(1).format(gpsFixDTO.speedWithBearing.speedInKnots))
|
||||
.append(" ").append(stringMessages.knotsUnit()).append("\n");
|
||||
final Integer rank = getRank(competitorDTO);
|
||||
if (rank != null) {
|
||||
infoText.append(stringMessages.rank()).append(" : ").append(rank);
|
||||
}
|
||||
return infoText.toString();
|
||||
}
|
||||
|
||||
private BoatOverlay createBoatOverlay(int zIndex, final CompetitorDTO competitorDTO, boolean highlighted) {
|
||||
final BoatOverlay boatCanvas = new BoatOverlay(map, zIndex, competitorDTO, competitorSelection.getColor(competitorDTO, raceIdentifier), coordinateSystem);
|
||||
boatCanvas.setSelected(highlighted);
|
||||
@@ -2779,11 +2765,10 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
|
||||
@Override
|
||||
public Integer getRank(CompetitorDTO competitor) {
|
||||
// TODO bug4175: obtain from raceBoardPanel.leaderboardPanel.leaderboard instead of QuickRanks
|
||||
final Integer result;
|
||||
QuickRankDTO quickRank = quickRanksDTOProvider.getQuickRanks().get(competitor.getIdAsString());
|
||||
if (quickRank != null) {
|
||||
result = quickRank.rank;
|
||||
result = quickRank.oneBasedRank;
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.QuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
|
||||
public abstract class AbstractQuickRanksDTOProvider implements QuickRanksDTOProvider {
|
||||
private final Set<QuickRanksListener> listeners;
|
||||
|
||||
public AbstractQuickRanksDTOProvider() {
|
||||
listeners = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addQuickRanksListener(QuickRanksListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeQuickRanksListener(QuickRanksListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
protected void notifyListeners(String competitorIdAsString, QuickRankDTO quickRank) {
|
||||
for (QuickRanksListener listener : listeners) {
|
||||
listener.rankChanged(competitorIdAsString, quickRank);
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
-25
@@ -10,7 +10,6 @@ import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.QuickRanksDTOProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -25,7 +24,7 @@ import com.sap.sse.common.Util;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class QuickRanksDTOFromLeaderboardDTOProvider implements QuickRanksDTOProvider {
|
||||
public class QuickRanksDTOFromLeaderboardDTOProvider extends AbstractQuickRanksDTOProvider {
|
||||
private LinkedHashMap<String, QuickRankDTO> quickRanks;
|
||||
private final RaceCompetitorSet raceCompetitorSet;
|
||||
private final RaceIdentifier selectedRace;
|
||||
@@ -43,6 +42,7 @@ public class QuickRanksDTOFromLeaderboardDTOProvider implements QuickRanksDTOPro
|
||||
quickRanks = new LinkedHashMap<>();
|
||||
for (final Entry<String, QuickRankDTO> e : quickRanksFromServer.entrySet()) {
|
||||
quickRanks.put(e.getKey(), e.getValue());
|
||||
notifyListeners(e.getKey(), e.getValue());
|
||||
}
|
||||
} else if (!lastLeaderboardProvidedLegNumbers) {
|
||||
// extract at least the leg numbers and update existing quick ranks accordingly in place
|
||||
@@ -65,33 +65,44 @@ public class QuickRanksDTOFromLeaderboardDTOProvider implements QuickRanksDTOPro
|
||||
}
|
||||
if (raceColumnName != null) {
|
||||
final List<CompetitorDTO> competitorsFromBestToWorst = leaderboard.getCompetitorsFromBestToWorst(raceColumnName);
|
||||
int rank = 1;
|
||||
for (final CompetitorDTO c : competitorsFromBestToWorst) {
|
||||
if (Util.contains(raceCompetitorSet.getIdsOfCompetitorsParticipatingInRaceAsStrings(), c.getIdAsString())) {
|
||||
final LeaderboardRowDTO row = leaderboard.rows.get(c);
|
||||
final int oneBasedLegNumber;
|
||||
if (row != null) {
|
||||
final LeaderboardEntryDTO raceEntryForCompetitor = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (raceEntryForCompetitor != null && raceEntryForCompetitor.legDetails != null) {
|
||||
oneBasedLegNumber = raceEntryForCompetitor.getOneBasedCurrentLegNumber();
|
||||
lastLeaderboardProvidedLegNumbers = true;
|
||||
if (competitorsFromBestToWorst.isEmpty()) {
|
||||
for (CompetitorDTO c : leaderboard.competitors) {
|
||||
final QuickRankDTO quickRank = new QuickRankDTO(c, /* oneBasedRank */ 0, /* leg number ignored */ 0);
|
||||
quickRanks.put(c.getIdAsString(), quickRank);
|
||||
notifyListeners(c.getIdAsString(), quickRank);
|
||||
}
|
||||
} else {
|
||||
int oneBasedRank = 1;
|
||||
for (final CompetitorDTO c : competitorsFromBestToWorst) {
|
||||
if (Util.contains(raceCompetitorSet.getIdsOfCompetitorsParticipatingInRaceAsStrings(), c.getIdAsString())) {
|
||||
final LeaderboardRowDTO row = leaderboard.rows.get(c);
|
||||
final int oneBasedLegNumber;
|
||||
if (row != null) {
|
||||
final LeaderboardEntryDTO raceEntryForCompetitor = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (raceEntryForCompetitor != null && raceEntryForCompetitor.legDetails != null) {
|
||||
oneBasedLegNumber = raceEntryForCompetitor.getOneBasedCurrentLegNumber();
|
||||
lastLeaderboardProvidedLegNumbers = true;
|
||||
} else {
|
||||
oneBasedLegNumber = 0;
|
||||
lastLeaderboardProvidedLegNumbers = false;
|
||||
}
|
||||
} else {
|
||||
oneBasedLegNumber = 0;
|
||||
lastLeaderboardProvidedLegNumbers = false;
|
||||
}
|
||||
} else {
|
||||
oneBasedLegNumber = 0;
|
||||
}
|
||||
QuickRankDTO quickRankToUpdate = quickRanks.get(c.getIdAsString());
|
||||
if (quickRankToUpdate == null) {
|
||||
quickRanks.put(c.getIdAsString(), new QuickRankDTO(c, rank, oneBasedLegNumber));
|
||||
} else {
|
||||
quickRankToUpdate.rank = rank;
|
||||
if (lastLeaderboardProvidedLegNumbers) {
|
||||
quickRankToUpdate.legNumberOneBased = oneBasedLegNumber;
|
||||
QuickRankDTO quickRankToUpdate = quickRanks.get(c.getIdAsString());
|
||||
if (quickRankToUpdate == null) {
|
||||
final QuickRankDTO quickRankDTO = new QuickRankDTO(c, oneBasedRank, oneBasedLegNumber);
|
||||
quickRanks.put(c.getIdAsString(), quickRankDTO);
|
||||
notifyListeners(c.getIdAsString(), quickRankDTO);
|
||||
} else {
|
||||
quickRankToUpdate.oneBasedRank = oneBasedRank;
|
||||
if (lastLeaderboardProvidedLegNumbers) {
|
||||
quickRankToUpdate.legNumberOneBased = oneBasedLegNumber;
|
||||
}
|
||||
notifyListeners(c.getIdAsString(), quickRankToUpdate);
|
||||
}
|
||||
oneBasedRank++;
|
||||
}
|
||||
rank++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,5 +121,4 @@ public class QuickRanksDTOFromLeaderboardDTOProvider implements QuickRanksDTOPro
|
||||
public LinkedHashMap<String, QuickRankDTO> getQuickRanks() {
|
||||
return quickRanks;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -2229,17 +2229,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
actualTimePoint = timePoint;
|
||||
}
|
||||
final RaceDefinition race = trackedRace.getRace();
|
||||
int rank = 1;
|
||||
int oneBasedRank = 1;
|
||||
final List<Competitor> competitorsFromBestToWorst = trackedRace.getCompetitorsFromBestToWorst(actualTimePoint);
|
||||
for (Competitor competitor : competitorsFromBestToWorst) {
|
||||
TrackedLegOfCompetitor trackedLeg = trackedRace.getTrackedLeg(competitor, actualTimePoint);
|
||||
if (trackedLeg != null) {
|
||||
int legNumberOneBased = race.getCourse().getLegs().indexOf(trackedLeg.getLeg()) + 1;
|
||||
QuickRankDTO quickRankDTO = new QuickRankDTO(baseDomainFactory.convertToCompetitorDTO(competitor),
|
||||
rank, legNumberOneBased);
|
||||
oneBasedRank, legNumberOneBased);
|
||||
result.add(quickRankDTO);
|
||||
}
|
||||
rank++;
|
||||
oneBasedRank++;
|
||||
}
|
||||
}
|
||||
return new QuickRanksDTO(result);
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class CompactQuickRankDTO implements IsSerializable {
|
||||
return competitorIdAsString;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
public int getOneBasedRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
Map<String, Integer> competitorIdAsStringToOneBasedLegNumber = new HashMap<>();
|
||||
if (quickRanks != null) {
|
||||
for (QuickRankDTO quickRank : quickRanks.getQuickRanks()) {
|
||||
this.quickRanks.add(new CompactQuickRankDTO(quickRank.competitor.getIdAsString(), quickRank.rank,
|
||||
this.quickRanks.add(new CompactQuickRankDTO(quickRank.competitor.getIdAsString(), quickRank.oneBasedRank,
|
||||
quickRank.legNumberOneBased));
|
||||
competitorIdAsStringToOneBasedLegNumber.put(quickRank.competitor.getIdAsString(), quickRank.legNumberOneBased);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
||||
for (CompactQuickRankDTO compactQuickRank : this.quickRanks) {
|
||||
final CompetitorDTO competitorDTO = competitorsByIdAsString.get(compactQuickRank.getCompetitorIdAsString());
|
||||
if (competitorDTO != null) {
|
||||
result.quickRanks.put(compactQuickRank.getCompetitorIdAsString(), new QuickRankDTO(competitorDTO, compactQuickRank.getRank(), compactQuickRank.getLegNumber()));
|
||||
result.quickRanks.put(compactQuickRank.getCompetitorIdAsString(), new QuickRankDTO(competitorDTO, compactQuickRank.getOneBasedRank(), compactQuickRank.getLegNumber()));
|
||||
}
|
||||
}
|
||||
result.courseSidelines = courseSidelines;
|
||||
|
||||
+3
-2
@@ -5,7 +5,8 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
|
||||
public class QuickRankDTO implements IsSerializable {
|
||||
public CompetitorDTO competitor;
|
||||
public int rank;
|
||||
|
||||
public int oneBasedRank;
|
||||
|
||||
/**
|
||||
* The {@link #competitor}'s leg number, starting with 1 for the first leg
|
||||
@@ -16,7 +17,7 @@ public class QuickRankDTO implements IsSerializable {
|
||||
|
||||
public QuickRankDTO(CompetitorDTO competitorDTO, int rank, int legNumberOneBased) {
|
||||
this.competitor = competitorDTO;
|
||||
this.rank = rank;
|
||||
this.oneBasedRank = rank;
|
||||
this.legNumberOneBased = legNumberOneBased;
|
||||
}
|
||||
}
|
||||
-630
@@ -1,630 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Analytics</h4>
|
||||
<div class="innerContent">
|
||||
<h5 class="articleSubheadline">May 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>It's now possible to show nationality flags in addition to competitor images in leaderboards if both are available.
|
||||
If no competitor images are available, this won't have any effect.
|
||||
You can activate this option through the leaderboard settings dialog to be found in various views.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Several pages are now enabled to save user settings. In settings dialogs there is a "Make default"
|
||||
button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
|
||||
button causes the system to use the new settings as default values for the same page for any other context opened, e.g. another event.
|
||||
A click on OK button causes the system to store current settings for the current context and restore the same settings
|
||||
when the user opens the page with the same context again unless there are specific parameters given by the URL. Settings saved this way are
|
||||
stored locally in the browser's local storage and in the user profile if you are logged in.
|
||||
Some settings are only valid in a specific context (e.g. the selected race columns to show are stored for a specific leaderboard only).
|
||||
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
|
||||
Affected pages:
|
||||
<ul>
|
||||
<li><code>/gwt/Leaderboard.html</code></li>
|
||||
<li><code>/gwt/RegattaOverview.html</code></li>
|
||||
<li>Leaderboards embedded in <code>/gwt/Home.html</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The maneuver loss calculation for penalty circles has been improved. Previously, the end of the
|
||||
penalty circle maneuver was considered to be at the last of the two adjacent tack/gybe maneuvers.
|
||||
This, usually, is earlier than when approaching the course over ground at the beginning of the
|
||||
penalty circle again. With this, the extrapolation of the speed/course at the beginning of
|
||||
the maneuver did not last long enough. Furthermore, penalties with strong accelerations during
|
||||
the gybing phase could have led to an incorrect inference of the speed and course at the
|
||||
beginning of the maneuver. Both of these issues have now been fixed, leading to good results
|
||||
also in very specific and unusual speed developments during a penalty circle maneuver.
|
||||
</li>
|
||||
<li>The advantage line display has been fixed for legs changing their type (upwind/downwind/reach)
|
||||
while the race is going on. It now uses the leg type at the same current time point that the
|
||||
leaderboard uses for calculating the competitor ranking.
|
||||
</li>
|
||||
<li>Images in the overall image gallery ("Photographers love Sailing") are now linked with the
|
||||
events to which they belong. Clicking the image navigates to the event page.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The SAP Sailing Analytics are now also available in French, Portugese, as well as Spanish.
|
||||
Find the language chooser in the lower right corner of the footer, or when signed in, go to your user
|
||||
profile and set your preferred language.
|
||||
</li>
|
||||
<li>The application's locale now switches based on the client's "Accept-Language" HTTP header field.
|
||||
This means that the application in all its parts will show in the user's default language if
|
||||
supported, defaulting to English otherwise.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">February 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The definition of "ride height" for foiling sensors has been changed. Instead of showing
|
||||
the ride height calculated by the sensor we are now showing the minimum of the port and
|
||||
starboard ride heights. Therefore, this new definition of ride height can be seen as the
|
||||
distance of lowest hull part from the water.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">January 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>An issue with wind-up map rotation which sometimes left the map centered over the African continent has been fixed.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">October 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>An issue with live re-calculation of the maximum speed over ground (SOG) values has been fixed.
|
||||
In some circumstances it was possible that new live data did not properly update the MaxSOG figures.
|
||||
Since this depended on the timing of read and write access it could have led to different values
|
||||
for different server instances, giving confusing results. The fix provided now ensures that
|
||||
the MaxSOG values are properly evaluated when new data has arrived.
|
||||
</li>
|
||||
<li>The buoy zone radius is now determined by a configurable regatta property. By default, it is
|
||||
set to two hull lengths, and a regatta administrator may choose to change it to any other factor
|
||||
such as 3 or 2.5. This determines the default used in the race viewer (RaceBoard.html). Users can
|
||||
still change the radius in the map settings to any arbitrary number, deviating from what has
|
||||
"officially" been set for the regatta.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">August 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>In order to prepare user-specific configuration support in additional parts of the application,
|
||||
various modules now require a user account to be accessed. Please sign up and log in to use their
|
||||
full functionality as usual. The following modules are affected:
|
||||
<ul>
|
||||
<li><tt>/gwt/Simulator.html</tt></li>
|
||||
<li><tt>/gwt/DataMining.html</tt></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">July 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The Wind arrow in the top left corner of the race map / player now serves as a toggle button
|
||||
for the wind streamlet overlay which can still also be reached through the map settings.
|
||||
</li>
|
||||
<li>If you want to analyze a race, the navigation slightly changed. The button, which is shown for tracked
|
||||
races won't lead you to the race board directly, but provides a small menu. There you can choose from
|
||||
several pre-defined analysis, which will launch the race board with respective configurations:
|
||||
<ul>
|
||||
<li>Replay/Watch live: Launches race board in play mode starting at race start, if race is already
|
||||
finished (Replay) or at the actual time, if the race is currently live (Watch live)
|
||||
</li>
|
||||
<li>Race analysis: Shows the race results by setting the timer to the end of the race.
|
||||
<i>This option is only available, if the race is already finished.</i>
|
||||
</li>
|
||||
<li>Start analysis: Shows the race start 10 sec after start and shows the speed over ground (SOG) of
|
||||
the best starters within the competitor chart (zoomed to start).
|
||||
<i>This option is only available, if the race is already started.</i>
|
||||
</li>
|
||||
<li>Winning lanes: Shows the full lanes of the best competitor, if race is already finished or the of
|
||||
leading competitors if the race is currently live.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>On the user profile page you now can maintain a list of you favorite boat classes and competitors.
|
||||
You can also opt in for notification mails about your favorites to stay informed.
|
||||
A requirement for notification mails to work for you is that you entered a valid mail address
|
||||
to your user profile and verified the address by clicking the link that has been sent via email.
|
||||
</li>
|
||||
<li>Users now may choose their preferred language on the user profile page.
|
||||
Currently only the mail notification mechanism will accept this setting to send mails in the preferred
|
||||
language. This also prepares additional language sensitive feature, e.g. automatically switching the
|
||||
website to your preferred language when logged in.
|
||||
</li>
|
||||
<li>The leaderboard now has a new measure value called "Ride height", which shows the ride height on
|
||||
foils of a competitor, if respective data is available (currently ESS only). This information can
|
||||
also be shown in the competitor chart on the RaceBaord page.
|
||||
</li>
|
||||
<li>To visualize multiple information at once, the competitor chart on the RaceBaord page can now be
|
||||
configured to show two Y-axes.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">May 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>It is now possible to follow races on the RaceBoard, even if there's no wind data available.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The <tt>/gwt/RaceBoard.html</tt> entry point now accepts an optional parameter "t" in the form
|
||||
<tt>[[hh:]mm:]ss</tt>, for example <tt>t=12:34</tt> to place the timer so much after the race start
|
||||
if the viewer comes up in Replay mode. You may also use just seconds, as in <tt>t=1234</tt> which
|
||||
makes specifying a time <em>before</em> the start somewhat easier (<tt>t=-123</tt> instead of
|
||||
<tt>t=-02:-03</tt>).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">February 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The website now features a user registration and authentication interface.
|
||||
User accounts are currently used to grant special permissions to administrators and moderators.
|
||||
New user specific features (e.g. preferences) will be available in the next couple of months.
|
||||
</li>
|
||||
<li>The RaceBoard URL Parameter "canReplayDuringLiveRaces" has been removed.
|
||||
This parameter was used to allow users to trigger autoplay for live races on non-live points in time.
|
||||
The permission "CAN_REPLAY_DURING_LIVE_RACES" and role "moderator" now grant this functionality to users.
|
||||
</li>
|
||||
<li>Mark positions are no longer interpolated between fixes. Instead, when a mark's track is asked for the
|
||||
mark's position, the last known position at or before the time point requested will be used. The
|
||||
"jumping" of marks in the UI that may otherwise be caused by this is ameliorated by introducing
|
||||
the same CSS animation for the marks that is already used for the boats.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">January 2016</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Show maneuver markers on the race board by default
|
||||
(tacks, jibes and penalty circles) with a smaller icon, which
|
||||
shows an info bubble when the marker is clicked.
|
||||
The icon turns green if the direction change is to starboard
|
||||
and red if to port.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">December 2015</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The advantage line is now animated and moves smoothly with the boats.
|
||||
</li>
|
||||
<li>New line hover behavior in race map. When the mouse is moved onto a line, for example the start line, a transparent,
|
||||
wider line is activated behind it that acts as a buffer for the thin line, where the text displayed by the hover is still shown.
|
||||
This makes it easier to hover over the lines. These wider lines can be made semi transparent instead of transparent
|
||||
by unticking the corresponding checkbox in the settings of the race map. Furthermore the stroke weight of the wider lines can be
|
||||
configured in the same settings dialog.
|
||||
</li>
|
||||
<li>The race viewer (RaceBoard.html) now intelligently chooses a layout that suits the screen size.
|
||||
When only little horizontal space is available, only the sail number and nationality but not the
|
||||
competitor's long name is displayed by default. When vertical space is scarce, competitor and wind
|
||||
charts are disabled and more horizontal space can be given to the time slider at the bottom. The
|
||||
leaderboard section can then be scaled to smaller widths and will reduce the column widths better
|
||||
than in the past.
|
||||
</li>
|
||||
<li>With the changes described above, the RaceBoard is now also accessible from the races page on mobile devices.
|
||||
</li>
|
||||
<li>For overall / series leaderboards such as a national sailing league or the Extreme Sailing Series, the
|
||||
live status of the overall leaderboard is now indicated. As long as a live race is ongoing, the respective
|
||||
column in the overall leaderboard is highlighted, and a comment is displayed that indicates which regatta
|
||||
is currently still live.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">November 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The smartphone page provides some structural navigation items for several pages in the upper right burger menu.
|
||||
You will see links to e.g. events, regattas and series when navigating on event and series pages.
|
||||
</li>
|
||||
<li>It is now possible to filter for competitors in the race list of events/regattas.
|
||||
If competitor information is available, there is a filter box in the upper right corner of the races page.
|
||||
The filter is searching for competitors by sail ID as well as the competitor's name.
|
||||
</li>
|
||||
<li>Regattas can now be filtered by boat category in the smartphone page.
|
||||
The filter will be shown for events with multiple regattas if there is more than on boat category associated with the event.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">October 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>A variety of tablets will now show the desktop page by default.
|
||||
The mobile version of the website is primarily designed to be used on smartphones,
|
||||
but you can manually switch back to the mobile version by clicking the corresponding link in the page footer.
|
||||
</li>
|
||||
<li>There is some amount of caching on the web page to reduce the consumed traffic for mobile users.
|
||||
Contents aren't loaded again on each page switch. This improves the traffic consumption and loading speed on fast page switches.
|
||||
</li>
|
||||
<li>The fullscreen image viewer (start page and event media page) can automatically slide through the images.
|
||||
This can be turned on by clicking the corresponding icon in the upper right corner of the fullscreen viewer.
|
||||
</li>
|
||||
<li>There is an optimized search and results page for mobile devices now.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">September 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Races in the event/regatta race list can now be shown in 'competition format'.
|
||||
In this format the races and flights are shown in a structural view.
|
||||
In contrast to the default list view there is no grouping by live and finished states and all
|
||||
(including upcoming) races/flights are shown in one structural view.
|
||||
</li>
|
||||
<li>The mobile page now provides regatta overview pages for events having multiple regattas.
|
||||
This page shows live races, an excerpt of the current results as well as statistics for the regatta.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">August 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Series events appear as only one entry in the events list, with a marker that
|
||||
this is only one of a certain number of events in a series. This way, the many series events
|
||||
don't produce clutter in the events list.
|
||||
</li>
|
||||
<li>Bug fix: memory leaks for distance cache have been solved. The issue could
|
||||
also lead to endless recursions, ultimately leading to server lock-ups.
|
||||
</li>
|
||||
<li>Bug fix: master data import detached race logs and regatta logs from database.
|
||||
Log entries added after import on the importing server were not written to the
|
||||
database and therefore were lost upon server restart.
|
||||
</li>
|
||||
<li>There is a smartphone-optimized version of the "solutions" page known from the desktop.
|
||||
</li>
|
||||
<li>The smartphone event history now has a slider that allows swiping through the events of a year.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">July 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Major improvements to the web page, with specific enhancements for smartphone
|
||||
users. Race lists are now sortable by various criteria by clicking on the column
|
||||
headers. A new fancy progress indicator now also provides visual feedback for
|
||||
multi-fleet regattas. A news ticker box has been implemented, and the event
|
||||
overview page can hold a video player on its stage. The event media gallery section
|
||||
has been greatly improved.
|
||||
</li>
|
||||
<li>Fixed a bug in the wind streamlet visualization. Now the wind streamlets
|
||||
correctly show the wind at the location selected also in wind-up mode.
|
||||
</li>
|
||||
<li>Added the "Course Geometry" option to the map display. With this option selected,
|
||||
the map will show an info text for each leg and the start and finish line (only
|
||||
for one of start/finish line if they are identical), telling the length of the leg
|
||||
or line, respectively, and its angle to the wind. For the start and finish line
|
||||
the advantage of the favored side is shown in meters.
|
||||
</li>
|
||||
<li>The SAP Sailing Analytics start page is now available in the smartphone version.
|
||||
This page features some events that are currently interesting as well as showing a
|
||||
quickfinder for a variety of recent and upcoming events.
|
||||
Previously, the start page redirected to the event history.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">May 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Competitors can have a separate flag image, such as a club flag to be displayed instead of
|
||||
the nationality flag usually displayed with the sail number. This enables national league events
|
||||
to display the club flags consistently when all nation flags would be the same anyway.
|
||||
</li>
|
||||
<li>The wind estimation from the tracked courses over ground has been improved. It now takes into
|
||||
account any polar data available for the boat class concerned. In particular, this helps to rule
|
||||
out very unlikely gybing angles in downwind clusters that otherwise could have led to an incorrect
|
||||
split of the downwind fleet into two clusters where actually all boats were on the same tack.
|
||||
</li>
|
||||
<li>Some significant improvements have been applied to the simulator feature which is embedded in the
|
||||
race viewer since some time now. The simulator now copes with very shifty wind conditions and finds
|
||||
solutions in scenarios where an upwind leg flips to a reach or even into a downwind leg over time.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>There is a new map setting "Wind-Up (show wind from top of map)". Selecting it will
|
||||
align the map's top with the combined true wind average direction around the time currently
|
||||
selected in the time slider. In this new view there are limitations as to how far you can zoom
|
||||
out. Furthermore, you will not be able to use the Satellite view with this setting. Tip:
|
||||
if you want to re-align to wind-up after a major wind shift, un-check the setting, confirm
|
||||
the setting change, then set it again. A compass shows the true north orientation. Clicking
|
||||
the compass will toggle between wind-up and north-up display.
|
||||
</li>
|
||||
<li>Bug fixes around addition of the "Regatta Rank" column in the leaderboard which could have
|
||||
distorted the leaderboard's column layout under certain conditions.
|
||||
</li>
|
||||
<li>Bug fix for cumulative points in the leaderboard ("Show added scores for each entry in leaderboard").
|
||||
With this setting, scores of competitors not tracked in the current race were not correctly represented
|
||||
and may have stayed blank.
|
||||
</li>
|
||||
<li>Bug fix for the leg counter in the regatta page: when the first boat has finished, the leg counter went
|
||||
to zero (e.g., "0 of 8"). This has now been fixed, and it will show, e.g., "8 of 8" upon the first boat
|
||||
crossing the finish line.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Added competitor chart type for Course Over Ground (COG)
|
||||
</li>
|
||||
<li>Added leaderboard column and competitor chart entry for distances considering
|
||||
gate starts. With gate starts, late starters sail a shorter distance in their first
|
||||
leg. To still make distances comparable, a new metric has been introduced that for a gate
|
||||
start adds the distance between the port side of the start line and the position where
|
||||
the competitor started to the distance sailed in the first leg.
|
||||
</li>
|
||||
<li>The weights of the wind measurement units, the wind estimation and manual wind inputs by the
|
||||
race committee are now used properly for the wind streamlet visualization. This fixes issues
|
||||
with exaggerated weights for an estimated wind direction of very low confidence.
|
||||
</li>
|
||||
<li>The expand/collapse toggle button in the race viewer's time panel has correct arrows now.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">February 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The leaderboard offers a new column: "Start delay." It shows the number of seconds that passed
|
||||
since the race start and the time the competitor passes the start mark / start line. As usual,
|
||||
you can sort for this column. For line starts, this is a fairly direct measure of start quality
|
||||
except for port starts which may have to be considered differently. For gate starts, you can use
|
||||
this measure to find out about early and late starters and dig into possible correlations between
|
||||
results and start time point.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">January 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The race viewer ("RaceBoard.html") now offers a new option in the map settings:
|
||||
"Show simulation overlay". Checking this feature will simulate the current leader's leg
|
||||
using different strategies and using the wind as it has been measured and estimated.
|
||||
This feature becomes particularly interesting when combined with the "Show wind streamlets overlay"
|
||||
feature that visualizes the spatial distribution of the wind field over the course.
|
||||
</li>
|
||||
<li>The race viewer is now more resilient against exceptional conditions such as the missing
|
||||
of all wind information and the missing of a course with its waypoints. If no wind information
|
||||
is available at all (no wind direction indicator is then shown in the upper left corner of
|
||||
the map) then all ranking and distances will be based on a projection onto the course instead
|
||||
of onto the wind direction, even for upwind and downwind legs.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">September 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The search feature now also includes results from currently ongoing events that may not yet be
|
||||
included in our archive. Search keywords are now properly used in constructing the query.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">August 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The 2D race viewer, also known as the "Race Board," now comes with a fresh, new design. The orange
|
||||
checkbox toggle buttons that open or close views such as the leaderboard or the charts for wind
|
||||
and competitor comparison, have been replaced by tabs with ">>" symbols. Clicking on those
|
||||
will expand or collapse the respective view. The views can now be resized using the handles attached
|
||||
to the dividers separating the views. They work much better on mobile and touch devices than the splitters
|
||||
used previously did. The settings buttons that used to be integrated with the orange toggle
|
||||
checkbox buttons have now been moved into the views that they control. For example, the map settings
|
||||
button is now displayed on the map, below the zoom control on the right map border.
|
||||
</li>
|
||||
<li>The leaderboard now has an improved search and filter control. Above the table displaying the
|
||||
competitors and their figures is a new field with a text input that you can use to filter for
|
||||
competitors, by their sail number or their name. While filtered, use the checkboxes in front of
|
||||
the table row to add the competitor to or remove it from the selection. Use the "X" button to the
|
||||
right of the search input field to clear the search. To the left of the search input field is a
|
||||
filter symbol that you can use to select and create advanced filtering rules, such as filtering
|
||||
by rank or nationality. Left of the filter button is the leaderboard settings button.
|
||||
</li>
|
||||
<li>The leaderboard has a new first column: a selection check box. We hope this makes it easier in
|
||||
particular for users on mobile or other touch devices to select more than one competitor at a time.
|
||||
The old-style multi-selection using the Control and Shift keys, as known well from typical desktop
|
||||
file explorers, still work like they did before. Note that it is possible to sort for the checkbox
|
||||
column, putting the selected competitors at the top of the leaderboard.
|
||||
</li>
|
||||
<li>When using the auto-zoom feature from the map settings, boats and wind streamlets will now
|
||||
continue to move smoothly as long as the map only needs panning. Please also note that auto-zooming
|
||||
to "tails" may slow down the display considerable, particularly when tracking at high frequency.
|
||||
</li>
|
||||
<li>When viewing a single race, the leaderboard now by default does no longer show the regatta rank as
|
||||
the first column (and not as the second one either, given that the first column now usually shows
|
||||
the checkboxes used for selecting items). If you'd like to get the regatta rank column back, also when
|
||||
looking at a single race, please choose it from the leaderboard settings dialog where you can find it
|
||||
in the "Overall Details" section. It may still be a nice column to have when following the last race
|
||||
in a regatta. If you're just interested in the relative regatta rank ordering you may as well sort by
|
||||
the right-most total points column which (surprising to some but welcome by most) sorts by the regatta
|
||||
rank and not by the plain points sum (taking into account medal race and gold/silver/... fleet participations).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">July 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The advantage line now uses the wind at the position in the middle of the leg that the
|
||||
competitor to which the line is attached is currently sailing in. Before, the "global" wind
|
||||
average was used which is still displayed in the top left corner of the map. You can understand
|
||||
the details by turning on the "Streamlet" wind visualization in the Map Settings.
|
||||
</li>
|
||||
<li>Faster wind streamlet loading: when you activate the streamlets for wind visualization, they now
|
||||
display much faster.
|
||||
</li>
|
||||
<li>Faster boat position display: We found that what you're probably the most interested in when
|
||||
you first open a race map or move the time slider to some very different point in time is the
|
||||
position of the boats at that point in time; and you want to know it fast.
|
||||
The tails which show how the boats got there are also interesting, but you won't blame us as much
|
||||
if it takes a little bit to update them. So we've separated the placement of the boats from the
|
||||
drawing of their tails. Now you may blame us for the tails temporarily not being attached to the
|
||||
boats anymore ;-).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">June 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>In the "Maps" settings in the RaceBoard page there is a new checkbox named
|
||||
"Show wind streamlets overlay." If you select it and wait for about a minute,
|
||||
a complete wind field will be calculated and visualized as an overlay on top
|
||||
of the race course display. It reacts to you moving the time slider and shows
|
||||
how the wind differs at different locations on the course. Stronger and faster-moving
|
||||
streamlets mean stronger breeze.
|
||||
</li>
|
||||
<li>Wind is now calculated location-based. At locations closer to a sensor, that sensor
|
||||
has a higher influence on the local wind field than sensors further away. The wind
|
||||
estimations based on the courses sailed are assigned a location that corresponds with
|
||||
the "center of gravity" of the field that was used for the estimation. For example,
|
||||
if the fleet is approaching the windward mark and the wind sensor in on the committee
|
||||
boat on the leeward side of the course, the course-based estimation influences the
|
||||
assumed wind field more on the windward side whereas the sensor counts more for
|
||||
the leeward side.
|
||||
</li>
|
||||
<li>Switched to the latest version of the Highcharts charting framework. This leads to improvements
|
||||
especially on mobile devices. Charts can be zoomed using pinch gestures now.
|
||||
</li>
|
||||
<li>To support the use of the SAP Sailing Analytics also for live video streaming formats, we
|
||||
introduced a new URL parameter <tt>viewShowMapControls</tt> for the <tt>Spectator.html</tt>
|
||||
and the <tt>RaceBoard.html</tt> pages. Setting this parameter to "false"
|
||||
will suppress the zoom, pan and map type selection
|
||||
controls on the map display. Example:
|
||||
<a href="http://danishleague2014.sapsailing.com/gwt/Spectator.html?leaderboardGroupName=Danish%20League%202014&showRaceDetails=true&viewShowMapControls=false">http://danishleague2014.sapsailing.com/gwt/Spectator.html?leaderboardGroupName=Danish%20League%202014&showRaceDetails=true&viewShowMapControls=false</a>.
|
||||
When used for the <tt>Spectator.html</tt> URL, this will apply
|
||||
to all <tt>RaceBoard.html</tt> pages (all races) reached from there. Of course, the map
|
||||
can still be panned and zoomed using the usual mouse gestures. A left double click zooms
|
||||
in, a right double click zooms out. Zoom can also be controlled using the mouse wheel.
|
||||
And panning works by clicking on the map and dragging the mouse. Without the map type
|
||||
control, switching to satellite view is not possible (keep this in mind when tracking
|
||||
races in China, see below for Google's random coordinate transformations there).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">May 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Fixed an issue with the wind speed charts. Charts that only had a single, unchanged
|
||||
wind speed crashed the browser. The solution scales the right hand side Y-axis denoting
|
||||
the wind speed such that it always starts at 0kts.
|
||||
</li>
|
||||
<li>Analysis of tacks and jibes around mark passings has now been improved. Before,
|
||||
a jibe followed by a tack that turns in the same direction (e.g., to port) so far
|
||||
was always called a penalty maneuver. Now, if a mark passing separates such a tack
|
||||
from such a jibe, no penalty is called anymore, and the two maneuvers are identified
|
||||
correctly.
|
||||
</li>
|
||||
<li>Another note on maneuver analysis: we received questions regarding the maneuvers
|
||||
involved in clearing an OCS. The SAP Sailing Analytics treat a clearing of
|
||||
an OCS, going back behind the start line and crossing it again, as if the competitor
|
||||
started again. In particular this means that all maneuvers prior to this new start
|
||||
do not count for the metrics; neither does the distance sailed between the first (OCS)
|
||||
start and the clear start.
|
||||
</li>
|
||||
<li>A hint regarding the "distance to start line" metrics: please keep in mind that currently this
|
||||
measurement is calculated as the distance of the GPS tracker from the line. Unless the tracker
|
||||
is mounted near the bow (or at the bow sprit, if any), the distance calculated this way will
|
||||
be greater than what counts for crossing the line. Ordering, comparing and aggregating over this
|
||||
figure still makes sense as long as you remember this detail.
|
||||
</li>
|
||||
<li>Introduced a new leaderboard entry "XTE +/-" featuring a signed cross-track error which shows
|
||||
for a leg and also aggregated for an entire race on which side of the leg a competitor stayed on
|
||||
average. Currently, the "side" is defined as viewing in the leg's direction, so "left" for a downwind
|
||||
leg is the same side as "right" for the corresponding upwind leg.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>China races, such as in Qingdao, may have the map background displayed at slightly wrong locations.
|
||||
This is due to an intentional random transformation that Google applies to GPS locations for
|
||||
China. You can circumvent this issue by switching to satellite view where the map background is displayed
|
||||
correctly. <img src="/images/mapsatellite.png"/>
|
||||
</li>
|
||||
<li>Fixed a bug that in some cases has caused the wind chart, the advantage line, the wind indicator on the map
|
||||
and the leaderboard to use slightly different wind values. The problem was related to different averaging and
|
||||
damping methods used for these values which has now been aligned.
|
||||
</li>
|
||||
<li>Fixed a bug that caused the time spent in a leg, race or regatta to always show the time at the end of the leg
|
||||
if the leg has been started by the competitor at the time point queried, e.g., by the time slider. While this
|
||||
did not have any serious effects in live mode, for replay races this left the leg time and race time constant
|
||||
at the total time spent so far up to the end of the last leg the competitor had started at that time.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Added a new setting for a leaderboard called "Show added scores". Using this feature one
|
||||
can display added scores for each leaderboard entry. An added score is the sum over all scores
|
||||
from the first column to the current column. One can describe it as an intermediate overall score.
|
||||
This feature can be used to know the score until a specific race while another race is live and
|
||||
constantly changes the overall score.</li>
|
||||
|
||||
<li>Added tooltips for leaderboard settings.</li>
|
||||
|
||||
<li>Fixed HighPointOverall scheme to also break a tie by looking at the ranks of the last regatta.</li>
|
||||
|
||||
<li>Progress indicator when expanding a race in the RaceBoard view</li>
|
||||
|
||||
<li>Leaderboard column "GPS Lag" shows how far a competitor's GPS signal lags behind the average
|
||||
tracking quality. A background color bar classifies into good/ok/bad (green/yellow/red).</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">February 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Fixed an issue with boat rotation on Safari browsers</li>
|
||||
|
||||
<li>Maneuver analysis now counts tacks and jibes based on wind
|
||||
at boat position and not based on leg type; subsequently,
|
||||
penalty circle analysis is now based on a tack and a jibe
|
||||
in close succession instead of a full circle.</li>
|
||||
|
||||
<li>Regatta rank and overall rank in competitor chart of leaderboard panel
|
||||
has been fixed; it did erroneously display the rank of the particular
|
||||
race, not the regatta/overall rank after that race.</li>
|
||||
|
||||
<li>Regatta overview now also displays all regatta leaderboards</li>
|
||||
|
||||
<li>Boat colors match tail colors</li>
|
||||
|
||||
<li>When selecting boats in leaderboard, de-selected boats' tails turn grey</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h5 class="articleSubheadline">January 2014</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Boat movement animated smoothly</li>
|
||||
|
||||
<li>Start and Finish line show line parameters (length, angle to wind,
|
||||
advantage) when mouse hovers over them</li>
|
||||
|
||||
<li>Start line has a count-down indicator displayed next to it
|
||||
before the start. The count-down is also displayed underneath the time
|
||||
slider</li>
|
||||
|
||||
<li>Competitor and Wind charts show pre-start data where possible</li>
|
||||
|
||||
<li>Competitors can be assigned a fixed color which they will keep
|
||||
for all races in a regatta</li>
|
||||
|
||||
<li>By default, videos are now shown in a moveable, resizable box embedded in
|
||||
the web page. For a two screen setup, the embedded box can be popped out to a
|
||||
dedicated browser window.</li>
|
||||
|
||||
<li>Official score corrections for historic races are only applied after
|
||||
the respective competitor finished the race. Therefore, in-between race
|
||||
scores now correspond with tracking, regardless of final corrected score.</li>
|
||||
|
||||
<li>By using negative playback speed (e.g., -1), replays can be run backwards.</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user