mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-04 03:13:49 +00:00
Merge branch 'master' into mak-refactor-TimePanelSettings
This commit is contained in:
commit
16bb72aab8
5 files changed
+110
-108
No files matched your search
+19
-33
@@ -40,7 +40,6 @@ import com.sap.sailing.domain.base.Buoy;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Gate;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
@@ -1026,10 +1025,13 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
TimePoint dateAsTimePoint = new MillisecondsTimePoint(date);
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
result.buoys = new ArrayList<MarkDTO>();
|
||||
result.buoys = new HashSet<MarkDTO>();
|
||||
result.waypointPositions = new ArrayList<PositionDTO>();
|
||||
Set<Buoy> buoys = new HashSet<Buoy>();
|
||||
Course course = trackedRace.getRace().getCourse();
|
||||
for (Waypoint waypoint : course.getWaypoints()) {
|
||||
Position waypointPosition = trackedRace.getApproximatePosition(waypoint, dateAsTimePoint);
|
||||
result.waypointPositions.add(new PositionDTO(waypointPosition.getLatDeg(), waypointPosition.getLngDeg()));
|
||||
for (Buoy b : waypoint.getBuoys()) {
|
||||
buoys.add(b);
|
||||
}
|
||||
@@ -1044,46 +1046,30 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
}
|
||||
|
||||
// set the buoys of the start and finish gate
|
||||
// set the positions of start and finish
|
||||
Waypoint firstWaypoint = course.getFirstWaypoint();
|
||||
if(firstWaypoint != null && firstWaypoint.getControlPoint() instanceof Gate) {
|
||||
Gate startGate = (Gate) firstWaypoint.getControlPoint();
|
||||
MarkDTO leftMark = null;
|
||||
MarkDTO rightMark = null;
|
||||
for(MarkDTO mark: result.buoys) {
|
||||
if(mark.name.equals(startGate.getLeft().getName())) {
|
||||
leftMark = mark;
|
||||
}
|
||||
if(mark.name.equals(startGate.getRight().getName())) {
|
||||
rightMark = mark;
|
||||
}
|
||||
}
|
||||
if(leftMark != null && rightMark != null) {
|
||||
result.startGate = new Pair<MarkDTO, MarkDTO>(leftMark, rightMark);
|
||||
}
|
||||
if (firstWaypoint != null) {
|
||||
result.startBuoyPositions = getBuoyPositionDTOs(dateAsTimePoint, trackedRace, firstWaypoint);
|
||||
}
|
||||
Waypoint lastWaypoint = course.getLastWaypoint();
|
||||
if(lastWaypoint != null && lastWaypoint.getControlPoint() instanceof Gate) {
|
||||
Gate finishGate = (Gate) lastWaypoint.getControlPoint();
|
||||
MarkDTO leftMark = null;
|
||||
MarkDTO rightMark = null;
|
||||
for(MarkDTO mark: result.buoys) {
|
||||
if(mark.name.equals(finishGate.getLeft().getName())) {
|
||||
leftMark = mark;
|
||||
}
|
||||
if(mark.name.equals(finishGate.getRight().getName())) {
|
||||
rightMark = mark;
|
||||
}
|
||||
}
|
||||
if(leftMark != null && rightMark != null) {
|
||||
result.finishGate = new Pair<MarkDTO, MarkDTO>(leftMark, rightMark);
|
||||
}
|
||||
if (lastWaypoint != null) {
|
||||
result.finishBuoyPositions = getBuoyPositionDTOs(dateAsTimePoint, trackedRace, lastWaypoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<PositionDTO> getBuoyPositionDTOs(TimePoint timePoint, TrackedRace trackedRace, Waypoint waypoint) {
|
||||
List<PositionDTO> startBuoyPositions = new ArrayList<PositionDTO>();
|
||||
for (Buoy startBuoy : waypoint.getBuoys()) {
|
||||
final Position estimatedBuoyPosition = trackedRace.getOrCreateTrack(startBuoy)
|
||||
.getEstimatedPosition(timePoint, /* extrapolate */false);
|
||||
startBuoyPositions.add(new PositionDTO(estimatedBuoyPosition.getLatDeg(), estimatedBuoyPosition.getLngDeg()));
|
||||
}
|
||||
return startBuoyPositions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuickRankDTO> getQuickRanks(RaceIdentifier raceIdentifier, Date date) throws NoWindException {
|
||||
List<QuickRankDTO> result = new ArrayList<QuickRankDTO>();
|
||||
|
||||
+5
-6
@@ -1,14 +1,13 @@
|
||||
package com.sap.sailing.gwt.ui.shared;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
|
||||
public class CourseDTO implements IsSerializable {
|
||||
public Pair<MarkDTO, MarkDTO> startGate;
|
||||
|
||||
public Pair<MarkDTO, MarkDTO> finishGate;
|
||||
|
||||
public List<MarkDTO> buoys;
|
||||
public List<PositionDTO> waypointPositions;
|
||||
public List<PositionDTO> startBuoyPositions;
|
||||
public List<PositionDTO> finishBuoyPositions;
|
||||
public Set<MarkDTO> buoys;
|
||||
}
|
||||
+72
-54
@@ -637,26 +637,31 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
return LatLng.newInstance(lat2 / Math.PI * 180., lon2 / Math.PI * 180.);
|
||||
}
|
||||
|
||||
private Pair<Integer, CompetitorDTO> getLeadingVisibleCompetitorInfo(Iterable<CompetitorDTO> competitorsToShow) {
|
||||
CompetitorDTO leadingCompetitorDTO = null;
|
||||
int legOfLeaderCompetitor = -1;
|
||||
// this only works because the quickRanks are sorted
|
||||
for (QuickRankDTO quickRank : quickRanks) {
|
||||
if (Util.contains(competitorsToShow, quickRank.competitor)) {
|
||||
leadingCompetitorDTO = quickRank.competitor;
|
||||
legOfLeaderCompetitor = quickRank.legNumber;
|
||||
return new Pair<Integer, CompetitorDTO>(legOfLeaderCompetitor, leadingCompetitorDTO);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void showAdvantageLine(Iterable<CompetitorDTO> competitorsToShow) {
|
||||
if(map != null && lastRaceTimesInfo != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null && lastCombinedWindTrackInfoDTO.windFixes.size() > 0) {
|
||||
if (map != null && lastRaceTimesInfo != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null
|
||||
&& lastCombinedWindTrackInfoDTO.windFixes.size() > 0) {
|
||||
// find competitor with highest rank
|
||||
CompetitorDTO leadingCompetitorDTO = null;
|
||||
int legOfLeaderCompetitor = -1;
|
||||
// this only works because the quickRanks are sorted
|
||||
for (QuickRankDTO quickRank : quickRanks) {
|
||||
if(Util.contains(competitorsToShow, quickRank.competitor)) {
|
||||
leadingCompetitorDTO = quickRank.competitor;
|
||||
legOfLeaderCompetitor = quickRank.legNumber;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (leadingCompetitorDTO != null && getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.ADVANTAGELINE) &&
|
||||
lastShownFix.containsKey(leadingCompetitorDTO) && lastShownFix.get(leadingCompetitorDTO) != -1
|
||||
&& legOfLeaderCompetitor > 0 && legOfLeaderCompetitor <= lastRaceTimesInfo.getLegInfos().size()) {
|
||||
LegInfoDTO legInfoDTO = lastRaceTimesInfo.getLegInfos().get(legOfLeaderCompetitor-1);
|
||||
GPSFixDTO lastBoatFix = getBoatFix(leadingCompetitorDTO);
|
||||
Pair<Integer, CompetitorDTO> visibleLeaderInfo = getLeadingVisibleCompetitorInfo(competitorsToShow);
|
||||
if (visibleLeaderInfo != null && getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.ADVANTAGELINE) &&
|
||||
lastShownFix.containsKey(visibleLeaderInfo.getB()) && lastShownFix.get(visibleLeaderInfo.getB()) != -1
|
||||
&& visibleLeaderInfo.getA() > 0 && visibleLeaderInfo.getA() <= lastRaceTimesInfo.getLegInfos().size()) {
|
||||
LegInfoDTO legInfoDTO = lastRaceTimesInfo.getLegInfos().get(visibleLeaderInfo.getA()-1);
|
||||
GPSFixDTO lastBoatFix = getBoatFix(visibleLeaderInfo.getB());
|
||||
double advantageLineLengthInKm = 1.0;
|
||||
double distanceFromBoatPosition = 0.005; // 5m
|
||||
// implement and use Position.translateRhumb()
|
||||
@@ -727,16 +732,17 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
|
||||
private void showStartAndFinishLines(final CourseDTO courseDTO) {
|
||||
if(map != null && courseDTO != null && quickRanks != null && !quickRanks.isEmpty() && lastRaceTimesInfo != null) {
|
||||
int legOfLeadingCompetitor = quickRanks.get(0).legNumber;
|
||||
if (map != null && courseDTO != null && quickRanks != null && !quickRanks.isEmpty() && lastRaceTimesInfo != null) {
|
||||
Pair<Integer, CompetitorDTO> leadingVisibleCompetitorInfo = getLeadingVisibleCompetitorInfo(getCompetitorsToShow());
|
||||
int legOfLeadingCompetitor = leadingVisibleCompetitorInfo == null ? -1 : leadingVisibleCompetitorInfo.getA();
|
||||
int numberOfLegs = lastRaceTimesInfo.legInfos.size();
|
||||
// draw the start line
|
||||
if(courseDTO.startGate != null && legOfLeadingCompetitor == 1 &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.STARTLINE)) {
|
||||
if (legOfLeadingCompetitor == 1 &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.STARTLINE) && courseDTO.startBuoyPositions.size() == 2) {
|
||||
LatLng[] startGatePoints = new LatLng[2];
|
||||
startGatePoints[0] = LatLng.newInstance(courseDTO.startGate.getA().position.latDeg, courseDTO.startGate.getA().position.lngDeg);
|
||||
startGatePoints[1] = LatLng.newInstance(courseDTO.startGate.getB().position.latDeg, courseDTO.startGate.getB().position.lngDeg);
|
||||
if(startLine == null) {
|
||||
startGatePoints[0] = LatLng.newInstance(courseDTO.startBuoyPositions.get(0).latDeg, courseDTO.startBuoyPositions.get(0).lngDeg);
|
||||
startGatePoints[1] = LatLng.newInstance(courseDTO.startBuoyPositions.get(1).latDeg, courseDTO.startBuoyPositions.get(1).lngDeg);
|
||||
if (startLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
startLine = new Polyline(startGatePoints, /* color */ "#FFFFFF", /* width */ 1, /* opacity */1.0, options);
|
||||
startLine.addPolylineMouseOverHandler(new PolylineMouseOverHandler() {
|
||||
@@ -760,17 +766,17 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(startLine != null) {
|
||||
if (startLine != null) {
|
||||
startLine.deleteVertex(1);
|
||||
startLine.deleteVertex(0);
|
||||
}
|
||||
}
|
||||
// draw the finish line
|
||||
if(courseDTO.finishGate != null && legOfLeadingCompetitor == numberOfLegs &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.FINISHLINE)) {
|
||||
if (legOfLeadingCompetitor == numberOfLegs &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.FINISHLINE) && courseDTO.finishBuoyPositions.size() == 2) {
|
||||
LatLng[] finishGatePoints = new LatLng[2];
|
||||
finishGatePoints[0] = LatLng.newInstance(courseDTO.finishGate.getA().position.latDeg, courseDTO.finishGate.getA().position.lngDeg);
|
||||
finishGatePoints[1] = LatLng.newInstance(courseDTO.finishGate.getB().position.latDeg, courseDTO.finishGate.getB().position.lngDeg);
|
||||
finishGatePoints[0] = LatLng.newInstance(courseDTO.finishBuoyPositions.get(0).latDeg, courseDTO.finishBuoyPositions.get(0).lngDeg);
|
||||
finishGatePoints[1] = LatLng.newInstance(courseDTO.finishBuoyPositions.get(1).latDeg, courseDTO.finishBuoyPositions.get(1).lngDeg);
|
||||
if(finishLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
finishLine = new Polyline(finishGatePoints, /* color */ "#000000", /* width */ 1, /* opacity */1.0, options);
|
||||
@@ -795,22 +801,23 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(finishLine != null) {
|
||||
if (finishLine != null) {
|
||||
finishLine.deleteVertex(1);
|
||||
finishLine.deleteVertex(0);
|
||||
}
|
||||
}
|
||||
// draw the course middle line
|
||||
if(courseDTO.startGate != null && legOfLeadingCompetitor == 1 && courseDTO.buoys.size() >= 1 &&
|
||||
if (courseDTO.waypointPositions.size() > legOfLeadingCompetitor &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.COURSEMIDDLELINE)) {
|
||||
LatLng[] courseMiddleLinePoints = new LatLng[2];
|
||||
double p1Lat = (courseDTO.startGate.getA().position.latDeg + courseDTO.startGate.getB().position.latDeg) / 2.0;
|
||||
double p1Lng = (courseDTO.startGate.getA().position.lngDeg + courseDTO.startGate.getB().position.lngDeg) / 2.0;
|
||||
courseMiddleLinePoints[0] = LatLng.newInstance(p1Lat, p1Lng);
|
||||
courseMiddleLinePoints[1] = LatLng.newInstance(courseDTO.buoys.get(0).position.latDeg, courseDTO.buoys.get(0).position.lngDeg);
|
||||
if(courseMiddleLine == null) {
|
||||
double p1Lat = courseDTO.waypointPositions.get(legOfLeadingCompetitor-1).latDeg;
|
||||
double p1Lng = courseDTO.waypointPositions.get(legOfLeadingCompetitor-1).lngDeg;
|
||||
courseMiddleLinePoints[0] = LatLng.newInstance(p1Lat, p1Lng);
|
||||
courseMiddleLinePoints[1] = LatLng.newInstance(courseDTO.waypointPositions.get(legOfLeadingCompetitor).latDeg,
|
||||
courseDTO.waypointPositions.get(legOfLeadingCompetitor).lngDeg);
|
||||
if (courseMiddleLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
courseMiddleLine = new Polyline(courseMiddleLinePoints, /* color */ "#FF0000", /* width */ 1, /* opacity */1.0, options);
|
||||
courseMiddleLine = new Polyline(courseMiddleLinePoints, /* color */ "#666666", /* width */ 1, /* opacity */1.0, options);
|
||||
courseMiddleLine.addPolylineMouseOverHandler(new PolylineMouseOverHandler() {
|
||||
@Override
|
||||
public void onMouseOver(PolylineMouseOverEvent event) {
|
||||
@@ -1383,24 +1390,31 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
@Override
|
||||
public void removedFromSelection(CompetitorDTO competitor) {
|
||||
if (getSettings().isShowOnlySelectedCompetitors()) {
|
||||
// if selection is now empty, show all competitors
|
||||
if (Util.isEmpty(competitorSelection.getSelectedCompetitors())) {
|
||||
timeChanged(timer.getTime());
|
||||
} else {
|
||||
// otherwise remove only deselected competitor's boat images and tail
|
||||
BoatCanvasOverlay removed = boatCanvasOverlays.remove(competitor);
|
||||
if (removed != null) {
|
||||
map.removeOverlay(removed);
|
||||
}
|
||||
removeTail(competitor);
|
||||
}
|
||||
if (isShowAnyHelperLines()) {
|
||||
// helper lines depend on which competitor is visible, because the *visible* leader is used for
|
||||
// deciding which helper lines to show:
|
||||
timeChanged(timer.getTime());
|
||||
} else {
|
||||
// "lowlight" currently selected competitor
|
||||
BoatCanvasOverlay boatCanvas = boatCanvasOverlays.get(competitor);
|
||||
if (boatCanvas != null) {
|
||||
boatCanvas.setSelected(displayHighlighted(competitor));
|
||||
boatCanvas.redraw(true);
|
||||
// try a more incremental update otherwise
|
||||
if (getSettings().isShowOnlySelectedCompetitors()) {
|
||||
// if selection is now empty, show all competitors
|
||||
if (Util.isEmpty(competitorSelection.getSelectedCompetitors())) {
|
||||
timeChanged(timer.getTime());
|
||||
} else {
|
||||
// otherwise remove only deselected competitor's boat images and tail
|
||||
BoatCanvasOverlay removed = boatCanvasOverlays.remove(competitor);
|
||||
if (removed != null) {
|
||||
map.removeOverlay(removed);
|
||||
}
|
||||
removeTail(competitor);
|
||||
}
|
||||
} else {
|
||||
// "lowlight" currently selected competitor
|
||||
BoatCanvasOverlay boatCanvas = boatCanvasOverlays.get(competitor);
|
||||
if (boatCanvas != null) {
|
||||
boatCanvas.setSelected(displayHighlighted(competitor));
|
||||
boatCanvas.redraw(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Trigger auto-zoom if needed
|
||||
@@ -1410,6 +1424,10 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isShowAnyHelperLines() {
|
||||
return getSettings().getHelpLinesSettings().isShowAnyHelperLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedShortName() {
|
||||
return stringMessages.map();
|
||||
|
||||
+11
-14
@@ -1,7 +1,8 @@
|
||||
package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class RaceMapHelpLinesSettings {
|
||||
|
||||
@@ -12,29 +13,21 @@ public class RaceMapHelpLinesSettings {
|
||||
STARTLINE, FINISHLINE, ADVANTAGELINE, COURSEMIDDLELINE
|
||||
}
|
||||
|
||||
private ArrayList<HelpLineTypes> visibleHelpLines;
|
||||
private final Set<HelpLineTypes> visibleHelpLines;
|
||||
|
||||
/**
|
||||
* Creates new RaceMapHelpLinesSettings with the {@link HelpLineTypes} <code>STARTLINE</code>, <code>FINISHLINE</code> and <code>ADVANTAGELINE</code>.<br />
|
||||
*/
|
||||
public RaceMapHelpLinesSettings() {
|
||||
visibleHelpLines = new ArrayList<HelpLineTypes>();
|
||||
visibleHelpLines = new HashSet<HelpLineTypes>();
|
||||
visibleHelpLines.add(HelpLineTypes.STARTLINE);
|
||||
visibleHelpLines.add(HelpLineTypes.FINISHLINE);
|
||||
visibleHelpLines.add(HelpLineTypes.ADVANTAGELINE);
|
||||
visibleHelpLines.add(HelpLineTypes.COURSEMIDDLELINE);
|
||||
}
|
||||
|
||||
public RaceMapHelpLinesSettings(ArrayList<HelpLineTypes> visibleHelpLines) {
|
||||
this.visibleHelpLines = visibleHelpLines;
|
||||
}
|
||||
|
||||
public List<HelpLineTypes> getVisibleHelpLines() {
|
||||
return visibleHelpLines;
|
||||
}
|
||||
|
||||
public void setVisibleHelpLines(List<HelpLineTypes> visibleHelpLines) {
|
||||
this.visibleHelpLines = new ArrayList<HelpLineTypes>(visibleHelpLines);
|
||||
public RaceMapHelpLinesSettings(Collection<HelpLineTypes> visibleHelpLines) {
|
||||
this.visibleHelpLines = new HashSet<HelpLineTypes>(visibleHelpLines);
|
||||
}
|
||||
|
||||
public boolean containsHelpLine(HelpLineTypes helpLineType) {
|
||||
@@ -65,4 +58,8 @@ public class RaceMapHelpLinesSettings {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isShowAnyHelperLines() {
|
||||
return !visibleHelpLines.isEmpty();
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
@@ -169,7 +171,7 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
}
|
||||
|
||||
private RaceMapHelpLinesSettings getHelpLinesSettings() {
|
||||
ArrayList<HelpLineTypes> helpLineTypes = new ArrayList<HelpLineTypes>();
|
||||
Set<HelpLineTypes> helpLineTypes = new HashSet<HelpLineTypes>();
|
||||
for (Pair<CheckBox, HelpLineTypes> pair : checkboxAndHelpLineType) {
|
||||
if (pair.getA().getValue()) {
|
||||
helpLineTypes.add(pair.getB());
|
||||
|
||||
Reference in new issue
Block a user