startanalysis card uses not racemap with custom settings to display start

This commit is contained in:
Alexander Ries committed 2015-03-19 13:54:30 +01:00
1 parent 5398ca77a8
commit 2c0b4f78b4
14 files changed
+200 -158

No files matched your search

@@ -36,7 +36,7 @@ public class RibDashboardEntryPoint extends AbstractEntryPoint<StringMessages> {
RibDashboardDataRetriever dataRetriever = new RibDashboardDataRetriever(ribdashboardService);
applyMGWTSettings();
RibDashboardPanel ribDashboardPanel = new RibDashboardPanel(ribdashboardService, dataRetriever);
RibDashboardPanel ribDashboardPanel = new RibDashboardPanel(ribdashboardService, sailingService, dataRetriever);
RootLayoutPanel.get().add(ribDashboardPanel);
WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(sailingService);
windBotDataRetriever.addNumberOfWindBotsChangeListeners(ribDashboardPanel);
@@ -33,9 +33,6 @@ public interface RibDashboardImageResources extends ClientBundle {
@Source("images/rightarrow_disabled.png")
ImageResource rightdisabled();
@Source("images/windarrow.png")
ImageResource windarrow();
@Source("images/compass.png")
ImageResource compass();
@@ -20,6 +20,7 @@ import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComp
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageComponent;
import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
/**
* This class contains all components of the Dashboard and the basic UI Elements of the Dashboard, like top and bottom
@@ -72,10 +73,10 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
private List<WindBotComponent> windBotComponents;
public RibDashboardPanel(RibDashboardServiceAsync ribDashboardService, RibDashboardDataRetriever ribDashboardDataRetriever) {
public RibDashboardPanel(RibDashboardServiceAsync ribDashboardService, SailingServiceAsync sailingServiceAsync, RibDashboardDataRetriever ribDashboardDataRetriever) {
windBotComponents = new ArrayList<WindBotComponent>();
ribDashboardDataRetriever.addDataObserver(this);
startanalysisComponent = new StartlineAnalysisComponent(ribDashboardService);
startanalysisComponent = new StartlineAnalysisComponent(ribDashboardService, sailingServiceAsync);
startLineCAComponent = new StartLineAdvantageComponent(ribDashboardDataRetriever);
initWidget(uiBinder.createAndBindUi(this));
initLogos();
@@ -1,7 +1,9 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
public interface StartAnalysisPageChangeListener {
public void loadMapAndContent(int newPageIndex);
public void startAnalysisComponentPageChangedToIndexAndStartAnalysis(int newPageIndex, StartAnalysisDTO startAnalysisDTO);
}
@@ -56,19 +56,12 @@
display: inline;
width: 80%;
height: 100%;
background-color: #4293DB;
margin-top: 1px; /*Zeigt sonst Linie am oberen Rand*/
/*#4293DB old water color*/
background-color: #004384;
margin-top: 1px; /*Shows otherwise small line at top edge*/
overflow: hidden;
}
.startanalysis_google_map {
position: absolute;
bottom: -20pt;
right: -20pt;
left: -20pt;
top: -20pt;
}
.startanalysis_card_table {
position: absolute;
bottom: 10pt;
@@ -87,30 +80,6 @@
z-index: 1;
}
.startanalysis_card_wind_direction_image {
position: absolute;
top: 0pt;
right: 0pt;
width: 45pt;
height: 45pt;
border-radius: 22.5pt;
background-color: white;
}
.startanalysis_card_wind_arrow {
width: 25pt;
height: 25pt;
margin-top: 10pt;
margin-left: 10pt;
}
.startanalysis_card_wind_canvas {
width: 25pt;
height: 25pt;
margin-top: 10pt;
margin-left: 10pt;
}
.startanalysis_card_data {
position: absolute;
right: 0pt;
@@ -124,14 +93,6 @@
text-align: center;
}
.startanalysis_card_wind_data_direction {
top: 55pt;
}
.startanalysis_card_wind_data_speed {
top: 85pt;
}
.startanalysis_card_line_advantage {
top: 0pt;
left: 55pt;
@@ -1,40 +1,44 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable.StartAnalysisStartRankTable;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
public class StartlineAnalysisCard extends Composite implements HasWidgets, StartAnalysisPageChangeListener {
private StartAnalysisSimpleMap simpleMap;
private final double WIND_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 185;
private final double GEOMETRIC_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 210;
private static StartlineAnalysisCardUiBinder uiBinder = GWT.create(StartlineAnalysisCardUiBinder.class);
interface StartlineAnalysisCardUiBinder extends UiBinder<Widget, StartlineAnalysisCard> {
}
interface StartlineAnalysis extends CssResource {
public String startanalysis_card_wind_canvas();
public String startanalysis_card_wind_arrow();
}
@UiField
@@ -42,73 +46,55 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
@UiField
HTMLPanel startanalysis_card;
@UiField
HTMLPanel winddirection;
@UiField
HTMLPanel startanalysis_card_table;
@UiField
DivElement startanalysis_card_wind_data_direction;
@UiField
DivElement startanalysis_card_wind_data_speed;
@UiField
DivElement startanalysis_card_line_advantage;
Canvas winddirectionContainer;
Image windarrow;
private int cardid;
private boolean containsMap = false;
private StartAnalysisDTO startAnalysisDTO;
private RaceMap raceMap;
public StartlineAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO) {
private SailingServiceAsync sailingServiceAsync;
private final CompetitorSelectionModel competitorSelectionModel;
private final double WIND_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 185;
private final double GEOMETRIC_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 210;
private final int TAIL_LENGHT_IN_MILLISECONDS = 900000;
private static StartAnalysisResources resources = GWT.create(StartAnalysisResources.class);
public StartlineAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO,
SailingServiceAsync sailingServiceAsync) {
resources.combinedWindPanelStyle().ensureInjected();
this.sailingServiceAsync = sailingServiceAsync;
competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */true);
initWidget(uiBinder.createAndBindUi(this));
startanalysis_card.getElement().getStyle().setLeft(leftCSSProperty, Unit.PCT);
winddirectionContainer = Canvas.createIfSupported();
this.startAnalysisDTO = startAnalysisDTO;
winddirectionContainer.setStyleName(style.startanalysis_card_wind_canvas());
windarrow = new Image();
windarrow.setResource(RibDashboardImageResources.INSTANCE.windarrow());
windarrow.setStyleName(style.startanalysis_card_wind_arrow());
winddirection.add(windarrow);
this.cardid = cardId;
if (cardid == 0) {
addMap(cardid);
}
startanalysis_card_table.add(new StartAnalysisStartRankTable(startAnalysisDTO.startAnalysisCompetitorDTOs));
fillWindAndStartLineData(this.startAnalysisDTO);
this.onLoad();
}
private void fillWindAndStartLineData(StartAnalysisDTO startAnalysisDTO) {
if (startAnalysisDTO.startAnalysisWindLineInfoDTO != null) {
String winddirectionformatted = NumberFormat.getFormat("#0").format(
startAnalysisDTO.startAnalysisWindLineInfoDTO.windDirectionInDegrees-90);
windarrow.getElement().getStyle()
.setProperty("transform", "rotate(" + winddirectionformatted + "deg)");
windarrow.getElement().getStyle().setProperty("webkitTransform", "rotate(" + winddirectionformatted + "deg)");
startanalysis_card_wind_data_direction
.setInnerHTML(NumberFormat.getFormat("#0.0").format(startAnalysisDTO.startAnalysisWindLineInfoDTO.windDirectionInDegrees) + "°");
startanalysis_card_wind_data_speed
.setInnerHTML(NumberFormat.getFormat("#0.0").format(startAnalysisDTO.startAnalysisWindLineInfoDTO.windSpeedInKnots) + " kts");
setLineAdvantageDivWidth(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType);
startanalysis_card_line_advantage.setInnerHTML(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType.getDisplayName()+": "+NumberFormat.getFormat("#0.0").format(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvantage)+" m");
startanalysis_card_line_advantage
.setInnerHTML(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType
.getDisplayName()
+ ": "
+ NumberFormat
.getFormat("#0.0")
.format(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvantage)
+ " m");
}
}
private void setLineAdvantageDivWidth(StartlineAdvantageType startlineAdvantageType) {
if (startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType
.equals(StartlineAdvantageType.GEOMETRIC)) {
@@ -118,37 +104,72 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
}
}
private void addMap(final int cardID) {
Timer timer = new Timer()
{
@Override
public void run()
{
simpleMap = new StartAnalysisSimpleMap(cardID, startAnalysisDTO);
startanalysis_card.add(simpleMap);
}
};
private void addMap(final int cardID, final StartAnalysisDTO startAnalysisDTO) {
AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
com.sap.sse.gwt.client.player.Timer timer = new com.sap.sse.gwt.client.player.Timer(PlayModes.Live, 1000l);
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds);
timer.pause();
timer.schedule(800);
containsMap = true;
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingServiceAsync,
asyncActionsExecutor, null, Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier), 5000l /* requestInterval */);
raceMap = new RaceMap(sailingServiceAsync, asyncActionsExecutor, null, timer, competitorSelectionModel,
StringMessages.INSTANCE, false, false, false, startAnalysisDTO.regattaAndRaceIdentifier,
resources.combinedWindPanelStyle());
competitorSelectionModel.setCompetitors(startAnalysisDTO.getCompetitorDTOsFromStartAnaylsisCompetitorDTOs(),
raceMap);
raceMap.onRaceSelectionChange(Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier));
raceMap.getSettings().setZoomSettings(new RaceMapZoomSettings(ZoomTypes.TAILS));
raceMap.getSettings().setHelpLinesSettings(getHelpLineSettings());
raceMap.getSettings().setTailLengthInMilliseconds(TAIL_LENGHT_IN_MILLISECONDS);
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
startanalysis_card.add(raceMap);
/**
* Executes onResize() after the reflow of the DOM. Otherwise it has no effect.
* Needs to resize the map because google maps are not shown loaded fully when they are hidden.
* */
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
raceMap.onResize();
}
});
}
private RaceMapHelpLinesSettings getHelpLineSettings() {
HashSet<HelpLineTypes> visibleHelpLines = new HashSet<HelpLineTypes>();
visibleHelpLines.add(HelpLineTypes.STARTLINE);
visibleHelpLines.add(HelpLineTypes.BOATTAILS);
visibleHelpLines.add(HelpLineTypes.STARTLINETOFIRSTMARKTRIANGLE);
return new RaceMapHelpLinesSettings(visibleHelpLines);
}
private void removeMap() {
if(simpleMap != null && simpleMap.isAttached()){
startanalysis_card.remove(simpleMap);
containsMap = false;
if (raceMap != null && raceMap.isAttached() == true) {
startanalysis_card.remove(raceMap);
}
}
@Override
public void loadMapAndContent(int newPageIndex) {
if (cardid == newPageIndex && containsMap == false) {
addMap(newPageIndex);
} else if (containsMap == true) {
removeMap();
public void startAnalysisComponentPageChangedToIndexAndStartAnalysis(final int newPageIndex,
final StartAnalysisDTO startAnalysisDTO) {
removeMap();
if (cardid == newPageIndex) {
/**
* Prevents UI to animate startanalysis card animation with small interruptions.
* The map gets added just after the DOM manipulation was executed.
* */
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
addMap(newPageIndex, startAnalysisDTO);
}
});
}
}
@Override
public void add(Widget w) {
throw new UnsupportedOperationException("The method add(Widget w) is not supported.");
@@ -7,15 +7,7 @@
src='StartlineAnalysis.css'></ui:style>
<g:HTMLPanel ui:field="startanalysis_card" styleName="{style.startanalysis_card}">
<!-- <maps:MapWidget></maps:MapWidget> -->
<div class="{style.startanalysis_card_wind_line_data_container}">
<g:HTMLPanel ui:field="winddirection"
styleName="{style.startanalysis_card_wind_direction_image}">
</g:HTMLPanel>
<div ui:field="startanalysis_card_wind_data_direction"
class="{style.startanalysis_card_data} {style.startanalysis_card_wind_data_direction}"></div>
<div ui:field="startanalysis_card_wind_data_speed"
class="{style.startanalysis_card_data} {style.startanalysis_card_wind_data_speed}"></div>
<div ui:field="startanalysis_card_line_advantage"
class="{style.startanalysis_card_data} {style.startanalysis_card_line_advantage}"></div>
</div>
@@ -32,6 +32,7 @@ import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.Competit
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sse.gwt.client.player.TimeListener;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
@@ -98,10 +99,11 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
private boolean displaysCards;
private List<StartAnalysisDTO> starts;
private List<StartAnalysisPageChangeListener> pageChangeListener;
private List<StartlineAnalysisCard> pageChangeListener;
private BottomNotification bottomNotification;
private Timer timer;
private RibDashboardServiceAsync ribDashboardServiceAsync;
private SailingServiceAsync sailingServiceAsync;
private static final int RERFRESH_INTERVAL = 10000;
@@ -118,9 +120,10 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
/**
* Component that contains handles, displays and loads startanalysis cards.
* */
public StartlineAnalysisComponent(RibDashboardServiceAsync ribDashboardServiceAsync) {
public StartlineAnalysisComponent(RibDashboardServiceAsync ribDashboardServiceAsync, SailingServiceAsync sailingServiceAsync) {
this.ribDashboardServiceAsync = ribDashboardServiceAsync;
pageChangeListener = new ArrayList<StartAnalysisPageChangeListener>();
this.sailingServiceAsync = sailingServiceAsync;
pageChangeListener = new ArrayList<StartlineAnalysisCard>();
starts = new ArrayList<StartAnalysisDTO>();
this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME);
@@ -174,9 +177,11 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
@Override
public void onSuccess(List<StartAnalysisDTO> result) {
if (!result.isEmpty()) {
if (displayedStartAnalysisCompetitorDifferentToRequestedOne()) {
removeAllStartAnalysisCards();
}
if (result.size() != starts.size()) {
showNotificationForNewStartAnalysis();
}
@@ -317,7 +322,7 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
}
}
private void addStartAnalysisCard(StartAnalysisDTO startAnalysisDTO) {
private void addStartAnalysisCard(final StartAnalysisDTO startAnalysisDTO) {
if (displaysCards == false) {
displaysCards = true;
@@ -326,12 +331,13 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
if (numberOfStartAnalysisCards > 0) {
rightButton.setResource(RibDashboardImageResources.INSTANCE.right());
}
StartlineAnalysisCard sac = new StartlineAnalysisCard(numberOfStartAnalysisCards
* SCROLL_OFFSET_STARTANALYSIS_CARDS + 10, numberOfStartAnalysisCards, startAnalysisDTO);
startanalysis_card_container.add(sac);
registerPageChangeListener(sac);
final StartlineAnalysisCard startlineAnalysisCard = new StartlineAnalysisCard(numberOfStartAnalysisCards
* SCROLL_OFFSET_STARTANALYSIS_CARDS + 10, numberOfStartAnalysisCards, startAnalysisDTO,
sailingServiceAsync);
startanalysis_card_container.add(startlineAnalysisCard);
startlineAnalysisCard.startAnalysisComponentPageChangedToIndexAndStartAnalysis(page, startAnalysisDTO);
registerPageChangeListener(startlineAnalysisCard);
numberOfStartAnalysisCards++;
}
private void removeAllStartAnalysisCards() {
@@ -344,7 +350,7 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
this.bottomNotification.show(BottomNotificationType.NEW_STARTANALYSIS_AVAILABLE);
}
public void registerPageChangeListener(StartAnalysisPageChangeListener s) {
public void registerPageChangeListener(StartlineAnalysisCard s) {
pageChangeListener.add(s);
}
@@ -354,7 +360,8 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
public void notifyStartAnalysisPageChangeListener(int newPageIndex) {
for (StartAnalysisPageChangeListener sO : pageChangeListener) {
sO.loadMapAndContent(newPageIndex);
if(starts.get(newPageIndex) != null)
sO.startAnalysisComponentPageChangedToIndexAndStartAnalysis(newPageIndex, starts.get(newPageIndex));
}
}
@@ -3,8 +3,6 @@ package com.sap.sailing.dashboards.gwt.client.windchart;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.moxieapps.gwt.highcharts.client.Axis.Type;
import org.moxieapps.gwt.highcharts.client.Chart;
@@ -38,7 +36,6 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardEntryPoint;
/**
* The class represents a wind chart that is displayed vertically. Because it is meant to be used to display wind fixes,
@@ -71,8 +68,6 @@ public class VerticalWindChart extends Composite implements HasWidgets {
private static final int MAX_SERIES_POINTS = 100000000;
private static final Logger logger = Logger.getLogger(RibDashboardEntryPoint.class.getName());
private static VerticalWindChartUiBinder uiBinder = GWT.create(VerticalWindChartUiBinder.class);
interface VerticalWindChartUiBinder extends UiBinder<Widget, VerticalWindChart> {
@@ -246,7 +241,6 @@ public class VerticalWindChart extends Composite implements HasWidgets {
} else {
pointRangeInMilliseconds = 0;
}
logger.log(Level.INFO, "Points Range " + pointRangeInMilliseconds);
return pointRangeInMilliseconds;
}
@@ -1,7 +1,5 @@
package com.sap.sailing.gwt.ui.client.shared.racemap;
import java.util.logging.Logger;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -28,8 +26,6 @@ public class CombinedWindPanel extends FlowPanel {
private CombinedWindPanelStyle combinedWindPanelStyle;
private static final Logger logger = Logger.getLogger(CombinedWindPanel.class.getName());
/**
*/
public CombinedWindPanel(RaceMapImageManager theRaceMapResources, CombinedWindPanelStyle combinedWindPanelStyle, StringMessages stringMessages) {
@@ -159,6 +159,16 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
* Polyline for the advantage line (the leading line for the boats, orthogonal to the wind direction; touching the leading boat).
*/
private Polyline advantageLine;
/**
* The windward of two Polylines representing a triangle between startline and first mark.
*/
private Polyline windwardStartLineMarkToFirstMarkLine;
/**
* The leeward of two Polylines representing a triangle between startline and first mark.
*/
private Polyline leewardStartLineMarkToFirstMarkLine;
private class AdvantageLineMouseOverMapHandler implements MouseOverMapHandler {
private double trueWindAngle;
@@ -325,7 +335,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
public RaceMap(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
ErrorReporter errorReporter, Timer timer, CompetitorSelectionProvider competitorSelection,
StringMessages stringMessages, boolean showMapControls, boolean showViewStreamlets, boolean showViewSimulation,
RegattaAndRaceIdentifier raceIdentifier) {
RegattaAndRaceIdentifier raceIdentifier, CombinedWindPanelStyle combinedWindPanelStyle) {
this.setSize("100%", "100%");
this.stringMessages = stringMessages;
this.sailingService = sailingService;
@@ -356,7 +366,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
panelForRightHeaderLabels = new AbsolutePanel();
initializeData(showMapControls);
combinedWindPanel = new CombinedWindPanel(raceMapImageManager, stringMessages);
combinedWindPanel = new CombinedWindPanel(raceMapImageManager, combinedWindPanelStyle, stringMessages);
combinedWindPanel.setVisible(false);
}
@@ -626,12 +636,14 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
@Override
public void timeChanged(final Date newTime, final Date oldTime) {
System.out.println("Race Map Time changed");
if (newTime != null && isMapInitialized) {
if (selectedRaces != null && !selectedRaces.isEmpty()) {
RegattaAndRaceIdentifier race = selectedRaces.get(selectedRaces.size() - 1);
final Iterable<CompetitorDTO> competitorsToShow = getCompetitorsToShow();
if (race != null) {
System.out.println("Data for "+race.getRaceName());
final com.sap.sse.common.Util.Triple<Map<CompetitorDTO, Date>, Map<CompetitorDTO, Date>, Map<CompetitorDTO, Boolean>> fromAndToAndOverlap =
fixesAndTails.computeFromAndTo(newTime, competitorsToShow, settings.getEffectiveTailLengthInMilliseconds());
int requestID = ++boatPositionRequestIDCounter;
@@ -741,10 +753,12 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error obtaining racemap data: " + caught.getMessage(), true /*silentMode */);
System.out.println("Error obtaining racemap data: " + caught.getMessage());
}
@Override
public void onSuccess(RaceMapDataDTO raceMapDataDTO) {
System.out.println("Got RaceMapDataDTO");
if (map != null && raceMapDataDTO != null) {
quickRanks = raceMapDataDTO.quickRanks;
if (showViewSimulation && settings.isShowSimulationOverlay()) {
@@ -770,6 +784,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
showCourseMarksOnMap(raceMapDataDTO.coursePositions);
showCourseSidelinesOnMap(raceMapDataDTO.courseSidelines);
showStartAndFinishLines(raceMapDataDTO.coursePositions);
showStartLineToFirstMarkTriangle(raceMapDataDTO.coursePositions);
// even though the wind data is retrieved by a separate call, re-draw the advantage line because it needs to
// adjust to new boat positions
showAdvantageLine(competitorsToShow, newTime);
@@ -1171,6 +1186,51 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
* active while auto-zooming whereas stopping them seems the better option for manual zooms.
*/
private boolean autoZoomInProgress;
private void showStartLineToFirstMarkTriangle(final CoursePositionsDTO courseDTO){
if (settings.getHelpLinesSettings().isVisible(HelpLineTypes.STARTLINETOFIRSTMARKTRIANGLE)){
LatLng windwardStartLinePoint = LatLng.newInstance(courseDTO.startMarkPositions.get(0).latDeg, courseDTO.startMarkPositions.get(0).lngDeg);
LatLng leewardStartLinePoint = LatLng.newInstance(courseDTO.startMarkPositions.get(1).latDeg, courseDTO.startMarkPositions.get(1).lngDeg);
LatLng firstMarkPoint = LatLng.newInstance(courseDTO.waypointPositions.get(1).latDeg, courseDTO.waypointPositions.get(1).lngDeg);
if (windwardStartLineMarkToFirstMarkLine == null && leewardStartLineMarkToFirstMarkLine == null) {
System.out.println("Draw Star First Mark Triangle");
PolylineOptions options = PolylineOptions.newInstance();
options.setGeodesic(true);
options.setStrokeColor("grey");
options.setStrokeWeight(1);
options.setStrokeOpacity(1.0);
MVCArray<LatLng> windwardLinePoints = MVCArray.newInstance();
windwardLinePoints.insertAt(0, windwardStartLinePoint);
windwardLinePoints.insertAt(1, firstMarkPoint);
MVCArray<LatLng> leewardLinePoints = MVCArray.newInstance();
windwardLinePoints.insertAt(0, leewardStartLinePoint);
windwardLinePoints.insertAt(1, firstMarkPoint);
windwardStartLineMarkToFirstMarkLine = Polyline.newInstance(options);
windwardStartLineMarkToFirstMarkLine.setPath(windwardLinePoints);
leewardStartLineMarkToFirstMarkLine = Polyline.newInstance(options);
leewardStartLineMarkToFirstMarkLine.setPath(leewardLinePoints);
windwardStartLineMarkToFirstMarkLine.setMap(map);
leewardStartLineMarkToFirstMarkLine.setMap(map);
} else {
windwardStartLineMarkToFirstMarkLine.getPath().removeAt(1);
windwardStartLineMarkToFirstMarkLine.getPath().removeAt(0);
windwardStartLineMarkToFirstMarkLine.getPath().insertAt(0, windwardStartLinePoint);
windwardStartLineMarkToFirstMarkLine.getPath().insertAt(1, firstMarkPoint);
leewardStartLineMarkToFirstMarkLine.getPath().removeAt(1);
leewardStartLineMarkToFirstMarkLine.getPath().removeAt(0);
leewardStartLineMarkToFirstMarkLine.getPath().insertAt(0, leewardStartLinePoint);
leewardStartLineMarkToFirstMarkLine.getPath().insertAt(1, firstMarkPoint);
}
}
}
private void showStartAndFinishLines(final CoursePositionsDTO courseDTO) {
if (map != null && courseDTO != null && lastRaceTimesInfo != null) {
@@ -10,7 +10,7 @@ public class RaceMapHelpLinesSettings {
* Types of help lines on the map
*/
public enum HelpLineTypes {
STARTLINE, FINISHLINE, ADVANTAGELINE, COURSEMIDDLELINE, BUOYZONE, BOATTAILS
STARTLINE, FINISHLINE, ADVANTAGELINE, COURSEMIDDLELINE, BUOYZONE, BOATTAILS, STARTLINETOFIRSTMARKTRIANGLE
}
private final Set<HelpLineTypes> visibleHelpLines;
@@ -45,6 +45,12 @@ public class RaceMapZoomSettings {
zoomToSelectedCompetitors = false;
}
public RaceMapZoomSettings(ZoomTypes zoomType) {
typesToConsiderOnZoom = new ArrayList<ZoomTypes>();
typesToConsiderOnZoom.add(zoomType);
zoomToSelectedCompetitors = false;
}
public RaceMapZoomSettings(ArrayList<ZoomTypes> typesToConsiderOnZoom, boolean zoomToSelected) {
this.typesToConsiderOnZoom = typesToConsiderOnZoom;
this.zoomToSelectedCompetitors = zoomToSelected;
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.DateTimeFormat;
@@ -48,6 +49,7 @@ import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.client.shared.filter.FilterWithUI;
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources;
import com.sap.sailing.gwt.ui.leaderboard.CompetitorFilterPanel;
import com.sap.sailing.gwt.ui.leaderboard.ExplicitRaceColumnSelectionWithPreselectedRace;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
@@ -115,6 +117,8 @@ public class RaceBoardPanel extends SimplePanel implements RegattasDisplayer, Ra
private final FlowPanel regattaAndRaceTimeInformationHeader;
private boolean currentRaceHasBeenSelectedOnce;
private static final RaceMapResources raceMapResources = GWT.create(RaceMapResources.class);
/**
* @param event
* an optional event that can be used for "back"-navigation in case the race board shows a race in the
@@ -154,8 +158,9 @@ public class RaceBoardPanel extends SimplePanel implements RegattasDisplayer, Ra
componentViewers = new ArrayList<ComponentViewer>();
competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
raceMapResources.combinedWindPanelStyle().ensureInjected();
raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer,
competitorSelectionModel, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewSimulation(), selectedRaceIdentifier);
competitorSelectionModel, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewSimulation(), selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle());
CompetitorFilterPanel competitorSearchTextBox = new CompetitorFilterPanel(competitorSelectionModel, stringMessages, raceMap,
new LeaderboardFetcher() {
@Override