java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/FieldNames.java
... ...
@@ -198,7 +198,7 @@ public enum FieldNames {
198 198
MARK_PASSINGS_FINGERPRINT, MARK_PASSINGS,
199 199
200 200
// MANEUVERS collection:
201
- MANEUVER_FINGERPRINT, MANEUVERS, TYPE, TACK, POSITION_LAT_RAD, POSITION_LNG_RAD, TIMEPOINT, MAIN_CURVE_BOUNDARIES,
201
+ MANEUVER_FINGERPRINT, MANEUVERS, SIMPLE_CLASS_NAME, TYPE, TACK, POSITION_LAT_RAD, POSITION_LNG_RAD, TIMEPOINT, MAIN_CURVE_BOUNDARIES,
202 202
MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES, MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND, MANEUVER_LOSS,
203 203
// MANEUVERS main curve boundaries properties, see MAIN_CURVE_BOUNDARIES field above
204 204
MANEUVER_TIMEPOINT_BEFORE, MANEUVER_TIMEPOINT_AFTER, MANEUVER_SPEED_WITH_BEARING_BEFORE, MANEUVER_SPEED_WITH_BEARING_AFTER,
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
... ...
@@ -262,7 +262,6 @@ import com.sap.sailing.domain.tracking.TrackedRace;
262 262
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
263 263
import com.sap.sailing.domain.tracking.WindTrack;
264 264
import com.sap.sailing.domain.tracking.impl.ManeuverCurveBoundariesImpl;
265
-import com.sap.sailing.domain.tracking.impl.ManeuverWithMainCurveBoundariesImpl;
266 265
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
267 266
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
268 267
import com.sap.sailing.server.gateway.deserialization.impl.BoatJsonDeserializer;
... ...
@@ -3353,7 +3352,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3353 3352
}
3354 3353
3355 3354
private Maneuver loadManeuver(Competitor competitor, Document maneuverDoc, Course course, TrackedRace trackedRace) {
3356
- final TimePoint timePoint = TimePoint.of( maneuverDoc.getLong(FieldNames.TIMEPOINT.name()));
3355
+ final String simpleClassName = maneuverDoc.getString(FieldNames.SIMPLE_CLASS_NAME.name());
3356
+ final TimePoint timePoint = TimePoint.of(maneuverDoc.getLong(FieldNames.TIMEPOINT.name()));
3357 3357
final double maxTurningRateInDegreesPerSecond = maneuverDoc.getDouble(FieldNames.MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND.name());
3358 3358
final String typeName = maneuverDoc.getString(FieldNames.TYPE.name());
3359 3359
final ManeuverType type = ManeuverType.valueOf(typeName);
... ...
@@ -3372,7 +3372,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3372 3372
} else {
3373 3373
markPassing = new MarkPassingProxy(timePoint, waypointIndex, competitor.getId(), trackedRace);
3374 3374
}
3375
- return new ManeuverWithMainCurveBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries,
3375
+ return Maneuver.create(simpleClassName, type, newTack, position, timePoint, mainCurveBoundaries,
3376 3376
maneuverCurveWithStableSpeedAndCourseBoundaries, maxTurningRateInDegreesPerSecond, markPassing,
3377 3377
maneuverLoss);
3378 3378
}
... ...
@@ -3405,21 +3405,21 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3405 3405
private ManeuverCurveBoundaries loadManeuverCurveBoundaries(Document document) {
3406 3406
final TimePoint timePointBefore = TimePoint.of(document.getLong(FieldNames.MANEUVER_TIMEPOINT_BEFORE.name()));
3407 3407
final TimePoint timePointAfter = TimePoint.of(document.getLong(FieldNames.MANEUVER_TIMEPOINT_AFTER.name()));
3408
- final Double SpeedWithBearingBeforeDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3409
- final Double SpeedWithBearingBeforeSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name());
3410
- final Bearing bearingBefore = new DegreeBearingImpl(SpeedWithBearingBeforeDegrees);
3411
- final SpeedWithBearing SpeedWithBearingBefore = new KnotSpeedWithBearingImpl(SpeedWithBearingBeforeSpeed, bearingBefore);
3412
- final Double SpeedWithBearingAfterDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_DEGREES.name());
3413
- final Double SpeedWithBearingAfterSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_SPEED.name());
3414
- final Bearing bearingAfter = new DegreeBearingImpl(SpeedWithBearingAfterSpeed);
3415
- final SpeedWithBearing SpeedWithBearingAfter = new KnotSpeedWithBearingImpl(SpeedWithBearingAfterDegrees, bearingAfter);
3408
+ final Double speedWithBearingBeforeDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3409
+ final Double speedWithBearingBeforeSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name());
3410
+ final Bearing bearingBefore = new DegreeBearingImpl(speedWithBearingBeforeDegrees);
3411
+ final SpeedWithBearing speedWithBearingBefore = new KnotSpeedWithBearingImpl(speedWithBearingBeforeSpeed, bearingBefore);
3412
+ final Double speedWithBearingAfterDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_DEGREES.name());
3413
+ final Double speedWithBearingAfterSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_SPEED.name());
3414
+ final Bearing bearingAfter = new DegreeBearingImpl(speedWithBearingAfterSpeed);
3415
+ final SpeedWithBearing speedWithBearingAfter = new KnotSpeedWithBearingImpl(speedWithBearingAfterDegrees, bearingAfter);
3416 3416
final double directionChangeInDegrees = document.getDouble(FieldNames.MANEUVER_DIRECTION_CHANGE_IN_DEGREES.name());
3417 3417
final double lowestSpeedDouble = document.getDouble(FieldNames.MANEUVER_LOWEST_SPEED.name());
3418 3418
final Speed lowestSpeed = new KnotSpeedImpl(lowestSpeedDouble);
3419 3419
final double highestSpeedDouble = document.getDouble(FieldNames.MANEUVER_HIGHEST_SPEED.name());
3420 3420
final Speed highestSpeed = new KnotSpeedImpl(highestSpeedDouble);
3421
- ManeuverCurveBoundaries maneuverCurveBoundaries = new ManeuverCurveBoundariesImpl(timePointBefore,
3422
- timePointAfter, SpeedWithBearingBefore, SpeedWithBearingAfter, directionChangeInDegrees, lowestSpeed,
3421
+ final ManeuverCurveBoundaries maneuverCurveBoundaries = new ManeuverCurveBoundariesImpl(timePointBefore,
3422
+ timePointAfter, speedWithBearingBefore, speedWithBearingAfter, directionChangeInDegrees, lowestSpeed,
3423 3423
highestSpeed);
3424 3424
return maneuverCurveBoundaries;
3425 3425
}
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
... ...
@@ -2046,6 +2046,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
2046 2046
if (e.getValue() != null) {
2047 2047
for (final Maneuver maneuver : e.getValue()) {
2048 2048
final Document maneuverDoc = new Document();
2049
+ maneuverDoc.put(FieldNames.SIMPLE_CLASS_NAME.name(), maneuver.getClass().getSimpleName());
2049 2050
maneuverDoc.put(FieldNames.TYPE.name(), maneuver.getType().name());
2050 2051
maneuverDoc.put(FieldNames.TACK.name(), maneuver.getNewTack().name());
2051 2052
maneuverDoc.put(FieldNames.POSITION_LAT_RAD.name(), maneuver.getPosition().getLatRad());
... ...
@@ -2070,12 +2071,12 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
2070 2071
2071 2072
private Document storeManeuverLoss(ManeuverLoss maneuverLoss) {
2072 2073
final Document maneuverLossDoc = new Document();
2073
- maneuverLossDoc.put(FieldNames.MANEUVER_DISTANCE_SAILED_POMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2074
+ maneuverLossDoc.put(FieldNames.MANEUVER_DISTANCE_SAILED_POMA.name(), maneuverLoss.getDistanceSailedProjectedOnMiddleManeuverAngle().getMeters());
2074 2075
maneuverLossDoc.put(FieldNames.MANEUVER_DISTANCE_SAILED_INMPOMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2075 2076
maneuverLossDoc.put(FieldNames.MANEUVER_START_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLatRad());
2076 2077
maneuverLossDoc.put(FieldNames.MANEUVER_START_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2077
- maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2078
- maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2078
+ maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverEndPosition().getLatRad());
2079
+ maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverEndPosition().getLngRad());
2079 2080
maneuverLossDoc.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name(), maneuverLoss.getSpeedWithBearingBefore().getBearing().getDegrees());
2080 2081
maneuverLossDoc.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name(), maneuverLoss.getSpeedWithBearingBefore().getKnots());
2081 2082
maneuverLossDoc.put(FieldNames.MIDDLE_MAEUVER_ANGLE.name(), maneuverLoss.getMiddleManeuverAngle().getDegrees());
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Maneuver.java
... ...
@@ -5,7 +5,11 @@ import com.sap.sailing.domain.common.NauticalSide;
5 5
import com.sap.sailing.domain.common.Tack;
6 6
import com.sap.sailing.domain.common.tracking.GPSFix;
7 7
import com.sap.sailing.domain.maneuverdetection.impl.ManeuverDetectorImpl;
8
+import com.sap.sailing.domain.tracking.impl.ManeuverWithCoarseGrainedBoundariesImpl;
9
+import com.sap.sailing.domain.tracking.impl.ManeuverWithMainCurveBoundariesImpl;
10
+import com.sap.sailing.domain.tracking.impl.ManeuverWithStableSpeedAndCourseBoundariesImpl;
8 11
import com.sap.sse.common.Duration;
12
+import com.sap.sse.common.Position;
9 13
import com.sap.sse.common.Speed;
10 14
import com.sap.sse.common.SpeedWithBearing;
11 15
import com.sap.sse.common.TimePoint;
... ...
@@ -38,6 +42,26 @@ import com.sap.sse.datamining.annotations.Statistic;
38 42
*
39 43
*/
40 44
public interface Maneuver extends GPSFix {
45
+ static Maneuver create(String simpleClassName, ManeuverType type, Tack newTack, Position position, TimePoint timePoint,
46
+ ManeuverCurveBoundaries mainCurveBoundaries,
47
+ ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries,
48
+ double maxTurningRateInDegreesPerSecond, MarkPassing markPassing, ManeuverLoss maneuverLoss) {
49
+ final Maneuver result;
50
+ if (simpleClassName.equals(ManeuverWithCoarseGrainedBoundariesImpl.class.getSimpleName())) {
51
+ result = new ManeuverWithCoarseGrainedBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries);
52
+ } else if (simpleClassName.equals(ManeuverWithMainCurveBoundariesImpl.class.getSimpleName())) {
53
+ result = new ManeuverWithMainCurveBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries,
54
+ maneuverCurveWithStableSpeedAndCourseBoundaries, maxTurningRateInDegreesPerSecond, markPassing,
55
+ maneuverLoss);
56
+ } else if (simpleClassName.equals(ManeuverWithStableSpeedAndCourseBoundariesImpl.class.getSimpleName())) {
57
+ result = new ManeuverWithStableSpeedAndCourseBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries,
58
+ maneuverCurveWithStableSpeedAndCourseBoundaries, maxTurningRateInDegreesPerSecond, markPassing,
59
+ maneuverLoss);
60
+ } else {
61
+ throw new IllegalArgumentException("Unsupported Maneuver implementation with simple class name: " + simpleClassName);
62
+ }
63
+ return result;
64
+ }
41 65
/**
42 66
* Gets the type of this maneuver, e.g. whether its a tack, jibe and etc. The maneuver type is determined
43 67
* considering the boat's course change, wind bearing and marks.
java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/ManeuverRaceFingerprintConversionTest.java
... ...
@@ -7,6 +7,7 @@ import java.net.MalformedURLException;
7 7
import java.net.URISyntaxException;
8 8
import java.net.UnknownHostException;
9 9
import java.util.HashMap;
10
+import java.util.Iterator;
10 11
import java.util.List;
11 12
import java.util.Map;
12 13
... ...
@@ -26,6 +27,7 @@ import com.sap.sailing.domain.persistence.PersistenceFactory;
26 27
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
27 28
import com.sap.sailing.domain.test.OnlineTracTracBasedTest;
28 29
import com.sap.sailing.domain.tracking.Maneuver;
30
+import com.sap.sailing.domain.tracking.ManeuverLoss;
29 31
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
30 32
import com.sap.sailing.domain.tractracadapter.ReceiverType;
31 33
import com.sap.sse.mongodb.MongoDBConfiguration;
... ...
@@ -69,8 +71,8 @@ public class ManeuverRaceFingerprintConversionTest extends OnlineTracTracBasedTe
69 71
final RaceIdentifier raceIdentifier = trackedRace1.getRaceIdentifier();
70 72
final Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
71 73
for (final Competitor competitor : getRace().getCompetitors()) {
72
- final List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, true);
73
- maneuvers.put(competitor,maneuversForCompetitor);
74
+ final List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, /* wait for latest */ true);
75
+ maneuvers.put(competitor, maneuversForCompetitor);
74 76
}
75 77
new MongoObjectFactoryImpl(firstDatabase).storeManeuvers(raceIdentifier, fingerprint, trackedRace1.getRace().getCourse(), maneuvers);
76 78
final DomainObjectFactory dF = PersistenceFactory.INSTANCE.getDomainObjectFactory(dbConfiguration.getService(), getDomainFactory().getBaseDomainFactory());
... ...
@@ -78,6 +80,32 @@ public class ManeuverRaceFingerprintConversionTest extends OnlineTracTracBasedTe
78 80
final ManeuverRaceFingerprint fingerprintAfterDB = fingerprintHashMap.get(trackedRace1.getRaceIdentifier());
79 81
assertTrue(fingerprintAfterDB.matches(trackedRace1), "Original and de-serialized copy are equal");
80 82
final Map<Competitor, List<Maneuver>> maneuversLoaded = dF.loadManeuvers(trackedRace1, trackedRace1.getRace().getCourse());
81
- assertEquals(maneuvers, maneuversLoaded);
83
+ assertEquals(maneuvers, maneuversLoaded); // this only checks the equality based on AbstractGPSFixImpl.equals, so lat/lng, cog/sog and time stamp
84
+ for (final Competitor c : maneuversLoaded.keySet()) {
85
+ final Iterator<Maneuver> maneuverIter = maneuvers.get(c).iterator();
86
+ for (final Maneuver m : maneuversLoaded.get(c)) {
87
+ final Maneuver maneuverDetected = maneuverIter.next();
88
+ assertEqualManeuverLoss(maneuverDetected.getManeuverLoss(), m.getManeuverLoss());
89
+ assertEquals(maneuverDetected.getAvgTurningRateInDegreesPerSecond(), m.getAvgTurningRateInDegreesPerSecond(), 0.000001);
90
+ assertEquals(maneuverDetected.getDirectionChangeInDegrees(), m.getDirectionChangeInDegrees());
91
+ }
92
+ }
93
+ }
94
+
95
+ private void assertEqualManeuverLoss(ManeuverLoss maneuverLoss1, ManeuverLoss maneuverLoss2) {
96
+ if (maneuverLoss1 != null) {
97
+ assertEquals(maneuverLoss1.getManeuverStartPosition(), maneuverLoss2.getManeuverStartPosition());
98
+ assertEquals(maneuverLoss1.getManeuverEndPosition(), maneuverLoss2.getManeuverEndPosition());
99
+ assertEquals(maneuverLoss1.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters(),
100
+ maneuverLoss2.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters(), 0.000001);
101
+ assertEquals(maneuverLoss1.getDistanceSailedProjectedOnMiddleManeuverAngle().getMeters(),
102
+ maneuverLoss2.getDistanceSailedProjectedOnMiddleManeuverAngle().getMeters(), 0.000001);
103
+ assertEquals(maneuverLoss1.getManeuverDuration().asSeconds(), maneuverLoss2.getManeuverDuration().asSeconds(), 0.000001);
104
+ assertEquals(maneuverLoss1.getMiddleManeuverAngle().getDegrees(), maneuverLoss2.getMiddleManeuverAngle().getDegrees(), 0.000001);
105
+ assertEquals(maneuverLoss1.getProjectedDistanceLost().getMeters(), maneuverLoss2.getProjectedDistanceLost().getMeters(), 0.000001);
106
+ assertEquals(maneuverLoss1.getRatioBetweenDistanceSailedWithAndWithoutManeuver(), maneuverLoss2.getRatioBetweenDistanceSailedWithAndWithoutManeuver(), 0.000001);
107
+ assertEquals(maneuverLoss1.getSpeedWithBearingBefore().getKnots(), maneuverLoss2.getSpeedWithBearingBefore().getKnots(), 0.000001);
108
+ assertEquals(maneuverLoss1.getSpeedWithBearingBefore().getBearing().getDegrees(), maneuverLoss2.getSpeedWithBearingBefore().getBearing().getDegrees(), 0.000001);
109
+ }
82 110
}
83 111
}