diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java index 5f1b685ab4a..da98865c19c 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java @@ -7,10 +7,8 @@ import java.util.concurrent.ExecutorService; import com.sap.sailing.datamining.data.HasMarkPassingContext; import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext; import com.sap.sailing.datamining.impl.data.MarkPassingWithContext; -import com.sap.sailing.domain.common.ManeuverType; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.tracking.Maneuver; -import com.sap.sailing.domain.tracking.MarkPassingManeuver; import com.sap.sse.common.TimePoint; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor; @@ -30,8 +28,8 @@ public class MarkPassingRetrievalProcessor extends AbstractRetrievalProcessor maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false); for (Maneuver maneuver : maneuvers) { - if (maneuver.getType() == ManeuverType.MARK_PASSING) { - maneuversWithContext.add(new MarkPassingWithContext(element, (MarkPassingManeuver) maneuver)); + if (maneuver.isMarkPassing()) { + maneuversWithContext.add(new MarkPassingWithContext(element, maneuver)); } } } catch (NoWindException e) { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/MarkPassingWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/MarkPassingWithContext.java index 76923fef37e..130d37a57d3 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/MarkPassingWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/MarkPassingWithContext.java @@ -7,22 +7,22 @@ import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.common.NauticalSide; import com.sap.sailing.domain.common.Wind; import com.sap.sailing.domain.leaderboard.Leaderboard; -import com.sap.sailing.domain.tracking.MarkPassingManeuver; +import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.Util; public class MarkPassingWithContext implements HasMarkPassingContext { private static final long serialVersionUID = -337042113749307686L; private final HasTrackedLegOfCompetitorContext trackedLegOfCompetitor; - private final MarkPassingManeuver maneuver; + private final Maneuver maneuver; private Double absoluteRank; private boolean rankHasBeenInitialized; private Wind wind; - public MarkPassingWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitor, MarkPassingManeuver maneuver) { + public MarkPassingWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitor, Maneuver markPassingManeuver) { this.trackedLegOfCompetitor = trackedLegOfCompetitor; - this.maneuver = maneuver; + this.maneuver = markPassingManeuver; } @Override @@ -31,13 +31,13 @@ public class MarkPassingWithContext implements HasMarkPassingContext { } @Override - public MarkPassingManeuver getManeuver() { + public Maneuver getManeuver() { return maneuver; } @Override public Waypoint getWaypoint() { - return getManeuver().getWaypointPassed(); + return getManeuver().getMarkPassing().getWaypoint(); } @Override diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ManeuverType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ManeuverType.java index 6412b44b236..52eae29de56 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ManeuverType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ManeuverType.java @@ -1,5 +1,5 @@ package com.sap.sailing.domain.common; public enum ManeuverType { - HEAD_UP, BEAR_AWAY, TACK, JIBE, PENALTY_CIRCLE, MARK_PASSING, UNKNOWN; + HEAD_UP, BEAR_AWAY, TACK, JIBE, PENALTY_CIRCLE, UNKNOWN; } \ No newline at end of file diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java index ad2bbf6eb14..c9ec2114367 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java @@ -69,7 +69,6 @@ import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo; import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.MarkPassing; -import com.sap.sailing.domain.tracking.MarkPassingManeuver; import com.sap.sailing.domain.tracking.RaceChangeListener; import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; @@ -950,19 +949,18 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard { } } break; - case MARK_PASSING: - // analyze all mark passings, not only those after this leg's start, to catch the mark passing - // maneuver starting this leg, even if its time point is slightly before the mark passing starting this leg - MarkPassingManeuver mpm = (MarkPassingManeuver) maneuver; - if (mpm.getWaypointPassed() == trackedLeg.getLeg().getFrom()) { - result.sideToWhichMarkAtLegStartWasRounded = mpm.getSide(); - } - break; default: /* Do nothing here. * Throwing an exception destroys the toggling (and maybe other behaviour) of the leaderboard. */ } + if(maneuver.isMarkPassing()) { + // analyze all mark passings, not only those after this leg's start, to catch the mark passing + // maneuver starting this leg, even if its time point is slightly before the mark passing starting this leg + if (maneuver.getMarkPassing().getWaypoint() == trackedLeg.getLeg().getFrom()) { + result.sideToWhichMarkAtLegStartWasRounded = maneuver.getSide(); + } + } } result.averageManeuverLossInMeters = new HashMap(); for (ManeuverType maneuverType : new ManeuverType[] { ManeuverType.TACK, ManeuverType.JIBE, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java index ce1ba3c2410..9d4b0e29306 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java @@ -35,7 +35,6 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.impl.ManeuverWithMainCurveBoundariesImpl; import com.sap.sailing.domain.tracking.impl.ManeuverWithStableSpeedAndCourseBoundariesImpl; -import com.sap.sailing.domain.tracking.impl.MarkPassingManeuverImpl; import com.sap.sailing.domain.tracking.impl.SpeedWithBearingStepImpl; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; @@ -416,30 +415,15 @@ public class ManeuverDetectorImpl implements ManeuverDetector { maneuverMainCurveDetails.getTimePointBefore()); TrackedLegOfCompetitor legAfterManeuver = trackedRace.getTrackedLeg(competitor, maneuverMainCurveDetails.getTimePointAfter()); - Waypoint waypointPassed = null; // set for MARK_PASSING maneuvers only - NauticalSide sideToWhichWaypointWasPassed = null; // set for MARK_PASSING maneuvers only - // check for mask passing first; a tacking / jibe-setting mark rounding thus takes precedence over being - // detected as a penalty circle - final TimePoint markPassingTimePoint; + MarkPassing markPassing = null; // will remain null if no mark passing has been recorded within maneuver + // boundaries + // check whether a waypoint has been passed within maneuver if (legBeforeManeuver != legAfterManeuver // a maneuver at the start line is not to be considered a MARK_PASSING maneuver; show a tack as a tack && legAfterManeuver != null && legAfterManeuver.getLeg().getFrom() != trackedRace.getRace().getCourse().getFirstWaypoint()) { - waypointPassed = legAfterManeuver.getLeg().getFrom(); - MarkPassing markPassing = trackedRace.getMarkPassing(competitor, waypointPassed); - markPassingTimePoint = markPassing != null ? markPassing.getTimePoint() : maneuverDetails.getTimePoint(); - Position markPassingPosition = markPassing != null - ? competitorTrack.getEstimatedPosition(markPassingTimePoint, /* extrapolate */false) - : maneuverPosition; - sideToWhichWaypointWasPassed = maneuverDirection; - // produce an additional mark passing maneuver; continue to analyze to catch jibe sets and kiwi drops - maneuvers.add(new MarkPassingManeuverImpl(ManeuverType.MARK_PASSING, tackAfterManeuver, markPassingPosition, - maneuverLoss, markPassingTimePoint, maneuverMainCurveDetails.extractCurveBoundariesOnly(), - maneuverDetails.extractCurveBoundariesOnly(), - maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond(), waypointPassed, - sideToWhichWaypointWasPassed)); - } else { - markPassingTimePoint = null; + Waypoint waypointPassed = legAfterManeuver.getLeg().getFrom(); + markPassing = trackedRace.getMarkPassing(competitor, waypointPassed); } BearingChangeAnalyzer bearingChangeAnalyzer = BearingChangeAnalyzer.INSTANCE; final Bearing courseBeforeManeuver = maneuverMainCurveDetails.getSpeedWithBearingBefore().getBearing(); @@ -451,26 +435,40 @@ public class ManeuverDetectorImpl implements ManeuverDetector { int numberOfTacks = wind == null ? 0 : bearingChangeAnalyzer.didPass(courseBeforeManeuver, mainCurveTotalCourseChangeInDegrees, courseAfterManeuver, wind.getFrom()); - if (markPassingTimePoint != null && (numberOfTacks + numberOfJibes > 0)) { - // In case of a mark passing we need to split the maneuver analysis into the phase before and after - // the mark passing. First of all, this is important to identify the correct maneuver time point for - // each tack and jibe, second it is essential to call a penalty which is only the case if the tack and - // the jibe are on the same side of the mark passing; otherwise this may have been a jibe set or a - // kiwi drop. - // Therefore, we recursively detect the maneuvers for the segment before and the segment after the - // mark passing and add the results to our result. - List maneuverSpots = detectManeuvers(maneuverDetails.getTimePointBefore(), - markPassingTimePoint.minus(1)); - maneuverSpots.addAll(detectManeuvers(markPassingTimePoint.plus(1), maneuverDetails.getTimePointAfter())); - maneuvers.addAll(getAllManeuversFromManeuverSpots(maneuverSpots)); - } else { - // Either there was no mark passing, or the mark passing was not accompanied by a tack or a jibe. - // For the first tack/jibe combination (they must alternate because the course changes in the same direction - // and - // the wind is considered sufficiently stable to not allow for two successive tacks or two successive jibes) - // we create a PENALTY_CIRCLE maneuver and recurse for the time interval after the first penalty circle has - // completed. - if (numberOfTacks > 0 && numberOfJibes > 0 && markPassingTimePoint == null) { + if (numberOfTacks > 0 && numberOfJibes > 0) { + boolean performPenaltyCircleAnalysis = true; + if (markPassing != null) { + // In case of a mark passing we need to split the maneuver analysis into the phase before and after + // the mark passing to catch kiwi drops. First of all, this is important to identify the correct + // maneuver time point for + // each tack and jibe, second it is essential to call a penalty which is only the case if the tack and + // the jibe are on the same side of the mark passing; otherwise this may have been a + // kiwi drop. + // Therefore, we recursively detect the maneuvers for the segment before and the segment after the + // mark passing and add the results to our result. + List maneuverSpotsBeforeMarkPassing = detectManeuvers( + maneuverDetails.getTimePointBefore(), markPassing.getTimePoint().minus(1)); + List maneuverSpotsAfterMarkPassing = detectManeuvers(markPassing.getTimePoint().plus(1), + maneuverDetails.getTimePointAfter()); + // split the penalty circle maneuver only by mark passing time point if tacks or jibes are present on + // both legs + if (getNumberOfTacksAndJibesFromManeuverSpots(maneuverSpotsAfterMarkPassing) != 0 + && getNumberOfTacksAndJibesFromManeuverSpots(maneuverSpotsAfterMarkPassing) != 0) { + performPenaltyCircleAnalysis = false; + maneuverSpotsBeforeMarkPassing.addAll(maneuverSpotsAfterMarkPassing); + maneuvers.addAll(getAllManeuversFromManeuverSpots(maneuverSpotsBeforeMarkPassing)); + } + } + if (performPenaltyCircleAnalysis) { + // Either there was no mark passing, or the mark passing was not accompanied by a tack or a jibe. + // For the first tack/jibe combination (they must alternate because the course changes in the same + // direction + // and + // the wind is considered sufficiently stable to not allow for two successive tacks or two successive + // jibes) + // we create a PENALTY_CIRCLE maneuver and recurse for the time interval after the first penalty circle + // has + // completed. TimePoint firstPenaltyCircleCompletedAt = getTimePointOfCompletionOfFirstPenaltyCircle( maneuverMainCurveDetails.getTimePointBefore(), courseBeforeManeuver, maneuverMainCurveDetails.getSpeedWithBearingSteps(), wind); @@ -511,7 +509,7 @@ public class ManeuverDetectorImpl implements ManeuverDetector { tackAfterManeuver, penaltyPosition, maneuverLoss, refinedPenaltyDetails.getTimePoint(), refinedPenaltyMainCurveDetails.extractCurveBoundariesOnly(), refinedPenaltyDetails.extractCurveBoundariesOnly(), - refinedPenaltyMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond()); + refinedPenaltyMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond(), markPassing); maneuvers.add(maneuver); // after we've "consumed" one tack and one jibe, recursively find more maneuvers if tacks and/or jibes // remain @@ -520,52 +518,74 @@ public class ManeuverDetectorImpl implements ManeuverDetector { maneuverDetails.getTimePointAfter()); maneuvers.addAll(getAllManeuversFromManeuverSpots(maneuverSpots)); } - } else { - final Maneuver maneuver; - if (numberOfTacks > 0 || numberOfJibes > 0) { - maneuverType = numberOfTacks > 0 ? ManeuverType.TACK : ManeuverType.JIBE; - maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(), maneuverDetails.getTimePoint(), - maneuverDetails.getTimePointAfter()); - maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver, - maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(), - maneuverMainCurveDetails.extractCurveBoundariesOnly(), - maneuverDetails.extractCurveBoundariesOnly(), - maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond()); - } else if (wind != null) { - // heading up or bearing away - Bearing windBearing = wind.getBearing(); - Bearing toWindBeforeManeuver = windBearing - .getDifferenceTo(maneuverMainCurveDetails.getSpeedWithBearingBefore().getBearing()); - Bearing toWindAfterManeuver = windBearing - .getDifferenceTo(maneuverMainCurveDetails.getSpeedWithBearingAfter().getBearing()); - maneuverType = Math.abs(toWindBeforeManeuver.getDegrees()) < Math - .abs(toWindAfterManeuver.getDegrees()) ? ManeuverType.HEAD_UP : ManeuverType.BEAR_AWAY; - // treat maneuver main curve details as main maneuver details, because the detected maneuver is - // either HEAD_UP or BEAR_AWAY - maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, - maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(), - maneuverMainCurveDetails.extractCurveBoundariesOnly(), - maneuverDetails.extractCurveBoundariesOnly(), - maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond()); - } else { - // no wind information; marking as UNKNOWN - maneuverType = ManeuverType.UNKNOWN; - maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(), maneuverDetails.getTimePoint(), - maneuverDetails.getTimePointAfter()); - maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver, - maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(), - maneuverMainCurveDetails.extractCurveBoundariesOnly(), - maneuverDetails.extractCurveBoundariesOnly(), - maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond()); - } - maneuvers.add(maneuver); } + } else { + final Maneuver maneuver; + if (numberOfTacks > 0 || numberOfJibes > 0) { + maneuverType = numberOfTacks > 0 ? ManeuverType.TACK : ManeuverType.JIBE; + maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(), maneuverDetails.getTimePoint(), + maneuverDetails.getTimePointAfter()); + maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver, + maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(), + maneuverMainCurveDetails.extractCurveBoundariesOnly(), + maneuverDetails.extractCurveBoundariesOnly(), + maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond(), markPassing); + } else if (wind != null) { + // heading up or bearing away + Bearing windBearing = wind.getBearing(); + Bearing toWindBeforeManeuver = windBearing + .getDifferenceTo(maneuverMainCurveDetails.getSpeedWithBearingBefore().getBearing()); + Bearing toWindAfterManeuver = windBearing + .getDifferenceTo(maneuverMainCurveDetails.getSpeedWithBearingAfter().getBearing()); + maneuverType = Math.abs(toWindBeforeManeuver.getDegrees()) < Math.abs(toWindAfterManeuver.getDegrees()) + ? ManeuverType.HEAD_UP : ManeuverType.BEAR_AWAY; + // treat maneuver main curve details as main maneuver details, because the detected maneuver is + // either HEAD_UP or BEAR_AWAY + maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition, + maneuverLoss, maneuverDetails.getTimePoint(), + maneuverMainCurveDetails.extractCurveBoundariesOnly(), + maneuverDetails.extractCurveBoundariesOnly(), + maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond(), markPassing); + } else { + // no wind information; marking as UNKNOWN + maneuverType = ManeuverType.UNKNOWN; + maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(), maneuverDetails.getTimePoint(), + maneuverDetails.getTimePointAfter()); + maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver, + maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(), + maneuverMainCurveDetails.extractCurveBoundariesOnly(), + maneuverDetails.extractCurveBoundariesOnly(), + maneuverMainCurveDetails.getMaxAngularVelocityInDegreesPerSecond(), markPassing); + } + maneuvers.add(maneuver); } return new ManeuverSpot(new ArrayList<>(douglasPeuckerFixesGroup), maneuverDirection, maneuvers, new WindMeasurement(maneuverDetails.getTimePoint(), maneuverPosition, wind == null ? null : wind.getBearing())); } + private int getNumberOfTacksAndJibesFromManeuverSpots(List maneuverSpots) { + int tackAndJibeCount = 0; + for (ManeuverSpot maneuverSpot : maneuverSpots) { + for (Maneuver maneuver : maneuverSpot.getManeuvers()) { + switch (maneuver.getType()) { + case JIBE: + case TACK: + ++tackAndJibeCount; + break; + case PENALTY_CIRCLE: + tackAndJibeCount += 2; + break; + case BEAR_AWAY: + case HEAD_UP: + case UNKNOWN: + break; + } + } + } + return tackAndJibeCount; + } + /** * Computes the maneuver loss as the distance projected onto the average course between entering and exiting the * maneuver that the boat lost compared to not having maneuvered. With this distance measure, the competitors speed diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Maneuver.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Maneuver.java index 9ab81f3dfae..b30061f143e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Maneuver.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Maneuver.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.tracking; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.ManeuverType; +import com.sap.sailing.domain.common.NauticalSide; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.SpeedWithBearing; import com.sap.sailing.domain.common.Tack; @@ -141,4 +142,20 @@ public interface Maneuver extends GPSFix { */ Speed getLowestSpeed(); + /** + * Gets the mark passing which is contained within maneuver. In case if no mark passing was passed, {@code null} is + * returned. + */ + MarkPassing getMarkPassing(); + + /** + * Determines whether the maneuver is mark passing maneuver. + */ + boolean isMarkPassing(); + + /** + * Gets the direction of the maneuver. It corresponds to the direction of mark passing side. + */ + NauticalSide getSide(); + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/MarkPassingManeuver.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/MarkPassingManeuver.java deleted file mode 100755 index e12ae4e7218..00000000000 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/MarkPassingManeuver.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sap.sailing.domain.tracking; - -import com.sap.sailing.domain.base.Waypoint; -import com.sap.sailing.domain.common.NauticalSide; - -public interface MarkPassingManeuver extends Maneuver { - Waypoint getWaypointPassed(); - - NauticalSide getSide(); -} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverImpl.java index 6ad3b871da7..653285bc44a 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverImpl.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.tracking.impl; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.ManeuverType; +import com.sap.sailing.domain.common.NauticalSide; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.SpeedWithBearing; @@ -9,6 +10,7 @@ import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.common.tracking.impl.AbstractGPSFixImpl; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries; +import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sse.common.TimePoint; /** @@ -25,11 +27,12 @@ public abstract class ManeuverImpl extends AbstractGPSFixImpl implements Maneuve private final double maxAngularVelocityInDegreesPerSecond; private final ManeuverCurveBoundaries mainCurveBoundaries; private final ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries; + private final MarkPassing markPassing; public ManeuverImpl(ManeuverType type, Tack newTack, Position position, Distance maneuverLoss, TimePoint timePoint, ManeuverCurveBoundaries mainCurveBoundaries, ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries, - double maxAngularVelocityInDegreesPerSecond) { + double maxAngularVelocityInDegreesPerSecond, MarkPassing markPassing) { this.type = type; this.newTack = newTack; this.position = position; @@ -38,6 +41,7 @@ public abstract class ManeuverImpl extends AbstractGPSFixImpl implements Maneuve this.mainCurveBoundaries = mainCurveBoundaries; this.maneuverCurveWithStableSpeedAndCourseBoundaries = maneuverCurveWithStableSpeedAndCourseBoundaries; this.maxAngularVelocityInDegreesPerSecond = maxAngularVelocityInDegreesPerSecond; + this.markPassing = markPassing; } @Override @@ -100,7 +104,8 @@ public abstract class ManeuverImpl extends AbstractGPSFixImpl implements Maneuve return super.toString() + " " + type + " on new tack " + newTack + " on position " + position + " at time point " + timePoint + ", " + getManeuverBoundaries() + ", max. angular velocity: " + maxAngularVelocityInDegreesPerSecond - + (getManeuverLoss() == null ? "" : " Lost approximately " + getManeuverLoss()); + + (getManeuverLoss() == null ? "" : ", Lost approximately " + getManeuverLoss()) + ", Mark passing: " + + markPassing; } @Override @@ -108,4 +113,16 @@ public abstract class ManeuverImpl extends AbstractGPSFixImpl implements Maneuve return maxAngularVelocityInDegreesPerSecond; } + public MarkPassing getMarkPassing() { + return markPassing; + } + + public boolean isMarkPassing() { + return markPassing != null; + } + + public NauticalSide getSide() { + return getMainCurveBoundaries().getDirectionChangeInDegrees() < 0 ? NauticalSide.PORT : NauticalSide.STARBOARD; + } + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithMainCurveBoundariesImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithMainCurveBoundariesImpl.java index bc72c7ea9c9..3872f48d81e 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithMainCurveBoundariesImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithMainCurveBoundariesImpl.java @@ -6,6 +6,7 @@ import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries; +import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sse.common.TimePoint; /** @@ -21,9 +22,9 @@ public class ManeuverWithMainCurveBoundariesImpl extends ManeuverImpl { public ManeuverWithMainCurveBoundariesImpl(ManeuverType type, Tack newTack, Position position, Distance maneuverLoss, TimePoint timePoint, ManeuverCurveBoundaries mainCurveBoundaries, ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries, - double maxAngularVelocityInDegreesPerSecond) { + double maxAngularVelocityInDegreesPerSecond, MarkPassing markPassing) { super(type, newTack, position, maneuverLoss, timePoint, mainCurveBoundaries, - maneuverCurveWithStableSpeedAndCourseBoundaries, maxAngularVelocityInDegreesPerSecond); + maneuverCurveWithStableSpeedAndCourseBoundaries, maxAngularVelocityInDegreesPerSecond, markPassing); } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithStableSpeedAndCourseBoundariesImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithStableSpeedAndCourseBoundariesImpl.java index ec97c52b344..091a76f425a 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithStableSpeedAndCourseBoundariesImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverWithStableSpeedAndCourseBoundariesImpl.java @@ -6,6 +6,7 @@ import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries; +import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sse.common.TimePoint; /** @@ -22,9 +23,9 @@ public class ManeuverWithStableSpeedAndCourseBoundariesImpl extends ManeuverImpl public ManeuverWithStableSpeedAndCourseBoundariesImpl(ManeuverType type, Tack newTack, Position position, Distance maneuverLoss, TimePoint timePoint, ManeuverCurveBoundaries mainCurveBoundaries, ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries, - double maxAngularVelocityInDegreesPerSecond) { + double maxAngularVelocityInDegreesPerSecond, MarkPassing markPassing) { super(type, newTack, position, maneuverLoss, timePoint, mainCurveBoundaries, - maneuverCurveWithStableSpeedAndCourseBoundaries, maxAngularVelocityInDegreesPerSecond); + maneuverCurveWithStableSpeedAndCourseBoundaries, maxAngularVelocityInDegreesPerSecond, markPassing); } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingManeuverImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingManeuverImpl.java deleted file mode 100755 index 02dab346f74..00000000000 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingManeuverImpl.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sap.sailing.domain.tracking.impl; - -import com.sap.sailing.domain.base.Waypoint; -import com.sap.sailing.domain.common.Distance; -import com.sap.sailing.domain.common.ManeuverType; -import com.sap.sailing.domain.common.NauticalSide; -import com.sap.sailing.domain.common.Position; -import com.sap.sailing.domain.common.Tack; -import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries; -import com.sap.sailing.domain.tracking.MarkPassingManeuver; -import com.sap.sse.common.TimePoint; - -public class MarkPassingManeuverImpl extends ManeuverWithStableSpeedAndCourseBoundariesImpl - implements MarkPassingManeuver { - private static final long serialVersionUID = 8935348908557191614L; - private final Waypoint waypointPassed; - private final NauticalSide side; - - public MarkPassingManeuverImpl(ManeuverType type, Tack newTack, Position position, Distance maneuverLoss, - TimePoint timePoint, ManeuverCurveBoundaries mainCurveBoundaries, - ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries, - double maxAngularVelocityInDegreesPerSecond, Waypoint waypointPassed, NauticalSide side) { - super(type, newTack, position, maneuverLoss, timePoint, mainCurveBoundaries, - maneuverCurveWithStableSpeedAndCourseBoundaries, maxAngularVelocityInDegreesPerSecond); - this.waypointPassed = waypointPassed; - this.side = side; - } - - @Override - public Waypoint getWaypointPassed() { - return waypointPassed; - } - - @Override - public NauticalSide getSide() { - return side; - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(super.toString()); - result.append(", passed waypoint " + getWaypointPassed() + " to " + getSide().name()); - return result.toString(); - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/ManeuverTypeFormatter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/ManeuverTypeFormatter.java index d6dd1df4c21..240e60b0e68 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/ManeuverTypeFormatter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/ManeuverTypeFormatter.java @@ -11,8 +11,6 @@ public class ManeuverTypeFormatter { return stringMessages.headUp(); case JIBE: return stringMessages.jibe(); - case MARK_PASSING: - return stringMessages.markPassing(); case PENALTY_CIRCLE: return stringMessages.penaltyCircle(); case TACK: diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 4e2883ead2f..31d78833c5c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -199,7 +199,6 @@ import com.sap.sailing.domain.common.LeaderboardNameConstants; import com.sap.sailing.domain.common.LeaderboardType; import com.sap.sailing.domain.common.LegIdentifier; import com.sap.sailing.domain.common.LegType; -import com.sap.sailing.domain.common.ManeuverType; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NotFoundException; @@ -334,7 +333,6 @@ import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.LineDetails; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.MarkPassing; -import com.sap.sailing.domain.tracking.MarkPassingManeuver; import com.sap.sailing.domain.tracking.RaceHandle; import com.sap.sailing.domain.tracking.RaceTracker; import com.sap.sailing.domain.tracking.Track; @@ -3419,14 +3417,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S List result = new ArrayList(); for (Maneuver maneuver : maneuvers) { final ManeuverDTO maneuverDTO; - if (maneuver.getType() == ManeuverType.MARK_PASSING) { + if (maneuver.isMarkPassing()) { maneuverDTO = new MarkpassingManeuverDTO(maneuver.getType(), maneuver.getNewTack(), maneuver.getPosition(), maneuver.getTimePoint().asDate(), createSpeedWithBearingDTO(maneuver.getSpeedWithBearingBefore()), createSpeedWithBearingDTO(maneuver.getSpeedWithBearingAfter()), maneuver.getDirectionChangeInDegrees(), maneuver.getManeuverLoss()==null?null:maneuver.getManeuverLoss().getMeters(), - ((MarkPassingManeuver) maneuver).getSide()); + maneuver.getSide()); } else { maneuverDTO = new ManeuverDTO(maneuver.getType(), maneuver.getNewTack(), maneuver.getPosition(),